* {
  box-sizing: border-box;
}

body {
  font-family: 'Segoe UI', system-ui, sans-serif;
  font-size: 14px;
  margin: 0;
  background: var(--color-white);
  color: var(--color-text);
}

/* #1763: forces the cursor back off whatever Excel's host left it as after a batch
   completes — was a CSSOM `body.style.cursor` write (CSP style-src forbids it). */
body.wait-cursor-reset { cursor: default; }

input, button, select, textarea {
  font-family: inherit;
}

/* ── RowEditor component styles ── */

.editor {
  padding: 0 0 56px;
}

/* ── Pane header ── */

.pane-header {
  background: #217346;
  height: 40px;
  padding: 0 12px;
  display: flex;
  align-items: center;
}

.pane-title {
  color: var(--color-white);
  font-size: 14px;
  font-weight: 600;
}

/* ── Tab navigation ── */

.tab-nav {
  display: flex;
  align-items: stretch;
  padding: 0 4px;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-white);
  flex-shrink: 0;
}

.tab-nav-inner {
  display: flex;
  flex-shrink: 0;
}

/* ── nav1: admin overflow ── */

.tab-more-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.tab-more {
  width: 34px;
  height: 44px;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  cursor: pointer;
  color: var(--color-text-muted);
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: -1px;
}

.tab-more:hover {
  color: var(--color-text);
  background: var(--color-bg-hover);
}

.tab-more.active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
}

.tab-more-menu {
  position: absolute;
  top: 44px;
  right: 0;
  width: 150px;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,.16);
  z-index: 100;
  overflow: hidden;
}

.tab-more-heading {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--color-text-secondary);
  padding: 8px 12px 4px;
}

.tab-more-item {
  display: block;
  width: 100%;
  padding: 9px 12px;
  font-size: 13px;
  color: var(--color-text);
  background: transparent;
  border: none;
  text-align: left;
  cursor: pointer;
}

.tab-more-item:hover {
  background: var(--color-bg-hover);
}

.tab-more-item.active {
  color: var(--color-primary);
  font-weight: 600;
}

.tab-btn {
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 9px;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  cursor: pointer;
  font-size: 14px;
  color: var(--color-text-muted);
  white-space: nowrap;
  margin-bottom: -1px;
}

.tab-btn:hover {
  color: var(--color-text);
  background: var(--color-bg-hover);
}

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

.tab-version {
  margin-left: auto;
  font-size: 11px;
  color: var(--color-border-strong);
  align-self: center;
  white-space: nowrap;
  padding: 0 8px;
  flex-shrink: 0;
}

/* #2214: always-visible "cell open for editing" indicator — a small pulsing dot in the tab-nav,
   shown only while Excel is in cell-edit mode (the JS API is suspended). `margin-left: auto`
   anchors it (and the version that follows) to the right of the bar; when `.hidden` it is removed
   from the flow and `.tab-version`'s own `margin-left: auto` keeps the version right-aligned. */
.edit-indicator {
  display: inline-flex;
  align-items: center;
  align-self: center;
  margin-left: auto;
  padding: 0 2px 0 6px;
  flex-shrink: 0;
}
.edit-indicator.hidden { display: none; }

.edit-indicator .ind-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-primary);
  animation: edit-indicator-pulse 1.2s ease-in-out infinite;
}
@keyframes edit-indicator-pulse {
  0%, 100% { opacity: .3; transform: scale(.8); }
  50%      { opacity: 1;  transform: scale(1); }
}
/* Respect reduced-motion: hold a steady dot instead of pulsing. */
@media (prefers-reduced-motion: reduce) {
  .edit-indicator .ind-dot { animation: none; opacity: 1; }
}

.tab-panel {
  padding: 10px 12px;
}


.model-subtabs {
  display: flex;
  border-bottom: 1px solid var(--color-border);
  margin: 0 0 8px;
}

.model-subtab {
  height: 32px;
  padding: 0 8px;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  font-size: 14px;
  color: var(--color-text-muted);
  cursor: pointer;
  margin-bottom: -1px;
}

.model-subtab:hover {
  color: var(--color-text);
  background: var(--color-bg-hover);
}

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

/* ── Trace wrapper / status messages ── */

.trace-message {
  font-size: 13px;
  color: var(--color-text-muted);
  padding: 10px 14px;
}

.trace-error {
  color: #a4262c;
}

/* ── TR-1: indented tree with operation chips ── */

.trace-tree {
  padding: 0 8px;
  font-size: 13px;
}

.trace-node {
  position: relative;
}

.trace-nrow {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 4px;
  border-radius: 3px;
  cursor: default;
}

.trace-nrow:hover {
  background: var(--color-bg-hover);
}

.trace-tog {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  color: var(--color-text-muted);
  border: 1px solid var(--color-border-strong);
  border-radius: 2px;
  background: var(--color-white);
  cursor: pointer;
  padding: 0;
}

.trace-tog.leaf {
  border: none;
  background: none;
  color: var(--color-border-strong);
}

.trace-op {
  flex-shrink: 0;
  min-width: 22px;
  height: 18px;
  padding: 0 4px;
  border-radius: 3px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--color-white);
}

.trace-op.sum    { background: var(--color-primary); }
.trace-op.mult   { background: #8764b8; }
.trace-op.neg    { background: #d13438; }
.trace-op.input  { background: var(--color-success); }
.trace-op.div    { background: #ca5010; }
.trace-op.minmax,
.trace-op.abs    { background: #038387; }
.trace-op.run    { background: #ca5010; }
.trace-op.plus   { background: var(--color-text-muted); }

.trace-nm {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  color: var(--color-text);
}

.trace-rt {
  font-size: 10px;
  color: var(--color-text-secondary);
  display: block;
  line-height: 1.1;
}

.trace-val {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  flex-shrink: 0;
  color: var(--color-text);
  font-size: 13px;
}

.trace-lag {
  font-size: 9px;
  font-family: Consolas, monospace;
  color: #ca5010;
  background: #fdf3ec;
  border: 1px solid #f4dcc8;
  border-radius: 2px;
  padding: 0 3px;
  flex-shrink: 0;
}

.trace-children {
  margin-left: 7px;
  padding-left: 12px;
  border-left: 1px dashed var(--color-border-strong);
}

/* multiplication boundary marker */
.trace-bound {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0 2px 7px;
  padding-left: 12px;
}

.trace-bx {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #8764b8;
  color: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}

.trace-blbl {
  font-size: 10px;
  color: var(--color-text-secondary);
  font-style: italic;
}

.trace-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 14px;
  padding: 10px 4px 4px;
  border-top: 1px solid var(--color-bg-hover);
}

.trace-legend .trace-op {
  cursor: default;
}

.trace-legend-t {
  font-size: 10px;
  color: var(--color-text-muted);
  align-self: center;
}

/* period bar above trace tree */
.period-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--color-text-muted);
  background: var(--color-bg-hover);
  border-radius: 4px;
  padding: 6px 8px;
  margin-bottom: 10px;
}

.period-bar b {
  color: var(--color-text);
}

.period-bar .pk {
  font-family: Consolas, monospace;
  color: var(--color-text-secondary);
}


/* ── Project tab ── */

.prj-grp-h {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 16px 0 8px;
}

.prj-grp-h:first-child { margin-top: 0; }

.prj-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 4px;
  background: linear-gradient(var(--color-white), #fafbfc);
}

.prj-toggle-txt { flex: 1; }
.prj-toggle-t   { font-size: 14px; font-weight: 600; }
.prj-toggle-d   { font-size: 11px; color: var(--color-text-secondary); }

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  flex-shrink: 0;
  cursor: pointer;
  margin-bottom: 0;
}

.toggle-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-track {
  position: absolute;
  inset: 0;
  background: #ccc;
  border-radius: 22px;
  transition: background 0.15s;
}

.toggle-track::before {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  left: 3px;
  top: 3px;
  background: var(--color-white);
  border-radius: 50%;
  transition: transform 0.15s;
}

.toggle-switch input:checked + .toggle-track {
  background: var(--color-primary);
}

.toggle-switch input:checked + .toggle-track::before {
  transform: translateX(18px);
}

/* Disabled state (epic #2041 S4, design §4.8 off-host) — the switch itself was previously never
   disabled anywhere in the product, so this state didn't exist yet. */
.toggle-switch.is-disabled {
  cursor: not-allowed;
}

.toggle-switch input:disabled + .toggle-track {
  opacity: .5;
}

.prj-cur {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 12px;
}

.prj-cur-controls {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  margin-bottom: 10px;
}

.prj-cur-sym {
  flex: 0 0 72px;
}

.prj-cur-sym input {
  width: 100%;
}

.prj-cur-pos {
  flex: 1;
}

.prj-seg {
  display: flex;
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  overflow: hidden;
  height: 32px;
}

.prj-seg-btn {
  flex: 1;
  border: none;
  background: var(--color-white);
  font-size: 12px;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: 0;
}

.prj-seg-btn.prj-seg-on {
  background: var(--color-primary);
  color: var(--color-white);
  font-weight: 600;
}

.prj-cur-sample {
  background: var(--color-bg-hover);
  border-radius: 6px;
  padding: 10px;
  text-align: center;
}

.prj-cur-preview {
  display: block;
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

.prj-cur-sample-c {
  display: block;
  font-size: 10px;
  color: var(--color-text-secondary);
  margin-top: 2px;
}

textarea {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #ccc;
  border-radius: 3px;
  font-size: 14px;
  resize: vertical;
}

textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 1px var(--color-primary);
}

details {
  border-top: 1px solid #e0e0e0;
  margin-top: 4px;
}

details > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 0 4px;
  user-select: none;
}

details > summary::-webkit-details-marker,
details > summary::marker {
  display: none;
  content: '';
}

details > summary > h2 {
  font-size: 13px;
  font-weight: 700;
  color: #555;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

details > summary::after {
  content: '›';
  color: #666;
  font-size: 22px;
  font-weight: 300;
  line-height: 1;
  display: inline-block;
  transition: transform 0.15s ease;
}

details[open] > summary::after {
  transform: rotate(90deg);
}

.panel-body {
  padding-top: 4px;
  padding-bottom: 4px;
}

/* ── re1: Smart accordion form sections ── */

.acc-section {
  border: 1px solid var(--color-border);
  border-radius: 2px;
  margin-bottom: 8px;
  /* Must stay `visible`: in-section picker dropdowns (.sp-dropdown — Row type /
     Other row / Format / Rounding) are position:absolute and overflow the short
     section box. `overflow: hidden` here clips them — see #377. The only thing
     clipping bought was trimming the 4px colour bar to the 2px rounded corners,
     which is visually negligible. */
  overflow: visible;
  background: var(--color-white);
  border-top: none; /* override global details border-top */
  margin-top: 0;    /* override global details margin-top */
}

.acc-section[open] {
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
}

.acc-section > summary {
  display: flex;
  align-items: center;
  height: 30px;
  padding: 0 10px 0 0;
  justify-content: flex-start;
}

.acc-section > summary::after {
  content: none; /* suppress global chevron */
}

.acc-section > summary::before {
  content: '';
  width: 4px;
  align-self: stretch;
  background: var(--sec, var(--color-primary));
  flex-shrink: 0;
  margin-right: 6px;
}

/* Per-section accent colour (#1763; was an inline `style="--sec:#…"` — CSP style-src
   forbids inline styles, custom-property or otherwise). One rule per fixed section id. */
#section-row       { --sec: #0078d4; }
#section-values     { --sec: #3a96e8; }
#section-formatting { --sec: #038387; }
#section-kpi         { --sec: #8764b8; }
#section-advanced   { --sec: #605e5c; }

/* KPI section entitlement gating (epic #1991 / S4, design §4.9) — disabled +
   "Premium" tag when `isDashboardEntitled()` is false; never hidden. The tag
   reuses the warning tokens (an amber badge reads as an upsell nudge, not an
   error). Controls are natively `:disabled` (checkboxes/inputs, and the mounted
   SearchPickers' `.sp-input`/`.sp-clear`) — this rule only adds the visual cue. */
.premium-tag {
  font-size: 11px;
  font-weight: 600;
  color: var(--color-warning);
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: 10px;
  padding: 1px 8px;
  margin-left: 8px;
  flex-shrink: 0;
}
#section-kpi.kpi-disabled .panel-body input:disabled,
#section-kpi.kpi-disabled .panel-body .sp-input:disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* re-c1: left disclosure caret (replaces the small right .acc-chev). The 4px
   colour bar carries section identity, so the abstract glyph icons are dropped. */
.acc-caret {
  width: 18px;
  text-align: center;
  color: var(--color-text-muted);
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
  margin-right: 4px;
}

.acc-caret::before { content: '\25B8'; }            /* ▸ collapsed */
.acc-section[open] .acc-caret::before { content: '\25BE'; }  /* ▾ open */

.sec-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
  flex-shrink: 0;
}

/* Identity rendered in the first section header (mode · row name), #507. */
.sec-name .sec-mode { color: var(--color-text-muted); font-weight: 600; }
.sec-name .sec-dot  { color: var(--color-text-secondary); margin: 0 5px; }
.sec-name .sec-rn   { color: var(--color-text); font-weight: 600; }

.sec-preview {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: var(--color-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: right;
  padding-left: 8px;
}

.acc-section[open] .sec-preview {
  display: none;
}

.acc-section .panel-body {
  padding: 4px 12px 14px;
  border-top: 1px solid var(--color-bg-hover);
}

/* ── #507 — model-tab slimming bits ───────────────────────────── */

/* PP identity header (the flat PP form has no accordion — non-collapsible,
   styled like a section header: colour bar + "Project Plan · <name>"). */
.pp-identity {
  display: flex;
  align-items: center;
  height: 30px;
  margin-bottom: 8px;
}
.pp-identity::before {
  content: '';
  width: 4px;
  align-self: stretch;
  background: var(--color-primary);
  flex-shrink: 0;
  margin-right: 10px;
}

/* PP Wait/Duration: small whole-month values (W1) — narrow input + unit */
.pp-months { display: inline-flex; align-items: center; gap: 6px; }
.pp-months input { width: 48px !important; text-align: center; }
.pp-months .pp-unit { font-size: 12px; color: var(--color-text-muted); }

/* ── out1: Output tab action list ── */

.out-runall {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}

.out-runall-btn {
  height: 32px;
  padding: 0 16px;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  border-radius: 2px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
}

.out-runall-btn:hover { background: var(--color-primary-hover); }
.out-runall-btn:disabled { opacity: .55; cursor: default; }

.out-runall-sub {
  font-size: 11px;
  color: var(--color-text-secondary);
}

.out-group-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 4px 0 8px;
}

.out-group-title + .out-group-title,
.out-act + .out-group-title {
  margin-top: 18px;
}

.out-act {
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 10px;
  margin-bottom: 8px;
  background: var(--color-white);
}

.out-act-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.out-act-ico {
  width: 30px;
  height: 30px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  color: var(--color-white);
  flex-shrink: 0;
}

