/* ════════════════════════════════════════════════════════════════════
   Inspector (right sidebar)  ·  split top + bottom
   ════════════════════════════════════════════════════════════════════ */

#inspector {
  display: flex;
  flex-direction: column;
  background: var(--surface-2);
  border-left: 1px solid var(--line);
  overflow: hidden;
  min-height: 0;
}

.ins-top {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

.ins-bottom {
  flex: 0 0 var(--ins-bottom-h);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface-2);
  min-height: 120px;
}

.ins-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.ins-title {
  font-family: var(--font-mono);
  font-size: 11px;                /* §4.7 R1 eyebrow — 阶下限 11 */
  font-weight: 600;
  letter-spacing: 0.08em;         /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-2);
}

.ins-id {
  font-family: var(--font-mono);
  font-size: 11px;                /* §4.7 R6 micro id — 阶下限 11 */
  color: var(--ink-1);
  font-weight: 500;
  letter-spacing: 0;              /* §4.7 tracking：非大写 0 */
}

/* ── Empty state · "no selection" ──────────────────────────────────
   Three-tier vertical rhythm:
   1. dashed-square mark   — geometric, hints at "drop slot" affordance
   2. mono caps eyebrow    — matches CONTROLS / SPECIFICATIONS rhythm
   3. plain-sans hint      — instructs what to do; line-broken naturally
   No emoji, no Unicode glyph, no decorative chrome. */
.ins-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  color: var(--ink-3);
  padding: 40px 28px;
  text-align: center;
}

.ins-empty-mark {
  color: var(--line);
  margin-bottom: 2px;
  line-height: 0;
}

.ins-empty-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;                /* §4.7 R1 eyebrow — 阶下限 11 */
  font-weight: 600;
  letter-spacing: 0.08em;         /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-3);
}

.ins-empty-text {
  font-size: 12px;             /* UX-2：空态副文案 11.5 ink-3 → 12 ink-2 */
  line-height: 1.7;
  color: var(--ink-2);
  max-width: 24ch;
}

.ins-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0 14px 14px;   /* UX-2 留白回收：20 → 14（§5.2 面板边距 12-16） */
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* Class selector overrides UA `[hidden] { display:none }`. Re-assert
   the hidden state with `.cls[attr]` specificity so empty state stays
   exclusive of body content. (Same pattern as .modal-backdrop[hidden].) */
.ins-body[hidden] { display: none; }

/* Inspector vNext: compact popover grammar, derived from the alert-summary
   panel before severity section color emphasis. */
#panel-inspector {
  background: var(--surface-2);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-color: var(--line-1);
  border-radius: 6px;
  box-shadow: 0 8px 24px var(--overlay-2), var(--float-edge);
}

#panel-inspector .panel-floating-header {
  height: 42px;
  justify-content: flex-end;
  background: transparent;
  border-bottom: none;
}

#panel-inspector .panel-floating-title {
  display: none;
}

#panel-inspector .panel-floating-body {
  background: var(--surface-2);
}

/* Inspector data is reference material: keep every displayed string natively
   selectable for copy/paste. Interaction chrome stays opt-out below so dragging
   and operating controls retain their existing pointer behavior. */
#panel-inspector .panel-floating-body,
#panel-inspector .panel-floating-body * {
  user-select: text;
  -webkit-user-select: text;
}

#panel-inspector .panel-floating-body :is(button, select, input[type="range"], input[type="checkbox"], [data-drag-handle], .panel-floating-resize),
#panel-inspector .panel-floating-body :is(button, select, input[type="range"], input[type="checkbox"], [data-drag-handle], .panel-floating-resize) * {
  user-select: none;
  -webkit-user-select: none;
}

#panel-inspector .panel-floating-btn {
  background: transparent;
  border: none;
  border-radius: var(--radius-md, 5px);
}

#panel-inspector .panel-floating-btn svg {
  width: 12px;
  height: 12px;
}

#panel-inspector .panel-floating-btn:hover {
  background: var(--overlay-1);
}

.ins-body {
  gap: 8px;
}

.ins-load-summary {
  min-height: 0;
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.4;
}

.ins-load-summary:empty { display: none; }

.ins-section-group {
  display: contents;
}

.ins-section-status {
  display: flex;
  min-height: 34px;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border: 1px solid var(--line-1);
  border-radius: 5px;
  color: var(--ink-2);
  font-size: 11px;
  line-height: 1.35;
}

.ins-section-status[hidden] { display: none; }

.ins-section-status::before {
  content: '';
  display: none;
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: currentColor;
  opacity: .35;
  animation: ins-load-breathe 1.1s ease-in-out infinite alternate;
}

.is-loading > .ins-section-status::before,
.is-error > .ins-section-status::before {
  display: block;
}

.is-error > .ins-section-status::before {
  background: var(--sig-error);
  opacity: 1;
  animation: none;
}

.ins-section-status-skeleton {
  display: grid;
  flex: 1 1 auto;
  gap: 6px;
}

.ins-section-status-skeleton[hidden] { display: none; }

.ins-section-status-skeleton > span {
  width: 72%;
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--overlay-1) 20%, var(--line-1) 50%, var(--overlay-1) 80%);
  background-size: 220% 100%;
  animation: ins-skeleton-shimmer 1.25s ease-in-out infinite;
}

.ins-section-status-skeleton > span:last-child { width: 46%; }

[data-ins-section].is-pending > :not(.ins-section-status):not([data-ins-section]),
[data-ins-section].is-loading > :not(.ins-section-status):not([data-ins-section]) {
  opacity: .28;
  pointer-events: none;
}

[data-ins-section].is-stale > :not(.ins-section-status):not([data-ins-section]) {
  visibility: hidden;
  opacity: 0;
}

