@icen.ai/ui 0.10.0 → 0.11.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 (355) hide show
  1. package/AGENTS.md +79 -309
  2. package/LICENSE +21 -0
  3. package/README.md +43 -54
  4. package/dist/base.css +57 -16
  5. package/dist/behaviors/accordion.mjs +1 -1
  6. package/dist/behaviors/ai-branch.mjs +1 -0
  7. package/dist/behaviors/ai-chat.d.mts +2 -2
  8. package/dist/behaviors/ai-chat.mjs +53 -10
  9. package/dist/behaviors/ai-composer.d.mts +5 -5
  10. package/dist/behaviors/ai-composer.mjs +21 -10
  11. package/dist/behaviors/ai-core.mjs +1 -0
  12. package/dist/behaviors/ai-diff.mjs +1 -0
  13. package/dist/behaviors/ai-feedback.mjs +1 -0
  14. package/dist/behaviors/ai-panel.d.mts +2 -2
  15. package/dist/behaviors/ai-panel.mjs +1 -0
  16. package/dist/behaviors/ai-provider.d.mts +1 -1
  17. package/dist/behaviors/ai-provider.mjs +1 -0
  18. package/dist/behaviors/ai-threads.mjs +1 -0
  19. package/dist/behaviors/ai-tool.d.mts +1 -1
  20. package/dist/behaviors/ai-tool.mjs +57 -24
  21. package/dist/behaviors/ai-tools.mjs +937 -28
  22. package/dist/behaviors/autocomplete.d.mts +1 -1
  23. package/dist/behaviors/autocomplete.mjs +1 -0
  24. package/dist/behaviors/back-top.mjs +1 -0
  25. package/dist/behaviors/carousel.mjs +8 -1
  26. package/dist/behaviors/cascader.mjs +14 -0
  27. package/dist/behaviors/charts.mjs +56 -20
  28. package/dist/behaviors/code-block.mjs +9 -1
  29. package/dist/behaviors/command-palette.mjs +3 -3
  30. package/dist/behaviors/context-menu.d.mts +2 -2
  31. package/dist/behaviors/context-menu.mjs +1 -0
  32. package/dist/behaviors/controls.d.mts +8 -8
  33. package/dist/behaviors/controls.mjs +37 -6
  34. package/dist/behaviors/copy.mjs +1 -0
  35. package/dist/behaviors/datatable.d.mts +3 -3
  36. package/dist/behaviors/datatable.mjs +76 -11
  37. package/dist/behaviors/date-picker.mjs +1 -0
  38. package/dist/behaviors/events.d.mts +10 -10
  39. package/dist/behaviors/events.mjs +11 -1
  40. package/dist/behaviors/form-validate.d.mts +10 -1
  41. package/dist/behaviors/form-validate.mjs +266 -4611
  42. package/dist/behaviors/i18n.d.mts +1 -0
  43. package/dist/behaviors/i18n.mjs +2 -0
  44. package/dist/behaviors/input.mjs +3 -0
  45. package/dist/behaviors/kb-access.d.mts +2 -2
  46. package/dist/behaviors/kb-access.mjs +8 -2
  47. package/dist/behaviors/kb-acl.d.mts +2 -2
  48. package/dist/behaviors/kb-acl.mjs +1 -0
  49. package/dist/behaviors/kb-answer.d.mts +2 -2
  50. package/dist/behaviors/kb-answer.mjs +56 -23
  51. package/dist/behaviors/kb-audit.d.mts +2 -2
  52. package/dist/behaviors/kb-audit.mjs +1 -0
  53. package/dist/behaviors/kb-canvas.d.mts +3 -3
  54. package/dist/behaviors/kb-canvas.mjs +1 -0
  55. package/dist/behaviors/kb-chain.d.mts +2 -2
  56. package/dist/behaviors/kb-chain.mjs +1 -0
  57. package/dist/behaviors/kb-checkpoint.d.mts +2 -2
  58. package/dist/behaviors/kb-checkpoint.mjs +1 -0
  59. package/dist/behaviors/kb-chunks.d.mts +2 -2
  60. package/dist/behaviors/kb-chunks.mjs +1 -0
  61. package/dist/behaviors/kb-citation.d.mts +2 -2
  62. package/dist/behaviors/kb-citation.mjs +20 -6
  63. package/dist/behaviors/kb-clarify.d.mts +2 -2
  64. package/dist/behaviors/kb-clarify.mjs +1 -0
  65. package/dist/behaviors/kb-conflict.d.mts +2 -2
  66. package/dist/behaviors/kb-conflict.mjs +1 -0
  67. package/dist/behaviors/kb-connector.d.mts +2 -2
  68. package/dist/behaviors/kb-connector.mjs +1 -0
  69. package/dist/behaviors/kb-core.d.mts +1 -1
  70. package/dist/behaviors/kb-core.mjs +1 -0
  71. package/dist/behaviors/kb-eval.d.mts +2 -2
  72. package/dist/behaviors/kb-eval.mjs +8 -2
  73. package/dist/behaviors/kb-explain.d.mts +2 -2
  74. package/dist/behaviors/kb-explain.mjs +13 -2
  75. package/dist/behaviors/kb-filter.d.mts +2 -2
  76. package/dist/behaviors/kb-filter.mjs +8 -2
  77. package/dist/behaviors/kb-gap.d.mts +2 -2
  78. package/dist/behaviors/kb-gap.mjs +1 -0
  79. package/dist/behaviors/kb-hittest.d.mts +2 -2
  80. package/dist/behaviors/kb-hittest.mjs +2 -1
  81. package/dist/behaviors/kb-metadata.mjs +6 -0
  82. package/dist/behaviors/kb-passage.d.mts +2 -2
  83. package/dist/behaviors/kb-passage.mjs +1 -0
  84. package/dist/behaviors/kb-pipeline.d.mts +2 -2
  85. package/dist/behaviors/kb-pipeline.mjs +1 -0
  86. package/dist/behaviors/kb-qa.mjs +1 -0
  87. package/dist/behaviors/kb-rerank.d.mts +2 -2
  88. package/dist/behaviors/kb-rerank.mjs +1 -0
  89. package/dist/behaviors/kb-retrieval.d.mts +2 -2
  90. package/dist/behaviors/kb-retrieval.mjs +18 -4
  91. package/dist/behaviors/kb-review.d.mts +2 -2
  92. package/dist/behaviors/kb-review.mjs +8 -2
  93. package/dist/behaviors/kb-sandbox.d.mts +2 -2
  94. package/dist/behaviors/kb-sandbox.mjs +7 -1
  95. package/dist/behaviors/kb-segment.d.mts +2 -2
  96. package/dist/behaviors/kb-segment.mjs +2 -1
  97. package/dist/behaviors/kb-select.mjs +8 -2
  98. package/dist/behaviors/kb-sources.d.mts +2 -2
  99. package/dist/behaviors/kb-sources.mjs +1 -0
  100. package/dist/behaviors/kb-sql.d.mts +2 -2
  101. package/dist/behaviors/kb-sql.mjs +1 -0
  102. package/dist/behaviors/kb-trace.d.mts +2 -2
  103. package/dist/behaviors/kb-trace.mjs +9 -3
  104. package/dist/behaviors/kb-visibility.d.mts +2 -2
  105. package/dist/behaviors/kb-visibility.mjs +1 -0
  106. package/dist/behaviors/kb-who-can.d.mts +2 -2
  107. package/dist/behaviors/kb-who-can.mjs +8 -2
  108. package/dist/behaviors/mentions.d.mts +1 -1
  109. package/dist/behaviors/mentions.mjs +1 -0
  110. package/dist/behaviors/modal.d.mts +1 -1
  111. package/dist/behaviors/modal.mjs +1 -0
  112. package/dist/behaviors/notification.d.mts +2 -2
  113. package/dist/behaviors/notification.mjs +14 -3
  114. package/dist/behaviors/panel.mjs +1 -0
  115. package/dist/behaviors/scroll-area.d.mts +17 -0
  116. package/dist/behaviors/scroll-area.mjs +59 -0
  117. package/dist/behaviors/select.mjs +8 -2
  118. package/dist/behaviors/slider.mjs +3 -3
  119. package/dist/behaviors/split-pane.mjs +2 -0
  120. package/dist/behaviors/suggestions.mjs +1 -0
  121. package/dist/behaviors/tabs.mjs +10 -0
  122. package/dist/behaviors/tag-input.mjs +1 -0
  123. package/dist/behaviors/theme-switcher.d.mts +2 -2
  124. package/dist/behaviors/theme-switcher.mjs +17 -2
  125. package/dist/behaviors/theme.mjs +16 -2
  126. package/dist/behaviors/toast.d.mts +2 -2
  127. package/dist/behaviors/toast.mjs +1 -0
  128. package/dist/behaviors/tree-select.mjs +14 -0
  129. package/dist/behaviors/tree.mjs +4 -4
  130. package/dist/behaviors/upload.mjs +1 -0
  131. package/dist/behaviors/url-safety.d.mts +8 -0
  132. package/dist/behaviors/url-safety.mjs +11 -0
  133. package/dist/components/accordion.d.mts +2 -0
  134. package/dist/components/ai-branch.d.mts +2 -0
  135. package/dist/components/ai-chat.css +40 -33
  136. package/dist/components/ai-chat.d.mts +2 -0
  137. package/dist/components/ai-composer.d.mts +2 -0
  138. package/dist/components/ai-context.d.mts +2 -0
  139. package/dist/components/ai-context.mjs +1 -0
  140. package/dist/components/ai-diff.css +6 -6
  141. package/dist/components/ai-diff.d.mts +2 -0
  142. package/dist/components/ai-feedback.d.mts +2 -0
  143. package/dist/components/ai-files.d.mts +2 -0
  144. package/dist/components/ai-message.d.mts +2 -0
  145. package/dist/components/ai-panel.css +12 -10
  146. package/dist/components/ai-reasoning.d.mts +2 -0
  147. package/dist/components/ai-subagent.d.mts +2 -0
  148. package/dist/components/ai-subagent.mjs +1 -0
  149. package/dist/components/ai-threads.d.mts +2 -0
  150. package/dist/components/ai-todo.d.mts +2 -0
  151. package/dist/components/ai-todo.mjs +1 -0
  152. package/dist/components/ai-tool-call.d.mts +2 -0
  153. package/dist/components/ai-tool-call.mjs +1 -0
  154. package/dist/components/ai-tool.css +16 -16
  155. package/dist/components/ai-usage.d.mts +2 -0
  156. package/dist/components/alert.d.mts +2 -0
  157. package/dist/components/autocomplete.css +12 -12
  158. package/dist/components/autocomplete.d.mts +2 -0
  159. package/dist/components/avatar.d.mts +2 -0
  160. package/dist/components/back-top.css +47 -16
  161. package/dist/components/back-top.d.mts +2 -0
  162. package/dist/components/badge.css +1 -1
  163. package/dist/components/badge.d.mts +2 -0
  164. package/dist/components/breadcrumb.css +26 -8
  165. package/dist/components/breadcrumb.d.mts +2 -0
  166. package/dist/components/btn.css +67 -62
  167. package/dist/components/btn.d.mts +2 -0
  168. package/dist/components/card.css +22 -22
  169. package/dist/components/card.d.mts +2 -0
  170. package/dist/components/carousel.d.mts +2 -0
  171. package/dist/components/cascader.css +56 -35
  172. package/dist/components/cascader.d.mts +2 -0
  173. package/dist/components/chart-area.css +46 -0
  174. package/dist/components/chart-area.d.mts +2 -0
  175. package/dist/components/chart-bar.css +66 -19
  176. package/dist/components/chart-bar.d.mts +2 -0
  177. package/dist/components/chart-calendar.d.mts +2 -0
  178. package/dist/components/chart-gauge.css +23 -3
  179. package/dist/components/chart-gauge.d.mts +2 -0
  180. package/dist/components/chart-graph.css +15 -3
  181. package/dist/components/chart-graph.d.mts +2 -0
  182. package/dist/components/chart-heatmap.css +117 -95
  183. package/dist/components/chart-heatmap.d.mts +2 -0
  184. package/dist/components/chart-line.css +54 -0
  185. package/dist/components/chart-line.d.mts +2 -0
  186. package/dist/components/chart-map.d.mts +2 -0
  187. package/dist/components/chart-pie.css +29 -0
  188. package/dist/components/chart-pie.d.mts +2 -0
  189. package/dist/components/chart-radar.css +50 -1
  190. package/dist/components/chart-radar.d.mts +2 -0
  191. package/dist/components/chart-scatter.css +39 -2
  192. package/dist/components/chart-scatter.d.mts +2 -0
  193. package/dist/components/chart-sparkline.css +20 -0
  194. package/dist/components/chart-sparkline.d.mts +2 -0
  195. package/dist/components/chart-stack.css +16 -5
  196. package/dist/components/chart-stack.d.mts +2 -0
  197. package/dist/components/charts.css +80 -35
  198. package/dist/components/charts.d.mts +2 -0
  199. package/dist/components/code-block.css +10 -8
  200. package/dist/components/code-block.d.mts +2 -0
  201. package/dist/components/command-palette.css +45 -38
  202. package/dist/components/command-palette.d.mts +2 -0
  203. package/dist/components/content.css +62 -57
  204. package/dist/components/context-menu.d.mts +2 -0
  205. package/dist/components/copy.css +10 -10
  206. package/dist/components/copy.d.mts +2 -0
  207. package/dist/components/datatable.css +72 -59
  208. package/dist/components/datatable.d.mts +2 -0
  209. package/dist/components/date-picker.css +26 -26
  210. package/dist/components/date-picker.d.mts +2 -0
  211. package/dist/components/desc.d.mts +2 -0
  212. package/dist/components/dropdown.d.mts +2 -0
  213. package/dist/components/empty.css +16 -16
  214. package/dist/components/empty.d.mts +2 -0
  215. package/dist/components/feedback.css +31 -29
  216. package/dist/components/form-validate.css +20 -6
  217. package/dist/components/form-validate.d.mts +2 -0
  218. package/dist/components/form.css +17 -14
  219. package/dist/components/form.d.mts +2 -0
  220. package/dist/components/icon.css +21 -10
  221. package/dist/components/icon.d.mts +2 -0
  222. package/dist/components/input.css +22 -22
  223. package/dist/components/input.d.mts +2 -0
  224. package/dist/components/kb-access.d.mts +2 -0
  225. package/dist/components/kb-acl.d.mts +2 -0
  226. package/dist/components/kb-agent.css +134 -55
  227. package/dist/components/kb-answer.d.mts +2 -0
  228. package/dist/components/kb-audit.d.mts +2 -0
  229. package/dist/components/kb-canvas.d.mts +2 -0
  230. package/dist/components/kb-chain.d.mts +2 -0
  231. package/dist/components/kb-checkpoint.d.mts +2 -0
  232. package/dist/components/kb-chunks.d.mts +2 -0
  233. package/dist/components/kb-citation.d.mts +2 -0
  234. package/dist/components/kb-clarify.d.mts +2 -0
  235. package/dist/components/kb-conflict.d.mts +2 -0
  236. package/dist/components/kb-connector.d.mts +2 -0
  237. package/dist/components/kb-data.css +192 -80
  238. package/dist/components/kb-eval.d.mts +2 -0
  239. package/dist/components/kb-explain.d.mts +2 -0
  240. package/dist/components/kb-filter.d.mts +2 -0
  241. package/dist/components/kb-gap.d.mts +2 -0
  242. package/dist/components/kb-ground.css +165 -73
  243. package/dist/components/kb-hittest.d.mts +2 -0
  244. package/dist/components/kb-ingest.css +308 -113
  245. package/dist/components/kb-metadata.d.mts +2 -0
  246. package/dist/components/kb-ops.css +189 -75
  247. package/dist/components/kb-passage.d.mts +2 -0
  248. package/dist/components/kb-perm.css +158 -87
  249. package/dist/components/kb-pipeline.d.mts +2 -0
  250. package/dist/components/kb-qa.d.mts +2 -0
  251. package/dist/components/kb-rerank.d.mts +2 -0
  252. package/dist/components/kb-retrieval.d.mts +2 -0
  253. package/dist/components/kb-review.d.mts +2 -0
  254. package/dist/components/kb-sandbox.d.mts +2 -0
  255. package/dist/components/kb-search.css +353 -116
  256. package/dist/components/kb-segment.d.mts +2 -0
  257. package/dist/components/kb-sources.d.mts +2 -0
  258. package/dist/components/kb-sql.d.mts +2 -0
  259. package/dist/components/kb-trace.d.mts +2 -0
  260. package/dist/components/kb-visibility.d.mts +2 -0
  261. package/dist/components/kb-who-can.d.mts +2 -0
  262. package/dist/components/kb.css +60 -36
  263. package/dist/components/kb.d.mts +2 -0
  264. package/dist/components/kbd.d.mts +2 -0
  265. package/dist/components/layout.css +10 -10
  266. package/dist/components/layout.d.mts +2 -0
  267. package/dist/components/list.d.mts +2 -0
  268. package/dist/components/material-chinese.css +10 -0
  269. package/dist/components/material-soviet.css +10 -0
  270. package/dist/components/material.css +61 -18
  271. package/dist/components/media-card.d.mts +2 -0
  272. package/dist/components/media.css +22 -27
  273. package/dist/components/mentions.css +18 -17
  274. package/dist/components/mentions.d.mts +2 -0
  275. package/dist/components/menu.css +32 -28
  276. package/dist/components/modal.css +30 -27
  277. package/dist/components/modal.d.mts +2 -0
  278. package/dist/components/nav.css +48 -44
  279. package/dist/components/nav.d.mts +2 -0
  280. package/dist/components/notification.css +31 -25
  281. package/dist/components/notification.d.mts +2 -0
  282. package/dist/components/pagination.css +15 -13
  283. package/dist/components/pagination.d.mts +2 -0
  284. package/dist/components/panel.css +19 -20
  285. package/dist/components/panel.d.mts +2 -0
  286. package/dist/components/pill.css +8 -7
  287. package/dist/components/pill.d.mts +2 -0
  288. package/dist/components/popover.css +32 -23
  289. package/dist/components/popover.d.mts +2 -0
  290. package/dist/components/progress.d.mts +2 -0
  291. package/dist/components/rating.d.mts +2 -0
  292. package/dist/components/result.d.mts +2 -0
  293. package/dist/components/scroll-area.css +84 -112
  294. package/dist/components/scroll-area.d.mts +2 -0
  295. package/dist/components/scroll-area.mjs +1 -0
  296. package/dist/components/segmented.css +47 -29
  297. package/dist/components/segmented.d.mts +2 -0
  298. package/dist/components/select.css +80 -41
  299. package/dist/components/select.d.mts +2 -0
  300. package/dist/components/sidebar.css +42 -38
  301. package/dist/components/sidebar.d.mts +2 -0
  302. package/dist/components/skeleton.d.mts +2 -0
  303. package/dist/components/slider.css +26 -22
  304. package/dist/components/slider.d.mts +2 -0
  305. package/dist/components/spinner.d.mts +2 -0
  306. package/dist/components/split-pane.css +16 -7
  307. package/dist/components/split-pane.d.mts +2 -0
  308. package/dist/components/stat.css +17 -16
  309. package/dist/components/stat.d.mts +2 -0
  310. package/dist/components/steps.css +26 -26
  311. package/dist/components/steps.d.mts +2 -0
  312. package/dist/components/switch.css +78 -39
  313. package/dist/components/switch.d.mts +2 -0
  314. package/dist/components/table.css +54 -32
  315. package/dist/components/table.d.mts +2 -0
  316. package/dist/components/tabs.css +53 -32
  317. package/dist/components/tabs.d.mts +2 -0
  318. package/dist/components/tag-input.css +12 -8
  319. package/dist/components/tag-input.d.mts +2 -0
  320. package/dist/components/tag.css +20 -12
  321. package/dist/components/tag.d.mts +2 -0
  322. package/dist/components/theme-switcher.css +7 -7
  323. package/dist/components/theme-switcher.d.mts +2 -0
  324. package/dist/components/timeline.d.mts +2 -0
  325. package/dist/components/toast.css +34 -30
  326. package/dist/components/toast.d.mts +2 -0
  327. package/dist/components/toolbar.css +19 -18
  328. package/dist/components/toolbar.d.mts +2 -0
  329. package/dist/components/tooltip.css +9 -8
  330. package/dist/components/tooltip.d.mts +2 -0
  331. package/dist/components/tree-select.css +63 -40
  332. package/dist/components/tree-select.d.mts +2 -0
  333. package/dist/components/tree.d.mts +2 -0
  334. package/dist/components/upload.css +9 -11
  335. package/dist/components/upload.d.mts +2 -0
  336. package/dist/index.d.mts +85 -84
  337. package/dist/index.mjs +14764 -14311
  338. package/dist/react.d.mts +18 -18
  339. package/dist/react.mjs +135 -36
  340. package/dist/registry.json +795 -64
  341. package/dist/tokens/colors.css +6 -0
  342. package/dist/tokens/design.css +130 -30
  343. package/dist/tokens/dtcg.json +6189 -1461
  344. package/dist/tokens/figma.variables.json +4107 -345
  345. package/dist/tokens/pixel.css +3 -0
  346. package/dist/tokens/scrollbars.css +40 -0
  347. package/dist/tokens/tokens-studio.json +5191 -271
  348. package/dist/tokens.css +304 -81
  349. package/dist/ui.css +4050 -2148
  350. package/dist/vue.d.mts +17 -17
  351. package/dist/vue.mjs +129 -34
  352. package/docs/spec/design-philosophy.md +5 -5
  353. package/docs/spec/design-primitives.md +10 -10
  354. package/docs/spec/scrollbars.md +46 -0
  355. package/package.json +16 -3
