:root {
  color-scheme: light;
  --primary: #1565c0;
  --secondary: #4527a0;
  --accent: #2e7d32;
  --warn: #b7791f;
  --danger: #b71c1c;
  --bg: #f8f9fa;
  --surface: #ffffff;
  --text: #262a2e;
  --muted: #6b7280;
  --border: #e3e6ea;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  margin: 0;
}

a { color: var(--primary); }

/* ---------- Header ----------
 * Charcoal/black, in keeping with Imperception's own brand (brushed steel on
 * near-black, with a thin blue-white glint) — the logo in .imp-logo is shot
 * on the same near-black, so it sits flush against this background. */
header.site-header {
  background: linear-gradient(135deg, #1c1e24, #08090b);
  color: white;
  padding: 1.25rem 2rem;
  border-bottom: 2px solid var(--primary);
}

.header-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.brand img.logo {
  height: 44px;
  width: auto;
  display: block;
  filter: drop-shadow(0 0 6px rgba(21,101,192,0.45));
}

/* Imperception logo — mix-blend-mode: screen drops out the image's near-black
 * background entirely (screen of black with anything = that thing unchanged),
 * so only the metallic wordmark and blue glint show against the header. */
.imp-logo {
  mix-blend-mode: screen;
}

.brand .tagline {
  margin: 0;
  font-size: 0.85rem;
  opacity: 0.85;
}

.version-badge {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  background: rgba(255,255,255,0.18);
  color: #fff;
}

.role-switch {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
}

.role-switch select {
  padding: 0.4rem 0.6rem;
  border-radius: 6px;
  border: none;
  font-size: 0.85rem;
}

/* ---------- Nav tabs ---------- */
nav.tabs {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.tabs-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  gap: 0.25rem;
  overflow-x: auto;
  padding: 0 1rem;
}

.tab-btn {
  border: none;
  background: none;
  padding: 0.9rem 1.1rem;
  font-size: 0.95rem;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}

.tab-btn:hover { color: var(--primary); }

.tab-btn.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
  font-weight: 600;
}

/* ---------- Layout ---------- */
main.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 2rem 1rem 4rem;
}

.view { display: none; }
.view.active { display: block; }

.view-intro { margin-bottom: 2rem; }
.view-intro h2 { margin-bottom: 0.4rem; }

/* ---------- Library sub-tabs (Navigator / Browser) ---------- */
.library-subtabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
}
.subtab-btn {
  border: none;
  background: none;
  padding: 0.7rem 1rem;
  font-size: 0.92rem;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}
.subtab-btn:hover { color: var(--primary); }
.subtab-btn.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
  font-weight: 600;
}
.library-subview { display: none; }
.library-subview.active { display: block; }
.subview-desc { color: var(--muted); margin: 0 0 1rem; }

/* ---------- Propose a Change: dialogue / sheet toggle (v1.62) ---------- */
/* .proptab-btn is a deliberate copy of .subtab-btn rather than a reuse of
   it — see wireProposalSubtabs() in app.js for why sharing the class would
   have been a bug, not a simplification. */
.proposal-mode-tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--border);
  margin: 1rem 0 0;
}
.proptab-btn {
  border: none;
  background: none;
  padding: 0.7rem 1rem;
  font-size: 0.92rem;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}
.proptab-btn:hover { color: var(--primary); }
.proptab-btn.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
  font-weight: 600;
}
.proposal-mode-hint { color: var(--muted); font-size: 0.86rem; margin: 0.5rem 0 1.1rem; }
.proposal-subview { display: none; }
.proposal-subview.active { display: block; }

/* ---------- "This rings true" (v1.62) ---------- */
.modal-toprow { display: flex; justify-content: flex-start; min-height: 0; margin: 0 0 0.6rem; }
.rings-true-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--border);
  background: #f4f5fb;
  color: var(--text);
  border-radius: 999px;
  padding: 0.35rem 0.8rem;
  font-size: 0.85rem;
  cursor: pointer;
}
.rings-true-btn:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.rings-true-btn.tapped {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-color: var(--primary);
  color: var(--primary);
  cursor: default;
}
.rings-true-btn:disabled { opacity: 0.9; }
.rings-true-count { font-weight: 600; }
.view-intro p { color: var(--muted); max-width: 70ch; }

.section-title {
  font-size: 1.1rem;
  margin: 2.25rem 0 1rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
}
.section-title:first-of-type { margin-top: 0; }

/* ---------- Cards / grid ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.25rem;
}

.card {
  background: var(--surface);
  padding: 1.25rem 1.4rem;
  border-radius: var(--radius);
  border-left: 5px solid var(--primary);
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.card h3, .card h4 { margin-top: 0; color: var(--primary); }
.card .meta-tag {
  display: inline-block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--secondary);
  background: rgba(69,39,160,0.08);
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  margin-bottom: 0.5rem;
}

.card.pending {
  opacity: 0.6;
  border-left-color: var(--muted);
}

.tension-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.9rem;
  margin: 0.6rem 0;
}
.tension-row .val { flex: 1; padding: 0.5rem 0.7rem; background: #f2f4f7; border-radius: 6px; }
.tension-row .vs { align-self: center; color: var(--muted); font-size: 0.8rem; }

.key-question {
  margin-top: 0.75rem;
  font-style: italic;
  color: var(--secondary);
}

/* ---------- Category groups (Library) ---------- */
.category-group { margin-bottom: 2rem; }
.category-group h3 {
  color: var(--secondary);
  margin-bottom: 0.75rem;
}

.aaa-list { font-size: 0.85rem; margin-top: 0.6rem; }
.aaa-list div { margin-bottom: 0.25rem; }
.aaa-list b { color: var(--text); }

/* ---------- Browse tables (Library) ---------- */
.browse-subhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 1.5rem 0 0.6rem;
}
.browse-subhead h4 {
  margin: 0;
  color: var(--secondary);
  font-size: 0.95rem;
}
.browse-subhead:first-of-type { margin-top: 0.5rem; }

.browse-filter {
  max-width: 260px;
  padding: 0.5rem 0.7rem;
  font-size: 0.85rem;
}

.browse-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
  margin-bottom: 1.75rem;
}
.browse-table th, .browse-table td {
  text-align: left;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
  vertical-align: top;
}
.browse-table th {
  background: #f2f4f7;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.browse-table tbody tr {
  cursor: pointer;
  transition: background 0.12s ease;
}
.browse-table tbody tr:hover { background: #f6f7ff; }
.browse-table tbody tr:last-child td { border-bottom: none; }
.browse-table tbody tr.row-pending { opacity: 0.6; }

.pending-note { color: var(--muted); font-style: italic; font-size: 0.85rem; }
.meta-category {
  display: inline-block;
  font-size: 0.75rem;
  color: var(--secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 0.5rem;
}

.cross-cutting-badge {
  background: rgba(46,125,50,0.12);
  color: var(--accent);
  font-size: 0.7rem;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
}

/* ---------- Concepts tab ---------- */
.concepts-shell {
  display: grid;
  grid-template-columns: 230px 1fr;
  gap: 2rem;
  align-items: start;
}

.concepts-nav {
  position: sticky;
  top: 76px;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.5rem;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.concepts-nav-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-align: left;
  background: none;
  border: none;
  padding: 0.55rem 0.7rem;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text);
  font-size: 0.85rem;
  line-height: 1.3;
}
.concepts-nav-item:hover { background: #f2f4f7; }
.concepts-nav-item.active {
  background: rgba(21,101,192,0.08);
  color: var(--primary);
  font-weight: 600;
}
.concepts-nav-num {
  font-size: 0.68rem;
  color: var(--muted);
  min-width: 1.3rem;
  flex-shrink: 0;
}
.concepts-nav-item.active .concepts-nav-num { color: var(--primary); }

.concept-content-pane { min-width: 0; }

.concept-eyebrow {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--secondary);
  margin-bottom: 0.35rem;
  font-weight: 600;
}
.concept-title { margin: 0 0 1.25rem; }

.concept-layout {
  display: grid;
  grid-template-columns: 1fr 260px;
  gap: 2rem;
  align-items: start;
}

.concept-article p {
  margin: 0 0 1rem;
  color: var(--text);
  max-width: 70ch;
}

/* Inline lists inside the prose — styled to breathe, with a coloured marker. */
.concept-article ul,
.concept-article ol {
  max-width: 70ch;
  margin: 0 0 1rem;
  padding-left: 1.35rem;
}
.concept-article li { margin: 0 0 0.5rem; color: var(--text); }
.concept-article li::marker { color: var(--primary); font-weight: 700; }
.concept-article strong { color: var(--secondary); }

/* ---------- Chip-strip diagram ----------
 * Numbered nodes joined by arrows, framed as a soft callout so an interleaved
 * diagram reads as an intentional visual rather than stray text. */
.concept-diagram {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 1.5rem 0;
  padding: 1.1rem 1.2rem;
  background: linear-gradient(135deg, #f6f7ff, #f2f4f7);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.concept-diagram-step {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.4rem 0.85rem 0.4rem 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--secondary);
  box-shadow: 0 1px 4px rgba(0,0,0,0.05);
}
.concept-diagram-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--secondary), var(--primary));
  color: #fff;
  font-size: 0.7rem;
  flex: none;
}
.concept-diagram-arrow { color: var(--primary); font-size: 0.95rem; font-weight: 700; }
.concept-diagram-note { color: var(--muted); font-size: 0.85rem; font-style: italic; margin: -0.75rem 0 1.25rem; }

/* ---------- Workflow loop (closed cycle) ----------
 * Used for the diagnostic and TERA workflows, which repeat. The steps run
 * left-to-right and a return line loops back to signal "this cycles". */
.concept-loop-wrap {
  margin: 1.5rem 0;
  padding: 1.25rem;
  background: linear-gradient(135deg, #f6f7ff, #f2f4f7);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.concept-loop {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.concept-loop-step {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.8rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--secondary);
  box-shadow: 0 1px 4px rgba(0,0,0,0.05);
}
.concept-loop-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 999px;
  background: var(--secondary);
  color: #fff;
  font-size: 0.72rem;
  flex: none;
}
.concept-loop-arrow { color: var(--primary); font-size: 1rem; font-weight: 700; }
.concept-loop-back {
  margin-top: 0.85rem;
  padding-top: 0.7rem;
  border-top: 1px dashed var(--border);
  font-size: 0.82rem;
  font-style: italic;
  color: var(--muted);
}
.concept-loop-back-arrow { color: var(--primary); font-size: 1.1rem; font-style: normal; margin-right: 0.25rem; }

/* ---------- System overview map (2-D) ----------
 * Inputs feed down into three family columns; the Activation Conditions bar is
 * drawn underneath, spanning all three, to show it cuts across them; outputs
 * exit at the bottom. */
.concept-overview {
  margin: 1.5rem 0;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
  text-align: center;
}
.concept-ov-row { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0.5rem; }
.concept-ov-input, .concept-ov-output {
  background: #f2f4f7;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--secondary);
}
.concept-ov-output { color: var(--accent); background: rgba(46,125,50,0.08); border-color: rgba(46,125,50,0.25); }
.concept-ov-plus { color: var(--muted); font-weight: 700; }
.concept-ov-down { color: var(--muted); font-size: 1.2rem; margin: 0.35rem 0; }
/* Meta-structure box: one labelled container holding four category columns of
 * three, the fourth (Activation Conditions) styled distinctly. Shared by the
 * Gravity Model overview and the Meta-Structure Map page. */
.concept-ms-box {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fbfbfe;
  padding: 0.9rem;
}
.concept-ms-box-title {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: 0.7rem;
}
.concept-ms-cats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
}
.concept-ms-cat {
  background: #f6f7ff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.5rem;
}
.concept-ms-cat.cross {
  background: linear-gradient(160deg, #4527a0, #1565c0);
  border-color: transparent;
}
.concept-ms-cat-name {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: 700;
  color: var(--primary);
  margin-bottom: 0.45rem;
  text-align: center;
}
.concept-ms-cat.cross .concept-ms-cat-name { color: #fff; }
.concept-ms-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.35rem 0.45rem;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 0.35rem;
  text-align: center;
}
.concept-ms-item:last-child { margin-bottom: 0; }
.concept-ms-cat.cross .concept-ms-item {
  background: rgba(255,255,255,0.16);
  border-color: rgba(255,255,255,0.3);
  color: #fff;
}
.concept-ms-cat-note {
  font-size: 0.64rem;
  font-style: italic;
  color: rgba(255,255,255,0.85);
  text-align: center;
  margin-top: 0.45rem;
}
.concept-metamap { margin: 1.5rem 0; }
@media (max-width: 620px) {
  .concept-ms-cats { grid-template-columns: 1fr 1fr; }
}

/* ---------- Relationship graphic (two nodes + alternating arrow) ----------
 * A TOP node and a BOTTOM node joined by a single arrow whose caption cycles
 * through phrases and periodically flips direction to explain the inverse
 * relationship. Animation driven by animateConceptRelations() in concepts.js. */
.concept-relation {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  max-width: 70ch;
  margin: 1.5rem 0;
  padding: 1.4rem 1.2rem;
  background: linear-gradient(135deg, #f6f7ff, #f2f4f7);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-align: center;
}
.concept-rel-node {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.55rem 1.1rem;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--secondary);
  box-shadow: 0 1px 5px rgba(0,0,0,0.06);
}
.concept-rel-mid {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  justify-content: center;
  min-height: 2.4rem;
}
.concept-rel-arrow {
  flex: none;
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--secondary), var(--primary));
  color: #fff;
  font-size: 1.1rem;
  font-weight: 700;
}
.concept-rel-caption {
  font-size: 0.85rem;
  color: var(--text);
  max-width: 46ch;
}
.concept-rel-static { color: var(--muted); }
.concept-rel-actor { font-weight: 700; color: var(--secondary); }
.concept-rel-verb {
  font-style: italic;
  color: var(--primary);
  margin: 0 0.4rem;
}

/* ---------- Tension spectrum (trade-off bar with an off-centre marker) ---------- */
.concept-spectrum {
  max-width: 70ch;
  margin: 1.5rem 0;
  padding: 1.3rem 1.4rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.concept-spectrum-intro { font-size: 0.85rem; color: var(--muted); margin: 0 0 1rem; }
.concept-spectrum-intro em { color: var(--secondary); font-style: italic; }
.concept-spectrum-row { margin: 0 0 1.4rem; }
.concept-spectrum-row:last-of-type { margin-bottom: 0.5rem; }
/* slogan elevated in the centre, above the track */
.concept-spectrum-slogan {
  text-align: center;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--secondary);
  margin-bottom: 0.35rem;
}
.concept-spectrum-labels {
  display: flex;
  justify-content: space-between;
  font-size: 0.76rem;
  margin-top: 0.3rem;
}
.concept-spectrum-protect { color: var(--accent); font-weight: 700; }
.concept-spectrum-heavy { color: var(--muted); font-weight: 600; }
.concept-spectrum-track {
  position: relative;
  height: 8px;
  border-radius: 999px;
  /* value (protect) on the LEFT now, heavy on the RIGHT */
  background: linear-gradient(90deg, rgba(46,125,50,0.28), rgba(107,114,128,0.28));
}
.concept-spectrum-base {
  font-size: 0.8rem;
  color: var(--secondary);
  margin: 1rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  text-align: center;
}
.concept-spectrum-base strong { color: var(--accent); }
.concept-spectrum-marker {
  position: absolute;
  top: 50%;
  left: var(--lean, 68%);
  width: 15px;
  height: 15px;
  border-radius: 999px;
  background: var(--surface);
  border: 3px solid var(--primary);
  transform: translate(-50%, -50%);
  box-shadow: 0 1px 4px rgba(0,0,0,0.2);
}
.concept-spectrum-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--muted);
}
.concept-spectrum-legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.concept-spectrum-key { width: 0.8rem; height: 0.8rem; border-radius: 3px; display: inline-block; }
.concept-spectrum-key.protect { background: var(--accent); }
.concept-spectrum-key.heavy { background: var(--muted); }

