/* ══════════════════════════════════════════════════════════════════
   kb.css —— 知识库站（顶栏第 3 站）：**中栏知识列表 + 右栏详情**
   来源（设计口径）：parts/02-ui-聚合中台与CRM界面.md §4「知识库管理页」
     §4.1 按 scope 三级分区 ｜ §4.2 来源可追溯（溯源线）｜ §4.4 冲突与过期
   来源（结构范式）：app/css/customers.css（内容层吃满 .app）+ shell.css 的 .crmmode 显隐段
   纪律：
     1. 本文件不得出现字面色值，一律 var() 令牌（四主题共用同一套结构，差异只在令牌值）。
     2. 类名一律 `kb-` 前缀 + 内容层 `#kbbody`，**与既有 .crm/.ph/.row/.tag 零复用**
        （引前已核：全仓 `.kb-|.kbmode|#kbbody` = 0 命中）。
     3. 密度不降：本站是操作台，不是展示页 ⇒ 行高/间距按中台既有节奏取，不做大留白。
   ══════════════════════════════════════════════════════════════════ */
.kb{display:none;flex:1 1 auto;min-width:0;min-height:0;flex-direction:column;
  background:var(--e2)}
.app.kbmode > .list,
.app.kbmode > .chat,
.app.kbmode > .side,
.app.kbmode > .spl{display:none}
.app.kbmode > #kbbody{display:flex}

/* ── 站头（44px）：站名 + 当前库 chip + 读数。**视图页签已迁入左导航轨**，见下 ── */
.kb-tabs{display:flex;align-items:center;gap:8px;flex:none;height:44px;padding:0 14px;
  border-bottom:1px solid var(--line);background:var(--e1)}
.kb-ttl{font-size:var(--fs-small);color:var(--t1);font-weight:500;white-space:nowrap}
.kb-sep{width:1px;height:16px;background:var(--line2);margin:0 2px}
.kb-meta{margin-left:auto;display:flex;align-items:center;gap:10px;
  font-size:var(--fs-micro);color:var(--t3);font-family:var(--font-num);white-space:nowrap}
.kb-meta b{color:var(--t2);font-weight:500}
/* 后端不可达时挂这里（file:// / 8410 未启）——降级必须与正常同形可辨（RULES 78）。
   ⚠ 自纠留痕（2026-09-18）：初稿此处写「`--warn` 只在主题 A 定义 ⇒ B/C/D 失效」并改成
   `--amber` —— **那个理由是错的**。`--warn:var(--amber)` 是**别名**（tokens.css:52），
   而主题是**在同一个 <html> 上增删类**（theme.js:31）⇒ `html{}` 与 `html.themeB` 同时匹配
   同一元素，`html{}` 的声明**继续生效**，值还会随 `--amber` 变。
   ⇒ 「只在一套主题块里定义」**不构成**「其它主题下失效」；故改回语义更准的 `--warn`。
   （真失效条件 = 被 themeB/C/D **覆盖过、却漏了某套** —— 那是另一条判据，见交付回报。） */
.kb-meta .down{color:var(--warn)}

/* ── 左导航轨（240px）—— A §3.2「左导航 240px ＋ 中工作区弹性 ＋ 右详情 320px」──
   三段（知识库 / 待办 / 工作台），**顺序与分段逐字对齐 A §3.1 与 mockup 三屏左栏**。
   ⚠ 三组交互属性互斥（工作台只挂 data-kbview / 三库只挂 data-kblib / 待办只挂 data-kbtodo），
     理由见 shell.js 委派段注释 —— 同元素挂两组时"哪个生效"在 DOM 上看不出来。 */
.kb-rail{flex:none;width:240px;min-height:0;overflow:auto;padding:8px 0 14px;
  border-right:1px solid var(--line);background:var(--e1)}
.kb-rsec{font-size:var(--fs-micro);color:var(--t3);padding:9px 14px 4px;white-space:nowrap}
.kb-ritem{display:flex;align-items:flex-start;gap:8px;padding:6px 14px;cursor:pointer;
  user-select:none;transition:background var(--dur-1)}
.kb-ritem:hover{background:var(--veil)}
.kb-ritem.on{background:var(--accent-wash)}
.kb-ritem .dot{flex:none;width:6px;height:6px;margin-top:6px;border-radius:var(--r-full);
  background:var(--line2)}