package/dist/tokens.css CHANGED
@@ -359,6 +359,12 @@
359
359
  --icen-token-surface-glass: color-mix(in srgb, var(--icen-token-surface) var(--icen-design-glass-opacity), transparent);
360
360
  --icen-token-overlay-bg: var(--icen-token-surface-glass);
361
361
  --icen-token-scrollbar-size: 8px;
362
+ --icen-token-scrollbar-size-sm: 6px;
363
+ --icen-token-scrollbar-size-lg: 12px;
364
+ --icen-token-scrollbar-inset: 2px;
365
+ --icen-token-scrollbar-gutter: auto;
366
+ --icen-token-scrollbar-idle-delay: 900ms;
367
+ --icen-token-scrollbar-fade-duration: var(--icen-duration-normal);
362
368
  --icen-token-scrollbar-track: transparent;
363
369
  --icen-token-scrollbar-thumb: color-mix(in srgb, var(--icen-design-ink) 22%, transparent);
364
370
  --icen-token-scrollbar-thumb-hover: color-mix(in srgb, var(--icen-design-ink) 38%, transparent);
@@ -394,6 +400,46 @@
394
400
  }
395
401
 
396
402
 
403
+ /* ── tokens/scrollbars.css ── */
404
+ /* Policy slots inherit across a component subtree; activity never inherits.
405
+ Without the optional behavior, auto/scroll retain a visible fallback. */
406
+ :where([data-icen-scrollbars-ready]) {
407
+ --icen-scrollbar-auto-idle: 0%;
408
+ --icen-scrollbar-idle: var(--icen-scrollbar-auto-idle);
409
+ --icen-scrollbar-hover: var(--icen-scrollbar-auto-idle);
410
+ }
411
+ :where([data-icen-scrollbars='auto'], [data-icen-scrollbars='scroll']) {
412
+ --icen-scrollbar-idle: var(--icen-scrollbar-auto-idle, 100%);
413
+ --icen-scrollbar-hover: 100%;
414
+ --icen-scrollbar-active: 100%;
415
+ --icen-scrollbar-width: thin;
416
+ --icen-scrollbar-webkit-width: auto;
417
+ --icen-scrollbar-display: block;
418
+ }
419
+ :where([data-icen-scrollbars='scroll']) {
420
+ --icen-scrollbar-hover: var(--icen-scrollbar-auto-idle, 100%);
421
+ }
422
+ :where([data-icen-scrollbars='visible']) {
423
+ --icen-scrollbar-idle: 100%;
424
+ --icen-scrollbar-hover: 100%;
425
+ --icen-scrollbar-active: 100%;
426
+ --icen-scrollbar-width: thin;
427
+ --icen-scrollbar-webkit-width: auto;
428
+ --icen-scrollbar-display: block;
429
+ }
430
+ :where([data-icen-scrollbars='hidden']) {
431
+ --icen-scrollbar-idle: 0%;
432
+ --icen-scrollbar-hover: 0%;
433
+ --icen-scrollbar-active: 0%;
434
+ --icen-scrollbar-width: none;
435
+ --icen-scrollbar-webkit-width: none;
436
+ --icen-scrollbar-display: none;
437
+ }
438
+ :where([data-icen-scrollbar-gutter='stable']) { --icen-token-scrollbar-gutter: stable; }
439
+ :where([data-icen-scrollbar-gutter='both-edges']) { --icen-token-scrollbar-gutter: stable both-edges; }
440
+ :where([data-icen-scrollbar-gutter='auto']) { --icen-token-scrollbar-gutter: auto; }
441
+
442
+
397
443
  /* ── tokens/style-profiles.css ── */
