/* ════════════════════════════════════════════════════════════════════
   Library push-stack navigator
   ────────────────────────────────────────────────────────────────────
   Single-column stack (groups → leaves → products) with iOS-style
   push/pop. One pane visible; new pane slides in from right, old pane
   shifts left + dims. Last depth (products) is a vertical list.
   ════════════════════════════════════════════════════════════════════ */

/* Accordion scroll container (2026-06-15 redesign)：直接承载分类行 + 区块标题 +
   产品卡（无 pane、无推栈滑动）。玻璃从列表整面透出。 */
.lib-stack {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  background: transparent;
  padding: 2px 0 8px;
  transition: opacity 0.12s var(--ease-out), transform 0.12s var(--ease-out);
}

/* Drill transition (2026-06-15 v2，user 要求「展开/消失动画棒一些」)：
   .lib-switching = 旧内容整体淡出 + 轻微上移（消失）；切换后 .lib-entering 给每行
   交错淡入下滑（展开）。reduced-motion 时 JS 直接重渲染、不加类。 */
.lib-stack.lib-switching {
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
}
@keyframes libRowIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.lib-stack.lib-entering > * {
  animation: libRowIn 0.26s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 22ms);
}
@media (prefers-reduced-motion: reduce) {
  .lib-stack, .lib-stack.lib-entering > * { transition: none; animation: none; }
}

/* ──────────────────────────────────────────────────────────────────
   Library pane · dense divider-free list (2026-06-15 redesign)
   User 定：讨厌分割线 + 减法的目的是「增加有价值的信息密度、压缩空白」。
   - 无分割线：行/头部/区块/卡片一律去 1px border，分组靠紧凑节奏 + hover-fill
   - 堆叠 UI：返回 + 面包屑上移到单条 dock 工具条（.lib-header），pane 只剩纯列表
   - 信息密度：行高 36→32、padding 收紧、卡片去 box 边、缩略图 56→44、间距压缩
   - Hover：full-row --overlay-1 fill + 2px --ink-1 左导轨（替代线做行分隔）
   - 全单色（DESIGN.md §3.5），无 cobalt
   .lib-pane-header / .lib-pane-back removed —— 头部归并进 .lib-header 工具条。
   ────────────────────────────────────────────────────────────────── */

/* ── Breadcrumb (lives in the dock toolbar — .lib-header — since 2026-06-15) ── */

.lib-crumb {
  /* Geist UI font, title-case, normal tracking (2026-06-15 redesign — user 反馈
     原 mono 大写「字体难看 + 塞不下信息」)。正常大小写 + 紧凑字距 = 更好看且
     同宽能显更多段。 */
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 1px;
  min-width: 0;
  font-family: var(--font-ui);
  font-size: 12px;
  letter-spacing: 0;
  overflow: hidden;
}
/* .lib-crumb-icon removed (2026-06-15)：empty-tax 头部已去，无图标段。 */
.lib-crumb-seg {
  flex: 0 1 auto;
  padding: 2px 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lib-crumb-link {
  background: none;
  border: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--ink-3);
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
  border-radius: 2px;
}
.lib-crumb-link:hover {
  color: var(--ink-1);          /* de-blue (DESIGN.md §3.5)：链接段 hover 退到墨黑 */
  background: var(--overlay-1);
}
.lib-crumb-current {
  /* 标题删除后 breadcrumb 是列表区顶部唯一文字锚点；当前段加重到 --ink-1
     （DESIGN.md §8.5，原 §8.6 的 --ink-2 是为了不盖过 dock 标题，标题已不存在）。 */
  color: var(--ink-1);
  font-weight: 600;
}
/* 分隔符：chevron icon → "/" 文字（DESIGN.md §8.5 "Optics / Mirrors" 写法，
   兼做减法去图标）。淡灰、左右留气。 */
.lib-crumb-sep {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding: 0 1px;
  color: var(--ink-4);
  font-weight: 400;
}

/* .lib-pane-count removed (2026-06-15 subtraction)：header 不再显数量徽章。 */

/* ── Pane body (scrollable list) ──────────────────────────────────── */

.lib-pane-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 2px 0 6px;
  min-height: 0;
}

/* ── Row button: divider-free dense list (2026-06-15 redesign) ─────── */
/* 行间不再用 1px 分割线，靠 hover full-row fill + 紧凑节奏区分（VS Code / Linear
   文件树语汇）。当前/hover 行用 2px --ink-1 左导轨。行高 36→32、padding 收紧。 */

.lib-row {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 4px;
  /* left pad grows with accordion depth (--depth) so nested categories indent */
  padding: 5px 10px 5px calc(10px + var(--depth, 0) * 13px);
  margin: 0;
  background: transparent;
  border: none;
  border-left: 2px solid transparent;
  border-radius: 0;
  cursor: pointer;
  transition: background 0.12s, border-left-color 0.12s, color 0.12s;
  position: relative;
  text-align: left;
  font-family: inherit;
  min-height: 32px;   /* U1 触控底线 */
}

.lib-row:hover {
  background: var(--overlay-1);
  border-left-color: var(--ink-1);   /* 左导轨替代分割线做行界定（monochrome §3.5） */
}

