dsh-data-domain-knowledge 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/cordis.patch.yml +410 -0
  4. package/eval/README.md +76 -0
  5. package/eval/evaluate-retrieval.mjs +121 -0
  6. package/eval/queries.example.jsonl +2 -0
  7. package/lib/client.js +111415 -0
  8. package/lib/types/config-schema.d.ts +35 -0
  9. package/lib/types/config-schema.d.ts.map +1 -0
  10. package/lib/types/config-schema.js +34 -0
  11. package/lib/types/config-schema.js.map +1 -0
  12. package/lib/types/convert/core-loader.d.ts +32 -0
  13. package/lib/types/convert/core-loader.d.ts.map +1 -0
  14. package/lib/types/convert/core-loader.js +60 -0
  15. package/lib/types/convert/core-loader.js.map +1 -0
  16. package/lib/types/convert/host.d.ts +88 -0
  17. package/lib/types/convert/host.d.ts.map +1 -0
  18. package/lib/types/convert/host.js +479 -0
  19. package/lib/types/convert/host.js.map +1 -0
  20. package/lib/types/convert/ingest.d.ts +125 -0
  21. package/lib/types/convert/ingest.d.ts.map +1 -0
  22. package/lib/types/convert/ingest.js +228 -0
  23. package/lib/types/convert/ingest.js.map +1 -0
  24. package/lib/types/convert/settings-schema.d.ts +18 -0
  25. package/lib/types/convert/settings-schema.d.ts.map +1 -0
  26. package/lib/types/convert/settings-schema.js +26 -0
  27. package/lib/types/convert/settings-schema.js.map +1 -0
  28. package/lib/types/convert/types.d.ts +46 -0
  29. package/lib/types/convert/types.d.ts.map +1 -0
  30. package/lib/types/convert/types.js +41 -0
  31. package/lib/types/convert/types.js.map +1 -0
  32. package/lib/types/diagnosis/cards.d.ts +71 -0
  33. package/lib/types/diagnosis/cards.d.ts.map +1 -0
  34. package/lib/types/diagnosis/cards.js +482 -0
  35. package/lib/types/diagnosis/cards.js.map +1 -0
  36. package/lib/types/diagnosis/problem-classes.d.ts +51 -0
  37. package/lib/types/diagnosis/problem-classes.d.ts.map +1 -0
  38. package/lib/types/diagnosis/problem-classes.js +66 -0
  39. package/lib/types/diagnosis/problem-classes.js.map +1 -0
  40. package/lib/types/diagnosis/schema.d.ts +65 -0
  41. package/lib/types/diagnosis/schema.d.ts.map +1 -0
  42. package/lib/types/diagnosis/schema.js +208 -0
  43. package/lib/types/diagnosis/schema.js.map +1 -0
  44. package/lib/types/diagnosis/seed-source.d.ts +20 -0
  45. package/lib/types/diagnosis/seed-source.d.ts.map +1 -0
  46. package/lib/types/diagnosis/seed-source.js +96 -0
  47. package/lib/types/diagnosis/seed-source.js.map +1 -0
  48. package/lib/types/diagnosis/seed.d.ts +50 -0
  49. package/lib/types/diagnosis/seed.d.ts.map +1 -0
  50. package/lib/types/diagnosis/seed.js +242 -0
  51. package/lib/types/diagnosis/seed.js.map +1 -0
  52. package/lib/types/diagnosis/store.d.ts +81 -0
  53. package/lib/types/diagnosis/store.d.ts.map +1 -0
  54. package/lib/types/diagnosis/store.js +409 -0
  55. package/lib/types/diagnosis/store.js.map +1 -0
  56. package/lib/types/diagnosis/types.d.ts +124 -0
  57. package/lib/types/diagnosis/types.d.ts.map +1 -0
  58. package/lib/types/diagnosis/types.js +13 -0
  59. package/lib/types/diagnosis/types.js.map +1 -0
  60. package/lib/types/directory-picker.d.ts +94 -0
  61. package/lib/types/directory-picker.d.ts.map +1 -0
  62. package/lib/types/directory-picker.js +110 -0
  63. package/lib/types/directory-picker.js.map +1 -0
  64. package/lib/types/extract-model.d.ts +76 -0
  65. package/lib/types/extract-model.d.ts.map +1 -0
  66. package/lib/types/extract-model.js +193 -0
  67. package/lib/types/extract-model.js.map +1 -0
  68. package/lib/types/extract.d.ts +121 -0
  69. package/lib/types/extract.d.ts.map +1 -0
  70. package/lib/types/extract.js +549 -0
  71. package/lib/types/extract.js.map +1 -0
  72. package/lib/types/fts.d.ts +96 -0
  73. package/lib/types/fts.d.ts.map +1 -0
  74. package/lib/types/fts.js +184 -0
  75. package/lib/types/fts.js.map +1 -0
  76. package/lib/types/index.d.ts +39 -0
  77. package/lib/types/index.d.ts.map +1 -0
  78. package/lib/types/index.js +1112 -0
  79. package/lib/types/index.js.map +1 -0
  80. package/lib/types/intent/engine.d.ts +108 -0
  81. package/lib/types/intent/engine.d.ts.map +1 -0
  82. package/lib/types/intent/engine.js +501 -0
  83. package/lib/types/intent/engine.js.map +1 -0
  84. package/lib/types/intent/host.d.ts +88 -0
  85. package/lib/types/intent/host.d.ts.map +1 -0
  86. package/lib/types/intent/host.js +389 -0
  87. package/lib/types/intent/host.js.map +1 -0
  88. package/lib/types/intent/preset-tools.d.ts +37 -0
  89. package/lib/types/intent/preset-tools.d.ts.map +1 -0
  90. package/lib/types/intent/preset-tools.js +45 -0
  91. package/lib/types/intent/preset-tools.js.map +1 -0
  92. package/lib/types/intent/settings-schema.d.ts +59 -0
  93. package/lib/types/intent/settings-schema.d.ts.map +1 -0
  94. package/lib/types/intent/settings-schema.js +57 -0
  95. package/lib/types/intent/settings-schema.js.map +1 -0
  96. package/lib/types/intent/store.d.ts +75 -0
  97. package/lib/types/intent/store.d.ts.map +1 -0
  98. package/lib/types/intent/store.js +139 -0
  99. package/lib/types/intent/store.js.map +1 -0
  100. package/lib/types/intent/tools.d.ts +63 -0
  101. package/lib/types/intent/tools.d.ts.map +1 -0
  102. package/lib/types/intent/tools.js +108 -0
  103. package/lib/types/intent/tools.js.map +1 -0
  104. package/lib/types/intent/types.d.ts +189 -0
  105. package/lib/types/intent/types.d.ts.map +1 -0
  106. package/lib/types/intent/types.js +62 -0
  107. package/lib/types/intent/types.js.map +1 -0
  108. package/lib/types/knowledge-bases.d.ts +266 -0
  109. package/lib/types/knowledge-bases.d.ts.map +1 -0
  110. package/lib/types/knowledge-bases.js +1107 -0
  111. package/lib/types/knowledge-bases.js.map +1 -0
  112. package/lib/types/layout.d.ts +262 -0
  113. package/lib/types/layout.d.ts.map +1 -0
  114. package/lib/types/layout.js +312 -0
  115. package/lib/types/layout.js.map +1 -0
  116. package/lib/types/migrate.d.ts +110 -0
  117. package/lib/types/migrate.d.ts.map +1 -0
  118. package/lib/types/migrate.js +280 -0
  119. package/lib/types/migrate.js.map +1 -0
  120. package/lib/types/recall-rank.d.ts +158 -0
  121. package/lib/types/recall-rank.d.ts.map +1 -0
  122. package/lib/types/recall-rank.js +261 -0
  123. package/lib/types/recall-rank.js.map +1 -0
  124. package/lib/types/runtime.d.ts +568 -0
  125. package/lib/types/runtime.d.ts.map +1 -0
  126. package/lib/types/runtime.js +3045 -0
  127. package/lib/types/runtime.js.map +1 -0
  128. package/lib/types/settings-schema.d.ts +117 -0
  129. package/lib/types/settings-schema.d.ts.map +1 -0
  130. package/lib/types/settings-schema.js +92 -0
  131. package/lib/types/settings-schema.js.map +1 -0
  132. package/lib/types/settings-volatile.d.ts +102 -0
  133. package/lib/types/settings-volatile.d.ts.map +1 -0
  134. package/lib/types/settings-volatile.js +114 -0
  135. package/lib/types/settings-volatile.js.map +1 -0
  136. package/lib/types/types.d.ts +799 -0
  137. package/lib/types/types.d.ts.map +1 -0
  138. package/lib/types/types.js +387 -0
  139. package/lib/types/types.js.map +1 -0
  140. package/lib/types/wiki-types.d.ts +68 -0
  141. package/lib/types/wiki-types.d.ts.map +1 -0
  142. package/lib/types/wiki-types.js +322 -0
  143. package/lib/types/wiki-types.js.map +1 -0
  144. package/package.json +101 -0
  145. package/preset/tita-data-agent/agent.cordis.yml +376 -0
  146. package/preset/tita-data-agent/preset.yml +3 -0
  147. package/python/requirements.txt +8 -0
  148. package/scripts/doctor.mjs +70 -0
  149. package/scripts/e2e-pipeline.mjs +355 -0
  150. package/scripts/install-agent-preset.mjs +92 -0
  151. package/scripts/setup-embedding.sh +34 -0
  152. package/scripts/sync-agent-preset.mjs +188 -0
  153. package/src/client/AgentPresetCard.tsx +247 -0
  154. package/src/client/DirectoryPicker.tsx +357 -0
  155. package/src/client/InfoHint.tsx +65 -0
  156. package/src/client/IntentLogicTab.tsx +185 -0
  157. package/src/client/IntentTab.tsx +715 -0
  158. package/src/client/KnowledgeBaseTab.tsx +1454 -0
  159. package/src/client/KnowledgeGraphView.tsx +306 -0
  160. package/src/client/KnowledgePanel.tsx +381 -0
  161. package/src/client/KnowledgeStepRail.tsx +60 -0
  162. package/src/client/NodeSettings.tsx +392 -0
  163. package/src/client/PreviewSections.tsx +116 -0
  164. package/src/client/RecallPanel.tsx +399 -0
  165. package/src/client/TypeDefinitionDrawer.tsx +215 -0
  166. package/src/client/WikiFlowCard.tsx +226 -0
  167. package/src/client/WikiTypeEditor.tsx +332 -0
  168. package/src/client/agent-preset.ts +121 -0
  169. package/src/client/arch/AgentArchitectureGraph.tsx +219 -0
  170. package/src/client/arch/NodeLogicPanel.tsx +133 -0
  171. package/src/client/arch/ProblemDetailPanel.tsx +88 -0
  172. package/src/client/arch/model.ts +691 -0
  173. package/src/client/architecture.css +191 -0
  174. package/src/client/architecture.tsx +530 -0
  175. package/src/client/attribution/AttributionGraph.tsx +104 -0
  176. package/src/client/attribution/AttributionTab.tsx +332 -0
  177. package/src/client/attribution/CaseView.tsx +102 -0
  178. package/src/client/attribution/GraphStage.tsx +87 -0
  179. package/src/client/attribution/RunView.tsx +184 -0
  180. package/src/client/attribution/StageChrome.tsx +403 -0
  181. package/src/client/attribution/ViewSwitch.tsx +107 -0
  182. package/src/client/attribution/graph-options.ts +381 -0
  183. package/src/client/attribution/model.ts +462 -0
  184. package/src/client/config-scope.ts +119 -0
  185. package/src/client/convert/ConvertPanel.tsx +594 -0
  186. package/src/client/convert/styles.css +138 -0
  187. package/src/client/convert/styles.ts +49 -0
  188. package/src/client/format.ts +39 -0
  189. package/src/client/graph/layout.ts +181 -0
  190. package/src/client/graph.css +113 -0
  191. package/src/client/index.ts +98 -0
  192. package/src/client/problem-domains.ts +114 -0
  193. package/src/client/styles.css +940 -0
  194. package/src/client/styles.ts +11 -0
  195. package/src/client/useFitScale.ts +68 -0
  196. package/src/config-schema.ts +45 -0
  197. package/src/convert/core-loader.ts +68 -0
  198. package/src/convert/host.ts +579 -0
  199. package/src/convert/ingest.ts +367 -0
  200. package/src/convert/settings-schema.ts +27 -0
  201. package/src/convert/types.ts +65 -0
  202. package/src/diagnosis/cards.ts +498 -0
  203. package/src/diagnosis/problem-classes.ts +117 -0
  204. package/src/diagnosis/schema.ts +260 -0
  205. package/src/diagnosis/seed-source.ts +107 -0
  206. package/src/diagnosis/seed.ts +291 -0
  207. package/src/diagnosis/store.ts +432 -0
  208. package/src/diagnosis/types.ts +152 -0
  209. package/src/directory-picker.ts +164 -0
  210. package/src/extract-model.ts +227 -0
  211. package/src/extract.ts +632 -0
  212. package/src/fts.ts +203 -0
  213. package/src/index.ts +1091 -0
  214. package/src/intent/README.md +63 -0
  215. package/src/intent/engine.ts +527 -0
  216. package/src/intent/host.ts +462 -0
  217. package/src/intent/preset-tools.ts +48 -0
  218. package/src/intent/settings-schema.ts +63 -0
  219. package/src/intent/store.ts +143 -0
  220. package/src/intent/tools.ts +139 -0
  221. package/src/intent/types.ts +245 -0
  222. package/src/knowledge-bases.ts +1160 -0
  223. package/src/layout.ts +350 -0
  224. package/src/migrate.ts +262 -0
  225. package/src/python/embedding_worker.py +471 -0
  226. package/src/recall-rank.ts +299 -0
  227. package/src/runtime.ts +3069 -0
  228. package/src/settings-schema.ts +94 -0
  229. package/src/settings-volatile.ts +122 -0
  230. package/src/types.ts +1140 -0
  231. package/src/wiki-types.ts +357 -0