/* Per-action icon colour (#1763; were inline `style="background:#…"` — CSP style-src
   forbids inline styles). One-off literals matching the values they replace. */
.out-act-ico-generate  { background: #0078d4; }
.out-act-ico-snapshot  { background: #8764b8; }
.out-act-ico-circ      { background: #038387; }
.out-act-ico-diff      { background: #ca5010; }
.out-act-ico-summaries { background: #605e5c; }
.out-act-ico-report    { background: #8a6d00; }
.out-act-ico-dashboard { background: #107c10; } /* #1991 S5 — Dashboard card icon chip (one-off literal, matching the local pattern) */

.out-act-txt {
  flex: 1;
  min-width: 0;
}

.out-act-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
}

.out-act-desc {
  font-size: 11px;
  color: var(--color-text-secondary);
  line-height: 1.3;
  margin-top: 1px;
}

.out-btn {
  height: 32px;
  padding: 0 14px;
  border-radius: 2px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
}

.out-btn-primary { background: var(--color-primary); color: var(--color-white); border: 1px solid transparent; }
.out-btn-primary:hover { background: var(--color-primary-hover); }
.out-btn-default { background: var(--color-white); color: var(--color-text); border: 1px solid var(--color-border); }
.out-btn-default:hover { background: var(--color-bg-hover); }
.out-btn:disabled { opacity: .55; cursor: default; }
/* #2366 (matches #btn-footer-save[aria-disabled] below): the Dashboard card's entitlement gate
   disables its button visually via aria-disabled, never natively — a natively-disabled button
   swallows the click and made the click-time re-evaluation unreachable. Same greyed look. */
#btn-open-dashboard[aria-disabled="true"] { opacity: .55; cursor: default; }

.out-result {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-size: 12px;
  padding: 6px 8px;
  border-radius: 4px;
}

.out-result-ok    { background: #f1faf1; color: #0b6a0b; }
.out-result-warn  { background: #fdf6ec; color: #8a4d0f; }
.out-result-error { background: #fdf3f4; color: #a4262c; }

.out-result-time {
  margin-left: auto;
  color: var(--color-text-secondary);
  font-size: 10px;
  white-space: nowrap;
}

.out-running {
  margin-top: 8px;
}

.out-run-line {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--color-primary);
}

.out-spin {
  width: 13px;
  height: 13px;
  border: 2px solid #cfe6f9;
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: out-spin 0.7s linear infinite;
  flex-shrink: 0;
}

@keyframes out-spin {
  to { transform: rotate(360deg); }
}

/* ── Error-report capture widget (#1554 / epic #1522) ──────────────────────────
   The reusable `@bp/ui` CaptureWidget (`documentation/issue-1522/mockup-capture-widget.html`).
   Only the overlay + consent classes below are new; the buttons (`.out-btn*`), spinner
   (`.out-running`/`.out-spin`), error row (`.out-result*`) and form field (`.field`/
   `label`/`textarea`) are reused from the grammar above. Modelled on `.cbar-min`
   (white card, shadow); S6 wires its Output-tab home + overlay placement. */
.rp-panel {
  margin: 0 10px 12px;
  border: 1px solid var(--color-border);
  background: var(--color-white);
  box-shadow: 0 3px 14px rgba(0,0,0,.16);
  border-radius: 6px;
  padding: 10px 12px;
}
.rp-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.rp-title { font-size: 13px; font-weight: 600; flex: 1; }
.rp-x {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  color: var(--color-text-secondary);
  padding: 2px 4px;
}
.rp-x:hover { color: var(--color-text); }
.rp-x:disabled { opacity: .4; cursor: default; }

/* Paste dropzone */
.rp-drop {
  border: 1.5px dashed var(--color-border-strong);
  border-radius: 6px;
  background: #fafbfc;
  padding: 14px 10px;
  text-align: center;
  font-size: 12px;
  color: var(--color-text-muted);
  cursor: pointer;
}
.rp-drop:hover { border-color: var(--color-primary); background: #f5faff; }
.rp-drop-key {
  display: inline-block;
  border: 1px solid var(--color-border-strong);
  border-radius: 3px;
  padding: 0 5px;
  font-size: 11px;
  background: var(--color-white);
  color: var(--color-text);
  margin: 0 1px;
}
.rp-drop-or { display: block; font-size: 11px; color: var(--color-text-secondary); margin-top: 6px; }

/* "Reading screenshot…" spinner shown while a pasted/chosen image is downscaled */
.rp-capturing {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px dashed var(--color-border-strong);
  border-radius: 6px;
  background: #fafbfc;
  padding: 14px 10px;
  font-size: 12px;
  color: var(--color-text-muted);
}

/* Preview thumbnail (real <img>, not the mockup's fake gradient) + remove button */
.rp-thumb {
  position: relative;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  overflow: hidden;
  margin-top: 2px;
}
.rp-thumb-img { position: relative; }
.rp-thumb-src {
  display: block;
  width: 100%;
  max-height: 160px;
  object-fit: contain;
  background: #f3f7fb;
}
.rp-thumb-x {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: rgba(0,0,0,.55);
  color: #fff;
  font-size: 14px;
  line-height: 22px;
  text-align: center;
  cursor: pointer;
}
.rp-thumb-meta {
  font-size: 10px;
  color: var(--color-text-secondary);
  padding: 4px 6px;
  background: #fafbfc;
  border-top: 1px solid var(--color-border);
}

/* "(optional)" qualifier on the description label once a screenshot is attached */
.rp-optional { font-weight: 400; color: var(--color-text-secondary); }

/* ≥1-of-{text,image} guard hint */
.rp-guard { font-size: 11px; color: var(--color-text-secondary); margin-top: 7px; }
.rp-guard.bad { color: var(--color-error); }

/* Consent row (the "Report a problem" path only) */
.rp-consent {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin-top: 9px;
  font-size: 11.5px;
  color: var(--color-text-muted);
  line-height: 1.35;
}
.rp-consent input { margin-top: 1px; flex-shrink: 0; }
.rp-consent a { color: var(--color-primary); text-decoration: underline; }

.rp-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 10px; }

.out-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--color-bg-hover);
  margin-top: 6px;
  overflow: hidden;
}

.out-bar > i {
  display: block;
  height: 100%;
  width: 20%;
  background: var(--color-primary);
  animation: out-bar-fill 2s ease-in-out infinite alternate;
}

@keyframes out-bar-fill {
  from { width: 20%; }
  to   { width: 85%; }
}

/* Assumption value controls — Varies toggle, Applies radios, hints, advisory
   (#485: bring the live editor up to the canonical mockup row-editor-vE.html).
   Scoped to .panel-body so the generic class names can't collide with chat. */

/* modrow — a toggle + label (Varies over time / Return as negative).
   #510 also reuses it in the PP "Expose dates" panel (#form-section-pp), which
   sits outside .panel-body — hence the extra selector. */
/* #harness-runner reuses the .modrow toggle (Skip already-green switch, #1196) — same
   declarations, extra scope so the switch styling applies outside .panel-body/#form-section-pp. */
.panel-body .modrow,
#form-section-pp .modrow,
#harness-runner .modrow {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  margin: 12px 0 9px;
  cursor: pointer;
}
.panel-body .modrow input[type="checkbox"],
#form-section-pp .modrow input[type="checkbox"],
#harness-runner .modrow input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex-shrink: 0;
  width: 30px;
  height: 16px;
  margin: 0;
  background: #ccc;
  border-radius: 16px;
  cursor: pointer;
  transition: background .12s;
}
.panel-body .modrow input[type="checkbox"]::before,
#form-section-pp .modrow input[type="checkbox"]::before,
#harness-runner .modrow input[type="checkbox"]::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 2px;
  width: 12px;
  height: 12px;
  background: #fff;
  border-radius: 50%;
  transition: transform .12s;
}
.panel-body .modrow input[type="checkbox"]:checked,
#form-section-pp .modrow input[type="checkbox"]:checked,
#harness-runner .modrow input[type="checkbox"]:checked { background: var(--color-primary); }
.panel-body .modrow input[type="checkbox"]:checked::before,
#form-section-pp .modrow input[type="checkbox"]:checked::before,
#harness-runner .modrow input[type="checkbox"]:checked::before { transform: translateX(14px); }
.panel-body .modrow input[type="checkbox"]:disabled,
#form-section-pp .modrow input[type="checkbox"]:disabled,
#harness-runner .modrow input[type="checkbox"]:disabled { opacity: .5; cursor: not-allowed; }

/* Applies — the phase/milestone chooser box + custom radio dots.
   #510 reuses .applies / .applies-lbl for the PP "Expose dates" panel. */
.panel-body .applies,
#form-section-pp .applies {
  background: #fafbfc;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 9px 10px;
  margin: 2px 0 10px;
}
.panel-body .applies-lbl,
#form-section-pp .applies-lbl {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--color-text-secondary);
  margin-bottom: 6px;
}
.panel-body .radio {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  margin-bottom: 5px;
  cursor: pointer;
}
.panel-body .radio:last-child { margin-bottom: 0; }
.panel-body .radio input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  margin: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 50%;
  cursor: pointer;
}
.panel-body .radio input[type="radio"]:checked { border-color: var(--color-primary); }
.panel-body .radio input[type="radio"]:checked::after {
  content: '';
  position: absolute;
  inset: 2px;
  background: var(--color-primary);
  border-radius: 50%;
}
.panel-body .radio:has(input:checked) { font-weight: 600; }

/* applies-radios — LAY-5 (#668 S6): the Phased / At radios laid out inline, to the
   right of the "Link to project plan" toggle (previously stacked below). Reuses the
   .radio controls verbatim; the block margin-bottom is zeroed for the row layout. */
.applies-radios {
  display: flex;
  gap: 14px;
  margin-left: 4px;
}
.applies-radios .radio { margin-bottom: 0; }

/* vhint — the per-profile explanatory line under the value */
.panel-body .vhint {
  font-size: 11px;
  color: var(--color-text-secondary);
  margin: 6px 0 0;
  line-height: 1.45;
}

/* note — Gate / Structure plain-text note (no value).
   #510 reuses it for the PP "Expose dates" help line. */
.panel-body .note,
#form-section-pp .note {
  font-size: 11.5px;
  color: var(--color-text-secondary);
  line-height: 1.45;
}

/* hint — the live blue composed hint (Calculation / Gate / Assumption) */
.panel-body .hint {
  margin-top: 4px;
  background: #eef4fb;
  border: 1px solid #cfe2f5;
  border-radius: 6px;
  padding: 9px 10px;
  font-size: 12.5px;
  color: #0c4a78;
  line-height: 1.45;
}
.panel-body .hint b { color: #083a60; }

/* gate-ptr — gate wiring pointer (#1492 CG-7, mockup panes N7/N8). A green-tinted
   teaching line on every gate row: "used by N rows". Bespoke widget (R3/R4) modelled
   on .hint's bordered-box shape; one-off green literals, matching the mockup. */
.panel-body .gate-ptr {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin-top: 8px;
  background: #f0f7f0;
  border: 1px solid #cfe6cf;
  border-radius: 5px;
  padding: 7px 10px;
  font-size: 11.5px;
  color: #245a24;
  line-height: 1.45;
}
.panel-body .gate-ptr .ic { flex-shrink: 0; }

/* growth — assumption compounding box (#504), modelled on .applies (tokens only) */
.panel-body .growth {
  background: #fafbfc;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 9px 10px;
  margin: 2px 0 4px;
}
.panel-body .growth-lbl {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--color-text-secondary);
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.panel-body .growth-lbl .anchor { text-transform: none; letter-spacing: 0; font-style: italic; }
/* "set growth start date →" reuses .pp-change-link (#504); inline in the caption,
   so it matches the caption size and sits on its baseline. */
.panel-body .growth-lbl .pp-change-link { font-size: inherit; vertical-align: baseline; }
.panel-body .growth-rate {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.panel-body .growth-rate input {
  width: 66px;
  border: 1px solid var(--color-border-strong);
  border-radius: 4px;
  padding: 7px;
  font-size: 15px;
  font-weight: 700;
  text-align: right;
}
.panel-body .growth-rate .pct { font-size: 14px; color: var(--color-text-muted); margin-left: -4px; }
.panel-body .growth-rate select {
  flex: 1;
  border: 1px solid var(--color-border-strong);
  border-radius: 4px;
  /* right pad for the inherited caret; background-color (not the `background`
     shorthand) so it does not wipe the shared caret image. */
  padding: 7px 26px 7px 7px;
  font-size: 13px;
  background-color: #fff;
}
.panel-body .proj-h {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--color-text-secondary);
  margin: 2px 0 5px;
}
.panel-body .proj-strip {
  display: flex;
  border: 1px solid var(--color-border);
  border-radius: 5px;
  overflow: hidden;
  background: #fff;
  text-align: center;
}
.panel-body .proj-cell { flex: 1; padding: 6px 2px; border-right: 1px solid var(--color-border); }
.panel-body .proj-cell:last-child { border-right: 0; }
.panel-body .proj-cell .yr { display: block; font-size: 9.5px; color: var(--color-text-secondary); }
.panel-body .proj-cell .val { display: block; font-size: 12px; font-weight: 600; color: var(--color-text); }
.panel-body .proj-empty {
  background: #fff;
  border: 1px dashed var(--color-border-strong);
  border-radius: 5px;
  padding: 12px 10px;
  text-align: center;
  font-size: 11.5px;
  color: var(--color-text-secondary);
  line-height: 1.45;
}


/* Phase / value inputs */

.phase-inputs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 8px;
  align-items: end;
}

