@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,136 +1,155 @@
1
+ @layer icen.components {
1
2
  /*
2
3
  * @icen.ai/ui — Component: ai-diff(AI 差异审阅 + 文件 chips,与 behaviors/ai-diff.ts 配套)
3
4
  *
5
+ * RTL 豁免(guard 文件级白名单 scripts/guard/rtl.ts):diff 视图是物理 LTR 代码面——
6
+ * 行号槽右对齐 / 代码列 padding / 分隔线全部保持物理(源码不随界面方向镜像),RTL 下不变。
7
+ *
4
8
  * 完整 DOM 契约(类名与规格 §4.6/§4.7 一致):
5
- * <div class="ai-diff">
6
- * <div class="ai-diff-file is-added|is-modified|is-deleted|is-renamed
7
- * [.is-accepted|.is-rejected]" data-path="src/foo.ts">
8
- * <div class="ai-diff-head" role="button" tabindex="0" aria-expanded="false">
9
- * <span class="ai-diff-path">src/foo.ts</span> <!-- renamed:旧路径 → 新路径 -->
10
- * <span class="ai-diff-stat"><b class="ai-diff-add">+12</b> <b class="ai-diff-del">−4</b></span>
11
- * <span class="ai-diff-actions">
12
- * <button type="button" data-ai-diff-accept>接受</button>
13
- * <button type="button" data-ai-diff-reject>拒绝</button>
9
+ * <div class="icen-ai-diff">
10
+ * <div class="icen-ai-diff-file is-added|is-modified|is-deleted|is-renamed
11
+ * [.is-accepted|.is-rejected]" data-icen-path="src/foo.ts">
12
+ * <div class="icen-ai-diff-head">
13
+ * <button type="button" class="icen-ai-diff-toggle" aria-expanded="false">
14
+ * <span class="icen-ai-diff-path">src/foo.ts</span> <!-- renamed:旧路径 → 新路径 -->
15
+ * <span class="icen-ai-diff-stat"><b class="icen-ai-diff-add">+12</b> <b class="icen-ai-diff-del">−4</b></span>
16
+ * </button>
17
+ * <span class="icen-ai-diff-actions">
18
+ * <button type="button" data-icen-ai-diff-accept>接受</button>
19
+ * <button type="button" data-icen-ai-diff-reject>拒绝</button>
14
20
  * </span>
15
- * <span class="ai-diff-verdict" hidden>已接受|已拒绝</span> <!-- 状态章(JS 决策后显示) -->
21
+ * <span class="icen-ai-diff-verdict" hidden>已接受|已拒绝</span> <!-- 状态章(JS 决策后显示) -->
16
22
  * </div>
17
- * <div class="ai-diff-body" hidden>
18
- * <table class="ai-diff-table">
19
- * <tr class="ai-diff-line--hunk"><td colspan="3">@@ -10,6 +10,8 @@ …</td></tr>
20
- * <tr class="ai-diff-line--ctx|ai-diff-line--add|ai-diff-line--del">
21
- * <td class="ai-diff-ln" aria-hidden="true">10</td>
22
- * <td class="ai-diff-ln" aria-hidden="true">10</td>
23
- * <td class="ai-diff-code">内容(行首符号由 ::before 提供)</td>
23
+ * <div class="icen-ai-diff-body" hidden>
24
+ * <icen-table class="icen-ai-diff-table">
25
+ * <tr class="icen-ai-diff-line--hunk"><td colspan="3">@@ -10,6 +10,8 @@ …</td></tr>
26
+ * <tr class="icen-ai-diff-line--ctx|icen-ai-diff-line--add|icen-ai-diff-line--del">
27
+ * <td class="icen-ai-diff-ln" aria-hidden="true">10</td>
28
+ * <td class="icen-ai-diff-ln" aria-hidden="true">10</td>
29
+ * <td class="icen-ai-diff-code">内容(行首符号由 ::before 提供)</td>
24
30
  * </tr>
25
- * </table>
31
+ * </icen-table>
26
32
  * </div>
27
33
  * </div>
28
34
  * </div>
29
35
  *
30
36
  * 文件 chips(纯 CSS 族,无 behavior;文件图标由消费方/ai-panel.ts 注入 svg):
31
- * <div class="ai-files">
32
- * <span class="ai-file-chip is-added|is-modified|is-deleted
37
+ * <div class="icen-ai-files">
38
+ * <span class="icen-ai-file-chip is-added|is-modified|is-deleted
33
39
  * ai-file-chip--ts|js|css|json|md|img|other">
34
- * <span class="ai-file-icon">…svg…</span>src/foo.ts
40
+ * <span class="icen-ai-file-icon">…svg…</span>src/foo.ts
35
41
  * </span>
36
42
  * </div>
37
43
  *
38
44
  * 状态视觉:
39
45
  * add 行 = success 底 / del 行 = error 底 / hunk 行 = info 文字(bg-soft 底)
40
46
  * 文件头状态色边(inset 左色条):added=success / modified=accent / deleted=error / renamed=info
41
- * .is-accepted / .is-rejected = 整体淡化 + .ai-diff-verdict 状态章,actions 由 JS hidden
47
+ * .is-accepted / .is-rejected = 整体淡化 + .icen-ai-diff-verdict 状态章,actions 由 JS hidden
42
48
  *
43
49
  * 依赖:base.css(--icen-tx-* / --icen-ring / keyframes icen-pop-in)。
44
- * 只消费 --token-* / --density-* / --radius-*;动画时长全部走组件局部变量。
50
+ * 只消费 --icen-token-* / --icen-density-* / --icen-radius-*;动画时长全部走组件局部变量。
45
51
  */
46
52
 
47
53
  /* ══════════════ ai-diff · 差异审阅 ══════════════ */
48
54
 
49
- .ai-diff {
55
+ .icen-ai-diff {
50
56
  display: flex;
51
57
  flex-direction: column;
52
- gap: var(--density-space-sm);
53
- font-size: var(--density-font-size-sm);
58
+ gap: var(--icen-density-space-sm);
59
+ font-size: var(--icen-density-font-size-sm);
54
60
  min-width: 0;
55
61
  align-self: stretch; /* 输出容器宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
56
62
  }
57
63
 
58
- .ai-diff-file {
59
- border: 1px solid var(--token-line-soft);
60
- border-radius: var(--radius-md);
61
- background: var(--token-surface);
64
+ .icen-ai-diff-file {
65
+ border: 1px solid var(--icen-token-line-soft);
66
+ border-radius: var(--icen-radius-md);
67
+ background: var(--icen-token-surface);
62
68
  overflow: hidden;
63
69
  min-width: 0;
64
70
  animation: icen-pop-in var(--ai-diff-pop-duration, var(--icen-tx-fast));
65
71
  }
66
72
 
67
73
  /* 文件头状态色边(inset 色条避免 border 宽差导致布局抖动) */
68
- .ai-diff-file.is-added { box-shadow: inset 3px 0 0 var(--token-success); }
69
- .ai-diff-file.is-modified { box-shadow: inset 3px 0 0 var(--token-accent); }
70
- .ai-diff-file.is-deleted { box-shadow: inset 3px 0 0 var(--token-error); }
71
- .ai-diff-file.is-renamed { box-shadow: inset 3px 0 0 var(--token-info); }
74
+ .icen-ai-diff-file.is-added { box-shadow: inset 3px 0 0 var(--icen-token-success); }
75
+ .icen-ai-diff-file.is-modified { box-shadow: inset 3px 0 0 var(--icen-token-accent); }
76
+ .icen-ai-diff-file.is-deleted { box-shadow: inset 3px 0 0 var(--icen-token-error); }
77
+ .icen-ai-diff-file.is-renamed { box-shadow: inset 3px 0 0 var(--icen-token-info); }
72
78
 
73
- /* 决策后淡化(状态章配色见 .ai-diff-verdict) */
74
- .ai-diff-file.is-accepted,
75
- .ai-diff-file.is-rejected {
79
+ /* 决策后淡化(状态章配色见 .icen-ai-diff-verdict) */
80
+ .icen-ai-diff-file.is-accepted,
81
+ .icen-ai-diff-file.is-rejected {
76
82
  opacity: 0.66;
77
83
  transition: opacity var(--ai-diff-fade-duration, var(--icen-tx-normal));
78
84
  }
79
85
 
80
86
  /* ── head ── */
81
87
 
82
- .ai-diff-head {
88
+ .icen-ai-diff-head {
83
89
  display: flex;
84
90
  align-items: center;
85
- gap: var(--density-space-sm);
86
- padding: var(--density-space-xs) var(--density-space-sm);
91
+ gap: var(--icen-density-space-sm);
92
+ padding: var(--icen-density-space-xs) var(--icen-density-space-sm);
87
93
  min-width: 0;
94
+ }
95
+ /* 折叠真按钮:占满行内容区(path+stat),行为 affordance 全在它身上;与决策钮兄弟平级 */
96
+ .icen-ai-diff-toggle {
97
+ flex: 1;
98
+ min-width: 0;
99
+ display: flex;
100
+ align-items: center;
101
+ gap: var(--icen-density-space-sm);
102
+ padding: 0;
103
+ border: 0;
104
+ background: none;
105
+ font: inherit;
106
+ color: inherit;
107
+ text-align: start;
88
108
  cursor: pointer;
89
109
  user-select: none;
110
+ border-radius: var(--icen-radius-xs);
90
111
  transition: background-color var(--icen-tx-fast);
91
112
  }
92
- .ai-diff-head:hover {
93
- background: var(--token-fill-1);
94
- }
95
- .ai-diff-head:focus-visible {
113
+ .icen-ai-diff-toggle:hover { background: var(--icen-token-fill-1); }
114
+ .icen-ai-diff-toggle:focus-visible {
96
115
  outline: none;
97
116
  box-shadow: var(--icen-ring);
98
117
  }
99
118
 
100
- .ai-diff-path {
119
+ .icen-ai-diff-path {
101
120
  flex: 1;
102
121
  min-width: 0;
103
122
  overflow: hidden;
104
123
  text-overflow: ellipsis;
105
124
  white-space: nowrap;
106
- font-family: var(--font-mono);
107
- font-size: var(--density-font-size-xs);
108
- color: var(--token-text);
125
+ font-family: var(--icen-font-mono);
126
+ font-size: var(--icen-density-font-size-xs);
127
+ color: var(--icen-token-text);
109
128
  }
110
129
 
111
- .ai-diff-stat {
130
+ .icen-ai-diff-stat {
112
131
  flex-shrink: 0;
113
132
  display: inline-flex;
114
- gap: var(--density-space-xs);
115
- font-size: var(--density-font-size-xs);
133
+ gap: var(--icen-density-space-xs);
134
+ font-size: var(--icen-density-font-size-xs);
116
135
  font-variant-numeric: tabular-nums;
117
136
  }
118
- .ai-diff-add { color: var(--token-success); font-weight: 600; }
119
- .ai-diff-del { color: var(--token-error); font-weight: 600; }
137
+ .icen-ai-diff-add { color: var(--icen-token-success); font-weight: 600; }
138
+ .icen-ai-diff-del { color: var(--icen-token-error); font-weight: 600; }
120
139
 
121
140
  /* accept / reject 行内小钮(DOM 无固定类,按 data 属性定位) */
122
- .ai-diff-actions {
141
+ .icen-ai-diff-actions {
123
142
  flex-shrink: 0;
124
143
  display: inline-flex;
125
- gap: var(--density-space-xs);
144
+ gap: var(--icen-density-space-xs);
126
145
  }
127
- .ai-diff-actions button {
146
+ .icen-ai-diff-actions button {
128
147
  padding: 3px 10px;
129
- border: 1px solid var(--token-line-soft);
130
- border-radius: var(--radius-full);
131
- background: var(--token-surface);
132
- color: var(--token-text-muted);
133
- font-size: var(--density-font-size-xs);
148
+ border: 1px solid var(--icen-token-line-soft);
149
+ border-radius: var(--icen-radius-full);
150
+ background: var(--icen-token-surface);
151
+ color: var(--icen-token-text-muted);
152
+ font-size: var(--icen-density-font-size-xs);
134
153
  line-height: 1.4;
135
154
  cursor: pointer;
136
155
  transition:
@@ -138,121 +157,121 @@
138
157
  border-color var(--icen-tx-fast),
139
158
  color var(--icen-tx-fast);
140
159
  }
141
- .ai-diff-actions button:focus-visible {
160
+ .icen-ai-diff-actions button:focus-visible {
142
161
  outline: none;
143
162
  box-shadow: var(--icen-ring);
144
163
  }
145
- .ai-diff-actions [data-ai-diff-accept]:hover {
146
- color: var(--token-success);
147
- border-color: color-mix(in srgb, var(--token-success) 45%, transparent);
148
- background: var(--token-success-muted);
164
+ .icen-ai-diff-actions [data-icen-ai-diff-accept]:hover {
165
+ color: var(--icen-token-success);
166
+ border-color: color-mix(in srgb, var(--icen-token-success) 45%, transparent);
167
+ background: var(--icen-token-success-muted);
149
168
  }
150
- .ai-diff-actions [data-ai-diff-reject]:hover {
151
- color: var(--token-error);
152
- border-color: color-mix(in srgb, var(--token-error) 45%, transparent);
153
- background: var(--token-error-muted);
169
+ .icen-ai-diff-actions [data-icen-ai-diff-reject]:hover {
170
+ color: var(--icen-token-error);
171
+ border-color: color-mix(in srgb, var(--icen-token-error) 45%, transparent);
172
+ background: var(--icen-token-error-muted);
154
173
  }
155
174
 
156
175
  /* 状态章:决策后 JS 置 text + 去 hidden */
157
- .ai-diff-verdict {
176
+ .icen-ai-diff-verdict {
158
177
  flex-shrink: 0;
159
178
  padding: 2px 8px;
160
179
  border: 1px solid currentColor;
161
- border-radius: var(--radius-full);
162
- font-size: var(--density-font-size-xs);
180
+ border-radius: var(--icen-radius-full);
181
+ font-size: var(--icen-density-font-size-xs);
163
182
  font-weight: 500;
164
183
  line-height: 1.4;
165
184
  }
166
- .ai-diff-file.is-accepted .ai-diff-verdict { color: var(--token-success); background: var(--token-success-muted); }
167
- .ai-diff-file.is-rejected .ai-diff-verdict { color: var(--token-error); background: var(--token-error-muted); }
185
+ .icen-ai-diff-file.is-accepted .icen-ai-diff-verdict { color: var(--icen-token-success); background: var(--icen-token-success-muted); }
186
+ .icen-ai-diff-file.is-rejected .icen-ai-diff-verdict { color: var(--icen-token-error); background: var(--icen-token-error-muted); }
168
187
 
169
188
  /* ── body / 表格 ── */
170
189
 
171
- .ai-diff-body {
172
- border-top: 1px solid var(--token-line-soft);
190
+ .icen-ai-diff-body {
191
+ border-top: 1px solid var(--icen-token-line-soft);
173
192
  overflow-x: auto;
174
193
  }
175
194
 
176
- .ai-diff-table {
195
+ .icen-ai-diff-table {
177
196
  width: 100%;
178
197
  border-collapse: collapse;
179
- font-family: var(--font-mono);
180
- font-size: var(--density-font-size-xs);
198
+ font-family: var(--icen-font-mono);
199
+ font-size: var(--icen-density-font-size-xs);
181
200
  line-height: 1.6;
182
201
  }
183
- .ai-diff-table td {
184
- padding: 0 var(--density-space-xs);
202
+ .icen-ai-diff-table td {
203
+ padding: 0 var(--icen-density-space-xs);
185
204
  vertical-align: top;
186
205
  }
187
206
 
188
207
  /* hunk 头:info 文字 */
189
- .ai-diff-line--hunk td {
190
- padding: 2px var(--density-space-sm);
191
- background: var(--token-bg-soft);
192
- color: var(--token-info);
208
+ .icen-ai-diff-line--hunk td {
209
+ padding: 2px var(--icen-density-space-sm);
210
+ background: var(--icen-token-bg-soft);
211
+ color: var(--icen-token-info);
193
212
  user-select: none;
194
213
  white-space: nowrap;
195
214
  }
196
215
 
197
- .ai-diff-ln {
216
+ .icen-ai-diff-ln {
198
217
  width: 1%;
199
218
  min-width: 3.5ch;
200
219
  text-align: right;
201
- color: var(--token-text-faint);
220
+ color: var(--icen-token-text-faint);
202
221
  font-variant-numeric: tabular-nums;
203
222
  user-select: none;
204
223
  }
205
224
  /* 行号区与代码区的分隔线画在第二列右侧 */
206
- .ai-diff-ln + .ai-diff-ln {
207
- border-right: 1px solid var(--token-line-soft);
225
+ .icen-ai-diff-ln + .icen-ai-diff-ln {
226
+ border-right: 1px solid var(--icen-token-line-soft);
208
227
  }
209
228
 
210
229
  /* add = success 底 / del = error 底 */
211
- .ai-diff-line--add { background: var(--token-success-muted); }
212
- .ai-diff-line--del { background: var(--token-error-muted); }
230
+ .icen-ai-diff-line--add { background: var(--icen-token-success-muted); }
231
+ .icen-ai-diff-line--del { background: var(--icen-token-error-muted); }
213
232
 
214
- .ai-diff-code {
233
+ .icen-ai-diff-code {
215
234
  white-space: pre-wrap;
216
235
  word-break: break-all;
217
- padding-left: var(--density-space-sm);
236
+ padding-left: var(--icen-density-space-sm);
218
237
  }
219
238
  /* 行首符号(选择 diff 内容时不带符号) */
220
- .ai-diff-code::before {
239
+ .icen-ai-diff-code::before {
221
240
  user-select: none;
222
241
  }
223
- .ai-diff-line--add .ai-diff-code::before {
242
+ .icen-ai-diff-line--add .icen-ai-diff-code::before {
224
243
  content: '+ ';
225
- color: var(--token-success);
244
+ color: var(--icen-token-success);
226
245
  }
227
- .ai-diff-line--del .ai-diff-code::before {
246
+ .icen-ai-diff-line--del .icen-ai-diff-code::before {
228
247
  content: '− ';
229
- color: var(--token-error);
248
+ color: var(--icen-token-error);
230
249
  }
231
- .ai-diff-line--ctx .ai-diff-code::before {
250
+ .icen-ai-diff-line--ctx .icen-ai-diff-code::before {
232
251
  content: ' ';
233
252
  }
234
253
 
235
254
  /* ══════════════ ai-files · 文件 chips(纯 CSS 族) ══════════════ */
236
255
 
237
- .ai-files {
256
+ .icen-ai-files {
238
257
  display: flex;
239
258
  flex-wrap: wrap;
240
- gap: var(--density-space-xs);
259
+ gap: var(--icen-density-space-xs);
241
260
  align-self: stretch; /* 容器自稳定;chip 自身保持内容宽 */
242
261
  }
243
262
 
244
- .ai-file-chip {
263
+ .icen-ai-file-chip {
245
264
  display: inline-flex;
246
265
  align-items: center;
247
266
  gap: 5px;
248
267
  max-width: 100%;
249
268
  padding: 2px 8px;
250
- border: 1px solid var(--token-line-soft);
251
- border-radius: var(--radius-full);
252
- background: var(--token-surface);
253
- color: var(--token-text-muted);
254
- font-family: var(--font-mono);
255
- font-size: var(--density-font-size-xs);
269
+ border: 1px solid var(--icen-token-line-soft);
270
+ border-radius: var(--icen-radius-full);
271
+ background: var(--icen-token-surface);
272
+ color: var(--icen-token-text-muted);
273
+ font-family: var(--icen-font-mono);
274
+ font-size: var(--icen-density-font-size-xs);
256
275
  line-height: 1.6;
257
276
  overflow: hidden;
258
277
  text-overflow: ellipsis;
@@ -261,51 +280,53 @@
261
280
  background-color var(--icen-tx-fast),
262
281
  border-color var(--icen-tx-fast);
263
282
  }
264
- .ai-file-chip:hover {
265
- background: var(--token-fill-1);
266
- border-color: var(--token-line);
283
+ .icen-ai-file-chip:hover {
284
+ background: var(--icen-token-fill-1);
285
+ border-color: var(--icen-token-line);
267
286
  }
268
287
 
269
288
  /* 状态色点(尾点,纯 CSS) */
270
- .ai-file-chip::after {
289
+ .icen-ai-file-chip::after {
271
290
  content: '';
272
291
  flex-shrink: 0;
273
292
  width: 6px;
274
293
  height: 6px;
275
- border-radius: var(--radius-full);
276
- background: var(--token-text-faint);
294
+ border-radius: var(--icen-radius-full);
295
+ background: var(--icen-token-text-faint);
277
296
  }
278
- .ai-file-chip.is-added::after { background: var(--token-success); }
279
- .ai-file-chip.is-modified::after { background: var(--token-accent); }
280
- .ai-file-chip.is-deleted::after { background: var(--token-error); }
297
+ .icen-ai-file-chip.is-added::after { background: var(--icen-token-success); }
298
+ .icen-ai-file-chip.is-modified::after { background: var(--icen-token-accent); }
299
+ .icen-ai-file-chip.is-deleted::after { background: var(--icen-token-error); }
281
300
 
282
- .ai-file-chip.is-deleted {
301
+ .icen-ai-file-chip.is-deleted {
283
302
  text-decoration: line-through;
284
- opacity: 0.75;
303
+ color: var(--icen-token-text-muted);
285
304
  }
286
305
 
287
- .ai-file-icon {
306
+ .icen-ai-file-icon {
288
307
  flex-shrink: 0;
289
308
  display: inline-flex;
290
- color: var(--token-text-faint);
309
+ color: var(--icen-token-text-faint);
291
310
  }
292
- .ai-file-icon svg {
311
+ .icen-ai-file-icon svg {
293
312
  width: 13px;
294
313
  height: 13px;
295
314
  }
296
315
 
297
316
  /* 文件类型色(语义 token):ts/js=冷调 accent-cold,css=accent,json=warning,md=info,img=success */
298
- .ai-file-chip--ts .ai-file-icon,
299
- .ai-file-chip--js .ai-file-icon { color: var(--token-accent-cold); }
300
- .ai-file-chip--css .ai-file-icon { color: var(--token-accent); }
301
- .ai-file-chip--json .ai-file-icon { color: var(--token-warning); }
302
- .ai-file-chip--md .ai-file-icon { color: var(--token-info); }
303
- .ai-file-chip--img .ai-file-icon { color: var(--token-success); }
317
+ .icen-ai-file-chip--ts .icen-ai-file-icon,
318
+ .icen-ai-file-chip--js .icen-ai-file-icon { color: var(--icen-token-accent-cold); }
319
+ .icen-ai-file-chip--css .icen-ai-file-icon { color: var(--icen-token-accent); }
320
+ .icen-ai-file-chip--json .icen-ai-file-icon { color: var(--icen-token-warning); }
321
+ .icen-ai-file-chip--md .icen-ai-file-icon { color: var(--icen-token-info); }
322
+ .icen-ai-file-chip--img .icen-ai-file-icon { color: var(--icen-token-success); }
304
323
 
305
324
  /* ── 动效守卫 ── */
306
325
 
307
326
  @media (prefers-reduced-motion: reduce) {
308
- .ai-diff-file { animation: none; }
309
- .ai-diff-file.is-accepted,
310
- .ai-diff-file.is-rejected { transition: none; }
327
+ .icen-ai-diff-file { animation: none; }
328
+ .icen-ai-diff-file.is-accepted,
329
+ .icen-ai-diff-file.is-rejected { transition: none; }
330
+ }
331
+
311
332
  }