.lib-row:focus-visible {
  outline: 1px dashed var(--ink-2);
  outline-offset: -3px;
}

/* .lib-row-icon removed (2026-06-15 subtraction)：行内分类图标已删，行只剩文字 + 下钻箭头。 */

.lib-row-text {
  flex: 1 1 auto;
  min-width: 0;
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
}
.lib-row-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* .lib-row-subtitle / .lib-row-count / .lib-row-sim removed (2026-06-15)。 */

/* Drill chevron (2026-06-15 v3)：行尾 ›「进入该层」affordance（替换式导航，不旋转）。
   hover 时轻微右移 + 提色，暗示「点进去」。 */
.lib-row-chevron {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  color: var(--ink-3);   /* v2 affordance ↑ ink-4→ink-3：drill 线索静止可辨（§8.5）*/
  transition: color 0.12s, transform 0.12s var(--ease-out);
}
.lib-row:hover .lib-row-chevron { color: var(--ink-1); transform: translateX(2px); }

/* ── Group block (v2 affordance — DESIGN.md §8.5 / P4 「Fill first, line second」) ──
   每个产品分区（section head + 其卡片）落在一块 --surface-3 底色块里 —— 用底色 + 留白
   把分组做「看得见」，替代 2026-06「减法运动」后靠 hover 才显形的隐形分隔。行内仍无线
   （§8.5「行保持无线」），hover 左导轨沿用。库面板玻璃透底，surface-3 半沉底块与之分层。 */
.lib-group {
  background: var(--surface-3);
  border-radius: var(--float-radius);
  padding: 2px 0 6px;
  margin: 6px 8px 8px;
}
.lib-group:first-child { margin-top: 4px; }

/* ── Section sub-heading inside leaf pane ─────────────────────────── */
/* Bare eyebrow label, no flanking rule lines (2026-06-15 redesign — user 讨厌
   分割线)。靠紧凑节奏 + 字距分组。 */

.lib-section-head {
  display: flex;
  align-items: center;
  padding: 9px 10px 3px calc(12px + var(--depth, 0) * 13px);   /* indent with accordion depth */
  margin: 0;
}
/* .lib-section-line removed (no divider) */
.lib-section-head .lib-section-label {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.lib-section-head.has-supported .lib-section-label { color: var(--good); }
.lib-section-head.has-preview .lib-section-label { color: var(--warn); }

/* ── Product card — flat dense row (2026-06-15 redesign) ───────────── */
/* 去 box 边框/玻璃卡底（无分割线/无框），收成贴着列表的紧凑行：缩略图 56→44、
   padding 收紧、行距压缩。draggable 感靠 grab 光标 + hover fill，不再靠卡片立体。 */

.lib-prod {
  display: grid;
  grid-template-columns: 44px 1fr auto;
  column-gap: 10px;
  row-gap: 2px;
  align-items: center;
  padding: 5px 10px 5px calc(12px + var(--depth, 0) * 13px);   /* indent with accordion depth */
  margin-bottom: 1px;
  background: transparent;
  border: 1px solid transparent;
  border-left: 2px solid transparent;
  border-radius: 5px;
  cursor: pointer;
  transition: background 0.12s, border-left-color 0.12s;
  position: relative;
}
.lib-prod-thumb {
  grid-row: 1 / span 2;
  grid-column: 1;
  width: 44px;
  height: 44px;
  background: var(--paper-soft);
  border-radius: 4px;
  border: 1px solid var(--line-soft);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.lib-prod-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.lib-prod-thumb.img-failed::after {
  content: '?';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  font-size: 20px;
  font-weight: 600;
}

.lib-prod-name {
  grid-row: 1;
  grid-column: 2;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lib-prod-sku {
  grid-row: 2;
  grid-column: 2;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink-3);
  letter-spacing: 0.02em;
}
.lib-prod-side {
  grid-row: 1 / span 2;
  grid-column: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
}
.lib-prod-spec {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-1);   /* de-blue (DESIGN.md §3.5)：参数值走墨黑 mono，不用蓝 */
  letter-spacing: 0.02em;
}
.lib-prod-spec .unit {
  color: var(--ink-3);
  font-weight: 400;
  margin-left: 1px;
}
.lib-prod-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 1px 7px;
  border-radius: 999px;
  line-height: 1.4;
}
.lib-prod-badge.ok {
  background: var(--sig-ok-bg);
  color: var(--ink-1);
  border: 1px solid var(--sig-ok);
}
.lib-prod-badge.preview {
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn);
}
/* A-2 fs 色散控制章（fs 源在台时叠加在 Draggable 章下方，软推荐 — 不灰显不禁用） */
.lib-prod-badge.fs-caution {
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn);
  cursor: help;
}
.lib-prod-badge.fs-ready {
  background: var(--sig-ok-bg);
  color: var(--ink-1);
  border: 1px solid var(--sig-ok);
  cursor: help;
}
/* D-3 波长失配章（台面光束与该 SKU 工作波段带外 — §13 warning，仍可拖，
   "Show draggable only" 过滤掉，hover 出拒绝原因）。复用 fs-caution 琥珀语汇。 */