.phase-input-item {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.phase-input-item label {
  font-size: 11px;
  color: #555;
  font-weight: normal;
  margin-bottom: 2px;
  line-height: 1.4;
  max-height: calc(3 * 1.4em);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

.phase-input-item input {
  width: 100%;
}

/* Values: single input */
.vi-single input {
  width: 100%;
}

/* Values: ih4 card grid (≤3 cards). Fixed 88px columns match the scroll-mode
   slot width so cards don't resize when crossing the 3→4 card threshold. */
.vi-card-grid {
  display: grid;
  grid-template-columns: repeat(3, 88px);
  gap: 8px;
}

/* Values: ih4 card */
.vi-card {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary);
  border-radius: 2px;
  padding: 5px 6px 5px 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* Origin / period-0 opening value: subtly tinted so it reads as intentional. */
.vi-card-phase {
  font-size: 13px;
  font-weight: 700;
  color: #201f1e;
  line-height: 1.2;
  /* Reserve two lines so single- and two-line names keep the input box aligned. */
  min-height: calc(13px * 1.2 * 2);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.vi-card-qualifier {
  display: block;
  /* Reserve a line even when empty so cards with/without a qualifier align. */
  min-height: calc(11px * 1.2);
  font-size: 11px;
  font-style: italic;
  color: var(--color-text-muted);
  line-height: 1.2;
}

.vi-card-date {
  display: block;
  /* Reserve a line even when empty so cards with/without a date align. */
  min-height: calc(11px * 1.2);
  font-family: 'Consolas', monospace;
  font-size: 11px;
  color: var(--color-text-secondary);
  text-align: left;
  margin-top: 4px;
}

/* Values: input row (shared by card and single) */
.vi-input-row {
  border: 1px solid var(--color-border-strong);
  border-radius: 2px;
  height: 26px;
  display: flex;
  align-items: stretch;
  min-width: 0;
  background: var(--color-white);
}

.vi-input-row input {
  flex: 1;
  min-width: 0;
  height: 24px;
  border: none;
  outline: none;
  padding: 0 6px;
  font-size: 13px;
  background: transparent;
  color: #201f1e;
}

.vi-input-row input:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: -1px;
  border-radius: 2px;
}

/* Values: ii2 horizontal-scroll overflow (>3 cards) */
.vi-scroll-outer {
  position: relative;
}

.vi-scroll-outer::after {
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  /* Clear the (taller) scrollbar so the fade doesn't sit over it. */
  bottom: 10px;
  width: 36px;
  background: linear-gradient(to right, transparent, var(--color-white));
  pointer-events: none;
  z-index: 1;
}

.vi-scroll {
  overflow-x: auto;
  padding-bottom: 6px;
  scrollbar-width: thin;
  scrollbar-color: var(--color-border-strong) transparent;
}

/* A 3px bar was easy to miss; 8px gives a clearer scroll affordance. */
.vi-scroll::-webkit-scrollbar {
  height: 8px;
}

.vi-scroll::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: 4px;
}

.vi-scroll-track {
  display: flex;
  gap: 8px;
  width: max-content;
}

.vi-scroll-slot {
  width: 88px;
  flex-shrink: 0;
}

.vi-scroll-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 5px;
}

.vi-scroll-count {
  font-size: 10px;
  color: var(--color-text-secondary);
}

.vi-scroll-hint {
  font-size: 10px;
  color: var(--color-text-secondary);
  font-style: italic;
}

/* ── Assumption value cards (#610) ───────────────────────────────────────────
   Recreates the approved design handoff (issue-610/design-handoff) reskinned to
   tokens + the existing .vi-card look (deviation D-e): horizontal flip-edit cards
   with hover `+` gap inserters, an anchor type-ahead (SearchPicker), APPLIES +
   LAG, value, and a derived date. Reuses .vi-card / .vi-input-row / .vi-card-*. */
.vi-cards-host { display: block; }

.vi-cards-row {
  display: flex;
  align-items: stretch;       /* equal-height cards, incl. mid-edit */
  gap: 0;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}

/* Gap inserter: a full-height hit target showing a `+` on hover. */
.vi-gap {
  flex: 0 0 22px;
  align-self: stretch;
  border: none;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
  padding: 0;
}
.vi-gap:hover {
  color: var(--color-primary);
  background: var(--color-bg-hover);
}

/* The display card reuses .vi-card; widen and position the edit affordance. */
.vi-cards-row .vi-card {
  position: relative;
  flex: 0 0 120px;
  width: 120px;
}
.vi-cards-row .vi-card.vi-edit {
  flex-basis: 150px;
  width: 150px;
  border: 1px solid var(--color-primary);
  border-left: 3px solid var(--color-primary);
  box-shadow: 0 0 0 3px rgba(0, 120, 212, 0.12);
}

/* Pencil edit button on display cards (#714, replaced the #667 kebab). Same
   top-right footprint; hidden until the card is hovered (or the button is
   keyboard-focused) so the card stays clean. Click → flip straight to edit. */
.vi-edit-btn {
  position: absolute;
  top: 3px; right: 3px;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: 3px;
  color: var(--color-text-secondary);
  cursor: pointer; padding: 0;
  opacity: 0;
  transition: opacity 0.1s;
}
.vi-cards-row .vi-card:hover .vi-edit-btn { opacity: 1; }
.vi-edit-btn:hover { background: var(--color-bg-hover); color: var(--color-text); }
.vi-edit-btn:focus-visible { opacity: 1; outline: 2px solid var(--color-primary); outline-offset: 1px; }
.vi-edit-btn svg { display: block; }

/* Empty/virgin "Add a value" placeholder (#646): a ghost card matching .vi-card's
   footprint but dashed + accent, button-shaped so keyboard/focus come for free.
   Click → insertAt(0), the same new card a mid-row `+` produces. */
.vi-card-add {
  flex: 0 0 142px;
  width: 142px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 96px;
  background: var(--color-white);
  border: 1px dashed var(--color-border-strong);
  border-left: 3px dashed var(--color-primary);
  border-radius: 2px;
  color: var(--color-primary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 12px 8px;
}
.vi-card-add:hover { background: var(--color-bg-hover); border-color: var(--color-primary); }
.vi-card-add:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
.vi-card-add .vi-add-plus { font-size: 20px; line-height: 1; }
.vi-card-add .vi-add-sub {
  font-size: 10px;
  font-weight: 400;
  color: var(--color-text-muted);
  text-align: center;
}

.vi-card-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: calc(10px * 1.2);
}

/* Lag chip — accent-tinted pill, right-aligned on the start/end line. */
.vi-lag-chip {
  background: var(--color-bg-hover);
  color: var(--color-primary);
  font-size: 10px;
  font-weight: 600;
  font-family: 'Consolas', monospace;
  padding: 1px 6px;
  border-radius: 999px;
  white-space: nowrap;
}

/* Edit-state labelled fields. */
.vi-flabel {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-text-secondary);
  margin: 4px 0 2px;
}
.vi-edit-row { display: flex; gap: 8px; }
.vi-edit-col { flex: 1; min-width: 0; }
/* Lag is hard-clamped narrow (#668 S2, LAG-2 / LD-8): flex-basis alone won't hold a
   bare <input>'s ~20ch intrinsic width, so pin the column AND the box (with size="2"
   on the input) — this leaves Value the rest of the shared Lag+Value row. */
.vi-lag-col  { flex: 0 0 40px; min-width: 40px; max-width: 40px; }
.vi-lag      { max-width: 40px; }

/* Edge-first italic edge word on a display card's label (#668 S2, LBL-1). Overrides
   the .vi-card-phase bold so the edge reads as a lighter qualifier before the name. */
.vi-edge { font-style: italic; font-weight: 400; color: var(--color-text-muted); }

/* Same-date collision cue (#668 S4, COLL-3): an amber left border on the card and a
   small ⚠ at its bottom-right, beside the date it warns about. No collision text in
   the card — the detail is the live commit-bar panel warning (S3/S4, #1438). The card
   already sets position:relative under .vi-cards-row, so the flag positions against it. */
.vi-card.is-collision { border-left-color: var(--color-warning); }
.vi-collide-flag {
  position: absolute;
  bottom: 4px;
  right: 5px;
  font-size: 11px;
  line-height: 1;
  color: var(--color-warning);
}

/* Empty-value ERROR cue (#668 S5, VAL-6): the card's left border is reddened and a red ⚠
   shows at the card's bottom-right. Unlike a same-date collision (a warning that still
   saves), an empty value BLOCKS the save (VAL-7). The value box itself is NOT reddened —
   the doubled red (card border + field outline) read as visually heavy, so #2113 keeps a
   single red cue on the card's left border (mirroring the .vi-card.is-collision amber; the
   tester's corrected target on reopen — #2116 had reddened the field outline instead, the
   inverse). Defined AFTER .vi-card.is-collision so the red error border overrides the amber
   collision border when a card is both. The flag reuses the .vi-collide-flag position; the
   card already sets position:relative under .vi-cards-row. */
.vi-card.is-invalid { border-left-color: var(--color-error); }
.vi-invalid-flag {
  position: absolute;
  bottom: 4px;
  right: 5px;
  font-size: 11px;
  line-height: 1;
  color: var(--color-error);
}

.vi-applies-single {
  height: 26px;
  display: flex;
  align-items: center;
  padding: 0 6px;
  color: var(--color-text-muted);
  border: 1px solid var(--color-border-strong);
  border-radius: 2px;
}

/* APPLIES + LAG dropdown menus. */
.vi-menu, .vi-lag { position: relative; }
.vi-menu-btn {
  /* appearance:none strips the native button chrome so this <button> renders at
     the same explicit 26px height as the .vi-lag <div> beside it — without it the
     webview's native control metrics make the two controls differ (#714). */
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 6px;
  border: 1px solid var(--color-border-strong);
  border-radius: 2px;
  background: var(--color-white);
  color: var(--color-text);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.vi-caret { color: var(--color-text-secondary); font-size: 10px; }

.vi-menu-list {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 40;
  background: var(--color-white);
  border: 1px solid var(--color-border-strong);
  border-radius: 4px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
  padding: 4px;
  max-height: 180px;
  overflow: hidden auto;
}
.vi-menu-opt {
  padding: 5px 8px;
  border-radius: 3px;
  font-size: 13px;
  color: var(--color-text);
  cursor: pointer;
}
.vi-menu-opt:hover { background: var(--color-bg-hover); }

/* Combined typable + tappable lag control. */
.vi-lag {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--color-border-strong);
  border-radius: 2px;
  height: 26px;
  background: var(--color-white);
}
.vi-lag-input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: none;
  outline: none;
  padding: 0 4px;
  font-size: 13px;
  font-family: 'Consolas', monospace;
  background: transparent;
}
/* (lag is a plain text field — the dropdown caret/menu were removed) */

.vi-edit-date { margin-top: 8px; }

.vi-edit-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
}
/* Delete (destructive) sits left; Cancel + Done group is pushed to the right (#714). */
.vi-delete {
  border: none;
  background: transparent;
  color: var(--color-error);
  font-size: 10px;
  cursor: pointer;
  padding: 3px 2px;
}
.vi-delete:hover { text-decoration: underline; }
.vi-edit-actions-right {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.vi-done {
  border: none;
  background: var(--color-primary);
  color: var(--color-white);
  border-radius: 3px;
  padding: 3px 9px;
  font-size: 10px;
  font-weight: 600;
  cursor: pointer;
}
.vi-done:hover { background: var(--color-primary-hover); }
.vi-cancel {
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 10px;
  cursor: pointer;
  padding: 3px 2px;
}
.vi-cancel:hover { color: var(--color-text); }

/* Anchor type-ahead reuses SearchPicker (.sp-*); just tighten its spacing here. */
.vi-anchor-pick .sp-input { font-size: 13px; }

/* Inline parse/serialize error (U-4) + read-only canonical preview (U-3). */
.vi-error {
  margin-top: 6px;
  padding: 6px 8px;
  font-size: 12px;
  color: #a4262c;
  background: #fdf3f4;
  border: 1px solid #f3d6d8;
  border-radius: 3px;
}
.field-row {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.field-row > .field {
  flex: 1;
  min-width: 0;
}

/* Utility hide — always use classList to toggle .hidden; el.style.display is defeated by !important. */
.hidden {
  display: none !important;
}

.picker-with-lag {
  display: flex;
  align-items: flex-end;
  gap: 6px;
}

.picker-with-lag > div:first-child {
  flex: 1;
  min-width: 0;
}

.lag-wrap {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.lag-label {
  font-size: 11px;
  color: #555;
  white-space: nowrap;
}

.lag-info {
  cursor: help;
  color: var(--color-primary);
}

.lag-input {
  width: 44px !important;
  text-align: center;
}

.row-hint {
  font-size: 12px;
  color: #555;
  line-height: 1.5;
  margin-bottom: 14px;
}

.field {
  margin-bottom: 12px;
}

/* #1319 — Row-type category preselector: one row of four icon tiles
   (Structure / Assumption / Calculation / Gate). Real <button> radios; the icons
   are inline SVG (currentColor). Selected tile mirrors the picker's selected-option
   blue (#eef4fb / #083a60 — the same one-off literals used by .hint, R1). */
.panel-body .rt-tiles {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
}
.panel-body .rt-tile {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 5px;
  background: var(--color-white);
  color: var(--color-text-muted);
  cursor: pointer;
  font-family: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  font-size: 9.5px;
  line-height: 1.12;
  /* #1531: +1px below the label so it doesn't sit flush against the tile border. */
  padding: 2px 2px 2px;
}
.panel-body .rt-tile .rt-ico {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text);
  height: 18px;
}
.panel-body .rt-tile .rt-ico svg { height: 18px; width: 18px; display: block; }
.panel-body .rt-tile .rt-ico-wide svg { height: 16px; width: auto; }   /* operator strip */
.panel-body .rt-tile .rt-ico-box svg { height: 18px; width: auto; }    /* "123" box (wider than tall) */
.panel-body .rt-tile .rt-ico-struct svg { height: 16px; width: 16px; } /* Structure: slightly smaller */
.panel-body .rt-tile .rt-lbl {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.panel-body .rt-tile:hover { border-color: var(--color-text-muted); }
.panel-body .rt-tile.on {
  border-color: var(--color-primary);
  background: #eef4fb;
  color: #083a60;
  font-weight: 600;
}
.panel-body .rt-tile.on .rt-ico { color: var(--color-primary); }
.panel-body .rt-tile:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }

label {
  display: block;
  font-weight: 600;
  margin-bottom: 2px;
}

.field-hint {
  font-size: 11px;
  color: var(--color-text-secondary);
  margin-bottom: 4px;
}

input[type="text"] {
  width: 100%;
  height: 32px;
  padding: 0 8px;
  border: 1px solid var(--color-text-muted);
  border-radius: 2px;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-white);
  outline: none;
}

/* The caret is a DROPDOWN affordance only — <select> (here) and the
   SearchPicker/MultiSearchPicker (.sp-caret). Plain text inputs above must NOT
   get it, so this rule is scoped to <select> and not shared with input. */
select {
  width: 100%;
  height: 32px;
  /* right pad reserves room for the shared caret; appearance:none strips the
     webview's own glyph so every <select> shows the same ▾ as the pickers. */
  padding: 0 26px 0 8px;
  border: 1px solid var(--color-text-muted);
  border-radius: 2px;
  font-size: 14px;
  color: var(--color-text);
  background-color: var(--color-white);
  background-image: var(--dropdown-caret);
  background-repeat: no-repeat;
  background-position: right 9px center;
  appearance: none;
  -webkit-appearance: none;
  outline: none;
}

input[type="text"]:focus,
select:focus {
  outline: none;
  border-bottom: 2px solid var(--color-primary);
}

.actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
}

button {
  height: 32px;
  padding: 0 16px;
  border-radius: 2px;
  border: 1px solid var(--color-border-strong);
  cursor: pointer;
  background: var(--color-white);
  font-size: 14px;
  color: var(--color-text);
}

button:hover {
  background: var(--color-bg-hover);
}

#btn-ok,
#btn-pp-ok {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}

#btn-ok:hover,
#btn-pp-ok:hover {
  background: var(--color-primary-dark);
}

/* ── Project Plan form ── */

.pp-pill-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

.pp-mode-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid #ccc;
  border-radius: 12px;
  background: var(--color-white);
  font-weight: 600;
  font-size: 13px;
}