@@ -0,0 +1,940 @@
1
+ /* ---------------------------------------------------------------- tokens
2
+ *
3
+ * **本文件不再声明任何 `--tita-*` 名字。** 读法因此只有一条:`--tita-*` 一律指
4
+ * `packages/ui/src/theme.css` 的共享令牌(声明在 `:root, body` 上,跟着宿主的
5
+ * `data-ds-dark-theme` 一起翻),插件自己派生的颜色一律挂 `--ddk-` 前缀。
6
+ *
7
+ * 旧版在这里重定义了 `--tita-blue` / `--tita-violet` / `--tita-green` / `--tita-amber`
8
+ * 四个同名不同义的槽位(amber 指向的其实是主色,`--tita-green` 是一个不参与主题的
9
+ * 固定值),名字与共享词表撞车;同时 `--tita-ink` 这类又反过来指向 `--color-tita-ink`,
10
+ * 而后者又指回 `--tita-ink` —— 在 `:root` 上构成一个自定义属性环。现在两件事都消失了:
11
+ * 共享令牌直接读,插件派生色只有一个来源。
12
+ *
13
+ * 共享词表里没有「红色底 / 红色边」这两档(danger 只是一个对比度达标的墨色),所以按
14
+ * 共享 tone 的同一套比例派生:10% 作底、32% 作边。混的是 surface 而不是 transparent
15
+ * —— 透明混色在深色底上等于看不见,而 surface 会跟着主题走。声明在 `:root, body`
16
+ * 而不是只在 `:root`:自定义属性的 `var()` 是在**声明它的那个元素**上求值的,只写在
17
+ * `:root` 会把浅色值冻在 <html> 上再分发给所有子节点(见 theme.css 文件头)。
18
+ */
19
+ :root,
20
+ body {
21
+ --ddk-danger-tint: color-mix(in srgb, var(--tita-danger) 10%, var(--tita-surface));
22
+ --ddk-danger-line: color-mix(in srgb, var(--tita-danger) 32%, var(--tita-surface));
23
+ }
24
+
25
+ .tita-panel {
26
+ box-sizing: border-box;
27
+ display: flex;
28
+ container-type: inline-size;
29
+ width: 100%;
30
+ min-width: 0;
31
+ /* `position: relative` 是这条「只允许一个滚动条」规则的一半:插件根节点必须同时
32
+ 是定位上下文。否则插件内 position:absolute 的装饰/无障碍节点(.tita-srOnly、
33
+ 视觉隐藏的节点列表)会向上找到宿主的 pane body 作为包含块,它们的静态位置
34
+ ——也就是长内容的末尾——会把宿主面板撑出第二条空滚动条。 */
35
+ position: relative;
36
+ /* One scroller only: the panel is capped at the host pane height and
37
+ `.tita-content` owns the vertical scroll, so the host pane never grows a
38
+ second scrollbar beside it. */
39
+ min-height: 0;
40
+ height: 100%;
41
+ max-height: 100%;
42
+ flex-direction: column;
43
+ overflow: hidden;
44
+ background: var(--tita-canvas);
45
+ color: var(--tita-ink);
46
+ /* 之前这里写的是 `Inter, ui-sans-serif, …`:Inter 从来没有被加载过(没有 @font-face、
47
+ 没有 font link),所以它一直只是「声明了一个不存在的字体」,实际渲染落到 ui-sans-serif。
48
+ 现在直接读共享的字体 token,并且把中文也点名——中文文案不该交给浏览器的兜底去决定。 */
49
+ font-family: var(--font-tita);
50
+ font-size: 13px;
51
+ line-height: 1.45;
52
+ }
53
+
54
+ .tita-panel *, .tita-panel *::before, .tita-panel *::after { box-sizing: border-box; }
55
+ /* 面板分两层:.tita-tabBar 是外壳(永远可见),.tita-content 是唯一的滚动区。
56
+ Tab 放在外壳里而不是靠 position: sticky —— 置顶就该是结构,不是补丁。
57
+ 0029:撤掉 tab 栏底边那条分隔线。分段控件自己就有边框和底板,横线是第二道
58
+ 区隔;两条挨着画,读起来像「两个工具条叠在一起」。 */
59
+ .tita-panelTabs { display: flex; min-height: 0; flex: 1 1 auto; flex-direction: column; }
60
+ /* 底边只留 4px:tab 自己的下边框就是内容的分界,下面再垫 7px 只是把两者推开
61
+ (GUI 反馈 2026-09-21「每个 tab 下的内容距离 tab 太远」)。8px 的内容上边距
62
+ 由 `TabsContent` 给,两者相加才是从分界线到第一块内容的距离。 */
63
+ .tita-tabBar { display: flex; flex: 0 0 auto; align-items: center; background: var(--tita-surface); padding: 7px 12px 4px; }
64
+ /* 视图级状态行:只在真的读取失败 / 读取中时才出现。标题行撤掉之后,
65
+ 这是内容顶部唯一允许出现的一行「关于这一页本身」的文字。 */
66
+ .tita-viewStatus { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; color: var(--tita-ink-muted); font-size: 11.5px; }
67
+ .tita-viewStatus > svg { flex: 0 0 auto; color: var(--tita-warning); }
68
+
69
+ .tita-content { flex: 1 1 auto; width: 100%; max-width: none; min-width: 0; min-height: 0; margin: 0; padding: 0 12px 28px; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-gutter: stable; }
70
+ .tita-hiddenInput { display: none; }
71
+
72
+ /* ------------------------------------------------- 画布优先的视图(智能归因) */
73
+ /* 为什么要有这一档:`.tita-content` 的默认契约是「唯一的纵向滚动区」,它给所有
74
+ 视图都留了四周内边距。而智能归因的主内容是一块画布 —— 画布既不该跟着页面滚,
75
+ 也不该被内边距削掉一圈。所以这里给它一个显式的**第二档契约**:内容区本身变成
76
+ 不滚动的纵向 flex 容器,滚动权下放给块内各自需要的区域(案例/排查正文)。
77
+ 这不是给一个视图开后门:它是「主内容是画布」这一类视图的通用形态,将来再有
78
+ 画布型视图(比如血缘图)直接复用这一档,而不是各自写一套负边距。 */
79
+ .tita-contentStage { display: flex; flex-direction: column; overflow: hidden; padding: 0 12px 12px; }
80
+ .tita-contentStage .tita-pageHeader { flex: 0 0 auto; padding-bottom: 6px; }
81
+ .tita-stageContent { display: flex; min-width: 0; min-height: 0; flex: 1 1 auto; flex-direction: column; padding-top: 0; }
82
+
83
+ /* ------------------------------------------------------------------ tabs */
84
+ /* 分段控件(segmented)落在白色工具条上:轨道是一块浅灰圆角底板,选中项是浮起的
85
+ 白色胶囊 + 主色文字。不用下划线 —— 下划线会和下方卡片边框在视觉上打架。
86
+ 0035:预览抽屉里「内容」那一行的 Markdown / 文本切换是**同一套控件**,所以选择器
87
+ 带上 `.tita-kbViewTabs`。抽屉走 Portal、不在 `.tita-panel` 里,这条容器规则必须显式
88
+ 点名它;触发器那几条规则没有 `.tita-panel` 前缀,所以自动生效 —— 两处一份定义,
89
+ 不各造一套。 */
90
+ .tita-panel .tita-tabsList,
91
+ .tita-kbViewTabs {
92
+ display: inline-flex;
93
+ max-width: 100%;
94
+ align-items: center;
95
+ gap: 2px;
96
+ overflow-x: auto;
97
+ border: 1px solid var(--tita-line);
98
+ border-radius: 9px;
99
+ background: var(--tita-surface-muted);
100
+ padding: 2px;
101
+ scrollbar-width: none;
102
+ }
103
+ .tita-tabsList::-webkit-scrollbar { display: none; }
104
+ .tita-tabsList .tita-uiTabsTrigger {
105
+ display: inline-flex;
106
+ min-height: 28px;
107
+ align-items: center;
108
+ gap: 5px;
109
+ border: 0;
110
+ border-radius: 7px;
111
+ background: transparent;
112
+ padding: 0 11px;
113
+ color: var(--tita-ink-muted);
114
+ font-size: 12px;
115
+ font-weight: 600;
116
+ letter-spacing: -.01em;
117
+ }
118
+ .tita-tabsList .tita-uiTabsTrigger svg { flex: 0 0 auto; opacity: .85; }
119
+ .tita-tabsList .tita-uiTabsTrigger:hover { background: color-mix(in srgb, var(--tita-surface) 70%, transparent); color: var(--tita-ink); }
120
+ .tita-tabsList .tita-uiTabsTrigger[data-state='active'] {
121
+ border-bottom-color: transparent;
122
+ background: var(--tita-surface);
123
+ color: var(--tita-primary);
124
+ font-weight: 680;
125
+ box-shadow: 0 1px 2px rgb(15 23 42 / .12), inset 0 0 0 1px var(--tita-primary-shadow);
126
+ }
127
+ .tita-tabsList .tita-uiTabsTrigger[data-state='active'] svg { opacity: 1; }
128
+ /* 抽屉里那一枚是**行内次级控件**:它站在「内容」这个小节标题旁边,所以比顶栏那枚小
129
+ 一号(顶栏是面板级导航,这里是同一个分块里的两种读法)。放在基础规则之后覆盖 ——
130
+ 选择器权重相同,靠顺序取胜。 */
131
+ .tita-kbViewTabs { min-height: 24px; }
132
+ .tita-kbViewTabs .tita-uiTabsTrigger { min-height: 20px; padding: 0 8px; font-size: 11px; }
133
+
134
+ /* ---------------------------------------------------------------- header */
135
+ /* 标题行只占一行:图标 + 标题 + 一句说明。状态徽标与 ⋯ 菜单已撤(0022)。 */
136
+ .tita-pageHeader { display: flex; align-items: center; padding: 8px 2px 10px; }
137
+ .tita-headingGroup { display: flex; min-width: 0; flex: 1 1 auto; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
138
+ .tita-headingGroup h1 { margin: 0; color: var(--tita-ink); font-size: 15px; font-weight: 750; letter-spacing: -.02em; line-height: 1.2; }
139
+ .tita-headingGroup > p { min-width: 0; margin: 0; overflow: hidden; color: var(--tita-ink-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
140
+ .tita-brandMark { display: inline-flex; width: 24px; height: 24px; flex: 0 0 auto; align-items: center; justify-content: center; border: 1px solid var(--tita-primary-line); border-radius: 8px; background: var(--tita-primary-soft); color: var(--tita-primary); }
141
+ .tita-brandMarkBlue { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); color: var(--tita-primary); }
142
+ .tita-brandMarkViolet { border-color: var(--tita-tone-violet-line); background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
143
+ .tita-brandMarkAmber { border-color: var(--tita-tone-amber-line); background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
144
+ .tita-brandMarkGreen { border-color: var(--tita-tone-green-line); background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
145
+
146
+ .tita-notice { display: flex; min-height: 42px; align-items: center; gap: 9px; margin: 0 0 14px; padding: 8px 8px 8px 13px; box-shadow: none; }
147
+ .tita-notice > span { flex: 1; min-width: 0; }
148
+ .tita-noticeError { border-color: var(--ddk-danger-line); background: var(--ddk-danger-tint); color: var(--tita-danger); }
149
+ .tita-noticeSuccess { border-color: var(--tita-tone-green-line); background: var(--tita-tone-green-tint); color: var(--tita-success); }
150
+
151
+ /* ------------------------------------------------------------- overview */
152
+ /* 概览是单列堆叠:问题域 → 回字形架构图。右侧栏(自进化状态/图例)随 0022 一并撤掉,
153
+ 248px 的第二列留着只会让回字形被挤窄。 */
154
+ .tita-architecture { display: grid; gap: 10px; min-width: 0; }
155
+
156
+ /* 车道身份靠「彩色标题条 + 底色」,不再靠左侧那条 3px 竖线(0022:竖线不承载信息,
157
+ 三条车道却各自都有一条,反而显得是同一套装饰)。 */
158
+
159
+
160
+
161
+ /* B 车道的四段:上传 → 编译 → 召回 → 重排。 */
162
+ .tita-stageStack { display: grid; flex: 1 1 100%; min-width: 0; gap: 8px; }
163
+ .tita-stageRow { display: grid; min-width: 0; gap: 6px; }
164
+ .tita-stageLabel { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; font-weight: 700; letter-spacing: .01em; }
165
+ .tita-stageLabel b { display: inline-flex; width: 17px; height: 17px; flex: 0 0 auto; align-items: center; justify-content: center; border-radius: 6px; font-size: 10px; font-weight: 800; }
166
+ .tita-stageLabelViolet { color: var(--tita-tone-violet); }
167
+ .tita-stageLabelViolet b { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
168
+ .tita-stageLabelGreen { color: var(--tita-tone-green); }
169
+ .tita-stageLabelGreen b { background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
170
+ .tita-stageTrack { display: flex; min-width: 0; flex-wrap: wrap; align-items: stretch; gap: 8px; }
171
+ .tita-stageConnector { display: flex; padding-left: 4px; }
172
+ .tita-flowFork { display: grid; min-width: 158px; flex: 1 1 176px; gap: 8px; align-content: stretch; }
173
+
174
+ .tita-flowNode { display: flex; min-width: 152px; max-width: 268px; flex: 1 1 176px; align-items: flex-start; gap: 9px; border: 1px solid var(--tita-line); border-radius: 10px; background: var(--tita-surface); padding: 10px 11px; color: var(--tita-ink); font: inherit; text-align: left; cursor: pointer; box-shadow: 0 1px 2px rgba(15, 23, 42, .04); transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease; }
175
+ .tita-flowNode:hover { transform: translateY(-1px); border-color: var(--tita-line-strong); box-shadow: 0 7px 16px rgba(30, 43, 67, .08); }
176
+ .tita-flowNode:focus-visible { outline: 3px solid var(--tita-focus-ring); outline-offset: 2px; }
177
+ .tita-flowNodeCompact { min-width: 146px; padding: 8px 10px; }
178
+ .tita-flowNodeSelected { border-color: currentColor; box-shadow: 0 0 0 3px var(--tita-primary-wash); }
179
+ .tita-flowNodeIcon { display: inline-flex; width: 30px; height: 30px; flex: 0 0 auto; align-items: center; justify-content: center; border-radius: 9px; }
180
+ .tita-flowNodeCompact .tita-flowNodeIcon { width: 26px; height: 26px; border-radius: 8px; }
181
+ .tita-flowNodeCopy { display: grid; min-width: 0; gap: 3px; }
182
+ .tita-flowNodeCopy strong { color: var(--tita-ink); font-size: 12px; font-weight: 700; line-height: 1.35; }
183
+ .tita-flowNodeCompact .tita-flowNodeCopy strong { font-size: 11.5px; }
184
+ .tita-flowNodeCopy small { color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.45; }
185
+ .tita-flowNodeBadges { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
186
+ .tita-flowNodeBadges .tita-uiBadge { min-height: 19px; padding: 0 6px; font-size: 10px; }
187
+
188
+ .tita-flowNodeBlue { color: var(--tita-primary); }
189
+ .tita-flowNodeBlue .tita-flowNodeIcon { background: var(--tita-primary-soft); color: var(--tita-primary); }
190
+ .tita-flowNodeViolet { color: var(--tita-tone-violet); }
191
+ .tita-flowNodeViolet .tita-flowNodeIcon { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
192
+ .tita-flowNodeGreen { color: var(--tita-tone-green); }
193
+ .tita-flowNodeGreen .tita-flowNodeIcon { background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
194
+ .tita-flowNodeAmber { color: var(--tita-tone-amber); }
195
+ .tita-flowNodeAmber .tita-flowNodeIcon { background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
196
+ .tita-flowNodeNeutral { color: var(--tita-ink-muted); }
197
+ .tita-flowNodeNeutral .tita-flowNodeIcon { background: var(--tita-surface-muted); color: var(--tita-ink-muted); }
198
+
199
+ .tita-flowArrow { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; color: var(--tita-ink-faint); }
200
+ .tita-flowArrowBlue { color: var(--tita-primary); }
201
+ .tita-flowArrowViolet { color: var(--tita-tone-violet); }
202
+ .tita-flowArrowGreen { color: var(--tita-success); }
203
+ .tita-flowArrowAmber { color: var(--tita-warning); }
204
+
205
+ .tita-archBridge { display: flex; align-items: center; gap: 9px; padding: 0 6px; color: var(--tita-success); }
206
+ .tita-archBridgeUp { display: inline-flex; flex: 0 0 auto; color: currentColor; }
207
+ .tita-archBridgeLine { height: 1px; min-width: 12px; flex: 1 1 auto; background: currentColor; opacity: .45; }
208
+ .tita-archBridgeLabel { flex: 0 0 auto; color: var(--tita-tone-green); font-size: 11px; font-weight: 650; }
209
+
210
+ /* ------------------------------------------------------------ right rail */
211
+ .tita-rail { display: grid; min-width: 0; align-content: start; gap: 12px; }
212
+ .tita-railCard { min-width: 0; padding: 14px; }
213
+ .tita-railCardHeader { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
214
+ .tita-railCardHeader h3 { margin: 0; color: var(--tita-ink); font-size: 13px; font-weight: 750; }
215
+ .tita-donut { position: relative; width: 132px; height: 132px; margin: 14px auto 12px; }
216
+ .tita-donut svg { display: block; width: 100%; height: 100%; }
217
+ .tita-donut strong { position: absolute; inset: 0; display: grid; place-items: center; color: var(--tita-ink); font-size: 22px; font-weight: 750; letter-spacing: -.02em; }
218
+ .tita-railRows { display: grid; margin: 0; padding: 0; list-style: none; }
219
+ .tita-railRows li { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--tita-surface-muted); padding: 8px 2px; color: var(--tita-ink-muted); font-size: 11.5px; }
220
+ .tita-railRows li:first-child { border-top: 0; }
221
+ .tita-railRowIcon { display: inline-flex; flex: 0 0 auto; color: var(--tita-ink-faint); }
222
+ .tita-railRowLabel { flex: 1 1 auto; min-width: 0; }
223
+ .tita-railRows strong { color: var(--tita-ink); font-size: 11.5px; white-space: nowrap; }
224
+ .tita-railRowDanger strong { color: var(--tita-danger); }
225
+ .tita-railRowDanger .tita-railRowIcon { color: var(--tita-danger); }
226
+ .tita-railActions { display: grid; gap: 7px; margin-top: 12px; }
227
+ .tita-railCta { width: 100%; }
228
+ .tita-legendList { display: grid; margin: 12px 0 0; padding: 0; list-style: none; gap: 12px; }
229
+ .tita-legendList li { display: flex; align-items: center; gap: 11px; }
230
+ .tita-legendList strong { display: block; color: var(--tita-ink); font-size: 11.5px; }
231
+ .tita-legendList small { display: block; color: var(--tita-ink-faint); font-size: 10.5px; }
232
+ .tita-legendArrow { position: relative; width: 34px; height: 0; flex: 0 0 auto; border-top: 2px solid currentColor; }
233
+ .tita-legendArrow::after { content: ''; position: absolute; top: -4px; right: -2px; border-left: 7px solid currentColor; border-top: 4px solid transparent; border-bottom: 4px solid transparent; }
234
+ .tita-legendArrowBlue { color: var(--tita-primary); }
235
+ .tita-legendArrowViolet { color: var(--tita-tone-violet); }
236
+ .tita-legendArrowGreen { color: var(--tita-tone-green); }
237
+ .tita-railQuote { margin: 2px 2px 0; color: var(--tita-ink-faint); font-size: 11px; line-height: 1.65; text-align: center; }
238
+ .tita-railQuote small { display: block; margin-top: 6px; color: var(--tita-ink-faint); }
239
+
240
+ /* -------------------------------------------------------- shared metrics */
241
+ .tita-viewStack { display: grid; gap: 14px; }
242
+ .tita-statsRow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
243
+ .tita-metricCard { display: flex; min-width: 0; align-items: center; gap: 11px; padding: 13px 14px; }
244
+ .tita-metricIcon { display: inline-flex; width: 34px; height: 34px; flex: 0 0 auto; align-items: center; justify-content: center; border-radius: 9px; background: var(--tita-surface-muted); color: var(--tita-ink-muted); }
245
+ .tita-metricToneViolet .tita-metricIcon { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
246
+ .tita-metricToneBlue .tita-metricIcon { background: var(--tita-primary-soft); color: var(--tita-primary); }
247
+ .tita-metricToneGreen .tita-metricIcon { background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
248
+ .tita-metricToneAmber .tita-metricIcon { background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
249
+ .tita-metricCopy { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
250
+ .tita-metricCopy small { color: var(--tita-ink-muted); font-size: 11px; }
251
+ .tita-metricCopy strong { overflow: hidden; color: var(--tita-ink); font-size: 18px; font-weight: 750; letter-spacing: -.02em; text-overflow: ellipsis; white-space: nowrap; }
252
+ .tita-metricCopy em { overflow: hidden; color: var(--tita-ink-faint); font-size: 10px; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }
253
+
254
+ .tita-workspaceCard { min-width: 0; padding: 16px; }
255
+ .tita-cardHeader { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 13px; }
256
+ /* 卡头右侧那一组:状态徽标 + 「参数」chip(0034)。它们是一组,所以 gap 比外层小。 */
257
+ .tita-cardHeaderActions { display: flex; flex: 0 0 auto; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 7px; }
258
+ .tita-workspaceCard h3, .tita-memoryCard h3, .tita-skillCard h3, .tita-skillHero h3, .tita-evalRunner h3, .tita-evalPlan h3 { margin: 4px 0 0; color: var(--tita-ink); font-size: 15px; font-weight: 750; }
259
+ .tita-sectionEyebrow { display: inline-flex; align-items: center; gap: 6px; color: var(--tita-ink-faint); font-size: 10px; font-weight: 750; letter-spacing: .1em; }
260
+ .tita-headerMetaText { padding-top: 16px; color: var(--tita-ink-faint); font-size: 11px; }
261
+ .tita-cardDescription { margin: 5px 0 13px; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; }
262
+ .tita-actionRow { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
263
+ .tita-resultBadge { margin-top: 10px; }
264
+ .tita-inputRow { display: flex; align-items: center; gap: 8px; }
265
+ .tita-inputRow .tita-uiInput { flex: 1; min-width: 0; }
266
+ .tita-infoList { display: grid; gap: 8px; margin-top: 14px; }
267
+ .tita-infoList > div { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; border-bottom: 1px solid var(--tita-line); padding: 7px 0; }
268
+ .tita-infoList span { color: var(--tita-ink-muted); font-size: 11px; }
269
+ .tita-infoList strong { color: var(--tita-ink); font-size: 11px; text-align: right; }
270
+
271
+ .tita-buildTrace { display: flex; min-width: 0; align-items: stretch; flex-wrap: wrap; gap: 9px; margin: 4px 0 2px; }
272
+ .tita-buildTraceItem { display: flex; min-width: 0; flex: 1 1 190px; align-items: center; gap: 9px; }
273
+ .tita-buildTraceNode { display: flex; width: 100%; min-width: 0; min-height: 58px; flex: 1 1 0; align-items: center; gap: 9px; border: 1px solid var(--tita-line); border-radius: 10px; background: var(--tita-surface); padding: 9px 10px; color: var(--tita-ink); font: inherit; text-align: left; cursor: pointer; transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease; }
274
+ .tita-buildTraceNode:hover { transform: translateY(-1px); border-color: var(--tita-line-strong); box-shadow: 0 6px 14px rgba(30, 43, 67, .06); }
275
+ .tita-buildTraceNode:focus-visible { outline: 3px solid var(--tita-focus-ring); outline-offset: 2px; }
276
+ .tita-buildTraceNodeSelected { border-color: currentColor; }
277
+ .tita-buildTraceIcon { display: inline-flex; width: 29px; height: 29px; flex: 0 0 auto; align-items: center; justify-content: center; border-radius: 8px; }
278
+ .tita-buildTraceNode > span:last-child { display: grid; min-width: 0; gap: 2px; }
279
+ .tita-buildTraceNode strong, .tita-buildTraceNode small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
280
+ .tita-buildTraceNode strong { color: var(--tita-ink); font-size: 12px; line-height: 1.3; }
281
+ .tita-buildTraceNode small { color: var(--tita-ink-muted); font-size: 10px; }
282
+ .tita-buildTraceBlue .tita-buildTraceIcon { background: var(--tita-primary-soft); color: var(--tita-primary); }
283
+ .tita-buildTraceViolet .tita-buildTraceIcon { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
284
+ .tita-buildTraceGreen .tita-buildTraceIcon { background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
285
+ .tita-buildTraceAmber .tita-buildTraceIcon { background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
286
+
287
+ .tita-memoryGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
288
+ .tita-memoryCard { min-width: 0; padding: 16px; }
289
+ .tita-memoryCardWide { grid-column: 1 / -1; }
290
+ .tita-memoryCard p { min-height: 42px; margin: 10px 0 15px; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.7; }
291
+ .tita-timeline { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 14px 0; color: var(--tita-ink-muted); font-size: 12px; }
292
+ .tita-timeline span { border: 1px solid var(--tita-line); border-radius: 7px; background: var(--tita-surface-muted); padding: 6px 9px; }
293
+ .tita-timeline i { color: var(--tita-ink-faint); font-style: normal; }
294
+
295
+ .tita-skillHero { display: flex; align-items: center; gap: 12px; padding: 15px 16px; }
296
+ .tita-skillHero > div:nth-child(2) { flex: 1; min-width: 0; }
297
+ .tita-skillHero p { margin: 5px 0 0; color: var(--tita-ink-muted); font-size: 12px; }
298
+ .tita-skillHeroIcon, .tita-skillIcon { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; border-radius: 10px; background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
299
+ .tita-skillHeroIcon { width: 40px; height: 40px; }
300
+ .tita-skillGrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
301
+ .tita-skillCard { min-width: 0; padding: 14px; }
302
+ .tita-skillCardTop { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
303
+ .tita-skillIcon { width: 30px; height: 30px; background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
304
+ .tita-skillCard p { min-height: 36px; margin: 8px 0 16px; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; }
305
+ .tita-skillMeta { display: flex; align-items: center; justify-content: space-between; border-top: 1px solid var(--tita-line); padding-top: 9px; color: var(--tita-ink-faint); font-size: 10px; }
306
+
307
+ .tita-evalGrid { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(280px, .8fr); gap: 14px; }
308
+ .tita-evalRunner, .tita-evalPlan { min-width: 0; padding: 16px; }
309
+ .tita-evalInput { display: flex; align-items: center; gap: 8px; margin-top: 13px; }
310
+ .tita-evalInput .tita-uiInput { flex: 1; min-width: 0; }
311
+ .tita-evalResult { display: flex; align-items: center; gap: 7px; margin-top: 12px; border: 1px solid var(--tita-tone-green-line); border-radius: 9px; background: var(--tita-tone-green-tint); color: var(--tita-success); padding: 9px 10px; font-size: 11px; }
312
+ .tita-evalResult span { margin-left: auto; color: var(--tita-success); }
313
+ .tita-emptyState { display: flex; align-items: center; gap: 7px; margin-top: 14px; border: 1px dashed var(--tita-line); border-radius: 9px; color: var(--tita-ink-faint); padding: 10px; font-size: 11px; }
314
+ .tita-evalRows { display: grid; margin: 8px 0 14px; }
315
+ .tita-evalRows > div { display: flex; justify-content: space-between; border-bottom: 1px solid var(--tita-line); padding: 9px 0; color: var(--tita-ink-muted); font-size: 11px; }
316
+ .tita-evalRows strong { color: var(--tita-ink-faint); font-weight: 600; }
317
+
318
+ /* --------------------------------------------------------------- drawer */
319
+ /*
320
+ * 抽屉宽度。内边距由 UI 包的 `.tita-uiDrawerBody`(左右 18px、上下 15px)提供。
321
+ *
322
+ * 这里原来还有一整套 `tita-drawerHeader` / `drawerBody` / `drawerDescription` /
323
+ * `drawerIcon` / `drawerActions` / `drawerSubtitle`,是平台抽屉换成共享组件之前留下的:
324
+ * 现在一个引用都没有(`styles.drawerHeader` 之类在客户端源码里 0 命中),留着只会让人
325
+ * 以为抽屉的间距由它们决定,改错地方。已删。
326
+ *
327
+ * 留下的是**真正决定预览抽屉版式**的三条:
328
+ */
329
+ .tita-drawer { width: min(440px, 100vw); }
330
+ /*
331
+ * 正文分块:块与块之间 14px。
332
+ *
333
+ * 它必须挂在抽屉正文上、而**分块容器**挂在每一块上 —— 因为一块(比如「元信息」)是
334
+ * 「小标题 + 它自己的表」两个同级节点,只在外层给统一 gap 会把标题和它自己的内容也
335
+ * 拉开 14px,读起来标题就不再管着下面那块了。
336
+ */
337
+ .tita-drawerStack { display: grid; gap: 14px; align-content: start; }
338
+ /* 一块内部:标题与自己的内容贴紧。 */
339
+ .tita-drawerSection { display: grid; gap: 6px; align-content: start; }
340
+ /* 分块之后,标题的上边距交给块间距 —— 否则 14 + 16 会在两处叠出一个空洞。 */
341
+ .tita-drawerSection > .tita-kbSubHead { margin: 0; }
342
+ .tita-toneBlue { background: var(--tita-primary-soft); color: var(--tita-primary); }
343
+ .tita-toneViolet { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
344
+ .tita-toneGreen { background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
345
+ .tita-toneAmber { background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
346
+ .tita-toneNeutral { background: var(--tita-surface-muted); color: var(--tita-ink-muted); }
347
+ .tita-actionPanel { border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); padding: 14px; }
348
+ .tita-actionPanel h3 { margin: 0; color: var(--tita-ink); font-size: 13px; }
349
+ .tita-actionPanel p { margin: 6px 0 12px; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; }
350
+ .tita-actionPanel > .tita-uiBadge { margin-top: 10px; }
351
+ .tita-inlineHint { display: flex; align-items: center; gap: 6px; margin: 10px 0 0; color: var(--tita-ink-faint); font-size: 11px; }
352
+ .tita-evolutionDetail > div:first-child { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
353
+ .tita-evolutionDetail > p { margin: 0 0 14px; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.7; }
354
+
355
+ /* ---------------------------------------------------- settings drawer UI */
356
+ /* 抽屉要比版本抽屉宽:这里每一块都是**两列字段 + 字段说明**,而且存储那一块还要
357
+ 显示三条完整路径。400px 下两列会挤成一列,路径会被截成读不出。 */
358
+ .tita-settingsDrawer { width: min(560px, 100vw); }
359
+ .tita-settingsError { border: 1px solid var(--ddk-danger-line); border-radius: 9px; background: var(--ddk-danger-tint); color: var(--tita-danger); padding: 9px 11px; font-size: 12px; }
360
+ .tita-settingsSection { border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); padding: 15px; }
361
+ /* 卡片头的「参数」chip 定位过来的那一块:**一次性**强调,1.6 秒后自己回到常态。
362
+ 它不是「选中态」(抽屉里没有选中这一回事),所以不复用 `.tita-kbStepOn` 的描边:
363
+ 边框与底色从强调蓝淡回默认,动画的 `both` 让终态就是默认值 —— 不需要 JS 计时器
364
+ 去清这个类。`scroll-margin-block-start` 给 `scrollIntoView` 留一口气,别让边框贴顶。 */
365
+ .tita-settingsSection { scroll-margin-block-start: 10px; }
366
+ .tita-settingsSection:focus-visible { outline: 2px solid var(--tita-primary); outline-offset: 2px; }
367
+ @keyframes tita-settings-settle {
368
+ from { border-color: var(--tita-primary); background: var(--tita-primary-soft); }
369
+ to { border-color: var(--tita-line); background: var(--tita-surface); }
370
+ }
371
+ .tita-settingsSectionOn { animation: tita-settings-settle 1.6s ease-out both; }
372
+ @media (prefers-reduced-motion: reduce) { .tita-settingsSectionOn { animation: none; } }
373
+ .tita-settingsSectionHeader { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 13px; }
374
+ .tita-settingsSectionHeader h3 { display: inline-flex; align-items: center; gap: 6px; margin: 0; color: var(--tita-ink); font-size: 14px; }
375
+ /*
376
+ * tooltip 面板:这里的说明是整句,要左对齐、可换行、限宽。
377
+ *
378
+ * 选择器**双写同名类**是为了拿到 (0,2,0) 的特异性。UI 包的 tooltip 自带 `max-w-xs`
379
+ * 和 `inline-flex`(320px 宽、不换行),而插件**没有自己的 Tailwind 构建** —— 用工具类
380
+ * 覆盖这条路是走不通的:`max-w-[260px]` 在插件里没有对应规则,而 `cn` 的 twMerge 会先
381
+ * 把 `max-w-xs` 删掉,限宽于是彻底失效(实测宽度从 320px 变成 996px)。双写是这里唯一
382
+ * 与样式表顺序无关的写法。
383
+ *
384
+ * 限宽**不往窄了压**(这里 320px,和 UI 包默认同值):说明要出现在图标**上方**,而第一
385
+ * 小节的标题离视口顶部只有 80 多像素 —— 压到 260px 会多出一行,整块高度超过那段空间,
386
+ * 顶部就被视口裁掉(实测裁了 21px)。让它宽一点、少一行,才既在上方又不被裁。
387
+ */
388
+ .tita-infoHintPanel.tita-infoHintPanel { display: block; max-width: 320px; padding: 8px 12px; line-height: 1.65; text-align: left; white-space: normal; }
389
+ /* 小节标题旁的说明入口:图标常驻、说明悬停才出现(见 `InfoHint`)。 */
390
+ .tita-infoHint { display: inline-flex; width: 16px; height: 16px; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--tita-subtle); cursor: help; }
391
+ .tita-infoHint:hover { background: var(--tita-surface-muted); color: var(--tita-ink-muted); }
392
+ .tita-infoHint:focus-visible { outline: 2px solid var(--tita-blue); outline-offset: 1px; }
393
+ .tita-settingsSectionHeader p { margin: 4px 0 0; color: var(--tita-ink-muted); font-size: 11px; }
394
+ .tita-settingMeta { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 4px; color: var(--tita-ink-faint); font-size: 10px; text-align: right; }
395
+ /* 写失败时那一行不是「状态」,是**待处理的事**,所以给它警示色而不是灰。 */
396
+ .tita-settingMetaBad { color: var(--tita-warning); font-weight: 600; }
397
+ /*
398
+ * 设置项**一列**排。
399
+ *
400
+ * 原来是两列网格,但抽屉只有 380–440px 宽,两列意味着每个控件约 200px;而标签和说明
401
+ * 都是整句中文,换行行数不一致,于是同一行的两个字段高度不同、提示文字错位,「构建设置」
402
+ * 和「知识库召回设置」里还混着占两列的字段(模型路径、Python),最后一列经常空半格 ——
403
+ * 看起来就是没对齐。
404
+ *
405
+ * 一列之后每项的宽度、标签基线、控件左边缘都一致,占两列那个变体也就没有意义了。
406
+ */
407
+ .tita-settingsGrid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
408
+ .tita-settingField { display: grid; min-width: 0; gap: 5px; }
409
+ .tita-settingField > span { color: var(--tita-ink-muted); font-size: 11px; font-weight: 600; }
410
+ .tita-settingField input { width: 100%; min-height: 34px; border: 1px solid var(--tita-line-strong); border-radius: 8px; background: var(--tita-surface); color: var(--tita-ink); padding: 0 9px; font: inherit; font-size: 12px; }
411
+ .tita-settingField input:disabled { background: var(--tita-surface-muted); color: var(--tita-ink-faint); cursor: not-allowed; }
412
+ /* 只读的路径框:它读起来必须像「值」,不像「待填的空」—— 所以底色是沉的,
413
+ 边框是浅的,光标是文本光标(能选中复制)。 */
414
+ .tita-settingField input[readonly] { border-color: var(--tita-line); background: var(--tita-surface-muted); color: var(--tita-ink); cursor: text; }
415
+ /* 开关不该被网格拉伸成整行宽:它是控件本身,不是「一整行」。 */
416
+ .tita-settingField > button[role='switch'] { justify-self: start; }
417
+ /* 字段说明:贴在字段下面,一行小字。 */
418
+ .tita-settingHint { color: var(--tita-ink-faint); font-size: 10px; line-height: 1.5; }
419
+
420
+ /* --------------------------------------------------- 根路径:选择 + 预览 */
421
+ .tita-pickerRow { display: flex; min-width: 0; align-items: center; gap: 8px; }
422
+ .tita-pickerRow input { flex: 1 1 auto; min-width: 0; font-variant-numeric: tabular-nums; }
423
+ .tita-pickerRow button { flex: 0 0 auto; white-space: nowrap; }
424
+ .tita-spin { animation: tita-spin 900ms linear infinite; }
425
+ @keyframes tita-spin { to { transform: rotate(360deg); } }
426
+ @media (prefers-reduced-motion: reduce) { .tita-spin { animation-duration: 3s; } }
427
+
428
+ .tita-layoutPreview { margin-top: 13px; border-top: 1px dashed var(--tita-line); padding-top: 12px; }
429
+ .tita-layoutSegments { display: grid; margin: 0; padding: 0; gap: 8px; list-style: none; }
430
+ .tita-layoutSegments > li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; }
431
+ .tita-layoutSegments code { color: var(--tita-ink); font-size: 11.5px; font-weight: 650; }
432
+ .tita-layoutSegments > li > span { grid-column: 1; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.5; }
433
+ .tita-layoutSegments em { grid-column: 2; grid-row: 1; color: var(--tita-ink-faint); font-size: 10px; font-style: normal; white-space: nowrap; }
434
+ .tita-layoutSegments small { grid-column: 1 / -1; overflow: hidden; color: var(--tita-ink-faint); font-size: 10px; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
435
+ .tita-layoutMigration { margin: 11px 0 0; border-left: 2px solid var(--tita-success); background: var(--tita-surface-muted); padding: 7px 9px; color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.6; }
436
+ .tita-layoutMigrationBad { border-left-color: var(--tita-warning); }
437
+ .tita-layoutMigration code { color: var(--tita-ink); overflow-wrap: anywhere; }
438
+ /* 家当不在 resource/ 下:一条**可操作**的告警,不是状态装饰 —— 所以每条都写清
439
+ 「在哪」与「要做什么」,而不是只报一个数。 */
440
+ .tita-layoutAssets { display: grid; margin: 11px 0 0; gap: 6px; }
441
+ .tita-layoutAssets > p { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--tita-warning); font-size: 11px; }
442
+ .tita-layoutAssets ul { display: grid; margin: 0; padding: 0; gap: 5px; list-style: none; }
443
+ .tita-layoutAssets li { color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.65; }
444
+ .tita-layoutAssets li b { color: var(--tita-ink); font-weight: 650; }
445
+ .tita-layoutAssets code { color: var(--tita-ink); overflow-wrap: anywhere; }
446
+ .tita-layoutError { display: flex; align-items: center; gap: 6px; margin: 11px 0 0; color: var(--tita-warning); font-size: 11px; }
447
+
448
+ /* --------------------------------------------------- Agent 提示词(只读预览) */
449
+ /* 这一块刻意没有输入框:提示词的真源是 preset 的组合文件,这里给的是**视图**。
450
+ 所以正文用等宽块 + 可选中复制,而不是一个看起来能编辑的 textarea。
451
+ 主操作是「打开真源目录」—— 改提示词那件事发生在文件管理器里,不在这里。 */
452
+ .tita-presetFacts { display: grid; margin: 0; gap: 7px; }
453
+ .tita-presetFacts > div { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; border-bottom: 1px solid var(--tita-line); padding-bottom: 6px; }
454
+ .tita-presetFacts > div:last-child { border-bottom: 0; padding-bottom: 0; }
455
+ .tita-presetFacts dt { color: var(--tita-ink-muted); font-size: 11px; }
456
+ .tita-presetFacts dd { display: inline-flex; align-items: baseline; gap: 6px; margin: 0; color: var(--tita-ink); font-size: 11.5px; font-weight: 650; text-align: right; }
457
+ .tita-presetTrust { border: 1px solid var(--tita-line); border-radius: 5px; background: var(--tita-surface-muted); padding: 1px 5px; color: var(--tita-ink-muted); font-size: 9.5px; font-weight: 500; }
458
+ .tita-presetMissing { color: var(--tita-warning); }
459
+ .tita-presetNote { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px; margin: 11px 0 0; color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.65; }
460
+ .tita-presetNote code { border-radius: 4px; background: var(--tita-surface-muted); padding: 1px 4px; color: var(--tita-ink); font-size: 10px; overflow-wrap: anywhere; }
461
+ .tita-presetNoteBad { color: var(--tita-warning); }
462
+ .tita-presetNote > svg { flex: 0 0 auto; align-self: center; color: var(--tita-success); }
463
+ .tita-promptPreview { margin-top: 13px; border: 1px solid var(--tita-line); border-radius: 10px; overflow: hidden; }
464
+ .tita-promptPreviewHead { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; border-bottom: 1px solid var(--tita-line); background: var(--tita-surface-muted); padding: 7px 10px; }
465
+ .tita-promptPreviewHead > span { color: var(--tita-ink); font-size: 11px; font-weight: 650; }
466
+ .tita-promptPreviewHead small { color: var(--tita-ink-faint); font-size: 10px; font-variant-numeric: tabular-nums; }
467
+ /* 正文很长,所以给它自己的滚动区而不是把抽屉撑到几屏高;等宽 + 保留换行让
468
+ 提示词里的编号与缩进读得出来。 */
469
+ .tita-promptBody { max-height: 260px; margin: 0; overflow: auto; background: var(--tita-surface); padding: 10px 11px; color: var(--tita-ink); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10.5px; line-height: 1.7; white-space: pre-wrap; overflow-wrap: anywhere; }
470
+ .tita-promptBody:focus-visible { outline: 2px solid var(--tita-primary); outline-offset: -2px; }
471
+ .tita-presetActions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
472
+ /* 路径本身是**可选中复制**的兜底:宿主拒绝打开这个路径时(`verifyDesktopPath` 不过),
473
+ 用户仍然要能把它拿走自己开。所以它不截断成不可读的省略号 —— 一行放不下就换行,
474
+ 并把完整值放在 `title` 里。 */
475
+ .tita-presetPath { flex: 1 1 220px; min-width: 0; border: 1px solid var(--tita-line); border-radius: 6px; background: var(--tita-surface-muted); padding: 4px 7px; color: var(--tita-ink-muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; line-height: 1.5; overflow-wrap: anywhere; }
476
+ /* `small` 默认是行内盒,直接当段落用会让 `margin-top` 不生效 —— 而它确实是一个段落。 */
477
+ .tita-presetHint { display: block; margin-top: 7px; }
478
+ .tita-presetHint code { border-radius: 4px; background: var(--tita-surface-muted); padding: 1px 4px; color: var(--tita-ink); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; overflow-wrap: anywhere; }
479
+
480
+ /* --------------------------------------------------- 页面内目录浏览(兜底) */
481
+ .tita-browseDialog { display: flex; width: min(680px, calc(100vw - 32px)); max-height: min(560px, calc(100vh - 64px)); flex-direction: column; gap: 10px; }
482
+ .tita-browseCrumbs { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 1px; }
483
+ .tita-browseCrumbWrap { display: inline-flex; align-items: center; gap: 1px; color: var(--tita-ink-faint); }
484
+ .tita-browseCrumb { max-width: 160px; overflow: hidden; border: 0; border-radius: 6px; background: transparent; padding: 3px 6px; color: var(--tita-ink-muted); font: inherit; font-size: 11px; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
485
+ .tita-browseCrumb:hover { background: var(--tita-surface-muted); color: var(--tita-ink); }
486
+ .tita-browseCrumbOn { color: var(--tita-ink); font-weight: 650; }
487
+ .tita-browsePath { overflow: hidden; border: 1px solid var(--tita-line); border-radius: 7px; background: var(--tita-surface-muted); padding: 6px 9px; color: var(--tita-ink); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
488
+ .tita-browseError { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--tita-warning); font-size: 11px; }
489
+ .tita-browseList { flex: 1 1 auto; min-height: 180px; margin: 0; overflow-y: auto; border: 1px solid var(--tita-line); border-radius: 9px; padding: 4px; list-style: none; }
490
+ .tita-browseRow { display: flex; width: 100%; align-items: center; gap: 7px; border: 0; border-radius: 7px; background: transparent; padding: 6px 8px; color: var(--tita-ink); font: inherit; font-size: 12px; text-align: left; cursor: pointer; }
491
+ .tita-browseRow:hover { background: var(--tita-surface-muted); }
492
+ .tita-browseRow > svg { flex: 0 0 auto; color: var(--tita-ink-faint); }
493
+ .tita-browseEmpty { padding: 16px 10px; color: var(--tita-ink-faint); font-size: 11.5px; text-align: center; }
494
+ .tita-browseNote { margin: 0; color: var(--tita-ink-faint); font-size: 10.5px; }
495
+ .tita-browseCreate { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
496
+ .tita-browseCreate input { flex: 1 1 160px; min-width: 0; }
497
+ .tita-browseHidden { display: inline-flex; align-items: center; gap: 5px; color: var(--tita-ink-muted); font-size: 11px; }
498
+
499
+ /* Visually hidden, still focusable: the non-pointer entry point (PRD §12.3). */
500
+ .tita-srOnly { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
501
+ .tita-srOnly:focus-within { position: static; width: auto; height: auto; clip: auto; clip-path: none; white-space: normal; }
502
+ .tita-srOnly ul { margin: 0; padding: 0; list-style: none; }
503
+
504
+ /* ------------------------------- responsive: react to the host pane width */
505
+ @container (max-width: 1080px) {
506
+ .tita-rail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
507
+ .tita-railQuote { grid-column: 1 / -1; }
508
+ .tita-statsRow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
509
+ .tita-evalGrid, .tita-memoryGrid { grid-template-columns: minmax(0, 1fr); }
510
+ .tita-skillGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
511
+ .tita-memoryCardWide { grid-column: auto; }
512
+ }
513
+
514
+ @container (max-width: 700px) {
515
+ .tita-rail { grid-template-columns: minmax(0, 1fr); }
516
+ .tita-statsRow { grid-template-columns: minmax(0, 1fr); }
517
+ .tita-skillGrid { grid-template-columns: minmax(0, 1fr); }
518
+ .tita-skillHero { align-items: flex-start; flex-wrap: wrap; }
519
+ .tita-skillHero > .tita-uiButton { width: 100%; }
520
+ .tita-settingFieldWide { grid-column: auto; }
521
+ .tita-inputRow { align-items: stretch; flex-direction: column; }
522
+ .tita-inputRow .tita-uiButton { width: 100%; }
523
+ }
524
+
525
+ /* Vertical flow once a single lane can no longer hold two nodes per row. */
526
+ @container (max-width: 560px) {
527
+ .tita-laneTrack, .tita-stageTrack { flex-direction: column; align-items: stretch; }
528
+ .tita-flowNode, .tita-flowFork { width: 100%; max-width: none; flex: 0 0 auto; }
529
+ .tita-flowArrow { align-self: center; transform: rotate(90deg); }
530
+ .tita-archBridge { padding: 0; }
531
+ }
532
+
533
+ /* ------------------------------------------- knowledge bases (issue 0019) */
534
+ /* 知识库 Tab:多知识库 + 文件类型 + 文件列表 + 文档详情与版本。 */
535
+ .tita-kbLayout { display: grid; gap: 12px; min-width: 0; }
536
+ .tita-kbToolbar { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
537
+ .tita-kbToolbar > :first-child { flex: 0 1 auto; min-width: 0; }
538
+ /* 动作跟着选择器往左排(0035):这一行只有一个主语(当前知识库)和它的动作。把动作推到
539
+ 最右边,中间会留一段**没有意义的空白**,而在窄栏里那段空白本来能放下第三个按钮。
540
+ 0035 也把计数撤出了这一行 —— 它们没有丢,步骤轨每一步第二行写的就是同一批数字。 */
541
+ .tita-kbToolbarActions { display: flex; flex: 0 0 auto; align-items: center; gap: 8px; }
542
+ /* 三个动作同形(图标 + 文字的 outline 按钮)。内核控制台是一个**链接**,靠 `Button asChild`
543
+ 拿到与按钮同一套外观,所以这里只补锚点自己带进来的下划线。 */
544
+ .tita-kbToolbarActions a.tita-uiButton { text-decoration: none; }
545
+
546
+ .tita-kbNotice { display: flex; align-items: center; gap: 8px; margin: 0; border: 1px solid var(--tita-tone-green-line); border-radius: 9px; background: var(--tita-tone-green-tint); color: var(--tita-success); padding: 8px 10px; font-size: 11.5px; }
547
+ .tita-kbNotice > span { flex: 1; min-width: 0; }
548
+ .tita-kbNoticeError { border-color: var(--ddk-danger-line); background: var(--ddk-danger-tint); color: var(--tita-danger); }
549
+ .tita-kbNoticeClose { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; border: 0; border-radius: 6px; background: transparent; color: inherit; padding: 3px; cursor: pointer; opacity: .7; }
550
+ .tita-kbNoticeClose:hover { opacity: 1; }
551
+
552
+ .tita-kbRoot { overflow: hidden; max-width: 100%; color: var(--tita-ink-faint); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
553
+
554
+ .tita-kbCard { min-width: 0; padding: 15px; }
555
+ .tita-kbCardHead { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
556
+ .tita-kbCardActions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 7px; }
557
+ .tita-kbEyebrow { display: inline-flex; align-items: center; gap: 5px; color: var(--tita-ink-faint); font-size: 9.5px; font-weight: 700; letter-spacing: .09em; }
558
+ .tita-kbCardHead h3 { margin: 3px 0 0; color: var(--tita-ink); font-size: 14px; font-weight: 750; letter-spacing: -.01em; }
559
+ .tita-kbCount { flex: 0 0 auto; color: var(--tita-ink-faint); font-size: 11px; }
560
+ .tita-kbHint { margin: 8px 0 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.65; }
561
+ .tita-kbHint b { color: var(--tita-ink-muted); }
562
+ .tita-kbEmpty { margin: 12px 0 0; border: 1px dashed var(--tita-line); border-radius: 9px; color: var(--tita-ink-faint); padding: 12px; font-size: 11.5px; text-align: center; }
563
+ .tita-kbSubHead { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 16px 0 6px; }
564
+ .tita-kbSubHead h4 { display: inline-flex; align-items: center; gap: 6px; margin: 0; color: var(--tita-ink); font-size: 12px; font-weight: 700; }
565
+ .tita-kbSubHead > span { color: var(--tita-ink-faint); font-size: 10.5px; }
566
+
567
+
568
+ /* 来源业务分类注册表(issue 0013):与「文件类型」同构,额外带一段内置只读判定规则。 */
569
+ .tita-kbSourceList { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 6px; }
570
+ .tita-kbSourceRow { display: grid; grid-template-columns: minmax(0, 1fr) 66px auto auto auto; align-items: center; gap: 8px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 6px 8px; }
571
+ .tita-kbSourceName { display: flex; min-width: 0; align-items: baseline; gap: 6px; overflow: hidden; }
572
+ .tita-kbSourceLabel { overflow: hidden; color: var(--tita-ink); font-size: 12px; font-weight: 620; text-overflow: ellipsis; white-space: nowrap; }
573
+ .tita-kbSourceId { flex: 0 0 auto; color: var(--tita-ink-faint); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; }
574
+ .tita-kbSourceTag { flex: 0 0 auto; border-radius: 4px; background: var(--tita-primary-soft); color: var(--tita-primary); padding: 1px 5px; font-size: 9.5px; }
575
+ .tita-kbSourceTagLock { background: var(--tita-surface-muted); color: var(--tita-ink-faint); }
576
+ .tita-kbPrompt { margin-top: 10px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface-muted); padding: 10px 12px; }
577
+ .tita-kbPrompt > summary { cursor: pointer; color: var(--tita-ink-muted); font-size: 11.5px; font-weight: 650; }
578
+ .tita-kbPromptNote { margin: 8px 0 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.7; }
579
+ .tita-kbPromptSteps { margin: 8px 0 0; padding-left: 18px; color: var(--tita-ink); font-size: 11px; line-height: 1.85; }
580
+ .tita-kbPromptSteps code { border-radius: 4px; background: var(--tita-surface-muted); padding: 0 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; }
581
+ .tita-kbPromptOff { color: var(--tita-danger); text-decoration: line-through; }
582
+ .tita-kbTextarea { width: 100%; min-height: 58px; resize: vertical; border: 1px solid var(--tita-line); border-radius: 8px; background: var(--tita-surface); color: var(--tita-ink); padding: 7px 9px; font-family: inherit; font-size: 11.5px; line-height: 1.6; }
583
+ .tita-kbTextarea:focus { border-color: var(--tita-primary-line); outline: 2px solid var(--tita-focus-ring); }
584
+ .tita-kbSourcePick { display: inline-flex; align-items: center; gap: 6px; color: var(--tita-ink-muted); font-size: 11px; }
585
+ .tita-kbSourcePick select { min-width: 150px; }
586
+ .tita-kbSourceAdd { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
587
+ .tita-kbSourceAdd .tita-kbHint { margin: 0; }
588
+
589
+ /* 筛选行:搜索 · 来源分类 · 文件类型 · 刷新 · 添加文件。
590
+ 0027 之前这里是两行(上传行 + 筛选行),而「来源分类」在两个地方各有一个控件;
591
+ 现在只有一行、一个控件 —— 它同时决定筛什么和按什么收录。 */
592
+ .tita-kbFilterRow { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
593
+ /* 搜索框给上限:它会 grow,不设上限就会把两个下拉和刷新挤到第二行去。
594
+ 两个下拉自己的宽度(`w-auto max-w-[220px]`)在调用处给 —— 盒子归共享组件,
595
+ 这里不再用元素选择器改 `select` 的长相。 */
596
+ .tita-kbFilterRow .tita-kbFilterSearch { flex: 1 1 180px; min-width: 0; max-width: 340px; }
597
+ /* 筛选行下面那行说明:它必须跟着筛选结果走,所以不能写成卡片底部的静态提示。 */
598
+ .tita-kbFilterHint { margin: 8px 0 0; color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.6; }
599
+ .tita-kbFilterHint b { color: var(--tita-ink-muted); font-weight: 650; }
600
+
601
+ .tita-kbDocList { display: grid; margin: 10px 0 0; padding: 0; list-style: none; gap: 4px; }
602
+ .tita-kbDocRow { display: flex; min-width: 0; align-items: center; gap: 6px; border: 1px solid transparent; border-radius: 9px; padding: 2px 4px 2px 0; }
603
+ .tita-kbDocRow:hover { border-color: var(--tita-line); background: var(--tita-surface-muted); }
604
+ .tita-kbDocMain { display: grid; flex: 1 1 auto; min-width: 0; gap: 3px; border: 0; background: transparent; padding: 7px 8px; color: inherit; font: inherit; text-align: left; cursor: pointer; }
605
+ .tita-kbDocTitle { display: flex; min-width: 0; align-items: center; gap: 6px; overflow: hidden; color: var(--tita-ink); font-size: 12px; font-weight: 620; text-overflow: ellipsis; white-space: nowrap; }
606
+ .tita-kbDocMeta { overflow: hidden; color: var(--tita-ink-faint); font-size: 10.5px; text-overflow: ellipsis; white-space: nowrap; }
607
+ .tita-kbDocActions { display: flex; flex: 0 0 auto; align-items: center; gap: 2px; }
608
+
609
+ .tita-kbForm { display: grid; gap: 10px; }
610
+ .tita-kbField { display: grid; gap: 5px; }
611
+ .tita-kbKv { display: grid; margin: 0; gap: 4px; }
612
+ .tita-kbKv > div { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 8px; }
613
+ .tita-kbKv dt { color: var(--tita-ink-faint); font-size: 11px; }
614
+ .tita-kbKv dd { margin: 0; overflow-wrap: anywhere; color: var(--tita-ink); font-size: 11.5px; }
615
+ .tita-kbCode { border-radius: 4px; background: var(--tita-surface-muted); padding: 1px 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; overflow-wrap: anywhere; }
616
+ .tita-kbAssets { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; margin-top: 12px; }
617
+ .tita-kbAsset { margin: 0; border: 1px solid var(--tita-line); border-radius: 8px; padding: 4px; }
618
+ .tita-kbAsset img { display: block; width: 100%; height: 62px; object-fit: contain; }
619
+ .tita-kbAsset figcaption { margin-top: 3px; color: var(--tita-ink-faint); font-size: 10px; text-align: center; }
620
+ /* 原文与卡片正文的阅读态容器(0030):内容由平台 Markdown 原子渲染,所以这里只
621
+ 交代「它在一个窄栏里也要能读」——行高、可断行、首尾外边距归零(上下都有自己的
622
+ 小节标题,留着那段空白只会让抽屉看起来像漏了一格)。内部排版交给渲染器,不在
623
+ 插件里另立一套 Markdown 样式,否则同一个原子在两处会长得不一样。 */
624
+ .tita-kbMarkdown { margin-top: 2px; color: var(--tita-ink); font-size: 12px; line-height: 1.7; overflow-wrap: anywhere; }
625
+ .tita-kbMarkdown > :first-child { margin-top: 0; }
626
+ .tita-kbMarkdown > :last-child { margin-bottom: 0; }
627
+ .tita-kbMarkdown img { max-width: 100%; border-radius: 6px; }
628
+ .tita-kbPre { max-height: 320px; margin: 0; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); color: var(--tita-ink); padding: 10px; overflow: auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10.5px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
629
+
630
+ /* ------------------------------------------------------ intent (issue 0019) */
631
+ .tita-intentHead { display: flex; align-items: center; gap: 8px; }
632
+ .tita-intentHead > :first-child { flex: 1 1 auto; min-width: 0; }
633
+
634
+ /* 意图页的两段式(issue 0023):记录(只读审计流)与配置(预置分类)分成两个 tab,
635
+ 不上下堆叠——配置项不该把记录挤到折叠以下。 */
636
+ .tita-intentSections { display: grid; gap: 12px; }
637
+ .tita-intentSectionBar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
638
+ .tita-intentSectionBar .tita-intentHead { flex: 0 1 auto; }
639
+
640
+ /* 「意图的逻辑」tab:说明性内容,读的是排版而不是控件。 */
641
+ .tita-intentDocList { display: grid; margin: 3px 0 0; padding-left: 18px; gap: 5px; color: var(--tita-ink); font-size: 11.5px; line-height: 1.75; }
642
+ .tita-intentDocList b { color: var(--tita-ink); }
643
+ .tita-intentDocList code, .tita-kbHint code { border-radius: 4px; background: var(--tita-surface-muted); padding: 0 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10.5px; }
644
+ .tita-intentDocGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px; margin-top: 10px; }
645
+ .tita-intentDocGrid > div { display: grid; gap: 3px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 9px 11px; }
646
+ .tita-intentDocGrid strong { color: var(--tita-ink); font-size: 11.5px; }
647
+ .tita-intentDocGrid span { color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.6; }
648
+ .tita-intentDocTableWrap { overflow-x: auto; margin-top: 8px; }
649
+ .tita-intentDocTable { width: 100%; border-collapse: collapse; font-size: 11px; }
650
+ .tita-intentDocTable th { border-bottom: 1px solid var(--tita-line); color: var(--tita-ink-muted); padding: 6px 8px; font-weight: 700; text-align: left; white-space: nowrap; }
651
+ .tita-intentDocTable td { border-bottom: 1px solid var(--tita-surface-muted); color: var(--tita-ink); padding: 6px 8px; line-height: 1.65; vertical-align: top; }
652
+ .tita-intentDocTable td:first-child code { border-radius: 4px; background: var(--tita-surface-muted); padding: 1px 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10.5px; }
653
+ .tita-intentDocTable td:nth-child(2) { color: var(--tita-tone-green); text-align: center; }
654
+ .tita-intentPaperList { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 10px; }
655
+ .tita-intentPaperList > li { border: 1px solid var(--tita-line); border-radius: 8px; background: var(--tita-surface); padding: 9px 11px; }
656
+ .tita-intentPaperList a { color: var(--tita-primary); font-size: 12px; font-weight: 640; text-decoration: none; }
657
+ .tita-intentPaperList a:hover { text-decoration: underline; }
658
+ .tita-intentPaperMeta { display: block; margin-top: 2px; color: var(--tita-ink-faint); font-size: 10px; }
659
+ .tita-intentPaperList p { margin: 6px 0 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.75; }
660
+ .tita-intentPaperNote { color: var(--tita-ink-faint) !important; font-size: 10.5px !important; }
661
+ .tita-intentMetric { display: grid; min-width: 0; gap: 2px; padding: 12px 13px; }
662
+ .tita-intentMetric small { color: var(--tita-ink-faint); font-size: 10.5px; }
663
+ .tita-intentMetric strong { overflow: hidden; color: var(--tita-ink); font-size: 17px; font-weight: 750; letter-spacing: -.02em; text-overflow: ellipsis; white-space: nowrap; }
664
+ .tita-intentMetric em { overflow: hidden; color: var(--tita-ink-faint); font-size: 10px; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }
665
+ .tita-intentTaskList { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 6px; }
666
+ .tita-intentTaskList li { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 7px 9px; }
667
+ .tita-intentTaskId { display: inline-flex; align-items: center; gap: 5px; color: var(--tita-ink-muted); font-size: 11.5px; font-weight: 600; }
668
+ .tita-intentList { display: grid; margin: 10px 0 0; padding: 0; list-style: none; gap: 8px; }
669
+ .tita-intentRow { display: grid; min-width: 0; gap: 5px; border: 1px solid var(--tita-line); border-radius: 10px; background: var(--tita-surface); padding: 9px 10px; }
670
+ .tita-intentRowHead { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
671
+ .tita-intentRelation { color: var(--tita-ink-muted); font-size: 10.5px; }
672
+ .tita-intentTime { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; color: var(--tita-ink-faint); font-size: 10px; }
673
+ .tita-intentInput { margin: 0; color: var(--tita-ink-muted); font-size: 11.5px; line-height: 1.6; overflow-wrap: anywhere; }
674
+ .tita-intentRowFoot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--tita-ink-faint); font-size: 10px; }
675
+ .tita-intentRegistry { display: grid; gap: 12px; margin-top: 10px; }
676
+ .tita-intentRegistry h4 { margin: 0 0 6px; color: var(--tita-ink-muted); font-size: 11px; font-weight: 700; }
677
+ .tita-intentChips { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
678
+ .tita-intentPredicate { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
679
+
680
+ /* Wiki 抽取流程(issue 0024):竖向四段,状态徽标按代码现状标注。 */
681
+ .tita-wikiFlow { display: grid; gap: 0; margin-top: 12px; }
682
+ .tita-wikiFlowSource, .tita-wikiFlowSink { display: flex; align-items: center; gap: 9px; border: 1px dashed var(--tita-line); border-radius: 10px; background: var(--tita-surface-muted); padding: 9px 11px; color: var(--tita-ink-muted); }
683
+ .tita-wikiFlowSink { border-style: solid; border-color: var(--tita-tone-green-line); background: var(--tita-tone-green-tint); color: var(--tita-success); }
684
+ .tita-wikiFlowSource strong, .tita-wikiFlowSink strong { display: block; color: var(--tita-ink); font-size: 11.5px; }
685
+ .tita-wikiFlowSource small, .tita-wikiFlowSink small { display: block; color: var(--tita-ink-faint); font-size: 10px; }
686
+ .tita-wikiFlowStageWrap { display: grid; }
687
+ .tita-wikiFlowArrow { display: flex; align-items: center; justify-content: center; color: var(--tita-ink-faint); padding: 3px 0; }
688
+ /* 阶段卡:整圈发丝线,不用左侧粗色条。阶段身份由卡片自己的状态点与标题承担;
689
+ 左色条既不比一圈细边多给信息,又是 AI 生成界面的典型指纹。 */
690
+ .tita-wikiFlowStage { border: 1px solid var(--tita-line); border-radius: 10px; background: var(--tita-surface); padding: 10px 12px; }
691
+ .tita-wikiFlowStageHead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px; }
692
+ .tita-wikiFlowStageHead strong { color: var(--tita-ink); font-size: 12px; font-weight: 700; }
693
+ .tita-wikiFlowPass { display: inline-flex; align-items: center; gap: 5px; border-radius: 999px; background: var(--tita-surface-muted); padding: 2px 8px; font-size: 10px; font-weight: 700; letter-spacing: .02em; }
694
+ .tita-wikiFlowLlm { margin-left: auto; color: var(--tita-ink-faint); font-size: 10px; }
695
+ .tita-wikiFlowIo { margin: 6px 0 0; color: var(--tita-ink-muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; }
696
+ .tita-wikiFlowBody { display: grid; margin: 6px 0 0; padding-left: 16px; gap: 3px; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.7; }
697
+ .tita-wikiFlowBody code { border-radius: 4px; background: var(--tita-surface-muted); padding: 0 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; }
698
+ .tita-wikiFlowNote { margin: 6px 0 0; color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.6; }
699
+ .tita-wikiFlowBlue { border-left-color: var(--tita-primary); }
700
+ .tita-wikiFlowBlue .tita-wikiFlowPass { background: var(--tita-primary-soft); color: var(--tita-primary); }
701
+ .tita-wikiFlowViolet { border-left-color: var(--tita-tone-violet); }
702
+ .tita-wikiFlowViolet .tita-wikiFlowPass { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
703
+ .tita-wikiFlowGreen { border-left-color: var(--tita-success); }
704
+ .tita-wikiFlowGreen .tita-wikiFlowPass { background: var(--tita-tone-green-tint); color: var(--tita-success); }
705
+ .tita-wikiFlowAmber { border-left-color: var(--tita-warning); }
706
+ .tita-wikiFlowAmber .tita-wikiFlowPass { background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); }
707
+ .tita-wikiFlowRules { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 7px; }
708
+ .tita-wikiFlowRules > li { display: flex; align-items: flex-start; gap: 8px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 8px 10px; }
709
+ .tita-wikiFlowRules > li > span:last-child { display: grid; gap: 2px; }
710
+ .tita-wikiFlowRules strong { color: var(--tita-ink); font-size: 11.5px; }
711
+ .tita-wikiFlowRules small { color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.65; }
712
+ .tita-wikiFlowRuleOrder { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 3px; border-radius: 999px; background: var(--tita-primary-soft); color: var(--tita-primary); padding: 2px 7px; font-size: 10px; font-weight: 700; }
713
+ .tita-wikiFlowDiff { display: flex; align-items: flex-start; gap: 8px; margin-top: 10px; border: 1px dashed var(--tita-line); border-radius: 9px; background: var(--tita-surface); color: var(--tita-ink-muted); padding: 9px 11px; font-size: 10.5px; line-height: 1.7; }
714
+ .tita-wikiFlowDiff b { color: var(--tita-ink-muted); }
715
+
716
+ /* Wiki 类型注册表(issue 0024):这张界面就是"SourceRaw → Wiki"的约束入口。 */
717
+ .tita-wikiTypeBar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px; }
718
+ .tita-wikiTypeMode { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
719
+ .tita-wikiTypeMode > span { display: grid; gap: 1px; }
720
+ .tita-wikiTypeMode strong { color: var(--tita-ink); font-size: 11.5px; }
721
+ .tita-wikiTypeMode small { color: var(--tita-ink-faint); font-size: 10px; }
722
+ .tita-wikiTypeIssueCount { border: 1px solid var(--tita-tone-amber-line); border-radius: 999px; background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); padding: 2px 9px; font-size: 10.5px; }
723
+ .tita-wikiTypeList { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 6px; }
724
+ /*
725
+ * 一行一个类型。**窄栏优先**:这里是 380–420px 的宿主侧边栏,不是宽屏表格。
726
+ *
727
+ * 原来这一行是 6 列 grid,首列 `minmax(200px, auto)`、第三列固定 56px、后面还有
728
+ * 三个 auto 列(开关 + 两个图标按钮):光最小宽度就是
729
+ * 200 + 0 + 56 + 3×28 + 5×8(gap) + 18(padding) ≈ 398px,正好卡满整个面板 ——
730
+ * 于是中间那列说明文字被压成 0 宽,描述和「必填小节」直接看不见,整块看起来就是
731
+ * 「间距异常」。
732
+ *
733
+ * 现在改成 flex:第 1 行是身份 + 操作,说明用 `order: 1` 换到第 2 行占满整宽。
734
+ * 视觉顺序变成「名字 → 操作 → 说明」,而 DOM 顺序仍是「名字 → 说明 → 操作」,
735
+ * 读屏照旧先听到描述。最长的文本拿到整宽才读得下去,第一行也不再有 200px 硬下限。
736
+ */
737
+ .tita-wikiTypeRow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 8px 10px; }
738
+ .tita-wikiTypeName { display: flex; flex: 1 1 auto; min-width: 0; flex-wrap: wrap; align-items: baseline; gap: 6px; }
739
+ .tita-wikiTypeLabel { color: var(--tita-ink); font-size: 12px; font-weight: 620; }
740
+ .tita-wikiTypeTag { flex: 0 0 auto; border-radius: 4px; background: var(--tita-primary-soft); color: var(--tita-primary); padding: 1px 5px; font-size: 9.5px; }
741
+ /* 说明排到最后一行、占满整宽:它是最长的文本,只有整宽才读得下去。 */
742
+ .tita-wikiTypeMeta { order: 1; flex: 1 1 100%; min-width: 0; color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.6; }
743
+ .tita-wikiTypeIssues { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 5px; }
744
+ .tita-wikiTypeIssues li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.6; }
745
+ .tita-wikiTypeIssues code { border-radius: 4px; background: var(--tita-surface-muted); padding: 1px 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; }
746
+ .tita-wikiTypeIssueLevel { border-radius: 4px; background: var(--tita-surface-muted); color: var(--tita-ink-muted); padding: 0 5px; font-size: 9.5px; }
747
+
748
+ /* 意图分类注册表(issue 0023):预置项是模型的匹配依据,所以定义与"例如"要露在行上。 */
749
+ .tita-intentCategoryList { display: grid; margin: 10px 0 0; padding: 0; list-style: none; gap: 6px; }
750
+ .tita-intentCategoryRow { display: grid; grid-template-columns: minmax(210px, auto) minmax(0, 1fr) auto auto auto; align-items: center; gap: 8px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 7px 9px; }
751
+ .tita-intentCategoryName { display: flex; min-width: 0; flex-wrap: wrap; align-items: baseline; gap: 6px; }
752
+ .tita-intentCategoryLabel { color: var(--tita-ink); font-size: 12px; font-weight: 620; }
753
+ .tita-intentCategoryExample { overflow: hidden; min-width: 0; color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.6; text-overflow: ellipsis; white-space: nowrap; }
754
+
755
+ /* --------------------------------------------------- recall routes (3-way) */
756
+ .tita-routeRow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 11px; }
757
+ .tita-routeChip { display: inline-flex; align-items: center; gap: 5px; border: 1px dashed var(--tita-line); border-radius: 999px; background: var(--tita-surface); color: var(--tita-ink-faint); padding: 3px 9px; font-size: 10.5px; }
758
+ .tita-routeChipOn { border-style: solid; border-color: var(--tita-tone-green-line); background: var(--tita-tone-green-tint); color: var(--tita-tone-green); font-weight: 620; }
759
+ /* 降级不是「没跑」,也不是「跑了」:它要能被看见,并且带上原因(芯片的 title)。 */
760
+ .tita-routeChipOff { border-style: solid; border-color: var(--tita-tone-amber-line); background: var(--tita-tone-amber-tint); color: var(--tita-tone-amber); font-weight: 620; }
761
+ .tita-routeBackend { margin-left: auto; color: var(--tita-ink-faint); font-size: 10px; font-weight: 700; letter-spacing: .08em; }
762
+
763
+
764
+ /* 节点指标:顶部链路计数条下沉到节点后的落点(0022)。数字跟着它描述的那个节点走。 */
765
+ .tita-nodeMetrics { display: flex; min-width: 0; flex-wrap: wrap; gap: 4px; }
766
+ .tita-nodeMetric { display: inline-flex; min-width: 0; align-items: baseline; gap: 4px; border: 1px solid var(--tita-line); border-radius: 6px; background: var(--tita-surface); padding: 1px 6px; }
767
+ .tita-nodeMetric small { color: var(--tita-ink-faint); font-size: 9.5px; }
768
+ .tita-nodeMetric b { color: var(--tita-ink); font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
769
+ .tita-flowNodeBadges + .tita-nodeMetrics { margin-top: 1px; }
770
+
771
+ /* 召回测试:作用范围 + 路线/参数 + 命中列表。 */
772
+ .tita-recallTop { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
773
+ .tita-recallScope { display: inline-flex; align-items: center; gap: 6px; color: var(--tita-ink-muted); font-size: 11px; }
774
+ .tita-recallScope b { color: var(--tita-ink); font-weight: 650; }
775
+ .tita-recallControls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
776
+ .tita-recallControls > label, .tita-recallControls > .tita-recallControl { display: inline-flex; align-items: center; gap: 6px; color: var(--tita-ink-muted); font-size: 11px; white-space: nowrap; }
777
+ /* 盒子归共享组件:Input 与 SelectMenu 都按 34px 的字段尺度渲染,所以这里只约束数字框的
778
+ 宽度,不再各写一套边框 / 圆角 / 字号 —— 那正是「同一个控件两种长相」的来源。 */
779
+ .tita-recallControls input { width: 68px; }
780
+ .tita-hitList { display: grid; margin: 12px 0 0; padding: 0; list-style: none; gap: 8px; }
781
+ .tita-hitRow { display: grid; min-width: 0; gap: 5px; border: 1px solid var(--tita-line); border-radius: 10px; background: var(--tita-surface); padding: 9px 10px; }
782
+ .tita-hitRow:hover { border-color: var(--tita-line); background: var(--tita-surface); }
783
+ .tita-hitHead { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 6px; }
784
+ .tita-hitTitle { min-width: 0; overflow: hidden; color: var(--tita-ink); font-size: 11.5px; font-weight: 640; text-overflow: ellipsis; white-space: nowrap; }
785
+ .tita-hitRoute { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 3px; border-radius: 999px; padding: 1px 7px; font-size: 9.5px; font-weight: 700; letter-spacing: .04em; }
786
+ .tita-hitRouteFts { background: var(--tita-primary-soft); color: var(--tita-primary); }
787
+ .tita-hitRouteVector { background: var(--tita-tone-violet-tint); color: var(--tita-tone-violet); }
788
+ .tita-hitRouteGraph { background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
789
+ .tita-hitRouteHybrid { background: var(--tita-tone-amber-tint); color: var(--tita-warning); }
790
+ .tita-hitScore { margin-left: auto; color: var(--tita-ink-faint); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; }
791
+ .tita-hitSnippet { margin: 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.6; overflow-wrap: anywhere; }
792
+ .tita-hitFoot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--tita-ink-faint); font-size: 10px; }
793
+
794
+ /* 意图:从最近记录里归纳出的分布(act / 分类 / 低置信度)。 */
795
+ .tita-distList { display: grid; gap: 7px; margin: 10px 0 0; }
796
+ .tita-distRow { display: grid; grid-template-columns: minmax(56px, 96px) minmax(0, 1fr) 34px; align-items: center; gap: 8px; }
797
+ .tita-distRow > span { overflow: hidden; color: var(--tita-ink-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
798
+ .tita-distBar { height: 7px; overflow: hidden; border-radius: 999px; background: var(--tita-surface-muted); }
799
+ .tita-distBar > i { display: block; height: 100%; border-radius: 999px; background: var(--tita-tone-violet); }
800
+ .tita-distBarFts > i { background: var(--tita-primary); }
801
+ .tita-distBarGraph > i { background: var(--tita-tone-green); }
802
+ .tita-distCount { color: var(--tita-ink-faint); font-size: 10.5px; text-align: right; }
803
+
804
+ /* 记忆:真实落盘计数(04_memory)与「示意」卡片分开摆,避免把占位数字读成真实数据。 */
805
+ .tita-memoryReal { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
806
+
807
+ /* 知识库文档详情:该文档编译出的 wiki 卡片(对应 WeKnora 的「分块」列表)。 */
808
+ .tita-cardList { display: grid; margin: 8px 0 0; padding: 0; list-style: none; gap: 6px; }
809
+ .tita-cardRow { display: grid; min-width: 0; gap: 4px; border: 1px solid var(--tita-line); border-radius: 9px; background: var(--tita-surface); padding: 8px 9px; }
810
+ .tita-cardRowHead { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: 6px; }
811
+ .tita-cardRowTitle { min-width: 0; overflow: hidden; color: var(--tita-ink); font-size: 11.5px; font-weight: 620; text-overflow: ellipsis; white-space: nowrap; }
812
+ .tita-cardRowText { margin: 0; color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.6; overflow-wrap: anywhere; }
813
+ /* 0025:卡片行变成可点入口(点开看内容与版本)。按钮要抹掉浏览器默认外观,
814
+ 同时保留 `.tita-cardRow` 的网格排版 —— 否则文字会掉到按钮默认的居中样式里。 */
815
+ .tita-cardRowMain { display: grid; width: 100%; gap: 4px; border: 0; background: none; padding: 0; color: inherit; font: inherit; text-align: left; cursor: pointer; }
816
+ .tita-cardRow:hover { border-color: var(--tita-line); background: var(--tita-surface); }
817
+
818
+ /* 知识库的步骤轨:**一条流水线,不是一排并列的 tab**。
819
+ 收录 → 编译 → 关联 → 检索 → 精排,步与步之间用箭头连起来 —— 方向本身就是信息
820
+ (写入侧在左、读取侧在右),而一排等宽按钮把它抹掉了。
821
+ 窄栏下换行而不是横向滚动:藏起来的那两步等于不存在。 */
822
+ .tita-kbSteps { display: flex; min-width: 0; flex-wrap: wrap; align-items: stretch; gap: 4px; }
823
+ .tita-kbStepArrow { display: inline-flex; flex: 0 0 auto; align-items: center; color: var(--tita-line-strong); }
824
+ .tita-kbStep {
825
+ display: grid;
826
+ /* `box-sizing` 显式写死:这一步的基准宽是 132px,而 padding + border 有 20px。
827
+ content-box 下外层变成 152px,五步就是 844px > 816px 可用宽 —— 于是第五步被挤到
828
+ 第二行,行尾还留一个指向空处的箭头(实测就是这个问题,不是基准宽不够)。 */
829
+ box-sizing: border-box;
830
+ min-width: 0;
831
+ /* 132px 的基准让五步在宿主侧栏(约 810px 可用)里排成**一行**:
832
+ 5×132 + 4 个箭头 + 间距 ≈ 744 < 810。换行会在行尾留一个指向空处的箭头,
833
+ 而 150px 的基准就会换行。窄到排不下时才换 —— 那时名字仍然完整(两行版式)。 */
834
+ flex: 1 1 132px;
835
+ gap: 2px;
836
+ border: 1px solid var(--tita-line);
837
+ border-radius: 9px;
838
+ background: var(--tita-surface);
839
+ padding: 7px 9px;
840
+ color: inherit;
841
+ font: inherit;
842
+ text-align: left;
843
+ cursor: pointer;
844
+ transition: border-color 140ms ease, background 140ms ease;
845
+ }
846
+ .tita-kbStep:hover { border-color: var(--tita-line-strong); background: var(--tita-surface-muted); }
847
+ .tita-kbStep:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }
848
+ /* 当前步:不是「已选中」的高亮,而是「你现在站在这一段的哪一格」。
849
+ 用左侧 3px 强调条之外的整圈描边 + 浅底来表达,避免和卡片套卡片混在一起。 */
850
+ .tita-kbStepOn { border-color: var(--tita-primary); background: var(--tita-primary-soft); box-shadow: inset 0 0 0 1px var(--tita-primary); }
851
+ .tita-kbStepTop { display: flex; min-width: 0; align-items: center; gap: 5px; color: var(--tita-ink); }
852
+ .tita-kbStepTop svg { flex: 0 0 auto; color: var(--tita-ink-faint); }
853
+ .tita-kbStepOn .tita-kbStepTop svg { color: var(--tita-primary); }
854
+ .tita-kbStepTop b { min-width: 0; overflow: hidden; font-size: 12px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
855
+ .tita-kbStepVerb { flex: 0 0 auto; border-radius: 4px; background: var(--tita-surface-muted); color: var(--tita-ink-muted); padding: 0 4px; font-size: 9.5px; font-style: normal; font-weight: 650; }
856
+ .tita-kbStepOn .tita-kbStepVerb { background: var(--tita-primary-soft); color: var(--tita-primary); }
857
+ /* 第二行:这一段的真实计数(醒目)+ 它做什么(次要,放不下就省略)。 */
858
+ .tita-kbStepFacts { display: flex; min-width: 0; align-items: baseline; gap: 5px; }
859
+ .tita-kbStepValue { flex: 0 0 auto; color: var(--tita-ink); font-size: 10px; font-weight: 650; white-space: nowrap; font-variant-numeric: tabular-nums; }
860
+ /* 说明前面加一枚分隔点:`topK 10` 和 `hybrid 三路融合` 直接相邻会读成 `10hybrid`。 */
861
+ .tita-kbStepNote { min-width: 0; overflow: hidden; color: var(--tita-ink-faint); font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
862
+ .tita-kbStepNote::before { content: '·'; margin-right: 5px; color: var(--tita-line-strong); }
863
+
864
+ /* 设置抽屉里两组设置之间留一口气:它们是两块独立的面板,不该贴在一起。 */
865
+ .tita-settingsStack { display: grid; gap: 14px; }
866
+
867
+ /* 知识图谱分栏:列的是可核对的节点 / 边清单,不在这里再画一张图。 */
868
+ .tita-graphList { display: grid; gap: 4px; margin: 10px 0 0; padding: 0; list-style: none; }
869
+ .tita-graphRow { display: flex; min-width: 0; align-items: center; gap: 8px; border: 1px solid var(--tita-line); border-radius: 8px; background: var(--tita-surface); padding: 6px 9px; }
870
+ .tita-graphTitle { min-width: 0; flex: 1 1 auto; overflow: hidden; color: var(--tita-ink); font-size: 11.5px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
871
+ .tita-graphArrow { color: var(--tita-ink-faint); font-size: 11px; }
872
+
873
+ /* 重排分栏:进入上下文包的 topN。序号是它的阅读顺序,所以用等宽数字列。 */
874
+ .tita-contextList { display: grid; gap: 8px; margin: 12px 0 0; padding: 0; list-style: none; }
875
+ .tita-contextRow { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 9px; border: 1px solid var(--tita-line); border-radius: 10px; background: var(--tita-surface); padding: 9px 10px; }
876
+ .tita-contextRank { display: inline-flex; height: 20px; align-items: center; justify-content: center; border-radius: 6px; background: var(--tita-primary-soft); color: var(--tita-primary); font-size: 10.5px; font-weight: 700; }
877
+ .tita-contextCopy { display: grid; min-width: 0; gap: 4px; }
878
+ .tita-contextHead { display: flex; min-width: 0; align-items: center; gap: 6px; }
879
+
880
+ /* ======================================================================
881
+ 台账世界的基线(issues/0026)
882
+ ----------------------------------------------------------------------
883
+ 这一段管的是「我们没有画、但它照样在交付设计」的那些部分:选区、光标、
884
+ 滚动条、焦点环、下划线偏移、数字的字形。它们全部来自浏览器默认值,属于任何
885
+ 设计系统之外——也正因如此,它们是「这个界面被建造过」最便宜的证据。
886
+ ====================================================================== */
887
+
888
+ /* 标题与正文同一个无衬线族,层级只靠字重与字号 —— 专业工具界面里没有第二种字体。
889
+ (0026 曾经在这里上宋体,那是把「台账」做成了「文学」。) */
890
+ .tita-panel h1,
891
+ .tita-panel h2,
892
+ .tita-panel h3,
893
+ .tita-panel h4 { font-family: var(--font-tita); font-weight: 700; letter-spacing: 0; }
894
+
895
+ /* 标题里的图标:icon 直接进标题,不再在标题上方另起一个英文小标签。
896
+ kicker 不增加信息,只增加一层要读的东西 —— 一个中文标题上面顶一行
897
+ 「SOURCE RAW」「INGEST SETTINGS」,读者得先跳过它才知道自己在看什么。 */
898
+ .tita-panel h2 > svg,
899
+ .tita-panel h3 > svg { margin-right: 6px; vertical-align: -2px; color: var(--tita-ink-faint); }
900
+
901
+ /* 数字、id、版本号:等宽 + tabular。它们是**测量值**,不是"技术感"的装饰,
902
+ 所以列与列之间的数字必须对齐。 */
903
+ .tita-kbCode,
904
+ .tita-panel code,
905
+ .tita-hitScore,
906
+ .tita-archPanelRecords dd,
907
+ .tita-infoList strong,
908
+ .tita-metricCopy strong,
909
+ .tita-archPanelMetric b,
910
+ .tita-archBarCounts { font-variant-numeric: tabular-nums; }
911
+ .tita-panel code, .tita-kbCode { font-family: var(--font-tita-mono); }
912
+
913
+ /* 选区:纸上的墨。默认的浏览器蓝会把台账的暖底打穿。 */
914
+ .tita-panel ::selection { background: var(--tita-primary-soft); color: var(--tita-ink); }
915
+
916
+ /* 光标用墨色,不用朱红——朱红在这个世界里只有一个含义(改动 / 异常 / 待实现),
917
+ 光标不是"改动"。 */
918
+ .tita-panel input,
919
+ .tita-panel textarea { caret-color: var(--tita-ink); }
920
+
921
+ /* 焦点环:墨色实线 + 偏移,像在纸上框出这一栏。不靠色相,也就不和朱红的语义打架。
922
+ 0035:抽屉走 Portal,**不在 `.tita-panel` 里** —— 只写 `.tita-panel :focus-visible`
923
+ 会让浮层退回浏览器默认的焦点环(一条不属于这套配色的蓝色 `auto` 描边),而它恰好
924
+ 是打开预览抽屉时第一个被自动聚焦的地方(schema 待补的 `<summary>`)。所以浮层
925
+ 显式共用同一条规则。 */
926
+ .tita-panel :focus-visible,
927
+ .tita-drawer :focus-visible,
928
+ .tita-settingsDrawer :focus-visible { outline: 2px solid var(--tita-ink); outline-offset: 2px; border-radius: 4px; }
929
+
930
+ /* 链接:下划线偏移与粗细也属于设计系统的一部分。 */
931
+ .tita-panel a { text-underline-offset: 2px; text-decoration-thickness: 1px; }
932
+
933
+ /* 滚动条:插件自己拥有滚动区(`.tita-content` 是唯一纵向滚动条),
934
+ 所以它必须从调色板上色,否则整块纸底会贴着一根系统灰条。 */
935
+ .tita-panel * { scrollbar-width: thin; scrollbar-color: var(--tita-line-strong) transparent; }
936
+ .tita-panel ::-webkit-scrollbar { width: 10px; height: 10px; }
937
+ .tita-panel ::-webkit-scrollbar-track { background: transparent; }
938
+ .tita-panel ::-webkit-scrollbar-thumb { border: 3px solid transparent; border-radius: 999px; background-clip: content-box; background-color: var(--tita-line-strong); }
939
+ .tita-panel ::-webkit-scrollbar-thumb:hover { background-color: var(--tita-ink-faint); }
940
+ .tita-panel ::-webkit-scrollbar-corner { background: transparent; }