[data-ins-load-disabled] { pointer-events: none; }

.ins-section-retry {
  margin-left: auto;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: transparent;
  color: var(--ink-1);
  font: inherit;
  cursor: pointer;
}

@keyframes ins-load-breathe {
  from { opacity: .2; transform: scale(.9); }
  to { opacity: .65; transform: scale(1); }
}

@keyframes ins-skeleton-shimmer {
  from { background-position: 100% 0; }
  to { background-position: -100% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ins-section-status::before { animation: none; transform: none; }
  .ins-section-status-skeleton > span { animation: none; }
}

/* ── Section rhythm: compact grouped blocks ───────────────────────── */
.ins-controls,
#ins-readout-section,
#ins-optical-height-section,
.ins-block-collapsible {
  margin-top: 12px;
  padding: 8px;
  background: transparent;
  border: 1px solid var(--line-1);
  border-radius: 5px;
}

.ins-controls:first-of-type,
#ins-readout-section:first-of-type,
#ins-optical-height-section:first-of-type,
.ins-block-collapsible:first-of-type {
  margin-top: 0;
}

/* Editorial section eyebrow — used by the merged Controls header.
   UX-2 升档：9.5/0.24em ink-3 → 11/0.08em ink-2（§4.2 阶下限 + §4.4）。 */
.ins-block-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0 0 8px;
  padding: 0;
  border: none;
}

/* Legacy section title (kept for Specifications collapsible toggle).
   Quieter than the previous heavy border-bottom version. */
.ins-block-title {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0;
  padding: 0;
  border: none;
}

/* Collapsible section header (Inspector Specifications). Clickable button
   wraps the title + chevron. When `aria-expanded="false"` on the button,
   the next sibling content is hidden. */
.ins-block-toggle {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: transparent;
  border: none;
  padding: 0;
  margin: 0 0 8px;
  cursor: pointer;
  color: inherit;
  font: inherit;
  text-align: left;
}
.ins-block-toggle .ins-block-title {
  flex: 1;
  margin: 0;
}
.ins-block-toggle .ins-block-chevron {
  flex: 0 0 auto;
  font-size: 11px;                /* §4.7 R6 — 阶下限 11 */
  color: var(--ink-3);
  transition: transform 0.15s ease;
  padding-left: 6px;
}
.ins-block-toggle[aria-expanded="false"] .ins-block-chevron {
  transform: rotate(-90deg);
}
.ins-block-toggle:hover .ins-block-title,
.ins-block-toggle:hover .ins-block-chevron {
  color: var(--ink);
}
.ins-block-toggle:focus-visible {
  outline: 1px dashed var(--ink-1);
  outline-offset: 2px;
}
.ins-block-toggle[aria-expanded="false"] + #ins-specs,
.ins-block-toggle[aria-expanded="false"] ~ #ins-specs {
  display: none;
}

/* Physics Model is an internal teaching-doc surface (assumptions/boundaries of
   the sim model) — hidden from end users, visible only in Developer Mode
   (§20.3, same gate as #db-status-pill / .settings-dev-only). `body.dev-mode`
   is set by apps/desktop-virtual-lab/dev-mode.js. */
body:not(.dev-mode) #ins-model-section { display: none !important; }

/* ── Physics Model block (read-only doc; from param template, §param-templates).
   Collapsible like Specs; tokens only (dark-safe). Stacked label-over-value. ── */
.ins-block-toggle[aria-expanded="false"] + #ins-model,
.ins-block-toggle[aria-expanded="false"] ~ #ins-model {
  display: none;
}
.ins-model { padding: 2px 0 4px; }
.ins-model-field {
  padding: 6px 0;
  border-top: 1px solid var(--line-soft);
}
.ins-model-field:first-child { border-top: none; }
.ins-model-key {
  display: block;
  font-family: var(--font-mono);  /* §4.7 R3 control label */
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 3px;
}
.ins-model-val {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
}
.ins-model-formula {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-1);
  background: var(--surface-3);
  padding: 5px 8px;
  border-radius: 4px;
  white-space: pre-wrap;
  word-break: break-word;
}
.ins-model-list {
  margin: 0;
  padding-left: 16px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-2);
}
.ins-model-list li { margin: 1px 0; }

/* ── Generic key/value rows (used inside Specifications block) ───── */

.ins-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 6px;
  background: var(--surface-1);
  border-radius: 4px;
  font-size: 12px;
}

/* UX-2 升档：key 11 ink-3 → 12 ink-2；val 11 → 13 ink-1（数值一律最强墨）。 */
.ins-row .ins-key {
  color: var(--ink-2);
  font-size: 12px;
}