.pp-swatch {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* #pp-type-swatch colour by row layout — one-off literals matching the JS-set values
   they replace (#1763; CSP style-src forbids the CSSOM background write). */
.pp-type-swatch-milestone { background: #2e6cb5; }
.pp-type-swatch-phase     { background: #d94a2a; }

.pp-change-link {
  background: none;
  border: none;
  color: var(--color-primary);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}

.pp-change-link:hover {
  text-decoration: underline;
  background: none;
}

.pp-combo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.pp-opt {
  font-size: 11px;
  font-weight: normal;
  font-style: italic;
  color: #888;
  margin-left: 3px;
}

.pp-date-selects {
  display: flex;
  gap: 8px;
}

.pp-date-selects select {
  flex: 1;
  min-width: 0;
}

/* PP "Expose dates" panel (#510) — grouped toggles + computed-month chips.
   The box/switch/help styling is reused from .applies / .modrow / .note
   (extended above to #form-section-pp); only the stacked rows + chip are new. */
.pp-expose-help {
  margin: -2px 0 8px;
}
.ud-stack {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
#form-section-pp .ud-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* tighten the reused .modrow inside a chip row (its standalone margin is for
   the Model-tab form, where rows stand alone). */
#form-section-pp .ud-row .modrow {
  margin: 4px 0;
}
.mo-chip {
  margin-left: auto;
  font-family: Consolas, monospace;
  font-size: 12px;
  color: var(--color-text);
  background: var(--color-bg-hover);
  border-radius: 3px;
  padding: 2px 7px;
  white-space: nowrap;
}

/* Standard reusable FAQ info-link (#509) — a circled "i" that deep-links to
   /faq#<slug>. Tokens only.
   See documentation/ux-review/issue-507/pp-controls.html §1.3. */
.faq-i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  border: 1px solid currentColor;
  border-radius: 50%;
  color: var(--color-primary);
  background: transparent;
  font-size: 10px;
  font-weight: 700;
  font-style: normal;
  line-height: 1;
  font-family: Georgia, 'Times New Roman', serif;
  text-decoration: none;
  cursor: pointer;
  vertical-align: middle;
}
.faq-i::before { content: 'i'; }
.faq-i:hover { background: var(--color-primary); color: var(--color-white); }

/* Inline (i) tooltip button + popup.
   .tip-wrap is position:relative so the popup anchors to it.
   .tip-btn is styled like .faq-i but not interactive on click (tooltip-only).
   .tip-text appears above the button, right-aligned to stay within the pane. */
.panel-body .tip-wrap {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  margin-left: 4px;
  vertical-align: middle;
}
.panel-body .tip-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  border: 1px solid var(--color-primary);
  border-radius: 50%;
  color: var(--color-primary);
  background: transparent;
  font-size: 9px;
  font-weight: 700;
  font-style: italic;
  font-family: Georgia, 'Times New Roman', serif;
  line-height: 1;
  cursor: default;
  flex-shrink: 0;
  padding: 0;
}
.panel-body .tip-btn::before { content: 'i'; }
.panel-body .tip-wrap:hover .tip-btn { background: var(--color-primary); color: var(--color-white); }
.panel-body .tip-text {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  width: 210px;
  background: var(--color-white);
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 11px;
  font-weight: 400;
  color: var(--color-text);
  line-height: 1.5;
  box-shadow: 0 2px 8px rgba(0,0,0,.12);
  z-index: 100;
  pointer-events: none;
}
.panel-body .tip-wrap:hover .tip-text { display: block; }

/* Toggle row that carries a trailing affordance (e.g. the no-project-plan
   warning beside "Link to project plan", #509). */
.modrow-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.pp-warn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: #7a5c00;
}

.message {
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: 3px;
  font-size: 13px;
}

.message.hint {
  background: #f5f5f5;
  color: #555;
  border: 1px solid #ddd;
}

.message.error {
  background: #fde7e9;
  color: #a4262c;
  border: 1px solid #f1c1c3;
}

.message.success {
  background: #dff6dd;
  color: var(--color-success);
  border: 1px solid #c3e6c3;
}


/* ── Harness runner / status view (#1011) ──────────────────────────────────────
   Harness-only DOM injected into #tab-testing (runnerUI.ts / statusView.ts),
   DCE'd from customer-prod. The pass/fail/skip step classes existed in the markup
   with no CSS — the colour-coding here is the core of the readability fix. */

.harness-runner-head {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
  margin: 14px 0 2px;
}

/* manualStep pause card (#1516): a titled "User action required" heading over a numbered list
   of the instruction's actions. The title reuses .harness-runner-head; these rules only tighten
   spacing inside the .message.hint box and give the <ol> its list layout. */
.hx-manual-title { margin: 0 0 6px; }
.hx-manual-lead { margin: 0 0 4px; font-size: 12px; color: var(--color-text-muted); }
.hx-manual-steps { margin: 4px 0 0; padding-left: 20px; }
.hx-manual-steps > li { margin: 2px 0; }

/* manualStep per-sub-step outcome controls (epic #1522 S7 / #1556): each authored sub-step in the
   pause card gets an OK/Failed/Note segmented control; a failed/note reveals an inline
   attach-screenshot + note detail, and the aggregate "Submit outcomes → verify" replaces the old
   single confirm click. Harness-only DOM (DCE'd from customer-prod). Binding UI contract:
   documentation/issue-1522/mockup-runner-substeps.html. Colours go through tokens; the pale
   on-state / detail washes are component-specific one-off literals, matching the local .out-result*
   pattern (R1). */
.hx-manual-body > .hx-manual-steps > li { margin: 0 0 12px; }
.hx-step-txt { font-size: 12.5px; line-height: 1.35; }

.hx-outcome {
  display: inline-flex;
  margin-top: 5px;
  border: 1px solid var(--color-border-strong);
  border-radius: 4px;
  overflow: hidden;
}
.hx-outcome-btn {
  border: none;
  border-right: 1px solid var(--color-border);
  background: var(--color-white);
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  cursor: pointer;
  color: var(--color-text-muted);
}
.hx-outcome-btn:last-child { border-right: none; }
.hx-outcome-btn:hover:not(:disabled) { background: var(--color-bg-hover); }
.hx-outcome-btn:disabled { cursor: default; opacity: .6; }
.hx-outcome-btn.on-ok { background: #eef7ee; color: var(--color-success); }
.hx-outcome-btn.on-failed { background: #fdf3f4; color: var(--color-error); }
.hx-outcome-btn.on-note { background: var(--color-warning-bg); color: var(--color-warning); }

.hx-sub-detail {
  margin-top: 6px;
  padding: 8px;
  border: 1px solid var(--color-border);
  border-radius: 5px;
}
.hx-sub-detail.d-failed { background: #fdf5f6; border-color: #f3d6d9; }
.hx-sub-detail.d-note { background: var(--color-warning-bg); border-color: var(--color-warning-border); }
.hx-attach-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.hx-attach-or { font-size: 11px; color: var(--color-text-secondary); }
.hx-shot-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--color-text-muted);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 2px 4px 2px 6px;
}
.hx-shot-name { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hx-shot-thumb { width: 26px; height: 18px; border-radius: 2px; object-fit: cover; border: 1px solid var(--color-border); }
.hx-shot-x { border: none; background: none; cursor: pointer; color: var(--color-text-secondary); font-size: 13px; line-height: 1; }
.hx-shot-x:disabled { cursor: default; opacity: .5; }
.hx-sub-detail .hx-note {
  width: 100%;
  min-height: 60px;
  padding: 6px 8px;
  border: 1px solid var(--color-border-strong);
  border-radius: 3px;
  font-size: 12px;
  font-family: inherit;
  line-height: 1.4;
  background: var(--color-white);
  color: var(--color-text);
  resize: vertical;
}
.hx-sub-detail .hx-note:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 1px var(--color-primary); }
.hx-req { font-size: 10.5px; color: var(--color-text-secondary); margin-top: 4px; }
.hx-req.bad { color: var(--color-error); }

.hx-manual-error { margin-top: 8px; }
.hx-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--color-border);
}
.hx-foot-note { flex: 1; font-size: 11px; color: var(--color-text-secondary); }

/* Read-only "Show" of a completed manual step (#1778 S3) — static outcome badge (no marking
   controls), read-only note box, and the read-only banner. Badge backgrounds match the marking
   card's `.hx-outcome-btn.on-*` literals (local pattern; R1 — no hex→token sweep). */
.hx-outcome-ro {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 5px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 4px;
  padding: 3px 9px;
}
.hx-outcome-ro.ro-ok { background: #eef7ee; color: var(--color-success); }
.hx-outcome-ro.ro-failed { background: #fdf3f4; color: var(--color-error); }
.hx-outcome-ro.ro-note { background: var(--color-warning-bg); color: var(--color-warning); }
.hx-ro-text {
  margin-top: 6px;
  font-size: 12px;
  color: var(--color-text);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 6px 8px;
  line-height: 1.35;
}
.hx-ro-banner {
  font-size: 11px;
  color: var(--color-text-muted);
  background: var(--color-bg-hover);
  border-radius: 4px;
  padding: 5px 9px;
  margin: 0 0 8px;
}
/* Visible degradation when a recorded screenshot can't be fetched (not in the mockup). */
.hx-shot-missing { font-size: 11px; color: var(--color-text-muted); }
/* Inline read-only fallback rendered into the TC group when the detached window can't open (M1). */
.hx-ro-inline { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--color-border); }

#btn-harness-manual-verify {
  background: var(--color-primary);
  color: var(--color-white);
  border: 1px solid transparent;
  height: 30px;
  padding: 0 12px;
  border-radius: 2px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
}
#btn-harness-manual-verify:hover:not(:disabled) { background: var(--color-primary-hover); }
#btn-harness-manual-verify:disabled { opacity: .5; cursor: default; }

#btn-harness-run {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}
#btn-harness-run:hover:not(:disabled) { background: var(--color-primary-hover); }

.hx-scope {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}
.hx-scope-lbl { font-size: 13px; color: var(--color-text-muted); }
.hx-scope-lbl.active { color: var(--color-text); font-weight: 600; }

.hx-run-line {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 10px;
}
.hx-run-line > select { flex: 1; }
/* #2244: the suite / scenario selectors are SearchPickers (a native <option> can't
   carry the last-run colour on every webview), so the picker wrap takes the same
   flex share the <select> did. */
.hx-run-line > .sp-wrap { flex: 1; min-width: 0; }

.hx-sel-stats { font-size: 11.5px; color: var(--color-text-secondary); margin: 5px 0 0; }

.hx-runrow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.hx-runrow > label { width: 58px; flex-shrink: 0; font-size: 12px; color: var(--color-text-muted); }
.hx-runrow > input {
  flex: 1;
  height: 32px;
  padding: 0 8px;
  border: 1px solid var(--color-text-muted);
  border-radius: 2px;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-white);
}
.hx-runrow > input:disabled { opacity: .5; }

.hx-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 14px;
}
.hx-head-row > .harness-runner-head { margin: 0; }
.hx-head-row > button { height: 26px; padding: 0 10px; font-size: 12px; }

.legend { font-size: 11.5px; color: var(--color-text-secondary); margin: 8px 0 4px; }
.legend b { color: var(--color-text); font-weight: 600; }

/* Result rows reuse the Integrity result-card house style (.int-item / .int-pill —
   the same component the onboarding setup log uses), compacted for the denser harness
   lists, and with wrapping messages so a step's failure detail stays on its card. */
.harness-run-steps { list-style: none; margin: 6px 0 0; padding: 0; }
#harness-runner .int-item,
#harness-status-view .int-item { padding: 5px 10px; margin-bottom: 3px; }
#harness-runner .int-item-msg,
#harness-status-view .int-item-msg { white-space: pre-wrap; }
#harness-run-summary { margin: 6px 0 0; }

/* Run surface (#1193/#1333): a bounded, auto-scrolling body so a long run can't push the tab
   forever; runLog.ts pins the scroll to the in-flight line (§9.1). The live log and the final
   Steps list share this one surface; the final render un-caps it (`hx-log--full`) so the whole
   report shows instead of scrolling inside 240px. */
.hx-log { max-height: 240px; overflow-y: auto; }
.hx-log.hx-log--full { max-height: none; overflow-y: visible; }

/* Compact "go to cell" control on a cell-addressed step card (#1333) — reveals the cell in
   Excel (probe.columnIndex → adapter.revealCell). Icon-only, sits after `.int-item-bd` in the
   flex `.int-item`, left of the duration; quiet until hovered. */
.hx-goto {
  flex-shrink: 0;
  align-self: center;
  width: 20px;
  height: 20px;
  padding: 0;
  line-height: 1;
  font-size: 13px;
  border: 1px solid var(--color-border);
  border-radius: 3px;
  background: transparent;
  color: var(--color-text-secondary);
  cursor: pointer;
}
.hx-goto:hover {
  color: var(--color-primary);
  border-color: var(--color-primary);
  background: var(--color-bg-hover);
}
.hx-goto:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* Live ticking elapsed timer on the in-flight Run-log line — right-aligned + tabular so the
   digits don't jitter as it ticks. Sits inside the flex .int-item after .int-item-bd. */
.hx-elapsed {
  flex-shrink: 0;
  align-self: center;
  font-size: 11.5px;
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}

/* Per-TC sub-lines under a scenario card — muted, status-coloured via tokens. */
.hx-tcline {
  font-size: 11.5px;
  padding: 1px 0 1px 14px;
  color: var(--color-text-secondary);
  white-space: pre-wrap;
}
.hx-tcline-pass { color: var(--color-success); }
.hx-tcline-fail { color: var(--color-error); }

/* Nested per-TC group in the grouped run viewer (#1779) — an .acc-section reused as-is; these
   two rules only truncate the name (so the right-aligned status pill survives at taskpane
   width) and right-align that pill in the reused summary flex row. */
.hx-tcgroup > summary .sec-name { flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.hx-tcpill { margin-left: auto; margin-right: 2px; flex-shrink: 0; }
/* The "Show" button on a manual TC's run-viewer group row (#1778 S3) — read-only recorded view. */
.hx-showbtn {
  flex-shrink: 0;
  height: 22px;
  padding: 0 9px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  background: var(--color-white);
  color: var(--color-primary);
  border: 1px solid var(--color-border-strong);
}
.hx-showbtn:hover { background: var(--color-bg-hover); border-color: var(--color-primary); }


/* ── Integrity tab badge ── */

.tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: #d13438;
  color: var(--color-white);
  font-size: 10px;
  font-weight: 700;
}

.tab-badge.tab-badge-ok {
  background: var(--color-success);
  min-width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 50%;
}

/* ── Integrity tab content (int1 severity triage) ── */

.vb-ok { color: var(--color-success); font-size: 13px; margin: 0; }
/* .vb-confirm/.vb-skip/.vb-picker kept as selector hooks for event wiring */