398
444
  /* Shared fallback defaults. Built-in primitive recipes live in design/pixel/chinese/soviet.css. */
399
445
  :root {
@@ -500,64 +546,153 @@ h1, h2, h3, h4, h5, h6 {
500
546
 
501
547
 
502
548
  /* ── tokens/design.css ── */
503
- /* 现代 primitive: geometry, type, rhythm and lighting. Color palettes live in themes.json. */
549
+ /* 现代 primitive: geometry, type, rhythm and lighting. Color palettes live in themes.json.
550
+ *
551
+ * The default primitive describes a precise desktop application surface: compact
552
+ * controls, restrained type, layered neutral surfaces and short, purposeful
553
+ * feedback. All values are semantic inputs; components never hardcode them.
554
+ * Other primitives (chinese / soviet / pixel) override this file's seeds and keep
555
+ * their own identity, so every rule here remains palette- and primitive-safe.
556
+ */
504
557
  :root {
558
+ /* ── Control geometry ── */
505
559
  --icen-design-radius: 10px;
506
560
  --icen-design-space: 4px;
507
- --icen-design-control-height: 40px;
508
- --icen-design-font-size: 14px;
509
- --icen-design-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
510
- --icen-design-glass-blur: 20px;
561
+ --icen-design-control-height: 34px;
562
+ --icen-design-font-size: 13px;
563
+ --icen-design-font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI Variable Text',
564
+ 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
565
+ --icen-design-glass-blur: 24px;
511
566
  --icen-design-motion: 1;
512
- }
513
567
 
514
- /* Materials and geometry belong to the primitive, across every palette. */
568
+ /* Semantic aliases consumed by component CSS. The height scale follows the
569
+ * active density; the aliases exist so components read intent, not arithmetic. */
570
+ --icen-control-height-sm: var(--icen-density-input-height-sm);
571
+ --icen-control-height-md: var(--icen-density-input-height-md);
572
+ --icen-control-height-lg: var(--icen-density-input-height-lg);
573
+ --icen-control-radius-sm: var(--icen-radius-sm);
574
+ --icen-control-radius: var(--icen-radius-sm);
575
+ --icen-control-radius-lg: var(--icen-radius-md);
576
+ --icen-control-padding-inline-sm: 9px;
577
+ --icen-control-padding-inline: 12px;
578
+ --icen-control-padding-inline-lg: 16px;
579
+ --icen-field-padding-inline: 9px;
580
+ --icen-field-padding-inline-sm: 8px;
581
+ --icen-control-gap: 6px;
582
+ --icen-control-gap-sm: 4px;
583
+ --icen-control-icon: 15px;
584
+ --icen-control-border-width: 1px;
585
+
586
+ /* Type roles. Sizes stay on the density scale; these aliases name the role. */
587
+ --icen-font-size-title: var(--icen-density-font-size-lg);
588
+ --icen-font-size-section: var(--icen-density-font-size-md);
589
+ --icen-font-size-control: var(--icen-density-font-size-md);
590
+ --icen-font-size-caption: var(--icen-density-font-size-xs);
591
+ --icen-font-weight-control: 500;
592
+ --icen-font-weight-title: 600;
593
+ --icen-font-weight-label: 500;
594
+ --icen-letter-spacing-control: -.006em;
595
+ --icen-letter-spacing-caption: .01em;
596
+
597
+ /* Motion: one-shot state changes are short; spatial entrances use the enter
598
+ * curve. No bouncy physics for ordinary controls. */
599
+ --icen-duration-fast: calc(110ms * var(--icen-design-motion));
600
+ --icen-duration-normal: calc(180ms * var(--icen-design-motion));
601
+ --icen-duration-slow: calc(260ms * var(--icen-design-motion));
602
+ --icen-ease-out: cubic-bezier(.22, .8, .24, 1);
603
+ --icen-ease-in: cubic-bezier(.5, 0, .8, .2);
604
+ --icen-ease-in-out: cubic-bezier(.45, 0, .25, 1);
605
+ --icen-ease-enter: cubic-bezier(.16, 1, .3, 1);
606
+ --icen-ease-exit: cubic-bezier(.4, 0, 1, 1);
607
+ --icen-ease-bounce: var(--icen-ease-out);
608
+ --icen-hover-border: var(--icen-token-line);
609
+ --icen-hover-border-strong: var(--icen-token-line-strong);
610
+ --icen-press: scale(.985);
611
+ --icen-press-soft: none;
612
+ --icen-disabled-opacity: .45;
613
+ --icen-ring: 0 0 0 2px var(--icen-token-surface), 0 0 0 4px color-mix(in srgb, var(--icen-token-accent) 62%, transparent);
614
+ --icen-ring-soft: 0 0 0 3px color-mix(in srgb, var(--icen-token-accent) 18%, transparent);
615
+ --icen-control-focus-border: color-mix(in srgb, var(--icen-token-accent) 62%, var(--icen-token-line));
616
+ --icen-control-focus-shadow: inset 0 1px 2px color-mix(in srgb, var(--icen-design-shadow-color) 8%, transparent), 0 0 0 3px color-mix(in srgb, var(--icen-token-accent) 18%, transparent);
617
+
618
+ /* Material motion: chrome and floating surfaces share a blur radius family. */
619
+ --icen-material-blur-chrome: 18px;
620
+ --icen-material-blur-floating: 28px;
621
+ --icen-material-saturate: 1.4;
622
+ }
623
+
624
+ /* Materials and geometry belong to the primitive, across every palette.
625
+ * Recompute the whole derived surface at each palette/theme boundary so an
626
+ * inherited resolved value can never freeze across a theme switch. */
515
627
  :root, [data-icen-preset], [data-icen-theme="dark"] {
628
+ /* Surface hierarchy: canvas → content → chrome → floating → modal. Chrome and
629
+ * toolbar sit between canvas and content; selected rows are a tinted content
630
+ * surface, not a second card. */
631
+ --icen-token-surface-chrome: color-mix(in srgb, var(--icen-design-canvas) 46%, var(--icen-design-surface));
632
+ --icen-token-surface-toolbar: color-mix(in srgb, var(--icen-design-canvas) 38%, var(--icen-design-surface));
633
+ --icen-token-surface-sidebar: color-mix(in srgb, var(--icen-design-canvas) 66%, var(--icen-design-surface));
634
+ --icen-token-surface-content: var(--icen-design-surface);
635
+ --icen-token-surface-raised: var(--icen-design-raised);
636
+ --icen-token-surface-pressed: color-mix(in srgb, var(--icen-design-ink) 8%, var(--icen-design-surface));
637
+ --icen-token-surface-selected: var(--icen-token-accent-subtle);
638
+
639
+ /* Interaction fills. Hover is a hint, pressed a physical push, selected a
640
+ * persistent state; none of them is used as a substitute for another. */
641
+ --icen-token-fill-hover: color-mix(in srgb, var(--icen-design-ink) 5%, transparent);
642
+ --icen-token-fill-pressed: color-mix(in srgb, var(--icen-design-ink) 9%, transparent);
643
+ --icen-token-fill-selected: color-mix(in srgb, var(--icen-design-accent) 13%, transparent);
644
+ --icen-token-separator-soft: var(--icen-token-line-soft);
645
+ --icen-token-separator: var(--icen-token-line);
646
+ --icen-token-separator-strong: var(--icen-token-line-strong);
647
+ --icen-token-focus-indicator: color-mix(in srgb, var(--icen-token-accent) 62%, transparent);
648
+ --icen-token-control-border: color-mix(in srgb, var(--icen-design-ink) 19%, transparent);
649
+ --icen-token-control-border-hover: color-mix(in srgb, var(--icen-design-ink) 28%, transparent);
516
650
  --icen-token-surface-glass: color-mix(in srgb, var(--icen-token-surface) var(--icen-design-glass-opacity), transparent);
651
+ --icen-token-surface-glass-chrome: color-mix(in srgb, var(--icen-token-surface-toolbar) 88%, transparent);
652
+
517
653
  /* Contact, near-field and ambient shadows share a light source. Negative
518
654
  * spread keeps the shadow under the object instead of fogging its outline. */
519
- --icen-token-shadow-card: 0 1px 2px -1px color-mix(in srgb, var(--icen-design-shadow-color) var(--icen-design-shadow-strength), transparent), 0 4px 10px -5px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .7), transparent), 0 12px 24px -12px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .5), transparent);
520
- --icen-token-shadow-elevated: 0 1px 3px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .75), transparent), 0 8px 20px -8px color-mix(in srgb, var(--icen-design-shadow-color) var(--icen-design-shadow-strength), transparent), 0 24px 48px -16px color-mix(in srgb, var(--icen-design-shadow-color) var(--icen-design-shadow-strength), transparent);
521
- --icen-token-shadow-overlay: 0 2px 6px color-mix(in srgb, var(--icen-design-shadow-color) var(--icen-design-shadow-strength), transparent), 0 16px 36px -12px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * 1.2), transparent), 0 40px 88px -24px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * 1.2), transparent);
655
+ --icen-token-shadow-card:
656
+ 0 1px 1px -1px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .5), transparent),
657
+ 0 3px 8px -4px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .55), transparent),
658
+ 0 10px 24px -16px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .45), transparent);
659
+ --icen-token-shadow-elevated:
660
+ 0 1px 2px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .55), transparent),
661
+ 0 8px 20px -8px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .8), transparent),
662
+ 0 26px 52px -22px color-mix(in srgb, var(--icen-design-shadow-color) var(--icen-design-shadow-strength), transparent);
663
+ --icen-token-shadow-overlay:
664
+ 0 2px 6px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .7), transparent),
665
+ 0 16px 36px -12px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * 1.1), transparent),
666
+ 0 44px 88px -28px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * 1.15), transparent);
667
+ --icen-token-shadow-control:
668
+ inset 0 1px 0 color-mix(in srgb, var(--icen-token-top-highlight) 55%, transparent),
669
+ 0 1px 1.5px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .38), transparent);
670
+ --icen-token-shadow-field: inset 0 1px 2px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .3), transparent);
522
671
  --icen-token-top-highlight: color-mix(in srgb, var(--icen-design-light) var(--icen-design-highlight-strength), transparent);