.kb-ritem.on .dot{background:var(--accent)}
.kb-ritem .tx{flex:1;min-width:0}
.kb-ritem .nm{display:block;font-size:var(--fs-small);color:var(--t2);line-height:1.45}
.kb-ritem.on .nm{color:var(--accent-text)}
.kb-ritem .sub{display:block;font-size:var(--fs-micro);color:var(--t3);line-height:1.45;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kb-ritem .cnt{flex:none;font-family:var(--font-num);font-size:var(--fs-micro);color:var(--t3);
  line-height:1.6}
.kb-ritem .cnt.hot{color:var(--amber)}
/* 「算不出来」的待办项：**不许渲染成 0**，用 `—` + 斜体位（与真 0 视觉可辨）。 */
.kb-ritem .cnt.na{color:var(--slot-empty-fg);font-style:normal}
.kb-ritem.na-cur{cursor:default}
.kb-ritem.na-cur:hover{background:transparent}
.kb-rfoot{margin:10px 14px 0;padding-top:9px;border-top:1px solid var(--line);
  font-size:var(--fs-micro);color:var(--t3);line-height:1.65}

/* ── 主体：中栏 + 右栏 ────────────────────────────────────────── */
.kb-body{flex:1 1 auto;min-height:0;display:flex}
.kb-mid{flex:1 1 auto;min-width:0;min-height:0;overflow:auto;padding:12px 16px 20px}
.kb-right{flex:none;width:336px;min-height:0;overflow:auto;padding:12px 16px 20px;
  border-left:1px solid var(--line);background:var(--e1)}
.kb-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:8px;height:100%;color:var(--t3);font-size:var(--fs-small);text-align:center}

/* ── 骨架屏（P0·E：取数未到位的"加载中"占位，与 `.kb-empty` 的"结论态"严格区分）──
   ⚠ 两者同形 = 把"加载中"冒充成"知识库是空的"（RULES-78 同源的降级可辨纪律）。
   全部吃令牌（`.kb-skel/.sk-bar` 不写死字面色值，沿用 `--line2` 底 + `--veil` 流光）。 */
.kb-skel{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));
  gap:10px;align-content:start;padding-top:2px}
.kb-skel-card{padding:12px 14px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--e1);display:flex;flex-direction:column;gap:8px}
.kb-skel-card .sk-bar{position:relative;overflow:hidden;height:10px;border-radius:var(--r-sm);
  background:var(--line2)}
.kb-skel-card .sk-bar::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,var(--veil),transparent);
  animation:kb-shimmer 1.15s ease-in-out infinite}
.kb-skel-card .w100{width:100%}.kb-skel-card .w90{width:90%}
.kb-skel-card .w70{width:70%}.kb-skel-card .w60{width:60%}.kb-skel-card .w50{width:50%}
/* 左栏「库」段骨架（railLibs 在 S._loading 时给，而非"库定义未取到"结论态） */
.kb-ritem.skel-row .sk-bar{display:block;position:relative;overflow:hidden;height:9px;
  margin-top:7px;border-radius:var(--r-sm);background:var(--line2)}
.kb-ritem.skel-row .sk-bar:first-child{margin-top:2px}
.kb-ritem.skel-row .sk-bar::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,var(--veil),transparent);
  animation:kb-shimmer 1.15s ease-in-out infinite}
.kb-ritem.skel-row .w55{width:55%}.kb-ritem.skel-row .w35{width:35%}
@keyframes kb-shimmer{to{transform:translateX(100%)}}

/* ── 检索条（视图①）─────────────────────────────────────────── */
.kb-sbox{display:flex;align-items:center;gap:9px;padding:9px 12px;margin-bottom:10px;
  border:1px solid var(--line2);border-radius:var(--r-md);background:var(--e1);color:var(--t3)}
.kb-sbox:focus-within{border-color:var(--focus)}
.kb-sbox input{flex:1;min-width:0;background:none;border:0;outline:none;
  color:var(--t1);font-size:var(--fs-body);font-family:var(--font-ui)}
.kb-sbox input::placeholder{color:var(--t3)}
.kb-sbox .go{flex:none;font-size:var(--fs-caption);padding:4px 10px;border-radius:var(--r-sm);
  background:var(--accent-wash);color:var(--accent-text);cursor:pointer;white-space:nowrap}
.kb-hint{font-size:var(--fs-micro);color:var(--t3);margin:0 0 10px 2px}