.int-summary {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.int-pill {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 12px;
}

.int-pill-error   { background: #fdf3f4; color: #a4262c; }
.int-pill-pending { background: #eaf4fc; color: var(--color-primary-hover); }
.int-pill-warn    { background: #fdf6ec; color: #8a4d0f; }
.int-pill-advisory { background: #f3f2f8; color: #5b5577; }
.int-pill-fixed   { background: #f1faf1; color: #0b6a0b; }

.int-rerun {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--color-primary);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}

.int-rerun:hover { text-decoration: underline; }
.int-rerun:disabled { opacity: .55; cursor: default; text-decoration: none; }

.int-group-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 14px 0 6px;
}

.int-summary + .int-group-title { margin-top: 0; }

.int-item {
  display: flex;
  gap: 8px;
  padding: 9px 10px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  margin-bottom: 6px;
  border-left: 3px solid;
  background: var(--color-white);
}

.int-item-error   { border-left-color: #d13438; }
.int-item-pending { border-left-color: var(--color-primary); }
.int-item-warn    { border-left-color: #ca5010; }
.int-item-advisory { border-left-color: #7a72a6; background: #fafaff; }
.int-item-fixed   { border-left-color: var(--color-success); background: #fbfdfb; }

.int-item-ic {
  flex-shrink: 0;
  font-weight: 700;
  font-size: 13px;
  margin-top: 1px;
}

.int-item-error   .int-item-ic { color: #d13438; }
.int-item-pending .int-item-ic { color: var(--color-primary); }
.int-item-warn    .int-item-ic { color: #ca5010; }
.int-item-advisory .int-item-ic { color: #7a72a6; }
.int-item-fixed   .int-item-ic { color: var(--color-success); }

.int-item-bd { flex: 1; min-width: 0; }

.int-item-msg {
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--color-text);
}

/* Currency conflict (#837): the editor blocks save when a row's value currency
   disagrees with its Format / mixes currencies / (calc) spans ≥2 contributor
   currencies. The inline message reuses .int-item-error (above); these add the
   error-state border on the offending inputs and the disabled-Save look. */
#currency-conflict { margin-top: 8px; }
.input-conflict,
.sp-input.input-conflict {
  border-color: var(--color-error) !important;
  box-shadow: 0 0 0 1px var(--color-error);
}
/* #1436: `saving` disables Save natively (:disabled); `blocked` disables it via
   aria-disabled while keeping it clickable (so a Save attempt still emits the harness
   op-complete). Both share the same greyed look — no visual drift. */
#btn-footer-save:disabled,
#btn-footer-save[aria-disabled="true"] { opacity: .55; cursor: default; }

.int-item-acts {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.int-btn {
  height: 28px;
  padding: 0 12px;
  border-radius: 2px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.int-btn-primary { background: var(--color-primary); color: var(--color-white); border: 1px solid transparent; }
.int-btn-primary:hover { background: var(--color-primary-hover); }
.int-btn-default { background: var(--color-white); color: var(--color-text); border: 1px solid var(--color-border); }
.int-btn-default:hover { background: var(--color-bg-hover); }

/* Definition errors per-row list (#814) — scrollable; one row per offending
   Definition cell: <b>Row Name</b> {definition} + a Go button (revealCell). */
.int-defn-list {
  margin-top: 8px;
  max-height: 168px;            /* ~4 rows; scrolls past that */
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-white);
}

.int-defn-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 7px 9px;
  border-bottom: 1px solid #f0f0f0;
}

.int-defn-row:last-child { border-bottom: none; }

.int-defn-text { flex: 1; min-width: 0; font-size: 12px; line-height: 1.35; }
.int-defn-name { font-weight: 700; }
.int-defn-defn { color: var(--color-text-muted); }
.int-defn-defn.is-missing { font-style: italic; color: #a4262c; }

.int-defn-go {
  flex-shrink: 0;
  height: 24px;
  padding: 0 10px;
  font-size: 11.5px;
  border: 1px solid var(--color-border);
  border-radius: 2px;
  background: #fafafa;
  color: var(--color-primary);
  cursor: pointer;
}

.int-defn-go:hover { background: #eef5fb; border-color: var(--color-primary); }
.int-btn:disabled { opacity: .55; cursor: default; }

/* ── non-numeric values panel (#439) ── */
.nn-seg { margin-top: 10px; }
.nn-seg-head {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--color-text-muted);
  margin: 10px 0 4px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.nn-seg-head.nn-ok::first-letter   { color: var(--color-success); }
.nn-seg-head.nn-warn::first-letter { color: #ca5010; }
.nn-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.nn-table th {
  text-align: left;
  color: var(--color-text-secondary);
  font-weight: 600;
  padding: 3px 6px;
  border-bottom: 1px solid var(--color-border);
}
.nn-table td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--color-bg-hover);
  vertical-align: middle;
}
.nn-ref  { color: var(--color-text-muted); }
.nn-bad  { color: #a4262c; font-family: 'Cascadia Code', Consolas, monospace; font-size: 11px; }
.nn-good { color: var(--color-success); font-weight: 600; font-family: 'Cascadia Code', Consolas, monospace; font-size: 11px; }
.nn-arr  { color: var(--color-text-secondary); }
.nn-jump { text-align: right; }
.nn-more td { text-align: center; color: var(--color-text-muted); }
.nn-go {
  background: none;
  border: none;
  color: var(--color-primary);
  font-size: 11.5px;
  cursor: pointer;
  padding: 0;
  white-space: nowrap;
}
.nn-go:hover { text-decoration: underline; }

/* ── pp-swap-confirm inline prompt (kept separate from footer) ── */

.unsaved-prompt {
  background: #fff4ce;
  border: 1px solid #e8c84b;
  border-radius: 3px;
  margin: 8px 0;
  padding: 8px 12px;
  font-size: 13px;
}

.unsaved-prompt-msg {
  display: block;
  margin-bottom: 6px;
  font-weight: 500;
}

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

.unsaved-prompt-actions button {
  flex: 1;
  padding: 4px 8px;
  font-size: 12px;
  cursor: pointer;
  border: 1px solid #ccc;
  border-radius: 3px;
  background: var(--color-white);
}

.unsaved-prompt-actions button:hover {
  background: #f5f5f5;
}

/* ── Sticky footer bar ── */

.footer-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  padding: 8px 12px;
  background: var(--color-white);
  border-top: 1px solid #e0e0e0;
  z-index: 100;
}

.footer-bar.footer-hidden {
  display: none;
}

.footer-bar.footer-dirty {
  background: #fff4ce;
  border-top-color: #e8c84b;
}

.footer-msg {
  flex: 1;
  font-size: 13px;
  font-weight: 500;
  color: #7a5c00;
}

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

.footer-actions button {
  padding: 5px 12px;
  font-size: 13px;
  cursor: pointer;
  border: 1px solid #ccc;
  border-radius: 3px;
  background: var(--color-white);
  white-space: nowrap;
}

.footer-actions button:hover {
  background: #f5f5f5;
}

#btn-footer-save {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}

#btn-footer-save:hover {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

/* ── Commit bar (#1437 / epic #1430) ──────────────────────────────────────────
   Chip · 11px pull handle · upward overlay panel. Ported from the binding mockup
   documentation/issue-1430/mockup-commit-bar.html (the review `.frame` scoping is
   dropped; the handle + panel are anchored to the fixed .footer-bar so the bar and
   its buttons never move). New widgets (R3), tokens where a colour has one; the
   message/dot one-off reds/ambers match the mockup literals (R1 local pattern). */

/* State chip — a real button in #footer-msg (dot + count), pins the panel. */
.cbar-state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  border: none;
  background: none;
  padding: 2px 4px;
  cursor: pointer;
  border-radius: 3px;
  color: inherit;
  font-family: inherit;
}
.cbar-state:hover { background: rgba(0,0,0,.05); }
.cbar-state.cbar-ok  { color: var(--color-success); }
.cbar-state.cbar-warn { color: var(--color-warning); }
.cbar-state.cbar-err { color: var(--color-error); }
.cbar-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.cbar-dot.ok { background: var(--color-success); }
.cbar-dot.warn { background: #c99700; }
.cbar-dot.err { background: var(--color-error); }
.cbar-count { font-weight: 400; color: var(--color-text-muted); }

/* Saving spinner shown in the bar (reuses the Output-tab out-spin keyframes). */
.cbar-spin {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid #cfe6f9;
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: out-spin .7s linear infinite;
  vertical-align: -2px;
  margin-right: 6px;
  flex-shrink: 0;
}

/* Pull handle — 11px tab on the bar's top edge (D4), anchored above the fixed bar. */
.cbar-pullrow {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.cbar-pull {
  width: 56px;
  height: 11px;
  padding: 0;
  /* Plain (white-bar) palette by default; the handle is a tab on the bar's top
     edge, so it tracks the bar's state — amber only under .footer-dirty below. */
  border: 1px solid #e0e0e0;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  background: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 -1px 2px rgba(0,0,0,.06);
  pointer-events: auto;
}
.cbar-grip { width: 18px; height: 2.5px; border-radius: 2px; background: #c2c2c2; }

/* Amber handle only when the bar itself is amber (dirty/blocked/etc.), so the
   tab and the bar always share one colour instead of clashing (#1766). */
.footer-dirty .cbar-pull { border-color: #e8c84b; background: #fff4ce; }
.footer-dirty .cbar-grip { background: #c9a83c; }

/* Upward overlay panel — absolute, opens above the handle; the bar never moves. */
.cbar-min {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 11px);
  border: 1px solid var(--color-border);
  border-bottom: none;
  background: var(--color-white);
  box-shadow: 0 -3px 10px rgba(0,0,0,.10);
  padding: 6px 12px;
  font-size: 12px;
  max-height: 40vh;
  overflow-y: auto;
}

/* DSL main line (green edge, monospace) — a click-jump button (D8). */
.cbar-dslonly {
  display: block;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  cursor: pointer;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 11.5px;
  color: var(--color-text);
  border-left: 3px solid var(--color-success);
  padding: 2px 0 2px 8px;
}
.cbar-dslonly:hover { background: var(--color-bg-hover); }

/* Flowing other-changes cells, one green bar each (D7/D10) — click-jump buttons. */
.cbar-chgs { display: flex; flex-wrap: wrap; gap: 3px 14px; margin-top: 5px; }
.cbar-cell {
  display: inline-flex;
  flex-direction: column;
  border-left: 3px solid var(--color-success);
  border-top: none;
  border-right: none;
  border-bottom: none;
  padding: 0 0 0 7px;
  white-space: nowrap;
  text-align: left;
  background: none;
  cursor: pointer;
  font-family: inherit;
}
.cbar-cell:hover { background: var(--color-bg-hover); }
.cbar-cell .l { font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--color-text-secondary); }
.cbar-cell .v { font-size: 12px; color: var(--color-text); }
/* #1745: the "nothing selected" cue for a cleared field — muted + italic so it
   reads as an absence, not a literal value. */
.cbar-cell .v.v-none { color: var(--color-text-muted); font-style: italic; }

/* Problem/warning cells in the G5 layout (R3). Problems: whole cell jumps. */
.cbar-probcell {
  display: flex;
  flex-direction: column;
  border-left: 3px solid var(--color-error);
  border-top: none;
  border-right: none;
  border-bottom: none;
  padding: 0 0 0 7px;
  margin: 4px 0;
  width: 100%;
  text-align: left;
  background: none;
  cursor: pointer;
  font-family: inherit;
}
.cbar-probcell:hover { background: var(--color-bg-hover); }
.cbar-probcell .l { font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--color-text-secondary); }
.cbar-probcell .v { font-size: 12px; color: #a4262c; }
.cbar-warncell { border-left-color: #c99700; cursor: default; }
.cbar-warncell:hover { background: none; }
.cbar-warncell .v { color: var(--color-warning); }

/* Empty panel note. */
.cbar-note { color: var(--color-text-muted); font-size: 11.5px; padding: 2px 0; }

/* Transient jump highlight on the target field (green-blue edge cue). */
.cbar-fieldmark { box-shadow: -3px 0 0 0 var(--color-primary); background: #f3f9ff; }

/* ── Compute UX (#1917 / epic #568 S8) ──────────────────────────────────────
   The footer's compute concern reuses .footer-bar / .footer-dirty / .footer-msg /
   .footer-actions / .cbar-state / .cbar-dot / .cbar-spin verbatim. The only NEW
   widgets: the [ Save | & Calc ] split (.sp / .sp-save / .sp-calc), the primary
   footer-action palette (.fa-primary), and the compute chip's neutral (no-dot,
   computing) tone. */

/* ── Composite compute bar (epic #2108) ─────────────────────────────────────
   Chip-row layout: the warning chip renders FIRST (warning, then compute info).
   flex-wrap is the L-10 width degradation — the stale/checking composites wrap
   their second chip to a new chip line at taskpane width; nothing truncates. */
#footer-compute-msg {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px 8px;
}

/* #2108 L-12: handle + panel are ONE stacked container anchored to the bar's top
   edge — panel open → the handle rides the PANEL's top edge (grab-to-close caps
   the thing it closes); panel hidden → the stack collapses to the 11px handle on
   the bar top, the pre-#2108 geometry. A bottom:100% child inside .cbar-min is
   clipped by its overflow-y:auto, hence the stack. The static overrides defeat
   the standalone absolute rules above; the stack itself is click-transparent so
   the 11px strip beside the handle doesn't swallow taps (the pullrow already is). */
.cbar-stack {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  pointer-events: none;
}
.cbar-stack .cbar-pullrow { position: static; }
.cbar-stack .cbar-min { position: static; pointer-events: auto; }

/* The [ Save | & Calc ] split. `.sp` is a transparent passthrough by default so a
   lone Save keeps its normal look (#btn-footer-save palette); `.sp-split` joins the
   two halves — white Save │ blue & Calc — only in the two plain dirty states. */
.sp { display: inline-flex; }
.sp.sp-split {
  border: 1px solid var(--color-border-strong);
  border-radius: 3px;
  overflow: hidden;
}
.sp.sp-split .sp-calc { border-right: none; }
.sp.sp-split .sp-save,
.sp.sp-split .sp-calc { padding: 2px 8px; border-radius: 0; }
/* id+class beats the #btn-footer-save id rule so the split Save reads as the white half. */
.sp.sp-split #btn-footer-save.sp-save {
  background: var(--color-white);
  color: var(--color-text);
  border: none;
  border-right: 1px solid var(--color-border-strong);
}
.sp.sp-split #btn-footer-save.sp-save:hover { background: var(--color-bg-hover); }
.sp .sp-calc {
  border: none;
  background: var(--color-primary);
  color: var(--color-white);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.sp .sp-calc:hover { background: var(--color-primary-dark); }
.sp .sp-calc.hidden { display: none; }

/* Primary footer action (the stale-state Calculate) — reuses the #btn-footer-save
   blue palette so the one physical bar looks consistent whichever concern it shows. */
.footer-actions .fa-primary {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}
.footer-actions .fa-primary:hover {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

input[type="number"] {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #ccc;
  border-radius: 3px;
  font-size: 14px;
}

input[type="number"]:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 1px var(--color-primary);
}

.rounding-input {
  width: 90px !important;
}

/* ── SearchPicker / MultiSearchPicker ── */

.sp-wrap,
.msp-wrap {
  position: relative;
}

.sp-input-row {
  display: flex;
  align-items: center;
  position: relative;
}

input.sp-input {
  width: 100%;
  padding: 6px 28px 6px 8px;
  border: 1px solid #ccc;
  border-radius: 3px;
  font-size: 13px;
  /* #1745: the closed control reads as a drop-down (caret affordance), so show a
     pointer on hover rather than the text I-beam. The text cursor returns on
     :focus, i.e. once the box switches to typing/filter mode. */
  cursor: pointer;
}

.sp-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 1px var(--color-primary);
  cursor: text;
}

.sp-clear {
  position: absolute;
  right: 6px;
  border: none;
  background: none;
  color: #888;
  font-size: 16px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}

.sp-clear:hover { color: #333; }

/* Dropdown caret (#1745): a static affordance so a SearchPicker reads as a
   drop-down. Hidden while the clear × is visible (a selection on a picker without
   `noneOption`) so the two never overlap; pointer-events off so a click falls
   through to the input, which opens the dropdown. */
/* Rendered from the shared --dropdown-caret (the span is emptied in
   SearchPicker.ts), so the picker caret is the identical ▾ the native <select>
   draws — one source, no drift. */
.sp-caret {
  position: absolute;
  right: 9px;
  top: 50%;
  width: 12px;
  height: 7px;
  transform: translateY(-50%);
  background: var(--dropdown-caret) no-repeat center;
  pointer-events: none;
}
.sp-input-row:has(.sp-clear:not(.hidden)) .sp-caret { display: none; }

/* #1742: an unset first-class-none picker shows its none-label (muted) in the closed
   control so a cleared picker reads as an explicit "none", not a bare search box. */
.sp-input.sp-none-value,
.sp-selected-label.sp-none-value { color: var(--color-text-muted); font-style: italic; }

.sp-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 200;
  background: var(--color-white);
  border: 1px solid #ccc;
  border-radius: 3px;
  box-shadow: 0 2px 6px rgba(0,0,0,.12);
  max-height: 180px;
  overflow-y: auto;
}

.sp-option {
  padding: 6px 10px;
  cursor: pointer;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
}

.sp-option:hover { background: #f0f6ff; }

/* Keyboard-active row (#2248) — the arrow keys move this marker and Enter commits
   it. Deliberately the SAME wash as :hover so the pointer and the keyboard read as
   one affordance; applied to the action row too, which is navigable but not an
   option. */
.sp-option.is-active,
.sp-action.is-active { background: #f0f6ff; }

/* Option status stamp (#2244, documentation/issue-2244/mockup-suite-selector.html) —
   a short toned note: the last-run age on the harness runner's suite / scenario
   pickers. In the dropdown it rides the `.sp-opt-desc` second line and only the
   colour is added here; `-inline` is the closed-control variant, which trails the
   selected label on one line (hence its own separator). Colour is the ONLY status
   signal by design (operator-only surface, #2244). */
.sp-stamp.is-ok  { color: var(--color-success); }
.sp-stamp.is-bad { color: var(--color-error); }
.sp-stamp-inline { font-size: 11px; }
.sp-stamp-inline::before { content: ' · '; color: var(--color-text-secondary); }
/* A disabled control (a run in flight) dims its stamp with it — the stamp's own colour
   would otherwise stay fully saturated against the greyed label (mockup frame F5). */
.sp-selected-label.is-disabled .sp-stamp { opacity: .55; }

/* Pinned, non-data "none" row at the top of the dropdown (#1527 S1). Reuses the
   `.sp-option` look; the border-bottom is the divider below it. `.is-current` tints
   it when nothing is selected so "none" reads as the active choice. */
.sp-option-none {
  font-style: italic;
  color: var(--color-text-muted);
  border-bottom: 1px solid #ececec;
}
.sp-option-none.is-current {
  color: var(--color-primary);
  font-style: normal;
  background: #f3f9ff;
}

.sp-no-match {
  padding: 7px 10px;
  font-size: 12px;
  color: #999;
}

/* Section header for grouped pickers (e.g. the row-type picker). */
.sp-group {
  padding: 6px 10px 3px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8a8a8a;
  background: #fafafa;
  position: sticky;
  top: 0;
}
.sp-group:not(:first-child) {
  border-top: 1px solid #ececec;
}

.sp-icon {
  flex-shrink: 0;
  width: 1.6em;
  text-align: right;
  font-size: 12px;
  opacity: 0.75;
}

/* Two-line option — icon + bold name over a one-line description — the informed
   Calc/Gate row-type picker (#1489). Description-less options keep the single-line
   `.sp-option` rule above. The icon leads (top-aligned) and the text stacks. */
.sp-option-2l {
  align-items: flex-start;
  justify-content: flex-start;
  gap: 8px;
}
.sp-option-2l .sp-icon {
  text-align: center;
  width: 1.4em;
  line-height: 1.35;
}
.sp-opt-two {
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.sp-opt-name {
  color: var(--color-text);
}
.sp-opt-desc {
  font-size: 11px;
  color: var(--color-text-secondary);
  line-height: 1.3;
}

/* Emphasised leading fragment in an option / the selected value (an italic edge
   word, e.g. "start"/"end"). Grouped with the (always-escaped) phase name in
   .sp-opt-body so the two stay adjacent under the option's space-between layout. */
.sp-opt-body {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sp-opt-edge {
  font-style: italic;
  color: var(--color-text-muted);
  margin-right: 5px;
}

/* SearchPicker markupSelection mode: the closed selection rendered as markup (so
   an option's italic edge shows) instead of a plain input value. Mimics .sp-input. */
.sp-selected-label {
  display: block;
  width: 100%;
  padding: 6px 28px 6px 8px;
  border: 1px solid #ccc;
  border-radius: 3px;
  font-size: 13px;
  background: var(--color-white);
  height: 31px;
  line-height: 19px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  /* #1745: the closed markup selection is a drop-down display (clicking it reveals
     the input for typing), so it reads as clickable — pointer, not the I-beam. */
  cursor: pointer;
}

/* External-data sub-editor (epic #1640 / E6) — the three original classes (design §11 /
   mockup-external-editor.html), tokens-only, plus the #1763 CSP additions below.
   .is-disabled: the value picker before a table is chosen ("Pick a table first"). */
.sp-selected-label.is-disabled {
  background: #f3f2f1;
  color: var(--color-text-secondary);
  cursor: not-allowed;
}
/* .is-muted: the display-only default-key label (#1763; was a CSSOM colour write). */
.sp-selected-label.is-muted { color: var(--color-text-muted); }
/* .ext-orient-override-note: the "(overriding auto-detect)" sub-label on the orientation
   override radios (#1763; was a CSSOM cssText write). */
.ext-orient-override-note { font-weight: 400; color: var(--color-text-secondary); font-size: 11px; }
/* .ext-note-spaced / .ext-hint-spaced: one-off spacing on the External-editor's key-field
   note and value-field hint (#1763; were CSSOM `margin*` writes). */
.ext-note-spaced { margin-bottom: 10px; }
.ext-hint-spaced { margin-top: 4px; }
/* .hint-override: the small inline "Override…" link inside the detected-orientation hint. */
.hint-override {
  display: inline-block;
  margin-top: 5px;
  color: var(--color-primary);
  font-weight: 600;
  font-size: 11.5px;
  cursor: pointer;
}
/* .rname: the muted-italic technical name in a Match radio ("carry forward"). */
.rname { font-style: italic; color: var(--color-text-muted); }
.panel-body .radio:has(input:checked) .rname { color: var(--color-text-muted); }

/* In-list action row (e.g. the ＋/－ show/hide-phase-ends toggle) — a clickable,
   non-selectable row pinned at the top of the dropdown. */
.sp-action {
  padding: 6px 10px;
  font-size: 11.5px;
  font-style: italic;
  color: var(--color-primary);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 7px;
  border-bottom: 1px solid #ececec;
  background: #fafcff;
}
.sp-action:hover { background: #f0f6ff; }
.sp-action-ico {
  font-style: normal;
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
  width: 12px;
  text-align: center;
}

/* MultiSearchPicker chips */

.msp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 6px;
}

.msp-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: #e8f0fe;
  border: 1px solid #c5d5f8;
  border-radius: 3px;
  padding: 2px 6px;
  font-size: 12px;
  color: #1a1a1a;
}

.msp-chip-remove {
  align-self: flex-start;
  border: none;
  background: none;
  color: #888;
  font-size: 13px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  margin-top: 1px;
}

.msp-chip-remove:hover { color: #a4262c; }

/* ── Onboarding step card ── */

.onb-step-card {
  display: flex;
  gap: 12px;
}

.onb-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

.onb-bubble {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  flex-shrink: 0;
  border: 2px solid var(--color-primary);
  color: var(--color-primary);
  background: var(--color-white);
  transition: background .2s, border-color .2s, color .2s;
}

.onb-bubble.done {
  background: var(--color-success);
  border-color: var(--color-success);
  color: var(--color-white);
}

/* #625: errored setup — red bubble instead of the success tick. */
.onb-bubble.error {
  background: #a4262c;
  border-color: #a4262c;
  color: var(--color-white);
}

.onb-body {
  flex: 1;
  min-width: 0;
}

.onb-title {
  font-size: 14px;
  font-weight: 700;
  margin-top: 3px;
  margin-bottom: 4px;
  color: var(--color-text);
}

.onb-desc {
  font-size: 12px;
  color: var(--color-text-secondary);
  margin-bottom: 10px;
  line-height: 1.45;
}

/* .onb-desc-row: a spinner + text laid out inline (#1763; was an inline
   `style="display:flex;…"` — CSP style-src forbids inline styles). */
.onb-desc-row { display: flex; align-items: center; gap: 8px; }

/* #1536: the choice-screen title row + circled-ⓘ info button. The button toggles the existing
   .onb-disclosure; a real <button> so keyboard + focus come free. Tokens only. */
.onb-title-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.onb-title-row .onb-title {
  margin: 0;
}

.onb-info-btn {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--color-border-strong);
  background: var(--color-white);
  color: var(--color-text-muted);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
}

.onb-info-btn:hover { border-color: var(--color-primary); color: var(--color-primary); }
.onb-info-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
.onb-info-btn[aria-expanded="true"] { border-color: var(--color-primary); color: var(--color-primary); background: #eef5fb; }

/* #1536: a not-yet-started friendly step (FriendlyProgress) — muted text + ellipsis icon, no
   left-accent, so pending rows read as "queued" beside the active/done ones. */
.onb-step-pending { border-left-color: var(--color-border); }
.onb-step-pending .int-item-ic,
.onb-step-pending .int-item-msg { color: var(--color-text-secondary); }

/* Disclosure widget — reuses global <details> chevron styling */
.onb-disclosure {
  border: 1px solid var(--color-border);
  border-radius: 4px;
  margin-bottom: 12px;
  border-top: 1px solid var(--color-border); /* override global details border-top reset */
  margin-top: 0;
}

/* .onb-disclosure-spaced: the choice-screen instance sits below the action cards, so it
   needs its own top margin (#1763; was an inline `style="margin-top:12px"`). */
.onb-disclosure-spaced { margin-top: 12px; }
/* .onb-disclosure-error: the failure-state "Details" disclosure sits below the error
   banner text (#1763; was a CSSOM `margin-top` write). */
.onb-disclosure-error { margin-top: 10px; }

.onb-disclosure > summary {
  padding: 7px 10px;
  font-size: 12px;
  color: var(--color-text-muted);
  background: var(--color-bg-hover);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: auto;
}

.onb-disclosure > summary::-webkit-details-marker { display: none; }

.onb-disclosure > summary > h2 { display: none; } /* suppress global h2 rule */

.onb-disclosure > summary::after {
  content: '›';
  color: var(--color-text-secondary);
  font-size: 18px;
  font-weight: 300;
  line-height: 1;
  display: inline-block;
  transition: transform 0.15s ease;
}

.onb-disclosure[open] > summary::after {
  transform: rotate(90deg);
}

.onb-disclosure-content {
  padding: 10px 12px;
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.onb-disclosure-content p {
  font-size: 12px;
  color: var(--color-text-muted);
  line-height: 1.45;
  margin: 0;
}

.onb-disclosure-content ul {
  margin: 2px 0 0 16px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.onb-disclosure-content li {
  font-size: 12px;
  color: var(--color-text-muted);
  line-height: 1.4;
}

.onb-disclosure-content code {
  font-family: Consolas, monospace;
  font-size: 11px;
  color: var(--color-text);
  background: var(--color-bg-hover);
  padding: 1px 4px;
  border-radius: 2px;
}

/* Replaces .onb-disclosure-content after setup completes (contains actual log output) */
.onb-disclosure-log {
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  border-top: 1px solid var(--color-border);
}

/* Log area (#881): a plain flex column of integrity .int-item cards — the grey box
   was dropped so the cards (which carry their own border/background) read cleanly. */
.onb-log {
  margin-bottom: 12px;
  font-size: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Plain-text log lines (the "Running setup…" placeholder and the catch-all error). */
.onb-step { color: var(--color-text-muted); }
.onb-error { color: #a4262c; }
/* .onb-step-spin: a spinner + text laid out inline (#1763; was an inline
   `style="display:flex;…"` — CSP style-src forbids inline styles). */
.onb-step-spin { display: flex; align-items: center; gap: 6px; }

/* #881: the "Other" years dropdown, revealed under the Other radio. */
.onb-years-other {
  margin: 6px 0 0 22px;
  max-width: 140px;
}

/* #881: the "change the number of years later" hint + Go button shown after generate. */
.onb-change-later {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--color-text-secondary);
  line-height: 1.4;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--color-border);
}

/* #625: failure banner — reuses the .message.error palette (#fde7e9 / #a4262c / #f1c1c3). */
.onb-status-error {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: #a4262c;
  background: #fde7e9;
  border: 1px solid #f1c1c3;
  border-radius: 4px;
  padding: 6px 10px;
  margin-bottom: 10px;
}

/* #1400: the start-mode choice cards (mockup B1). Each card is a real <button> so keyboard and
   focus come for free; the button reset (width / text-align / font / colour) is why these
   values differ from the mockup's <div> version. Tokens only. */
.onb-choice-card {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  height: auto;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 12px;
  cursor: pointer;
  background: var(--color-white);
  width: 100%;
  text-align: left;
  font-family: inherit;
  color: var(--color-text);
}

.onb-choice-card:hover { border-color: var(--color-primary); }
.onb-choice-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
.onb-choice-card.rec { border: 2px solid var(--color-primary); }

.onb-choice-ic {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: var(--color-bg-hover);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  flex-shrink: 0;
}

/* the text column inside the button (icon is the other flex child) */
.onb-choice-bd {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.onb-choice-t {
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 2px;
  color: var(--color-text);
}

.onb-choice-d {
  font-size: 11.5px;
  color: var(--color-text-muted);
  line-height: 1.4;
}

.onb-choice-badge {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  border-radius: 10px;
  padding: 1px 7px;
  margin-left: 6px;
  vertical-align: 2px;
}

/* #1401: the example gallery (mockup B2). Slim, expandable rows built on native <details> so the
   catalogue stays scannable as it grows: collapsed = one compact row (name · domain · complexity
   badge — the badge reuses .setup-loader-badge); tapping expands the detail (summary, driver
   chips, Load). Accordion behaviour (opening one closes the others) is wired in JS. Tokens only. */
.onb-ex-row {
  border: 1px solid var(--color-border);
  border-radius: 6px;
  margin-bottom: 6px;
  background: var(--color-white);
}
.onb-ex-row > summary {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 10px;
  cursor: pointer;
  list-style: none;
  min-width: 0;
}
.onb-ex-row > summary::-webkit-details-marker { display: none; }
.onb-ex-row:hover { border-color: var(--color-primary); }
.onb-ex-row[open] { border-color: var(--color-primary); }
.onb-ex-name {
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.onb-ex-domain {
  font-size: 11px;
  color: var(--color-text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}
.onb-ex-body { padding: 0 10px 10px; }
.onb-ex-sum {
  font-size: 11.5px;
  color: var(--color-text-muted);
  line-height: 1.4;
  margin: 0 0 6px;
}
.onb-ex-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 8px;
}
.onb-ex-chip {
  font-size: 10px;
  color: var(--color-text-muted);
  background: var(--color-bg-hover);
  border-radius: 10px;
  padding: 2px 7px;
}
.onb-ex-load {
  height: 26px;
  padding: 0 12px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--color-primary);
  border-radius: 2px;
  background: var(--color-white);
  color: var(--color-primary);
  cursor: pointer;
  font-family: inherit;
}
.onb-ex-load:hover { background: #e3f0fc; }

/* #1401: small back link (mockup B2 — return to the choice screen). */
.onb-back {
  border: none;
  background: none;
  color: var(--color-primary);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
  margin-bottom: 8px;
  font-family: inherit;
}

/* ── Tester tests-first flow (epic #1388 S3 #1402; __HARNESS__-gated, never in customer build) ──
   Ships ALL tester-strip CSS incl. the T4 tone-variant classes (green/neutral) so S4 (#1403,
   the T4 strip wiring) stays CSS-free — delivery-plan P3 file-disjointness. Copied from the
   mockup's NEW-widgets block, tokens only. */

/* onb-tester-strip — test-build welcome/status banner (T1/T4). A neutral card with a primary
   accent border (the mockup's blue tint, rendered tokens-only). S4's T4 strip picks a tone via
   the modifier classes below (border colour), which are shipped here so S4 stays CSS-free. */
.onb-tester-strip {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  background: var(--color-bg-hover);
  border: 1px solid var(--color-primary);
  border-radius: 6px;
  padding: 9px 10px;
  font-size: 12px;
  color: var(--color-text);
  line-height: 1.45;
  margin-bottom: 12px;
}
.onb-tester-strip b { font-weight: 600; }
.onb-tester-strip a { font-weight: 600; color: var(--color-primary); }
/* T4 tone variants (used by S4 #1403): green when this tester's build is all-green, neutral
   otherwise. Border-colour only (no color-mix — unsupported on the older harness webviews). */
.onb-tester-strip.is-green { border-color: var(--color-success); }
.onb-tester-strip.is-neutral { border-color: var(--color-border); }

/* Dimmed "step 2" preview card (T1). */
.onb-step-dim { opacity: 0.45; margin-top: 14px; }

/* onb-suite — tester run-all progress lines (T2/T3): the batch rolling-collapse of the
   Testing-tab runner (#1369), rendered inside the onboarding card. */
.onb-suite-status {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 12.5px;
  color: var(--color-text-muted);
  margin-bottom: 8px;
}
.onb-suite {
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 6px 10px;
  margin-bottom: 10px;
  font-size: 12px;
  line-height: 1.7;
}
.onb-suite-line {
  display: flex;
  gap: 6px;
  align-items: baseline;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.onb-suite-line .g-ok  { color: var(--color-success); font-weight: 700; }
.onb-suite-line .g-bad { color: var(--color-error); font-weight: 700; }
.onb-suite-line .g-run { color: var(--color-primary); font-weight: 700; }
.onb-suite-line .t {
  margin-left: auto;
  color: var(--color-text-secondary);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.onb-suite-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Skip-already-green checkbox row (T1). */
.onb-suite-skip-row {
  display: flex;
  gap: 6px;
  align-items: center;
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 8px;
}

/* Action area */
.onb-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.onb-btn-setup {
  height: 36px;
  padding: 0 16px;
  width: 100%;
  background: var(--color-white);
  color: var(--color-primary);
  border: 2px solid var(--color-primary);
  border-radius: 2px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.onb-btn-setup:hover { background: #e3f0fc; }

.onb-btn-primary {
  height: 36px;
  padding: 0 16px;
  width: 100%;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  border-radius: 2px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.onb-btn-primary:hover    { background: var(--color-primary-hover); }
.onb-btn-primary:disabled { background: var(--color-border-strong); cursor: not-allowed; }

.onb-btn-secondary {
  height: 36px;
  padding: 0 16px;
  width: 100%;
  background: var(--color-white);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: 2px;
  font-size: 14px;
  cursor: pointer;
}

.onb-btn-secondary:hover    { border-color: var(--color-border-strong); background: var(--color-bg-hover); }
.onb-btn-secondary:disabled { color: var(--color-text-secondary); cursor: not-allowed; }

.section-divider {
  border: none;
  border-top: 1px solid #e0e0e0;
  margin: 16px 0;
}

.section-heading {
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 6px;
  color: var(--color-text);
}

.domain-pack-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 8px;
  min-height: 20px;
}

.domain-pack-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  cursor: pointer;
}

.pack-list-hint {
  font-size: 12px;
  color: #777;
}

/* ── Setup tab ── */

/* Onboarding (set2) */
.setup-empty {
  text-align: center;
  padding: 14px 0 18px;
}

.setup-empty-art {
  width: 72px;
  height: 72px;
  border-radius: 18px;
  background: linear-gradient(135deg, #e5f1fb, #cfe6f9);
  margin: 0 auto 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 34px;
  color: var(--color-primary);
}

.setup-empty-h {
  font-size: 17px;
  font-weight: 700;
  margin: 0;
}

.setup-empty-p {
  font-size: 12.5px;
  color: var(--color-text-secondary);
  margin: 6px 14px 16px;
  line-height: 1.45;
}

.setup-cta {
  height: 40px;
  padding: 0 22px;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  border-radius: 3px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.setup-cta:hover { background: var(--color-primary-hover); }

.setup-divider {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--color-text-secondary);
  font-size: 11px;
  margin: 18px 0 12px;
}

.setup-divider::before,
.setup-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

.setup-lrows { display: flex; flex-direction: column; gap: 8px; }

.setup-lrow {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 10px 12px;
  cursor: pointer;
}

.setup-lrow:hover { border-color: var(--color-primary); }

.setup-lrow-ic {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--color-bg-hover);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  flex-shrink: 0;
}

.setup-lrow-tt { flex: 1; }
.setup-lrow-t  { font-size: 13px; font-weight: 600; }
.setup-lrow-d  { font-size: 11px; color: var(--color-text-secondary); }
.setup-lrow-arr { color: var(--color-text-secondary); }

/* Console (set3) */
.setup-create-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 14px;
  background: linear-gradient(var(--color-white), #fafbfc);
}

.setup-create-tt { flex: 1; }
.setup-create-t  { font-size: 13px; font-weight: 600; }
.setup-create-d  { font-size: 11px; color: var(--color-text-secondary); }

.setup-create-btn {
  height: 30px;
  padding: 0 14px;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  border-radius: 3px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.setup-create-btn:hover { background: var(--color-primary-hover); }

.setup-loaders-h {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 0 0 8px;
}

.setup-loader {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 10px;
}

.setup-loader > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  cursor: pointer;
  list-style: none;
}

.setup-loader > summary::-webkit-details-marker { display: none; }

.setup-loader-ic {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--color-bg-hover);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex-shrink: 0;
}

.setup-loader-t    { font-size: 13px; font-weight: 600; }
.setup-loader-badge {
  margin-left: auto;
  font-size: 10px;
  color: var(--color-text-secondary);
  background: var(--color-bg-hover);
  border-radius: 10px;
  padding: 2px 8px;
}

.setup-loader-cv {
  color: var(--color-text-muted);
  font-size: 11px;
  transition: transform .15s;
  margin-left: 6px;
}

.setup-loader[open] > summary .setup-loader-cv {
  transform: rotate(90deg);
}

.setup-loader-body {
  padding: 0 12px 12px;
  border-top: 1px solid var(--color-bg-hover);
}

.setup-loader-hint {
  font-size: 11px;
  color: var(--color-text-secondary);
  margin: 8px 0;
}

.setup-loader-actions {
  margin-top: 8px;
}

/* Example-model section (#1404, frame S). The destructive-replace confirm is error-weight
   (red card + red primary) per the #1333 D7 lesson, reusing the .message.error family
   literals (#fde7e9 / #f1c1c3 / #a4262c) and the .int-item-error accent (#d13438). Values
   copied verbatim from the mockup's NEW-widgets block; no new token added (R1). */
.ex-confirm {
  border: 1px solid #f1c1c3;
  border-left: 3px solid #d13438;
  border-radius: 6px;
  background: #fde7e9;
  padding: 10px 12px;
  margin-top: 10px;
}
.ex-confirm-t { font-size: 12.5px; font-weight: 700; color: #a4262c; margin-bottom: 4px; }
.ex-confirm-d { font-size: 12px; color: #a4262c; line-height: 1.45; margin-bottom: 10px; }
.ex-confirm-acts { display: flex; gap: 8px; }
.btn-danger {
  height: 28px;
  padding: 0 12px;
  font-size: 12px;
  font-weight: 600;
  border: none;
  border-radius: 2px;
  background: #d13438;
  color: var(--color-white);
  cursor: pointer;
  font-family: inherit;
}
.btn-danger:hover { background: #a4262c; }
/* The confirm's actions are inline (not the full-width onb-btn default); the Retry pill in
   the message area is likewise content-sized. */
.ex-confirm-acts .onb-btn-secondary { width: auto; height: 28px; padding: 0 12px; font-size: 12px; }
.setup-example-retry { width: auto; height: 26px; padding: 0 10px; font-size: 12px; margin-left: 8px; }

/* ── Chat tab ── */

.btn-primary {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}

.btn-primary:hover {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

/* Chat tab — shared */
#tab-chat {
  overflow: hidden;
  padding: 0;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 84px); /* 40px pane-header + 44px tab-nav */
}


.chat-attach-link {
  font-size: 12px;
  color: var(--color-primary);
  cursor: pointer;
  text-decoration: underline;
}

.chat-attach-preview {
  font-size: 12px;
  color: #555;
  margin-top: 4px;
}

/* Launcher (virgin state) */
.chat-launcher {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px 20px;
  overflow: hidden;
}

.chat-hero {
  text-align: center;
}

.chat-hero-logo {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--color-primary), #8764b8);
  margin: 0 auto 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-white);
  font-size: 22px;
}

.chat-hero-h {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
}

.chat-hero-sub {
  font-size: 12px;
  color: var(--color-text-secondary);
  margin: 3px 0 0;
}

.chat-bigbox {
  border: 1px solid var(--color-border-strong);
  border-radius: 10px;
  padding: 10px;
  margin-bottom: 14px;
  box-shadow: 0 1px 3px rgba(0,0,0,.05);
}

.chat-bigbox-ta {
  width: 100%;
  resize: none;
  border: none;
  outline: none;
  font-size: 14px;
  padding: 2px;
  min-height: 54px;
}

.chat-bigbox-row {
  display: flex;
  align-items: center;
  margin-top: 6px;
}

.chat-ask-btn {
  margin-left: auto;
  height: 32px;
  padding: 0 16px;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.chat-ask-btn:hover {
  background: var(--color-primary-dark);
}

.chat-chips-h {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  margin-bottom: 8px;
}

.chat-chips {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.chat-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 10px 12px;
  cursor: pointer;
  font-size: 13px;
  background: var(--color-white);
}

.chat-chip:hover {
  border-color: var(--color-primary);
  background: #f7fbff;
}

.chat-chip-ico {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--color-white);
  flex-shrink: 0;
}

.chat-chip-ct { flex: 1; }
.chat-chip-t  { font-weight: 600; }
.chat-chip-d  { font-size: 11px; color: var(--color-text-secondary); }
.chat-chip-arr { color: var(--color-text-secondary); }

.chat-foot {
  font-size: 10px;
  color: var(--color-border-strong);
  text-align: center;
  margin-top: 4px;
}

/* Thread — document style (chat2) */
.chat-thread {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}


.chat-turn {
  padding: 10px 14px;
  border-bottom: 1px solid var(--color-bg-hover);
  font-size: 13px;
  line-height: 1.5;
}

.chat-turn-user {
  background: #fafafa;
}

.chat-turn-role {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 6px;
}

.chat-turn-av {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--color-white);
  flex-shrink: 0;
}

.chat-turn-av-u { background: var(--color-text-muted); }
.chat-turn-av-a { background: var(--color-primary); }

.chat-turn-name {
  font-size: 12px;
  font-weight: 700;
}

.chat-turn-body { font-size: 13px; }
.chat-turn-body p { margin-bottom: 6px; }
.chat-turn-body ul { margin: 4px 0 6px 18px; }
.chat-turn-body li { margin-bottom: 3px; }

.chat-turn-body code {
  background: #edebe9;
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 12px;
  font-family: Consolas, monospace;
}

.chat-turn-body pre {
  background: #edebe9;
  border-radius: 4px;
  padding: 8px;
  overflow-x: auto;
  margin: 6px 0 0;
}

.chat-turn-body pre code {
  background: none;
  padding: 0;
  font-size: 12px;
}

/* Inline diff table (chat2) */
.chat-dtab {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  margin-top: 8px;
  overflow: hidden;
}

.chat-dtab-h {
  padding: 7px 10px;
  background: #fafafa;
  font-size: 11px;
  font-weight: 700;
  border-bottom: 1px solid var(--color-bg-hover);
  display: flex;
}

.chat-dtab-c {
  margin-left: auto;
  color: var(--color-text-secondary);
  font-weight: 400;
}

.chat-drow {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 0 6px;
  padding: 7px 10px;
  font-size: 12px;
  border-bottom: 1px solid var(--color-bg-hover);
  align-items: start;
}

.chat-drow:last-child { border-bottom: none; }

.chat-dtag {
  font-size: 10px;
  font-weight: 700;
  text-align: center;
  padding: 1px 5px;
  border-radius: 2px;
  line-height: 1.4;
}

.chat-dtag-add  { color: var(--color-success); background: rgba(16, 124, 16, 0.09); }
.chat-dtag-edit { color: var(--color-primary); background: rgba(0, 120, 212, 0.09); }
.chat-dtag-del  { color: #d13438; background: rgba(209, 52, 56, 0.09); }
.chat-dtag-move { color: #8764b8; background: rgba(135, 100, 184, 0.09); }

.chat-drow-ct { min-width: 0; }

.chat-drow-nm-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.chat-dnm {
  font-size: 12px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-text);
}

.chat-dval {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  flex-shrink: 0;
  color: var(--color-text-muted);
}

.chat-drt {
  font-size: 10px;
  color: var(--color-text-secondary);
  margin-top: 1px;
}

.chat-dpos-inline {
  font-size: 10px;
  color: var(--color-text-muted);
  font-style: italic;
}

.chat-dpos-inline strong {
  font-style: normal;
  font-weight: 600;
  color: var(--color-text);
}

.chat-drow-list {
  max-height: 220px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--color-border) transparent;
}

.chat-drow-list::-webkit-scrollbar {
  width: 4px;
}

.chat-drow-list::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: 2px;
}

/* Inline diff action buttons */
.chat-dactions {
  display: flex;
  gap: 8px;
  padding: 8px 10px;
  background: #fafafa;
  border-top: 1px solid var(--color-bg-hover);
}

.btn-chat-apply-inline {
  height: 30px;
  padding: 0 14px;
  border-radius: 2px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
}

.btn-chat-apply-inline:hover { background: var(--color-primary-dark); }
.btn-chat-apply-inline:disabled { background: var(--color-border-strong); cursor: default; }

.btn-chat-discard-inline {
  height: 30px;
  padding: 0 14px;
  border-radius: 2px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  background: var(--color-white);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
}

.btn-chat-discard-inline:hover { background: var(--color-bg-hover); }
.btn-chat-discard-inline:disabled { color: var(--color-text-secondary); cursor: default; }

.chat-diff-msg {
  font-size: 12px;
  padding: 4px 0;
  color: #d13438;
}

.chat-apply-ok {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--color-success);
  font-weight: 600;
}

.chat-apply-working {
  color: var(--color-text-muted);
  font-style: italic;
  font-weight: 400;
}

.chat-apply-warn {
  color: #ca5010;
  font-weight: 600;
}

.chat-correction-notice {
  color: #ca5010;
  font-size: 12px;
  font-style: italic;
  display: flex;
  align-items: baseline;
  gap: 4px;
}
.chat-correction-notice code {
  font-style: normal;
  background: #fef3ec;
  padding: 1px 4px;
  border-radius: 3px;
}

.chat-no-response {
  color: var(--color-text-muted);
  font-size: 12px;
  font-style: italic;
}

/* Native-feature referral deep-link (#727): an outline call-to-action on an
   assistant turn that focuses/opens the target surface (e.g. the Trace tab).
   Mirrors .btn-chat-discard-inline (outline button) with primary text. */
.chat-feature {
  margin-top: 8px;
}
.chat-feature-link {
  height: 30px;
  padding: 0 14px;
  border-radius: 2px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  background: var(--color-white);
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
}
.chat-feature-link:hover { background: var(--color-bg-hover); }
.chat-feature-link:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* Track byline in the assistant role header (#1377 S6, mockup-chat-track-chip.html). */
.chat-track-by {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;                     /* right edge of .chat-turn-role */
  font-size: 10px;
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.chat-track-by b { color: var(--color-text-muted); font-weight: 600; }
.chat-track-by-tent b { color: var(--color-warning); }
.chat-track-change {
  border: none;
  background: none;
  padding: 0;
  margin-left: 2px;
  font-size: 10px;
  color: var(--color-primary);
  cursor: pointer;
  text-decoration: underline;
}
.chat-track-change:hover { color: var(--color-primary-hover); }
.chat-track-change:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }

/* Segmented track-override strip, shown on "change" (#1377 S6). */
.chat-track-seg {
  display: flex;
  margin: 0 0 8px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  overflow: hidden;
}
.chat-track-seg-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 2px;
  border: none;
  background: var(--color-white);
  font-size: 9px;
  color: var(--color-text-muted);
  cursor: pointer;
  border-right: 1px solid var(--color-bg-hover);
}
.chat-track-seg-btn:last-child { border-right: none; }
.chat-track-seg-btn:hover { background: var(--color-bg-hover); }
.chat-track-seg-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.chat-track-seg-btn .e { font-size: 14px; }
.chat-track-seg-btn-cur { background: var(--color-bg-hover); font-weight: 700; color: var(--color-text); }

.chat-apply-detail {
  font-size: 11px;
  font-weight: 400;
  color: var(--color-text-muted);
  margin-top: 2px;
}

/* Thinking animation */
.chat-thinking-text {
  font-style: italic;
  color: var(--color-text-muted);
  font-size: 12px;
  min-height: 1.4em;
  display: block;
  margin-top: 4px;
}

.chat-thinking-text::after {
  content: '|';
  display: inline-block;
  animation: chat-cursor-blink 0.8s steps(1) infinite;
  margin-left: 1px;
  opacity: 1;
}

@keyframes chat-cursor-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}

/* Staged-changes drawer (chat3) */
.chat-drawer {
  flex-shrink: 0;
  border-top: 2px solid var(--color-primary);
  background: #f7fbff;
}

.chat-drawer-h {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  cursor: pointer;
}

.chat-drawer-ti {
  width: 20px;
  height: 20px;
  border-radius: 5px;
  background: var(--color-primary);
  color: var(--color-white);
  font-size: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.chat-drawer-tt {
  font-size: 12px;
  font-weight: 700;
}

.chat-drawer-pill {
  font-size: 10px;
  background: var(--color-primary);
  color: var(--color-white);
  border-radius: 9px;
  padding: 1px 7px;
  font-weight: 700;
}

.chat-drawer-chev {
  margin-left: auto;
  color: var(--color-text-muted);
  font-size: 11px;
}

.chat-drawer-b {
  max-height: 130px;
  overflow-y: auto;
  padding: 0 12px 4px;
}

.chat-ditem {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  font-size: 12px;
  border-top: 1px solid #e3eef8;
}

.chat-ditem-bd { flex: 1; min-width: 0; }
.chat-ditem-nm { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-ditem-dt { color: var(--color-text-muted); font-size: 11px; }

.chat-ditem-x {
  color: var(--color-text-secondary);
  cursor: pointer;
  flex-shrink: 0;
  background: none;
  border: none;
  font-size: 13px;
  padding: 0 2px;
  line-height: 1;
}

.chat-ditem-x:hover { color: #d13438; background: none; }

.chat-drawer-f {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 7px 12px;
  border-top: 1px solid #e3eef8;
}

.chat-drawer-apply {
  flex: 1;
  height: 30px;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  border-radius: 3px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.chat-drawer-apply:hover { background: var(--color-primary-dark); }

.chat-drawer-discard {
  height: 30px;
  padding: 0 14px;
  background: var(--color-white);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: 3px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

/* Input bar (thread mode) */
.chat-inbar {
  flex-shrink: 0;
  border-top: 1px solid var(--color-border);
  padding: 8px 10px;
}

.chat-inbar-core {
  display: flex;
  gap: 8px;
  align-items: flex-end;
}

.chat-inbar-ta {
  flex: 1;
  resize: none;
  min-height: 34px;
  max-height: 120px;
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  padding: 7px 8px;
  font-size: 13px;
  outline: none;
}

.chat-inbar-ta:focus { border-color: var(--color-primary); }

.chat-send-sm {
  width: 34px;
  height: 34px;
  border-radius: 6px;
  background: var(--color-primary);
  color: var(--color-white);
  border: none;
  cursor: pointer;
  font-size: 14px;
  flex-shrink: 0;
  padding: 0;
}

.chat-send-sm:hover { background: var(--color-primary-dark); }

.chat-inbar-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 5px;
}

.chat-hint {
  font-size: 10px;
  color: var(--color-border-strong);
}

/* M2 build strip (#1818 Amendment A, design §A.4.3) — a slim contextual strip above the
   input row, shown only while a discuss exchange is open; secondary by default, primary
   (highlighted) when the assistant offered the build. New widget, tokens only. */
.chat-buildstrip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  margin-bottom: 8px;
  border-radius: 6px;
  font-size: 11px;
}
.chat-buildstrip-lbl { flex: 1; color: var(--color-text-muted); }
.chat-buildstrip-btn {
  border: none;
  font-size: 11px;
  font-weight: 600;
  border-radius: 4px;
  padding: 4px 10px;
  cursor: pointer;
  white-space: nowrap;
}
/* secondary — discussing, no build offered yet */
.chat-buildstrip.secondary { background: var(--color-bg-hover); border: 1px solid var(--color-border); }
.chat-buildstrip.secondary .chat-buildstrip-btn {
  background: var(--color-white);
  color: var(--color-primary);
  border: 1px solid var(--color-border-strong);
}
/* primary — shape agreed / build offered (buildOffered highlight) */
.chat-buildstrip.primary { background: rgba(0, 120, 212, .06); border: 1px solid rgba(0, 120, 212, .18); }
.chat-buildstrip.primary .chat-buildstrip-btn { background: var(--color-primary); color: var(--color-white); }
.chat-buildstrip.primary .chat-buildstrip-btn:hover { background: var(--color-primary-dark); }

.chat-gear {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
  color: var(--color-border-strong);
}

.chat-gear:hover { color: var(--color-primary); }

/* Settings panel (invite token + BYOK key) */
.chat-settings {
  border: 1px solid var(--color-border-strong);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 8px;
  background: var(--color-surface, var(--color-white));
}

.chat-settings-h {
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 8px;
}

.chat-set-lbl {
  display: block;
  font-size: 11px;
  color: var(--color-text-muted, var(--color-border-strong));
  margin-bottom: 8px;
}

.chat-set-inp {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 3px;
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 13px;
  outline: none;
}

.chat-set-inp:focus { border-color: var(--color-primary); }

.chat-set-actions {
  display: flex;
  gap: 6px;
  margin-top: 2px;
}

.chat-set-save,
.chat-set-clear,
.chat-set-close {
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  cursor: pointer;
  border: 1px solid var(--color-border-strong);
  background: var(--color-white);
}

.chat-set-save {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}

.chat-set-save:hover { background: var(--color-primary-dark); }

.chat-set-msg {
  font-size: 11px;
  margin-top: 6px;
}

.chat-set-msg.error   { color: var(--color-danger, #b00020); }
.chat-set-msg.success { color: var(--color-success, #1a7f37); }
.chat-set-msg.hint    { color: var(--color-border-strong); }

.chat-set-note {
  font-size: 10px;
  color: var(--color-border-strong);
  margin-top: 8px;
  line-height: 1.4;
}

/* ══ Calc/Gate operand cards — the .vic card family (#1490 / epic #1453, S2) ══
   The operand-card flavour of the assumption .vi-card, promoted from the binding
   mockup (documentation/issue-1453/mockup-calc-gate-editor.html, panes N1–N8;
   `.pane .vic-*` there). Rendered by the CalcOperands component (@bp/ui). Reuses the
   assumption card look (border-left colour bar, shadow, tokens) and the shared
   .vi-edit-btn / .vi-flabel / .vi-done / .sp-* controls. */

/* Binary / unary / running-balance: cards laid out in a row with an optional infix
   connector between (the .vic-x glyph — binary only). */
.vic-row { display: flex; align-items: stretch; gap: 8px; margin: 6px 0 2px; }

/* One operand card. `padding-right` leaves room for the top-right pen / ✕. The whole
   card is tappable (→ edit), matching the assumption-card idiom (#714). */
.vic {
  position: relative;
  flex: 1;
  min-width: 0;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary);
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  padding: 5px 24px 5px 8px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  cursor: pointer;
}

/* Uppercase role caption (Inflow (+) / Outflow (−) for running balance; "Row" while
   editing) — reuses the .vi-flabel type treatment. */
.vic-role {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-text-secondary);
}

.vic-body { min-width: 0; }

/* The bold row name; wraps to at most two lines. */
.vic-nm {
  font-size: 13px;
  font-weight: 700;
  color: #201f1e;
  line-height: 1.2;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* The amber lag badge trails the name text (inline, so a long two-line name still
   wraps normally and the badge follows the last word — a fixed right column clipped
   short names in testing, mockup R29). */
.vic-body .wc-lag {
  display: inline-block;
  margin-left: 6px;
  vertical-align: 1px;
  white-space: nowrap;
  font-size: 10.5px;
  color: var(--color-warning);
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: 8px;
  padding: 0 6px;
}

/* The top-right pen affordance (reuses .vi-edit-btn); .vic is position:relative. */
.vic .vi-edit-btn { position: absolute; top: 4px; right: 4px; opacity: 1; }

/* The infix connector glyph between two binary cards (+50% vs the name size). */
.vic-x {
  align-self: center;
  flex: 0 0 auto;
  font-size: 20px;
  font-weight: 600;
  color: var(--color-text-muted);
  line-height: 1;
  padding: 0 2px;
}

/* Empty / unset required operand: a dashed placeholder card ("Choose a row…"). */
.vic.empty {
  border-style: dashed;
  border-left-style: dashed;
  border-left-width: 1.5px;
  border-color: var(--color-border-strong);
  box-shadow: none;
}
.vic.empty .vic-nm { font-weight: 400; color: var(--color-text-muted); }

/* Edit flip: the picker on top, then the Lag · (spacer) · Done row; Cancel is the ✕
   top-right. Primary border to signal the active card. */
.vic.edit { border-color: var(--color-primary); cursor: default; }
.vic.edit .vic-pick { margin: 2px 0 5px; }
.vic-cancel-x {
  position: absolute;
  top: 3px;
  right: 4px;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--color-text-muted);
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
}
.vic-cancel-x:hover { color: var(--color-text); }
.vic-editrow { display: flex; align-items: flex-end; gap: 6px; }
.vic-editrow .lagcol { flex: 0 0 44px; }
.vic-editrow .lagcol .vi-flabel { margin-top: 0; }
.vic-editrow .spacer { flex: 1; }
.vic-editrow .vi-done { height: 26px; }
/* The narrow lag input inside an edit card (mockup .lag-mini). */
.lag-mini {
  width: 44px;
  height: 26px;
  text-align: center;
  font-size: 12px;
  border: 1px solid var(--color-border-strong);
  border-radius: 3px;
  padding: 0 4px;
}
.lag-mini:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 1px var(--color-primary); }

/* Subtotal: the members as a 2-up grid of the same cards + a dashed "+ Add row…". */
.vic-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 6px 0 2px; }
.vic-grid .vic { flex: none; }

/* Subtotal members are delete-only: no pen, not tappable; the × sits top-right where
   the pen would be (§2.4). */
.vic.member { cursor: default; padding-right: 24px; }
.vic-x-remove {
  position: absolute;
  top: 3px;
  right: 4px;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--color-text-muted);
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
}
.vic-x-remove:hover { color: var(--color-error); }

/* The dashed "+ Add row…" card. */
.vic-add {
  border: 1.5px dashed var(--color-border-strong);
  border-radius: 2px;
  background: none;
  color: var(--color-text-muted);
  font-size: 12px;
  cursor: pointer;
  min-height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.vic-add:hover { border-color: var(--color-primary); color: var(--color-primary); }