523
672
  --icen-token-shadow-inset: inset 0 1px 2px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .35), transparent), inset 0 -1px 0 color-mix(in srgb, var(--icen-token-top-highlight) 45%, transparent);
524
673
  --icen-token-shadow-popover: var(--icen-token-shadow-elevated);
525
674
  --icen-token-material-edge: color-mix(in srgb, var(--icen-token-text) var(--icen-design-edge-strength), transparent);
526
675
  --icen-token-material-light: inset 0 1px 0 var(--icen-token-top-highlight), inset 0 -1px 0 color-mix(in srgb, var(--icen-token-top-highlight) 18%, transparent);
527
- --icen-token-scrim: color-mix(in srgb, var(--icen-design-shadow-color) 32%, transparent);
676
+ --icen-token-scrim: color-mix(in srgb, var(--icen-design-shadow-color) 38%, transparent);
528
677
  }
529
678
 
530
679
  :root {
531
680
  --icen-design-light: #ffffff;
532
- --icen-radius-xs: max(0px, calc(var(--icen-design-radius) - 6px));
681
+ --icen-radius-xs: max(0px, calc(var(--icen-design-radius) - 5px));
533
682
  --icen-radius-sm: max(0px, calc(var(--icen-design-radius) - 2px));
534
683
  --icen-radius-md: var(--icen-design-radius);
535
- --icen-radius-lg: calc(var(--icen-design-radius) + 6px);
536
- --icen-radius-xl: calc(var(--icen-design-radius) + 14px);
684
+ --icen-radius-lg: calc(var(--icen-design-radius) + 4px);
685
+ --icen-radius-xl: calc(var(--icen-design-radius) + 10px);
537
686
  --icen-radius-full: 999px;
538
687
  --icen-font-body: var(--icen-design-font);
539
688
  --icen-font-heading: var(--icen-design-font);
540
689
  --icen-font-cjk: var(--icen-design-font);
541
- --icen-font-mono: ui-monospace, SFMono-Regular, Consolas, monospace;
690
+ --icen-font-mono: ui-monospace, 'SF Mono', SFMono-Regular, 'Cascadia Mono', 'Segoe UI Mono', Consolas, monospace;
542
691
  --icen-font-mono-paper: var(--icen-font-mono);
543
- --icen-line-height-body: 1.55;
692
+ --icen-line-height-body: 1.5;
544
693
  --icen-line-height-heading: 1.25;
545
694
  --icen-letter-spacing-body: 0;
546
- --icen-letter-spacing-heading: -.02em;
547
- --icen-duration-fast: calc(120ms * var(--icen-design-motion));
548
- --icen-duration-normal: calc(180ms * var(--icen-design-motion));
549
- --icen-duration-slow: calc(260ms * var(--icen-design-motion));
550
- --icen-ease-out: cubic-bezier(.16, 1, .3, 1);
551
- --icen-ease-bounce: var(--icen-ease-out);
552
- --icen-hover-border: var(--icen-token-line);
553
- --icen-hover-border-strong: var(--icen-token-line-strong);
554
- --icen-press: scale(.985);
555
- --icen-press-soft: scale(.99);
556
- --icen-disabled-opacity: .48;
557
- --icen-ring: 0 0 0 2px var(--icen-token-surface), 0 0 0 4px var(--icen-token-accent);
558
- --icen-ring-soft: 0 0 0 3px var(--icen-token-accent-subtle);
559
- --icen-control-focus-border: var(--icen-token-accent);
560
- --icen-control-focus-shadow: var(--icen-token-shadow-inset), var(--icen-ring-soft);
695
+ --icen-letter-spacing-heading: -.015em;
561
696
  }