.ins-row .ins-val {
  color: var(--ink-1);
  font-family: var(--font-mono);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

#ins-specs,
#ins-readout,
#ins-warnings {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* ════════════════════════════════════════════════════════════════════
   Editorial header card  ·  replaces 3-row Identity block
   ──────────────────────────────────────────────────────────────────── */

/* Header restructured to a vertical stack (2026-06-05): identity owns the
   full panel width, the 5 action icons become a full-width toolbar below.
   Kills the old side-by-side fight where fixed 32px buttons squeezed the
   SKU column and overlapped the text on narrow panels. */
.ins-card {
  background: var(--surface-3);
  padding: 8px;
  border-radius: 5px;
  border-bottom: none;
  margin-top: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ins-card-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.ins-card-caption {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 11px;             /* UX-2 升档：9.5/0.18em ink-3 → 11/0.08em ink-2 */
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  line-height: 1;
}

.ins-card-sep {
  color: var(--ink-3);
  opacity: 0.45;
}

.ins-card-sku {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0;              /* §4.7 R2 SKU headline — tracking 0 */
  color: var(--ink);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;   /* full SKU on hover via title attr (JS) */
}

/* Full-width action toolbar — icons share the row equally so there's no
   dead whitespace; Delete is split off to the right (see is-destructive). */
.ins-card-actions {
  display: flex;
  align-items: stretch;
  justify-content: flex-start;
  gap: 4px;
}

.ins-icon-btn {
  flex: 0 0 26px;
  width: 26px;
  min-width: 0;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--radius-md, 5px);
  color: var(--ink-2);
  cursor: pointer;
  text-decoration: none;
  transition: color 0.15s, border-color 0.15s, background 0.15s, opacity 0.15s;
  padding: 0;
}

.ins-icon-btn svg {
  width: 12px;
  height: 12px;
}

.ins-icon-btn:hover {
  color: var(--ink-1);
  background: var(--overlay-1);
}
.ins-icon-btn:focus-visible {
  outline: 1px dashed var(--ink-1);
  outline-offset: 2px;
}
.ins-icon-btn:disabled,
.ins-icon-btn[disabled] {
  cursor: not-allowed;
  opacity: 0.4;
  pointer-events: none;
}

/* Primary action variant for future Inspector icon actions. */
.ins-icon-btn.is-primary {
  color: var(--ink-1);
  background: transparent;
}
.ins-icon-btn.is-primary:hover:not(:disabled):not([disabled]) {
  color: var(--surface);
  background: var(--ink-1);
}
.ins-icon-btn.is-primary:disabled,
.ins-icon-btn.is-primary[disabled] {
  color: var(--ink-3);
  background: transparent;
  opacity: 0.5;
}

/* Destructive variant — visually muted by default, red on hover.
   Used by Delete in the header card actions row. Extra left margin to
   spatially separate from non-destructive icons. */
.ins-icon-btn.is-destructive {
  flex: 0 0 auto;
  width: 26px;
  margin-left: auto;
  color: var(--sig-error);
}
.ins-icon-btn.is-destructive:hover {
  color: var(--bad);
  background: var(--bad-bg);   /* was hardcoded #fef2f2 — broke in dark (DESIGN.md §3.3) */
}
.ins-icon-btn.is-destructive:focus-visible {
  outline-color: var(--bad);
}

/* Show Data — FROG-only wide button (frog-panel.js). Full controls-width
   rectangle, sitting below the pose stack (Yaw) and above the Beam align
   height (Y) readout. Cobalt-tinted to read as a primary affordance. */
.ins-showdata-btn {
  display: block;
  width: 100%;
  height: 30px;
  margin: 8px 0 4px;
  background: var(--surface-2);
  border: 1px solid var(--ink-1);
  border-radius: 4px;
  color: var(--ink-1);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.ins-showdata-btn:hover {
  background: var(--ink-1);
  color: #fff;
}
.ins-showdata-btn:focus-visible {
  outline: 1px dashed var(--ink-1);
  outline-offset: 2px;
}
/* Re-assert UA `[hidden] { display:none }` over the display:block above so the
   FROG-only gating in updateShowDataButtonForSku takes effect (same pattern as
   .ins-body[hidden] / #fab-assemble-all[hidden]). */
.ins-showdata-btn[hidden] { display: none; }

/* ════════════════════════════════════════════════════════════════════
   Controls section  ·  Tunable + Pose merged · dense single-line rows
   ──────────────────────────────────────────────────────────────────── */

/* Tunable sub-wrapper (Power / Wavelength etc.) — full-width sliders. */
.ins-controls-tunable {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ins-controls-tunable:empty {
  display: none;
}
/* Space between Tunable area and Pose grid if Tunable exists. */
.ins-controls-tunable:not(:empty) + .ins-pose-stack {
  margin-top: 6px;
}

/* Pose stack: 1-column vertical so each slider gets a long track.
   (2026-05-27 reverted from 2-col grid back to vertical per user request) */
.ins-pose-stack {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ── Vertical 2-row control (used by BOTH tunable + pose) ──────────
   Row 1: label · editable number-input · unit
   Row 2: full-width slider (long track spanning all 3 cols)
   The number input is the value display AND keyboard entry point —
   typing clamps to [min,max] and propagates through updateInstrument.
   Used by `.tunable` (legacy class name) + `.ins-control` both. */
.ins-control,
.tunable {
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 6px;
  row-gap: 4px;
  padding: 6px;
  margin: 0;
  background: var(--surface-1);
  border: none;
  border-radius: 4px;
}

/* Legacy `.tunable > .tunable-label` mapping (defensive alias). */
.tunable > .tunable-label {
  display: contents;
}

.ins-control > .ins-control-label,
.tunable > .tunable-label > span {
  grid-column: 1;
  grid-row: 1;
  font-family: var(--font-mono);
  font-size: 12px;             /* UX-2 升档：10.5 ink-3 → 12 ink-2 */
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
  line-height: 1;
}

/* Editable number value — visually a label, behaves as <input>.
   Spinners hidden on both engines. Focus = cobalt outline + tint. */
.ins-control > .ins-value-input,
.tunable > .ins-value-input {
  grid-column: 2;
  grid-row: 1;
  width: 76px;                 /* UX-2：13px 数字需要的位宽（64 → 76） */
  min-width: 0;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 13px;             /* UX-2 升档：11.5 → 13（数值 = base） */
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  background: transparent;
  border: none;
  border-radius: 2px;
  padding: 2px 5px;
  margin: 0;
  outline: none;
  -moz-appearance: textfield;
  appearance: textfield;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.ins-control > .ins-value-input::-webkit-outer-spin-button,
.ins-control > .ins-value-input::-webkit-inner-spin-button,
.tunable > .ins-value-input::-webkit-outer-spin-button,
.tunable > .ins-value-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.ins-control > .ins-value-input:hover,
.tunable > .ins-value-input:hover {
  background: var(--overlay-1);
}
.ins-control > .ins-value-input:focus,
.tunable > .ins-value-input:focus {
  background: var(--surface-2);
  color: var(--ink-1);
}
.ins-control > .ins-value-input.is-invalid,
.tunable > .ins-value-input.is-invalid {
  color: var(--bad);
}

.ins-control > .ins-unit,
.tunable > .ins-unit {
  grid-column: 3;
  grid-row: 1;
  font-family: var(--font-mono);
  font-size: 11px;             /* §4.7 R6 unit — 11 */
  font-weight: 500;
  letter-spacing: 0;           /* §4.7 tracking：非大写 0 */
  color: var(--ink-3);
  white-space: nowrap;
  line-height: 1;
  min-width: 18px;
}

/* Fixed (non-tunable) parameter — reuses the .ins-control tunable layout so the
   label / value / unit fonts match the editable sliders exactly. The value is a
   disabled field (read-only) and the slider row is replaced by a status caption
   (.ins-fixed-note) sitting where the track would be. */
.ins-control-fixed > .ins-value-input:disabled {
  color: var(--ink);
  -webkit-text-fill-color: var(--ink);
  opacity: 1;
  cursor: default;
  /* 固定（只读）值不是输入框 —— 去掉 v2 数值输入框的座/边，读作纯数值不误导可编辑。 */
  background: transparent;
  border-color: transparent;
}
.ins-control-fixed > .ins-value-input:disabled:hover {
  border-color: transparent;
}
.ins-control-fixed > .ins-fixed-note {
  grid-column: 1 / -1;
  grid-row: 2;
  font-family: var(--font-mono);
  font-size: 11px;             /* §4.7 R6 note — 阶下限 11 */
  font-weight: 500;
  letter-spacing: 0.08em;      /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1;
}

.rail-slider-control {
  grid-template-columns: 1fr auto auto auto;
}
.rail-slider-control > .rail-slider-remove {
  grid-column: 4;
  grid-row: 1;
}
.rail-slider-remove,
.rail-slider-add {
  appearance: none;
  border: 1px solid var(--line-1);
  background: transparent;
  color: var(--ink-2);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  padding: 5px 7px;
  cursor: pointer;
}
.rail-slider-remove:hover,
.rail-slider-add:hover {
  border-color: var(--ink-3);
  color: var(--ink-1);
  background: var(--overlay-1);
}
.rail-slider-add:disabled {
  cursor: default;
  opacity: 0.45;
  background: transparent;
}
.rail-slider-action {
  grid-template-columns: 1fr auto;
}
.rail-slider-action > .rail-slider-add {
  grid-column: 2;
  grid-row: 1;
}
.rail-slider-action > .ins-fixed-note {
  grid-column: 1 / -1;
  grid-row: 2;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1;
}

/* Slider — row 2, spans all columns for the full-width long track */
.ins-control > .ins-tunable-hint,
.tunable > .ins-tunable-hint {
  grid-column: 1 / -1;
  grid-row: 3;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 10px;
  row-gap: 2px;
  margin-top: 2px;
  font-family: var(--font-mono);
  font-size: 11px;             /* §4.7 R6 hint — 阶下限 11 */
  font-weight: 500;
  letter-spacing: 0;           /* §4.7 tracking：非大写 0 */
  color: var(--ink-3);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.ins-tunable-hint-row {
  display: contents;
}
.ins-tunable-hint-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ins-tunable-hint-value {
  text-align: right;
  color: var(--ink-2);
  white-space: nowrap;
}

.ins-control input[type="range"],
.tunable input[type="range"] {
  grid-column: 1 / -1;
  grid-row: 2;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2px;
  background: var(--paper-deep);
  outline: none;
  border-radius: 999px;
  cursor: pointer;
  margin: 4px 0 0;
  padding: 0;
  border: none;
}

.ins-control input[type="range"]::-webkit-slider-thumb,
.tunable input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;                       /* v2 affordance ↑ 12→14（DESIGN.md §8.3）*/
  height: 14px;
  background: var(--bg);
  border: 1px solid var(--ctl-line); /* v2：thumb 边并入控件座系统（原 1.5px ink 强边）*/
  border-radius: 50%;
  cursor: grab;
  box-shadow: 0 1px 3px -1px rgba(0, 0, 0, 0.45);
  transition: transform 0.15s, box-shadow 0.15s;
}
.ins-control input[type="range"]:hover::-webkit-slider-thumb,
.tunable input[type="range"]:hover::-webkit-slider-thumb {
  transform: scale(1.12);
  box-shadow: 0 2px 6px -1px rgba(0, 0, 0, 0.55);
}
.ins-control input[type="range"]::-webkit-slider-thumb:active,
.tunable input[type="range"]::-webkit-slider-thumb:active {
  cursor: grabbing;
  background: var(--ink-1);
}

.ins-control input[type="range"]::-moz-range-thumb,
.tunable input[type="range"]::-moz-range-thumb {
  width: 14px;                       /* v2 affordance ↑ 12→14（DESIGN.md §8.3）*/
  height: 14px;
  background: var(--bg);
  border: 1px solid var(--ctl-line);
  border-radius: 50%;
  cursor: grab;
}

/* ── AOI direct control (#ctl-aoi, signed slider — mirror only) ────────
   v1.11.01 merged control. Track paints the SKU's rated AOI window mirrored
   onto the signed axis (--aoi-track inline gradient, set by
   inspector-panel.syncAoiTrack); overlay dots mark the centre 0° (hollow,
   static DOM) and the rated boundaries (filled, injected by syncAoiTrack at
   the dark/amber junctions — also the drag clamp limits, Shift overrides).
   The note row underneath carries rated / out-of-rated / no-beam status.
   Display only — the physics gate (AOI-GATE-001) owns the judgment.
   FUTURE (A-3 single-value design AOI): full-amber track + two rated dots,
   non-Shift thumb snapping between them — same dot/note vocabulary.
   .is-disabled = no beam lands on the mirror front (AOI 概念不存在，整模块灰，
                  与 pitch 无关 — v1.11.02 user 定灰显语义).
   .is-slider-locked = beam present but not directly draggable (pitch ≠ 0 非线性
                  / 无 XZ 参考束)：只灰轨道+拇指，数字框转全墨只读、note 照常.
   .is-out = live AOI outside rated range (warn voice on value + note). */
#ctl-aoi,
.ins-control > .pose-track-wrap {
  /* 半个拇指宽（.ins-control 12px range thumb 的一半）——拇指中心行程两端各
     内缩半拇指，渐变交界 / 边界点 / 拇指中心统一用该值折算坐标（裸 % 会让
     拖到 rated 边界的拇指与点心错开半个拇指，syncAoiTrack calc 同源）。
     v5.0.19：BBO Yaw 轨道的相位匹配目标点复用同一折算 → 共用这一处声明。 */
  --aoi-thumb-r: 6px;
}
#ctl-aoi input[type="range"] {
  background: var(--aoi-track, var(--paper-deep));
  margin: 0;                /* spacing moves to .aoi-track-wrap */
}
#ctl-aoi .aoi-track-wrap {
  grid-column: 1 / -1;      /* takes the slider's row-2 grid slot */
  grid-row: 2;
  position: relative;
  display: flex;
  align-items: center;
  margin-top: 4px;
}
/* Pose 控件的 Yaw 轨道包层（v5.0.19）：BBO 解锁态要在轨道上标「相位匹配到位」的目标点，
   点需要一个 position:relative 的容器 → range 外包一层，由 wrap 顶替 range 原来的 grid
   槽（行 2 整宽，与 #ctl-aoi .aoi-track-wrap 同构）。非 BBO 件 wrap 内只有 range，
   视觉与改版前逐像素一致。 */
.ins-control > .pose-track-wrap {
  grid-column: 1 / -1;
  grid-row: 2;
  position: relative;
  display: flex;
  align-items: center;
}

/* Explicit yaw ownership action. It sits inside the Yaw card, directly below the
   track, so it remains part of the canonical Controls section when Workbench moves
   that section. Direct actions may use a thin outline; the resting fill stays
   transparent and appears only on hover (project chrome affordance convention). */
.ins-align-beam-btn {
  grid-column: 1 / -1;
  grid-row: 3;
  min-height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 2px;
  padding: 5px 9px;
  appearance: none;
  background: transparent;
  border: 1px solid var(--ctl-line);
  border-radius: 3px;
  color: var(--ink-2);
  font: inherit;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s, opacity 0.15s;
}
.ins-align-beam-btn[hidden] { display: none; }
.ins-align-beam-btn:hover:not(:disabled) {
  color: var(--ink-1);
  border-color: var(--ink-3);
  background: var(--overlay-1);
}
.ins-align-beam-btn:focus-visible {
  outline: 1px dashed var(--ink-1);
  outline-offset: 2px;
}
.ins-align-beam-btn:disabled {
  cursor: not-allowed;
  opacity: 0.42;
  background: transparent;
}
.aoi-dot {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  pointer-events: none;     /* markers only — drag passes through */
}
.aoi-dot-zero {
  left: 50%;
  background: var(--surface);
  border: 1px solid var(--ink-3);
}
.aoi-dot-rated {
  background: var(--ink-1);          /* same voice as the in-range segment */
  border: 1px solid var(--surface);   /* halo keeps it legible on both segments */
}
/* Design-AOI mirrors (chirped): the track is all-amber (every angle but the
   design angle is off-spec) with two ink dots marking ±design — non-Shift drag
   snaps between them, Shift frees it and fires AOI-DESIGN-001. Ink (not cobalt)
   sets them apart from a rated acceptance range. (A-3 吸附制 / DEVLOG) */
.aoi-dot-design {
  background: var(--ink);
  border: 1px solid var(--surface);   /* halo keeps it legible on the amber track */
}
#ctl-aoi .aoi-note {
  grid-column: 1 / -1;
  grid-row: 3;
  font-family: var(--font-mono);
  font-size: 11px;          /* §4.7 R6 note — 阶下限 11（.ins-fixed-note voice） */
  font-weight: 500;
  letter-spacing: 0.08em;   /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-3);
  line-height: 1;
  margin-top: 2px;
  min-height: 10px;         /* keep row height stable when note is empty */
  font-variant-numeric: tabular-nums;
}
#ctl-aoi.is-out .aoi-note,
#ctl-aoi.is-out .ins-value-input { color: var(--warn); }
#ctl-aoi.is-disabled {
  opacity: 0.45;
}
#ctl-aoi.is-disabled input {
  cursor: default;
}
/* 滑块单独锁定（有束但不可直拖）：只灰轨道+点+拇指；数字框是活读数 →
   disabled 但走全墨（is-out 时警色），note 行照常不灰。 */