/* 检索命中的「知识门」条：过门/未过门**按数值分色**，不写无条件断言 */
.kb-gate{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:9px 12px;
  margin-bottom:10px;border:1px solid var(--line2);border-radius:var(--r-md);background:var(--e1);
  font-size:var(--fs-caption);color:var(--t2)}
.kb-gate b{font-family:var(--font-num);color:var(--t1)}
.kb-gate.pass{border-color:var(--accent-line)}
.kb-gate.stop{border-color:var(--amber-line)}
.kb-gate.blk{border-color:var(--danger-line);background:var(--danger-bg)}

/* ── 条目卡 / 命中卡 / 来源行 / 红线行（共用一张「行卡」皮肤）─────── */
.kb-card{background:var(--e1);border:1px solid var(--line);border-radius:var(--r-md);
  padding:11px 13px;margin-bottom:8px;cursor:pointer;transition:border-color var(--dur-1)}
.kb-card:hover{border-color:var(--line2);background:var(--face-hover)}
.kb-card.on{border-color:var(--accent-line);background:var(--accent-wash)}
.kb-card .h{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:6px}
.kb-card .tit{font-size:var(--fs-body);color:var(--t1);font-weight:500}
.kb-card .cl{font-size:var(--fs-small);color:var(--t2);line-height:1.62}
.kb-card .ft{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:7px;
  font-size:var(--fs-micro);color:var(--t3);font-family:var(--font-num)}
.kb-card .ft .sp{margin-left:auto}
.kb-rank{flex:none;font-family:var(--font-num);font-size:var(--fs-micro);color:var(--t3);
  width:20px;text-align:right}
.kb-score{font-family:var(--font-num);color:var(--data)}

/* 徽标（scope / verdict / 状态 / 动作）：一枚 .kb-tag 打底，语义只换令牌 */
.kb-tag{display:inline-flex;align-items:center;gap:4px;flex:none;
  font-size:var(--fs-micro);line-height:1.5;padding:1px 7px;
  border-radius:var(--r-xs);border:1px solid var(--line2);background:var(--e3);color:var(--t2);
  white-space:nowrap}
.kb-tag.can{background:var(--accent-wash);color:var(--accent-text);border-color:var(--accent-line)}
/* ★ 不用 `--danger`：本项目**红 = 健康红线专用**，而 `cannot` 是"否定性结论"
   （如「局部减脂不存在」），不是风险 ⇒ 用陶土 `--clay`／`--on-clay`（令牌对，四主题齐备）。
   ⚠ 引前已机械核过：`--cyan*` 在本仓 tokens.css **无定义**（初稿误用，判据抓出）。 */
.kb-tag.cannot{background:var(--clay);color:var(--on-clay);border-color:transparent}
.kb-tag.depends{background:var(--amber-bg);color:var(--amber);border-color:var(--amber-line)}
.kb-tag.block{background:var(--danger-bg);color:var(--danger-text);border-color:var(--danger-line)}
.kb-tag.warn{background:var(--amber-bg);color:var(--amber);border-color:var(--amber-line)}
.kb-tag.off{background:var(--slot-empty-bg);color:var(--slot-empty-fg)}
.kb-tag.ghost{background:transparent;color:var(--t3)}

/* ── 视图⑤：指标瓦片 ─────────────────────────────────────────── */
.kb-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:8px;
  margin-bottom:14px}
.kb-tile{padding:11px 13px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1)}
.kb-tile .k{font-size:var(--fs-micro);color:var(--t3);margin-bottom:5px}
.kb-tile .v{font-size:var(--fs-h3);font-family:var(--font-num);color:var(--t1);line-height:1.25}
.kb-tile .v em{font-size:var(--fs-caption);font-style:normal;color:var(--t3);margin-left:3px}
.kb-tile.stale{border-style:dashed}
.kb-tile.stale .v{color:var(--t3)}
.kb-h{display:flex;align-items:center;gap:8px;margin:16px 0 8px;
  font-size:var(--fs-caption);color:var(--t2);font-weight:500}
.kb-h .rule{flex:1;height:1px;background:var(--line)}
.kb-note{font-size:var(--fs-micro);color:var(--t3);line-height:1.7;margin-top:6px}

/* 分段表（通过率按 reranker_ver 分段 —— 换版本前后不可直接比）*/
.kb-seg{display:flex;align-items:center;gap:10px;padding:8px 12px;margin-bottom:6px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--e1);
  font-size:var(--fs-caption);color:var(--t2);font-family:var(--font-num)}