562
697
 
563
698
  /* Density changes rhythm and row height, never shrinks reading text. Re-declare
@@ -578,6 +713,12 @@ h1, h2, h3, h4, h5, h6 {
578
713
  --icen-density-input-height-sm: max(28px, calc(var(--icen-design-control-height) + var(--icen-design-density-offset) - 8px));
579
714
  --icen-density-input-height-md: calc(var(--icen-design-control-height) + var(--icen-design-density-offset));
580
715
  --icen-density-input-height-lg: calc(var(--icen-design-control-height) + var(--icen-design-density-offset) + 8px);
716
+ --icen-density-item-height: max(24px, calc(var(--icen-design-control-height) + var(--icen-design-density-offset) - 6px));
717
+ /* 控件高度别名必须在密度边界重新声明:只写在 :root 会在根上解析成固定值,
718
+ * 之后嵌套 [data-icen-density] 覆盖密度时不再联动。 */
719
+ --icen-control-height-sm: var(--icen-density-input-height-sm);
720
+ --icen-control-height-md: var(--icen-density-input-height-md);
721
+ --icen-control-height-lg: var(--icen-density-input-height-lg);
581
722
  --icen-density-font-size-2xs: max(12px, calc(var(--icen-design-font-size) - 2px));
582
723
  --icen-density-font-size-xs: max(12px, calc(var(--icen-design-font-size) - 2px));
583
724
  --icen-density-font-size-sm: max(12px, calc(var(--icen-design-font-size) - 1px));
@@ -585,6 +726,10 @@ h1, h2, h3, h4, h5, h6 {
585
726
  --icen-density-font-size-lg: calc(var(--icen-design-font-size) + 2px);
586
727
  --icen-density-font-size-xl: calc(var(--icen-design-font-size) + 6px);
587
728
  --icen-density-font-size-2xl: calc(var(--icen-design-font-size) + 12px);
729
+ --icen-font-size-title: var(--icen-density-font-size-lg);
730
+ --icen-font-size-section: var(--icen-density-font-size-md);
731
+ --icen-font-size-control: var(--icen-density-font-size-md);
732
+ --icen-font-size-caption: var(--icen-density-font-size-xs);
588
733
  }
589
734
  :root[data-icen-density="compact"],
590
735
  :root [data-icen-density="compact"] {
@@ -601,6 +746,7 @@ h1, h2, h3, h4, h5, h6 {
601
746
  --icen-density-input-height-sm: max(44px, calc(var(--icen-design-control-height) + var(--icen-design-density-offset) - 8px));
602
747
  --icen-density-input-height-md: max(44px, calc(var(--icen-design-control-height) + var(--icen-design-density-offset)));
603
748
  --icen-density-input-height-lg: max(44px, calc(var(--icen-design-control-height) + var(--icen-design-density-offset) + 8px));
749
+ --icen-density-item-height: max(44px, calc(var(--icen-design-control-height) + var(--icen-design-density-offset) - 6px));
604
750
  }
605
751
  }