#ctl-aoi.is-slider-locked .aoi-track-wrap {
  opacity: 0.45;
}
#ctl-aoi.is-slider-locked input[type="range"] {
  cursor: default;
}
#ctl-aoi.is-slider-locked input[type="range"]::-webkit-slider-thumb {
  cursor: default;
}
#ctl-aoi.is-slider-locked .ins-value-input:disabled {
  color: var(--ink);
  -webkit-text-fill-color: var(--ink);
  opacity: 1;
  cursor: default;
}
#ctl-aoi.is-slider-locked .ins-value-input:disabled:hover {
  border-color: transparent;
}
#ctl-aoi.is-out.is-slider-locked .ins-value-input:disabled {
  color: var(--warn);
  -webkit-text-fill-color: var(--warn);
}

.ins-control.is-slider-locked:not(#ctl-aoi) .ins-zero-track,
.ins-control.is-slider-locked:not(#ctl-aoi) input[type="range"] {
  opacity: 0.45;
}
.ins-control.is-slider-locked:not(#ctl-aoi) input[type="range"],
.ins-control.is-slider-locked:not(#ctl-aoi) input[type="range"]::-webkit-slider-thumb {
  cursor: default;
}
.ins-control.is-slider-locked:not(#ctl-aoi) .ins-value-input:disabled {
  color: var(--ink);
  -webkit-text-fill-color: var(--ink);
  opacity: 1;
  cursor: default;
}
.ins-control.is-slider-locked:not(#ctl-aoi) .ins-value-input:disabled:hover {
  border-color: transparent;
}

/* ── DB spec rows (lighter weight than sim rows) ─────────────────── */

.ins-spec-divider {
  height: 1px;
  background: var(--line-soft);
  margin: 8px 0 6px;
}
.ins-row-db .ins-key {
  color: var(--ink-3);
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
}
.ins-row-db .ins-val {
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  color: var(--ink-2);
}

/* ════════════════════════════════════════════════════════════════════
   Inspector footer  ·  pinned action bar (primary + ghost-danger)
   ──────────────────────────────────────────────────────────────────── */

/* (2026-05-27) Footer fully removed — all 4 actions live as icon buttons
   in the header card. No pinned chrome bar at the bottom of the inspector. */

/* Legacy class kept as backward-compat alias (still referenced by JS-
   inserted preview banners that close out the renderPreview path). */
.ins-actions { margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }

button.primary {
  height: 38px;
  padding: 0 16px;
  background: var(--ink-1);
  color: var(--surface);
  border: none;
  border-radius: 2px;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background 0.18s, color 0.18s;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

button.primary::after {
  content: '→';
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 13px;
  transition: transform 0.22s;
}

button.primary:hover:not(:disabled) {
  background: var(--ink-1);
}

button.primary:hover:not(:disabled)::after {
  transform: translateY(-50%) translateX(4px);
}

button.primary:disabled {
  background: var(--paper-deep);
  color: var(--ink-3);
  cursor: not-allowed;
}

button.primary:disabled::after { opacity: 0.3; }

/* Ghost destructive — sits below the primary; quiet by default, red on hover. */
button.secondary {
  height: 30px;
  padding: 0 14px;
  background: transparent;
  color: var(--ink-3);
  border: 1px solid transparent;
  border-radius: 2px;
  font-family: var(--font-ui);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

button.secondary:hover {
  border-color: var(--bad);
  color: var(--bad);
  background: transparent;
}

/* ── Warning chips (inside Inspector "Warnings" section) ─────────── */

.ins-block-warnings {
  position: relative;
  overflow: hidden;
  margin-top: 12px;
  padding: 8px 8px 8px 11px;
  background: var(--sig-warn-bg);
  border: none;
  border-radius: 5px;
}

.ins-block-warnings::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  background: var(--sig-warn);
}

.ins-block-warnings.is-error {
  background: var(--sig-error-bg);
}

.ins-block-warnings.is-error::before {
  background: var(--sig-error);
}

.ins-warning-toggle {
  position: relative;
  z-index: 1;
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0;
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
  text-align: left;
}

.ins-warning-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-1);
}

.ins-warning-count {
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--sig-warn);
  color: var(--surface-1);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 18px;
  text-align: center;
}