.kb-seg .nm{flex:1;min-width:0;color:var(--t1);font-family:var(--font-ui);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.kb-seg .bar{flex:none;width:74px;height:5px;border-radius:var(--r-full);
  background:var(--ai-track);overflow:hidden}
.kb-seg .bar i{display:block;height:100%;background:var(--accent);border-radius:var(--r-full)}

/* ── 右栏：详情 + 溯源链（02-ui §4.2 的「溯源线」）────────────── */
.kb-dt-h{font-size:var(--fs-title);color:var(--t1);line-height:1.5;margin-bottom:7px}
.kb-dt-sub{font-size:var(--fs-micro);color:var(--t3);font-family:var(--font-num);
  display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.kb-claim{padding:10px 12px;border-radius:var(--r-md);background:var(--e2);
  border-left:2px solid var(--accent);font-size:var(--fs-small);color:var(--t1);line-height:1.72}
.kb-chain{margin-top:14px;padding-left:13px;border-left:1px solid var(--line2)}
.kb-ev{position:relative;padding:0 0 13px 0}
.kb-ev:last-child{padding-bottom:0}
.kb-ev::before{content:'';position:absolute;left:-17px;top:5px;width:7px;height:7px;
  border-radius:var(--r-full);background:var(--e2);border:1px solid var(--accent-line)}
.kb-ev .txt{font-size:var(--fs-small);color:var(--t2);line-height:1.7}
.kb-ev .src{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-top:5px;
  font-size:var(--fs-micro);color:var(--t3);font-family:var(--font-num)}
.kb-ev .src .t{font-family:var(--font-num);color:var(--data);padding:0 5px;
  border-radius:var(--r-xs);background:var(--e2)}
.kb-ev .src .ref{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── 窄窗让位（中栏信息密度不许被右栏挤掉 ⇒ 右栏先缩、再落底）─────
   ★ 三级下降**逐级可见**：240→200 是缩窄，≤980 是**换成横向条**（不是 display:none）。
     本仓头号忌讳是"静默剪裁"—— 窄窗把整段导航藏起来，用户会以为「知识库没有三库」，
     然后自己发挥。所以这里只改排布方向，不减项。 */
@media (max-width:1180px){ .kb-right{width:286px} .kb-rail{width:200px} }
@media (max-width:980px){
  .kb-body{flex-direction:column}
  /* 导航轨 → 横向 wrap 条（仍在文档流里、仍占位、仍可点）
     ★★ 2026-09-23 去掉 `max-height:140px` —— 修**报障**（X 线普查实测）：
       加上 140px 上限 + `overflow-y:auto` 之后，wrap 后内容实测高 **349px**，
       被压成一条**横向滚动条** ⇒ 6 个视图 tab（`.kb-ritem`）全部沉到滚动区底部。
       实测（逐个 tab 中心 `elementFromPoint`）：tab 的 `top` = **374 / 404**，
       而 rail 可视区只有 **164..303** ⇒ **0 / 6 可点**；
       内存内变异 `max-height:none` ⇒ rail **509×350**、**6 / 6 可点**。
       用户看到的是「库1 / 库2 / 库3」那几条（`.kb-rsec` / `.kb-rfoot`），
       既看不到 tab、也未必知道这条能滚 ⇒ **窄窗下知识库进不了任何子视图**。
       ⚠ 取舍：去掉上限后 rail 约 **350px**、把中栏往下推 —— 但那 6 个 tab 是
         本站**唯一入口**，可见性优先于省这点纵向空间。
       ⚠ `overflow-y:auto` **保留**（内容不再溢出 ⇒ 现无实际作用；留给将来更长的库列表）。
       ⚠ 本仓另有 shell 层断点 `narrowMax = 949`，与这里的 `980` **不同**；
         修掉本行之后，`W ∈ (949, 980]` 那段落缝**不再产生缺陷**（两个宽度下 tab 都可点），
         故本批**不动断点**（动它要重新验三栏在 960 处装不装得下）。 */
  .kb-rail{width:auto;flex:none;display:flex;flex-wrap:wrap;align-items:center;
    gap:2px 4px;padding:7px 10px;border-right:0;border-bottom:1px solid var(--line);
    overflow-y:auto}
  .kb-rsec{width:100%;padding:3px 4px 1px}
  .kb-ritem{padding:5px 9px;border-radius:var(--r-sm)}
  .kb-ritem .dot{margin-top:5px}
  .kb-ritem .sub{display:inline;margin-left:5px}
  .kb-rfoot{width:100%;margin:6px 4px 0}
  .kb-right{width:auto;flex:none;max-height:46%;border-left:0;
    border-top:1px solid var(--line)}
}

/* ══ 三库切换的白名单说明条（A §3.1：派生视图必须说清"为什么少"）══════
   ⚠ 灰显占位（.kb-hidden）与"空态"是**两件事**，样式必须可辨：
     空态 = 真的没有；灰显 = 有，但当前库不可见。混成一种 = 界面在骗人。 */
.kb-derive{display:flex;align-items:flex-start;gap:9px;flex-wrap:wrap;
  padding:9px 12px;margin-bottom:10px;border:1px solid var(--accent-line);
  border-radius:var(--r-md);background:var(--accent-wash);
  font-size:var(--fs-caption);color:var(--t2);line-height:1.6}
.kb-derive b{color:var(--t1)}
.kb-derive .wl{font-family:var(--font-num);color:var(--accent-text)}
.kb-hidden{display:flex;align-items:center;gap:8px;padding:7px 11px;margin:6px 0;
  border:1px dashed var(--line2);border-radius:var(--r-sm);
  font-size:var(--fs-micro);color:var(--t3);font-style:normal}
.kb-hidden .bar{flex:none;width:3px;height:14px;border-radius:var(--r-full);
  background:var(--line2)}

/* ══ 教练层**人设子筛选**（2026-10-14）═════════════════════════════════════
   库3 教练按 `scope='coach_private'` 取，而**同一层里可并存多个人设**
   （904 = 刘教练那台号 / 905 = 宋教练那台号）⇒ 不出这条行，两个教练的条目在同一列
   混排，"这条是谁的知识 / 该维护谁"在界面上分不出来。
   ★ 尺度：本行是**一枚筛选行**（本仓红线「筛选只放列表上方一行」）——
     它不新增面板、不占第二行、**≤1 个人设时不渲染**（单教练的库多一行就是噪声）。
   ⚠ 与 `.kb-derive`（说明条）的关系：说明条答"本库层共几条"（滤前），
     本行答"其中这个人设几条"（滤后）。两者的数**故意不同**，故样式上也要分开：
     说明条是实底强调块、本行是**轻量 chip 行**（无底色、无边框容器），一眼能分辨。 */
/* ══ 条目视图的两枚筛选行：「人设」`.kb-pdef` 与「节点」`.kb-stage` ═══════════
   ⚠ 两行是**同一族控件** ⇒ **共用一份规则**（选择器并列写），不各写一套。
     各写一套 = 两张表：改一处忘一处，两行迟早长得不一样（间距 / 圆角 / 选中色各自漂移），
     而**没有任何读数会红** —— 与"前后端各存一份中英对照"是同一族的错误。
   ⚠ 但**类名各自独立**、**不叠用**（不写 `class="kb-pdef kb-stage"`）：
     叠用之后 `querySelector('.kb-pdef')` 就变成"两行里随便哪一行"，
     判据与调试都会**读错对象**（且不报错）。各持一个类名 ⇒ 谁是哪个一眼可辨。
     （下面的后代选择器不受影响，它们锚在各自的类名上。） */
.kb-pdef,.kb-stage{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  padding:0 2px 8px;margin-top:-4px;
  font-size:var(--fs-caption);color:var(--t3)}
.kb-pdef .lb,.kb-stage .lb{flex:none;color:var(--t3)}
.kb-pdef .pg,.kb-stage .pg{display:inline-flex;align-items:center;gap:5px;
  padding:3px 10px;border:1px solid var(--line);border-radius:var(--r-full);
  background:var(--e1);color:var(--t2);cursor:pointer;user-select:none}
.kb-pdef .pg .n,.kb-stage .pg .n{font-family:var(--font-num);color:var(--t3)}
.kb-pdef .pg:hover,.kb-stage .pg:hover{border-color:var(--accent-line)}
.kb-pdef .pg.on,.kb-stage .pg.on{background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent-text)}
.kb-pdef .pg.on .n,.kb-stage .pg.on .n{color:var(--accent-text)}
/* 节点行**接在**人设行下面：`kb-pdef` 自带 `padding-bottom:8px`，此处再收回 4px ⇒ 净 4px 间隙，
   让两行读起来是**一组**（都是"条目的取数视角"），而不是两块互不相干的控件。 */
.kb-stage{margin-top:-4px}

/* ══ 待办队列（三来源）═════════════════════════════════════════════ */
.kb-que{border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1);
  margin-bottom:12px;overflow:hidden}
.kb-que .qh{display:flex;align-items:center;gap:8px;padding:9px 13px;
  border-bottom:1px solid var(--line);background:var(--e2)}
.kb-que .qh .nm{font-size:var(--fs-body);color:var(--t1);font-weight:500}
.kb-que .qh .n{font-family:var(--font-num);font-size:var(--fs-small);color:var(--t2)}
.kb-que .qh .rule{margin-left:auto;font-size:var(--fs-micro);color:var(--t3)}
/* 被左栏「待办 N」锚中的那一段 —— 让"点了哪一项"在画面上有落点（否则滚过去了也看不出）*/
.kb-que.on{border-color:var(--accent-line)}
.kb-que .qb{padding:8px 13px 11px}
.kb-que .qrule{font-size:var(--fs-micro);color:var(--t3);line-height:1.7;
  font-family:var(--font-num);word-break:break-word}
/* ★ 「算不出来」与「算出来是 0」必须长得不一样（RULES 78 降级可辨）：
   `.kb-blocked` 用虚线 + 警示色 + 明写依赖的表名；空态用普通灰字。 */
.kb-blocked{margin-top:8px;padding:9px 11px;border:1px dashed var(--amber-line);
  border-radius:var(--r-sm);background:var(--amber-bg);
  font-size:var(--fs-micro);color:var(--t2);line-height:1.7}
.kb-blocked b{color:var(--amber)}
.kb-trow{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:7px 0;
  border-top:1px solid var(--line);font-size:var(--fs-caption);color:var(--t2)}
.kb-trow:first-child{border-top:0}
.kb-trow .id{font-family:var(--font-num);font-size:var(--fs-micro);color:var(--t3)}
/* ★★ 0.7.9 审核位（B 方案）：待审条目的「通过 / 不要」两个动作。
   口径与既有伪按钮（`.go` 那族）一致：cursor + hover 反馈；键盘可达由 `role="button"` 给
   （`shell.js` 的 `kbActivatable` 走角色白名单 ⇒ 这里**不写** role 相关的样式，也没有 role 可写）。
   ⚠ `flex:none` + `nowrap`：`.kb-trow` 是 `flex-wrap:wrap` 容器，窄屏下这两个按钮
     不许被压成竖排两行（同 `xiaoe.css` 里 `.go` 那条的理由）。
   ⚠ `margin-left:auto` 把它们推到**行尾**：「动作位」与左侧「内容位」在位置上分开，
     鼠标扫过去不会误点（整行是可读的，按钮才可点）。 */
.kb-act{display:inline-flex;gap:6px;flex:none;margin-left:auto}
.kb-act span{flex:none;white-space:nowrap;font-size:var(--fs-micro);padding:2px 9px;
  border-radius:var(--r-sm);border:1px solid var(--line2);color:var(--t2);cursor:pointer;
  transition:background var(--dur-1),color var(--dur-1)}
.kb-act .go{color:var(--accent-text);border-color:var(--accent-line)}
.kb-act .go:hover{background:var(--accent-wash)}
.kb-act .no:hover{background:var(--e2)}
.kb-act .busy{color:var(--t3);border-style:dashed;cursor:default}

/* ══ 新人培训（A §6）══════════════════════════════════════════════ */
.kb-tk{margin-bottom:16px}
.kb-lv{border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1);
  padding:10px 13px;margin-bottom:8px}