/* ---------- Signal vs slogan split card ---------- */
.concept-split { margin: 1.5rem 0; display: flex; flex-direction: column; gap: 0.75rem; max-width: 70ch; }
.concept-split-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.concept-split-side { padding: 0.9rem 1rem; }
.concept-split-side p { margin: 0.25rem 0 0; font-size: 0.86rem; }
.concept-split-tag {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}
.concept-split-slogan { background: #f2f4f7; }
.concept-split-slogan .concept-split-tag { color: var(--muted); }
.concept-split-signal { background: rgba(21,101,192,0.06); }
.concept-split-signal .concept-split-tag { color: var(--primary); }
.concept-split-toggle {
  border: none;
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  background: var(--surface);
  color: var(--primary);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  padding: 0 0.8rem;
}
.concept-split-toggle:hover { background: #f6f7ff; }
/* collapsed by default: signal hidden until revealed */
.concept-split-signal { display: none; }
.concept-split-row.revealed { grid-template-columns: 1fr auto 1fr; }
.concept-split-row.revealed .concept-split-signal { display: block; }
.concept-split-row:not(.revealed) { grid-template-columns: 1fr auto; }
@media (max-width: 620px) {
  .concept-split-row, .concept-split-row.revealed { grid-template-columns: 1fr; }
  .concept-split-row:not(.revealed) { grid-template-columns: 1fr; }
  .concept-split-toggle { border: none; border-top: 1px solid var(--border); padding: 0.4rem; }
}

/* ---------- Zone indicator (expert / adaptive / fog) ---------- */
.concept-zonebar { margin: 1.5rem 0; max-width: 70ch; }
.concept-zone-bands { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
.concept-zone-band {
  position: relative;
  text-align: center;
  padding: 0.9rem 0.5rem;
  border-radius: 8px;
  font-weight: 700;
  font-size: 0.82rem;
  border: 1px solid var(--border);
  color: var(--secondary);
}
.concept-zone-band.expert   { background: rgba(46,125,50,0.08); }
.concept-zone-band.adaptive { background: rgba(21,101,192,0.08); }
.concept-zone-band.fog      { background: rgba(107,114,128,0.12); }
.concept-zone-band.is-user { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(21,101,192,0.25); }
.concept-zone-band.is-pattern { border-color: var(--warn); }
.concept-zone-pin {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--primary);
}
.concept-zone-pin.pattern { color: var(--warn); }
.concept-zone-note { font-size: 0.82rem; color: var(--muted); margin: 0.7rem 0 0; }
.concept-zone-note.mismatch { color: var(--warn); font-weight: 500; }

/* ---------- Sphere-of-influence rings ---------- */
.concept-spheres { margin: 1.5rem 0; max-width: 70ch; text-align: center; }
.concept-sphere-stage {
  position: relative;
  width: 260px;
  height: 260px;
  margin: 0.5rem auto;
}
.concept-sphere-ring {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 999px;
  border: 1.5px solid var(--border);
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.concept-sphere-ring.in-reach { background: rgba(21,101,192,0.05); border-color: rgba(21,101,192,0.35); }
.concept-sphere-ring.out-reach { background: rgba(107,114,128,0.04); border-style: dashed; }
.concept-sphere-label {
  margin-top: 0.25rem;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  background: var(--surface);
  padding: 0 0.3rem;
}
.concept-sphere-ring.in-reach .concept-sphere-label { color: var(--primary); }
.concept-sphere-dot {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  background: var(--primary);
  border: 2px solid var(--surface);
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
  cursor: default;
}
.concept-sphere-dot.out-reach { background: var(--warn); }
.concept-sphere-escalate {
  position: absolute;
  left: 50%;
  top: -1.1rem;
  transform: translateX(-50%);
  color: var(--warn);
  font-weight: 700;
  font-size: 0.85rem;
}
.concept-sphere-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--muted);
}
.concept-sphere-legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.concept-sphere-key { width: 0.8rem; height: 0.8rem; border-radius: 999px; display: inline-block; }
.concept-sphere-key.in-reach { background: var(--primary); }
.concept-sphere-key.out-reach { background: var(--warn); }
.concept-sphere-note { font-size: 0.82rem; color: var(--muted); margin: 0.7rem auto 0; max-width: 60ch; }
/* faint, undetailed outermost "environment" ring */
.concept-sphere-ring.env {
  background: repeating-radial-gradient(circle, rgba(107,114,128,0.05) 0 6px, transparent 6px 12px);
  border-style: dotted;
  border-color: rgba(107,114,128,0.4);
}
.concept-sphere-ring.env .concept-sphere-label { color: var(--muted); font-weight: 600; }

/* ---------- Circular TERA cycle (four 90° quadrants + rotating arrow) ---------- */
.concept-tera { margin: 1.5rem 0; text-align: center; }
.concept-tera-ring {
  position: relative;
  width: 260px;
  height: 260px;
  margin: 0.5rem auto;
  border-radius: 999px;
}
.concept-tera-quad {
  position: absolute;
  width: 50%;
  height: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  color: #fff;
  font-weight: 700;
  font-size: 0.9rem;
}
/* four quadrant chevrons, each a quarter-circle via border-radius */
.concept-tera-quad.q0 { top: 0; left: 50%; border-radius: 0 100% 0 0; background: linear-gradient(135deg, #1565c0, #4527a0); }
.concept-tera-quad.q1 { top: 50%; left: 50%; border-radius: 0 0 100% 0; background: linear-gradient(225deg, #1565c0, #4527a0); }
.concept-tera-quad.q2 { top: 50%; left: 0; border-radius: 0 0 0 100%; background: linear-gradient(315deg, #1565c0, #4527a0); }
.concept-tera-quad.q3 { top: 0; left: 0; border-radius: 100% 0 0 0; background: linear-gradient(45deg, #1565c0, #4527a0); }
.concept-tera-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.3rem; height: 1.3rem; border-radius: 999px;
  background: rgba(255,255,255,0.25); font-size: 0.72rem;
}
.concept-tera-label { padding: 0 0.4rem; }
.concept-tera-hub {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 34%; height: 34%; border-radius: 999px;
  background: var(--surface);
  border: 2px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 0.85rem; color: var(--secondary);
  letter-spacing: 0.05em;
  z-index: 2;
}
.concept-tera-spin {
  position: absolute; top: 50%; left: 50%;
  width: 46%; height: 46%;
  transform: translate(-50%, -50%);
  border-radius: 999px;
  border: 2px dashed var(--primary);
  border-left-color: transparent;
  border-bottom-color: transparent;
  z-index: 1;
}
.concept-tera-note { font-size: 0.82rem; color: var(--muted); margin: 0.6rem auto 0; max-width: 60ch; }

/* ---------- Activation cross-cut (blocks on a power bar) ---------- */
.concept-crosscut {
  margin: 1.5rem 0;
  max-width: 70ch;
  padding: 1.2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.concept-cc-blocks { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.6rem; }
.concept-cc-block {
  text-align: center;
  padding: 0.9rem 0.5rem;
  border-radius: 8px;
  font-weight: 700;
  font-size: 0.82rem;
  background: #f6f7ff;
  border: 1px solid var(--border);
  color: var(--secondary);
  transition: opacity 0.4s ease, filter 0.4s ease, background 0.4s ease;
}
.concept-cc-current {
  height: 0.5rem;
  margin: 0.55rem 0;
  border-radius: 999px;
  background: repeating-linear-gradient(90deg, var(--primary) 0 8px, transparent 8px 14px);
  opacity: 0.9;
  transition: opacity 0.4s ease, filter 0.4s ease;
}
.concept-cc-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.7rem 0.8rem;
  border-radius: 8px;
  background: linear-gradient(135deg, #4527a0, #1565c0);
  color: #fff;
  transition: filter 0.4s ease, opacity 0.4s ease;
}
.concept-cc-bar-label {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em;
  font-weight: 700; opacity: 0.85; width: 100%; text-align: center;
}
.concept-cc-bar-item {
  background: rgba(255,255,255,0.16);
  border: 1px solid rgba(255,255,255,0.3);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  font-size: 0.74rem;
  font-weight: 600;
}
.concept-cc-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem; margin-top: 0.9rem; }
.concept-cc-toggle {
  border: 1px solid var(--primary);
  background: var(--surface);
  color: var(--primary);
  border-radius: 6px;
  padding: 0.4rem 0.8rem;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  flex: none;
}
.concept-cc-toggle:hover { background: #f6f7ff; }
.concept-cc-note { font-size: 0.8rem; color: var(--muted); }
/* powered-off state: blocks and current go dark */
.concept-crosscut:not(.is-on) .concept-cc-block { opacity: 0.4; filter: grayscale(1); background: #eceef1; }
.concept-crosscut:not(.is-on) .concept-cc-current { opacity: 0.15; filter: grayscale(1); }
.concept-crosscut:not(.is-on) .concept-cc-bar { filter: grayscale(0.7) brightness(0.8); }

/* ============================================================================
 * Diagram animations — subtle & professional. Because openConceptPage() rewrites
 * conceptContent.innerHTML on every page open, these elements are fresh DOM
 * nodes each time, so the entrance animations replay whenever a page is shown.
 * All motion is wrapped in prefers-reduced-motion: no-preference so it fully
 * stops for users who ask their OS to minimise motion.
 * ========================================================================= */
@keyframes concept-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes concept-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* A soft sheen that sweeps across the activation bar to underline that it cuts
 * across the three families. */
@keyframes concept-sheen {
  0%   { background-position: -140% 0; }
  60%  { background-position: 220% 0; }
  100% { background-position: 220% 0; }
}
/* Marching-ants dashes flowing along the loop's return line — signals "repeats"
 * without being loud. */
@keyframes concept-dash-flow {
  from { background-position: 0 0; }
  to   { background-position: -16px 0; }
}

@media (prefers-reduced-motion: no-preference) {

  /* --- Chip strip: staggered rise of each node, arrows fading between --- */
  .concept-diagram > * {
    opacity: 0;
    animation: concept-rise 0.45s ease-out forwards;
  }
  .concept-diagram > *:nth-child(1)  { animation-delay: 0.05s; }
  .concept-diagram > *:nth-child(2)  { animation-delay: 0.15s; }
  .concept-diagram > *:nth-child(3)  { animation-delay: 0.25s; }
  .concept-diagram > *:nth-child(4)  { animation-delay: 0.35s; }
  .concept-diagram > *:nth-child(5)  { animation-delay: 0.45s; }
  .concept-diagram > *:nth-child(6)  { animation-delay: 0.55s; }
  .concept-diagram > *:nth-child(7)  { animation-delay: 0.65s; }
  .concept-diagram > *:nth-child(8)  { animation-delay: 0.75s; }
  .concept-diagram > *:nth-child(9)  { animation-delay: 0.85s; }
  .concept-diagram > *:nth-child(10) { animation-delay: 0.95s; }
  .concept-diagram > *:nth-child(11) { animation-delay: 1.05s; }
  .concept-diagram > *:nth-child(12) { animation-delay: 1.15s; }
  .concept-diagram > *:nth-child(13) { animation-delay: 1.25s; }
  /* gentle idle lift on hover */
  .concept-diagram-step { transition: transform 0.18s ease, box-shadow 0.18s ease; }
  .concept-diagram-step:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(21,101,192,0.18); }

  /* --- Loop: staggered reveal of steps + flowing return line --- */
  .concept-loop > * {
    opacity: 0;
    animation: concept-rise 0.45s ease-out forwards;
  }
  .concept-loop > *:nth-child(1) { animation-delay: 0.10s; }
  .concept-loop > *:nth-child(2) { animation-delay: 0.20s; }
  .concept-loop > *:nth-child(3) { animation-delay: 0.30s; }
  .concept-loop > *:nth-child(4) { animation-delay: 0.40s; }
  .concept-loop > *:nth-child(5) { animation-delay: 0.50s; }
  .concept-loop > *:nth-child(6) { animation-delay: 0.60s; }
  .concept-loop > *:nth-child(7) { animation-delay: 0.70s; }
  .concept-loop-step { transition: transform 0.18s ease, box-shadow 0.18s ease; }
  .concept-loop-step:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(21,101,192,0.18); }
  .concept-loop-back {
    opacity: 0;
    animation: concept-fade 0.5s ease-out 0.8s forwards;
    /* the dashed rule becomes a subtly flowing line */
    border-top-color: transparent;
    background-image: repeating-linear-gradient(90deg, var(--primary) 0 6px, transparent 6px 12px);
    background-size: 16px 1px;
    background-repeat: repeat-x;
    background-position: 0 0;
  }
  .concept-loop-back { animation: concept-fade 0.5s ease-out 0.8s forwards, concept-dash-flow 0.9s linear infinite; }
  .concept-loop-back-arrow { display: inline-block; animation: concept-fade 0.5s ease-out 1.0s both; }

  /* --- Overview map: rows cascade in top-to-bottom; activation bar sheens --- */
  .concept-overview > * {
    opacity: 0;
    animation: concept-rise 0.5s ease-out forwards;
  }
  .concept-overview > *:nth-child(1) { animation-delay: 0.05s; }
  .concept-overview > *:nth-child(2) { animation-delay: 0.20s; }
  .concept-overview > *:nth-child(3) { animation-delay: 0.35s; }
  .concept-overview > *:nth-child(4) { animation-delay: 0.55s; }
  .concept-overview > *:nth-child(5) { animation-delay: 0.70s; }
  .concept-overview > *:nth-child(6) { animation-delay: 0.85s; }
  .concept-ov-family { transition: transform 0.18s ease, box-shadow 0.18s ease; }
  .concept-ov-family:hover { transform: translateY(-3px); box-shadow: 0 6px 16px rgba(21,101,192,0.14); }
  /* sheen overlay on the activation bar (delayed until after it fades in) */
  .concept-ov-activation {
    position: relative;
    overflow: hidden;
  }
  .concept-ov-activation::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,0.28) 50%, transparent 60%);
    background-size: 220% 100%;
    background-repeat: no-repeat;
    animation: concept-sheen 4.5s ease-in-out 1.2s infinite;
    pointer-events: none;
  }
  /* the down-arrows quietly bob to hint at flow direction */
  .concept-ov-down { animation: concept-fade 0.6s ease-out both; }

  /* --- Relationship graphic: caption cross-fades, arrow flips smoothly --- */
  .concept-rel-caption {
    opacity: 0;
    transition: opacity 0.25s ease;
  }
  .concept-rel-caption.concept-rel-show { opacity: 1; }
  .concept-rel-arrow {
    transition: transform 0.4s ease, background 0.4s ease;
  }
  .concept-rel-arrow.is-down {
    /* subtle emphasis when explaining the reverse direction */
    background: linear-gradient(135deg, var(--primary), var(--accent));
  }
  /* a soft pulse ring so the eye is drawn to the acting node's arrow */
  .concept-rel-arrow::after {
    content: "";
    position: absolute;
    width: 2rem;
    height: 2rem;
    border-radius: 999px;
    border: 2px solid var(--primary);
    opacity: 0;
    animation: concept-rel-pulse 4.2s ease-out infinite;
  }
  .concept-rel-arrow { position: relative; }

  /* --- Tension spectrum: marker glides from centre to its resting lean --- */
  .concept-spectrum-marker {
    animation: concept-spectrum-settle 1.1s cubic-bezier(0.25, 0.9, 0.3, 1) 0.15s both;
  }
  .concept-spectrum-track { transition: box-shadow 0.2s ease; }

  /* --- Zone bands + sphere rings: gentle staggered fade-in --- */
  .concept-zone-band { opacity: 0; animation: concept-rise 0.45s ease-out forwards; }
  .concept-zone-band:nth-child(1) { animation-delay: 0.05s; }
  .concept-zone-band:nth-child(2) { animation-delay: 0.15s; }
  .concept-zone-band:nth-child(3) { animation-delay: 0.25s; }
  .concept-zone-band.is-user { animation: concept-rise 0.45s ease-out forwards, concept-zone-glow 2.8s ease-in-out 0.6s infinite; }

  .concept-sphere-ring { opacity: 0; animation: concept-fade 0.5s ease-out forwards; }
  .concept-sphere-ring:nth-child(1) { animation-delay: 0.05s; }
  .concept-sphere-ring:nth-child(2) { animation-delay: 0.16s; }
  .concept-sphere-ring:nth-child(3) { animation-delay: 0.27s; }
  .concept-sphere-ring:nth-child(4) { animation-delay: 0.38s; }
  .concept-sphere-ring:nth-child(5) { animation-delay: 0.49s; }
  .concept-sphere-dot { opacity: 0; animation: concept-rise 0.5s ease-out 0.6s forwards; }
  .concept-sphere-dot.out-reach .concept-sphere-escalate { animation: concept-escalate-bob 1.8s ease-in-out 1s infinite; }

  /* relationship example line fades with the caption */
  .concept-rel-example { opacity: 0; transition: opacity 0.25s ease; }
  .concept-rel-example.concept-rel-show { opacity: 1; }

  /* circular TERA: the dashed inner ring slowly rotates to signal the cycle */
  .concept-tera-spin { animation: concept-tera-rotate 9s linear infinite; }
  .concept-tera-quad { transition: transform 0.2s ease; }
  .concept-tera-quad:hover { transform: scale(1.03); }

  /* activation cross-cut: the "current" line pulses while powered on */
  .concept-crosscut.is-on .concept-cc-current { animation: concept-cc-flow 2.2s ease-in-out infinite; }
}
@keyframes concept-tera-rotate { to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes concept-cc-flow {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}
@keyframes concept-rel-pulse {
  0%   { transform: scale(1);   opacity: 0.5; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}
@keyframes concept-spectrum-settle {
  from { left: 50%; }
  to   { left: var(--lean, 68%); }
}
@keyframes concept-zone-glow {
  0%, 100% { box-shadow: 0 0 0 2px rgba(21,101,192,0.20); }
  50%      { box-shadow: 0 0 0 4px rgba(21,101,192,0.32); }
}
@keyframes concept-escalate-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(-3px); }
}

table.concept-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
  margin: 1rem 0 1.5rem;
}
.concept-table th, .concept-table td {
  text-align: left;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.88rem;
  vertical-align: top;
}
.concept-table th {
  background: #f2f4f7;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.concept-table tbody tr:last-child td { border-bottom: none; }

.concept-aside {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.concept-box {
  background: var(--surface);
  border-left: 4px solid var(--secondary);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.concept-box h4 {
  margin: 0 0 0.4rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--secondary);
}
.concept-box p { margin: 0; font-size: 0.85rem; color: var(--muted); }

.concept-pills { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.concept-pill {
  background: #f2f4f7;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.32rem 0.75rem;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--primary);
  cursor: pointer;
}
.concept-pill:hover { background: rgba(21,101,192,0.1); }

.concept-nextprev {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.concept-nav-link {
  background: none;
  border: 1px solid var(--border);
  color: var(--primary);
  padding: 0.6rem 1rem;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 400;
}
.concept-nav-link:hover { background: #f6f7ff; }

@media (max-width: 760px) {
  .concepts-shell, .concept-layout { grid-template-columns: 1fr; }
  .concepts-nav {
    position: static;
    flex-direction: row;
    overflow-x: auto;
    gap: 0.3rem;
  }
  .concepts-nav-item { white-space: nowrap; }
}

/* ---------- Detail lightbox ---------- */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(20, 22, 30, 0.55);
  z-index: 100;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.modal-overlay.open { display: flex; }

.modal-card {
  position: relative;
  background: var(--surface);
  border-radius: var(--radius);
  max-width: 640px;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
  padding: 2rem 2.2rem;
  box-shadow: 0 20px 50px rgba(0,0,0,0.3);
}

.modal-card .result-card {
  border: none;
  background: none;
  padding: 0;
  box-shadow: none;
}

.modal-card h4 {
  margin: 1.25rem 0 0.4rem;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}
.modal-card ul { margin: 0.3rem 0; padding-left: 1.2rem; }
.modal-card li { margin-bottom: 0.25rem; }

.modal-close {
  position: absolute;
  top: 0.9rem;
  right: 1rem;
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  padding: 0.2rem 0.5rem;
}
.modal-close:hover { color: var(--text); }

/* ---------- Diagnostic engine ---------- */
#diagnostic-tool {
  background: var(--surface);
  padding: 1.75rem;
  border-radius: var(--radius);
  box-shadow: 0 4px 15px rgba(0,0,0,0.08);
}

.symptom-input-row {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}

input[type="text"], input[type="password"], textarea, select.form-control {
  width: 100%;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  font-family: inherit;
}

.dashboard-key-modal .modal-card { max-width: 380px; }
.dashboard-key-modal p { color: var(--muted); margin-top: 0; }
.change-key-link { font-size: 0.82rem; color: var(--muted); }

.symptom-input-row input[type="text"] { flex: 1; min-width: 240px; }

button, .btn {
  padding: 0.7rem 1.3rem;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
}
button:hover, .btn:hover { filter: brightness(1.08); }
button.secondary, .btn.secondary { background: var(--primary); }
button.ghost, .btn.ghost { background: transparent; color: var(--primary); border: 1px solid var(--primary); }
button.danger, .btn.danger { background: var(--danger); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

.symptom-suggestions {
  margin-top: 0.6rem;
  font-size: 0.82rem;
  color: var(--muted);
}
.symptom-suggestions button {
  background: #f2f4f7;
  color: var(--text);
  padding: 0.25rem 0.6rem;
  font-size: 0.78rem;
  font-weight: 400;
  margin: 0.2rem 0.3rem 0.2rem 0;
}

#results { margin-top: 1.5rem; }
.result-card {
  border-left: 5px solid var(--secondary);
  background: #faf9ff;
  padding: 1.25rem 1.4rem;
  border-radius: var(--radius);
}
.result-card h3 { margin-top: 0; color: var(--secondary); }

.result-card:has(.pattern-type.positive) { border-left-color: var(--accent); background: #f3faf3; }

.pattern-type {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  margin-left: 0.4rem;
}
.pattern-type.mismatch { background: rgba(183,28,28,0.1); color: var(--danger); }
.pattern-type.positive { background: rgba(46,125,50,0.12); color: var(--accent); }

.match-score {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  margin-left: 0.4rem;
  background: rgba(69,39,160,0.1);
  color: var(--secondary);
}

.keyword-chips {
  margin: 0.6rem 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.keyword-chip {
  display: inline-block;
  font-size: 0.75rem;
  background: #eef0f4;
  color: var(--text);
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
}

.jump-link {
  color: var(--primary);
  text-decoration: none;
  border-bottom: 1px dotted var(--primary);
}
.jump-link:hover { border-bottom-style: solid; }

.suggested-interventions { margin-top: 1rem; }
.suggested-interventions ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.suggested-interventions li { margin-bottom: 0.3rem; }

.no-match { color: var(--muted); }

/* ---------- Semantic matching cascade (mode banner, why-line, pick list) ---------- */
.match-mode {
  font-size: 0.8rem;
  margin: 0 0 0.9rem;
  padding: 0.4rem 0.7rem;
  border-radius: 8px;
}
.match-mode-smart {
  background: rgba(46,125,50,0.08);
  color: #2e7d32;
}
.match-mode-smart .match-mode-interp {
  color: var(--text);
  font-style: italic;
}
.match-mode-lexical {
  background: #fff4e5;
  color: #8a5a00;
}
/* Tiny grey engine hint (gm/mi/gq/lex) — a diagnostic marker, deliberately faint. */
.model-marker {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: #9aa0ac;
  background: rgba(120,128,140,0.12);
  padding: 0.02rem 0.32rem;
  border-radius: 4px;
  vertical-align: middle;
  text-transform: lowercase;
}
.rate-note {
  background: #fdecea;
  color: #a03530;
  font-size: 0.85rem;
  padding: 0.5rem 0.8rem;
  border-radius: 8px;
  margin: 0 0 0.9rem;
}
.match-why {
  font-size: 0.9rem;
  color: var(--secondary);
}
.try-label { color: var(--muted); font-size: 0.85rem; }
.input-precision-hint {
  color: var(--muted);
  font-size: 0.82rem;
  margin: 0.35rem 0 0.6rem;
}
.precision-note {
  background: #fff8e6;
  color: #8a6416;
  font-size: 0.85rem;
  padding: 0.55rem 0.85rem;
  border-radius: 8px;
  margin: 0 0 0.9rem;
  line-height: 1.4;
}

/* ---------------- Gravity graphic + impact explorer (v1.27) ---------------- */
.grav-figure { margin: 0.6rem 0 0; }
.grav-svg { width: 100%; max-width: 560px; height: auto; display: block; margin: 0 auto; overflow: visible; }
.grav-ring { fill: none; stroke: var(--border, #e5e5e5); stroke-width: 1; opacity: 0.7; }
.grav-centre { fill: var(--brand, #4527a0); opacity: 0.92; }
.grav-centre-label { fill: #fff; font-size: 13px; font-weight: 700; letter-spacing: 0.03em; }
.grav-label { font-size: 11.5px; font-weight: 600; fill: var(--text, #222); }
.grav-sub { font-size: 9.5px; fill: var(--muted, #777); }
.grav-caption {
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--muted, #666);
  margin-top: 0.5rem;
  text-align: center;
}
.grav-draft { font-style: italic; opacity: 0.85; }

/* A dependency you have reported as broken is drawn under strain — the orbit
   is not settled, and the picture should not pretend otherwise. Confined to a
   1px wobble so it reads as tension, not decoration. */
@keyframes grav-wobble {
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(1.1px, -0.7px); }
  50%      { transform: translate(-0.6px, 1.1px); }
  75%      { transform: translate(0.8px, 0.6px); }
}
.grav-node.strained { animation: grav-wobble 1.9s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.37s); transform-box: fill-box; transform-origin: center; }
.grav-edge.strained { stroke-dasharray: 7 3; opacity: 0.95; }
.grav-halo { animation: grav-pulse 2.4s ease-in-out infinite; }
@keyframes grav-pulse { 0%, 100% { opacity: 0.15; } 50% { opacity: 0.5; } }
@media (prefers-reduced-motion: reduce) {
  .grav-node.strained, .grav-halo { animation: none; }
}

/* Forces table (v1.28) — the numbered answer to "what's holding this back?" */
.grav-forces { margin-top: 0.9rem; border-top: 1px solid var(--border, #e5e5e5); padding-top: 0.7rem; }
.grav-forces h5 { margin: 0 0 0.4rem; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted, #777); }
.grav-forces table { width: 100%; border-collapse: collapse; font-size: 0.84rem; }
.grav-forces td { padding: 0.3rem 0.35rem 0.3rem 0; vertical-align: top; border-top: 1px solid rgba(0, 0, 0, 0.05); }
.grav-forces tr:first-child td { border-top: none; }
.gf-icon { width: 1.2rem; font-weight: 700; }
.gf-name { font-weight: 600; white-space: nowrap; }
.gf-effect { color: var(--muted, #666); line-height: 1.4; }
.gf-value { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap; }
tr.gf-hurts .gf-icon, tr.gf-hurts .gf-value, .grav-sub.gf-hurts { fill: #c62828; color: #c62828; }
tr.gf-helps .gf-icon, tr.gf-helps .gf-value, .grav-sub.gf-helps { fill: #2e7d32; color: #2e7d32; }
tr.gf-risk .gf-icon, .grav-sub.gf-risk { fill: #c62828; color: #c62828; }
tr.gf-unknown .gf-icon, .grav-sub.gf-unknown { fill: #9a8a55; color: #9a8a55; }
tr.gf-acts .gf-icon { color: var(--brand, #4527a0); }
.gf-net { font-size: 0.84rem; margin: 0.5rem 0 0; color: var(--muted, #666); }
.gf-net .gf-neg { color: #c62828; }
.gf-net .gf-pos { color: #2e7d32; }
.gf-note { font-size: 0.78rem; font-style: italic; }

/* v1.33 — the plain-English reading above the gravity graphic. Set slightly
   wider than the caption and with no bullet list: this is meant to be read as
   three sentences, not scanned as a checklist, because the whole point is that
   it is the one part of the result that survives being read aloud. */
.grav-summary {
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.85rem;
  border-left: 3px solid var(--brand, #4527a0);
  background: rgba(69, 39, 160, 0.04);
  border-radius: 0 4px 4px 0;
}
.grav-summary h5 {
  margin: 0 0 0.45rem;
  font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--muted, #777);
}
.grav-summary p { margin: 0 0 0.45rem; font-size: 0.9rem; line-height: 1.5; }
.grav-summary p:last-child { margin-bottom: 0; }

/* Structures the pattern flags that this option does not touch. Grey, hollow
   and dotted on purpose: the node must never be mistaken for a relationship. */
.grav-ghost circle { opacity: 0.85; }
.grav-label-ghost { fill: var(--muted, #777); font-weight: 500; font-style: italic; }
.grav-ghostnote { font-style: italic; opacity: 0.85; }
tr.gf-gap .gf-icon, tr.gf-gap .gf-name, tr.gf-gap .gf-effect { color: var(--muted, #777); font-style: italic; }

/* Marks the arithmetic as the engine showing its working, not as the answer. */
.gf-masteronly {
  font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px solid currentColor; border-radius: 3px; padding: 0 0.25rem;
  opacity: 0.6; font-style: normal; margin-left: 0.3rem;
}
.gf-draft {
  font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px dotted currentColor; border-radius: 3px; padding: 0 0.25rem; opacity: 0.7; font-weight: 400;
}

.ie-listhead { display: flex; gap: 0.5rem; flex-wrap: wrap; justify-content: space-between; margin-bottom: 0.5rem; }
.ie-scope-note { font-size: 0.78rem; color: var(--muted, #888); margin: 0.45rem 0 0; line-height: 1.4; }

.impact-explorer .ie-body { display: flex; gap: 1.2rem; align-items: flex-start; flex-wrap: wrap; }
.impact-explorer .ie-left { flex: 1 1 340px; min-width: 280px; }
.impact-explorer .ie-right { flex: 1 1 300px; min-width: 260px; }

.ie-rank-row {
  display: grid;
  grid-template-columns: 1.5rem 2.2rem minmax(0, 1fr) auto auto;
  gap: 0.5rem;
  align-items: center;
  width: 100%;
  text-align: left;
  background: transparent;
  color: inherit;
  border: 1px solid transparent;
  border-bottom: 1px solid var(--border, #e5e5e5);
  border-radius: 6px;
  padding: 0.3rem 0.45rem;
  font-weight: 400;
  font-size: 0.8rem;
  line-height: 1.25;
  cursor: pointer;
}
.ie-rank-row:hover { background: rgba(0, 0, 0, 0.03); filter: none; }
.ie-rank-row.selected { border-color: var(--brand, #4527a0); background: rgba(69, 39, 160, 0.06); }
.ie-rank-n { font-weight: 700; color: var(--muted, #777); }
.ie-rank-name { line-height: 1.3; min-width: 0; overflow-wrap: anywhere; }
.ie-rank-band { font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 10px; white-space: nowrap; }
.ie-move { font-size: 0.75rem; font-weight: 700; min-width: 2.2rem; text-align: right; }
.ie-move.up { color: #2e7d32; }
.ie-move.down { color: #c62828; }
.ie-move.flat { color: var(--muted, #aaa); font-weight: 400; }

.ie-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.9rem 1.4rem;
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border, #e5e5e5);
}
.ie-control label { display: block; font-size: 0.8rem; font-weight: 700; margin-bottom: 0.25rem; }
.ie-control input[type="range"] { width: 100%; margin: 0.1rem 0; accent-color: var(--brand, #4527a0); }
.ie-value { font-size: 0.85rem; }
.ie-yours { font-size: 0.72rem; color: var(--muted, #888); font-style: italic; }
.ie-seg { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.ie-seg button {
  font-size: 0.75rem;
  padding: 0.3rem 0.55rem;
  background: var(--surface, #f2f2f5);
  color: var(--text, #333);
  border: 1px solid var(--border, #ddd);
  border-radius: 6px;
  font-weight: 500;
}
.ie-seg button:hover { filter: none; background: rgba(69, 39, 160, 0.08); }
.ie-seg button.selected { background: var(--brand, #4527a0); color: #fff; border-color: var(--brand, #4527a0); }
.ie-secondary { grid-column: 1 / -1; }
.ie-sec-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.35rem; }
.ie-sec-name { font-size: 0.83rem; min-width: 11rem; }
.ie-actions { margin-top: 1rem; }

@media (max-width: 700px) {
  .impact-explorer .ie-body { flex-direction: column; }
  .ie-sec-name { min-width: 0; flex-basis: 100%; }
}

/* Ranking explanations + secondary meta-structure health (v1.26) */
.reco-why {
  font-size: 0.85rem;
  line-height: 1.5;
  margin: 0.5rem 0 0.6rem;
  padding: 0.5rem 0.7rem;
  border-left: 3px solid var(--accent, #2d6a4f);
  background: rgba(0, 0, 0, 0.025);
  border-radius: 0 6px 6px 0;
  color: var(--secondary, #444);
}
.reco-why b { font-weight: 700; }
.reco-warn {
  font-size: 0.85rem;
  line-height: 1.45;
  margin: 0 0 0.6rem;
  padding: 0.45rem 0.7rem;
  border-radius: 6px;
  background: #fdecea;
  color: #a03530;
}
/* Spec §3.4 — never present a machine-derived assessment as reviewed content. */
.reco-warn.unreviewed { border: 1px dotted #a03530; }
.reco-draft {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.75;
  border: 1px dotted currentColor;
  border-radius: 4px;
  padding: 0 0.3rem;
  margin-left: 0.3rem;
}

.secondary-health .sec-health-row {
  margin: 0.7rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border, #e5e5e5);
}
.secondary-health .sec-health-row:first-of-type { border-top: none; }
.secondary-health .shr-prompt {
  font-size: 0.9rem;
  line-height: 1.45;
  margin-bottom: 0.4rem;
}

/* meta-impacts editor (Master record sheet) */
.mi-editor .mi-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 0.4rem;
}
.mi-editor .mi-row .mi-meta { flex: 1 1 12rem; }
.mi-editor .mi-row .mi-type { flex: 2 1 18rem; }
.mi-editor .mi-row .mi-weight { flex: 0 0 4.5rem; }
.mi-editor .mi-remove {
  background: none;
  border: none;
  color: var(--danger, #c0392b);
  font-size: 1.1rem;
  cursor: pointer;
  padding: 0 0.4rem;
}
.mi-editor .mi-draft {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px dotted currentColor;
  border-radius: 4px;
  padding: 0 0.3rem;
  opacity: 0.7;
}
.mi-editor .mi-legend {
  display: none;
}
.mi-editor .mi-add { margin-top: 0.2rem; }

/* Query preflight gate (v1.25) — shown in place of results when a description
   is checked BEFORE the semantic matcher runs. "thin" is advice with a way
   past it; "block" is a stop, so it carries the warmer-but-firmer red. */
.query-gate {
  border-radius: 10px;
  padding: 1rem 1.1rem;
  margin: 0 0 1rem;
  line-height: 1.5;
  border-left: 4px solid;
}
.query-gate h4 {
  margin: 0 0 0.35rem;
  font-size: 1rem;
}
.query-gate p { margin: 0 0 0.5rem; font-size: 0.9rem; }
.query-gate .qgate-example {
  font-size: 0.85rem;
  opacity: 0.9;
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.55);
}
.query-gate .form-actions { margin-top: 0.8rem; }
.query-gate-thin {
  background: #fff8e6;
  color: #8a6416;
  border-left-color: #d9a520;
}
.query-gate-block {
  background: #fdecea;
  color: #a03530;
  border-left-color: var(--danger, #c0392b);
}

/* "Let me think…" loading state */
.thinking {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--secondary);
  font-size: 0.95rem;
  padding: 0.6rem 0;
}
.thinking-dots { display: inline-flex; gap: 0.25rem; }
.thinking-dots span {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--primary);
  animation: thinking-bounce 1.2s infinite ease-in-out both;
}
.thinking-dots span:nth-child(1) { animation-delay: -0.24s; }
.thinking-dots span:nth-child(2) { animation-delay: -0.12s; }
@keyframes thinking-bounce {
  0%, 80%, 100% { transform: scale(0.5); opacity: 0.4; }
  40% { transform: scale(1); opacity: 1; }
}

/* Multi-result guidance + focus button */
.result-guidance {
  background: rgba(69,39,160,0.06);
  border-left: 3px solid var(--primary);
  padding: 0.6rem 0.9rem;
  border-radius: 6px;
  margin: 0 0 1rem;
  font-size: 0.92rem;
}
.focus-btn {
  background: var(--primary);
  color: #fff;
  border: none;
  padding: 0.45rem 0.9rem;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
  margin-right: 0.5rem;
}
.focus-btn:hover { filter: brightness(1.08); }

.no-match-panel { color: var(--text); }
.pick-list {
  list-style: none;
  margin: 0.8rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.pick-pattern {
  cursor: pointer;
  font-size: 0.8rem;
  background: #eef0f4;
  color: var(--text);
  border: 1px solid #dcdce4;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
}
.pick-pattern:hover {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}

/* ---------- Diagnostic Steps 3 & 4 (validation + navigation pause) ---------- */
.panel-card {
  border: 1px solid #e3e1f2;
  background: #fff;
  padding: 1.25rem 1.4rem;
  border-radius: var(--radius);
  margin-top: 1rem;
}
.panel-card h3 { margin-top: 0; color: var(--secondary); }
.panel-card h4 { margin-bottom: 0.4rem; }

.signs-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.2rem;
  margin: 0.8rem 0;
}
.signs-col.green h4 { color: var(--accent); }
.signs-col.theater h4 { color: var(--danger); }
.sign-row {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
  font-size: 0.92rem;
  cursor: pointer;
}
.sign-row input { margin-top: 0.2rem; }

.validation-verdict { padding: 0.6rem 0.8rem; border-radius: var(--radius); font-size: 0.92rem; }
.validation-verdict.theater { background: rgba(183,28,28,0.08); color: var(--danger); }
.validation-verdict.healthy { background: rgba(46,125,50,0.08); color: var(--accent); }
.validation-verdict.neutral { background: #f3f2fa; color: var(--muted); }

.filter-group { margin-bottom: 1.1rem; }
.filter-group p { color: var(--muted); font-size: 0.88rem; margin: 0.2rem 0 0.5rem; }
.filter-btn-row { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.filter-btn-row button {
  background: #eef0f4;
  color: var(--text);
}
/* Zone & AAA options have long plain-language labels — stack them full-width,
 * left-aligned, so they read as choices rather than cramped pills. */
/* v1.26 — these used to be [data-filter="zone"] / [data-filter="aaa"], which
   stopped matching when the context keys were renamed to userZone/userAAA. The
   rule had been silently dead ever since, so EVERY Step 3 option ran its label
   straight into its description ("We know what good looks likeA competent
   person could tell us…"). `.filter-btn-row` is only ever used by the Step 3
   questions, so it is safe to apply to all of them rather than name each key
   and risk the same drift again. */
.filter-btn-row {
  flex-direction: column;
  align-items: stretch;
}
.filter-btn-row button {
  text-align: left;
  white-space: normal;
  line-height: 1.35;
  padding: 0.6rem 0.8rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.opt-title { font-weight: 600; }
.opt-desc { font-size: 0.82rem; opacity: 0.85; }
.filter-btn-row button.selected .opt-desc { opacity: 0.95; }

.step-heading {
  margin: 0 0 0.7rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid rgba(69,39,160,0.15);
  color: var(--secondary);
}
.filter-btn-row button.selected {
  background: var(--secondary);
  color: #fff;
}

.mismatch-note { color: #9a6700; background: rgba(154,103,0,0.08); padding: 0.5rem 0.7rem; border-radius: var(--radius); font-size: 0.88rem; }
.context-summary-card {
  background: #f3f2fa;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  font-size: 0.9rem;
  margin-top: 0.4rem;
}

/* ---------- Steps 5 & 6 (Fit Score ranking + TERA cards) ---------- */
.reco-card {
  border-left: 5px solid var(--accent);
  background: #f8fbf8;
  padding: 1.1rem 1.3rem;
  border-radius: var(--radius);
  margin-top: 1rem;
}
.reco-card h3 { margin-top: 0.3rem; color: var(--secondary); }
.reco-card .strengthen { font-style: italic; color: var(--muted); }
.reco-card .tera { margin: 0.6rem 0 0; padding-left: 1.2rem; }
.reco-card .tera li { margin-bottom: 0.4rem; }

/* ---------- Step 7 (Proximity / Neighbourhood Checks) ---------- */
.proximity {
  background: #fff8e6;
  border-left: 3px solid #b58900;
  padding: 0.5rem 0.8rem;
  border-radius: 4px;
  margin: 0.5rem 0;
  font-size: 0.92rem;
}

/* ---------- Forms (Proposal interface) ---------- */
.form-grid {
  display: grid;
  gap: 1rem;
  max-width: 640px;
}
.form-field label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
  color: var(--muted);
}
.form-actions { display: flex; gap: 0.6rem; margin-top: 0.5rem; flex-wrap: wrap; }

.new-entity-links-title {
  margin: 1.25rem 0 0.5rem;
  color: var(--muted);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-top: 1px solid var(--border);
  padding-top: 1rem;
}

.settings-box {
  background: #fff8e6;
  border: 1px solid #f0dca0;
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  margin-bottom: 1.5rem;
  font-size: 0.88rem;
}
.settings-box input { margin-top: 0.4rem; max-width: 360px; display: inline-block; }

/* ---------- Entity edit form (Proposal interface) ---------- */
.field-diff-header { display: none; }
.field-diff-header-OLD {
  display: grid;
  grid-template-columns: 160px 1fr 1fr;
  gap: 1rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  padding: 0 0 0.3rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.5rem;
}

.field-edit-row {
  display: block;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.88rem;
  align-items: start;
}
.field-edit-row:last-child { border-bottom: none; }

.field-label {
  font-weight: 600;
  color: var(--text);
  font-size: 0.95rem;
  margin-bottom: 0.5rem;
}
.field-desc {
  display: block;
  font-weight: 400;
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 0.15rem;
}
/* Current (read-only) above, Proposed (editable) below — both full width so
 * the editable inputs get real room. */
.field-current {
  color: var(--muted);
  background: #f7f7fb;
  border-radius: 6px;
  padding: 0.4rem 0.6rem;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
}
.field-current ul { margin: 0.2rem 0 0; padding-left: 1.1rem; }
.field-col-tag {
  display: block;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 0.2rem;
  font-weight: 700;
}
.field-proposed .field-col-tag { color: var(--secondary); }

.field-proposed textarea,
.field-proposed input[type="text"],
.field-proposed select,
.form-field textarea,
.form-field input[type="text"],
.form-field select {
  width: 100%;
  box-sizing: border-box;
  font-size: 0.9rem;
  padding: 0.5rem 0.6rem;
}
.field-proposed textarea,
.form-field textarea { min-height: 5rem; line-height: 1.4; resize: vertical; }
.field-proposed select[multiple],
.form-field select[multiple] { padding: 0.3rem; min-height: 7rem; }
.field-hint { font-size: 0.72rem; color: var(--muted); margin-top: 0.2rem; }

.req { color: #c0392b; font-weight: 700; }

/* ---------- Editing form: inline validation & search (v0.71) ---------- */
.entity-filter { margin-bottom: 0.5rem; }
.form-field.has-error textarea,
.form-field.has-error input,
.form-field.has-error select {
  border-color: #c0392b !important;
  box-shadow: 0 0 0 2px rgba(192, 57, 43, 0.15);
}
.form-message {
  margin: 0.4rem 0 0.9rem;
  padding: 0.7rem 0.9rem;
  border-radius: 8px;
  font-size: 0.9rem;
  line-height: 1.45;
  border: 1px solid transparent;
}
.form-message[hidden] { display: none; }
.form-message.error { background: #fdecea; border-color: #f5c6c0; color: #a5271b; }
.form-message.success { background: #e7f6ec; border-color: #b6e0c4; color: #1e7d40; }
.form-message.info { background: #eef2fb; border-color: #cdd8f0; color: #33477a; }

.consent-field { margin-top: 0.6rem; }
.consent-label {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  font-weight: 400;
  font-size: 0.88rem;
  cursor: pointer;
}
.consent-label input { margin-top: 0.2rem; }
.spam-note { font-size: 0.78rem; color: var(--muted); margin: 0.5rem 0 0; }
.pattern-examples { margin-top: 0.8rem; }
.pattern-examples ul { margin: 0.3rem 0 0; padding-left: 1.2rem; }

/* Library detail: category pill, "More detail" disclosure, meta reverse-links */
.meta-category-pill {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  margin-left: 0.4rem;
  background: #eef0f4;
  color: var(--secondary);
}
.more-detail {
  margin-top: 1rem;
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}
.more-detail > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--primary);
  list-style: none;
  padding: 0.3rem 0;
}
.more-detail > summary::before { content: "▸ "; }
.more-detail[open] > summary::before { content: "▾ "; }
.more-detail > summary:hover { text-decoration: underline; }
.more-detail-body { padding-top: 0.4rem; }
.more-detail-body h4 { margin: 0.9rem 0 0.3rem; font-size: 0.9rem; }
.more-detail-body ul { margin: 0.3rem 0; padding-left: 1.2rem; }
.meta-links { margin-top: 0.9rem; font-size: 0.9rem; }
.meta-links p { margin: 0.25rem 0; }
.vs-inline { color: var(--muted); font-size: 0.8rem; font-style: italic; }

/* ---------- Library usability: global search, counts, sticky headers ---------- */
.library-search-bar {
  position: relative;
  margin: 0.5rem 0 0.3rem;
}
.library-search {
  width: 100%;
  box-sizing: border-box;
  font-size: 1rem;
  padding: 0.7rem 2.4rem 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.library-search:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(69, 39, 160, 0.12);
}
.library-search-clear {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: transparent;
  font-size: 1rem;
  color: var(--muted);
  cursor: pointer;
  display: none;
  padding: 0.3rem 0.5rem;
}
.library-search-clear:hover { color: var(--text); }
.library-search-summary {
  font-size: 0.85rem;
  color: var(--secondary);
  margin: 0 0 1rem;
  min-height: 1rem;
}
.row-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted);
  background: #eef0f4;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  margin-left: 0.4rem;
}
/* Sticky table headers so column labels stay visible while scrolling long tables. */
.browse-table thead th {
  position: sticky;
  top: 0;
  background: var(--surface, #fff);
  z-index: 1;
}
/* Clearer clickable-row affordance. */
.browse-table tbody tr[data-id] { cursor: pointer; }
.browse-table tbody tr[data-id]:hover { background: rgba(69, 39, 160, 0.06); }
.no-match-cell {
  color: var(--muted);
  font-style: italic;
  text-align: center;
  padding: 0.8rem;
}

/* ---------- Interactive framework map ---------- */
.framework-map {
  margin: 0.5rem 0 2rem;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: linear-gradient(180deg, #fbfbfe 0%, #f4f5fb 100%);
  overflow: hidden;
}
.map-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.map-hint { font-size: 0.85rem; color: var(--muted); }
.map-toolbar-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
#mapFocus.active { background: var(--accent); }
.map-zoom-controls {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.15rem;
}
.map-zoom-controls button {
  padding: 0.3rem 0.65rem;
  font-size: 0.9rem;
  line-height: 1;
}
.map-zoom-label {
  font-size: 0.78rem;
  color: var(--muted);
  min-width: 2.6rem;
  text-align: center;
}
.map-search-bar { margin: 0.7rem 1rem 0.2rem; }
.map-search-summary { margin: 0 1rem 0.5rem; font-size: 0.8rem; }
.map-scroll { overflow-x: auto; padding: 0.5rem; }
#mapSvg { display: block; }

/* Expanded / larger viewing area for the framework map (v0.72). */
.framework-map.is-expanded .map-scroll {
  max-height: none;
  min-height: 70vh;
}
.framework-map.is-expanded {
  position: relative;
  z-index: 5;
}
@media (min-width: 1100px) {
  .framework-map.is-expanded {
    width: 96vw;
    max-width: 1600px;
    margin-left: calc(50% - 48vw);
    margin-right: calc(50% - 48vw);
  }
}

/* Results export/copy actions (v0.72). */
.result-actions { align-items: center; }
.copy-note {
  font-size: 0.82rem;
  color: #1e7d40;
  font-weight: 600;
}
.copy-note[hidden] { display: none; }

/* ============================================================
   v0.73 — brand refresh, wide-desktop layout, sticky slim header,
   meta-structure hover previews.
   ============================================================ */

/* ---------- Full-screen intro overlay (v0.75) ----------
   Shown on page (re)load only. Covers the whole viewport in near-black, plays
   the reveal, holds, then dissolves to show the homepage beneath. */
.intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: #050505;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;                 /* click anywhere to skip */
  opacity: 1;
  transition: opacity 900ms ease;  /* the dissolve */
}
.intro-overlay[hidden] { display: none; }
.intro-overlay.dissolve { opacity: 0; }
/* Inside the full-screen overlay, blend the wordmark straight into the pure-black
   backdrop so no seam shows even though the PNG's own background isn't exactly
   #050505. `lighten` against black shows the image faithfully while erasing the
   slightly-lighter PNG border. No rounded corners here. */
.intro-overlay .imp-intro { width: min(760px, 88vw); margin: 0; background: transparent; border-radius: 0; overflow: visible; }
/* Start fully hidden/dark so the very first paint is pure black — the PNG never
   flashes before the reveal. The existing `.imp-intro.play` animation (below)
   fades it up from here; `both` fill keeps frame-0 state until it runs. */
.intro-overlay .imp-intro-img { opacity: 0; filter: brightness(0.15) contrast(0.8); }
/* Blend into pure black AND feather the rectangular edges to transparent, so when
   the flare brightens the image plate its border never shows a hard cut against
   the black backdrop. The mask fades the outer band of every edge. */
.intro-overlay .imp-intro-img {
  mix-blend-mode: lighten;
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 12%, #000 88%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 12%, #000 88%, transparent 100%);
  mask-composite: intersect;
}
.intro-skip {
  position: absolute;
  bottom: 1.4rem;
  right: 1.6rem;
  background: none;
  border: 1px solid rgba(255,255,255,0.18);
  color: rgba(230,235,245,0.65);
  font-size: 0.82rem;
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}
.intro-skip:hover { color: #fff; border-color: rgba(255,255,255,0.4); }
@media (prefers-reduced-motion: reduce) {
  /* Don't animate for reduced-motion users — the overlay just isn't shown (JS). */
  .intro-overlay { transition: none; }
}

/* ---------- Cinematic Imperception intro (wordmark reveal) ----------
   A 2.5s title-sequence reveal. The uploaded PNG is the base layer, so the
   FINAL frame matches it exactly; the animation only reveals it (fade from
   dark steel), then adds a baseline glow + a brief restrained lens flare that
   fade away, leaving the untouched image. No JS-driven motion, no particles. */
.landing-hero { text-align: center; }
.imp-intro {
  position: relative;
  display: block;
  width: min(560px, 88vw);
  margin: 0.5rem auto 0.6rem;
  aspect-ratio: 1234 / 338;
  background: #050505;          /* almost-pure-black backdrop */
  border-radius: 4px;
  overflow: hidden;
}
.imp-intro-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Star / baseline glow — a soft radial bloom centred on the flare point
   (horizontal centre, on the baseline ≈ 90% down). */
.imp-intro-glow,
.imp-intro-flare {
  position: absolute;
  left: 50%;
  top: 90%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
}
.imp-intro-glow {
  width: 26%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(210,235,255,0.95) 0%, rgba(120,170,255,0.35) 35%, rgba(80,130,255,0) 70%);
  filter: blur(2px);
}
/* The horizontal lens-flare streak — expands to ≈1/3 width, then fades. */
.imp-intro-flare {
  height: 3px;
  width: 34%;
  background: linear-gradient(90deg,
    rgba(120,170,255,0) 0%,
    rgba(200,225,255,0.9) 45%,
    #ffffff 50%,
    rgba(200,225,255,0.9) 55%,
    rgba(120,170,255,0) 100%);
  filter: blur(0.6px);
  box-shadow: 0 0 12px 2px rgba(190,220,255,0.7);
}

/* --- Timeline (2.5s total) --- */
/* Image: black → fades up from dark steel to full brightness (0.4s–2.1s). */
@keyframes impReveal {
  0%    { opacity: 0; filter: brightness(0.15) contrast(0.8); }   /* 0.00s */
  16%   { opacity: 0; filter: brightness(0.15) contrast(0.8); }   /* 0.40s */
  64%   { opacity: 1; filter: brightness(0.75) contrast(1.05); }  /* 1.60s */
  84%   { opacity: 1; filter: brightness(1) contrast(1); }        /* 2.10s */
  100%  { opacity: 1; filter: brightness(1) contrast(1); }        /* 2.50s */
}
/* Star glow: begins ~1.6s, peaks at flare, settles after. */
@keyframes impGlow {
  0%,64% { opacity: 0; transform: translate(-50%,-50%) scale(0.6); }
  84%    { opacity: 0.5; transform: translate(-50%,-50%) scale(0.9); }  /* 2.10s */
  90%    { opacity: 1; transform: translate(-50%,-50%) scale(1.15); }   /* 2.25s */
  94%    { opacity: 0.55; transform: translate(-50%,-50%) scale(1); }   /* 2.35s */
  100%   { opacity: 0.28; transform: translate(-50%,-50%) scale(1); }   /* settle */
}
/* Lens flare: brief expansion ≈2.10–2.35s, then fades by 2.5s. */
@keyframes impFlare {
  0%,84% { opacity: 0; width: 6%; }                 /* 2.10s */
  90%    { opacity: 1; width: 34%; }                /* 2.25s peak */
  94%    { opacity: 0.8; width: 32%; }              /* 2.35s */
  100%   { opacity: 0; width: 30%; }                /* 2.50s faded */
}
@media (prefers-reduced-motion: no-preference) {
  .imp-intro.play .imp-intro-img   { animation: impReveal 2.5s ease-out both; }
  .imp-intro.play .imp-intro-glow  { animation: impGlow 2.5s ease-out both; }
  .imp-intro.play .imp-intro-flare { animation: impFlare 2.5s ease-out both; }
}
/* Reduced motion / no-JS fallback: just show the final image, no animation. */
@media (prefers-reduced-motion: reduce) {
  .imp-intro-glow, .imp-intro-flare { display: none; }
}

/* ---------- Landing: try-an-example chips ---------- */
.landing-try { margin: 1.1rem auto 0; max-width: 44rem; }
.landing-try-label { display: block; font-size: 0.85rem; color: var(--muted); margin-bottom: 0.5rem; }
.landing-example {
  display: inline-block;
  margin: 0.25rem;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text, inherit);
  font-size: 0.88rem;
  cursor: pointer;
}
.landing-example:hover { border-color: var(--primary); color: var(--primary); }

/* ---------- Slim sticky header ---------- */
.slim-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 90;
  background: #0b0c0f;
  color: #eef0f4;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  transform: translateY(-100%);
  transition: transform 0.22s ease;
}
.slim-header.visible { transform: translateY(0); }
.slim-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0.4rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.slim-brand {
  background: none; border: none; color: #fff;
  font-weight: 700; font-size: 0.95rem; letter-spacing: -0.3px; cursor: pointer;
}
.slim-meta { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.slim-chip {
  font-size: 0.72rem; font-weight: 600;
  padding: 0.12rem 0.5rem; border-radius: 999px;
  background: rgba(255,255,255,0.1); color: #e6e8ee;
}
.slim-ver { font-size: 0.7rem; color: #9aa0ac; }

/* ---------- Reference picker cards (proposal forms) ---------- */
.ref-pick-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.ref-pick-hint { font-size: 0.78rem; color: var(--muted); margin-bottom: 0.4rem; }
.ref-pick-list {
  list-style: none; margin: 0; padding: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  max-height: 22rem;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.ref-card { border-bottom: 1px solid var(--border); }
.ref-card:last-child { border-bottom: none; }
.ref-card-main {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.7rem 0.8rem;
  cursor: pointer;
}
.ref-card-main:hover { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.ref-card-input {
  flex: none;
  width: 1.15rem; height: 1.15rem;   /* comfortable tap target */
  margin-top: 0.1rem;
  accent-color: var(--primary);
}
.ref-card-text { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.ref-card-name { font-weight: 600; font-size: 0.9rem; }
.ref-card-id { font-size: 0.72rem; color: var(--muted); font-weight: 500; }
.ref-card-summary { font-size: 0.82rem; color: var(--muted); line-height: 1.45; }
/* Selected card gets a subtle highlight. */
.ref-card:has(.ref-card-input:checked) { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.ref-card:has(.ref-card-input:checked) .ref-card-name { color: var(--primary); }

.ref-card-toggle {
  margin: 0 0.8rem 0.5rem 2.55rem;   /* align under the text, not the checkbox */
  padding: 0.15rem 0.5rem;
  font-size: 0.76rem;
  color: var(--primary);
  background: none;
  border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent);
  border-radius: 999px;
  cursor: pointer;
}
.ref-card-toggle::after { content: " ⌄"; }
.ref-card-toggle.open::after { content: " ⌃"; }
.ref-card-detail {
  margin: 0 0.8rem 0.7rem 2.55rem;
  padding: 0.6rem 0.8rem;
  border-left: 3px solid var(--primary);
  border-radius: 0 8px 8px 0;
  background: color-mix(in srgb, var(--primary) 6%, var(--surface));
  font-size: 0.83rem;
  line-height: 1.5;
}
.ref-card-detail[hidden] { display: none; }
.ref-card-detail p { margin: 0.2rem 0; color: var(--muted); }
.ref-card-detail p b { color: var(--text, inherit); font-weight: 600; }

@media (max-width: 620px) {
  .ref-pick-list { max-height: 18rem; }
  .ref-card-toggle, .ref-card-detail { margin-left: 2.55rem; margin-right: 0.6rem; }
}

/* ---------- Wide-desktop layout ---------- */
/* On large screens, let the working views (diagnostic, library, proposals,
   dashboard, wizard) use more of the screen width, while keeping reading-width
   text blocks comfortable. The landing hero stays centred and narrow. */
@media (min-width: 1400px) {
  main.container { max-width: 1320px; }
  .header-inner, .tabs-inner, .slim-inner { max-width: 1320px; }
  .view-intro p, .landing-lead, .landing-more { max-width: 70ch; }
  .field-edit-row { gap: 2rem; }
}

/* ============================================================
   Responsive / dynamic sizing pass (v0.72)
   Tablet ≤ 768px, phone ≤ 480px. Base layout already uses
   max-width + auto margins and scrollable tabs; these rules
   tighten spacing, stack multi-column areas, and enlarge tap
   targets so the tool works on phones and tablets.
   ============================================================ */
@media (max-width: 768px) {
  header.site-header { padding: 1rem 1.1rem; }
  .header-inner { gap: 0.9rem; }
  .header-controls { gap: 0.7rem; width: 100%; }
  main.container { padding: 1.4rem 0.9rem 3rem; }
  .view-intro { margin-bottom: 1.4rem; }
  .modal-card { padding: 1.5rem 1.2rem; max-height: 92vh; }
  .type-info-btn { top: 0.7rem; right: 2.2rem; }
  /* Editing form + generic two-up grids collapse to one column. */
  .form-grid { grid-template-columns: 1fr; }
  .map-toolbar { gap: 0.6rem; }
  .map-hint { flex-basis: 100%; }
  /* Comfortable tap targets for the main interactive controls. */
  .tab-btn { padding: 0.9rem 0.9rem; }
  button, .form-control, input, select, textarea { font-size: 16px; } /* avoids iOS zoom-on-focus */
  .form-actions button, .result-actions button { min-height: 2.75rem; }
}

@media (max-width: 480px) {
  header.site-header { padding: 0.85rem 0.9rem; }
  .tagline { font-size: 0.78rem; }
  main.container { padding: 1.1rem 0.75rem 2.5rem; }
  .modal-card { padding: 1.25rem 0.95rem; border-radius: 0; max-height: 100vh; height: 100%; }
  .modal-overlay { align-items: stretch; }
  /* Stack action rows full-width for easy tapping. */
  .form-actions, .result-actions { flex-direction: column; align-items: stretch; }
  .form-actions button, .result-actions button { width: 100%; }
  .result-actions .copy-note { text-align: center; }
  .landing-badges { gap: 0.35rem; }
  .landing-cta { width: 100%; }
}

/* Column header cards */
.map-header { cursor: pointer; }
.map-header rect {
  fill: var(--node-color);
  opacity: 0.12;
  stroke: var(--node-color);
  stroke-opacity: 0.4;
  transition: opacity 0.15s;
}
.map-header:hover rect { opacity: 0.2; }
.map-header.open rect { opacity: 0.22; stroke-opacity: 0.7; stroke-width: 1.6; }
.map-header-title { fill: var(--node-color); font-weight: 700; font-size: 13px; }
.map-header-count { fill: var(--node-color); font-weight: 700; font-size: 13px; text-anchor: end; opacity: 0.8; }
.map-header-blurb { fill: var(--muted); font-size: 9.5px; }

/* Nodes */
.map-node { cursor: pointer; }
.map-node rect {
  fill: #fff;
  stroke: var(--node-color);
  stroke-width: 1.5;
  transition: fill 0.15s, opacity 0.15s;
}
.map-node text { fill: var(--text); font-size: 11px; pointer-events: none; }
.map-node:hover rect { fill: color-mix(in srgb, var(--node-color) 14%, #fff); }

/* Edges */
.map-edge {
  fill: none;
  stroke: #b9bccb;
  stroke-width: 1.2;
  opacity: 0.35;
  transition: opacity 0.15s, stroke 0.15s;
}

/* Selection states */
#mapSvg.has-selection .map-node.dim { opacity: 0.18; }
#mapSvg.has-selection .map-edge.dim { opacity: 0.05; }
#mapSvg.has-selection .map-node.hl rect { fill: color-mix(in srgb, var(--node-color) 16%, #fff); }
#mapSvg.has-selection .map-node.selected rect {
  fill: var(--node-color);
  stroke-width: 2.5;
}
#mapSvg.has-selection .map-node.selected text { fill: #fff; font-weight: 700; }
#mapSvg.has-selection .map-edge.hl { stroke: var(--secondary); opacity: 0.85; stroke-width: 1.8; }

/* Search states — independent of selection; matches glow amber, the rest dims. */
#mapSvg.has-search .map-node.dim { opacity: 0.18; }
#mapSvg.has-search .map-edge.dim { opacity: 0.05; }
#mapSvg.has-search .map-node.match rect {
  fill: color-mix(in srgb, var(--warn) 22%, #fff);
  stroke: var(--warn);
  stroke-width: 2.5;
}
#mapSvg.has-search .map-node.match text { font-weight: 700; }
#mapSvg.has-search .map-edge.match { stroke: var(--warn); opacity: 0.85; stroke-width: 1.8; }

/* Explanation panel */
.map-panel { border-top: 1px solid var(--border); padding: 1rem; min-height: 3rem; }
.map-panel-empty { color: var(--muted); font-size: 0.9rem; margin: 0; }
.map-panel-card .meta-tag { margin-bottom: 0.3rem; }
.map-panel-card h4 { margin: 0.3rem 0; }
.map-chips { margin: 0.6rem 0; font-size: 0.85rem; }
.map-chip {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
  background: var(--node-color);
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  margin: 0.15rem 0.25rem 0.15rem 0;
}

/* ---------- Mode toggle + mode-based visibility ---------- */
.header-controls { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.mode-switch {
  display: inline-flex;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 999px;
  overflow: hidden;
}
.mode-btn {
  background: transparent;
  color: #fff;
  border: none;
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  cursor: pointer;
  opacity: 0.8;
}
.mode-btn.active { background: #fff; color: var(--primary); font-weight: 700; opacity: 1; }
/* In Standard mode, hide the Values & Principles group in the Library. */
body.mode-standard .values-principles-group { display: none; }

/* ---------- Inline notice (non-modal info banner, v0.69) ---------- */
.inline-notice {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 0 0 1.2rem;
  padding: 0.85rem 1rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 25%, transparent);
}
.inline-notice[hidden] { display: none; }
.inline-notice-body { font-size: 0.92rem; line-height: 1.5; flex: 1; }
.inline-notice-close {
  flex: none;
  background: none;
  border: none;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  padding: 0 0.2rem;
}
.inline-notice-close:hover { color: var(--text, inherit); }

/* ---------- Welcome screen ---------- */
.welcome-card { max-width: 560px; text-align: center; }
.welcome-logo { width: 64px; height: 64px; margin: 0.5rem auto 0.3rem; display: block; }
.welcome-card h2 { margin: 0.3rem 0; }
.welcome-lead { color: var(--muted); max-width: 46ch; margin: 0.4rem auto 1.2rem; }
.welcome-steps { text-align: left; display: flex; flex-direction: column; gap: 0.8rem; margin: 0 auto 1.4rem; max-width: 30rem; }
.welcome-step { display: flex; gap: 0.8rem; align-items: flex-start; font-size: 0.92rem; }
.welcome-step-num {
  flex: none;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  color: #fff;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.welcome-actions { display: flex; flex-direction: column; align-items: center; gap: 0.7rem; }
#welcomeStart { font-size: 1rem; padding: 0.6rem 1.3rem; }
.welcome-dismiss { font-size: 0.8rem; color: var(--muted); display: flex; align-items: center; gap: 0.35rem; cursor: pointer; }

/* ---------- Landing / Home view (v0.68) ---------- */
.landing { max-width: 100%; margin: 1.5rem auto; text-align: center; }
.landing-hero { max-width: 640px; margin: 0 auto; }
.landing-title {
  margin: 0.4rem 0 0.2rem;
  font-size: clamp(2rem, 5vw, 2.9rem);
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--text, #1a1a2e);
}
.landing-lead { color: var(--muted); max-width: 48ch; margin: 0.4rem auto 1.1rem; }
/* Plain-text edition line (was pill/badge buttons). */
.landing-meta {
  color: var(--muted);
  font-size: 0.9rem;
  margin: 0 auto 1.4rem;
  letter-spacing: 0.01em;
}
/* Learn more is now an inline text link within the edition line. */
.landing-learn { background: none; border: none; color: var(--primary); text-decoration: underline; cursor: pointer; font-size: inherit; padding: 0; }

/* Learn more box: reuses the light-blue .inline-notice look, opens inline. */
.landing-more { text-align: left; max-width: 640px; margin: 0.4rem auto 1.6rem; }
.landing-more .inline-notice-body h3 { margin: 0.9rem 0 0.25rem; font-size: 1rem; }
.landing-more .inline-notice-body h3:first-child { margin-top: 0; }
.landing-more .inline-notice-body p { color: var(--muted); font-size: 0.92rem; margin: 0; }

/* ---------- Four home panels ---------- */
/* The panel grid breaks out wider than the narrow hero column so it uses the
   full working width. 4 across on desktop → 2×2 tablet → 1 column on mobile. */
.home-panels {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.1rem;
  margin: 2rem auto 0;
  width: min(1240px, 96vw);
  text-align: left;
}
.home-panel {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1.2rem 1.25rem 1.3rem;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  box-shadow: 0 2px 12px rgba(20,20,50,0.05);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.home-panel:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 26px rgba(20,20,50,0.1);
  border-color: color-mix(in srgb, var(--primary) 35%, var(--border));
}
.home-panel h2 { margin: 0; font-size: 1.05rem; color: var(--text, #1a1a2e); }
.home-panel > p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; flex: 1; }
.home-panel-btn {
  align-self: flex-start;
  margin-top: 0.5rem;
  padding: 0.55rem 1.05rem;
  font-size: 0.9rem;
}

/* Animated scene at the top of each panel — fixed height so panels stay level. */
.home-scene {
  height: 92px;
  margin: -0.2rem 0 0.3rem;
  color: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
}
.home-scene svg { width: 100%; height: 100%; display: block; }

/* Rotating example pill in the Diagnose panel — FIXED size so it never jumps. */
.home-example {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  height: 2.2rem;
  padding: 0 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 6%, transparent);
  color: var(--text, inherit);
  cursor: pointer;
  overflow: hidden;
  text-align: left;
}
.home-example:hover { border-color: var(--primary); }
.home-example-label { flex: none; font-size: 0.78rem; color: var(--muted); font-weight: 600; }
.home-example-text {
  flex: 1;
  min-width: 0;                 /* allow it to shrink inside the flex row */
  font-size: 0.82rem;           /* JS shrinks this per example so it always fits one line */
  white-space: nowrap;
  overflow: hidden;
  transition: opacity 0.35s ease;
}
.home-example-text.fading { opacity: 0; }

@media (max-width: 1080px) {
  .home-panels { grid-template-columns: repeat(2, minmax(0, 1fr)); width: min(760px, 94vw); }
}
@media (max-width: 620px) {
  .home-panels { grid-template-columns: minmax(0, 1fr); width: min(440px, 92vw); }
}

/* ================= Panel scene animations =================
 * v1.10 — HOVER-ONLY. Previously all four landing scenes ran `infinite`
 * animations simultaneously and permanently, which Karin flagged in the 22 July
 * call as visual noise competing with the four entry points for attention.
 * Now the default paint is a readable STATIC frame, and motion only runs while a
 * panel is hovered or keyboard-focused (:focus-within keeps it reachable for
 * keyboard users, not just mouse). Everything is still inside the
 * prefers-reduced-motion guard, so motion-sensitive visitors get nothing at all.
 * If this needs reverting, the change is purely in the selectors below —
 * drop the `.home-panel:hover/:focus-within` prefixes and restore the two
 * `opacity` defaults marked "static frame". */
@media (prefers-reduced-motion: no-preference) {

  /* 1. Diagnose — signal rings pulse outward, magnifier drifts in. */
  .scene-diagnose .dg-ring { fill: none; stroke: currentColor; stroke-width: 2; opacity: 0.4; } /* static frame */
  .scene-diagnose .dg-node { fill: currentColor; }
  .scene-diagnose .dg-glass { color: var(--secondary); }
  @keyframes dgPulse { 0% { opacity: 0; transform: scale(0.5); } 30% { opacity: 0.6; } 100% { opacity: 0; transform: scale(1.15); } }
  .scene-diagnose .dg-ring { transform-box: fill-box; transform-origin: center; }
  .home-panel:hover .scene-diagnose .dg-ring,
  .home-panel:focus-within .scene-diagnose .dg-ring { animation: dgPulse 3.2s ease-out infinite; }
  .scene-diagnose .dg-ring2 { animation-delay: 0.5s; }
  .scene-diagnose .dg-ring3 { animation-delay: 1s; }
  @keyframes dgGlass { 0%,100% { transform: translate(0,0); } 50% { transform: translate(-3px,-3px); } }
  .home-panel:hover .scene-diagnose .dg-glass,
  .home-panel:focus-within .scene-diagnose .dg-glass { animation: dgGlass 4s ease-in-out infinite; }

  /* 2. Browse — the network map cross-fades with a list, back and forth. */
  .scene-browse .br-map rect { fill: color-mix(in srgb, var(--primary) 18%, transparent); stroke: var(--primary); stroke-width: 1.5; }
  .scene-browse .br-link { stroke: var(--primary); stroke-width: 1.5; opacity: 0.6; }
  .scene-browse .br-list rect { fill: color-mix(in srgb, var(--secondary) 16%, transparent); stroke: var(--secondary); stroke-width: 1.2; }
  .scene-browse .br-list { opacity: 0; } /* static frame: the map, not the list */
  @keyframes brMapCycle  { 0%,42% { opacity: 1; } 50%,92% { opacity: 0; } 100% { opacity: 1; } }
  @keyframes brListCycle { 0%,42% { opacity: 0; } 50%,92% { opacity: 1; } 100% { opacity: 0; } }
  .home-panel:hover .scene-browse .br-map,
  .home-panel:focus-within .scene-browse .br-map  { animation: brMapCycle 6s ease-in-out infinite; }
  .home-panel:hover .scene-browse .br-list,
  .home-panel:focus-within .scene-browse .br-list { animation: brListCycle 6s ease-in-out infinite; }

  /* 3. Concepts — open book, pages flick over one at a time. */
  .scene-concepts .bk-cover { fill: color-mix(in srgb, var(--primary) 14%, transparent); stroke: var(--primary); stroke-width: 2; }
  .scene-concepts .bk-spine { stroke: var(--primary); stroke-width: 2; }
  .scene-concepts .bk-text { stroke: var(--muted); stroke-width: 2; stroke-linecap: round; }
  .scene-concepts .bk-page { fill: #fff; stroke: var(--primary); stroke-width: 1; transform-box: fill-box; transform-origin: left center; }
  @keyframes bkFlip { 0% { transform: scaleX(1); opacity: 1; } 45% { transform: scaleX(-0.15); opacity: 0.5; } 90%,100% { transform: scaleX(1); opacity: 1; } }
  .home-panel:hover .scene-concepts .bk-page1,
  .home-panel:focus-within .scene-concepts .bk-page1 { animation: bkFlip 4.5s ease-in-out infinite; }
  .home-panel:hover .scene-concepts .bk-page2,
  .home-panel:focus-within .scene-concepts .bk-page2 { animation: bkFlip 4.5s ease-in-out infinite 1.5s; }
  .home-panel:hover .scene-concepts .bk-page3,
  .home-panel:focus-within .scene-concepts .bk-page3 { animation: bkFlip 4.5s ease-in-out infinite 3s; }

  /* 4. Propose — bulb glows, then bulb fades and the wordmark rises in its place. */
  .scene-propose .pr-bulb { color: var(--primary); transform-box: fill-box; transform-origin: center; }
  .scene-propose .pr-rays line { stroke: var(--secondary); stroke-width: 2.5; stroke-linecap: round; }
  .scene-propose .pr-word { fill: var(--primary); font-family: "Segoe UI", system-ui, sans-serif; font-weight: 800; font-size: 13px; letter-spacing: -0.5px; opacity: 0; }
  @keyframes prBulb { 0%,35% { opacity: 1; transform: translateY(0) scale(1); } 55%,88% { opacity: 0; transform: translateY(-4px) scale(0.9); } 100% { opacity: 1; transform: translateY(0) scale(1); } }
  @keyframes prRays { 0%,20% { opacity: 0; } 30% { opacity: 1; } 40%,100% { opacity: 0; } }
  @keyframes prWord { 0%,45% { opacity: 0; transform: translateY(6px); } 60%,85% { opacity: 1; transform: translateY(0); } 95%,100% { opacity: 0; } }
  .scene-propose .pr-word { transform-box: fill-box; transform-origin: center; }
  .home-panel:hover .scene-propose .pr-bulb,
  .home-panel:focus-within .scene-propose .pr-bulb { animation: prBulb 5s ease-in-out infinite; }
  .home-panel:hover .scene-propose .pr-rays,
  .home-panel:focus-within .scene-propose .pr-rays { animation: prRays 5s ease-in-out infinite; }
  .home-panel:hover .scene-propose .pr-word,
  .home-panel:focus-within .scene-propose .pr-word { animation: prWord 5s ease-in-out infinite; }
}

/* Reduced-motion / no-JS: show a sensible static frame. */
@media (prefers-reduced-motion: reduce) {
  .scene-diagnose .dg-ring { fill: none; stroke: currentColor; stroke-width: 2; opacity: 0.4; }
  .scene-diagnose .dg-node { fill: currentColor; }
  .scene-diagnose .dg-glass { color: var(--secondary); }
  .scene-browse .br-list { opacity: 0; }
  .scene-browse .br-map rect { fill: color-mix(in srgb, var(--primary) 18%, transparent); stroke: var(--primary); stroke-width: 1.5; }
  .scene-browse .br-link { stroke: var(--primary); stroke-width: 1.5; opacity: 0.6; }
  .scene-concepts .bk-cover { fill: color-mix(in srgb, var(--primary) 14%, transparent); stroke: var(--primary); stroke-width: 2; }
  .scene-concepts .bk-spine, .scene-concepts .bk-page { stroke: var(--primary); }
  .scene-concepts .bk-page { fill: #fff; }
  .scene-concepts .bk-text { stroke: var(--muted); stroke-width: 2; }
  .scene-propose .pr-bulb { color: var(--primary); }
  .scene-propose .pr-word { opacity: 0; }
}

/* ---------- Explainers: type ⓘ on detail modals, map ⓘ, relationship arrows ---------- */
.type-info-btn {
  position: absolute;
  top: 0.9rem;
  right: 2.6rem;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: #f4f5fb;
  color: var(--primary);
  font-size: 0.95rem;
  cursor: pointer;
  line-height: 1;
  z-index: 2;
}
.type-info-btn:hover, .type-info-btn.open { background: var(--primary); color: #fff; }

/* Inline help panel revealed by the ⓘ inside a detail modal (v0.71) — replaces
   the old modal-swap so the definition sits alongside the content. */
.type-info-panel {
  margin: 0 0 1rem;
  padding: 0.8rem 1rem;
  border-left: 3px solid var(--primary);
  border-radius: 0 8px 8px 0;
  background: color-mix(in srgb, var(--primary) 7%, transparent);
  text-align: left;
}
.type-info-panel[hidden] { display: none; }
.type-info-panel h4 { margin: 0 0 0.3rem; font-size: 0.95rem; }
.type-info-panel p { margin: 0; line-height: 1.6; font-size: 0.9rem; color: var(--muted); }

.explainer-modal { text-align: left; }
.explainer-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  color: #fff;
  font-size: 1.2rem;
  margin-bottom: 0.4rem;
}
.explainer-modal h3 { margin: 0.2rem 0 0.5rem; }
.explainer-modal p { line-height: 1.6; }

/* Map header ⓘ */
.map-info { fill: #fff; stroke: var(--node-color); stroke-width: 1.3; cursor: pointer; }
.map-info-i { fill: var(--node-color); font-size: 11px; font-weight: 700; font-style: italic; text-anchor: middle; cursor: pointer; pointer-events: none; }
.map-header:hover .map-info { fill: color-mix(in srgb, var(--node-color) 18%, #fff); }

/* Relationship arrows + ⓘ */
.map-rel { cursor: pointer; }
.map-rel-line { stroke: #9aa0b4; stroke-width: 1.6; }
.map-rel-arrowhead { fill: #9aa0b4; }
.map-rel-info { fill: #fff; stroke: var(--secondary); stroke-width: 1.4; transition: fill 0.15s; }
.map-rel-i { fill: var(--secondary); font-size: 12px; font-weight: 700; font-style: italic; text-anchor: middle; pointer-events: none; }
.map-rel:hover .map-rel-info { fill: color-mix(in srgb, var(--secondary) 16%, #fff); }
.map-rel:hover .map-rel-line, .map-rel:hover .map-rel-arrowhead { stroke: var(--secondary); fill: var(--secondary); }

/* ---------- Diagnostic mode choice + guided wizard ---------- */
.wizard-choice h3, .wizard-root h3 { margin-top: 0; color: var(--text); }
.wizard-sub { color: var(--muted); font-size: 0.92rem; }
.wizard-choice-cards { display: flex; gap: 1rem; margin-top: 1rem; flex-wrap: wrap; }
.wizard-choice-card {
  flex: 1 1 220px;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
.wizard-choice-card:hover { border-color: var(--primary); box-shadow: 0 2px 10px rgba(69,39,160,0.1); }
.wcc-title { font-weight: 700; font-size: 1rem; }
.wcc-desc { font-size: 0.85rem; color: var(--muted); }

.wizard-progress { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
.wp-dot { font-size: 0.72rem; color: var(--muted); background: #eef0f4; padding: 0.2rem 0.6rem; border-radius: 999px; }
.wp-dot.active { background: var(--primary); color: #fff; font-weight: 700; }
.wp-dot.done { background: #d7ecdb; color: #2e7d32; }

/* ---------- The guided surface (v0.70; folded into the workspace v1.57) ----------
 * .wizard-shell / .wizard-topbar / .wizard-exit / .wp-step belonged to
 * view-wizard, which no longer exists: the guided depth is #dp-guided inside
 * the diagnostic workspace and wears the shared station bar. The rules are
 * kept because .wizard-body still carries the padding, and because a rule with
 * no markup costs a selector match and nothing else — but nothing new should
 * reach for them. */
.wizard-shell {
  max-width: 760px;
  margin: 0 auto;
  background: var(--card, #fff);
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 12px;
  box-shadow: 0 6px 24px rgba(20, 20, 50, 0.06);
  overflow: hidden;
}
.wizard-topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.8rem 1.1rem;
  border-bottom: 1px solid var(--border, #e3e6ec);
  background: color-mix(in srgb, var(--primary) 5%, transparent);
}
.wizard-exit {
  flex: none;
  background: none;
  border: 1px solid var(--border, #d5d9e0);
  border-radius: 6px;
  padding: 0.35rem 0.7rem;
  font-size: 0.85rem;
  color: var(--muted);
  cursor: pointer;
}
.wizard-exit:hover { border-color: var(--primary); color: var(--primary); }
.wizard-steps-header {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-wrap: wrap;
  flex: 1;
}
.wp-step {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: none;
  padding: 0.25rem 0.4rem;
  border-radius: 6px;
  font-size: 0.82rem;
  color: var(--muted);
  cursor: pointer;
}
.wp-step .wp-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  background: #eef0f4;
  font-weight: 700;
  font-size: 0.78rem;
}
.wp-step.done .wp-num { background: #d7ecdb; color: #2e7d32; }
.wp-step.active { color: var(--text, inherit); font-weight: 700; }
.wp-step.active .wp-num { background: var(--primary); color: #fff; }
.wp-step.reachable:not(.active):hover { color: var(--primary); }
.wp-step.reachable:not(.active):hover .wp-num { background: color-mix(in srgb, var(--primary) 20%, #eef0f4); }
.wp-step.disabled { opacity: 0.45; cursor: default; }
.wp-step:disabled { cursor: default; }
.wp-sep { color: var(--muted); opacity: 0.5; font-size: 0.9rem; }
.wizard-body { padding: 1.4rem 1.3rem 1.6rem; }
.wizard-qcount { display: inline-block; font-size: 0.78rem; color: var(--muted); margin-left: 0.4rem; opacity: 0.8; }
.wizard-actions-final { justify-content: space-between; }

/* Responsive: collapse step labels on narrow screens so the header still fits. */
@media (max-width: 640px) {
  .wizard-shell { border-radius: 0; border-left: none; border-right: none; }
  .wizard-body { padding: 1.1rem 0.9rem 1.3rem; }
  .wp-step .wp-label { display: none; }
  .wizard-actions { justify-content: stretch; }
  .wizard-actions button { flex: 1; }
  .wizard-actions-final { flex-wrap: wrap; }
}

.wizard-picks, .wizard-opts { display: flex; flex-direction: column; gap: 0.6rem; margin: 1rem 0; }
.wizard-pick {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  text-align: left;
  padding: 0.8rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
.wizard-pick:hover { border-color: var(--primary); background: rgba(69,39,160,0.04); }
.wizard-pick-num {
  flex: none; width: 1.9rem; height: 1.9rem; border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), var(--secondary)); color: #fff;
  font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.wizard-pick-body { display: flex; flex-direction: column; gap: 0.2rem; }
.wizard-pick-name { font-weight: 700; }
.wizard-pick-desc { font-size: 0.88rem; color: var(--muted); }

.wizard-opt {
  text-align: left;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  font-size: 0.95rem;
}
.wizard-opt:hover { border-color: var(--primary); background: rgba(69,39,160,0.04); }

.wizard-signs { margin: 0.8rem 0; }
.wizard-signs h4 { margin: 0.6rem 0 0.3rem; font-size: 0.9rem; }
.wizard-check { display: flex; gap: 0.5rem; align-items: flex-start; padding: 0.3rem 0; font-size: 0.9rem; cursor: pointer; }

.wizard-actions { display: flex; gap: 0.6rem; justify-content: flex-end; margin-top: 1.2rem; flex-wrap: wrap; }
.wizard-note { margin-top: 0.8rem; }

/* REPAIRED v1.13 — this rule was truncated mid-declaration ("border-ra") by a
 * bad file write in an earlier session, leaving the block unclosed. Because CSS
 * supports nesting, every rule between here and the next stray "}" (~250 lines
 * later) was being parsed as a DESCENDANT of .wizard-reco — so .wizard-opt.selected
 * effectively meant ".wizard-reco .wizard-opt.selected" and could never match.
 * That is why three rounds of restyling the wizard selection had no visible
 * effect, while the questionnaire's equivalent rule (defined earlier in the file,
 * above the damage) worked fine. The sphere badges and the result-protocol styles
 * were silently dead for the same reason. */
.wizard-reco {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  padding: 0.8rem 0.9rem;
  margin: 0.7rem 0;
}
.wizard-reco-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.3rem; }
.wizard-reco-trial { font-size: 0.9rem; margin: 0.45rem 0 0; }

/* --------------------------- Sphere of influence --------------------------- */
.sphere-switch { margin-left: 0.4rem; }

.sphere-badge {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  line-height: 1.4;
  margin: 0.25rem 0;
}
.sphere-ok { background: rgba(46,125,50,0.12); color: var(--accent); }
.sphere-out { background: rgba(183,121,31,0.14); color: var(--warn); }

.sphere-gap { margin: 0.3rem 0 0.4rem; }
.sphere-move {
  font-size: 0.85rem;
  margin: 0.2rem 0 0;
  padding: 0.45rem 0.6rem;
  background: #fff8e6;
  border: 1px solid #f0e2b8;
  border-radius: 8px;
}

/* ---------- Wizard selection state (v1.12 — made unmistakable) ----------
 * History: the original .selected differed from :hover by 4% background alpha.
 * v1.10 raised that to a 12% tint plus a left rail; still reported as invisible
 * on the Context step. The lesson is that a *tint* is the wrong instrument —
 * on a light surface it reads as a hover artefact, not as a commitment.
 *
 * v1.12 inverts instead: a chosen option becomes a solid filled block in the
 * brand colour with white text and a circled tick. There is no reading of that
 * as "hover". Four independent cues carry it — fill inversion, the tick badge,
 * bold weight, and elevation — so it survives greyscale, colour-vision
 * differences, and a mouse still resting on the button. */

.wizard-opt.selected {
  background: var(--secondary);
  border-color: var(--secondary);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 2px 10px rgba(69,39,160,0.35);
  padding-right: 2.6rem; /* room for the tick badge */
  position: relative;
}
/* Hover must not mask or compete with the selection. */
.wizard-opt.selected:hover {
  background: #3a1f8f;
  border-color: #3a1f8f;
  color: #fff;
}
.wizard-opt.selected::after {
  content: "✓";
  position: absolute;
  right: 0.7rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  background: #fff;
  color: var(--secondary);
  font-weight: 900;
  font-size: 0.85rem;
  line-height: 1.35rem;
  text-align: center;
}

/* Pattern picks carry a muted description line, so inverting the whole card
 * would hurt readability. They get the strong-tint treatment instead: a heavy
 * rail, a filled number badge and the same tick. */
.wizard-pick.selected {
  border-color: var(--secondary);
  border-left: 6px solid var(--secondary);
  background: color-mix(in srgb, var(--secondary) 14%, var(--surface));
  box-shadow: 0 2px 10px rgba(69,39,160,0.22);
  position: relative;
  padding-right: 2.6rem;
}
.wizard-pick.selected:hover {
  background: color-mix(in srgb, var(--secondary) 18%, var(--surface));
  border-color: var(--secondary);
}
.wizard-pick.selected .wizard-pick-name { color: var(--secondary); }
.wizard-pick.selected .wizard-pick-num { background: var(--secondary); color: #fff; }
.wizard-pick.selected::after {
  content: "✓";
  position: absolute;
  right: 0.7rem;
  top: 0.8rem;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  background: var(--secondary);
  color: #fff;
  font-weight: 900;
  font-size: 0.85rem;
  line-height: 1.35rem;
  text-align: center;
}

/* ---------- Shared result protocol (v1.12) ----------
 * Rendered identically by the wizard's final step and by the questionnaire's
 * "See your full result" button, and mirrored section-for-section by the
 * printable PDF — so what's on screen is what comes out of the printer. */
.result-protocol { margin-top: 0.4rem; }
.rp-head h3 { margin: 0 0 0.2rem; color: var(--secondary); }

.rp-step {
  border-top: 1px solid var(--border);
  padding: 0.9rem 0 0.2rem;
}
.rp-step:first-of-type { border-top: none; }
.rp-step h4 {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 0.45rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--secondary);
}
.rp-n {
  display: inline-block;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  background: var(--secondary);
  color: #fff;
  text-align: center;
  line-height: 1.4rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0;
  flex: none;
}

.rp-quote {
  border-left: 3px solid var(--border);
  padding: 0.25rem 0 0.25rem 0.8rem;
  color: var(--muted);
  font-style: italic;
  margin: 0.3rem 0;
}
.rp-interp { font-size: 0.9rem; margin: 0.4rem 0 0; }
.rp-pattern { font-size: 1.1rem; font-weight: 700; margin: 0.1rem 0 0.3rem; }
.rp-id {
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  background: var(--secondary);
  color: #fff;
  border-radius: 999px;
  padding: 0.08rem 0.45rem;
  vertical-align: middle;
  font-weight: 600;
}
.rp-cands { list-style: none; padding-left: 0; margin: 0.3rem 0; }
.rp-cands li { padding: 0.3rem 0; border-bottom: 1px dotted var(--border); font-size: 0.92rem; }
.rp-cands li.chosen { font-weight: 700; }
.rp-pill {
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  font-size: 0.66rem;
  padding: 0.05rem 0.45rem;
  margin-left: 0.3rem;
  letter-spacing: 0.04em;
}
.rp-vlabel { font-size: 0.82rem; font-weight: 600; color: var(--muted); margin: 0.5rem 0 0.1rem; }

.rp-ctx { width: 100%; border-collapse: collapse; }
.rp-ctx th {
  text-align: left;
  width: 40%;
  padding: 0.35rem 0.8rem 0.35rem 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.rp-ctx td { padding: 0.35rem 0; font-size: 0.9rem; border-bottom: 1px solid var(--border); }

.rp-reco {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  margin: 0.6rem 0;
  background: var(--surface);
}
.rp-reco.top { border-color: var(--secondary); box-shadow: 0 1px 8px rgba(69,39,160,0.12); }
.rp-reco-head { display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.3rem; }
.rp-rank {
  background: var(--secondary);
  color: #fff;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  text-align: center;
  line-height: 1.5rem;
  font-size: 0.8rem;
  font-weight: 700;
  flex: none;
}
.rp-reco-head b { flex: 1; }
.rp-tera-row {
  display: grid;
  grid-template-columns: 5rem 1fr;
  gap: 0.6rem;
  padding: 0.25rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
}
.rp-tera-row b {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--secondary);
}
@media (max-width: 560px) {
  .rp-tera-row { grid-template-columns: 1fr; gap: 0.1rem; }
}

.rp-caveat {
  background: #f7f6fd;
  border-left: 4px solid var(--secondary);
  border-radius: 0 8px 8px 0;
  padding: 0.7rem 0.9rem;
  margin: 1.2rem 0 0;
  font-size: 0.9rem;
}

/* ---------- Fit bands + reachability groups (v1.14) ----------
 * Replaces the raw "Fit score 8" integer. 31 of 32 fit matrices are drafted and
 * 57 of 58 patterns are unreviewed, so a precise number claimed a confidence the
 * data doesn't have. Bands are computed relative to the candidate set, which is
 * the comparison a user actually wants. */
.fit-band {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 0.12rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
}
.fit-strong { background: #e6f4ea; color: #1e6b30; border: 1px solid #b6ddc2; }
.fit-possible { background: #eef0fb; color: var(--secondary); border: 1px solid #cdd2f0; }
.fit-weak { background: #f3f4f6; color: var(--muted); border: 1px solid var(--border); }

.reco-group { margin-top: 1.2rem; }
.reco-group-title {
  margin: 0 0 0.2rem;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--secondary);
  padding-bottom: 0.3rem;
  border-bottom: 2px solid var(--border);
}
.fit-note {
  margin-top: 1rem;
  font-size: 0.8rem;
  color: var(--muted);
  font-style: italic;
}

/* Context echo in the questionnaire's summary card. */
.csc-list { list-style: none; padding-left: 0; margin: 0.4rem 0 0; }
.csc-list li { padding: 0.2rem 0; font-size: 0.9rem; border-bottom: 1px dotted var(--border); }
.csc-q {
  display: inline-block;
  min-width: 11rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}
@media (max-width: 560px) { .csc-q { display: block; min-width: 0; } }

/* ---------- Take-away bar (v1.13) ----------
 * One primary action; alternates as quiet text. See the note in app.js — the
 * previous version presented six equally-weighted buttons at the end of the
 * flow, which made "what do I do now?" harder than the diagnosis. */
.rp-takeaway {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1.1rem;
  margin-top: 1.4rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(120deg, #f7f6fd, var(--surface) 70%);
}
.rp-takeaway-copy { flex: 1 1 15rem; display: flex; flex-direction: column; gap: 0.15rem; }
.rp-takeaway-copy b { color: var(--secondary); }
.rp-takeaway-copy span { font-size: 0.85rem; color: var(--muted); line-height: 1.45; }
.rp-takeaway .rp-download {
  font-size: 1rem;
  padding: 0.6rem 1.3rem;
  font-weight: 600;
  white-space: nowrap;
}
.rp-alt {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
}
.rp-alt-sep { color: var(--border); }

/* Quiet, link-styled buttons — used for the alternates and for wizard
   navigation, so neither competes with the primary action. */
.linkish {
  background: none;
  border: none;
  padding: 0.15rem 0.1rem;
  margin: 0;
  color: var(--muted);
  font: inherit;
  font-size: 0.85rem;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  box-shadow: none;
}
.linkish:hover { color: var(--secondary); }
.linkish:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; border-radius: 3px; }

.wizard-nav-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1.3rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

/* ---------- Wizard option label + explanation (v1.13) ----------
 * Each choice now carries a concrete example under the label, because these
 * answers feed the Fit Score directly and a guessed answer produces a
 * confidently wrong recommendation. */
.wizard-opt { display: flex; flex-direction: column; gap: 0.15rem; }
.wo-label { font-weight: 600; }
.wo-desc { font-size: 0.84rem; color: var(--muted); line-height: 1.45; }
.wizard-opt.selected .wo-desc { color: rgba(255,255,255,0.85); }
.wizard-opt.selected .wo-label { color: #fff; }

.wizard-answered {
  margin-top: 1rem;
  padding-top: 0.7rem;
  border-top: 1px dashed var(--border);
}
.wc-q {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  font-weight: 600;
}

/* A running echo of what's been chosen, so the answer stays visible after the
 * step advances rather than vanishing with the question. */
.wizard-chosen {
  margin: 0.45rem 0 0;
  font-size: 0.86rem;
  color: var(--secondary);
  font-weight: 600;
  padding-left: 1.1rem;
  position: relative;
}
.wizard-chosen::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0.95rem;
  color: var(--accent);
}

/* Validation-step checkboxes had no selected treatment at all. :has() keeps this
 * pure CSS — no JS wiring needed, and it degrades to the plain row on browsers
 * without :has() support rather than breaking. */
.wizard-check:has(input:checked) {
  background: color-mix(in srgb, var(--secondary) 12%, var(--surface));
  border-radius: 8px;
  font-weight: 600;
  color: var(--secondary);
  padding-left: 0.45rem;
  padding-right: 0.45rem;
  box-shadow: inset 4px 0 0 var(--secondary);
}
/* REPAIRED v1.13 — second truncation from the same bad write: this rule lost its
 * selector and first line, leaving an orphan "var(--muted);" at top level and a
 * stray "}" that silently closed the broken .wizard-reco block above. Restored
 * from its usage in app.js (centralEditRows → .central-current). */
.central-current {
  font-size: 0.85rem;
  color: var(--muted);
  background: #f7f7fb;
  border-radius: 6px;
  padding: 0.3rem 0.5rem;
  margin-bottom: 0.3rem;
}
.central-edit {
  width: 100%;
  box-sizing: border-box;
  font-size: 0.9rem;
  padding: 0.45rem 0.6rem;
  line-height: 1.4;
  resize: vertical;
}
.edited-flag {
  color: #8a5a00;
  background: #fff4e5;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.72rem;
}
.history-card {
  border: 1px solid var(--border);
  border-left: 4px solid var(--muted);
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
  margin-bottom: 0.7rem;
}
.history-card.accepted { border-left-color: #2e7d32; }
.history-card.rejected { border-left-color: #c0392b; }
.history-head { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.history-text {
  white-space: pre-wrap;
  background: #f4f4f7;
  padding: 0.6rem;
  border-radius: 6px;
  font-size: 0.82rem;
  margin: 0.5rem 0 0;
}
.status-pill.accepted { background: #e6f4ea; color: #2e7d32; }
.status-pill.rejected { background: #fdecea; color: #c0392b; }

/* ---------- Contact us ---------- */
.footer-contact-btn {
  background: none; border: none; padding: 0;
  color: inherit; text-decoration: underline; cursor: pointer;
  font-size: inherit; font-family: inherit;
}
.footer-contact-btn:hover { color: var(--primary); }
.contact-card { max-width: 480px; text-align: left; }
.contact-sub { color: var(--muted); font-size: 0.9rem; margin: 0 0 1rem; }
.contact-count { text-align: right; font-size: 0.75rem; color: var(--muted); margin-top: 0.2rem; }
/* Honeypot — visually and from-AT hidden, but still in the DOM for bots. */
.contact-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- Load .imp row ---------- */
.imp-load-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  padding: 0.6rem 0.8rem;
  margin-bottom: 1rem;
  border: 1px dashed var(--border);
  border-radius: 10px;
  background: color-mix(in srgb, var(--primary) 4%, transparent);
}
.imp-load-label { font-size: 0.85rem; color: var(--muted); }

/* ---------- Full entity overview (review + print share the structure) ---------- */
.entity-overview {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.2rem;
  background: var(--surface);
  margin: 0.4rem 0 0.8rem;
}
.ov-heading { margin: 0 0 0.2rem; font-size: 1.05rem; }
.ov-legend { margin: 0 0 0.8rem; font-size: 0.8rem; color: var(--muted); }
.ov-table { width: 100%; border-collapse: collapse; }
.ov-table th {
  text-align: left; vertical-align: top; width: 32%;
  padding: 0.5rem 0.8rem 0.5rem 0;
  color: var(--muted); font-weight: 600; font-size: 0.86rem;
  border-bottom: 1px solid var(--border);
}
.ov-table td {
  padding: 0.5rem 0; vertical-align: top;
  font-size: 0.9rem; line-height: 1.5;
  border-bottom: 1px solid var(--border);
}
.ov-row-changed th, .ov-row-changed td { background: #fff8e6; }
.ov-old { color: #a03530; text-decoration: line-through; }
.ov-new { color: #1e7d40; font-weight: 600; }
.ov-arrow { color: var(--muted); }
.ov-same { color: var(--text, inherit); }
.ov-empty { color: var(--muted); font-style: italic; }
.ov-notes { margin-top: 0.9rem; padding-top: 0.6rem; border-top: 1px solid var(--border); }
.ov-notes h5 { margin: 0 0 0.2rem; font-size: 0.9rem; }
.ov-notes p { margin: 0; color: var(--muted); font-size: 0.88rem; }

/* ---------- Proposal review & thank-you ---------- */
.proposal-review { max-width: 720px; }
.review-lead { color: var(--muted); font-size: 0.9rem; margin: 0 0 1rem; }
.review-notes { margin: 0.6rem 0 0; font-size: 0.9rem; }
.review-meta { color: var(--muted); font-size: 0.8rem; margin: 0.6rem 0 0; }
.review-actions { justify-content: space-between; margin-top: 1.2rem; }
.excluded { opacity: 0.5; }
.ref-card.excluded .ref-card-name::after { content: " (primary)"; font-size: 0.72rem; color: var(--muted); font-weight: 500; }

.proposal-thankyou { max-width: 560px; margin: 1rem auto; text-align: center; }
.thankyou-check {
  width: 3rem; height: 3rem; margin: 0 auto 0.6rem;
  border-radius: 50%;
  background: #e7f6ec; color: #1e7d40;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.6rem; font-weight: 700;
}
.proposal-thankyou h3 { margin: 0.2rem 0; }
.proposal-thankyou p { color: var(--muted); }
.proposal-thankyou .form-actions { justify-content: center; margin-top: 1.2rem; }
@media (max-width: 620px) {
  .review-actions, .proposal-thankyou .form-actions { flex-direction: column; }
  .review-actions button, .proposal-thankyou .form-actions button { width: 100%; }
}

/* ---------- Proposal / dashboard list ---------- */
.proposal-card {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  padding: 1.1rem 1.3rem;
  margin-bottom: 1rem;
}
.proposal-card .top-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
}
.status-pill {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-weight: 600;
}
.status-pill.pending { background: rgba(183,121,31,0.14); color: var(--warn); }
.status-pill.merged { background: rgba(46,125,50,0.14); color: var(--accent); }
.status-pill.rejected { background: rgba(183,28,28,0.14); color: var(--danger); }
.status-pill.published { background: rgba(21,101,192,0.14); color: var(--primary); }

#publishStatus { margin-top: 0.8rem; }
.publish-success { color: var(--accent); font-weight: 600; }
.publish-error { color: var(--danger); font-weight: 600; }

.diff-view {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: 0.8rem;
  font-size: 0.85rem;
}
.diff-view > div { background: #f2f4f7; border-radius: 6px; padding: 0.7rem 0.9rem; }
.diff-view .proposed { background: #eef7ee; }
.diff-view h6 { margin: 0 0 0.4rem; font-size: 0.72rem; text-transform: uppercase; color: var(--muted); }
.diff-view.single-col { grid-template-columns: 1fr; }

.empty-state {
  text-align: center;
  color: var(--muted);
  padding: 3rem 1rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}

.role-gate {
  text-align: center;
  color: var(--muted);
  padding: 3rem 1rem;
}

.badge-count {
  background: var(--danger);
  color: white;
  border-radius: 999px;
  font-size: 0.68rem;
  padding: 0.05rem 0.4rem;
  margin-left: 0.3rem;
}

/* ---------- Site footer (v1.10 — dark, carries the CC licence) ----------
 * Agreed in the 22 July call: a site-wide black footer holding the CC BY-NC-ND
 * notice. Dark is deliberate — the licence needs to read as a boundary of the
 * site, not as another piece of body copy. */
footer.site-footer {
  margin-top: 3rem;
  padding: 1.3rem 1rem 1.2rem;
  background: #14161a;
  color: #b9bec6;
  font-size: 0.82rem;
  text-align: center;
  border-top: 3px solid var(--secondary);
}
footer.site-footer .footer-inner { max-width: 940px; margin: 0 auto; }
footer.site-footer .footer-line { margin: 0.3rem 0; line-height: 1.5; }
footer.site-footer b { color: #e8eaee; font-weight: 600; }

footer.site-footer .footer-licence { color: #d3d7dd; }

/* One flowing row of links on desktop; wraps naturally on narrow screens
   instead of forcing a stack of separate lines. */
footer.site-footer .footer-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.35rem 0.9rem;
  margin-top: 0.55rem;
  padding-top: 0.55rem;
  border-top: 1px solid rgba(255,255,255,0.12);
  font-size: 0.78rem;
}
footer.site-footer .footer-tag { color: #7d838c; }

/* CC icon strip — inverted so the black glyphs read on the dark background. */
footer.site-footer .cc-icons { display: inline-flex; align-items: center; }
footer.site-footer .cc-icons img {
  max-width: 1em;
  max-height: 1em;
  margin-left: 0.2em;
  filter: invert(1);
  opacity: 0.85;
  vertical-align: text-bottom;
}

footer.site-footer .footer-link,
footer.site-footer .footer-contact-btn {
  color: #d3d7dd;
  text-decoration: underline;
  text-underline-offset: 2px;
}
footer.site-footer .footer-link:hover,
footer.site-footer .footer-contact-btn:hover { color: #fff; }
footer.site-footer .footer-link:focus-visible,
footer.site-footer .footer-contact-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* ---------- "Living community edition" chip (v1.11) ----------
 * Deliberately NOT a WIP banner. Andy's point was that "1.0.9" plus visible
 * content holes reads as unprofessional; the fix agreed was framing, not
 * hiding the version. This sits next to the version badge and says the gaps
 * are the model, not an accident. */
.edition-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  background: rgba(255,255,255,0.16);
  border: 1px solid rgba(255,255,255,0.28);
  color: #fff;
  white-space: nowrap;
  cursor: help;
}
@media (max-width: 640px) { .edition-badge { display: none; } }

/* ---------- Legal & Transparency view (v1.11) ---------- */
.legal-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 1.4rem;
}
.legal-jump a {
  font-size: 0.82rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--secondary);
  text-decoration: none;
}
.legal-jump a:hover { border-color: var(--secondary); background: color-mix(in srgb, var(--secondary) 8%, var(--surface)); }

.legal-body { max-width: 760px; }
.legal-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.3rem 1.4rem;
  margin-bottom: 1.1rem;
  scroll-margin-top: 5rem;
}
.legal-block h3 {
  margin: 0 0 0.8rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--secondary);
  color: var(--secondary);
}
.legal-block h4 { margin: 1.2rem 0 0.3rem; font-size: 0.95rem; color: var(--text); }
.legal-block p { margin: 0.5rem 0; font-size: 0.92rem; }
.legal-block ul { margin: 0.5rem 0; padding-left: 1.2rem; font-size: 0.92rem; }
.legal-block li { margin: 0.3rem 0; }
.legal-a { color: var(--primary); }
.legal-note {
  font-size: 0.86rem !important;
  color: var(--muted);
  border-left: 3px solid var(--border);
  padding-left: 0.7rem;
}
.legal-updated { font-size: 0.8rem; color: var(--muted); text-align: right; }

/* ---------- Propose-a-change step-by-step help (v1.11) ----------
 * A <details> rather than a modal or a video: costs nothing when closed, can't
 * go stale silently, and is searchable by the browser's find-in-page. */
.proposal-help {
  border: 1px solid var(--border);
  border-left: 4px solid var(--secondary);
  border-radius: var(--radius);
  background: var(--surface);
  margin: 0 0 1.2rem;
}
.proposal-help > summary {
  cursor: pointer;
  padding: 0.7rem 1rem;
  font-weight: 600;
  color: var(--secondary);
  list-style-position: inside;
}
.proposal-help > summary:hover { background: color-mix(in srgb, var(--secondary) 5%, var(--surface)); }
.proposal-help[open] > summary { border-bottom: 1px solid var(--border); }
.proposal-help-hint {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--muted);
  margin-left: 0.4rem;
}
.proposal-help-body { padding: 0.4rem 1.2rem 1.1rem; font-size: 0.92rem; }
.proposal-help-body h4 { margin: 1.1rem 0 0.35rem; font-size: 0.92rem; color: var(--secondary); }
.proposal-help-lead { color: var(--muted); margin: 0.6rem 0 0; }
.proposal-help-steps { margin: 0.3rem 0; padding-left: 1.3rem; }
.proposal-help-steps li { margin: 0.35rem 0; line-height: 1.55; }
.proposal-help-steps code {
  background: #f4f5fb;
  border-radius: 4px;
  padding: 0.05rem 0.3rem;
  font-size: 0.88em;
}
.proposal-help-foot {
  margin-top: 1rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.87rem;
}

@media (max-width: 640px) {
  .diff-view { grid-template-columns: 1fr; }
  .header-inner { flex-direction: column; align-items: flex-start; }
}

/* =====================================================================
   RECORD SHEET EDITOR (v1.16)
   Replaces the three-column label/current/proposed grid in the proposal
   flows. One column at every width, so phone and desktop get the same
   layout rather than a squeezed version of the same idea. Text controls
   are borderless until focused, which is what makes it read as a filled
   document instead of a form.
   ===================================================================== */

.rec-sheet {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  margin-top: 0.6rem;
}

/* Sticky change counter — the answer to "what have I actually altered?" */
.rec-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.6rem 0.9rem;
  background: linear-gradient(120deg, #2a1268, var(--secondary) 70%);
  color: #fff;
}
.rec-bar-title { font-weight: 700; font-size: 0.95rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rec-id {
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  background: rgba(255,255,255,0.2);
  border-radius: 999px;
  padding: 0.08rem 0.45rem;
  margin-left: 0.3rem;
  vertical-align: middle;
}
.rec-bar-right { display: flex; align-items: center; gap: 0.7rem; flex: none; }
.rec-count { font-size: 0.78rem; opacity: 0.85; white-space: nowrap; }
.rec-count.has-changes {
  opacity: 1;
  font-weight: 700;
  background: rgba(255,255,255,0.2);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
}
.rec-bar .linkish { color: #fff; opacity: 0.9; font-size: 0.78rem; }
.rec-bar .linkish:hover { color: #fff; opacity: 1; }

.rec-body { padding: 0.3rem 0.9rem 1rem; }

.rec-field { padding: 0.75rem 0; border-bottom: 1px solid var(--border); position: relative; }
.rec-field:last-child { border-bottom: none; }
.rec-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 700;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.rec-field.primary .rec-label { color: var(--secondary); }
.rec-optional { text-transform: none; letter-spacing: 0; font-weight: 500; font-size: 0.72rem; opacity: 0.8; }
.rec-help { font-size: 0.82rem; color: var(--muted); line-height: 1.45; margin: 0.15rem 0 0.35rem; }
.rec-control { margin-top: 0.2rem; }

/* Edited marker — colour plus a text label plus a left rail, so it survives
   greyscale and colour-vision differences. */
.rec-badge {
  display: none;
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  background: var(--secondary);
  color: #fff;
  border-radius: 999px;
  padding: 0.08rem 0.45rem;
}
.rec-field.edited { background: color-mix(in srgb, var(--secondary) 5%, transparent); box-shadow: inset 3px 0 0 var(--secondary); padding-left: 0.6rem; margin-left: -0.6rem; border-radius: 0 6px 6px 0; }
.rec-field.edited .rec-badge { display: inline-block; }
.rec-field.filled .rec-label { color: var(--accent); }

.rec-was { margin-top: 0.35rem; font-size: 0.82rem; color: var(--muted); display: flex; align-items: baseline; gap: 0.4rem; flex-wrap: wrap; }
/* The "was …" line is toggled by the `hidden` attribute from wireRecordSheet().
   `display:flex` above out-specifies the UA `[hidden] { display:none }` rule, so
   without this every field showed a struck-through copy of its own unchanged
   value plus a revert link — the sheet read as if everything had been edited. */
.rec-was[hidden] { display: none; }
.rec-was-label { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 700; opacity: 0.75; }
.rec-was-value { text-decoration: line-through; opacity: 0.85; }

/* --- borderless-until-focused text controls --- */
.rec-input {
  width: 100%;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  padding: 0.35rem 0.45rem;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text);
  line-height: 1.5;
  resize: none;
}
.rec-input::placeholder { color: var(--muted); font-style: italic; opacity: 0.75; }
.rec-input:hover { border-color: var(--border); background: #fcfcfe; }
.rec-input:focus {
  outline: none;
  border-color: var(--secondary);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(69,39,160,0.12);
}
.rec-area { overflow: hidden; min-height: 2.6rem; }

.rec-select {
  font: inherit;
  font-size: 0.92rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  max-width: 100%;
}
.rec-select:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 3px rgba(69,39,160,0.12); }

/* --- yes/no toggle --- */
.rec-toggle { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; font-size: 0.92rem; }
.rec-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.rec-toggle-track {
  width: 2.4rem; height: 1.35rem; border-radius: 999px;
  background: #d6d9e0; position: relative; transition: background 0.15s ease; flex: none;
}
.rec-toggle-track::after {
  content: ""; position: absolute; top: 0.15rem; left: 0.15rem;
  width: 1.05rem; height: 1.05rem; border-radius: 50%; background: #fff;
  transition: transform 0.15s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.rec-toggle input:checked + .rec-toggle-track { background: var(--secondary); }
.rec-toggle input:checked + .rec-toggle-track::after { transform: translateX(1.05rem); }
.rec-toggle input:focus-visible + .rec-toggle-track { box-shadow: 0 0 0 3px rgba(69,39,160,0.25); }

/* --- chips (lists and references share one interaction) --- */
.rec-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.rec-chip-list { display: contents; }
.rec-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  background: color-mix(in srgb, var(--secondary) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--secondary) 30%, var(--border));
  color: var(--secondary);
  border-radius: 999px;
  padding: 0.2rem 0.3rem 0.2rem 0.65rem;
  font-size: 0.85rem;
  font-weight: 600;
  max-width: 100%;
}
.rec-chip-x {
  border: none; background: none; cursor: pointer;
  color: inherit; opacity: 0.65; font-size: 1rem; line-height: 1;
  padding: 0 0.25rem; border-radius: 50%;
}
.rec-chip-x:hover { opacity: 1; background: rgba(69,39,160,0.15); }
.rec-add {
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--secondary);
  border-radius: 999px;
  padding: 0.25rem 0.75rem;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: none;
}
.rec-add:hover { border-color: var(--secondary); background: color-mix(in srgb, var(--secondary) 7%, transparent); }
.rec-add-row { display: flex; gap: 0.4rem; flex: 1 1 14rem; min-width: 0; }
.rec-add-input {
  flex: 1; min-width: 0;
  border: 1px solid var(--border); border-radius: 7px;
  padding: 0.3rem 0.5rem; font: inherit; font-size: 0.88rem;
}
.rec-add-input:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 3px rgba(69,39,160,0.12); }
.rec-empty { color: var(--muted); font-style: italic; font-size: 0.88rem; }
.rec-hidden { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; overflow: hidden; }

.rec-section-head {
  margin-top: 1.2rem; padding-top: 0.9rem;
  border-top: 2px solid var(--border);
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.09em;
  font-weight: 700; color: var(--secondary);
}
.rec-section-help { font-size: 0.85rem; color: var(--muted); margin: 0.2rem 0 0; }

/* =====================================================================
   Reference picker sheet — one component for every reference field.
   Bottom sheet on a phone, centred panel on a desktop.
   ===================================================================== */
.recpick-overlay {
  position: fixed; inset: 0; z-index: 3000;
  background: rgba(20,22,26,0.55);
  display: flex; align-items: flex-end; justify-content: center;
}
body.recpick-open { overflow: hidden; }
.recpick {
  background: var(--surface);
  width: 100%;
  max-width: 620px;
  max-height: 88vh;
  display: flex; flex-direction: column;
  border-radius: 14px 14px 0 0;
  box-shadow: 0 -8px 40px rgba(0,0,0,0.3);
}
@media (min-width: 640px) {
  .recpick-overlay { align-items: center; }
  .recpick { border-radius: 14px; max-height: 80vh; }
}
.recpick-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  padding: 0.85rem 1rem; border-bottom: 1px solid var(--border);
}
.recpick-title { font-weight: 700; color: var(--secondary); font-size: 0.95rem; }
.recpick-close {
  border: none; background: none; font-size: 1.5rem; line-height: 1;
  cursor: pointer; color: var(--muted); padding: 0 0.3rem; box-shadow: none;
}
.recpick-close:hover { color: var(--text); }
.recpick-search { padding: 0.7rem 1rem; border-bottom: 1px solid var(--border); }
.recpick-input {
  width: 100%; font: inherit; font-size: 0.95rem;
  padding: 0.55rem 0.7rem; border: 1px solid var(--border); border-radius: 8px;
}
.recpick-input:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 3px rgba(69,39,160,0.12); }
.recpick-list { overflow-y: auto; flex: 1; -webkit-overflow-scrolling: touch; }
.recpick-row {
  display: flex; gap: 0.7rem; align-items: flex-start;
  padding: 0.7rem 1rem; border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.recpick-row:hover { background: color-mix(in srgb, var(--secondary) 5%, transparent); }
.recpick-row.on { background: color-mix(in srgb, var(--secondary) 10%, transparent); }
.recpick-row input { margin-top: 0.25rem; flex: none; width: 1.1rem; height: 1.1rem; accent-color: var(--secondary); }
.recpick-text { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.recpick-name { font-weight: 600; font-size: 0.92rem; }
.recpick-id { font-size: 0.7rem; color: var(--muted); font-weight: 500; }
.recpick-sum { font-size: 0.82rem; color: var(--muted); line-height: 1.45; }
.recpick-none { padding: 1.5rem 1rem; text-align: center; color: var(--muted); }
.recpick-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
  padding: 0.75rem 1rem; border-top: 1px solid var(--border);
  padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
}
.recpick-count { font-size: 0.85rem; color: var(--muted); }
.recpick-done { padding: 0.5rem 1.4rem; font-weight: 600; }

/* Touch targets: comfortable on a phone without looking oversized on desktop. */
@media (pointer: coarse) {
  .rec-input { padding: 0.5rem; font-size: 1rem; }
  .rec-chip { padding: 0.35rem 0.4rem 0.35rem 0.75rem; font-size: 0.9rem; }
  .rec-add { padding: 0.4rem 0.9rem; }
  .recpick-row { padding: 0.9rem 1rem; }
}

.ie-oor {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #a05a00;
  background: #fff4e0;
  border-radius: 4px;
  padding: 0.05rem 0.3rem;
  white-space: nowrap;
}

/* Denser rows: more options stay visible while the sliders are still in reach. */
.ie-rank-id {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--brand, #4527a0);
  background: rgba(69, 39, 160, 0.08);
  border-radius: 4px;
  padding: 0.05rem 0.25rem;
  text-align: center;
}
.ie-rank-band { font-size: 0.66rem; padding: 0.05rem 0.35rem; }
.ie-move { font-size: 0.7rem; min-width: 1.9rem; }
.ie-oor { font-size: 0.62rem; }
.wizard-handoff { margin-top: 1.2rem; }
.wizard-handoff-note { font-size: 0.83rem; color: var(--muted, #777); margin: 0.4rem 0 0; line-height: 1.45; }

/* ---------------- Portfolio scatter (v1.30) ----------------
   Emphasis form: one accent hue plus a de-emphasis gray, with identity carried
   by direct labels and reach by a hollow ring — never by colour alone. */
.sc-figure { margin: 0.5rem 0 0; }
.sc-svg { width: 100%; max-width: 520px; height: auto; display: block; margin: 0 auto; }
.sc-guide { stroke: var(--border, #e5e5e5); stroke-width: 1; stroke-dasharray: 4 4; }
.sc-axis { stroke: #cfcfd6; stroke-width: 1; }
.sc-axis-label { font-size: 10.5px; fill: var(--muted, #888); }
.sc-quad {
  font-size: 9.5px;
  fill: var(--muted, #aaa);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-weight: 700;
}
.sc-label { font-size: 10.5px; font-weight: 700; fill: var(--text, #333); }
.sc-dot { cursor: pointer; }
.sc-dot:focus { outline: none; }
.sc-dot:focus-visible circle:nth-of-type(2),
.sc-dot:hover circle:nth-of-type(2) { stroke: #1f1235; stroke-width: 2.5; }
.sc-caption { font-size: 0.8rem; color: var(--muted, #888); text-align: center; margin-top: 0.4rem; line-height: 1.45; }
.ie-view { margin-bottom: 0.5rem; }
.sc-ref { font-size: 9px; fill: #b9b9c4; letter-spacing: 0.04em; }

/* meta-relations matrix editor (v1.31) — two numbers per structure */
.mr-editor { font-size: 0.85rem; }
.mr-head, .mr-row {
  display: grid;
  grid-template-columns: minmax(9rem, 1fr) 6.5rem 7.5rem 3.4rem 2rem;
  gap: 0.4rem;
  align-items: center;
}
.mr-head { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted, #999); margin-bottom: 0.2rem; }
.mr-row { padding: 0.22rem 0; border-top: 1px solid rgba(0, 0, 0, 0.05); }
.mr-row:first-child { border-top: none; }
.mr-row.locked { background: rgba(69, 39, 160, 0.04); border-radius: 4px; }
.mr-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mr-cell { display: flex; align-items: center; gap: 0.3rem; }
.mr-cell > span { font-size: 0.68rem; color: var(--muted, #999); }
.mr-cell select { flex: 1; min-width: 3.2rem; }
.mr-lock { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted, #aaa); }
.mr-add-row { display: flex; gap: 0.4rem; align-items: center; margin-top: 0.5rem; flex-wrap: wrap; }
.mr-add-row .mr-add-pick { flex: 1 1 14rem; }
tr.gf-idle .gf-icon, tr.gf-idle .gf-name, tr.gf-idle .gf-effect { opacity: 0.55; }
@media (max-width: 620px) {
  .mr-head { display: none; }
  .mr-row { grid-template-columns: 1fr 1fr; grid-auto-rows: auto; }
  .mr-name { grid-column: 1 / -1; }
}
/* the remove control is shared by both editors; the old rule was scoped to .mi-editor only */
.mr-editor .mi-remove {
  background: none;
  border: none;
  color: var(--danger, #c0392b);
  font-size: 1.1rem;
  cursor: pointer;
  padding: 0 0.4rem;
  font-weight: 700;
}
.mr-editor .mi-remove:hover { filter: none; opacity: 0.7; }

/* ============================================================
 * RELATEDNESS MAP  (v1.32)
 * ============================================================ */

.grav-leader { stroke: var(--muted, #999); stroke-width: 0.75; fill: none; opacity: 0.55; }

.ie-sec-target {
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--muted, #777);
  border: 1px solid var(--border, #e0e0e0);
  border-radius: 999px;
  padding: 0 0.34rem;
  vertical-align: 1px;
}

.rel-figure { margin: 0; }
.rel-body { display: flex; gap: 0.9rem; align-items: flex-start; flex-wrap: wrap; }
.rel-mapwrap { flex: 1 1 340px; min-width: 280px; }
.rel-svg { width: 100%; height: auto; display: block; overflow: visible; }

.rel-ring { fill: none; stroke: var(--border, #e5e5e5); stroke-width: 1; opacity: 0.75; }
.rel-ring-close { opacity: 0.95; }

/* The one transition that matters: every node slides along its own fixed
 * bearing when the centre changes, so re-centring reads as a change of
 * distance rather than a reshuffle. */
.rel-node, .rel-edge-scale { transition: transform 0.5s cubic-bezier(0.22, 0.8, 0.3, 1); }
.rel-node circle, .rel-edge { transition: r 0.5s, fill-opacity 0.5s, stroke 0.3s, stroke-width 0.3s; }
@media (prefers-reduced-motion: reduce) {
  .rel-node, .rel-edge-scale, .rel-node circle, .rel-edge { transition: none; }
}

.rel-node { cursor: pointer; }
.rel-node:hover circle { fill-opacity: 0.85; }
.rel-node:focus { outline: none; }
.rel-node:focus-visible circle { stroke: var(--brand, #4527a0); stroke-width: 3.5; }
.rel-node.is-centre { cursor: default; }

.rel-id { font-size: 10px; font-weight: 700; fill: #fff; pointer-events: none; }
.rel-id-centre { font-size: 13px; }
.rel-flag { font-size: 10px; fill: #b26a00; pointer-events: none; }

/* v1.34 — the rim names are painted after every arm and carry a halo of the
   card background behind them. Moving the rim out past the parked-gap ring
   fixed the worst of the collisions; the halo covers the rest, where an arm at
   a neighbouring bearing crosses a long name on its way out. paint-order puts
   the stroke under the fill so the halo never thickens the letterforms. */
.rel-rim {
  font-size: 10.5px; font-weight: 600; fill: var(--text, #222); pointer-events: none;
  paint-order: stroke fill;
  stroke: var(--surface, #fff); stroke-width: 3.5px; stroke-linejoin: round;
}
.rel-rim.is-centre { fill: var(--brand, #4527a0); font-size: 12px; font-weight: 700; }
.rel-rim-gap { fill: var(--muted, #999); font-style: italic; }

/* The derived half of the neighbourhood check — complete by construction,
   generated wording, so it is visually subordinate to the hand-written checks
   above it rather than competing with them. */
.prox-derived {
  margin-top: 0.9rem; padding-top: 0.8rem;
  border-top: 1px dashed var(--border, #e5e5e5);
}
.prox-derived h4 { margin: 0 0 0.3rem; font-size: 0.95rem; }
.prox-derived .muted-note { margin: 0 0 0.5rem; }
.prox-list { margin: 0; padding-left: 1.1rem; }
.prox-list li { margin-bottom: 0.35rem; line-height: 1.5; }

.rel-panel { flex: 1 1 200px; min-width: 190px; }
.rel-group + .rel-group { margin-top: 0.6rem; }
.rel-group h5 {
  margin: 0 0 0.3rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted, #777);
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.rel-group h5 em { font-style: normal; opacity: 0.7; }
.rel-swatch { width: 14px; height: 3px; border-radius: 2px; background: #b9b6c6; display: inline-block; }
.rel-swatch-close { background: #4527a0; height: 4px; }
.rel-swatch-medium { background: #7a72a8; }

.rel-picks { display: flex; flex-direction: column; gap: 2px; }
.rel-pick {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 0.16rem 0.34rem;
  font: inherit;
  font-size: 0.82rem;
  color: inherit;
  cursor: pointer;
}
.rel-pick:hover { background: rgba(69, 39, 160, 0.06); border-color: var(--border, #e5e5e5); }
.rel-pick-id { font-weight: 700; font-size: 0.74rem; min-width: 2.2rem; color: var(--brand, #4527a0); }
.rel-pick-name { flex: 1; }
.rel-pick-flag { font-size: 0.7rem; color: #b26a00; white-space: nowrap; }
.rel-gap-note { font-size: 0.76rem; color: var(--muted, #777); margin: 0.2rem 0 0.3rem; }
.rel-caption { font-size: 0.8rem; color: var(--muted, #666); margin-top: 0.6rem; line-height: 1.45; }
.rel-caption b { color: var(--text, #222); }
.rel-note { color: #b26a00; }

/* --- relatedness field editor --- */
.rl-editor { border: 1px solid var(--border, #e5e5e5); border-radius: 7px; padding: 0.5rem 0.6rem; }
.rl-row {
  display: grid;
  grid-template-columns: minmax(9rem, 1fr) auto minmax(6rem, auto);
  gap: 0.5rem;
  align-items: center;
  padding: 0.2rem 0;
  border-top: 1px solid rgba(0, 0, 0, 0.05);
}
.rl-row:first-child { border-top: none; }
.rl-row.clash { background: rgba(178, 106, 0, 0.06); border-radius: 4px; }
.rl-name { font-size: 0.82rem; }
.rl-opts { display: flex; gap: 2px; }
.rl-opts button {
  font: inherit;
  font-size: 0.72rem;
  padding: 0.1rem 0.44rem;
  border: 1px solid var(--border, #ddd);
  background: #fff;
  color: var(--muted, #666);
  cursor: pointer;
  border-radius: 4px;
}
.rl-opts button.selected { background: var(--brand, #4527a0); border-color: var(--brand, #4527a0); color: #fff; font-weight: 600; }
.rl-mirror { font-size: 0.72rem; color: var(--muted, #888); text-align: right; }
.rl-row.clash .rl-mirror { color: #b26a00; }
.rl-note { font-size: 0.76rem; color: var(--muted, #777); margin: 0.5rem 0 0; }

@media (max-width: 640px) {
  .rl-row { grid-template-columns: 1fr; gap: 0.2rem; }
  .rl-mirror { text-align: left; }
}


/* ============================================================ v1.36 =========
   Multi-answer questions, the odds/impact line, and the out-of-reach group. */

/* A multi-select has to LOOK different from a pick-one or people tick once and
   move on, which is exactly the forced choice this change removes. Square
   corners and a check mark on the chosen ones; a pick-one keeps its pills. */
.filter-btn-row.multi button.selected::before,
.wizard-opts.multi .wizard-opt.selected .wo-label::before {
  content: "✓ ";
  font-weight: 700;
}
.filter-btn-row.multi button { border-radius: 5px; }
.wizard-multi-note,
.ie-multi-hint {
  font-size: 0.78rem; color: var(--muted, #777); font-style: italic;
}
.wizard-multi-note { margin: 0.35rem 0 0; }
.ie-multi-hint { font-style: normal; opacity: 0.7; }

/* The two numbers the ranking is actually computed from. Stated plainly and
   without a band, because a percentage that moves as you answer is the whole
   point — a band would hide the movement again. */
.reco-axes {
  margin: 0.35rem 0 0.2rem;
  font-size: 0.88rem;
  color: var(--text, #222);
}
.reco-axes b { color: var(--brand, #4527a0); }
.reco-axes-note {
  display: block;
  font-size: 0.82rem; color: var(--muted, #777); font-style: italic;
  margin-top: 0.15rem;
}

/* Out of reach: present and countable when closed, complete when open. */
.reco-escalate {
  margin: 0.9rem 0 0;
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.015);
}
.reco-escalate > summary {
  cursor: pointer;
  padding: 0.6rem 0.75rem;
  font-size: 0.92rem;
  list-style: none;
}
.reco-escalate > summary::-webkit-details-marker { display: none; }
.reco-escalate > summary::before {
  content: "▸ ";
  color: var(--muted, #777);
}
.reco-escalate[open] > summary::before { content: "▾ "; }
.reco-escalate .re-count {
  display: inline-block;
  min-width: 1.5em; text-align: center;
  background: var(--brand, #4527a0); color: #fff;
  border-radius: 10px; padding: 0 0.4em;
  font-size: 0.8rem; font-weight: 700;
  margin-right: 0.25rem;
}
.reco-escalate .re-hint { color: var(--muted, #777); font-style: italic; }
.reco-escalate > .muted-note,
.reco-escalate > .reco-card { margin-left: 0.75rem; margin-right: 0.75rem; }
.reco-escalate > .reco-card:last-child { margin-bottom: 0.75rem; }


/* ============================================================ v1.37 =========
   The Master scoring tuner. Two columns: controls left, consequences right —
   the readout is the point of the panel, so it never scrolls out of view while
   a slider is moving. */

.tn-panel {
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 6px;
  margin: 0.4rem 0 1.2rem;
  background: var(--surface, #fff);
}
.tn-panel > summary {
  cursor: pointer; padding: 0.7rem 0.85rem; font-weight: 600;
  list-style: none;
}
.tn-panel > summary::-webkit-details-marker { display: none; }
.tn-panel > summary::before { content: "▸ "; color: var(--muted, #777); }
.tn-panel[open] > summary::before { content: "▾ "; }
.tn-warnchip {
  display: inline-block; margin-left: 0.5rem;
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700;
  color: #b3261e; border: 1px solid currentColor; border-radius: 3px; padding: 0 0.35em;
}
.tn-warning {
  margin: 0 0.85rem 0.9rem;
  padding: 0.7rem 0.85rem;
  border-left: 3px solid #b3261e;
  background: rgba(179, 38, 30, 0.05);
  border-radius: 0 4px 4px 0;
  font-size: 0.88rem; line-height: 1.55; max-width: 78ch;
}

.tn-body { display: flex; gap: 1.1rem; align-items: flex-start; padding: 0 0.85rem; flex-wrap: wrap; }
.tn-controls { flex: 1 1 380px; min-width: 300px; }
.tn-side { flex: 0 1 320px; min-width: 260px; position: sticky; top: 0.6rem; }

.tn-group { margin-bottom: 1.1rem; }
.tn-group h5 { margin: 0 0 0.2rem; font-size: 0.95rem; }
.tn-groupnote { margin: 0 0 0.6rem; font-size: 0.82rem; color: var(--muted, #777); line-height: 1.5; max-width: 62ch; }
.tn-advanced { border-top: 1px dashed var(--border, #e5e5e5); padding-top: 0.8rem; }

.tn-row { margin-bottom: 0.6rem; }
.tn-row label { display: flex; align-items: baseline; gap: 0.5rem; font-size: 0.86rem; }
.tn-label { flex: 1 1 auto; }
.tn-val {
  font-variant-numeric: tabular-nums; font-weight: 700;
  color: var(--brand, #4527a0); min-width: 3.2em; text-align: right;
}
.tn-share { font-size: 0.74rem; color: var(--muted, #777); min-width: 8.5em; text-align: right; }
.tn-row input[type="range"] { width: 100%; margin: 0.15rem 0 0; }
.tn-desc { margin: 0.1rem 0 0; font-size: 0.78rem; color: var(--muted, #777); line-height: 1.45; max-width: 60ch; }

/* The readout. The headline is a traffic light on ONE question: how many
   patterns would recommend something else. */
.tn-readout {
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 6px; padding: 0.75rem 0.85rem;
  background: rgba(0, 0, 0, 0.015);
}
.tn-readout h5 { margin: 0.85rem 0 0.3rem; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted, #777); }
.tn-readout h5:first-of-type { margin-top: 0.4rem; }
.tn-headline {
  padding: 0.5rem 0.6rem; border-radius: 4px; font-size: 0.9rem; line-height: 1.4;
  border-left: 3px solid currentColor;
}
.tn-headline b { font-size: 1.25rem; }
.tn-headline .tn-sub { display: block; font-size: 0.79rem; opacity: 0.85; margin-top: 0.15rem; font-weight: 400; }
.tn-ok { color: #2e7d32; background: rgba(46, 125, 50, 0.07); }
.tn-warn { color: #b26a00; background: rgba(178, 106, 0, 0.07); }
.tn-alarm { color: #b3261e; background: rgba(179, 38, 30, 0.07); }

.tn-bar { display: flex; height: 20px; border-radius: 3px; overflow: hidden; background: var(--border, #eee); }
.tn-seg {
  display: flex; align-items: center; justify-content: center;
  font-size: 0.7rem; font-weight: 700; color: #fff; overflow: hidden;
  transition: width 0.18s ease;
}
.tn-strong, .tn-now { background: #2e7d32; }
.tn-possible, .tn-quick { background: #7a72a8; }
.tn-groundwork { background: #b26a00; }
.tn-weak, .tn-park { background: #9aa0ad; }
.tn-legend { margin: 0.25rem 0 0; font-size: 0.72rem; color: var(--muted, #777); }
.tn-key { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin: 0 0.2rem 0 0.5rem; }
.tn-legend .tn-key:first-child { margin-left: 0; }

.tn-ranges { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.tn-ranges th { text-align: left; font-weight: 500; color: var(--muted, #777); padding: 0.15rem 0.4rem 0.15rem 0; }
.tn-ranges td { font-variant-numeric: tabular-nums; }
.tn-med { color: var(--muted, #777); font-size: 0.76rem; }
.tn-hint { margin: 0.45rem 0 0; font-size: 0.78rem; line-height: 1.45; }
.tn-note { margin: 0.4rem 0 0; font-size: 0.72rem; color: var(--muted, #777); line-height: 1.4; }

.tn-changes { margin: 0.4rem 0 0; padding-left: 1.1rem; font-size: 0.85rem; }
.tn-changes li { margin-bottom: 0.2rem; }
.tn-chg-name { color: var(--muted, #777); }

@media (max-width: 760px) {
  .tn-side { position: static; }
}

/* ==================================================================
   v1.38 — the reachable range cloud, the diagram legends, and a panel
   that keeps the picture in view while you move the controls.
   ================================================================== */

/* The cloud is a region, not another mark. No stroke, low alpha, painted
   under everything: it has to be readable as "somewhere the dot could be"
   at a glance, and anything with an edge starts competing with the dots. */
.sc-cloud {
  fill: #5b3fd1;
  fill-opacity: 0.09;
  stroke: #5b3fd1;
  stroke-opacity: 0.28;
  stroke-width: 1;
  stroke-dasharray: 3 3;
  pointer-events: none;
}
.sc-drag { cursor: crosshair; }
.sc-drag:active { cursor: grabbing; }

/* --- the legend ------------------------------------------------------- */
.ie-legend {
  margin: 0.5rem 0 0;
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.015);
  font-size: 0.82rem;
}
.ie-legend > summary {
  cursor: pointer;
  padding: 0.45rem 0.6rem;
  font-weight: 600;
  list-style: none;
}
.ie-legend > summary::-webkit-details-marker { display: none; }
.ie-legend > summary::before { content: "▸ "; color: var(--muted, #999); }
.ie-legend[open] > summary::before { content: "▾ "; }
.ie-legend .lg-view { font-weight: 400; color: var(--muted, #888); }
.lg-rows {
  margin: 0;
  padding: 0 0.6rem 0.6rem;
  display: grid;
  grid-template-columns: minmax(8.5rem, 12rem) 1fr;
  gap: 0.3rem 0.7rem;
  align-items: baseline;
}
.lg-rows dt { font-weight: 600; line-height: 1.45; }
.lg-rows dd { margin: 0; color: var(--muted, #666); line-height: 1.45; }

/* Every swatch is drawn from the same colour the picture uses, passed in as
   --c. Shape is carried by the class so nothing depends on colour alone. */
.lg-key {
  display: inline-block;
  width: 12px; height: 12px;
  margin-right: 0.35rem;
  vertical-align: -1px;
}
.lg-dot { border-radius: 50%; background: var(--c, #5b3fd1); }
.lg-dot-lg { width: 16px; height: 16px; border-radius: 50%; background: var(--c, #5b3fd1); vertical-align: -3px; }
.lg-ring { border-radius: 50%; border: 2px solid var(--c, #9aa0ad); }
.lg-ring-dash { border-radius: 50%; border: 2px dashed var(--c, #9a8a55); }
.lg-hub { border-radius: 50%; background: var(--c, #4527a0); width: 14px; height: 14px; vertical-align: -2px; }
.lg-ghost { border-radius: 50%; border: 1.5px dotted #9aa0ad; }
.lg-line { height: 0; border-top: 3px solid var(--c, #2e7d32); width: 16px; vertical-align: 3px; }
.lg-line-dash { height: 0; border-top: 3px dashed var(--c, #c62828); width: 16px; vertical-align: 3px; }
.lg-guide { height: 0; border-top: 1.5px dashed #b9b9c4; width: 16px; vertical-align: 3px; }
.lg-axis { height: 0; border-top: 1.5px solid #cfcfd6; width: 16px; vertical-align: 3px; }
.lg-trail { height: 0; border-top: 2px solid #c9c4e4; width: 16px; vertical-align: 3px; }
.lg-cloud { background: rgba(91, 63, 209, 0.16); border: 1px dashed rgba(91, 63, 209, 0.5); border-radius: 3px; width: 16px; }
.lg-orbit { border-radius: 50%; border: 1.5px solid var(--border, #ddd); }
.lg-size {
  border-radius: 50%;
  background: linear-gradient(90deg, rgba(69, 39, 160, 0.35) 45%, rgba(69, 39, 160, 0.9) 45%);
}
.lg-arrow-in::before, .lg-arrow-out::before {
  display: inline-block; font-size: 12px; line-height: 12px; color: var(--muted, #666);
}
.lg-arrow-in::before { content: "→|"; }
.lg-arrow-out::before { content: "|→"; }

/* --- keeping the picture in view -------------------------------------- */
/* The controls now live beside the list, and the graphic column is pinned.
   Before this the sliders sat below the whole body, so reaching one scrolled
   the picture it changes off the screen. */
.ie-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.ie-head h3 { margin-bottom: 0.2rem; }
.ie-density {
  font-size: 0.75rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--border, #ddd);
  background: transparent;
  color: var(--muted, #777);
  cursor: pointer;
}
.ie-density[aria-pressed="true"] {
  background: var(--brand, #4527a0);
  border-color: var(--brand, #4527a0);
  color: #fff;
}
.impact-explorer .ie-controls { margin-top: 0.9rem; }

@media (min-width: 980px) {
  .impact-explorer .ie-left { flex: 1 1 420px; }
  .impact-explorer .ie-stick {
    position: sticky;
    top: 0.75rem;
    max-height: calc(100vh - 1.5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* Compact density. Not a separate layout — the same panel with the type
   stepped down, which is what it takes to get a 340px plot and six sliders
   onto a 13-inch screen at once. */
.impact-explorer.ie-compact { font-size: 0.92rem; }
.impact-explorer.ie-compact .grav-svg,
.impact-explorer.ie-compact .sc-svg { max-width: 420px; }
.impact-explorer.ie-compact .ie-control label { font-size: 0.74rem; }
.impact-explorer.ie-compact .ie-value { font-size: 0.78rem; }
.impact-explorer.ie-compact .ie-yours { font-size: 0.68rem; }
.impact-explorer.ie-compact .ie-seg button { font-size: 0.72rem; padding: 0.18rem 0.42rem; }
.impact-explorer.ie-compact .ie-rank-row { padding: 0.22rem 0.4rem; font-size: 0.8rem; }
.impact-explorer.ie-compact .ie-controls { gap: 0.45rem 0.8rem; margin-top: 0.6rem; }
.impact-explorer.ie-compact .sc-caption,
.impact-explorer.ie-compact .grav-caption { font-size: 0.74rem; }
.impact-explorer.ie-compact .ie-legend { font-size: 0.76rem; }
.impact-explorer.ie-compact .muted-note { font-size: 0.76rem; }

/* --- multi-answer, stated in the questionnaire too -------------------- */
.multi-note {
  margin: 0.2rem 0 0.4rem;
  font-size: 0.82rem;
  color: var(--muted, #666);
}
.multi-note b { color: var(--brand, #4527a0); }

/* --- Master-only numbers ---------------------------------------------- */
.reco-axes-master {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted, #999);
  margin-left: 0.4rem;
}

/* --- the scales table in the tuner ------------------------------------ */
.tn-scales {
  margin: 0.6rem 0 0.9rem;
  border: 1px solid var(--border, #e5e5e5);
  border-radius: 8px;
  padding: 0.1rem 0.6rem;
  background: rgba(0, 0, 0, 0.015);
}
.tn-scales > summary { cursor: pointer; padding: 0.45rem 0; font-weight: 600; font-size: 0.88rem; }
.tn-scaletable { width: 100%; border-collapse: collapse; font-size: 0.8rem; margin: 0.3rem 0 0.5rem; }
.tn-scaletable th {
  text-align: left; font-weight: 600; color: var(--muted, #777);
  padding: 0.2rem 0.5rem 0.2rem 0; border-bottom: 1px solid var(--border, #e5e5e5);
}
.tn-scaletable td { padding: 0.35rem 0.5rem 0.35rem 0; vertical-align: top; border-top: 1px solid rgba(0, 0, 0, 0.05); line-height: 1.45; }
.tn-scalerange { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted, #666); }
.tn-scaletable code { font-size: 0.74rem; color: var(--muted, #777); }

@media (max-width: 760px) {
  .lg-rows { grid-template-columns: 1fr; gap: 0.1rem; }
  .lg-rows dd { margin-bottom: 0.4rem; }
}

/* ==================================================================
   v1.39 — the seven-point condition slider, and the graphic's new
   two-channel encoding (size = magnitude, colour = sign).
   ================================================================== */

.sec-health-row {
  padding: 0.5rem 0.1rem 0.6rem;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}
.sec-health-row:first-of-type { border-top: none; }
.shr-prompt { font-size: 0.86rem; line-height: 1.4; margin-bottom: 0.3rem; }
.shr-control { display: flex; align-items: center; gap: 0.6rem; }
.shr-slider {
  flex: 1 1 auto;
  min-width: 8rem;
  accent-color: var(--brand, #4527a0);
}
/* Unanswered has to look unanswered. The thumb sits at the midpoint because it
   has to sit somewhere, and a full-strength control there would read as
   "neither one nor the other" — which is a different answer. */
.sec-health-row:not(.answered) .shr-slider { opacity: 0.45; }
.shr-unknown {
  flex: 0 0 auto;
  font-size: 0.72rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--border, #ddd);
  background: transparent;
  color: var(--muted, #777);
  cursor: pointer;
}
.shr-unknown.selected {
  background: var(--muted, #777);
  border-color: var(--muted, #777);
  color: #fff;
}
.shr-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.2rem;
  font-size: 0.72rem;
  color: var(--muted, #888);
}
.shr-end { flex: 0 0 auto; }
.shr-read {
  flex: 1 1 auto;
  text-align: center;
  font-weight: 600;
  color: var(--text, #333);
}
.sec-health-row:not(.answered) .shr-read { font-weight: 400; color: var(--muted, #888); font-style: italic; }
.shr-swatch {
  display: inline-block;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--c, #d7d4dc);
  border: 1px solid rgba(0, 0, 0, 0.18);
  margin-right: 0.3rem;
  vertical-align: -1px;
}

/* In the explorer the rows sit in a narrow column, so the ends of the scale
   are dropped rather than wrapped — the read-out under the thumb names the
   answer, which is what people actually read. */
.ie-secondary .shr-end { display: none; }
.ie-secondary .shr-read { text-align: left; }
.ie-secondary .sec-health-row { padding: 0.35rem 0 0.4rem; }
.ie-secondary .shr-prompt { font-size: 0.8rem; margin-bottom: 0.15rem; }
.impact-explorer.ie-compact .ie-secondary .shr-prompt { font-size: 0.74rem; }
.impact-explorer.ie-compact .ie-secondary .shr-foot { font-size: 0.68rem; }

/* The legend's condition ramp: seven swatches in a row need to sit tight
   enough to read as one scale rather than as seven separate keys. */
.lg-rows dt .lg-dot + .lg-dot { margin-left: -0.25rem; }

/* A full-width track makes seven notches feel like a continuum and the
   difference between -3 and -2 like a matter of aim. Capped so a notch is a
   notch. */
.secondary-health .shr-slider { max-width: 28rem; }
.sec-health-row:not(.answered) .shr-slider { opacity: 0.35; accent-color: var(--muted, #999); }
/* The end labels have to line up with the ENDS OF THE TRACK, not with the row,
   or "A real strength" floats a hand's width past the point it names. */
.secondary-health .shr-foot { max-width: 28rem; }

/* ================= v1.40 — language switch ================= */
/* Deliberately the same pill as the Standard/Expert switch: they are the same
   kind of control (a two-state view preference), and giving them different
   shapes would imply a difference that isn't there. */
.lang-switch {
  display: inline-flex;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 999px;
  overflow: hidden;
}
.lang-btn {
  background: transparent;
  color: #fff;
  border: none;
  padding: 0.35rem 0.75rem;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  cursor: pointer;
  opacity: 0.8;
}
.lang-btn.active { background: #fff; color: var(--primary); font-weight: 700; opacity: 1; }

/* ============ v1.40 — "none of these fit" → propose a pattern ============ */
.nofit-block {
  margin: 1.6rem 0 0.5rem;
  padding: 1rem 1.1rem;
  border-radius: 10px;
  border: 1px dashed color-mix(in srgb, var(--primary) 35%, transparent);
  background: color-mix(in srgb, var(--primary) 4%, transparent);
}
.nofit-lead { margin: 0 0 0.7rem; font-size: 0.95rem; }
.nofit-block .form-actions { margin: 0; }
.nofit-panel { margin-top: 1rem; }
.nofit-panel[hidden] { display: none; }
.nofit-filter { margin: 0.6rem 0 0.4rem; }

/* Capped and scrollable on purpose: the point of the list is that it is the
   WHOLE library, and a list that pushes the confirm checkbox off the screen
   is a list nobody scrolls to the end of. */
.nofit-list {
  max-height: 22rem;
  overflow-y: auto;
  margin: 0 0 0.9rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 8px;
  background: #fff;
}
.nofit-list li { padding: 0.3rem 0; border-bottom: 1px solid rgba(0, 0, 0, 0.06); }
.nofit-list li:last-child { border-bottom: none; }
.nofit-sig {
  display: block;
  font-size: 0.82rem;
  opacity: 0.75;
  margin: 0.1rem 0 0 0.2rem;
}
.nofit-confirm { display: block; margin: 0.2rem 0 0.9rem; font-weight: 600; }
.nofit-go[disabled] { opacity: 0.45; cursor: not-allowed; }

/* ============ v1.41 — a pattern's two signal texts ============ */
/* The summary is the lead line of every pattern card; the fuller description
   sits behind the existing .more-detail disclosure so a stack of three
   candidates stays scannable. */
.result-card .pattern-summary {
  font-size: 1.02rem;
  line-height: 1.5;
}
.result-card .more-detail { margin: 0.2rem 0 0.9rem; }
.result-card .more-detail-body p { margin: 0 0 0.6rem; }

/* ============ v1.42 — the lightbox's exits ============ */
/* A sticky strip at the foot of the card, because the card scrolls and an exit
   you have to scroll to find is an exit most people will not use. */
.modal-nav {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  align-items: center;
  margin: 1.2rem -1.5rem -1.5rem;
  padding: 0.75rem 1.5rem;
  border-top: 1px solid var(--border, #e5e5e5);
  background: color-mix(in srgb, var(--card, #fff) 92%, transparent);
  backdrop-filter: blur(6px);
}
.modal-nav[hidden] { display: none; }
.detail-exit {
  background: transparent;
  border: 1px solid var(--border, #d8d8e0);
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--text, #222);
}
.detail-exit:hover { border-color: var(--brand, #4527a0); color: var(--brand, #4527a0); }
.detail-exit.primary { margin-left: auto; border-color: var(--brand, #4527a0); color: var(--brand, #4527a0); font-weight: 600; }

/* The cross-links look like links now that they behave like links. */
.jump-link { color: var(--brand, #4527a0); text-decoration: underline; text-underline-offset: 2px; }
.jump-link:hover { text-decoration-thickness: 2px; }

/* ============ v1.42 — the questionnaire's progress rail ============ */
/* Sticky, because the whole point is orientation on a page long enough to lose
   your place in. Deliberately the same shape as the wizard's step header: the
   two routes are the same five decisions, and giving them different furniture
   would imply otherwise. */
.diag-steps {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 0.15rem;
  flex-wrap: wrap;
  margin: 1rem 0 0.4rem;
  padding: 0.45rem 0.2rem;
  background: color-mix(in srgb, var(--bg, #fff) 92%, transparent);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border, #e8e8ee);
}
.diag-steps[hidden] { display: none; }
.diag-step {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: transparent;
  border: none;
  border-radius: 999px;
  padding: 0.25rem 0.55rem;
  font-size: 0.82rem;
  color: var(--muted, #777);
  cursor: pointer;
}
.diag-step.ready { color: var(--text, #222); }
.diag-step.ready:hover { background: color-mix(in srgb, var(--brand, #4527a0) 8%, transparent); }
.diag-step.current { color: var(--brand, #4527a0); font-weight: 700; }
.diag-step.pending { opacity: 0.42; cursor: default; }
.diag-step-num {
  width: 1.25rem; height: 1.25rem; flex: none;
  border-radius: 50%;
  display: inline-grid; place-items: center;
  font-size: 0.7rem; font-weight: 700;
  background: var(--border, #e8e8ee); color: var(--muted, #777);
}
.diag-step.ready .diag-step-num { background: color-mix(in srgb, var(--brand, #4527a0) 16%, transparent); color: var(--brand, #4527a0); }
.diag-step.current .diag-step-num { background: var(--brand, #4527a0); color: #fff; }
.diag-step-sep { color: var(--border, #d7d7e0); font-size: 0.8rem; }
@media (max-width: 620px) { .diag-step-label { display: none; } }

/* "What you tested" — the explorer excursion, on screen and in the report. */
.rp-tested table { width: 100%; border-collapse: collapse; margin: 0.4rem 0; font-size: 0.88rem; }
.rp-tested th { text-align: left; font-weight: 600; color: var(--muted, #777); padding: 0.3rem 0.6rem 0.3rem 0; border-bottom: 1px solid var(--border, #eee); }
.rp-tested td { padding: 0.3rem 0.6rem 0.3rem 0; border-bottom: 1px solid var(--border, #eee); vertical-align: top; }
.rp-tested .from { color: var(--muted, #888); }
.rp-tested .to { font-weight: 600; }
.rp-verdict { margin: 0.5rem 0 0; font-size: 0.9rem; }
.rp-verdict.moved { color: var(--brand, #4527a0); font-weight: 600; }

/* ============ v1.44 — what the ranking does not know ============ */
/* Amber rather than red: an unanswered question is a limit on the reading, not
   an error the reader made. */
.unanswered-note {
  margin: 0.8rem 0 1rem;
  padding: 0.7rem 0.95rem;
  border: 1px solid #e0c179;
  border-left: 4px solid #c99b28;
  border-radius: 8px;
  font-size: 0.88rem;
  line-height: 1.5;
}
.unanswered-note p { margin: 0 0 0.45rem; }
.unanswered-note p:last-child { margin-bottom: 0; }
.unanswered-head {
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #8a6a12;
}

/* The explorer says what its picture is about, in words rather than an id. */
.ie-subject {
  margin: 0.5rem 0 0.2rem;
  font-size: 0.88rem;
  color: var(--muted, #777);
}
.ie-subject b { color: var(--text, #222); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.82rem; }

.sec-health-intro { margin: 0.3rem 0 0.7rem; }

/* ============ v1.45 — the Navigator's selection panel ============ */
/* The map is often 2,000-3,000px tall, and this card was written to its FOOT.
   So the answer to "what did I just click?" was always somewhere you had to
   scroll to find — and by the time you got there the node you clicked was off
   the top of the screen. That is what made the Navigator feel messy.
 *
 * `position: sticky` was the first attempt and does not solve it: sticky only
 * stops an element leaving the viewport once you have scrolled TO it. It cannot
 * pull a card up from 2,600px below. A selection has to appear where the eye
 * already is, so while something is selected the panel is a fixed bottom sheet.
 * It is a descendant of #view-library, so leaving the Library removes it with
 * the view — no separate teardown to forget. */
.map-panel.is-selected {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  margin: 0;
  padding: 0 max(0.75rem, env(safe-area-inset-left)) env(safe-area-inset-bottom);
  pointer-events: none; /* the strip itself must not swallow map clicks */
}
.map-panel.is-selected .map-panel-card {
  pointer-events: auto;
  position: relative;
  max-width: 1100px;
  margin: 0 auto;
  border: 1px solid var(--border, #e0e0e8);
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.16);
  background: var(--card, #fff);
  padding: 0.85rem 1.1rem 0.9rem;
  max-height: 40vh;
  overflow-y: auto;
}
.map-panel-close {
  position: absolute;
  top: 0.4rem;
  right: 0.5rem;
  background: none;
  border: none;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  color: var(--muted, #888);
  padding: 0.1rem 0.35rem;
}
.map-panel-close:hover { color: var(--text, #222); }
.map-panel-actions { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin-top: 0.5rem; }
.map-panel-hint { font-size: 0.8rem; color: var(--muted, #888); }

/* Focusable nodes need a visible focus ring, or keyboard operation is invisible. */
.map-node { cursor: pointer; }
.map-node:focus { outline: none; }
.map-node:focus-visible rect { stroke: var(--brand, #4527a0); stroke-width: 3; }

@media (max-width: 640px) {
  .map-panel.is-selected .map-panel-card { max-height: 52vh; padding: 0.7rem 0.9rem; }
  .map-panel-hint { display: none; }  /* there is no double-click on touch */
}

/* ============================================================================
 * v1.46 — external-user feedback pass
 * ========================================================================= */

/* --- A pattern name always arrives with its description (feedback 1) ------ */

/* The pick card can no longer be the whole candidate: a <button> may not
 * contain a <details>, so the disclosure is a sibling and the wrapper is what
 * the list lays out. */
.wizard-pick-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.wizard-pick-wrap > .pattern-more {
  margin: 0 0 0 2.35rem;
  font-size: 0.9rem;
}
.pattern-more > summary {
  cursor: pointer;
  color: var(--primary);
  font-size: 0.88rem;
}
.pattern-more .more-detail-body p { margin: 0.4rem 0; }

/* Library table: the name carries its one-liner rather than standing alone. */
.lib-name { display: block; }
.lib-sub {
  display: block;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.35;
  margin-top: 0.15rem;
  max-width: 60ch;
}

/* --- Validation is optional, not a gate (feedback 3.2) ------------------- */
.wizard-doublecheck {
  margin: 1.1rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px dashed var(--border);
  font-size: 0.9rem;
}
.wizard-doublecheck .linkish { font-weight: 600; }
.wizard-doublecheck-sub {
  display: block;
  color: var(--muted);
  font-size: 0.84rem;
  margin-top: 0.15rem;
}

/* --- The recommendations are a declared stopping point (feedback 3.3) ---- */
.wizard-reco-desc { margin: 0.3rem 0 0.5rem; }
.wizard-reco .grav-summary {
  margin: 0.6rem 0 0;
  padding: 0.6rem 0.8rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.wizard-reco .grav-summary h5 { margin: 0 0 0.35rem; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.wizard-reco .grav-summary p { margin: 0.3rem 0; font-size: 0.9rem; }
.wizard-reco .reco-warn { margin: 0.5rem 0 0; font-size: 0.88rem; color: var(--warn); }

.wizard-threshold {
  margin: 1.6rem 0 0.5rem;
  padding: 1.1rem 1.2rem;
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
}
.wizard-threshold h4 { margin: 0 0 0.4rem; font-size: 1.05rem; }
.wizard-threshold > p { margin: 0 0 1rem; color: var(--muted); max-width: 72ch; }

.wizard-fork {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.85rem;
}
.wizard-fork-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  text-align: left;
  padding: 0.9rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.wizard-fork-card:hover,
.wizard-fork-card:focus-visible { border-color: var(--primary); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.07); }
.wfc-title { font-weight: 700; }
.wfc-desc { color: var(--muted); font-size: 0.87rem; line-height: 1.4; }

/* --- The sandbox explains its own disagreement (feedback 3.5) ------------ */
.ie-divergence:empty { display: none; }
.ie-diverge-card {
  position: relative;
  margin: 0 0 0.75rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-left: 4px solid var(--warn);
  border-radius: var(--radius);
  background: #fffdf5;
  font-size: 0.88rem;
}
.ie-diverge-card.moved { border-left-color: var(--danger); }
.ie-diverge-card p { margin: 0.3rem 0; }
/* Not float: the site's global button rule paints buttons white-on-primary,
 * and a floated pill inheriting that came out as an empty white box. Own line,
 * own colours, stated explicitly. */
.ie-diverge-reset {
  display: inline-block;
  margin: 0 0 0.45rem;
  padding: 0.2rem 0.6rem;
  font: inherit;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
}
.ie-diverge-reset:hover { border-color: var(--primary); color: var(--primary); }

/* A row the diagnosis never put forward must not look like one that it did. */
.ie-rank-row.off-pattern { opacity: 0.92; }
.ie-rank-row.off-pattern .ie-rank-n { color: var(--muted); }
.ie-offpattern {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.7rem;
  border-radius: 999px;
  background: #f3e8d6;
  color: #7a5a1b;
  /* Deliberately NOT nowrap: this is a phrase, not a token, and holding it on
     one line was what made the ranked list overflow a phone. */
  max-width: 100%;
}

/* ============================================================================
 * v1.47 — finishing a diagnostic
 * ========================================================================= */

/* The third fork card. Deliberately quieter than the other two: it is the
 * destructive one, and it should read as available rather than as an
 * equally-weighted next step. */
/* Full width on its own row under the two real choices, and laid out as a
 * single line rather than a card: three equal-looking tiles made the
 * destructive one read as a third next step, and at two columns it was left
 * stranded on a row by itself. */
.wizard-fork-card.wizard-fork-clear {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.15rem 0.6rem;
  padding: 0.6rem 0.9rem;
  background: var(--bg);
}
.wizard-fork-card.wizard-fork-clear .wfc-desc { flex: 1 1 16rem; }
.wizard-fork-card.wizard-fork-clear .wfc-title { color: var(--muted); }
.wizard-fork-card.wizard-fork-clear:hover,
.wizard-fork-card.wizard-fork-clear:focus-visible { border-color: var(--danger); }
.wizard-fork-card.wizard-fork-clear:hover .wfc-title { color: var(--danger); }

/* Same door on the questionnaire surface, pushed to the end of the progress
 * rail so it never sits between two steps. */
.diag-step-clear {
  margin-left: auto;
  padding: 0.25rem 0.6rem;
  font: inherit;
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
}
.diag-step-clear:hover { color: var(--danger); border-color: var(--danger); }

/* ============================================================================
 * v1.48 — the deep dive as a tabbed workspace
 *
 * The old rail scrolled between six stacked sections on one very tall page.
 * These rules turn it into a tab bar with one panel visible at a time, and are
 * written mobile-first: at phone widths the bar scrolls sideways and the tabs
 * shrink, and only from 700px up does it get the full-width treatment.
 * ========================================================================= */

.diag-workspace[hidden] { display: none; }
.diag-workspace {
  margin-top: 1.1rem;
  /* The slim header is fixed and ~53px tall once the page has scrolled, so a
     plain scrollIntoView parks the tab bar underneath it. Both numbers below
     are that height plus a little air; they must stay in step with each
     other or the bar lands either behind the header or below its own panel. */
  scroll-margin-top: 4.2rem;
}

.diag-tabs {
  position: sticky;
  top: 3.4rem;
  z-index: 40;
  display: flex;
  align-items: stretch;
  gap: 0.25rem;
  /* Sideways scroll rather than wrap: a tab bar that reflows to two rows moves
     the panel underneath it every time the active tab changes row. */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
  padding: 0.35rem 0.1rem 0;
  margin: 0 0 0.1rem;
  background: var(--bg);
  border-bottom: 2px solid var(--border);
}
.diag-tab {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--muted);
  background: transparent;
  border: none;
  border-bottom: 3px solid transparent;
  border-radius: 6px 6px 0 0;
  padding: 0.5rem 0.8rem;
  margin-bottom: -2px;
  cursor: pointer;
  white-space: nowrap;
}
.diag-tab:hover:not([disabled]) { color: var(--text); background: rgba(0, 0, 0, 0.03); }
.diag-tab.current {
  color: var(--secondary);
  border-bottom-color: var(--secondary);
  background: var(--surface);
}
.diag-tab[disabled] { opacity: 0.4; cursor: default; }
.diag-tab:focus-visible { outline: 2px solid var(--secondary); outline-offset: -3px; }

.diag-tab-hint {
  margin: 0.5rem 0 0.9rem;
  color: var(--muted);
  font-size: 0.87rem;
  line-height: 1.45;
  max-width: 78ch;
}
.diag-tab-hint:empty { display: none; }

.diag-panel[hidden] { display: none; }
/* A panel arriving in place of another must not inherit the previous one's
   scroll position mid-animation; this keeps the swap visually still. */
.diag-panel { animation: diagPanelIn 0.16s ease-out; }
@keyframes diagPanelIn {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .diag-panel { animation: none; }
}

/* The clear button rides at the end of the bar. On a phone it would otherwise
   push the last real tab off-screen, so it loses its label there. */
.diag-tabs .diag-step-clear { flex: 0 0 auto; margin-left: auto; align-self: center; }

@media (max-width: 560px) {
  .diag-tab { font-size: 0.84rem; padding: 0.45rem 0.6rem; }
  .diag-tabs .diag-step-clear { margin-left: 0.4rem; }
}

/* --- the bridge from the ranking to the sandbox --- */
.panel-pointer {
  margin: 1.2rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px dashed var(--border);
  font-size: 0.92rem;
}
.panel-pointer .linkish { font-weight: 700; }
.panel-pointer-sub {
  display: block;
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 0.15rem;
}

/* --- the organisation profile --- */
.org-profile {
  margin: 0 0 1.4rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg);
}
.org-profile-head { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.org-profile-when { color: var(--muted); font-size: 0.8rem; }
.org-profile-sub { margin: 0.3rem 0 0.6rem; color: var(--muted); font-size: 0.87rem; max-width: 72ch; }

.carry-table { width: 100%; border-collapse: collapse; margin: 0.4rem 0 0.6rem; font-size: 0.9rem; }
.carry-table th,
.carry-table td { text-align: left; vertical-align: top; padding: 0.28rem 0.5rem 0.28rem 0; border-bottom: 1px solid var(--border); }
.carry-table th { font-weight: 600; width: 48%; }
.carry-table td { color: var(--muted); }
.carry-table tr:last-child th,
.carry-table tr:last-child td { border-bottom: none; }

/* --- "not asked" reads as information, not as a telling-off --- */
.unanswered-note.informational { border-left-color: var(--muted); background: var(--bg); }
.unanswered-skipped { color: var(--muted); }

/* --- terms: hover on a pointer, tap anywhere else ---
 * A button rather than <abbr>, because a title attribute is invisible on a
 * touch device and these are definitions the reader needs in order to answer
 * the question they are attached to. */
.term {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: help;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--muted);
}
.term:hover,
.term:focus-visible { color: var(--secondary); text-decoration-color: var(--secondary); }
.term:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; border-radius: 3px; }
/* Inside a graphic the node is the target, so the cursor is the only hint. */
.grav-node[data-term-meta] { cursor: help; }
.grav-node[data-term-meta]:focus-visible { outline: 2px solid var(--secondary); }

/* Long label on a wide screen, short one when the bar has to fit in a phone.
   Both are in the DOM so the swap costs no re-render. */
.diag-tab-short { display: none; }
@media (max-width: 620px) {
  .diag-tab-label { display: none; }
  .diag-tab-short { display: inline; }
}

/* v1.48 — the explorer got its own tab, which is the first time it has had to
   survive a narrow viewport without a wider page around it. Its two columns
   declare min-width: 280px/260px, and on a 390px phone the card's own padding
   pushes that past the screen edge — 4px of horizontal document scroll, which
   is the kind that makes a page feel broken without ever looking broken.
   Flex children need min-width: 0 to be allowed to shrink at all. */
@media (max-width: 620px) {
  .impact-explorer .ie-left,
  .impact-explorer .ie-right {
    min-width: 0;
    flex-basis: 100%;
    max-width: 100%;
  }
  .impact-explorer .ie-stick,
  .impact-explorer .ie-seg,
  .impact-explorer .ie-subject { max-width: 100%; }
  /* The view/scope switchers are three long labels in a row; let them wrap
     rather than set the width of the panel. */
  .impact-explorer .ie-seg { flex-wrap: wrap; }
}

/* ============================================================================
 * v1.49 — why an option is not one of this pattern's recommendations
 * ========================================================================= */

.ie-offpattern-why {
  margin: 0.6rem 0 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.ie-offpattern-head {
  margin: 0 0 0.35rem;
  font-weight: 700;
  font-size: 0.88rem;
}
.ie-offpattern-why p { margin: 0.3rem 0; }
.ie-offpattern-why .muted-note {
  margin-top: 0.5rem;
  padding-top: 0.45rem;
  border-top: 1px dashed var(--border);
  color: var(--muted);
  font-size: 0.83rem;
}

/* The chip says which of the three reasons applies, so it should not look the
   same in all three cases. A missing link is a gap in the library (neutral,
   even promising); a neighbouring structure is a sequencing note; anything
   else is the one that genuinely means "this is not your answer". */
.ie-offpattern.off-gap { background: #e7eefb; color: #1a4a8a; }
.ie-offpattern.off-neighbour { background: #e9f3ec; color: #245c37; }
.ie-diverge-also { margin-top: 0.6rem; color: var(--muted); font-size: 0.85rem; }

/* ============================================================================
 * v1.50 — the database failed to load, and the page says so
 *
 * Previously this state was invisible: an empty database rendered as a healthy
 * site with nothing in it. The banner is deliberately loud and sits directly
 * under the tab bar, above every view, because it invalidates two of them.
 * ========================================================================= */
.db-failure {
  max-width: 1100px;
  margin: 1rem auto 0;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--danger);
  border-left: 5px solid var(--danger);
  border-radius: var(--radius);
  background: #fdf3f3;
  color: var(--text);
  font-size: 0.92rem;
  line-height: 1.5;
}
.db-failure b { color: var(--danger); }
.db-failure-detail {
  display: block;
  margin-top: 0.4rem;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  overflow-wrap: anywhere;
}
@media (min-width: 1400px) {
  .db-failure { max-width: 1320px; }
}

/* ------------------------------------------------------------------
   v1.52 — Master: diagnostic matching providers panel.
   Reuses .tn-panel / .tn-warning / .tn-warnchip for the shell; these
   rules only cover the switch rows and the result table.
   ------------------------------------------------------------------ */
.pv-rows {
  display: grid;
  gap: 0.35rem;
  margin: 0.8rem 0;
}
.pv-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--line, #e2e2e2);
  border-radius: 6px;
}
.pv-switch {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  margin: 0;
}
.pv-name { font-weight: 600; }
.pv-status {
  font-size: 0.85rem;
  color: var(--muted, #777);
  font-variant-numeric: tabular-nums;
}
.pv-ok { color: #1a7f4b; font-weight: 600; }
.pv-bad { color: #b3261e; font-weight: 600; }
.pv-query {
  width: 100%;
  max-width: 62ch;
  margin: 0.5rem 0 0;
}
.pv-report { margin-top: 0.9rem; }
.pv-note {
  color: var(--muted, #777);
  font-size: 0.85rem;
  max-width: 70ch;
}
.pv-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}
.pv-table th,
.pv-table td {
  text-align: left;
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--line, #e2e2e2);
  vertical-align: top;
}
.pv-err {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
  overflow-wrap: anywhere;
  max-width: 34ch;
}

/* v1.52 → v1.53: provider panel additions — the live model id per row and the
   model catalogue listing. */
.pv-model {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
  color: var(--muted, #777);
  overflow-wrap: anywhere;
}
.pv-models {
  columns: 2;
  column-gap: 1.5rem;
  margin: 0.3rem 0 0.8rem;
  padding-left: 1.1rem;
  font-size: 0.82rem;
}
.pv-models li { break-inside: avoid; }
@media (max-width: 640px) {
  .pv-models { columns: 1; }
}

/* ------------------------------------------------------------------
   v1.55 — match progress (visitor-facing) and the Master sub-tabs.
   ------------------------------------------------------------------ */
.mp-wrap { max-width: 62ch; margin: 0.5rem 0 1rem; }
.mp-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--line, #e4e4e4);
  overflow: hidden;
  margin: 0.55rem 0 0.35rem;
}
.mp-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--accent, #3b6ea5);
  /* Matches the 250ms sampling interval, so the bar glides instead of ticking. */
  transition: width 0.25s linear;
}
.mp-text { font-weight: 500; }
.mp-foot {
  color: var(--muted, #777);
  font-size: 0.85rem;
  margin: 0;
}
@media (prefers-reduced-motion: reduce) {
  .mp-fill { transition: none; }
}

.db-tabs {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line, #e2e2e2);
  margin: 0 0 1.2rem;
}
.db-tab {
  background: none;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  padding: 0.5rem 0.9rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--muted, #777);
  cursor: pointer;
  margin-bottom: -1px;
}
.db-tab.is-on {
  color: inherit;
  border-color: var(--line, #e2e2e2);
  background: var(--card, #fff);
}

/* =========================================================================
 * v1.57 — one spine, and the chat skin over its guided depth
 *
 * The controls that used to be split between a wizard topbar and a tab rail
 * now sit in one row under the station bar: how deep (guided / full detail)
 * and, inside the guided depth, how to answer (steps / chat). They are
 * deliberately quiet — the station bar is the navigation, these only change
 * how much of a station you are shown.
 * ===================================================================== */

.journey-modes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.55rem 0 0.1rem;
}
.journey-modes:empty { display: none; }

.depth-toggle, .chat-toggle {
  display: inline-flex;
  background: var(--surface, #f4f5f8);
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 999px;
  padding: 2px;
}
.depth-btn, .chat-btn {
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--muted);
  background: transparent;
  border: none;
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  cursor: pointer;
  white-space: nowrap;
}
.depth-btn:hover:not([disabled]), .chat-btn:hover { color: var(--text); }
.depth-btn.on, .chat-btn.on {
  background: var(--card, #fff);
  color: var(--secondary);
  box-shadow: 0 1px 2px rgba(20, 20, 50, 0.12);
}
.depth-btn[disabled] { opacity: 0.4; cursor: default; }
.depth-btn:focus-visible, .chat-btn:focus-visible { outline: 2px solid var(--secondary); outline-offset: 1px; }

/* The description, folded away while a diagnosis is live. */
.journey-query {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0 0 0.6rem;
  font-size: 0.88rem;
  color: var(--muted);
}
.journey-query[hidden] { display: none; }
.journey-query .jq-label { font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.72rem; }
.journey-query .jq-text {
  color: var(--text);
  font-style: italic;
  /* A long description must not push Edit off the row on a phone. */
  flex: 1 1 14rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* The guided depth as a panel of the workspace, rather than a card of its own.
   It no longer needs the shell's border and shadow — the workspace provides
   the frame, and doubling it made the guided screens look like a dialog that
   had opened on top of the tool. */
.diag-panel-guided { padding: 0; }
.diag-panel-guided .wizard-body { padding: 1.2rem 0 1.4rem; }
@media (max-width: 640px) {
  .diag-panel-guided .wizard-body { padding: 0.9rem 0 1.1rem; }
}

/* ------------------------------ chat mode ------------------------------
 * A transcript with the live screen as its last bubble. The live bubble is
 * the ordinary wizard step, unchanged — these rules only restyle it, which is
 * what keeps the two renderings honestly identical underneath. */
.wizard-root.chat {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-height: min(72vh, 680px);
}
.chat-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.2rem 0.1rem 0.4rem;
  scroll-behavior: smooth;
}
.ch-turn { display: flex; margin: 0 0 0.55rem; }
.ch-turn.you { justify-content: flex-end; }
.ch-bubble {
  max-width: 44rem;
  padding: 0.6rem 0.85rem;
  border-radius: 14px;
  font-size: 0.95rem;
  line-height: 1.5;
}
.ch-turn.bot > .ch-bubble {
  background: var(--surface, #f4f5f8);
  border: 1px solid var(--border, #e3e6ec);
  border-bottom-left-radius: 4px;
}
.ch-turn.you > .ch-bubble {
  background: var(--primary);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.ch-bubble.ch-miss { color: var(--muted); font-style: italic; }

/* The live step. Same markup as steps mode; it just has to read as something
   the tool is saying rather than as a page. */
.ch-turn.chat-live {
  display: block;
  background: var(--surface, #f4f5f8);
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 14px 14px 14px 4px;
  padding: 0.9rem 1rem 1rem;
}
.ch-turn.chat-live .wizard-step > h3 {
  font-size: 1.05rem;
  margin: 0 0 0.35rem;
}
.ch-turn.chat-live .wizard-sub { font-size: 0.88rem; margin: 0.25rem 0 0.5rem; }
/* The running echo of earlier answers is what the transcript IS in chat mode,
   so showing it again inside the live bubble says everything twice. */
.ch-turn.chat-live .wizard-answered { display: none; }
/* Options become reply chips: a row that wraps, not a stack of full-width
   cards, because a chip row is what "pick one and carry on" looks like. */
.ch-turn.chat-live .wizard-opts,
.ch-turn.chat-live .wizard-picks {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.6rem 0 0.3rem;
}
.ch-turn.chat-live .wizard-opt {
  flex: 0 1 auto;
  max-width: 100%;
  border-radius: 999px;
  padding: 0.4rem 0.85rem;
}
.ch-turn.chat-live .wizard-opt .wo-desc {
  /* The example belongs on the chip's tooltip, not in a chat bubble: the whole
     point of the chip row is that the next thing to say fits on one line. */
  display: none;
}
.ch-turn.chat-live .wizard-actions { margin-top: 0.7rem; }

/* The composer. Pinned under the transcript, so a long conversation scrolls
   past it rather than pushing it off the screen. */
.chat-composer {
  display: flex;
  gap: 0.45rem;
  flex: 0 0 auto;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border, #e3e6ec);
}
.chat-composer input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 0.95rem;
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--border, #d5d9e0);
  border-radius: 999px;
  background: var(--card, #fff);
  color: var(--text);
}
.chat-composer input:focus { outline: 2px solid var(--secondary); outline-offset: -1px; }
.chat-composer button {
  flex: 0 0 auto;
  border-radius: 999px;
  padding: 0.55rem 1.1rem;
}
.chat-composer-note {
  flex: 0 0 auto;
  margin: 0.3rem 0 0;
  font-size: 0.75rem;
  color: var(--muted);
}

@media (max-width: 560px) {
  .wizard-root.chat { max-height: none; }
  .chat-scroll { overflow-y: visible; }
  .ch-bubble { font-size: 0.92rem; }
}

/* The selected-state tick is drawn over the chip's right edge, so a chip needs
   room for it that a full-width option card did not. */
.ch-turn.chat-live .wizard-opt.selected { padding-right: 2.1rem; }

/* =========================================================================
 * v1.58 — "Talk it through": the diagnostic as a conversation
 *
 * A tinted room with one column in it. No tab bar, no toggles, no rail: the
 * whole design argument of this surface is that a first-timer should have
 * exactly one thing to do at any moment, and every control on screen is a
 * promise of complexity made before they have done anything.
 * ===================================================================== */

.dlg-shell {
  max-width: 780px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  background: var(--card, #fff);
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 16px;
  box-shadow: 0 8px 30px rgba(20, 20, 50, 0.07);
  overflow: hidden;
  /* Tall enough to feel like a room, short enough that the composer and the
     newest turn are both on screen without scrolling the page. */
  height: min(78vh, 760px);
}

.dlg-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  border-bottom: 1px solid var(--border, #e3e6ec);
  background: var(--card, #fff);
}
.dlg-head-title { display: flex; gap: 0.7rem; align-items: flex-start; }
.dlg-head h2 { margin: 0; font-size: 1.05rem; }
.dlg-head p { margin: 0.15rem 0 0; font-size: 0.85rem; color: var(--muted); max-width: 46ch; }
.dlg-head-mark {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 1.05rem;
}
.dlg-restart {
  flex: none;
  background: none;
  border: 1px solid var(--border, #d5d9e0);
  border-radius: 999px;
  padding: 0.32rem 0.8rem;
  font-size: 0.8rem;
  color: var(--muted);
  cursor: pointer;
}
.dlg-restart:hover { border-color: var(--primary); color: var(--primary); }

/* v1.61 — a second header action (Save conversation) sits beside Start
   again; grouping both in their own flex row keeps the title | actions
   two-column layout of .dlg-head intact. */
.dlg-head-actions { display: flex; align-items: center; gap: 0.5rem; flex: none; }
.dlg-save {
  flex: none;
  background: none;
  border: 1px solid var(--border, #d5d9e0);
  border-radius: 999px;
  padding: 0.32rem 0.8rem;
  font-size: 0.8rem;
  color: var(--muted);
  cursor: pointer;
}
.dlg-save:hover { border-color: var(--primary); color: var(--primary); }

/* The tint. It is the one piece of pure atmosphere here and it earns its
   place: it marks the transcript as a different kind of space from the rest of
   the site, which is most of what tells someone they are in a conversation
   rather than on a page. */
.dlg-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1.1rem 1.1rem 0.6rem;
  /* --surface is white in this theme, so the tint is mixed from the brand
     colour rather than taken from a token. Without it the bot's white bubbles
     sit on a white field and the transcript loses its shape entirely — the
     tint is not decoration here, it is what separates one speaker's turns
     from the room they are in. */
  background:
    radial-gradient(130% 55% at 50% 0%, color-mix(in srgb, var(--primary) 9%, transparent), transparent 72%),
    color-mix(in srgb, var(--primary) 4%, #f3f4f7);
  scroll-behavior: smooth;
}

/* v1.67 — "Share your ideas" is a different room from "Work through an issue",
   and it has to be legible as one at a glance: the reader arrives here
   mid-thought from the other conversation and must not think they have been
   sent back to the start. Tint only — same shell, same rhythm, same composer —
   because the point is a change of PLACE, not of tool. Colour is never the only
   cue: the banner and the ✎ glyph carry it for anyone who cannot see the tint. */
.dlg-shell--propose .dlg-scroll {
  background:
    radial-gradient(130% 55% at 50% 0%, color-mix(in srgb, var(--secondary) 12%, transparent), transparent 72%),
    color-mix(in srgb, var(--secondary) 5%, #f5f4f0);
}
.dlg-shell--propose .dlg-head-mark { background: var(--secondary); }
.dlg-shell--propose .dlg-av { background: var(--secondary); }
.dlg-room-note {
  margin: 0;
  padding: 0.5rem 1.1rem;
  font-size: 0.82rem;
  color: var(--muted);
  background: color-mix(in srgb, var(--secondary) 8%, transparent);
  border-bottom: 1px solid var(--border, #e3e6ec);
}
@media print {
  .dlg-shell--propose .dlg-scroll { background: none; }
  .dlg-room-note { background: none; }
}

.dlg-turn { display: flex; gap: 0.55rem; margin: 0 0 0.7rem; align-items: flex-end; }
.dlg-turn.you { justify-content: flex-end; }
.dlg-av {
  flex: none;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  margin-bottom: 0.15rem;
}
/* Only the first bubble of a run needs the avatar; consecutive ones are the
   same speaker still talking, and a column of identical circles reads as
   interruption rather than continuation. */
.dlg-turn.bot + .dlg-turn.bot .dlg-av { visibility: hidden; }

.dlg-bubble {
  max-width: 42rem;
  padding: 0.65rem 0.9rem;
  border-radius: 16px;
  font-size: 0.95rem;
  line-height: 1.55;
  background: var(--card, #fff);
  border: 1px solid var(--border, #e3e6ec);
  border-bottom-left-radius: 5px;
  box-shadow: 0 1px 2px rgba(20, 20, 50, 0.04);
}
.dlg-turn.you .dlg-bubble {
  background: var(--primary);
  color: #fff;
  border-color: transparent;
  border-bottom-left-radius: 16px;
  border-bottom-right-radius: 5px;
}
.dlg-bubble p { margin: 0.5rem 0 0; }
.dlg-bubble p:first-child { margin-top: 0; }

/* v1.61 — going back to change an answer. The bubble itself is the hit
   target, so the affordance scales with the reply instead of adding a
   separate control per turn; the pencil only shows on hover/focus so the
   transcript does not read as though every line is up for negotiation. */
.dlg-turn.you.dlg-editable { cursor: pointer; }
.dlg-turn.you.dlg-editable .dlg-bubble { transition: box-shadow 0.15s ease; }
.dlg-turn.you.dlg-editable:hover .dlg-bubble,
.dlg-turn.you.dlg-editable:focus-visible .dlg-bubble {
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.6) inset, 0 2px 10px rgba(20, 20, 50, 0.22);
}
.dlg-turn.you.dlg-editable:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; border-radius: 16px; }
.dlg-edit-hint {
  display: inline-block;
  margin-left: 0.4rem;
  font-size: 0.82em;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.dlg-turn.you.dlg-editable:hover .dlg-edit-hint,
.dlg-turn.you.dlg-editable:focus-visible .dlg-edit-hint { opacity: 0.75; }

/* Asides — "that changes things", "one thing to be straight about". Said in a
   quieter voice because they are commentary on the conversation rather than a
   move in it, and a reader should be able to skip them without losing the
   thread. */
.dlg-turn.aside .dlg-bubble {
  background: transparent;
  border-style: dashed;
  color: var(--muted);
  font-size: 0.88rem;
  box-shadow: none;
}
.dlg-quiet { color: var(--muted); font-size: 0.88rem; }

.dlg-typing { display: inline-flex; gap: 0.28rem; align-items: center; padding: 0.8rem 0.9rem; }
.dlg-typing span {
  width: 0.42rem;
  height: 0.42rem;
  border-radius: 50%;
  background: var(--muted);
  opacity: 0.45;
  animation: dlgBlink 1.1s infinite ease-in-out;
}
.dlg-typing span:nth-child(2) { animation-delay: 0.16s; }
.dlg-typing span:nth-child(3) { animation-delay: 0.32s; }
@keyframes dlgBlink {
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
  40% { opacity: 0.9; transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
  .dlg-typing span { animation: none; }
  .dlg-scroll { scroll-behavior: auto; }
}

/* Replies. A row when they are short, a stack when they are sentences — a
   three-line chip in a wrapping row is unreadable, and a one-word chip in a
   stack looks like a menu. */
.dlg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.9rem 2.25rem;
  justify-content: flex-end;
}
.dlg-chips.stack { flex-direction: column; align-items: flex-end; }
/* A stacked reply is a sentence, so it needs room; a stacked SHORT reply is
   just a menu item and should not stretch to the full width of the room. */
.dlg-chips.stack .dlg-chip { max-width: 100%; }
.dlg-chip {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: left;
  color: var(--primary);
  background: var(--card, #fff);
  border: 1.5px solid color-mix(in srgb, var(--primary) 35%, transparent);
  border-radius: 999px;
  padding: 0.45rem 0.95rem;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.dlg-chips.stack .dlg-chip { border-radius: 14px; }
.dlg-chip:hover:not([disabled]) { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.dlg-chip.quiet { color: var(--muted); border-color: var(--border, #d5d9e0); font-weight: 500; }
.dlg-chip:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; }
.dlg-chip.chosen, .dlg-chip.toggle.chosen {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}
.dlg-chip.done { align-self: flex-end; }
/* A spent row is removed from the DOM (see dlgChips). The rule survives only
   for the instant between the class landing and the node going, so a row
   cannot flash as interactive while it is being taken away. */
.dlg-chips.spent { display: none; }

/* Folded detail — the entire disclosure budget of a question turn. */
.dlg-fold { margin-top: 0.5rem; }
.dlg-fold > summary {
  cursor: pointer;
  font-size: 0.82rem;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  list-style: none;
}
.dlg-fold > summary::-webkit-details-marker { display: none; }
.dlg-fold > summary::before { content: "＋ "; }
.dlg-fold[open] > summary::before { content: "－ "; }
.dlg-fold > summary:hover { color: var(--primary); }
.dlg-fold > div { margin-top: 0.4rem; font-size: 0.88rem; color: var(--text); }
.dlg-ex { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.88rem; }
.dlg-ex li { margin: 0.25rem 0; }
.dlg-kv { list-style: none; margin: 0.5rem 0 0; padding: 0; font-size: 0.9rem; }
.dlg-kv li { display: flex; gap: 0.5rem; justify-content: space-between; padding: 0.2rem 0; border-bottom: 1px dotted var(--border); }
.dlg-kv li:last-child { border-bottom: none; }
.dlg-kv-k { color: var(--muted); }

/* The answer. The one bubble allowed to look like an arrival. */
.dlg-answer { margin: -0.1rem 0; }
.dlg-answer h3 { margin: 0 0 0.3rem; font-size: 1.1rem; color: var(--primary); }
.dlg-trial {
  margin-top: 0.5rem !important;
  padding: 0.5rem 0.7rem;
  background: color-mix(in srgb, var(--primary) 6%, transparent);
  border-left: 3px solid var(--primary);
  border-radius: 0 8px 8px 0;
  font-size: 0.92rem;
}

.dlg-composer {
  flex: 0 0 auto;
  display: flex;
  gap: 0.5rem;
  padding: 0.7rem 1.1rem;
  border-top: 1px solid var(--border, #e3e6ec);
  background: var(--card, #fff);
}
.dlg-composer input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 0.95rem;
  padding: 0.6rem 0.95rem;
  border: 1px solid var(--border, #d5d9e0);
  border-radius: 999px;
  background: var(--surface, #f4f5f8);
  color: var(--text);
}
.dlg-composer input:focus { outline: 2px solid var(--secondary); outline-offset: -1px; background: var(--card, #fff); }
.dlg-composer input:disabled { opacity: 0.55; cursor: not-allowed; }
.dlg-composer button { flex: 0 0 auto; border-radius: 999px; padding: 0.6rem 1.2rem; }
.dlg-foot {
  margin: 0;
  padding: 0.45rem 1.1rem 0.6rem;
  font-size: 0.75rem;
  color: var(--muted);
  background: var(--card, #fff);
  border-top: 1px solid var(--border, #e3e6ec);
}

.tab-beta {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: 0.35em;
  opacity: 0.75;
}

/* v1.66 — on a phone there is ONE scroller, and it is the page.
 *
 * The bug this replaces: .dlg-shell was height:auto here, so #dlgScroll never
 * got a bounded height and could never scroll its own content — while it kept
 * overflow-y:auto and overscroll-behavior:contain from the desktop rule, which
 * makes it a scroll container with nothing to scroll. A touch drag starting
 * inside the transcript was therefore swallowed by a box that could not move,
 * and `contain` stopped it chaining to the page, so the conversation sat still
 * under the finger. Dragging the header or the footer line worked, which is
 * what made it read as intermittent; pinch-zooming escaped it entirely,
 * because panning a zoomed visual viewport is not scrolling at all — exactly
 * the two-finger workaround readers found.
 *
 * Nesting a scroller inside an unbounded box IS the trap, so the fix is to
 * stop nesting one. The transcript overflows visibly, the page scrolls it, and
 * the composer sticks to the bottom of the viewport so the reply box stays
 * reachable without scrolling to the end. dlgScroll() / pdlgScroll() detect
 * that the transcript is no longer its own scroller and move the page instead.
 *
 * .dlg-shell must be overflow:visible here and not merely unbounded: an
 * overflow:hidden ancestor is itself a scrollport, and a sticky child inside
 * one sticks to a box that never scrolls — i.e. not at all. */
@media (max-width: 640px) {
  .dlg-shell {
    height: auto;
    min-height: 0;
    overflow: visible;
    border-radius: 0;
    border-left: none;
    border-right: none;
  }
  .dlg-scroll {
    flex: 0 0 auto;
    overflow: visible;
    overscroll-behavior: auto;
    /* Smooth scrolling belongs to a box the app scrolls itself. The page is
       scrolled by the finger here, and a smooth-behaviour page fights a drag
       that arrives while an app-driven scroll is still animating. */
    scroll-behavior: auto;
    padding-bottom: 0.9rem;
  }
  .dlg-composer {
    position: sticky;
    bottom: 0;
    z-index: 3;
    box-shadow: 0 -6px 18px rgba(20, 20, 50, 0.06);
    padding-bottom: calc(0.7rem + env(safe-area-inset-bottom, 0px));
  }
  .dlg-head p { display: none; }
  .dlg-head-actions { gap: 0.35rem; }
  .dlg-save, .dlg-restart { padding: 0.3rem 0.55rem; font-size: 0.72rem; }
  .dlg-bubble { font-size: 0.92rem; }
  .dlg-chips { margin-left: 0; }
  .dlg-chips.stack .dlg-chip { width: 100%; }
}

/* ===================== SUPPORT (v1.64) =====================
   The support view borrows .legal-body / .legal-block for its typography on
   purpose — it is the same kind of page, read in the same way, and a second
   set of prose rules would drift from the first. Only what is genuinely new
   is styled here: the two buttons, the fact list and the footer route in. */
.support-actions {
  margin: 1.4rem 0 1.8rem;
}
.support-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}
.support-btn {
  display: inline-block;
  padding: 0.7rem 1.4rem;
  border-radius: var(--radius);
  background: var(--primary);
  color: #fff;
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  border: 1px solid var(--primary);
  transition: filter 0.15s ease;
}
.support-btn:hover {
  filter: brightness(1.08);
  text-decoration: none;
}
.support-btn:focus-visible {
  outline: 3px solid var(--secondary);
  outline-offset: 2px;
}
.support-btn.secondary {
  background: var(--surface);
  color: var(--primary);
}
.support-note,
.support-pending {
  margin: 0.8rem 0 0;
  font-size: 0.86rem;
  color: var(--muted);
  max-width: 60ch;
}
.support-pending {
  padding: 0.7rem 0.9rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.support-facts {
  margin: 0.6rem 0 0;
  padding-left: 1.1rem;
}
.support-facts li {
  margin-bottom: 0.55rem;
  line-height: 1.55;
}
/* An inline "link" that is really a button, because it switches view rather
   than navigating — same trick, and same look, as the footer legal links. */
.legal-inline-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--primary);
  text-decoration: underline;
  cursor: pointer;
}
/* The footer route in. .footer-contact-btn is written for a <button>; this is
   an <a> because #support is a real address worth copying and opening in a
   new tab, so only the anchor defaults need neutralising. */
.footer-support-link {
  text-decoration: none;
  display: inline-block;
}
@media (max-width: 560px) {
  .support-btn-row .support-btn {
    flex: 1 1 100%;
    text-align: center;
  }
}

/* ===================== ONE READ (v1.65) =====================
   The finished diagnosis is one scroll of named sections rather than five
   tabs. Two rules carry the whole design: a closed section must say what is
   inside it (so folding is not hiding), and the answer must never be folded.

   NOTE: the .wizard-* / .diag-tab* / .depth-* / .chat-* blocks earlier in this
   file are DEAD as of v1.65 — the guided wizard, the station bar and the depth
   toggle are gone. They are left in place for one release rather than cut
   blind: this file has a documented history of a truncated declaration
   silently nesting ~250 lines of rules inside the previous selector, and that
   failure is invisible to a brace check. Remove them in a release where the
   result can be looked at. */
.read-glance {
  margin: 0 0 1.1rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--border);
  border-left: 4px solid var(--primary);
  border-radius: var(--radius);
  background: var(--surface);
}
.read-glance-title {
  margin: 0 0 0.5rem;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.read-glance dl {
  display: grid;
  grid-template-columns: minmax(8rem, auto) 1fr;
  gap: 0.3rem 0.9rem;
  margin: 0;
}
.read-glance dt { color: var(--muted); font-size: 0.86rem; }
.read-glance dd { margin: 0; font-weight: 600; font-size: 0.94rem; }
.read-glance .cid { font-weight: 400; color: var(--muted); font-size: 0.82rem; }

.read-sections { display: flex; flex-direction: column; gap: 0.7rem; }
.read-sec {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  /* The slim header is fixed and ~53px tall once scrolled; without this a
     scrollIntoView parks the heading behind it. */
  scroll-margin-top: 4.2rem;
}
.read-sec-lead { border-color: var(--primary); }
.read-sec > summary {
  cursor: pointer;
  padding: 0.85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  list-style: none;
}
.read-sec > summary::-webkit-details-marker { display: none; }
.read-sec > summary::after {
  content: "⌄";
  position: absolute;
  right: 1rem;
  color: var(--muted);
  transition: transform 0.15s ease;
}
.read-sec > summary { position: relative; padding-right: 2.4rem; }
.read-sec[open] > summary::after { transform: rotate(180deg); }
.read-sec > summary:hover .read-sec-title { color: var(--primary); }
.read-sec > summary:focus-visible { outline: 3px solid var(--secondary); outline-offset: -3px; }
.read-sec-title { font-weight: 700; font-size: 1.02rem; color: var(--text); }
.read-sec-hint { color: var(--muted); font-size: 0.86rem; font-weight: 400; }
/* The lead section has no summary, so its heading carries the same padding. */
.read-sec-lead > .read-sec-title { display: block; margin: 0; padding: 0.85rem 1rem 0; }
.read-sec[open] > *:not(summary),
.read-sec-lead > *:not(.read-sec-title) { padding: 0 1rem 1rem; }
/* Panels already carry their own .panel-card padding, so the wrapper only adds
   the gutter — anything doubling up reads as an indent nobody intended. */
.read-sec .panel-card { border: none; padding: 0; background: none; box-shadow: none; }

.read-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: space-between;
  margin-top: 1.2rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}
.read-foot-back {
  background: var(--surface);
  color: var(--primary);
  border: 1px solid var(--border);
}
.rp-sub { color: var(--muted); font-size: 0.92rem; }
@media (max-width: 560px) {
  .read-glance dl { grid-template-columns: 1fr; gap: 0.1rem 0; }
  .read-glance dt { margin-top: 0.4rem; }
  .read-foot { flex-direction: column; }
}

/* One first move, then the rest (v1.65). The lead card carries the emphasis the
   whole section is for; the disclosure below it borrows .reco-escalate's look,
   because "more options" and "options out of reach" are the same gesture and
   should not look like two different ones. */
.reco-lead .reco-card {
  border-color: var(--primary);
  box-shadow: 0 2px 12px rgba(69, 39, 160, 0.09);
}
.reco-rest,
.reco-escalate {
  margin-top: 0.9rem;
}
.reco-rest > summary {
  cursor: pointer;
  padding: 0.6rem 0.2rem;
  color: var(--muted);
  font-size: 0.92rem;
}
.reco-rest > summary:hover { color: var(--primary); }
.reco-rest .re-count {
  display: inline-block;
  min-width: 1.5rem;
  padding: 0.05rem 0.4rem;
  margin-right: 0.3rem;
  border-radius: 999px;
  background: var(--border);
  color: var(--text);
  font-weight: 700;
  text-align: center;
}
.reco-rest .re-hint { color: var(--faint, var(--muted)); }

/* The ranking's caveat, folded (v1.65). It is the same content as before and
   in the same place in the reading order — after the answer, not in front of
   it — with one line visible so nobody has to open it to know it is there.
   The report renders it flat: paper has no disclosures. */
details.unanswered-note > summary {
  cursor: pointer;
  padding: 0.55rem 0.7rem;
  font-size: 0.9rem;
  color: var(--text);
  list-style: none;
}
details.unanswered-note > summary::-webkit-details-marker { display: none; }
details.unanswered-note .ua-more {
  color: var(--primary);
  text-decoration: underline;
  margin-left: 0.3rem;
  font-size: 0.86rem;
}
details.unanswered-note[open] > summary { border-bottom: 1px solid var(--border); margin-bottom: 0.4rem; }
details.unanswered-note .unanswered-head { display: none; }

/* v1.65 — [hidden] must actually hide these two.
   `.symptom-input-row { display: flex }` and `.view-intro { display: block }`
   both out-specify the UA's `[hidden] { display: none }` rule, so the v1.57
   "fold the description away once a diagnosis is live" behaviour set the
   attribute and changed nothing on screen: every reader has had an empty
   description box sitting above their finished answer since that release. Same
   trap the .rec-was rule above documents. */
.symptom-input-row[hidden],
.view-intro[hidden] { display: none; }

/* The take-away call to action (v1.65). */
.read-take-cta { padding: 0 1rem 1rem; }
.read-take-cta[hidden] { display: none; }

/* ===========================================================================
 * v1.68
 * ======================================================================== */

/* --- The first move, folded (see renderRecommendation in app.js) ---------
 * The closed state has to read as a door and not as a boundary, which is why
 * the hint sits in the summary rather than inside: a disclosure that does not
 * say what it holds is a disclosure nobody opens. */
.reco-more { margin: 0.55rem 0 0; }
.reco-more > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--secondary);
  padding: 0.3rem 0;
}
.reco-more > summary::-webkit-details-marker { display: none; }
.reco-more > summary::before {
  content: "›";
  display: inline-block;
  transition: transform 0.15s ease;
  font-weight: 700;
}
.reco-more[open] > summary::before { transform: rotate(90deg); }
.reco-more > summary:hover { text-decoration: underline; }
.reco-more > summary:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; border-radius: 4px; }
.reco-more-hint { font-weight: 400; color: var(--muted); font-size: 0.8rem; }
.reco-more-body { border-top: 1px solid var(--border, #e3e6ec); padding-top: 0.6rem; margin-top: 0.1rem; }
.reco-card .tera-lead { margin: 0.7rem 0 0.1rem; font-size: 0.85rem; color: var(--muted); }
@media (prefers-reduced-motion: reduce) {
  .reco-more > summary::before { transition: none; }
}

/* --- The conversation narrates the wait (dialog.js dlgProgressBubble) -----
 * app.js's match-progress markup, reframed for a speech bubble: the same
 * narration and the same budget bar the questionnaire has shown since v1.55,
 * with the bubble's own padding doing the work the panel's box used to. */
.dlg-progress-bubble { min-width: min(20rem, 72vw); }
.dlg-progress .mp-wrap { margin: 0; }
.dlg-progress .mp-text { font-size: 0.93rem; }
.dlg-progress .mp-bar {
  height: 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  overflow: hidden;
  margin: 0.55rem 0 0.4rem;
}
.dlg-progress .mp-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--primary);
  transition: width 0.25s linear;
}
.dlg-progress .mp-foot { margin: 0; font-size: 0.78rem; color: var(--muted); line-height: 1.45; }
@media (prefers-reduced-motion: reduce) {
  .dlg-progress .mp-fill { transition: none; }
}

/* --- "Three things you can do with it now" (dialog.js dlgSayWhatNow) ----- */
ul.dlg-next { margin: 0.2rem 0 0; padding-left: 1.05rem; }
ul.dlg-next li { margin: 0.35rem 0; line-height: 1.5; }
ul.dlg-next b { color: var(--secondary); }

/* --- The verdict line, on screen ----------------------------------------
 * Its print twin lives in the report's own inline stylesheet (app.js); this
 * is the on-screen protocol's copy. Kept visually distinct from a bordered
 * callout: it is the document speaking, not an aside. */
.result-protocol .verdict {
  margin: 0 0 1rem;
  padding: 0 0 0 0.9rem;
  border-left: 4px solid var(--secondary);
  font-size: 1rem;
  line-height: 1.6;
}
.result-protocol .verdict b { color: var(--secondary); }

/* ============================================================
   v1.69 — SETTINGS MENU
   Language, detail mode, role, support and the two version
   numbers, behind one ⚙ in the banner. The controls inside are
   the same elements that used to sit loose across the header,
   so the rules above for .lang-switch / .mode-switch /
   .role-switch still apply; these only lay out the panel.
   The panel is positioned relative to its own button rather
   than to the header, so it stays put when the header wraps on
   a narrow screen.
   ============================================================ */
.settings-menu { position: relative; display: inline-flex; }

.settings-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(255,255,255,0.14);
  border: 1px solid rgba(255,255,255,0.3);
  color: #fff;
  border-radius: 999px;
  padding: 0.35rem 0.8rem;
  font-size: 0.85rem;
  cursor: pointer;
}
.settings-btn:hover { background: rgba(255,255,255,0.24); }
.settings-gear { font-size: 1rem; line-height: 1; }
.settings-menu.is-open .settings-btn { background: #fff; color: var(--primary); font-weight: 600; }

.settings-panel {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 60;
  min-width: 17rem;
  padding: 0.9rem 1rem 1rem;
  border-radius: 10px;
  background: var(--surface, #fff);
  color: var(--text, #1a1a1a);
  border: 1px solid var(--border, rgba(0,0,0,0.12));
  box-shadow: 0 14px 38px rgba(0,0,0,0.26);
  text-align: left;
}
.settings-panel[hidden] { display: none; }

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  margin: 0 0 0.6rem;
}
.settings-label {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--muted, #666);
}
.settings-label label { font: inherit; color: inherit; }

/* The two pill toggles were built white-on-dark for the banner; inside the
   panel they sit on a light surface and need their own colours. */
.settings-panel .lang-switch,
.settings-panel .mode-switch { border-color: var(--border, rgba(0,0,0,0.2)); }
.settings-panel .lang-btn,
.settings-panel .mode-btn { color: var(--text, #1a1a1a); opacity: 0.75; }
.settings-panel .lang-btn.active,
.settings-panel .mode-btn.active { background: var(--primary); color: #fff; opacity: 1; }
.settings-panel .role-switch select { border: 1px solid var(--border, rgba(0,0,0,0.2)); }

.settings-note {
  margin: -0.2rem 0 0.7rem;
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--muted, #666);
}
.settings-sep { border: none; border-top: 1px solid var(--border, rgba(0,0,0,0.1)); margin: 0.7rem 0; }

.settings-support {
  display: block;
  width: 100%;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  color: var(--primary);
  font-size: 0.86rem;
  font-weight: 600;
  cursor: pointer;
}
.settings-support:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }

.settings-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.7rem;
  margin: 0;
  font-size: 0.78rem;
}
.settings-meta dt { color: var(--muted, #666); }
.settings-meta dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 600; }

/* The panel is a menu, not a drawer: on a phone it pins to the right edge of
   the viewport rather than growing past it. */
@media (max-width: 480px) {
  .settings-btn-label { display: none; }
  .settings-panel { min-width: 15rem; max-width: calc(100vw - 2rem); }
}

/* ============================================================
   v1.69 — COMMUNITY SIGNAL PANEL (Master Dashboard)
   Ratings and "this rings true" taps. Master-only, so it is
   inside the data-i18n="skip" dashboard and is not translated.
   ============================================================ */
.sig-wrap { margin: 0 0 1.4rem; }
.sig-bars { display: grid; gap: 0.35rem; margin: 0.3rem 0 0.6rem; max-width: 34rem; }
.sig-bar-row { display: grid; grid-template-columns: 8.5rem 1fr 6rem; align-items: center; gap: 0.6rem; font-size: 0.85rem; }
.sig-bar-label { color: var(--muted); }
.sig-bar { display: block; height: 0.6rem; border-radius: 999px; background: var(--border); overflow: hidden; }
.sig-bar-fill { display: block; height: 100%; border-radius: 999px; background: var(--primary); }
.sig-bar-fill.spot { background: #2e9e5b; }
.sig-bar-fill.rough { background: #d9a325; }
.sig-bar-fill.off { background: #c1503f; }
.sig-bar-n { font-variant-numeric: tabular-nums; color: var(--muted); font-size: 0.8rem; }
.sig-note { color: var(--muted); font-size: 0.82rem; margin: 0.2rem 0 0.9rem; }

.sig-cards { display: grid; gap: 0.6rem; }
.sig-card { border: 1px solid var(--border); border-left-width: 4px; border-radius: 8px; padding: 0.7rem 0.9rem; background: var(--surface); }
.sig-card.spot { border-left-color: #2e9e5b; }
.sig-card.rough { border-left-color: #d9a325; }
.sig-card.off { border-left-color: #c1503f; }
.sig-card-head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.sig-comment { margin: 0.5rem 0 0; font-size: 0.93rem; line-height: 1.5; }
.sig-meta { margin: 0.4rem 0 0; font-size: 0.82rem; color: var(--muted); }
.sig-desc { margin: 0.4rem 0 0; font-size: 0.82rem; color: var(--muted); }
.sig-desc summary { cursor: pointer; }

.sig-table { width: 100%; border-collapse: collapse; font-size: 0.87rem; margin: 0.3rem 0 0.8rem; }
.sig-table th, .sig-table td { text-align: left; padding: 0.35rem 0.6rem; border-bottom: 1px solid var(--border); }
.sig-type { color: var(--muted); font-size: 0.8rem; }
.sig-n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }

/* v1.69 — the "picking up where you left off" line after a language switch.
   Quiet: it is a note about the machinery, not something anybody said. */
.dlg-bubble.dlg-resumed { font-style: italic; opacity: 0.75; }

/* The slim bar's route back to the settings panel (v1.69). */
.slim-gear {
  background: rgba(255,255,255,0.16);
  border: 1px solid rgba(255,255,255,0.28);
  color: #fff;
  border-radius: 999px;
  width: 1.7rem;
  height: 1.7rem;
  line-height: 1;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0;
}
.slim-gear:hover { background: rgba(255,255,255,0.3); }

/* ============================================================
   v1.71 — "Why this option is on this pattern's list"
   The library's own reason for the pattern↔intervention link,
   distinct from the session's ranking explanation beside it.
   Given a quiet left rule rather than a box: it is context for
   what follows, not a callout competing with it.
   ============================================================ */
.why-here {
  margin: 0 0 0.8rem;
  padding: 0.1rem 0 0.1rem 0.8rem;
  border-left: 3px solid color-mix(in srgb, var(--primary) 35%, transparent);
}
.why-here .vlabel {
  margin: 0 0 0.2rem;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.why-here-text { margin: 0; font-size: 0.92rem; line-height: 1.5; }
/* Paper has no colour fidelity to spare and no hover, so the printed version
   keeps the label and drops the rule. */
.why-here.plain { border-left: none; padding-left: 0; }
.why-here.plain .vlabel { text-transform: none; letter-spacing: 0; font-weight: 700; }

/* The conversation states it as a sentence of its own, so it needs no frame —
   only the draft caveat under it, which .dlg-quiet already styles. */

/* v1.72 — the library's reason for a pattern↔option link, shown in the list
   where the link itself is shown. Indented under the name and set quieter than
   it: the name is what you scan, the reason is what you read when one of them
   stops you. */
.si-why {
  display: block;
  margin: 0.15rem 0 0.5rem;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--muted);
}
.iv-why-list { margin: 0.2rem 0 0.8rem; padding-left: 1.1rem; }
.iv-why-list > li { margin: 0 0 0.3rem; }

/* ============================================================
   v1.74 — THE SETTINGS PANEL ON A PHONE

   The panel is anchored to its own button (position:absolute,
   right:0 inside .settings-menu). On a narrow screen
   .header-controls wraps and that button can land near the LEFT
   edge — and right:0 then puts a 15rem panel's left edge off the
   side of the screen, where it cannot be scrolled to or reached.

   Two changes. The gear is pushed to the right of the controls
   row, so it is where a settings control belongs and lands in a
   predictable place. And below 640px the panel stops being
   anchored to the button at all: it is positioned against the
   HEADER, pinned to both side gutters, so its width and position
   no longer depend on where the button happened to wrap to.
   .site-header takes position:relative to be that anchor — it has
   no transform and no z-index, so this creates no stacking
   context and the panel's own z-index still clears the sticky
   nav beneath it.
   ============================================================ */
.settings-menu { margin-left: auto; }

@media (max-width: 640px) {
  header.site-header { position: relative; }
  .settings-menu { position: static; }
  .settings-panel {
    top: calc(100% - 0.4rem);
    left: 0.75rem;
    right: 0.75rem;
    min-width: 0;
    max-width: none;
  }
}

/* ============================================================
   v1.75 — CURATION WORKBENCH (Master Dashboard, third tab)
   Master-only, inside the data-i18n="skip" dashboard, so none
   of this is translated. A long list of one-field rows: the
   title is what you scan, the textarea is what you work in,
   and the dirty state has to be findable while scrolling.
   ============================================================ */
.cur-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin: 0.6rem 0 0.4rem;
}
.cur-controls .rec-select { max-width: 18rem; }
.cur-controls #curSearch { flex: 1 1 12rem; min-width: 10rem; }

.cur-count { color: var(--muted); font-size: 0.85rem; margin: 0 0 0.6rem; }
.cur-broken-note { color: var(--danger); font-weight: 600; }

.cur-list { display: grid; gap: 0.5rem; }

.cur-row {
  border: 1px solid var(--border);
  border-left: 4px solid transparent;
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  background: var(--surface);
}
/* Unsaved work has to be findable in a list of two hundred. */
.cur-row.is-dirty { border-left-color: var(--primary); background: color-mix(in srgb, var(--primary) 4%, var(--surface)); }
.cur-row.is-broken { border-left-color: var(--danger); }

.cur-row-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.8rem;
  margin: 0 0 0.35rem;
}
.cur-row-title { font-weight: 600; font-size: 0.9rem; }
.cur-row-id { color: var(--muted); font-size: 0.78rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

.cur-broken {
  margin: 0 0 0.4rem;
  font-size: 0.82rem;
  color: var(--danger);
  line-height: 1.45;
}

.cur-row-body { display: flex; gap: 0.8rem; align-items: flex-start; }
.cur-text {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 0.88rem;
  line-height: 1.45;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  resize: vertical;
}
.cur-text:disabled { background: rgba(0,0,0,0.04); color: var(--muted); }

.cur-row-side {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: flex-start;
  padding-top: 0.15rem;
}
.cur-reviewed { font-size: 0.82rem; white-space: nowrap; display: flex; align-items: center; gap: 0.35rem; }

/* Sticky, because the list is long and a footer that scrolls away is a footer
   nobody finds. */
.cur-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
  justify-content: space-between;
  margin-top: 0.8rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: 0 -6px 18px rgba(0,0,0,0.08);
}
.cur-bar[hidden] { display: none; }
.cur-bar-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }

@media (max-width: 640px) {
  .cur-row-body { flex-direction: column; }
  .cur-row-side { flex-direction: row; align-items: center; gap: 0.8rem; }
}

/* v1.76 — a curation row holds several fields now, each labelled, and a link
   row can be marked for removal. */
.cur-fields { flex: 1 1 auto; min-width: 0; display: grid; gap: 0.5rem; }
.cur-field { display: block; }
.cur-field-label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.15rem;
}
.cur-field .cur-text { width: 100%; box-sizing: border-box; }

.cur-row.is-unlinked { opacity: 0.72; border-left-color: var(--danger); }
.cur-unlinked-note {
  margin: 0 0 0.4rem;
  font-size: 0.82rem;
  color: var(--danger);
  font-weight: 600;
}

/* v1.79 — the report names the reader's own choice when it differs from the
   ranking's leader. Quiet, and never an apology: choosing against the ranking
   is a legitimate act by the person who knows the organisation. */
.reco-override {
  margin: 0.3rem 0 0.5rem;
  font-size: 0.85rem;
  font-style: italic;
  color: var(--muted);
}

/* ===========================================================================
 * v1.83 — Navigator labels wrap; the conversation links to what it names.
 * ======================================================================== */
.map-node text .map-node-id { font-weight: 700; opacity: 0.7; }
#mapSvg.has-selection .map-node.selected text .map-node-id { opacity: 0.9; }

.dlg-open-row { margin: 0.45rem 0 0; }
.dlg-open-link {
  background: none; border: 0; padding: 0; font: inherit; font-size: 0.85rem;
  color: var(--primary); cursor: pointer; text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px;
}
.dlg-open-link:hover, .dlg-open-link:focus-visible { text-decoration-thickness: 2px; }
.dlg-steps { margin: 0.4rem 0 0.2rem; padding-left: 1.3rem; }
.dlg-steps li { margin: 0.25rem 0; }
.dlg-phase { color: var(--muted); font-size: 0.8rem; }
.dlg-sub { margin: 0.6rem 0 0.1rem; font-weight: 600; font-size: 0.9rem; }
@media print { .dlg-open-link, .dlg-open-row:empty { display: none !important; } }

/* v1.85 — plain condition question first, framework name second. */
.dlg-q { margin: 0 0 0.3rem; font-weight: 600; }
.dlg-bubble p.dlg-quiet .term, .dlg-bubble b .term { font-size: inherit; }

/* ===================== v1.87 =====================
   (1) The organisation-profile check. Ten rows in one column plus ten stacked
   reply chips pushed the list off the top of the screen before it could be
   read. The list flows into two columns where the bubble is wide enough, and
   the chips flow as a row (see dlgMoveProfileCheck). */
.dlg-kv.cols { columns: 2 14rem; column-gap: 1.6rem; }
.dlg-kv.cols li { break-inside: avoid; }

/* (2) "Make a video" (dialog-video.js), moderators only. An editor on the
   left, the stage on the right. The stage is laid out at 540 CSS px and
   zoomed to fit, so the video looks the same whatever the window size. */
.dv-overlay { position: fixed; inset: 0; z-index: 4000; display: flex; background: rgba(12, 14, 28, 0.74); }
.dv-overlay[hidden] { display: none; }
body.dv-open { overflow: hidden; }
.dv-panel {
  flex: 0 0 min(440px, 46vw);
  background: var(--card, #fff);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.9rem 1rem;
  overflow: hidden;
  font-size: 0.88rem;
}
.dv-panel-head { display: flex; justify-content: space-between; align-items: center; }
.dv-panel-head h3 { margin: 0; font-size: 1.05rem; }
.dv-x { background: none; border: none; font-size: 1.5rem; line-height: 1; cursor: pointer; color: var(--muted); }
.dv-help { margin: 0; color: var(--muted); }
.dv-settings-fold > summary { cursor: pointer; font-weight: 600; font-size: 0.85rem; color: var(--primary); margin-bottom: 0.4rem; }
.dv-settings { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem 0.6rem; }
.dv-settings label { display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.78rem; color: var(--muted); }
.dv-settings .dv-check { flex-direction: row; align-items: center; gap: 0.35rem; grid-column: 1 / -1; color: var(--text); }
.dv-settings input[type="text"] { grid-column: 1 / -1; font: inherit; font-size: 0.85rem; padding: 0.35rem 0.5rem; border: 1px solid var(--border, #d5d9e0); border-radius: 6px; }
.dv-settings select, .dv-row select { font: inherit; font-size: 0.8rem; }
.dv-bulk { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.dv-bulk button, .dv-actions button, .dv-from {
  font: inherit; font-size: 0.8rem; border: 1px solid var(--border, #d5d9e0); background: var(--card, #fff);
  color: var(--text); border-radius: 999px; padding: 0.3rem 0.75rem; cursor: pointer;
}
.dv-est { margin-left: auto; color: var(--muted); font-size: 0.8rem; }
.dv-est.long { color: #b3261e; }
.dv-list { list-style: none; margin: 0; padding: 0 0.2rem 0 0; display: flex; flex-direction: column; gap: 0.35rem; flex: 1 1 auto; overflow: auto; min-height: 8rem; }
.dv-row { display: flex; gap: 0.5rem; padding: 0.45rem 0.5rem; border: 1px solid var(--border, #e3e6ec); border-radius: 8px; }
.dv-row.user { background: color-mix(in srgb, var(--primary) 6%, transparent); }
.dv-row.off { opacity: 0.45; }
.dv-row.off .dv-prev, .dv-row.off .dv-edit { text-decoration: line-through; }
.dv-keep { display: flex; flex-direction: column; align-items: center; gap: 0.1rem; flex: none; font-size: 0.68rem; cursor: pointer; }
.dv-who { font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.dv-body { flex: 1; min-width: 0; }
.dv-prev { font-size: 0.82rem; line-height: 1.4; }
.dv-edit { width: 100%; box-sizing: border-box; font: inherit; font-size: 0.82rem; padding: 0.25rem 0.4rem; border: 1px solid var(--border, #d5d9e0); border-radius: 5px; }
.dv-row-meta { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.25rem; font-size: 0.72rem; color: var(--muted); }
.dv-tag { background: var(--surface, #f4f5f8); border-radius: 4px; padding: 0 0.3rem; }
.dv-from { margin-left: auto; padding: 0.1rem 0.5rem; font-size: 0.72rem; }
.dv-actions { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; border-top: 1px solid var(--border, #e3e6ec); padding-top: 0.6rem; }
.dv-actions .dv-primary { background: var(--primary); color: #fff; border-color: var(--primary); }
.dv-actions .dv-rec { color: #b3261e; border-color: #b3261e; font-weight: 600; }
.dv-actions button:disabled { opacity: 0.45; cursor: default; }
.dv-sep { flex: 1; }
.dv-status { margin: 0; font-size: 0.8rem; min-height: 1.2em; color: var(--text); }
.dv-status.bad { color: #b3261e; }
.dv-busy .dv-list, .dv-busy .dv-settings, .dv-busy .dv-bulk { pointer-events: none; opacity: 0.6; }
.dv-stage-wrap { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; justify-content: center; padding: 12px; }
.dv-stage { position: relative; flex: none; overflow: hidden; background: #fff; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35); }
.dv-inner { zoom: var(--dv-zoom, 1); position: relative; pointer-events: none; user-select: none; }
.dv-shell { height: 100%; max-width: none; border: none; border-radius: 0; box-shadow: none; }
.dv-shell .dlg-head { padding: 0.7rem 1rem; align-items: center; }
.dv-brand { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.06em; color: var(--muted); text-transform: uppercase; }
.dv-scroll { overflow: hidden !important; scroll-behavior: auto !important; }
.dv-card {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 2.5rem; color: #fff; opacity: 0; transition: opacity 0.4s ease;
  background: radial-gradient(120% 80% at 50% 0%, var(--secondary), var(--primary));
}
.dv-card.on { opacity: 1; }
.dv-card[hidden] { display: none; }
.dv-card h2 { margin: 0.9rem 0 0.5rem; font-size: 2rem; line-height: 1.2; color: #fff; }
.dv-card p { margin: 0; font-size: 1.1rem; opacity: 0.92; max-width: 26ch; }
.dv-card-mark { width: 4rem; height: 4rem; border-radius: 50%; background: rgba(255, 255, 255, 0.18); display: flex; align-items: center; justify-content: center; font-size: 2.2rem; }
.dv-in { animation: dvIn 0.28s ease-out; }
@keyframes dvIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.dv-tap { transform: scale(0.95); transition: transform 0.15s, background 0.15s; }
.dv-composer input.dv-typing-now { outline: 2px solid var(--secondary); outline-offset: -1px; background: var(--card, #fff); }
@media (max-width: 800px) {
  .dv-overlay { flex-direction: column; }
  .dv-panel { flex: 0 0 52vh; }
}
/* v1.88 — the closing banner. Background matches the banner's own dark
   edges (top #0a0a0b, bottom #171a20) so letterboxing is invisible. */
.dv-banner {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(#0a0a0b, #0a0a0b 30%, #171a20 70%, #171a20);
  opacity: 0; transition: opacity 0.4s ease;
}
.dv-banner.on { opacity: 1; }
.dv-banner[hidden] { display: none; }
.dv-banner img { width: 100%; height: auto; display: block; }
@media print { .dv-overlay { display: none !important; } }

/* ============================================================
   v1.89 — ENGLISH ⇄ GERMAN (Master Dashboard, translations.js)
   Inside the data-i18n="skip" dashboard, like the curation
   workbench whose row styles the Translations tab reuses.
   ============================================================ */
.tr-summary { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin: 0.4rem 0 0.2rem; }
.tr-meta { color: var(--muted); font-size: 0.8rem; margin-left: 0.4rem; }
.tr-pill {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  white-space: nowrap;
}
.tr-pill.missing { color: #8a5a00; background: #fff6e0; border-color: #f0d9a0; }
.tr-pill.stale { color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, var(--surface)); border-color: color-mix(in srgb, var(--danger) 30%, var(--border)); }
.tr-pill.ok { color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.tr-pill.de-only { color: var(--primary); }
.tr-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.8rem; }
.tr-col { display: block; min-width: 0; }
.tr-col .cur-text { width: 100%; box-sizing: border-box; }
.tr-en { font-size: 0.88rem; line-height: 1.45; white-space: pre-wrap; color: var(--text); padding: 0.45rem 0; }
.tr-was { margin: 0.4rem 0 0; font-size: 0.8rem; color: var(--muted); line-height: 1.4; }
.tr-note { color: var(--muted); font-size: 0.85rem; margin: 0.6rem 0 0; }
@media (max-width: 720px) { .tr-cols { grid-template-columns: minmax(0, 1fr); } }

/* The Deutsch box under a field of the Master record editor. */
.rec-de {
  margin: 0.5rem 0 0;
  padding: 0.45rem 0.6rem 0.55rem;
  border-left: 3px solid color-mix(in srgb, var(--primary) 45%, var(--border));
  background: color-mix(in srgb, var(--primary) 3%, var(--surface));
  border-radius: 0 6px 6px 0;
}
.rec-de-head { display: flex; flex-wrap: wrap; gap: 0.45rem; align-items: center; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); margin: 0 0 0.3rem; }
.rec-de-flag { text-transform: none; letter-spacing: 0; font-weight: 600; color: var(--danger); }
.rec-de-flag[hidden] { display: none; }
.rec-de .rec-de-input { width: 100%; box-sizing: border-box; }