.ins-block-warnings.is-error .ins-warning-count {
  background: var(--sig-error);
}

#ins-warnings {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}

#ins-warnings[hidden] {
  display: none;
}

.warn-chip {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px;
  background: var(--warn-bg);
  border-left: 2px solid var(--warn);
  border-radius: 0 3px 3px 0;
  font-size: 11px;
  color: var(--warn-ink);
  line-height: 1.5;
  margin-bottom: 5px;
}

/* 橙档 .warn-chip.caution 已废（2026-07-28：finding.level 只剩 warn 黄 / bad 红，
   纯由 severity 派生）。--caution / --fault-caution token 本身保留 —— 装配面板
   碰撞徽章与台面可用区高亮另有用途，与报错分级无关。 */

.warn-chip.bad {
  background: var(--bad-bg);
  border-left-color: var(--bad);
  color: var(--bad-ink);
}

/* 光高族 chip（category=beam_height）：标尺图标 + Δ 距离 pill。pill 渲成档色
   （warn 黄 / bad 红），让「差了哪一段距离」一眼可读，
   并与通用告警 chip 区分（2026-06-12 user）。 */
.warn-chip-delta {
  flex: 0 0 auto;
  align-self: center;
  margin-left: 4px;
  padding: 1px 8px;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  font-family: var(--font-mono, monospace);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--warn);
}
.warn-chip.bad .warn-chip-delta { color: var(--bad); }