.kb-lv .lh{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:5px}
.kb-lv .no{flex:none;width:20px;height:20px;border-radius:var(--r-full);
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-wash);color:var(--accent-text);
  font-family:var(--font-num);font-size:var(--fs-micro)}
.kb-lv .nm{font-size:var(--fs-body);color:var(--t1);font-weight:500}
.kb-lv .rl{font-size:var(--fs-micro);color:var(--t3);line-height:1.7;font-family:var(--font-num)}
.kb-lv .bar{height:4px;border-radius:var(--r-full);background:var(--ai-track);
  overflow:hidden;margin:7px 0 6px}
.kb-lv .bar i{display:block;height:100%;background:var(--accent);border-radius:var(--r-full)}
.kb-qz{margin-top:8px;border-top:1px solid var(--line);padding-top:7px}
.kb-qz .qq{font-size:var(--fs-small);color:var(--t1);line-height:1.65;margin-bottom:4px}
.kb-qz .opts{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:3px}
.kb-qz .ans{font-size:var(--fs-micro);color:var(--data);font-family:var(--font-num)}

/* ══ 人设视图（identity/register/rhythm/relation/taboo 五层）══════════════
   ★ 2026-10-15 补：上一版 `personaDetailHtml` 用了 `.kb-pcard`/`.kb-fld`/`.subf`/
     `.kb-ops`/`.kb-btn` 五个类，但 kb.css **一个都没定义** ⇒ 字段/按钮裸奔、不对齐，
     界面看着"不整齐"。本块把它们补齐（沿用既有变量，不引入新 token）。 */