.lib-prod-badge.wl-caution {
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--warn);
  cursor: help;
}
/* λ 失配卡片整体压暗（保留 grab 光标）。flat row → hover 用 fill + amber 左导轨。 */
.lib-prod.supported.wl-incompatible { opacity: 0.62; }
.lib-prod.supported.wl-incompatible:hover {
  opacity: 1;
  background: var(--sig-warn-bg);
  border-left-color: var(--warn);
}

/* SUPPORTED draggable products: flat hover = fill + ink left rail, no box lift
   (2026-06-15 redesign — divider/box-free dense list). */
.lib-prod.supported:hover {
  background: var(--overlay-1);
  border-left-color: var(--ink-1);
}
.lib-prod.supported {
  cursor: grab;
}
.lib-prod.supported:active { cursor: grabbing; }
.lib-prod.supported.dragging { opacity: 0.5; }

/* Preview-only products: warm fill + amber left rail on hover */
.lib-prod.preview-only:hover {
  background: var(--sig-warn-bg);
  border-left-color: var(--warn);
}

/* Selected breadboard — ink left rail + faint fill (flat, no box/shadow) */
.lib-prod.selected-bench {
  background: var(--overlay-1);
  border-left-color: var(--ink-1);
}
.lib-prod.selected-bench .lib-prod-badge {
  background: var(--ink-1);
  color: var(--surface);   /* theme-aware reverse ink on solid ink fill (DESIGN.md §3.3) */
  border-color: var(--ink-1);
}

/* ── Summary card ("+N more products") ────────────────────────────── */

/* Flat row, no dashed box (2026-06-15 — user 讨厌分割线/框)；hover fill + 左导轨。 */
.lib-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px 6px calc(12px + var(--depth, 0) * 13px);   /* indent with accordion depth */
  background: transparent;
  border: none;
  border-left: 2px solid transparent;
  border-radius: 0;
  cursor: pointer;
  transition: background 0.12s, border-left-color 0.12s;
  margin-top: 2px;
}
.lib-summary:hover {
  background: var(--overlay-1);
  border-left-color: var(--ink-1);
}
.lib-summary-icon {
  flex: 0 0 auto;
  width: 44px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-2);
  background: transparent;
}
.lib-summary-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.lib-summary-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
}
.lib-summary-sub {
  font-size: 10.5px;
  color: var(--ink-3);
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}
.lib-summary-cta {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-1);   /* de-blue (DESIGN.md §3.5) */
}

/* ── Empty taxonomy state (no DB, no cache) ───────────────────────── */

.lib-empty-tax {
  padding: 40px 20px;
  text-align: left;
  color: var(--ink-2);
}
.lib-empty-tax-headline {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
  letter-spacing: 0.02em;
}
.lib-empty-tax-body {
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-2);
  margin-bottom: 14px;
}
.lib-empty-tax-actions {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.lib-empty-tax-actions li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 11.5px;
  color: var(--ink);
}
.lib-empty-tax-actions code {
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--surface);
  padding: 2px 6px;
  border-radius: 2px;
  border: 1px solid var(--line);
  color: var(--ink-1);
}
.lib-empty-tax-actions .muted {
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--ink-3);
  letter-spacing: 0.04em;
}
.lib-empty-tax-hint {
  font-size: 11px;
  color: var(--ink-3);
  line-height: 1.5;
}
.lib-empty-tax-hint strong {
  color: var(--ink-1);
  font-weight: 600;
}

/* ── Loading state (end users — replaces the dev diagnostic above) ──
   Determinate bar tracks real products_3d download bytes (dbState.progress);
   probe/connect/unknown-size phases fall back to an indeterminate sweep. */
.lib-loading {
  padding: 40px 20px;
  color: var(--ink-2);
}
.lib-loading-headline {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}
.lib-loading-sub {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
  margin-bottom: 14px;
}
.lib-loading-track {
  position: relative;
  height: 6px;
  border-radius: 999px;
  background: var(--paper-soft);
  border: 1px solid var(--line);
  overflow: hidden;
}
.lib-loading-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--ink-1);
  transition: width 0.3s ease;
}
.lib-loading-pct {
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  min-height: 13px;       /* reserve the line so the bar doesn't jump when % shows */
}
/* Indeterminate: a fixed-width segment sweeps left→right (size unknown). */
.lib-loading.is-indeterminate .lib-loading-fill {
  width: 40%;
  transition: none;
  animation: lib-loading-sweep 1.15s ease-in-out infinite;
}
@keyframes lib-loading-sweep {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}
@media (prefers-reduced-motion: reduce) {
  .lib-loading.is-indeterminate .lib-loading-fill {
    animation: none;
    width: 100%;
    opacity: 0.4;
  }
}

/* ── Breadboard select (replaces dropdown when in mechanics leaf) ── */

.lib-bb-select-wrap {
  margin: 4px 4px 12px;
  padding: 10px 12px;
  background: var(--surface-2);
  border: 1px solid var(--ink-1);
  border-radius: 4px;
}
.lib-bb-select-wrap label {
  display: block;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-1);
  margin-bottom: 6px;
}