.warn-chip-icon {
  flex: 0 0 auto;
  font-size: 12px;
  line-height: 1.3;
}

.warn-chip-text {
  flex: 1;
  font-family: var(--font-ui);
}

.warn-chip-text strong {
  font-weight: 600;
}

/* 统一报错引擎规则 ID 徽标（finding.ruleId，如 AOI-GATE-001）——触发后
   Inspector 显示规则 ID（CLAUDE.md §5.6），可按 ID 回 constraints.json 查规则。 */
.warn-chip-rule {
  flex: 0 0 auto;
  align-self: flex-start;
  margin-left: 4px;
  padding: 1px 5px;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-family: var(--font-mono, monospace);
  font-size: 11px;                   /* §4.7 R6 rule badge — 阶下限 11 */
  letter-spacing: 0;                 /* §4.7 tracking：非大写 0 */
  opacity: 0.65;
  white-space: nowrap;
}

/* 替代型号推荐区（warn-chip 下挂，§13「推荐替代型号」）。候选行复用
   .ins-swap-item / -sku / -meta（与 Swap 菜单同视觉）；空集 = 统一
   Coming soon badge（§20.4）。 */
.warn-fix {
  margin: 4px 0 0;
  padding: 6px 8px;
  background: var(--surface-1);
  border: none;
  border-radius: 4px;
}
.warn-fix-head {
  padding: 0 2px 4px;
  font-family: var(--font-mono);
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  letter-spacing: 0.08em;        /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-3);
}
.warn-fix-note {
  margin-left: 6px;
  font-size: 11px;
  color: var(--ink-3);
}
.warn-fix-item { min-height: 28px; }
.warn-fix-item .ins-swap-item-meta { white-space: normal; text-align: right; }
/* 'add' 类推荐（爬高架 FLOOR-HEIGHT-001）= 只读行：复用 -sku/-meta 内排版，
   但不可点击（无 button / 无 hover / 无指针，user 2026-06-26）。 */