.kb-pcard{display:flex;flex-direction:column;gap:0;
  border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1);
  padding:6px 14px;margin-bottom:12px}
/* 字段行：label 定宽右对齐 + 值区占满 ⇒ 上下所有字段的 label/值**对齐**（治"不整齐"） */
.kb-fld{display:flex;align-items:flex-start;gap:12px;
  padding:9px 0;border-bottom:1px solid var(--line2)}
.kb-fld:last-child{border-bottom:0}
.kb-fld .lb{flex:none;width:112px;text-align:right;color:var(--t3);
  font-size:var(--fs-caption);line-height:1.7;padding-top:1px}
.kb-fld .vl{flex:1;min-width:0;color:var(--t1);font-size:var(--fs-small);line-height:1.7;
  overflow-wrap:anywhere}
.kb-fld.ro .vl{color:var(--t2)}
/* 编辑态输入 */
.kb-fld textarea,.kb-fld input{flex:1;min-width:0;width:100%;
  font:inherit;font-size:var(--fs-small);line-height:1.6;color:var(--t1);
  padding:6px 9px;border:1px solid var(--line2);border-radius:var(--r-sm);
  background:var(--e3);resize:vertical}
.kb-fld textarea:focus,.kb-fld input:focus{outline:none;border-color:var(--accent-line);
  background:var(--e1)}
