@icen.ai/ui 0.9.0 → 0.10.0

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 (281) hide show
  1. package/AGENTS.md +138 -80
  2. package/README.md +66 -91
  3. package/dist/base.css +208 -179
  4. package/dist/behaviors/accordion.mjs +8 -8
  5. package/dist/behaviors/ai-branch.d.mts +1 -1
  6. package/dist/behaviors/ai-branch.mjs +1010 -94
  7. package/dist/behaviors/ai-chat.d.mts +7 -7
  8. package/dist/behaviors/ai-chat.mjs +1071 -161
  9. package/dist/behaviors/ai-composer.d.mts +44 -12
  10. package/dist/behaviors/ai-composer.mjs +1997 -524
  11. package/dist/behaviors/ai-core.d.mts +1 -1
  12. package/dist/behaviors/ai-core.mjs +1016 -107
  13. package/dist/behaviors/ai-diff.mjs +1019 -127
  14. package/dist/behaviors/ai-feedback.d.mts +1 -1
  15. package/dist/behaviors/ai-feedback.mjs +1035 -126
  16. package/dist/behaviors/ai-panel.d.mts +8 -8
  17. package/dist/behaviors/ai-panel.mjs +1284 -266
  18. package/dist/behaviors/ai-provider.mjs +1003 -101
  19. package/dist/behaviors/ai-threads.d.mts +1 -1
  20. package/dist/behaviors/ai-threads.mjs +1068 -154
  21. package/dist/behaviors/ai-tool.d.mts +2 -2
  22. package/dist/behaviors/ai-tool.mjs +2037 -396
  23. package/dist/behaviors/ai-tools.d.mts +89 -16
  24. package/dist/behaviors/ai-tools.mjs +4448 -372
  25. package/dist/behaviors/autocomplete.d.mts +53 -0
  26. package/dist/behaviors/autocomplete.mjs +1600 -0
  27. package/dist/behaviors/back-top.d.mts +1 -1
  28. package/dist/behaviors/back-top.mjs +951 -14
  29. package/dist/behaviors/carousel.d.mts +1 -1
  30. package/dist/behaviors/carousel.mjs +906 -11
  31. package/dist/behaviors/cascader.d.mts +48 -0
  32. package/dist/behaviors/cascader.mjs +1853 -0
  33. package/dist/behaviors/charts.d.mts +72 -8
  34. package/dist/behaviors/charts.mjs +1901 -256
  35. package/dist/behaviors/code-block.d.mts +36 -0
  36. package/dist/behaviors/code-block.mjs +1611 -0
  37. package/dist/behaviors/command-palette.d.mts +9 -6
  38. package/dist/behaviors/command-palette.mjs +161 -59
  39. package/dist/behaviors/context-menu.d.mts +9 -8
  40. package/dist/behaviors/context-menu.mjs +1112 -44
  41. package/dist/behaviors/controls.d.mts +13 -13
  42. package/dist/behaviors/controls.mjs +989 -130
  43. package/dist/behaviors/copy.d.mts +21 -2
  44. package/dist/behaviors/copy.mjs +1206 -42
  45. package/dist/behaviors/datatable.d.mts +53 -3
  46. package/dist/behaviors/datatable.mjs +1963 -207
  47. package/dist/behaviors/date-picker.d.mts +0 -1
  48. package/dist/behaviors/date-picker.mjs +1340 -293
  49. package/dist/behaviors/design.d.mts +54 -0
  50. package/dist/behaviors/design.mjs +109 -0
  51. package/dist/behaviors/dropdown.d.mts +5 -6
  52. package/dist/behaviors/dropdown.mjs +262 -110
  53. package/dist/behaviors/events.d.mts +120 -3
  54. package/dist/behaviors/events.mjs +47 -2
  55. package/dist/behaviors/feedback.d.mts +30 -0
  56. package/dist/behaviors/feedback.mjs +296 -0
  57. package/dist/behaviors/focus.d.mts +8 -0
  58. package/dist/behaviors/focus.mjs +24 -0
  59. package/dist/behaviors/form-validate.d.mts +102 -0
  60. package/dist/behaviors/form-validate.mjs +6091 -0
  61. package/dist/behaviors/i18n.d.mts +789 -0
  62. package/dist/behaviors/i18n.mjs +1711 -0
  63. package/dist/behaviors/icons.d.mts +93 -0
  64. package/dist/behaviors/icons.mjs +113 -0
  65. package/dist/behaviors/input.d.mts +9 -1
  66. package/dist/behaviors/input.mjs +1056 -60
  67. package/dist/behaviors/kb-access.d.mts +1 -1
  68. package/dist/behaviors/kb-access.mjs +2129 -239
  69. package/dist/behaviors/kb-acl.d.mts +6 -6
  70. package/dist/behaviors/kb-acl.mjs +1119 -179
  71. package/dist/behaviors/kb-answer.mjs +2070 -418
  72. package/dist/behaviors/kb-audit.d.mts +1 -1
  73. package/dist/behaviors/kb-audit.mjs +1076 -154
  74. package/dist/behaviors/kb-canvas.mjs +1100 -177
  75. package/dist/behaviors/kb-chain.mjs +1022 -100
  76. package/dist/behaviors/kb-checkpoint.d.mts +1 -1
  77. package/dist/behaviors/kb-checkpoint.mjs +1319 -169
  78. package/dist/behaviors/kb-chunks.mjs +1152 -213
  79. package/dist/behaviors/kb-citation.d.mts +1 -1
  80. package/dist/behaviors/kb-citation.mjs +1201 -179
  81. package/dist/behaviors/kb-clarify.mjs +1058 -130
  82. package/dist/behaviors/kb-conflict.mjs +1041 -119
  83. package/dist/behaviors/kb-connector.mjs +1104 -176
  84. package/dist/behaviors/kb-core.d.mts +6 -1
  85. package/dist/behaviors/kb-core.mjs +1077 -162
  86. package/dist/behaviors/kb-eval.mjs +1971 -144
  87. package/dist/behaviors/kb-explain.d.mts +1 -1
  88. package/dist/behaviors/kb-explain.mjs +1024 -102
  89. package/dist/behaviors/kb-filter.mjs +2008 -178
  90. package/dist/behaviors/kb-gap.d.mts +1 -1
  91. package/dist/behaviors/kb-gap.mjs +1043 -121
  92. package/dist/behaviors/kb-hittest.d.mts +1 -1
  93. package/dist/behaviors/kb-hittest.mjs +1093 -150
  94. package/dist/behaviors/kb-metadata.mjs +1052 -130
  95. package/dist/behaviors/kb-passage.d.mts +2 -2
  96. package/dist/behaviors/kb-passage.mjs +1101 -161
  97. package/dist/behaviors/kb-pipeline.d.mts +2 -2
  98. package/dist/behaviors/kb-pipeline.mjs +1082 -162
  99. package/dist/behaviors/kb-qa.mjs +1088 -160
  100. package/dist/behaviors/kb-rerank.mjs +1047 -114
  101. package/dist/behaviors/kb-retrieval.mjs +2063 -224
  102. package/dist/behaviors/kb-review.mjs +1990 -159
  103. package/dist/behaviors/kb-sandbox.d.mts +1 -1
  104. package/dist/behaviors/kb-sandbox.mjs +1026 -104
  105. package/dist/behaviors/kb-segment.mjs +1111 -179
  106. package/dist/behaviors/kb-select.d.mts +24 -0
  107. package/dist/behaviors/kb-select.mjs +1989 -0
  108. package/dist/behaviors/kb-sources.d.mts +1 -1
  109. package/dist/behaviors/kb-sources.mjs +1084 -170
  110. package/dist/behaviors/kb-sql.d.mts +1 -1
  111. package/dist/behaviors/kb-sql.mjs +1143 -226
  112. package/dist/behaviors/kb-trace.d.mts +1 -1
  113. package/dist/behaviors/kb-trace.mjs +1042 -128
  114. package/dist/behaviors/kb-visibility.mjs +1086 -158
  115. package/dist/behaviors/kb-who-can.mjs +1974 -137
  116. package/dist/behaviors/mentions.d.mts +93 -0
  117. package/dist/behaviors/mentions.mjs +2152 -0
  118. package/dist/behaviors/modal.d.mts +4 -3
  119. package/dist/behaviors/modal.mjs +1055 -33
  120. package/dist/behaviors/nav.d.mts +1 -1
  121. package/dist/behaviors/nav.mjs +6 -6
  122. package/dist/behaviors/notification.d.mts +16 -8
  123. package/dist/behaviors/notification.mjs +1615 -265
  124. package/dist/behaviors/panel.d.mts +4 -0
  125. package/dist/behaviors/panel.mjs +994 -0
  126. package/dist/behaviors/popover.d.mts +28 -5
  127. package/dist/behaviors/popover.mjs +225 -24
  128. package/dist/behaviors/select.d.mts +5 -2
  129. package/dist/behaviors/select.mjs +1410 -117
  130. package/dist/behaviors/sidebar.d.mts +1 -1
  131. package/dist/behaviors/sidebar.mjs +13 -13
  132. package/dist/behaviors/slider.d.mts +1 -1
  133. package/dist/behaviors/slider.mjs +9 -9
  134. package/dist/behaviors/split-pane.d.mts +1 -1
  135. package/dist/behaviors/split-pane.mjs +7 -7
  136. package/dist/behaviors/suggestions.d.mts +27 -0
  137. package/dist/behaviors/suggestions.mjs +1089 -0
  138. package/dist/behaviors/svg-parse.d.mts +14 -0
  139. package/dist/behaviors/svg-parse.mjs +37 -0
  140. package/dist/behaviors/tabs.d.mts +2 -2
  141. package/dist/behaviors/tabs.mjs +25 -25
  142. package/dist/behaviors/tag-input.d.mts +23 -5
  143. package/dist/behaviors/tag-input.mjs +1359 -104
  144. package/dist/behaviors/theme-switcher.d.mts +24 -0
  145. package/dist/behaviors/theme-switcher.mjs +1981 -0
  146. package/dist/behaviors/theme.d.mts +15 -8
  147. package/dist/behaviors/theme.mjs +390 -28
  148. package/dist/behaviors/toast.d.mts +24 -25
  149. package/dist/behaviors/toast.mjs +1266 -88
  150. package/dist/behaviors/tooltip.d.mts +4 -0
  151. package/dist/behaviors/tooltip.mjs +378 -0
  152. package/dist/behaviors/tree-select.d.mts +69 -0
  153. package/dist/behaviors/tree-select.mjs +1907 -0
  154. package/dist/behaviors/tree.d.mts +1 -1
  155. package/dist/behaviors/tree.mjs +15 -15
  156. package/dist/behaviors/upload.d.mts +3 -2
  157. package/dist/behaviors/upload.mjs +1076 -66
  158. package/dist/cli.mjs +5 -6
  159. package/dist/components/ai-chat.css +666 -573
  160. package/dist/components/ai-diff.css +153 -132
  161. package/dist/components/ai-panel.css +351 -343
  162. package/dist/components/ai-tool.css +393 -238
  163. package/dist/components/autocomplete.css +61 -0
  164. package/dist/components/autocomplete.mjs +3 -0
  165. package/dist/components/back-top.css +34 -31
  166. package/dist/components/badge.css +44 -41
  167. package/dist/components/breadcrumb.css +67 -46
  168. package/dist/components/btn.css +80 -74
  169. package/dist/components/card.css +117 -106
  170. package/dist/components/cascader.css +311 -0
  171. package/dist/components/cascader.mjs +3 -0
  172. package/dist/components/chart-area.css +8 -2
  173. package/dist/components/chart-bar.css +95 -33
  174. package/dist/components/chart-gauge.css +14 -11
  175. package/dist/components/chart-graph.css +20 -17
  176. package/dist/components/chart-heatmap.css +96 -90
  177. package/dist/components/chart-line.css +8 -3
  178. package/dist/components/chart-pie.css +9 -6
  179. package/dist/components/chart-radar.css +8 -5
  180. package/dist/components/chart-scatter.css +9 -6
  181. package/dist/components/chart-sparkline.css +5 -2
  182. package/dist/components/chart-stack.css +14 -11
  183. package/dist/components/charts.css +164 -73
  184. package/dist/components/code-block.css +418 -0
  185. package/dist/components/code-block.mjs +4 -0
  186. package/dist/components/command-palette.css +138 -117
  187. package/dist/components/content.css +257 -251
  188. package/dist/components/copy.css +72 -44
  189. package/dist/components/datatable.css +423 -181
  190. package/dist/components/date-picker.css +135 -104
  191. package/dist/components/empty.css +68 -65
  192. package/dist/components/feedback.css +201 -183
  193. package/dist/components/form-validate.css +120 -0
  194. package/dist/components/form-validate.mjs +3 -0
  195. package/dist/components/form.css +150 -127
  196. package/dist/components/icon.css +102 -0
  197. package/dist/components/icon.mjs +3 -0
  198. package/dist/components/input.css +159 -104
  199. package/dist/components/kb-agent.css +188 -173
  200. package/dist/components/kb-data.css +257 -253
  201. package/dist/components/kb-ground.css +197 -185
  202. package/dist/components/kb-ingest.css +334 -350
  203. package/dist/components/kb-ops.css +265 -259
  204. package/dist/components/kb-perm.css +260 -271
  205. package/dist/components/kb-search.css +317 -360
  206. package/dist/components/kb.css +120 -109
  207. package/dist/components/layout.css +85 -82
  208. package/dist/components/material-chinese.css +73 -0
  209. package/dist/components/material-soviet.css +76 -0
  210. package/dist/components/material.css +275 -0
  211. package/dist/components/media.css +220 -166
  212. package/dist/components/mentions.css +189 -0
  213. package/dist/components/mentions.mjs +3 -0
  214. package/dist/components/menu.css +113 -105
  215. package/dist/components/modal.css +107 -112
  216. package/dist/components/nav.css +118 -115
  217. package/dist/components/notification.css +238 -174
  218. package/dist/components/pagination.css +56 -53
  219. package/dist/components/panel.css +66 -63
  220. package/dist/components/panel.mjs +1 -0
  221. package/dist/components/pill.css +81 -71
  222. package/dist/components/popover.css +67 -53
  223. package/dist/components/scroll-area.css +113 -110
  224. package/dist/components/segmented.css +146 -143
  225. package/dist/components/select.css +206 -186
  226. package/dist/components/sidebar.css +137 -127
  227. package/dist/components/slider.css +117 -114
  228. package/dist/components/split-pane.css +112 -109
  229. package/dist/components/stat.css +112 -106
  230. package/dist/components/steps.css +109 -103
  231. package/dist/components/switch.css +138 -134
  232. package/dist/components/table.css +131 -107
  233. package/dist/components/tabs.css +114 -108
  234. package/dist/components/tag-input.css +48 -133
  235. package/dist/components/tag.css +81 -71
  236. package/dist/components/theme-switcher.css +105 -0
  237. package/dist/components/theme-switcher.mjs +3 -0
  238. package/dist/components/toast.css +100 -86
  239. package/dist/components/toolbar.css +45 -42
  240. package/dist/components/tooltip.css +102 -43
  241. package/dist/components/tooltip.mjs +1 -0
  242. package/dist/components/tree-select.css +416 -0
  243. package/dist/components/tree-select.mjs +3 -0
  244. package/dist/components/upload.css +135 -92
  245. package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
  246. package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
  247. package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
  248. package/dist/fonts/OFL.txt +96 -0
  249. package/dist/fonts/README.md +14 -0
  250. package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
  251. package/dist/index.d.mts +28 -14
  252. package/dist/index.mjs +20705 -9601
  253. package/dist/react.d.mts +91 -0
  254. package/dist/react.mjs +8208 -0
  255. package/dist/registry.json +130 -13
  256. package/dist/tokens/chinese.css +44 -0
  257. package/dist/tokens/colors.css +365 -1222
  258. package/dist/tokens/design.css +109 -0
  259. package/dist/tokens/dtcg.json +11198 -0
  260. package/dist/tokens/figma.variables.json +7017 -0
  261. package/dist/tokens/icon-masks.css +78 -0
  262. package/dist/tokens/pixel.css +50 -0
  263. package/dist/tokens/soviet.css +44 -0
  264. package/dist/tokens/style-profiles.css +36 -547
  265. package/dist/tokens/themes.json +308 -0
  266. package/dist/tokens/tokens-studio.json +6728 -0
  267. package/dist/tokens/typography.css +21 -18
  268. package/dist/tokens.css +1555 -1801
  269. package/dist/ui.css +11975 -9831
  270. package/dist/vue.d.mts +344 -0
  271. package/dist/vue.mjs +7781 -0
  272. package/docs/spec/ai-input-experience.md +75 -0
  273. package/docs/spec/ai-native.md +238 -147
  274. package/docs/spec/design-philosophy.md +189 -0
  275. package/docs/spec/design-primitives.md +196 -0
  276. package/docs/spec/kb-family.md +147 -115
  277. package/package.json +43 -8
  278. package/dist/retro-effects.css +0 -255
  279. package/dist/tokens/retro-effects.css +0 -255
  280. package/docs/research/2026-10-03-ai-kb-components.md +0 -392
  281. package/docs/research/2026-10-03-kb-permissions.md +0 -992