.warn-fix-item-static {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 28px;
  padding: 4px 6px;
  cursor: default;
}
.warn-fix-item-static .ins-swap-item-meta { white-space: normal; text-align: right; }


/* ── Hardware Parts（装配硬件信息块，2026-06-22 user：双击带架镜片同时展示
   机械架信息）。卡片堆叠在 Mount/Post/Holder 下拉之下：每件 = SKU + label +
   vendor + 关键尺寸 + 价格 + datasheet 链接。display-only，无副作用。 */
.ins-hardware {
  margin-top: 8px;
}
.ins-hardware-title {
  margin: 0 0 4px;
  padding: 0 2px;
  font-family: var(--font-mono);
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  letter-spacing: 0.08em;        /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-3);
}
.ins-hardware-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ins-hw-card {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 4px 8px;
  align-items: baseline;
  padding: 6px;
  background: var(--surface-1);
  border: none;
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.35;
}
.ins-hw-role {
  grid-column: 1;
  font-family: var(--font-mono);
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  letter-spacing: 0.08em;        /* §4.7 tracking：大写 0.08em */
  text-transform: uppercase;
  color: var(--ink-3);
}
.ins-hw-main {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ins-hw-sku {
  font-family: var(--font-mono);
  color: var(--ink-1);
  word-break: break-all;
}
.ins-hw-label {
  margin-top: 1px;
  color: var(--ink-2);
}
.ins-hw-meta {
  margin-top: 1px;
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  color: var(--ink-3);
}
.ins-hw-side {
  grid-column: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  white-space: nowrap;
}
.ins-hw-price {
  font-family: var(--font-mono);
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  color: var(--ink-2);
}
.ins-hw-link {
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  color: var(--accent, var(--ink-2));
  text-decoration: none;
}
.ins-hw-link:hover { text-decoration: underline; }

/* ════════════════════════════════════════════════════════════════════
   Optical-height section  ·  3D-only readout (#ins-optical-height-section)
   ────────────────────────────────────────────────────────────────────
   Mirrors §6.4 4-tier Δ status (≤1mm normal / 1-3 soft / 3-10 warn /
   >10 err). The pill sits inline with the Δ value, no row colour
   override (delta colour comes from the pill alone to keep the readout
   table tone-neutral).
   ════════════════════════════════════════════════════════════════════ */
/* Row rhythm: match the Specifications block (#ins-specs uses flex gap:4px)
   so the stacked white rows breathe the same 4px apart. Here the rows are
   direct children of the section (title + rows share one container, no
   #ins-specs-style flex-gap wrapper), so space them with adjacent-sibling
   margin — leaves the title→row1 gap and the global .ins-row untouched. */
#ins-optical-height-section .ins-row + .ins-row {
  margin-top: 4px;
}
/* Δ row: pill on its own line below the value so a narrow Inspector
   doesn't wrap "+29.25 mm" mid-number. The pill is a child of .ins-val,
   so we make .ins-val a flex-wrap column container. */
#ins-optical-height-section .ins-row-delta .ins-val {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}
#ins-optical-height-section .ins-row-delta .ins-val > .ins-height-pill {
  white-space: nowrap;
}
.ins-height-pill {
  font-family: var(--font-sans, inherit);
  font-size: 11px;               /* §4.7 R6 — 阶下限 11 */
  font-weight: 500;
  padding: 1px 6px;
  border-radius: 999px;
  white-space: nowrap;
  letter-spacing: 0;             /* §4.7 tracking：非大写 0 */
}
.ins-height-pill--ok   { color: var(--sig-ok);    background: var(--sig-ok-bg); }
.ins-height-pill--soft { color: var(--ink-2);     background: var(--sig-warn-bg); }
.ins-height-pill--warn { color: var(--sig-warn);  background: var(--sig-warn-bg); }
.ins-height-pill--err  { color: var(--sig-error); background: var(--sig-error-bg); }

/* ── 电动旋转光学座托管件槽下拉（rotary_mount，2026-07-01）：复用装配浮窗 .aa-dd 自绘下拉
      （22-assembly-panel.css）+ 左边栏 .lib-prod 卡片选项（缩略图+SKU+规格）。项目 UI 风格、全 token。 ── */