/* 语域子字段（句式/称呼/口头禅/专业尺度）：两列排，label 与值上下结构 */
.kb-fld .sub{flex:1;min-width:0;display:grid;grid-template-columns:1fr 1fr;gap:8px 14px}
.subf{display:flex;flex-direction:column;gap:4px}
.subf .lb{width:auto;text-align:left;flex:none;color:var(--t3);font-size:var(--fs-micro)}
.subf .vl{color:var(--t1);font-size:var(--fs-small);line-height:1.6;overflow-wrap:anywhere}
.subf textarea{width:100%;font:inherit;font-size:var(--fs-small);line-height:1.55;color:var(--t1);
  padding:5px 8px;border:1px solid var(--line2);border-radius:var(--r-sm);background:var(--e3);resize:vertical}
.subf textarea:focus{outline:none;border-color:var(--accent-line);background:var(--e1)}
/* 操作按钮区 */
.kb-ops{display:flex;align-items:center;gap:8px;margin-bottom:16px}
.kb-btn{display:inline-flex;align-items:center;justify-content:center;gap:5px;
  font-size:var(--fs-caption);line-height:1;padding:7px 15px;
  border-radius:var(--r-sm);border:1px solid var(--line2);color:var(--t2);
  background:var(--e1);cursor:pointer;transition:background var(--dur-1),color var(--dur-1),
  border-color var(--dur-1)}
.kb-btn:hover{background:var(--e2)}
.kb-btn.primary{background:var(--accent);border-color:transparent;color:var(--accent-text)}
.kb-btn.primary:hover{background:var(--accent-wash);color:var(--accent-text);border-color:var(--accent-line)}
.kb-btn:disabled{opacity:.5;cursor:default}
.kb-ops .kb-note.err{margin:0;color:var(--danger-text)}

/* ── ★ 自动化面板（2026-10-15 · 0.9.0 · 建档自动化开关 + 9 节点总览）──
   只用既有令牌（--accent/--accent-wash/--line/--line2/--e1/--e2/--t1/--t2/--t3/
   --amber/--amber-bg/--danger-text），四主题共用同一套结构。 */
.kb-auto{display:flex;flex-direction:column;gap:10px;margin-bottom:6px}
.kb-auto-row{display:flex;align-items:center;gap:14px;padding:13px 15px;
  border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1)}