@@ -1,51 +1,52 @@
1
+ @layer icen.components {
1
2
  /*
2
- * @icen.ai/ui — Component: ai-tool(AI 工具调用卡 + 子智能体卡;含 .ai-item 条目基元完整定义)
3
+ * @icen.ai/ui — Component: ai-tool(AI 工具调用卡 + 子智能体卡;含 .icen-ai-item 条目基元完整定义)
3
4
  *
4
5
  * 完整契约:
5
- * ── 条目基元 .ai-item(规格 §2 骨架:所有行式 AI 条目的"基类",todo/panel 亦复用)──
6
- * <div class="ai-item is-running" style="--ai-item-tint: var(--token-accent)">
7
- * <span class="ai-item-icon"><!-- svg --></span>
8
- * <div class="ai-item-main">
9
- * <div class="ai-item-title">一行摘要</div>
10
- * <div class="ai-item-sub">次要信息(路径/参数)</div>
6
+ * ── 条目基元 .icen-ai-item(规格 §2 骨架:所有行式 AI 条目的"基类",todo/panel 亦复用)──
7
+ * <div class="icen-ai-item is-running" style="--ai-item-tint: var(--icen-token-accent)">
8
+ * <span class="icen-ai-item-icon"><!-- svg --></span>
9
+ * <div class="icen-ai-item-main">
10
+ * <div class="icen-ai-item-title">一行摘要</div>
11
+ * <div class="icen-ai-item-sub">次要信息(路径/参数)</div>
11
12
  * </div>
12
- * <div class="ai-item-side">
13
- * <span class="ai-item-status"></span> ← 状态点,纯 CSS 由 .is-* 驱动
14
- * <span class="ai-item-meta">1.2s</span>
13
+ * <div class="icen-ai-item-side">
14
+ * <span class="icen-ai-item-status"></span> ← 状态点,纯 CSS 由 .is-* 驱动
15
+ * <span class="icen-ai-item-meta">1.2s</span>
15
16
  * </div>
16
- * <div class="ai-item-detail" hidden>展开详情</div>
17
+ * <div class="icen-ai-item-detail" hidden>展开详情</div>
17
18
  * </div>
18
19
  *
19
- * ── 工具调用卡(.ai-tool-head 复用 .ai-item-* 零件,不带 .ai-item 壳)──
20
- * <div class="ai-tool ai-tool--shell is-done" data-ai-id="…" data-ai-kind="shell">
21
- * <button class="ai-tool-head" type="button" aria-expanded="false">
22
- * <span class="ai-item-icon" aria-hidden="true">…svg…</span>
23
- * <span class="ai-item-main">
24
- * <span class="ai-item-title">Read</span>
25
- * <span class="ai-item-sub">src/foo.ts:1-50</span>
20
+ * ── 工具调用卡(.icen-ai-tool-head 复用 .ai-item-* 零件,不带 .icen-ai-item 壳)──
21
+ * <div class="icen-ai-tool icen-ai-tool--shell is-done" data-icen-ai-id="…" data-icen-ai-kind="shell">
22
+ * <button class="icen-ai-tool-head" type="button" aria-expanded="false">
23
+ * <span class="icen-ai-item-icon" aria-hidden="true">…svg…</span>
24
+ * <span class="icen-ai-item-main">
25
+ * <span class="icen-ai-item-title">Read</span>
26
+ * <span class="icen-ai-item-sub">src/foo.ts:1-50</span>
26
27
  * </span>
27
- * <span class="ai-item-status" role="img" aria-label="完成"></span>
28
- * <span class="ai-item-meta">0.4s</span>
28
+ * <span class="icen-ai-item-status" role="img" aria-label="完成"></span>
29
+ * <span class="icen-ai-item-meta">0.4s</span>
29
30
  * </button>
30
- * <div class="ai-tool-body" hidden>
31
- * <div class="ai-tool-io"><div class="ai-tool-io-label">输入</div><pre class="ai-tool-io-content">…</pre></div>
32
- * <div class="ai-tool-io"><div class="ai-tool-io-label">输出</div><pre class="ai-tool-io-content">…</pre></div>
33
- * <div class="ai-tool-approval"> ← 仅 .is-approval 显示(纯 CSS 驱动)
34
- * <div class="ai-tool-approval-reason" hidden>审批原因</div> ← 可选(model.approval.reason)
35
- * <button class="btn btn-sm btn-primary" data-ai-approve type="button">允许</button>
36
- * <button class="btn btn-sm" data-ai-reject type="button">拒绝</button>
31
+ * <div class="icen-ai-tool-body" hidden>
32
+ * <div class="icen-ai-tool-io"><div class="icen-ai-tool-io-label">输入</div><pre class="icen-ai-tool-io-content">…</pre></div>
33
+ * <div class="icen-ai-tool-io"><div class="icen-ai-tool-io-label">输出</div><pre class="icen-ai-tool-io-content">…</pre></div>
34
+ * <div class="icen-ai-tool-approval"> ← 仅 .is-approval 显示(纯 CSS 驱动)
35
+ * <div class="icen-ai-tool-approval-reason" hidden>审批原因</div> ← 可选(model.approval.reason)
36
+ * <button class="icen-btn icen-btn-sm icen-btn-primary" data-icen-ai-approve type="button">允许</button>
37
+ * <button class="icen-btn icen-btn-sm" data-icen-ai-reject type="button">拒绝</button>
37
38
  * </div>
38
39
  * </div>
39
40
  * </div>
40
41
  *
41
42
  * ── 子智能体卡 ──
42
- * <div class="ai-subagent is-running" data-ai-id="…" data-ai-kind="subagent">
43
- * <button class="ai-subagent-head" type="button" aria-expanded="false">…head 结构同上…</button>
44
- * <div class="ai-subagent-body" hidden>
45
- * <div class="ai-subagent-stream"> ← 嵌套 .ai-tool / .ai-subagent;
43
+ * <div class="icen-ai-subagent is-running" data-icen-ai-id="…" data-icen-ai-kind="subagent">
44
+ * <button class="icen-ai-subagent-head" type="button" aria-expanded="false">…head 结构同上…</button>
45
+ * <div class="icen-ai-subagent-body" hidden>
46
+ * <div class="icen-ai-subagent-stream"> ← 嵌套 .icen-ai-tool / .icen-ai-subagent;
46
47
  * … 行间 style="--ai-activity-index:i" 驱动渐入 stagger
47
48
  * </div>
48
- * <div class="ai-subagent-result">完成回执摘要</div>
49
+ * <div class="icen-ai-subagent-result">完成回执摘要</div>
49
50
  * </div>
50
51
  * </div>
51
52
  *
@@ -62,91 +63,117 @@
62
63
  * read/search/grep/glob=info · edit/write=accent · rm=error · shell=muted · mcp/skill=success
63
64
  * browser/fetch/todo/plan/subagent/note = 默认 accent(不写规则)
64
65
  * 第三方 registerAiKind 的 tint 由 behavior 内联 --ai-item-tint 兜底。
66
+ *
67
+ * ── AI 工具挂载区(ai-tools.ts createAiToolArea,§13;状态类挂 .icen-ai-tools-item)──
68
+ * <div class="icen-ai-tools-mount">
69
+ * <div class="icen-ai-tools-item is-approval|is-running|is-done|is-error|is-cancelled">
70
+ * <button class="icen-ai-tools-item-head" aria-expanded="true">
71
+ * chevron / 名 / 时间 / <span class="icen-ai-tools-item-status">状态点</span> / ×
72
+ * </button>
73
+ * <div class="icen-ai-tools-item-approval"> ← 仅审批态(requiresApproval),批准/拒绝后移除
74
+ * <div class="icen-ai-tools-item-approval-text">
75
+ * <div class="icen-ai-tools-item-approval-reason">工具 description(原因行)</div>
76
+ * <div class="icen-ai-tools-item-approval-preview">归一输入 JSON 预览</div>
77
+ * </div>
78
+ * <button class="icen-btn icen-btn-sm icen-btn-primary">批准</button>
79
+ * <button class="icen-btn icen-btn-sm">拒绝</button>
80
+ * </div>
81
+ * <div class="icen-ai-tools-item-error" role="alert"> ← 仅失败态(校验/执行/超时),逐行一条
82
+ * <div class="icen-ai-tools-item-error-line">…</div>
83
+ * </div>
84
+ * <div class="icen-ai-tools-item-body">…</div> ← 工具自渲染(折叠时隐藏)
85
+ * <div class="icen-ai-tools-item-stream"> ← 活动流(run ctx.icen-progress 懒建追加)
86
+ * <div class="icen-ai-tools-item-stream-line">…</div>
87
+ * </div>
88
+ * </div>
89
+ * </div>
65
90
  */
66
91
 
67
92
  /* ══════════════════════════════════════════════════════════════
68
- 条目基元 .ai-item(行式条目"基类")
93
+ 条目基元 .icen-ai-item(行式条目"基类")
69
94
  ══════════════════════════════════════════════════════════════ */
70
95
 
71
- .ai-item {
96
+ .icen-ai-item {
72
97
  /* 局部变量槽:kind/变体只覆盖这些变量(--btn-* 同款继承模式) */
73
- --ai-item-tint: var(--token-accent);
98
+ --ai-item-tint: var(--icen-token-accent);
74
99
  --ai-item-pulse-duration: 1.5s; /* running 脉冲(pill --pill-pulse-duration 同款变量化) */
75
100
  --ai-item-blink-duration: 1s; /* streaming 光标闪烁 */
76
101
 
77
102
  display: flex;
78
103
  flex-wrap: wrap;
79
104
  align-items: center;
80
- gap: var(--density-space-sm);
105
+ gap: var(--icen-density-space-sm);
81
106
  min-width: 0;
82
107
  align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap(width:100% 会塌成 min-content,禁用) */
83
108
  }
84
109
 
85
- .ai-item-icon {
110
+ .icen-ai-item-icon {
86
111
  display: inline-flex;
87
112
  align-items: center;
88
113
  justify-content: center;
89
114
  flex-shrink: 0;
90
- width: 20px;
91
- height: 20px;
115
+ inline-size: 28px;
116
+ block-size: 28px;
117
+ border-radius: var(--icen-radius-sm);
118
+ background: color-mix(in srgb, var(--ai-item-tint) 8%, var(--icen-token-surface));
92
119
  color: var(--ai-item-tint);
93
120
  transition: color var(--icen-tx-fast);
94
121
  }
95
- .ai-item-icon > svg {
122
+ .icen-ai-item-icon > svg {
96
123
  width: 16px;
97
124
  height: 16px;
98
125
  }
99
126
 
100
- .ai-item-main {
127
+ .icen-ai-item-main {
101
128
  flex: 1 1 auto;
102
129
  min-width: 0;
103
130
  display: flex;
104
131
  flex-direction: column;
105
132
  gap: 1px;
106
133
  }
107
- .ai-item-title {
108
- font-size: var(--density-font-size-md);
134
+ .icen-ai-item-title {
135
+ font-size: var(--icen-density-font-size-md);
109
136
  line-height: 1.4;
110
- color: var(--token-text);
137
+ color: var(--icen-token-text);
111
138
  overflow: hidden;
112
139
  text-overflow: ellipsis;
113
140
  white-space: nowrap;
114
141
  }
115
- .ai-item-sub {
116
- font-size: var(--density-font-size-xs);
142
+ .icen-ai-item-sub {
143
+ font-size: var(--icen-density-font-size-xs);
117
144
  line-height: 1.4;
118
- color: var(--token-text-muted);
145
+ color: var(--icen-token-text-muted);
119
146
  overflow: hidden;
120
147
  text-overflow: ellipsis;
121
148
  white-space: nowrap;
122
149
  }
123
- .ai-item-side {
150
+ .icen-ai-item-side {
124
151
  display: inline-flex;
125
152
  align-items: center;
126
- gap: var(--density-space-xs);
127
- margin-left: auto;
153
+ gap: var(--icen-density-space-xs);
154
+ margin-inline-start: auto;
128
155
  flex-shrink: 0;
129
156
  }
130
- /* head 直排结构(无 .ai-item-side 包裹)时,状态点顶到右侧 */
131
- .ai-tool-head > .ai-item-status,
132
- .ai-subagent-head > .ai-item-status {
133
- margin-left: auto;
157
+ /* head 直排结构(无 .icen-ai-item-side 包裹)时,状态点顶到行内末端 */
158
+ .icen-ai-tool-head > .icen-ai-item-status,
159
+ .icen-ai-subagent-head > .icen-ai-item-status {
160
+ margin-inline-start: auto;
134
161
  }
135
162
 
136
- .ai-item-meta {
137
- font-size: var(--density-font-size-xs);
138
- color: var(--token-text-faint);
163
+ .icen-ai-item-meta {
164
+ font-size: var(--icen-density-font-size-xs);
165
+ color: var(--icen-token-text-faint);
139
166
  font-variant-numeric: tabular-nums;
140
167
  flex-shrink: 0;
141
168
  }
142
169
 
143
- .ai-item-detail {
170
+ .icen-ai-item-detail {
144
171
  flex-basis: 100%;
145
- min-width: 100%;
172
+ min-inline-size: 100%;
146
173
  }
147
174
 
148
- /* ── 状态点 .ai-item-status(纯 CSS 圆点,由 .is-* 决定颜色与动效) ── */
149
- .ai-item-status {
175
+ /* ── 状态点 .icen-ai-item-status(纯 CSS 圆点,由 .is-* 决定颜色与动效) ── */
176
+ .icen-ai-item-status {
150
177
  position: relative;
151
178
  flex-shrink: 0;
152
179
  width: 8px;
@@ -154,13 +181,13 @@
154
181
  border-radius: 50%;
155
182
  }
156
183
 
157
- /* 等待:faint 空心点(.ai-subagent 与 .ai-item 共享同一状态语言) */
158
- :is(.ai-item, .ai-tool, .ai-subagent).is-pending .ai-item-status {
159
- border: 1.5px solid var(--token-text-faint);
184
+ /* 等待:faint 空心点(.icen-ai-subagent 与 .icen-ai-item 共享同一状态语言) */
185
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-pending .icen-ai-item-status {
186
+ border: 1.5px solid var(--icen-token-text-faint);
160
187
  }
161
188
 
162
189
  /* 执行中:tint 脉冲点 */
163
- :is(.ai-item, .ai-tool, .ai-subagent).is-running .ai-item-status {
190
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-running .icen-ai-item-status {
164
191
  background: var(--ai-item-tint);
165
192
  animation: ai-item-pulse var(--ai-item-pulse-duration) ease-in-out infinite;
166
193
  }
@@ -170,363 +197,491 @@
170
197
  }
171
198
 
172
199
  /* 流式中:▍光标闪烁(复用 colors.css 的 blink keyframes,animate-blink 同款) */
173
- :is(.ai-item, .ai-tool, .ai-subagent).is-streaming .ai-item-status {
200
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-streaming .icen-ai-item-status {
174
201
  width: 3px;
175
202
  height: 12px;
176
- border-radius: 1px;
203
+ border-radius: 1px; /* guard:allow-radius 微构件(bar/dot/track/指示器等图形级,不属容器圆角面) */
177
204
  background: var(--ai-item-tint);
178
205
  animation: blink var(--ai-item-blink-duration) step-end infinite;
179
206
  }
180
207
 
181
208
  /* 待人确认:warning 点 + 外环 */
182
- :is(.ai-item, .ai-tool, .ai-subagent).is-approval .ai-item-status {
183
- background: var(--token-warning);
184
- box-shadow: 0 0 0 3px var(--token-warning-muted);
209
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-approval .icen-ai-item-status {
210
+ background: var(--icen-token-warning);
211
+ box-shadow: 0 0 0 3px var(--icen-token-warning-muted);
185
212
  }
186
213
 
187
- /* 完成:success 对勾(纯 CSS,无 SVG) */
188
- :is(.ai-item, .ai-tool, .ai-subagent).is-done .ai-item-status::after {
189
- content: "";
214
+ /* 完成:success 对勾(共享 check 几何 mask,颜色由 background 承载) */
215
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-done .icen-ai-item-status::after {
216
+ content: '';
190
217
  position: absolute;
191
- left: 1px;
192
- top: -1px;
193
- width: 5px;
194
- height: 9px;
195
- border-right: 1.5px solid var(--token-success);
196
- border-bottom: 1.5px solid var(--token-success);
197
- transform: rotate(45deg);
218
+ inset: 0;
219
+ background: var(--icen-token-success);
220
+ mask: var(--icen-token-icon-check) center / 75% no-repeat;
198
221
  }
199
222
 
200
223
  /* 失败:error 点 + 外环 */
201
- :is(.ai-item, .ai-tool, .ai-subagent).is-error .ai-item-status {
202
- background: var(--token-error);
203
- box-shadow: 0 0 0 3px var(--token-error-muted);
224
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-error .icen-ai-item-status {
225
+ background: var(--icen-token-error);
226
+ box-shadow: 0 0 0 3px var(--icen-token-error-muted);
204
227
  }
205
228
 
206
229
  /* 已取消:faint 点 + 标题删除线 */
207
- :is(.ai-item, .ai-tool, .ai-subagent).is-cancelled .ai-item-status {
208
- background: var(--token-text-faint);
230
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-cancelled .icen-ai-item-status {
231
+ background: var(--icen-token-text-faint);
209
232
  opacity: 0.6;
210
233
  }
211
- :is(.ai-item, .ai-tool, .ai-subagent).is-cancelled .ai-item-title {
212
- color: var(--token-text-faint);
234
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-cancelled .icen-ai-item-title {
235
+ color: var(--icen-token-text-faint);
213
236
  text-decoration: line-through;
214
237
  }
215
238
 
216
239
  /* ══════════════════════════════════════════════════════════════
217
- 工具调用卡 .ai-tool
240
+ 工具调用卡 .icen-ai-tool
218
241
  ══════════════════════════════════════════════════════════════ */
219
242
 
220
- .ai-tool {
221
- --ai-item-tint: var(--token-accent);
243
+ .icen-ai-tool {
244
+ --ai-item-tint: var(--icen-token-accent);
222
245
  align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
223
- border: 1px solid var(--token-line-soft);
224
- border-radius: var(--radius-md);
225
- background: var(--token-surface);
246
+ border: 1px solid var(--icen-token-line-soft);
247
+ border-radius: var(--icen-radius-md);
248
+ background: var(--icen-token-surface);
226
249
  }
227
250
 
228
251
  /* ── kind 修饰类:只覆盖 --ai-item-tint ──
229
252
  browser/fetch/todo/plan/subagent/note 用默认 accent,不写规则 */
230
- .ai-tool--read,
231
- .ai-tool--search,
232
- .ai-tool--grep,
233
- .ai-tool--glob {
234
- --ai-item-tint: var(--token-info);
253
+ .icen-ai-tool--read,
254
+ .icen-ai-tool--search,
255
+ .icen-ai-tool--grep,
256
+ .icen-ai-tool--glob {
257
+ --ai-item-tint: var(--icen-token-info);
235
258
  }
236
- .ai-tool--edit,
237
- .ai-tool--write {
238
- --ai-item-tint: var(--token-accent);
259
+ .icen-ai-tool--edit,
260
+ .icen-ai-tool--write {
261
+ --ai-item-tint: var(--icen-token-accent);
239
262
  }
240
- .ai-tool--rm {
241
- --ai-item-tint: var(--token-error);
263
+ .icen-ai-tool--rm {
264
+ --ai-item-tint: var(--icen-token-error);
242
265
  }
243
- .ai-tool--shell {
244
- --ai-item-tint: var(--token-text-muted);
266
+ .icen-ai-tool--shell {
267
+ --ai-item-tint: var(--icen-token-text-muted);
245
268
  }
246
- .ai-tool--mcp,
247
- .ai-tool--skill {
248
- --ai-item-tint: var(--token-success);
269
+ .icen-ai-tool--mcp,
270
+ .icen-ai-tool--skill {
271
+ --ai-item-tint: var(--icen-token-success);
249
272
  }
250
273
 
251
274
  /* ── head ── */
252
- .ai-tool-head,
253
- .ai-subagent-head {
275
+ .icen-ai-tool-head,
276
+ .icen-ai-subagent-head {
254
277
  display: flex;
255
278
  align-items: center;
256
- gap: var(--density-space-sm);
279
+ gap: var(--icen-density-space-sm);
257
280
  width: 100%;
258
- padding: var(--density-space-xs) var(--density-space-sm);
281
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
259
282
  border: none;
260
283
  border-radius: inherit; /* hover 底色不戳破卡片圆角 */
261
284
  background: transparent;
262
285
  color: inherit;
263
286
  font: inherit;
264
- text-align: left;
287
+ text-align: start;
265
288
  cursor: pointer;
266
289
  -webkit-tap-highlight-color: transparent;
267
290
  transition: background-color var(--icen-tx-fast);
268
291
  }
269
- .ai-tool-head:hover,
270
- .ai-subagent-head:hover {
271
- background: var(--token-fill-1);
292
+ .icen-ai-tool-head:hover,
293
+ .icen-ai-subagent-head:hover {
294
+ background: var(--icen-token-fill-1);
272
295
  }
273
- .ai-tool-head:focus-visible,
274
- .ai-subagent-head:focus-visible {
296
+ .icen-ai-tool-head:focus-visible,
297
+ .icen-ai-subagent-head:focus-visible {
275
298
  outline: none;
276
299
  box-shadow: var(--icen-ring);
277
300
  }
278
301
 
279
302
  /* ── body ── */
280
- .ai-tool-body {
303
+ .icen-ai-tool-body {
281
304
  display: flex;
282
305
  flex-direction: column;
283
- gap: var(--density-space-sm);
284
- padding: var(--density-space-sm);
285
- border-top: 1px solid var(--token-line-soft);
306
+ gap: var(--icen-density-space-sm);
307
+ padding: var(--icen-density-space-sm);
308
+ border-top: 1px solid var(--icen-token-line-soft);
286
309
  animation: icen-pop-in var(--icen-tx-fast);
287
310
  }
288
- .ai-tool-body[hidden],
289
- .ai-subagent-body[hidden],
290
- .ai-tool-io[hidden],
291
- .ai-subagent-result[hidden] {
311
+ .icen-ai-tool-body[hidden],
312
+ .icen-ai-subagent-body[hidden],
313
+ .icen-ai-tool-io[hidden],
314
+ .icen-ai-subagent-result[hidden] {
292
315
  display: none;
293
316
  }
294
317
 
295
318
  /* ── 输入/输出区块(pre 等宽、可滚、max-height 收敛) ── */
296
- .ai-tool-io {
319
+ .icen-ai-tool-io {
297
320
  display: flex;
298
321
  flex-direction: column;
299
322
  gap: 4px;
300
- min-width: 0;
323
+ min-inline-size: 0;
301
324
  }
302
- .ai-tool-io-label {
303
- font-size: var(--density-font-size-2xs);
325
+ .icen-ai-tool-io-label {
326
+ font-size: var(--icen-density-font-size-2xs);
304
327
  font-weight: 600;
305
328
  letter-spacing: 0.08em;
306
329
  text-transform: uppercase;
307
- color: var(--token-text-faint);
330
+ color: var(--icen-token-text-faint);
308
331
  }
309
- .ai-tool-io-content {
332
+ .icen-ai-tool-io-content {
310
333
  --ai-tool-io-max: 12rem; /* 收敛上限(组件局部变量) */
311
334
  margin: 0;
312
- padding: var(--density-space-xs) var(--density-space-sm);
313
- max-height: var(--ai-tool-io-max);
335
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
336
+ max-block-size: var(--ai-tool-io-max);
314
337
  overflow: auto;
315
- background: var(--token-bg-soft);
316
- border: 1px solid var(--token-line-soft);
317
- border-radius: var(--radius-sm);
318
- font-family: var(--font-mono);
319
- font-size: var(--density-font-size-sm);
338
+ background: var(--icen-token-bg-soft);
339
+ border: 1px solid var(--icen-token-line-soft);
340
+ border-radius: var(--icen-radius-sm);
341
+ font-family: var(--icen-font-mono);
342
+ font-size: var(--icen-density-font-size-sm);
320
343
  line-height: 1.5;
321
- color: var(--token-text);
344
+ color: var(--icen-token-text);
322
345
  white-space: pre-wrap;
323
346
  word-break: break-word;
324
347
  }
325
348
 
326
349
  /* 多模态回执(MCP content 数组 → 媒体/链接,spec §10.3):
327
- 容器纵向排布;媒体本体复用 ai-chat.css 的 .ai-msg-media 全局样式 */
328
- .ai-tool-io-media {
350
+ 容器纵向排布;媒体本体复用 ai-chat.css 的 .icen-ai-msg-media 全局样式 */
351
+ .icen-ai-tool-io-media {
329
352
  display: flex;
330
353
  flex-direction: column;
331
- gap: var(--density-space-xs);
332
- min-width: 0;
354
+ gap: var(--icen-density-space-xs);
355
+ min-inline-size: 0;
333
356
  }
334
357
 
335
358
  /* ── 审批区(仅 .is-approval 显示,纯 CSS 驱动) ── */
336
- .ai-tool-approval {
359
+ .icen-ai-tool-approval {
337
360
  display: none;
338
361
  align-items: center;
339
- gap: var(--density-space-sm);
340
- padding-top: var(--density-space-xs);
341
- border-top: 1px dashed var(--token-line-soft);
362
+ gap: var(--icen-density-space-sm);
363
+ padding-top: var(--icen-density-space-xs);
364
+ border-top: 1px dashed var(--icen-token-line-soft);
342
365
  }
343
- .ai-tool.is-approval .ai-tool-approval {
366
+ .icen-ai-tool.is-approval .icen-ai-tool-approval {
344
367
  display: flex;
345
368
  }
346
- .ai-tool-approval-reason {
369
+ .icen-ai-tool-approval-reason {
347
370
  flex: 1 1 auto;
348
- min-width: 0;
349
- font-size: var(--density-font-size-xs);
371
+ min-inline-size: 0;
372
+ font-size: var(--icen-density-font-size-xs);
350
373
  line-height: 1.5;
351
- color: var(--token-text-muted);
374
+ color: var(--icen-token-text-muted);
352
375
  }
353
- .ai-tool.is-approval {
354
- border-color: color-mix(in srgb, var(--token-warning) 40%, transparent);
376
+ .icen-ai-tool.is-approval {
377
+ border-color: color-mix(in srgb, var(--icen-token-warning) 40%, transparent);
355
378
  }
356
- .ai-tool.is-error {
357
- border-color: color-mix(in srgb, var(--token-error) 40%, transparent);
379
+ .icen-ai-tool.is-error {
380
+ border-color: color-mix(in srgb, var(--icen-token-error) 40%, transparent);
358
381
  }
359
382
 
360
383
  /* ══════════════════════════════════════════════════════════════
361
- 子智能体卡 .ai-subagent(嵌套活动流 = 缩进 + 左侧引导线,可递归)
384
+ 子智能体卡 .icen-ai-subagent(嵌套活动流 = 缩进 + 起始缘引导线,可递归)
362
385
  ══════════════════════════════════════════════════════════════ */
363
386
 
364
- .ai-subagent {
365
- --ai-item-tint: var(--token-accent);
387
+ .icen-ai-subagent {
388
+ --ai-item-tint: var(--icen-token-accent);
366
389
  align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
367
- border: 1px solid var(--token-line-soft);
368
- border-left: 3px solid var(--ai-item-tint); /* 代理卡身份:tint 左边条 */
369
- border-radius: var(--radius-md);
370
- background: var(--token-surface);
390
+ border: 1px solid var(--icen-token-line-soft);
391
+ border-inline-start: 3px solid var(--ai-item-tint); /* 代理卡身份:tint 起始缘边条 */
392
+ border-radius: var(--icen-radius-md);
393
+ background: var(--icen-token-surface);
371
394
  }
372
- .ai-subagent.is-error {
373
- border-left-color: var(--token-error);
395
+ .icen-ai-subagent.is-error {
396
+ border-inline-start-color: var(--icen-token-error);
374
397
  }
375
- .ai-subagent.is-done {
376
- border-left-color: var(--token-success);
398
+ .icen-ai-subagent.is-done {
399
+ border-inline-start-color: var(--icen-token-success);
377
400
  }
378
401
 
379
- .ai-subagent-body {
402
+ .icen-ai-subagent-body {
380
403
  display: flex;
381
404
  flex-direction: column;
382
- gap: var(--density-space-sm);
383
- padding: var(--density-space-sm);
384
- border-top: 1px solid var(--token-line-soft);
405
+ gap: var(--icen-density-space-sm);
406
+ padding: var(--icen-density-space-sm);
407
+ border-top: 1px solid var(--icen-token-line-soft);
385
408
  }
386
409
 
387
- /* 嵌套流:缩进 + 引导线;行间渐入 stagger 由 --ai-activity-index(render 写入)驱动 */
388
- .ai-subagent-stream {
410
+ /* 嵌套流:缩进 + 起始缘引导线;行间渐入 stagger 由 --ai-activity-index(render 写入)驱动 */
411
+ .icen-ai-subagent-stream {
389
412
  --ai-stagger-step: 40ms; /* 活动项渐入步长(组件局部变量) */
390
413
  position: relative;
391
414
  display: flex;
392
415
  flex-direction: column;
393
- gap: var(--density-space-xs);
394
- padding-left: var(--density-space-md);
416
+ gap: var(--icen-density-space-xs);
417
+ padding-inline-start: var(--icen-density-space-md);
395
418
  }
396
- .ai-subagent-stream::before {
419
+ .icen-ai-subagent-stream::before {
397
420
  content: "";
398
421
  position: absolute;
399
- left: 5px;
400
- top: var(--density-space-xs);
401
- bottom: var(--density-space-xs);
422
+ inset-inline-start: 5px;
423
+ top: var(--icen-density-space-xs);
424
+ bottom: var(--icen-density-space-xs);
402
425
  width: 1px;
403
- background: var(--token-line-soft);
426
+ background: var(--icen-token-line-soft);
404
427
  }
405
428
  /* 展开(body 从 hidden 解除)时,活动项逐条 icen-pop-in 渐入 */
406
- .ai-subagent-stream > * {
429
+ .icen-ai-subagent-stream > * {
407
430
  animation: icen-pop-in var(--icen-tx-fast) backwards;
408
431
  animation-delay: calc(var(--ai-activity-index, 0) * var(--ai-stagger-step));
409
432
  }
410
433
 
411
434
  /* 完成回执 */
412
- .ai-subagent-result {
413
- padding: var(--density-space-xs) var(--density-space-sm);
414
- background: var(--token-bg-soft);
415
- border: 1px solid var(--token-line-soft);
416
- border-radius: var(--radius-sm);
417
- font-size: var(--density-font-size-sm);
435
+ .icen-ai-subagent-result {
436
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
437
+ background: var(--icen-token-bg-soft);
438
+ border: 1px solid var(--icen-token-line-soft);
439
+ border-radius: var(--icen-radius-sm);
440
+ font-size: var(--icen-density-font-size-sm);
418
441
  line-height: 1.5;
419
- color: var(--token-text-muted);
442
+ color: var(--icen-token-text-muted);
420
443
  }
421
- .ai-subagent.is-done .ai-subagent-result {
422
- color: var(--token-text);
423
- border-color: color-mix(in srgb, var(--token-success) 30%, transparent);
444
+ .icen-ai-subagent.is-done .icen-ai-subagent-result {
445
+ color: var(--icen-token-text);
446
+ border-color: color-mix(in srgb, var(--icen-token-success) 30%, transparent);
424
447
  }
425
448
 
426
449
  /* ══════════════════════════════════════════════════════════════
427
450
  动效守卫
428
451
  ══════════════════════════════════════════════════════════════ */
429
452
  @media (prefers-reduced-motion: reduce) {
430
- :is(.ai-item, .ai-tool, .ai-subagent).is-running .ai-item-status,
431
- :is(.ai-item, .ai-tool, .ai-subagent).is-streaming .ai-item-status {
453
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-running .icen-ai-item-status,
454
+ :is(.icen-ai-item, .icen-ai-tool, .icen-ai-subagent).is-streaming .icen-ai-item-status {
432
455
  animation: none;
433
456
  }
434
- .ai-tool-body,
435
- .ai-subagent-stream > * {
457
+ .icen-ai-tool-body,
458
+ .icen-ai-subagent-stream > * {
436
459
  animation: none;
437
460
  }
438
- .ai-tool-head,
439
- .ai-subagent-head {
461
+ .icen-ai-tool-head,
462
+ .icen-ai-subagent-head {
440
463
  transition: none;
441
464
  }
442
465
  }
443
466
 
444
467
  /* ═══ 工具卡内嵌图表(回执 = ChartSpec 时 setIo 走 renderChart,§13)═══ */
445
- .ai-tool-io-chart {
468
+ .icen-ai-tool-io-chart {
446
469
  width: 100%;
447
470
  min-width: 0;
448
471
  }
449
472
 
450
- /* ═══ AI 工具挂载区(ai-tools.ts 的 createAiToolArea,§13)═══
451
- * .ai-tools-mount > .ai-tools-item > head(名/时间/×)+ body(工具自渲染) */
452
- .ai-tools-mount {
473
+ /* ═══ AI 工具挂载区(ai-tools.ts 的 createAiToolArea,§13;完整 DOM 契约见文件头)═══
474
+ * .icen-ai-tools-mount > .icen-ai-tools-item(状态类 is-*)> head(名/时间/状态点/×)
475
+ * + approval(仅审批态)+ error(仅失败态)+ body(工具自渲染)+ stream(progress 活动流) */
476
+ .icen-ai-tools-mount {
453
477
  display: grid;
454
478
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
455
- gap: var(--density-space-md);
479
+ gap: var(--icen-density-space-md);
456
480
  align-items: start;
457
481
  }
458
- .ai-tools-item {
482
+ .icen-ai-tools-item {
459
483
  display: flex;
460
484
  flex-direction: column;
461
485
  min-width: 0;
462
- border: 1px solid var(--token-line-soft);
463
- border-radius: var(--radius-md);
464
- background: var(--token-surface);
465
- animation: icen-pop-in var(--duration-normal) var(--ease-out);
486
+ border: 1px solid var(--icen-token-line-soft);
487
+ border-radius: var(--icen-radius-md);
488
+ background: var(--icen-token-surface);
489
+ animation: icen-pop-in var(--icen-duration-normal) var(--icen-ease-out);
466
490
  }
467
- .ai-tools-item-head {
491
+ .icen-ai-tools-item-head {
468
492
  display: flex;
469
493
  align-items: center;
470
- gap: var(--density-space-sm);
471
- padding: var(--density-space-xs) var(--density-space-sm);
472
- border-bottom: 1px solid var(--token-line-soft);
494
+ gap: var(--icen-density-space-sm);
495
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
496
+ border-bottom: 1px solid var(--icen-token-line-soft);
473
497
  }
474
- .ai-tools-item-name {
475
- font-family: var(--font-mono);
476
- font-size: var(--density-font-size-xs);
477
- color: var(--token-text);
498
+ .icen-ai-tools-item-name {
499
+ font-family: var(--icen-font-mono);
500
+ font-size: var(--icen-density-font-size-xs);
501
+ color: var(--icen-token-text);
478
502
  }
479
- .ai-tools-item-meta {
503
+ .icen-ai-tools-item-meta {
480
504
  flex: 1;
481
- font-family: var(--font-mono);
482
- font-size: var(--density-font-size-2xs);
483
- color: var(--token-text-faint);
505
+ font-family: var(--icen-font-mono);
506
+ font-size: var(--icen-density-font-size-2xs);
507
+ color: var(--icen-token-text-faint);
484
508
  font-variant-numeric: tabular-nums;
485
509
  }
486
- .ai-tools-item-remove {
510
+ .icen-ai-tools-item-remove {
487
511
  border: 0;
488
512
  background: transparent;
489
- color: var(--token-text-faint);
513
+ color: var(--icen-token-text-faint);
490
514
  cursor: pointer;
491
- border-radius: var(--radius-xs);
492
- font-size: var(--density-font-size-sm);
515
+ border-radius: var(--icen-radius-xs);
516
+ font-size: var(--icen-density-font-size-sm);
493
517
  line-height: 1;
494
518
  padding: 2px 6px;
495
519
  transition: color var(--icen-tx-fast), background-color var(--icen-tx-fast);
496
520
  }
497
- .ai-tools-item-remove:hover { color: var(--token-error); background: var(--token-fill-1); }
498
- .ai-tools-item-remove:focus-visible { outline: none; box-shadow: var(--icen-ring); }
499
- .ai-tools-item-body {
500
- padding: var(--density-space-sm);
521
+ .icen-ai-tools-item-remove:hover { color: var(--icen-token-error); background: var(--icen-token-fill-1); }
522
+ .icen-ai-tools-item-remove:focus-visible { outline: none; box-shadow: var(--icen-ring); }
523
+ .icen-ai-tools-item-body {
524
+ padding: var(--icen-density-space-sm);
501
525
  min-width: 0;
502
526
  }
503
527
 
504
528
  @media (prefers-reduced-motion: reduce) {
505
- .ai-tools-item { animation: none; }
529
+ .icen-ai-tools-item { animation: none; }
506
530
  }
507
531
 
508
532
  /* 挂载项折叠态:head 为 button(chevron + 名/时间 + ×) */
509
- .ai-tools-item-head {
533
+ .icen-ai-tools-item-head {
510
534
  cursor: pointer;
511
535
  border: 0;
512
536
  background: transparent;
513
- text-align: left;
514
- width: 100%;
537
+ text-align: start;
538
+ inline-size: 100%;
515
539
  font: inherit;
516
540
  }
517
- .ai-tools-item-chevron {
541
+ .icen-ai-tools-item-chevron {
518
542
  flex-shrink: 0;
519
- color: var(--token-text-faint);
520
- font-size: var(--density-font-size-xs);
543
+ color: var(--icen-token-text-faint);
544
+ font-size: var(--icen-density-font-size-xs);
521
545
  transition: transform var(--icen-tx-fast);
522
546
  }
523
- .ai-tools-item-head[aria-expanded='false'] .ai-tools-item-chevron {
547
+ .icen-ai-tools-item-head[aria-expanded='false'] .icen-ai-tools-item-chevron {
524
548
  transform: rotate(-90deg);
525
549
  }
526
- .ai-tools-item.is-collapsed .ai-tools-item-body {
550
+ .icen-ai-tools-item.is-collapsed .icen-ai-tools-item-body,
551
+ .icen-ai-tools-item.is-collapsed .icen-ai-tools-item-stream {
527
552
  display: none;
528
553
  }
529
- .ai-tools-item-head:focus-visible {
554
+ .icen-ai-tools-item-head:focus-visible {
530
555
  outline: none;
531
556
  box-shadow: var(--icen-ring);
532
557
  }
558
+
559
+ /* ── 挂载卡状态点 + 状态类(7 态状态机的挂载区形态,规格 §13)── */
560
+ .icen-ai-tools-item-status {
561
+ flex-shrink: 0;
562
+ width: 8px;
563
+ height: 8px;
564
+ border-radius: 50%;
565
+ background: var(--icen-token-text-faint);
566
+ }
567
+ .icen-ai-tools-item.is-running .icen-ai-tools-item-status {
568
+ background: var(--icen-token-accent);
569
+ animation: ai-item-pulse 1.5s ease-in-out infinite;
570
+ }
571
+ .icen-ai-tools-item.is-approval {
572
+ border-color: color-mix(in srgb, var(--icen-token-warning) 40%, transparent);
573
+ }
574
+ .icen-ai-tools-item.is-approval .icen-ai-tools-item-status {
575
+ background: var(--icen-token-warning);
576
+ box-shadow: 0 0 0 3px var(--icen-token-warning-muted);
577
+ }
578
+ .icen-ai-tools-item.is-done .icen-ai-tools-item-status {
579
+ background: var(--icen-token-success);
580
+ }
581
+ .icen-ai-tools-item.is-error {
582
+ border-color: color-mix(in srgb, var(--icen-token-error) 40%, transparent);
583
+ }
584
+ .icen-ai-tools-item.is-error .icen-ai-tools-item-status {
585
+ background: var(--icen-token-error);
586
+ box-shadow: 0 0 0 3px var(--icen-token-error-muted);
587
+ }
588
+ .icen-ai-tools-item.is-cancelled {
589
+ opacity: 0.75;
590
+ }
591
+ .icen-ai-tools-item.is-cancelled .icen-ai-tools-item-status {
592
+ background: var(--icen-token-text-faint);
593
+ opacity: 0.6;
594
+ }
595
+ .icen-ai-tools-item.is-cancelled .icen-ai-tools-item-name {
596
+ color: var(--icen-token-text-faint);
597
+ text-decoration: line-through;
598
+ }
599
+
600
+ /* ── 审批区(仅审批态在 DOM,批准/拒绝后由 behavior 移除;按钮复用 btn 契约类)── */
601
+ .icen-ai-tools-item-approval {
602
+ display: flex;
603
+ align-items: center;
604
+ gap: var(--icen-density-space-sm);
605
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
606
+ border-bottom: 1px dashed color-mix(in srgb, var(--icen-token-warning) 45%, transparent);
607
+ background: color-mix(in srgb, var(--icen-token-warning) 7%, transparent);
608
+ }
609
+ .icen-ai-tools-item-approval-text {
610
+ flex: 1 1 auto;
611
+ min-inline-size: 0;
612
+ display: flex;
613
+ flex-direction: column;
614
+ gap: 1px;
615
+ }
616
+ .icen-ai-tools-item-approval-reason {
617
+ font-size: var(--icen-density-font-size-xs);
618
+ line-height: 1.5;
619
+ color: var(--icen-token-text);
620
+ overflow: hidden;
621
+ text-overflow: ellipsis;
622
+ white-space: nowrap;
623
+ }
624
+ .icen-ai-tools-item-approval-preview {
625
+ font-family: var(--icen-font-mono);
626
+ font-size: var(--icen-density-font-size-2xs);
627
+ line-height: 1.5;
628
+ color: var(--icen-token-text-faint);
629
+ overflow: hidden;
630
+ text-overflow: ellipsis;
631
+ white-space: nowrap;
632
+ }
633
+
634
+ /* ── 错误清单(仅失败态在 DOM:校验/执行/超时;逐行 textContent)── */
635
+ .icen-ai-tools-item-error {
636
+ display: flex;
637
+ flex-direction: column;
638
+ gap: 2px;
639
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
640
+ border-bottom: 1px solid var(--icen-token-line-soft);
641
+ background: color-mix(in srgb, var(--icen-token-error) 6%, transparent);
642
+ }
643
+ .icen-ai-tools-item-error-line {
644
+ font-family: var(--icen-font-mono);
645
+ font-size: var(--icen-density-font-size-2xs);
646
+ line-height: 1.5;
647
+ color: var(--icen-token-error);
648
+ word-break: break-word;
649
+ }
650
+
651
+ /* ── 活动流(run ctx.icen-progress(line) 懒建追加;每行渐入)── */
652
+ .icen-ai-tools-item-stream {
653
+ display: flex;
654
+ flex-direction: column;
655
+ gap: 2px;
656
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
657
+ border-top: 1px dashed var(--icen-token-line-soft);
658
+ }
659
+ .icen-ai-tools-item-stream-line {
660
+ position: relative;
661
+ padding-inline-start: 12px;
662
+ font-family: var(--icen-font-mono);
663
+ font-size: var(--icen-density-font-size-2xs);
664
+ line-height: 1.6;
665
+ color: var(--icen-token-text-muted);
666
+ word-break: break-word;
667
+ animation: icen-pop-in var(--icen-tx-fast);
668
+ }
669
+ .icen-ai-tools-item-stream-line::before {
670
+ content: "";
671
+ position: absolute;
672
+ inset-inline-start: 2px;
673
+ top: 0.62em;
674
+ width: 4px;
675
+ height: 4px;
676
+ border-radius: 50%;
677
+ background: var(--icen-token-text-faint);
678
+ }
679
+
680
+ @media (prefers-reduced-motion: reduce) {
681
+ .icen-ai-tools-item.is-running .icen-ai-tools-item-status,
682
+ .icen-ai-tools-item-stream-line {
683
+ animation: none;
684
+ }
685
+ }
686
+
687
+ }