606
752
  @media (prefers-reduced-motion: reduce) {
@@ -741,6 +887,9 @@ h1, h2, h3, h4, h5, h6 {
741
887
  --icen-ring: 0 0 0 2px var(--icen-token-surface), 0 0 0 4px var(--icen-token-accent);
742
888
  --icen-ring-soft: 0 0 0 2px var(--icen-token-accent);
743
889
  --icen-control-focus-shadow: 0 0 0 2px var(--icen-token-accent);
890
+ /* shadow-inset 被本原语置 none,base.css 合成的 error 版会变成非法的「none, …」
891
+ 列表 → 整条 box-shadow 失效:像素原语自持一份硬边错误光环 */
892
+ --icen-control-error-shadow: 0 0 0 2px var(--icen-token-error);
744
893
  --icen-ease-out: steps(1, end);
745
894
  --icen-ease-bounce: steps(1, end);
746
895
  }
@@ -829,17 +978,21 @@ h1, h2, h3, h4, h5, h6 {
829
978
  @layer icen.components {
830
979
  /* Material contract (default 现代 primitive; theme via data-icen-preset):
831
980
  * <section data-icen-material="content|chrome|floating">arbitrary content</section>
832
- * content = opaque reading; chrome = translucent navigation; floating = temporary
981
+ * content = opaque reading; chrome = navigation; floating = temporary
833
982
  * operations. HTML primitives need no JS. Existing components consume the same
834
983
  * recipes automatically. Force opaque via html[data-icen-transparency="reduced"].
835
984
  * This file ships with tokens.css as well as ui.css; kit consumers need no extras.
985
+ *
986
+ * 分层登记(guard: tier-direction 文件级白名单):材料适配是横切层——选中态/磨砂
987
+ * 配方覆盖 .icen-ai-composer-popup* 与 .icen-kb-checkpoint-menu-item 等 Beta 类名;
988
+ * Beta 类名变更对本文件仅静默降级,不破坏 Core 用户,故允许 Core 引用 Beta。
836
989
  */
837
990
  /* The base layer also defines interaction defaults. Keep the primitive's
838
991
  * interaction recipe in the components layer so separately imported base.css
839
992
  * cannot quietly restore a different press/focus model. */
840
993
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) {
841
994
  --icen-press: scale(.985);
842
- --icen-press-soft: scale(.99);
995
+ --icen-press-soft: none;
843
996
  --icen-hover-border: var(--icen-token-line);
844
997
  --icen-hover-border-strong: var(--icen-token-line-strong);
845
998
  --icen-ring: 0 0 0 2px var(--icen-token-surface), 0 0 0 4px var(--icen-token-accent);
@@ -951,23 +1104,21 @@ h1, h2, h3, h4, h5, h6 {
951
1104
  }
952
1105
  :root .icen-nav { box-shadow: var(--icen-token-material-light); }
953
1106
  :root .icen-btn {
954
- --btn-border-hover: var(--icen-token-line);
955
- gap: var(--icen-density-space-sm);
956
- border-radius: var(--icen-radius-md);
957
- letter-spacing: 0;
1107
+ --btn-border-hover: var(--icen-hover-border);
1108
+ gap: var(--icen-control-gap);
1109
+ border-radius: var(--icen-control-radius);
1110
+ letter-spacing: var(--icen-letter-spacing-control);
958
1111
  }
959
1112
  :root .icen-btn-primary { --btn-border-hover: var(--icen-token-accent-strong); }
960
1113
  :root :is(.icen-btn-ghost,.icen-btn-link) { --btn-border-hover: transparent; }
961
1114
  :root .icen-btn-link { --btn-fg: var(--icen-token-accent-text); }
962
- :root .icen-btn-primary:hover:not(:focus-visible) { box-shadow: none; }
963
- :root .icen-btn:active:not(:disabled):not([aria-disabled="true"]):not([data-icen-disabled]):not(.is-loading) { transform: var(--icen-press-soft); }
964
- :root .icen-btn-danger:hover { color: var(--icen-token-error); background: var(--icen-token-error-muted); }
965
- :root .icen-segmented { padding: var(--icen-density-space-xs); gap: var(--icen-density-space-xs); }
966
- :root .icen-segmented-item { border-radius: max(0px, calc(var(--icen-radius-md) - var(--icen-density-space-xs) - 1px)); }
1115
+ :root .icen-btn-danger:hover:not(:disabled) { color: var(--icen-token-error); background: var(--icen-token-error-muted); }
1116
+ :root .icen-segmented { padding: 3px; gap: 2px; }
1117
+ :root .icen-segmented-item { border-radius: max(0px, calc(var(--icen-radius-md) - 4px)); }
967
1118
  :root :is(.icen-segmented-item.is-active,.icen-segmented-item[aria-checked="true"],.icen-toggle-group-btn.is-active) {
968
1119
  background: var(--icen-token-surface);
969
1120
  color: var(--icen-token-text);
970
- box-shadow: var(--icen-token-shadow-card);
1121
+ box-shadow: var(--icen-token-shadow-control);
971
1122
  }
972
1123
  :root :is(.icen-menu,.icen-popover,.icen-select-panel) { border-radius: var(--icen-radius-lg); }
973
1124
  :root .icen-modal {
@@ -980,33 +1131,74 @@ h1, h2, h3, h4, h5, h6 {
980
1131
  -webkit-backdrop-filter: none;
981
1132
  }
982
1133
  :root .icen-card--elevated { box-shadow: var(--icen-token-shadow-card); }
983
- :root .icen-card--interactive:hover { transform: none; border-color: var(--icen-token-line); }
1134
+ :root .icen-card--interactive:hover { transform: none; border-color: var(--icen-token-control-border-hover); }
984
1135
  :root .icen-card--interactive:focus-within { box-shadow: var(--icen-ring); }
985
- :root .icen-switch-thumb { background: var(--icen-token-text-muted); }
986
- :root .icen-switch[aria-checked="true"] .icen-switch-thumb { background: var(--icen-token-on-accent); }
987
- :root .icen-input-wrap--sm { padding-inline: var(--icen-density-space-sm); }
988
1136
  /* 现代: small controls have a legible edge and a quiet, tactile surface. Keep
989
1137
  * these optical refinements local to the default primitive; other primitives
990
1138
  * supply their own surface physics without fighting a global component rule. */
991
1139
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-btn:not(.icen-btn-ghost):not(.icen-btn-link) {
992
- box-shadow: inset 0 1px 0 color-mix(in srgb, var(--icen-token-top-highlight) 45%, transparent), 0 1px 2px color-mix(in srgb, var(--icen-design-shadow-color) calc(var(--icen-design-shadow-strength) * .35), transparent);
1140
+ background-image: linear-gradient(
1141
+ to bottom,
1142
+ color-mix(in srgb, var(--icen-token-top-highlight) 32%, transparent),
1143
+ transparent 52%
1144
+ );
1145
+ box-shadow: var(--icen-token-shadow-control);
1146
+ }
1147
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-btn-primary {
1148
+ background-image: linear-gradient(
1149
+ to bottom,
1150
+ color-mix(in srgb, var(--icen-token-top-highlight) 16%, transparent),
1151
+ transparent 58%
1152
+ );
993
1153
  }
994
1154
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-btn:focus-visible {
995
1155
  box-shadow: var(--icen-ring);
996
1156
  }
1157
+ /* Stable opaque planes keep content readable over any application backdrop. */
1158
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) :is([data-icen-material],.icen-menu,.icen-popover,.icen-select-panel,.icen-date-picker-panel,.icen-autocomplete-panel,.icen-cascader-panel,.icen-tree-select-panel,.icen-mentions-panel,.icen-ai-composer-popup,.icen-command-palette,.icen-card--glass,.icen-nav,.icen-toast,.icen-notification,.icen-chart-tooltip,.icen-back-top,.icen-carousel-arrow) {
1159
+ background: var(--icen-token-surface);
1160
+ backdrop-filter: none;
1161
+ -webkit-backdrop-filter: none;
1162
+ }
1163
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) [data-icen-material="chrome"] {
1164
+ background: var(--icen-token-surface-toolbar);
1165
+ }
1166
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-nav.is-scrolled {
1167
+ background: var(--icen-token-surface-toolbar);
1168
+ }
1169
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) :is(.icen-card-tag,.icen-media-card-overlay,.icen-carousel-dot,.icen-carousel-index,.icen-spinner-overlay) {
1170
+ backdrop-filter: none;
1171
+ -webkit-backdrop-filter: none;
1172
+ }
997
1173
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-btn:active:not(:disabled):not([aria-disabled="true"]):not([data-icen-disabled]):not(.is-loading) {
1174
+ background-image: none;
998
1175
  box-shadow: var(--icen-token-shadow-inset);
999
1176
  }
1000
1177
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-btn:active:focus-visible {
1001
1178
  box-shadow: var(--icen-token-shadow-inset), var(--icen-ring);
1002
1179
  }
1003
1180
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) :is(.icen-input-wrap,.icen-textarea-wrap) {
1004
- padding-inline: var(--icen-density-space-md);
1181
+ padding-inline: var(--icen-field-padding-inline);
1182
+ padding-block: 0;
1005
1183
  }
1006
1184
  :root:where(:not([data-icen-style]),[data-icen-style="modern"]) :is(.icen-input,.icen-textarea)::placeholder {
1007
1185
  color: var(--icen-token-text-faint);
1008
1186
  opacity: 1;
1009
1187
  }