.kb-auto-info{flex:1;min-width:0}
.kb-auto-info .nm{font-size:var(--fs-small);color:var(--t1);font-weight:500;line-height:1.5}
.kb-auto-info .ds{font-size:var(--fs-micro);color:var(--t3);line-height:1.7;margin-top:4px}
/* 开关：开关态吃 accent、关态吃中性线；禁用时降透明度（提交中） */
.kb-toggle{flex:none;display:inline-flex;align-items:center;gap:8px;padding:0;
  background:transparent;border:none;cursor:pointer;font:inherit}
.kb-toggle .knob{position:relative;width:42px;height:22px;border-radius:var(--r-full);
  background:var(--line2);transition:background var(--dur-1)}
.kb-toggle .knob::after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;
  border-radius:50%;background:var(--e1);transition:transform var(--dur-1)}
.kb-toggle.on .knob{background:var(--accent)}
.kb-toggle.on .knob::after{transform:translateX(20px)}
.kb-toggle .lbl{font-size:var(--fs-caption);color:var(--t2);white-space:nowrap}
.kb-toggle.on .lbl{color:var(--accent)}
.kb-toggle.busy{opacity:.6;cursor:default}
/* 9 节点卡片墙 */
.kb-nodes{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;
  margin-bottom:14px}
.kb-node{padding:11px 13px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--e1);cursor:pointer;transition:border-color var(--dur-1),background var(--dur-1)}
.kb-node:hover{border-color:var(--accent-line);background:var(--e2)}
.kb-node.on{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent-line)}
.kb-node .lb{font-size:var(--fs-small);color:var(--t1);font-weight:500;margin-bottom:9px}
.kb-node .num{display:flex;align-items:baseline;gap:4px;font-family:var(--font-num)}
.kb-node .num b{font-size:var(--fs-h3);color:var(--t1);line-height:1.1}
.kb-node .num.c b{color:var(--t2)}
.kb-node .num i{font-size:var(--fs-micro);font-style:normal;color:var(--t3)}
/* 缺话术节点：琥珀色警示（这一环 AI 没东西可答） */
.kb-node.short{border-color:var(--amber);background:var(--amber-bg)}
.kb-node.short .num b{color:var(--danger-text)}

/* ── ★ 自动化面板 · 建档话术编辑区（2026-10-15 · 0.9.1）── */
.kb-intake{display:flex;flex-direction:column;gap:8px;margin-bottom:6px}
.kb-intake-ta{width:100%;min-height:150px;resize:vertical;font:inherit;
  font-size:var(--fs-small);line-height:1.7;color:var(--t1);
  padding:11px 13px;border:1px solid var(--line2);border-radius:var(--r-md);
  background:var(--e3);box-sizing:border-box}
.kb-intake-ta:focus{outline:none;border-color:var(--accent-line);background:var(--e1)}
.kb-intake-foot{display:flex;align-items:center;gap:10px}
.kb-intake-hint{font-size:var(--fs-micro);color:var(--t3)}

/* ── ★ 自动化面板 · 跨人设知识共享（2026-10-15 · 0.9.2）── */
.kb-share-list{display:flex;flex-direction:column;gap:6px;margin-bottom:10px}
.kb-share-row{display:flex;align-items:center;gap:8px;padding:8px 12px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--e1);
  font-size:var(--fs-small);color:var(--t1)}
.kb-share-row .from{color:var(--t1);font-weight:500}
.kb-share-row .to{color:var(--t1);font-weight:500}
.kb-share-row .arrow,.kb-share-add .arrow{color:var(--t3);font-size:var(--fs-micro);white-space:nowrap}
.kb-share-del{margin-left:auto;padding:4px 10px;font-size:var(--fs-micro)}
.kb-share-add{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.kb-share-sel{flex:1;min-width:0;font:inherit;font-size:var(--fs-small);color:var(--t1);
  padding:6px 9px;border:1px solid var(--line2);border-radius:var(--r-sm);background:var(--e3)}
.kb-share-sel:focus{outline:none;border-color:var(--accent-line);background:var(--e1)}

/* 加/删共享边的反馈条（成功绿 / 失败红，不能静默） */
.kb-share-msg{padding:7px 12px;border-radius:var(--r-sm);font-size:var(--fs-small);
  line-height:1.6;margin-bottom:8px}
.kb-share-msg.ok{color:var(--accent-text);background:var(--accent-wash);border:1px solid var(--accent-line)}
.kb-share-msg.err{color:var(--danger-text);background:var(--danger-bg,var(--e2));border:1px solid var(--danger-line,var(--danger-text))}