.rm-optic-dd { flex: 1; min-width: 0; }
.rm-optic-dd .aa-dd-btn { min-height: 42px; padding: 3px 22px 3px 4px; display: flex; align-items: center; }
.rm-optic-dd .aa-dd-caret { top: 50%; transform: translateY(-50%); }
.rm-optic-dd .aa-dd-list { max-height: 280px; }
.rm-optic-dd .aa-dd-opt { padding: 2px 3px; white-space: normal; }
.rm-optic-empty { color: var(--ink-2); padding: 4px 6px; font-size: 12px; }
/* 卡片下拉内的功能分组标题（Cube optic：Beamsplitters / Mirrors，2026-07-29）——排印仿
   .sp-group / .rel-group；非选项行，故不吃指针事件。 */
.rm-optic-dd .aa-dd-group {
  padding: 8px 6px 3px; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3-v1);
  pointer-events: none;
}
.rm-optic-dd .aa-dd-group:first-child { padding-top: 5px; }

/* ── 笼式 cube 折向 4 档选择器（cage_cube，Phase 2）：→↑←↓ 分段按钮，占 ins-control row-2 全宽。
      项目 UI 风格、全 token。选中态 is-active 高亮（承 §10.3 离散折向吸附）。 ── */
.cage-roll-seg { grid-column: 1 / -1; grid-row: 2; display: flex; gap: 4px; }
.cage-roll-seg .aa-seg-btn {
  flex: 1; min-width: 0; min-height: 30px; padding: 2px 0;
  font-size: 15px; line-height: 1; cursor: pointer;
  color: var(--ink-2); background: var(--surface-2);
  border: 1px solid var(--stroke-1); border-radius: 5px;
}
.cage-roll-seg .aa-seg-btn:hover { color: var(--ink-1); border-color: var(--stroke-2); }
.cage-roll-seg .aa-seg-btn.is-active {
  color: var(--accent-ink, #fff); background: var(--accent, #3a7afe); border-color: var(--accent, #3a7afe);
}
/* 卡片选项：复用 .lib-prod grid，但去左边栏卡片的外边距/边框/悬停，贴合下拉宽度。 */
.rm-opt-card.lib-prod {
  margin: 0; border: 0; padding: 4px 6px; background: transparent;
  grid-template-columns: 34px 1fr auto; column-gap: 8px; width: 100%; cursor: pointer;
}
.rm-opt-card.lib-prod:hover { background: transparent; border: 0; transform: none; box-shadow: none; }
.rm-opt-card .lib-prod-thumb { width: 34px; height: 34px; }
.rm-opt-card .lib-prod-name { font-size: 11px; line-height: 1.2; }
.rm-opt-card .lib-prod-sku { font-size: 11px; }  /* §4.7 R6 — 阶下限 11 */

/* Oscilloscope readout shared by Inspector and Workbench. */
.scope-readout {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.scope-source-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 10px;
  border: 1px solid var(--line-1);
  border-radius: 5px;
  background: var(--surface-2);
}
.scope-source-key {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}
.scope-source-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-1);
}
.scope-screen-wrap {
  overflow: hidden;
  border-radius: 10px;
  background: #07090d;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    inset 0 -18px 42px rgba(0, 0, 0, 0.45),
    0 8px 24px rgba(0, 0, 0, 0.18);
}
.scope-screen {
  display: block;
  width: 100%;
  max-width: 430px;
  height: auto;
}
.wb-card.is-fullscreen .scope-screen {
  max-width: none;
}
.scope-bezel {
  fill: #161a21;
  stroke: rgba(255, 255, 255, 0.13);
  stroke-width: 1;
}
.scope-crt {
  fill: #020703;
  stroke: rgba(104, 255, 154, 0.23);
  stroke-width: 1;
}
.scope-hud-bg {
  fill: rgba(15, 22, 18, 0.88);
}
.scope-grid-line {
  stroke: rgba(91, 255, 148, 0.15);
  stroke-width: 0.8;
}
.scope-grid-line.is-major {
  stroke: rgba(91, 255, 148, 0.32);
  stroke-width: 1;
}
.scope-trigger-line {
  stroke: rgba(255, 216, 89, 0.4);
  stroke-width: 0.9;
  stroke-dasharray: 3 5;
}
.scope-trigger {
  fill: #ffd859;
  opacity: 0.9;
}
.scope-trace,
.scope-trace-glow {
  stroke: #69ff9a;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.scope-trace {
  stroke-width: 1.8;
  filter: drop-shadow(0 0 3px rgba(105, 255, 154, 0.85));
}
.scope-trace-glow {
  stroke-width: 6;
  opacity: 0.16;
  filter: blur(1px);
}
.scope-hud-text,
.scope-screen-foot {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.04em;
  fill: rgba(224, 255, 232, 0.72);
}
.scope-hud-text.is-live {
  fill: #69ff9a;
}
.scope-hud-right {
  text-anchor: end;
}
.scope-foot-center {
  text-anchor: middle;
}
.scope-time-control {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 7px 10px;
  align-items: center;
}
.scope-time-label,
.scope-time-value {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
}
.scope-time-label {
  color: var(--ink-3);
}
.scope-time-value {
  color: var(--ink-1);
}
.scope-time-control input[type="range"] {
  grid-column: 1 / -1;
  width: 100%;
  height: 2px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  outline: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background: linear-gradient(90deg, rgba(105, 255, 154, 0.9), var(--paper-deep));
}
.scope-time-control input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--ctl-line);
  background: var(--surface);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.28);
}
.scope-time-control input[type="range"]::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--ctl-line);
  background: var(--surface);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.28);
}
.scope-data-grid {
  display: grid;
  gap: 6px;
}
.scope-data-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 10px;
  border: 1px solid var(--line-1);
  border-radius: 5px;
  background: var(--surface-2);
}
.scope-data-row span,
.scope-data-row strong {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
}
.scope-data-row span {
  color: var(--ink-3);
}
.scope-data-row strong {
  color: var(--ink-1);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