1188
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-segmented {
1189
+ background: var(--icen-token-surface-raised);
1190
+ border-color: var(--icen-token-line-soft);
1191
+ box-shadow: none;
1192
+ }
1193
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-segmented-item.is-active,
1194
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-segmented-item[aria-checked="true"] {
1195
+ border: 1px solid color-mix(in srgb, var(--icen-token-line) 72%, transparent);
1196
+ margin: -1px;
1197
+ }
1198
+ :root:where(:not([data-icen-style]),[data-icen-style="modern"]) .icen-toggle-group {
1199
+ background: var(--icen-token-surface-raised);
1200
+ border-color: var(--icen-token-line-soft);
1201
+ }
1010
1202
  /* Data readability is explicit, never applied to every numeral in prose. */
1011
1203
  :root :is(.icen-numeric,.icen-table,.icen-datatable,.icen-stat-num) { font-variant-numeric: lining-nums tabular-nums; }
1012
1204
  /* Any translucent material has an opaque alternative, including native controls. */
@@ -1103,6 +1295,8 @@ h1, h2, h3, h4, h5, h6 {
1103
1295
  /* 中式 material adapter. DOM contract: html[data-icen-style="chinese"] with
1104
1296
  * existing ICEN components or [data-icen-material="content|chrome|floating"].
1105
1297
  * No additional wrappers, decorative pseudo-elements or JavaScript required.
1298
+ * 分层登记(guard: tier-direction 白名单):横切材料适配引用 Beta 类名
1299
+ * .icen-ai-composer-popup,理由同 material.css 头注释。
1106
1300
  */
1107
1301
  :root[data-icen-style="chinese"] {
1108
1302
  --icen-press: scale(.995);
@@ -1160,6 +1354,14 @@ h1, h2, h3, h4, h5, h6 {
1160
1354
  @media (prefers-reduced-motion: reduce) {
1161
1355
  :root[data-icen-style="chinese"] { --icen-press: none; --icen-press-soft: none; }
1162
1356
  }
1357
+ /* 减少透明偏好:玻璃面回落实底,文字不叠在内容上 */
1358
+ @media (prefers-reduced-transparency: reduce) {
1359
+ :root[data-icen-style="chinese"] :is(.icen-card--glass, [data-icen-material="floating"], .icen-command-palette) {
1360
+ background: var(--icen-token-surface-raised);
1361
+ -webkit-backdrop-filter: none;
1362
+ backdrop-filter: none;
1363
+ }
1364
+ }
1163
1365
  @media (forced-colors: active) {
1164
1366
  :root[data-icen-style="chinese"] :is([data-icen-material],.icen-card,.icen-panel,.icen-menu,.icen-popover,.icen-select-panel,.icen-date-picker-panel,.icen-autocomplete-panel,.icen-cascader-panel,.icen-tree-select-panel,.icen-mentions-panel,.icen-ai-composer-popup,.icen-command-palette,.icen-modal,.icen-nav) {
1165
1367
  background: Canvas;
@@ -1174,6 +1376,8 @@ h1, h2, h3, h4, h5, h6 {
1174
1376
  /* 苏式 material adapter. DOM contract: html[data-icen-style="soviet"] with
1175
1377
  * existing ICEN components or [data-icen-material="content|chrome|floating"].
1176
1378
  * Structural emphasis belongs to frame/header/action, not long-form text.
1379
+ * 分层登记(guard: tier-direction 白名单):横切材料适配引用 Beta 类名
1380
+ * .icen-ai-composer-popup,理由同 material.css 头注释。
1177
1381
  */
1178
1382
  :root[data-icen-style="soviet"] {
1179
1383
  --icen-press: translateY(1px);
@@ -1233,6 +1437,14 @@ h1, h2, h3, h4, h5, h6 {
1233
1437
  @media (prefers-reduced-motion: reduce) {
1234
1438
  :root[data-icen-style="soviet"] { --icen-press: none; --icen-press-soft: none; }
1235
1439
  }
1440
+ /* 减少透明偏好:玻璃面回落实底,文字不叠在内容上 */
1441
+ @media (prefers-reduced-transparency: reduce) {
1442
+ :root[data-icen-style="soviet"] :is(.icen-card--glass, [data-icen-material="floating"], .icen-command-palette) {
1443
+ background: var(--icen-token-surface-raised);
1444
+ -webkit-backdrop-filter: none;
1445
+ backdrop-filter: none;
1446
+ }
1447
+ }
1236
1448
  @media (forced-colors: active) {
1237
1449
  :root[data-icen-style="soviet"] :is([data-icen-material],.icen-card,.icen-panel,.icen-menu,.icen-popover,.icen-select-panel,.icen-date-picker-panel,.icen-autocomplete-panel,.icen-cascader-panel,.icen-tree-select-panel,.icen-mentions-panel,.icen-ai-composer-popup,.icen-command-palette,.icen-modal,.icen-nav) {
1238
1450
  background: Canvas;
@@ -1265,9 +1477,9 @@ h1, h2, h3, h4, h5, h6 {
1265
1477
  cursor: pointer;
1266
1478
  transition: opacity var(--icen-tx-fast), background-color var(--icen-tx-fast), color var(--icen-tx-fast), transform var(--icen-tx-fast);
1267
1479
  }
1268
- .icen-icon-action:hover { background: var(--icen-token-fill-1); color: var(--icen-token-text); }
1269
- .icen-icon-action:active { transform: scale(.94); }
1270
- .icen-icon-action:focus-visible { outline: 2px solid var(--icen-token-accent); outline-offset: 2px; }
1480
+ .icen-icon-action:hover { background: var(--icen-token-fill-hover); color: var(--icen-token-text); }
1481
+ .icen-icon-action:active { background: var(--icen-token-fill-pressed); }
1482
+ .icen-icon-action:focus-visible { outline: none; box-shadow: var(--icen-ring); }
1271
1483
  .icen-icon-action:disabled { opacity: var(--icen-disabled-opacity); pointer-events: none; }
1272
1484
  @media (hover: hover) and (pointer: fine) {
1273
1485
  .icen-icon-action[data-icen-reveal] { opacity: 0; }
@@ -1280,7 +1492,6 @@ h1, h2, h3, h4, h5, h6 {
1280
1492
  }
1281
1493
  @media (prefers-reduced-motion: reduce) {
1282
1494
  .icen-icon-action { transition: none; }
1283
- .icen-icon-action:active { transform: none; }
1284
1495
  }
1285
1496
 
1286
1497
  :root[data-icen-style="pixel"] .icen-symbol { stroke-linecap: square; stroke-linejoin: miter; shape-rendering: crispEdges; }
@@ -1312,11 +1523,14 @@ h1, h2, h3, h4, h5, h6 {
1312
1523
  .icen-search-clear > svg { inline-size: 16px; block-size: 16px; pointer-events: none; }
1313
1524
  .icen-search-clear:hover {
1314
1525
  color: var(--icen-token-text);
1315
- background: var(--icen-token-surface-hover);
1526
+ background: var(--icen-token-fill-hover);
1527
+ }
1528
+ .icen-search-clear:active {
1529
+ background: var(--icen-token-fill-pressed);
1316
1530
  }
1317
1531
  .icen-search-clear:focus-visible {
1318
- outline: 2px solid var(--icen-token-accent);
1319
- outline-offset: -2px;
1532
+ outline: none;
1533
+ box-shadow: var(--icen-ring);
1320
1534
  }
1321
1535
  @media (prefers-reduced-motion: reduce) {
1322
1536
  .icen-search-clear { transition: none; }
@@ -1338,13 +1552,22 @@ h1, h2, h3, h4, h5, h6 {
1338
1552
  .icen-suggestion-symbol > svg { inline-size: 16px; block-size: 16px; }
1339
1553
  .icen-suggestion-copy { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; }
1340
1554
  .icen-suggestion-status.is-loading .icen-suggestion-symbol > svg { animation: icen-spin calc(var(--icen-duration-normal) * 4) linear infinite; }
1341
- .icen-suggestion-retry { flex: 0 0 auto; padding-inline: var(--icen-density-space-sm); min-block-size: var(--icen-density-input-height-sm); border: 1px solid var(--icen-token-outline-soft); border-radius: var(--icen-radius-sm); background: var(--icen-token-fill-1); color: var(--icen-token-text); font: inherit; cursor: pointer; }
1342
- .icen-suggestion-retry:focus-visible { outline: 2px solid var(--icen-token-accent); outline-offset: 1px; }
1343
- @media (hover: hover) and (pointer: fine) { .icen-suggestion-retry:hover { background: var(--icen-token-fill-2); } }
1555
+ .icen-suggestion-retry { flex: 0 0 auto; padding-inline: var(--icen-density-space-sm); min-block-size: var(--icen-density-input-height-sm); border: 1px solid var(--icen-token-outline-soft); border-radius: var(--icen-radius-sm); background: var(--icen-token-fill-1); color: var(--icen-token-text); font: inherit; cursor: pointer; transition: background-color var(--icen-tx-fast), border-color var(--icen-tx-fast); }
1556
+ .icen-suggestion-retry:focus-visible { outline: none; box-shadow: var(--icen-ring); }
1557
+ @media (hover: hover) and (pointer: fine) { .icen-suggestion-retry:hover { background: var(--icen-token-fill-2); border-color: var(--icen-token-line); } }
1344
1558
  @media (pointer: coarse) { .icen-suggestion-retry { min-inline-size: 44px; min-block-size: 44px; } }
1345
1559
  :root[data-icen-style="pixel"] .icen-suggestion-status.is-loading .icen-suggestion-symbol > svg { animation-timing-function: steps(8,end); }
1346
1560
  @media (prefers-reduced-motion: reduce) { .icen-suggestion-status.is-loading .icen-suggestion-symbol > svg { animation: none; } }
1347
1561
 
1562
+ @media (forced-colors: active) {
1563
+ .icen-icon-action,
1564
+ .icen-search-clear,
1565
+ .icen-suggestion-retry { border: 1px solid CanvasText; }
1566
+ .icen-icon-action:focus-visible,
1567
+ .icen-search-clear:focus-visible,
1568
+ .icen-suggestion-retry:focus-visible { outline: 2px solid Highlight; outline-offset: 1px; box-shadow: none; }
1569
+ }
1570
+
1348
1571
  /*
1349
1572
  * @icen.ai/ui — Component: input(wrapper 式输入框 / 多行 / 搜索)
1350
1573
  * 规格源自 opengal primitives/input.tsx;与 behaviors/input.ts 配套。
@@ -1376,16 +1599,16 @@ h1, h2, h3, h4, h5, h6 {
1376
1599
  .icen-kb-filter-value {
1377
1600
  box-sizing: border-box;
1378
1601
  min-inline-size: 0;
1379
- block-size: var(--input-height, var(--icen-density-input-height-md));
1380
- padding: 0 var(--input-padding-inline, var(--icen-density-space-sm));
1602
+ block-size: var(--input-height, var(--icen-control-height-md));
1603
+ padding: 0 var(--input-padding-inline, var(--icen-field-padding-inline));
1381
1604
  font-family: var(--icen-font-body);
1382
- font-size: var(--input-font-size, var(--icen-density-font-size-md));
1383
- line-height: 1.5;
1605
+ font-size: var(--input-font-size, var(--icen-font-size-control));
1606
+ line-height: 1.4;
1384
1607
  color: var(--icen-token-text);
1385
1608
  background: var(--icen-token-control);
1386
- border: 1px solid var(--icen-token-outline-soft);
1387
- border-radius: var(--icen-radius-md);
1388
- box-shadow: var(--icen-token-shadow-inset);
1609
+ border: var(--icen-control-border-width) solid var(--icen-token-control-border);
1610
+ border-radius: var(--icen-control-radius);
1611
+ box-shadow: var(--icen-token-shadow-field);
1389
1612
  transition: border-color var(--icen-tx-fast), box-shadow var(--icen-tx-fast);
1390
1613
  }
1391
1614
  .icen-input-wrap {
@@ -1396,7 +1619,7 @@ h1, h2, h3, h4, h5, h6 {
1396
1619
  inline-size: 100%;
1397
1620
  }
1398
1621
  :is(.icen-input-wrap,.icen-input-control,.icen-kb-input,.icen-kb-retrieval-query,.icen-kb-hittest-input,.icen-kb-filter-field,.icen-kb-filter-value):hover {
1399
- border-color: var(--icen-hover-border);
1622
+ border-color: var(--icen-token-control-border-hover);
1400
1623
  }
1401
1624
  :is(.icen-input-wrap,.icen-input-control,.icen-kb-input,.icen-kb-retrieval-query,.icen-kb-hittest-input,.icen-kb-filter-field,.icen-kb-filter-value):focus-within {
1402
1625
  outline: none;
@@ -1423,13 +1646,13 @@ h1, h2, h3, h4, h5, h6 {
1423
1646
  /* 尺寸变体 */
1424
1647
  .icen-input-wrap--sm, .icen-input-control--sm,
1425
1648
  .icen-kb-input, .icen-kb-retrieval-query, .icen-kb-hittest-input, .icen-kb-filter-field, .icen-kb-filter-value {
1426
- --input-height: var(--icen-density-input-height-sm);
1427
- --input-padding-inline: max(8px, calc(var(--icen-density-space-sm) * 1.25));
1649
+ --input-height: var(--icen-control-height-sm);
1650
+ --input-padding-inline: var(--icen-field-padding-inline-sm);
1428
1651
  --input-font-size: var(--icen-density-font-size-sm);
1429
1652
  }
1430
1653
  .icen-input-wrap--lg, .icen-input-control--lg {
1431
- --input-height: var(--icen-density-input-height-lg);
1432
- --input-padding-inline: var(--icen-density-space-md);
1654
+ --input-height: var(--icen-control-height-lg);
1655
+ --input-padding-inline: var(--icen-control-padding-inline-lg);
1433
1656
  --input-font-size: var(--icen-density-font-size-lg);
1434
1657
  }
1435
1658
 
@@ -1445,7 +1668,7 @@ h1, h2, h3, h4, h5, h6 {
1445
1668
  font: inherit;
1446
1669
  }
1447
1670
  .icen-input::placeholder {
1448
- color: color-mix(in srgb, var(--icen-token-text-faint) 60%, transparent);
1671
+ color: var(--icen-token-text-faint); /* 全量 faint:60% 混透浅色仅 ~2.4:1 低于 AA(faint 全量 ≥4.9:1) */
1449
1672
  }
1450
1673
  .icen-input:read-only {
1451
1674
  color: var(--icen-token-text-muted);
@@ -1508,7 +1731,7 @@ h1, h2, h3, h4, h5, h6 {
1508
1731
  align-items: center;
1509
1732
  justify-content: center;
1510
1733
  flex-shrink: 0;
1511
- width: 22px; height: 22px;
1734
+ width: 24px; height: 24px; /* WCAG 2.5.8 下限(22 → 24) */
1512
1735
  padding: 0;
1513
1736
  border: none;
1514
1737
  background: transparent;
@@ -1537,14 +1760,14 @@ h1, h2, h3, h4, h5, h6 {
1537
1760
  display: flex;
1538
1761
  width: 100%;
1539
1762
  background: var(--icen-token-control);
1540
- border: 1px solid var(--icen-token-outline-soft);
1541
- border-radius: var(--icen-radius-md);
1542
- box-shadow: var(--icen-token-shadow-inset);
1763
+ border: var(--icen-control-border-width) solid var(--icen-token-control-border);
1764
+ border-radius: var(--icen-control-radius);
1765
+ box-shadow: var(--icen-token-shadow-field);
1543
1766
  transition: border-color var(--icen-tx-fast),
1544
1767
  box-shadow var(--icen-tx-fast);
1545
1768
  }
1546
1769
  .icen-textarea-wrap:hover {
1547
- border-color: var(--icen-hover-border);
1770
+ border-color: var(--icen-token-control-border-hover);
1548
1771
  }
1549
1772
  .icen-textarea-wrap:focus-within {
1550
1773
  box-shadow: var(--icen-control-focus-shadow);
@@ -1567,19 +1790,19 @@ h1, h2, h3, h4, h5, h6 {
1567
1790
 
1568
1791
  .icen-textarea {
1569
1792
  width: 100%;
1570
- padding: var(--icen-density-space-sm) var(--icen-density-space-md);
1793
+ padding: var(--icen-density-space-sm) var(--icen-field-padding-inline);
1571
1794
  background: transparent;
1572
1795
  border: none;
1573
1796
  outline: none;
1574
1797
  resize: vertical;
1575
1798
  color: var(--icen-token-text);
1576
1799
  font: inherit;
1577
- font-size: var(--icen-density-font-size-md);
1800
+ font-size: var(--icen-font-size-control);
1578
1801
  line-height: 1.5;
1579
- min-height: calc(3 * 1.5em + 24px);
1802
+ min-height: calc(3 * 1.5em + 22px);
1580
1803
  }
1581
1804
  .icen-textarea::placeholder {
1582
- color: color-mix(in srgb, var(--icen-token-text-faint) 60%, transparent);
1805
+ color: var(--icen-token-text-faint); /* 全量 faint:60% 混透浅色仅 ~2.4:1 低于 AA(faint 全量 ≥4.9:1) */
1583
1806
  }
1584
1807
 
1585
1808
  /* 字符计数(behavior 可挂到 .icen-input-wrap 或 .icen-textarea-wrap 内行内末端) */