@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,20 +1,21 @@
1
+ @layer icen.components {
1
2
  /*
2
3
  * @icen.ai/ui — Component: modal(对话框 + 贴边 Sheet,与 behaviors/modal 配套)
3
4
  *
4
5
  * 完整契约:
5
- * <div class="modal-backdrop" data-modal="id" hidden>
6
- * <div class="modal [--sm|--lg|--xl|--full] [role=dialog] aria-modal="true" aria-labelledby="title-id">
7
- * <div class="modal-header">
6
+ * <div class="icen-modal-backdrop" data-icen-modal="id" hidden>
7
+ * <div class="icen-modal [--sm|--lg|--xl|--full] [role=dialog] aria-modal="true" aria-labelledby="title-id">
8
+ * <div class="icen-modal-header">
8
9
  * <div>
9
- * <h2 class="modal-title" id="title-id">标题</h2>
10
- * <p class="modal-description">副标题(可选)</p>
10
+ * <h2 class="icen-modal-title" id="title-id">标题</h2>
11
+ * <p class="icen-modal-description">副标题(可选)</p>
11
12
  </div>
12
- * <button class="modal-close" aria-label="关闭">…</button>
13
+ * <button class="icen-modal-close" aria-label="关闭">…</button>
13
14
  * </div>
14
- * <div class="modal-body">…</div>
15
- * <div class="modal-footer [modal-footer--between|modal-footer--start|modal-footer--column]">
16
- * <button class="btn">取消</button>
17
- * <button class="btn btn-primary">确认</button>
15
+ * <div class="icen-modal-body">…</div>
16
+ * <div class="icen-modal-footer [icen-modal-footer--between|icen-modal-footer--start|icen-modal-footer--column]">
17
+ * <button class="icen-btn">取消</button>
18
+ * <button class="icen-btn icen-btn-primary">确认</button>
18
19
  * </div>
19
20
  * </div>
20
21
  * </div>
@@ -23,191 +24,185 @@
23
24
  * behavior 维护:focus trap、ESC 关闭、点击 backdrop 关闭、scroll lock。
24
25
  */
25
26
 
26
- .modal-backdrop {
27
+ .icen-modal-backdrop {
27
28
  position: fixed;
28
29
  inset: 0;
29
- z-index: var(--z-dialog);
30
+ z-index: var(--icen-z-dialog);
30
31
  display: flex;
31
32
  align-items: center;
32
33
  justify-content: center;
33
- padding: var(--density-space-md);
34
- background: color-mix(in srgb, var(--token-text) 45%, transparent);
34
+ padding: var(--icen-density-space-md);
35
+ background: color-mix(in srgb, var(--icen-token-text) 45%, transparent);
35
36
  backdrop-filter: blur(4px);
36
37
  -webkit-backdrop-filter: blur(4px);
37
- animation: icen-modal-fade-in var(--icen-tx-normal);
38
+ opacity: 1;
39
+ transition: opacity var(--icen-duration-fast) var(--icen-ease-out), display var(--icen-duration-fast) allow-discrete;
38
40
  }
39
- .modal-backdrop[hidden] { display: none; }
41
+ .icen-modal-backdrop[hidden] { display: none; opacity: 0; pointer-events: none; }
40
42
 
41
- .modal {
43
+ .icen-modal {
42
44
  display: flex;
43
45
  flex-direction: column;
44
46
  overflow: hidden;
45
47
  width: 100%;
46
48
  max-width: 480px;
47
49
  max-height: calc(100vh - 32px);
48
- background: var(--token-card-strong);
49
- color: var(--token-text);
50
- border: 1px solid var(--token-outline);
51
- box-shadow: var(--token-shadow-overlay);
52
- border-radius: var(--radius-xl);
53
- animation: icen-modal-scale-in var(--icen-tx-slow);
54
- }
55
- .modal:focus { outline: none; }
56
- .modal:focus-visible {
57
- box-shadow: var(--token-shadow-overlay), var(--icen-ring-soft);
50
+ max-block-size: calc(100dvh - 2 * var(--icen-density-space-md));
51
+ background: var(--icen-token-card-strong);
52
+ color: var(--icen-token-text);
53
+ border: 1px solid var(--icen-token-outline);
54
+ box-shadow: var(--icen-token-shadow-overlay);
55
+ border-radius: var(--icen-radius-xl);
56
+ --modal-enter-transform: translateY(6px) scale(.985);
57
+ opacity: 1;
58
+ transform: translate(0, 0) scale(1);
59
+ transition: opacity var(--icen-duration-fast) var(--icen-ease-out), transform var(--icen-duration-normal) var(--icen-ease-out);
60
+ }
61
+ .icen-modal:focus { outline: none; }
62
+ .icen-modal:focus-visible {
63
+ box-shadow: var(--icen-token-shadow-overlay), var(--icen-ring-soft);
58
64
  }
59
65
 
60
66
  /* ── 尺寸档 ── */
61
- .modal--sm { max-width: 360px; }
62
- .modal--lg { max-width: 640px; }
63
- .modal--xl { max-width: 800px; }
64
- .modal--full {
67
+ .icen-modal--sm { max-width: 360px; }
68
+ .icen-modal--lg { max-width: 640px; }
69
+ .icen-modal--xl { max-width: 800px; }
70
+ .icen-modal--full {
65
71
  width: calc(100vw - 32px);
66
72
  max-width: none;
67
- height: calc(100vh - 32px);
73
+ height: calc(100dvh - 32px);
68
74
  max-height: none;
69
- border-radius: var(--radius-lg);
75
+ border-radius: var(--icen-radius-lg);
70
76
  }
71
77
 
72
78
  /* ── 头部 / 主体 / 底栏 ── */
73
- .modal-header {
79
+ .icen-modal-header {
74
80
  display: flex;
75
81
  align-items: flex-start;
76
82
  justify-content: space-between;
77
- gap: var(--density-space-md);
78
- padding: var(--density-space-lg) var(--density-space-lg) var(--density-space-sm);
83
+ gap: var(--icen-density-space-md);
84
+ padding: var(--icen-density-space-lg) var(--icen-density-space-lg) var(--icen-density-space-sm);
79
85
  }
80
- .modal-title {
86
+ .icen-modal-title {
81
87
  margin: 0;
82
- font-size: var(--density-font-size-lg);
88
+ font-size: var(--icen-density-font-size-lg);
83
89
  font-weight: 600;
84
90
  line-height: 1.3;
85
- font-family: var(--font-heading);
91
+ font-family: var(--icen-font-heading);
86
92
  }
87
- .modal-description {
93
+ .icen-modal-description {
88
94
  margin: 2px 0 0;
89
- font-size: var(--density-font-size-sm);
90
- color: var(--token-text-muted);
95
+ font-size: var(--icen-density-font-size-sm);
96
+ color: var(--icen-token-text-muted);
91
97
  line-height: 1.5;
92
98
  }
93
- .modal-close {
99
+ .icen-modal-close {
94
100
  display: inline-flex;
95
101
  align-items: center;
96
102
  justify-content: center;
97
- width: 28px;
98
- height: 28px;
103
+ inline-size: var(--icen-density-input-height-sm);
104
+ block-size: var(--icen-density-input-height-sm);
99
105
  padding: 0;
100
106
  flex-shrink: 0;
101
107
  background: none;
102
108
  border: 0;
103
109
  cursor: pointer;
104
- color: var(--token-text-faint);
105
- font-size: var(--density-font-size-lg);
110
+ color: var(--icen-token-text-faint);
111
+ font-size: var(--icen-density-font-size-lg);
106
112
  line-height: 1;
107
- border-radius: var(--radius-sm);
113
+ border-radius: var(--icen-radius-sm);
108
114
  transition:
109
115
  background-color var(--icen-tx-fast),
110
116
  color var(--icen-tx-fast);
111
117
  }
112
- .modal-close:hover {
113
- background: var(--token-surface-hover);
114
- color: var(--token-text);
118
+ .icen-modal-close > svg { inline-size: 16px; block-size: 16px; }
119
+ .icen-modal-close:hover {
120
+ background: var(--icen-token-surface-hover);
121
+ color: var(--icen-token-text);
115
122
  }
116
- .modal-close:focus-visible {
123
+ .icen-modal-close:focus-visible {
117
124
  outline: none;
118
125
  box-shadow: var(--icen-ring);
119
126
  }
120
127
 
121
- .modal-body {
128
+ .icen-modal-body {
122
129
  flex: 1;
123
130
  overflow-y: auto;
124
131
  overscroll-behavior: contain;
125
- padding: 0 var(--density-space-lg) var(--density-space-md);
126
- font-size: var(--density-font-size-md);
132
+ padding: 0 var(--icen-density-space-lg) var(--icen-density-space-md);
133
+ font-size: var(--icen-density-font-size-md);
127
134
  line-height: 1.6;
128
135
  }
129
136
 
130
- .modal-footer {
137
+ .icen-modal-footer {
131
138
  display: flex;
132
139
  justify-content: flex-end;
133
- gap: var(--density-space-sm);
134
- padding: var(--density-space-md) var(--density-space-lg);
135
- border-top: 1px solid color-mix(in srgb, var(--token-line-soft) 40%, transparent);
136
- }
137
- .modal-footer--start { justify-content: flex-start; }
138
- .modal-footer--between { justify-content: space-between; }
139
- .modal-footer--column { flex-direction: column; }
140
- .modal-footer--column > * { width: 100%; }
140
+ gap: var(--icen-density-space-sm);
141
+ padding: var(--icen-density-space-md) var(--icen-density-space-lg);
142
+ border-top: 1px solid color-mix(in srgb, var(--icen-token-line-soft) 40%, transparent);
143
+ }
144
+ .icen-modal-footer--start { justify-content: flex-start; }
145
+ .icen-modal-footer--between { justify-content: space-between; }
146
+ .icen-modal-footer--column { flex-direction: column; }
147
+ .icen-modal-footer--column > * { width: 100%; }
141
148
 
142
149
  /* ── Sheet 变体:面板 fixed 贴边,radius 只保留非贴边侧 ── */
143
- .modal--sheet-left,
144
- .modal--sheet-right,
145
- .modal--sheet-top,
146
- .modal--sheet-bottom {
150
+ .icen-modal--sheet-left,
151
+ .icen-modal--sheet-right,
152
+ .icen-modal--sheet-top,
153
+ .icen-modal--sheet-bottom {
147
154
  position: fixed;
148
155
  max-width: none;
149
156
  max-height: none;
157
+ max-inline-size: 100vw;
158
+ max-block-size: 100dvh;
150
159
  border-radius: 0;
151
160
  }
152
- .modal--sheet-left {
153
- left: 0; top: 0; bottom: 0;
161
+ .icen-modal--sheet-left {
162
+ left: 0; top: 0; bottom: 0; /* guard:allow-physical --sheet-left 是按物理侧边命名的变体(贴左缘抽屉),RTL 语义不变 */
154
163
  width: 360px;
155
164
  height: 100%;
156
- border-radius: 0 var(--radius-xl) var(--radius-xl) 0;
157
- animation-name: icen-modal-slide-left;
165
+ border-radius: 0 var(--icen-radius-xl) var(--icen-radius-xl) 0; /* guard:allow-physical 圆角贴着物理左缘(sheet-left 变体),RTL 语义不变 */
166
+ --modal-enter-transform: translateX(-16px);
158
167
  }
159
- .modal--sheet-right {
160
- right: 0; top: 0; bottom: 0;
168
+ .icen-modal--sheet-right {
169
+ right: 0; top: 0; bottom: 0; /* guard:allow-physical --sheet-right 是按物理侧边命名的变体(贴右缘抽屉),RTL 语义不变 */
161
170
  width: 360px;
162
171
  height: 100%;
163
- border-radius: var(--radius-xl) 0 0 var(--radius-xl);
164
- animation-name: icen-modal-slide-right;
172
+ border-radius: var(--icen-radius-xl) 0 0 var(--icen-radius-xl); /* guard:allow-physical 圆角贴着物理右缘(sheet-right 变体),RTL 语义不变 */
173
+ --modal-enter-transform: translateX(16px);
165
174
  }
166
- .modal--sheet-top {
167
- top: 0; left: 0; right: 0;
175
+ .icen-modal--sheet-top {
176
+ top: 0; inset-inline: 0;
168
177
  width: 100%;
169
178
  height: 300px;
170
- border-radius: 0 0 var(--radius-xl) var(--radius-xl);
171
- animation-name: icen-modal-slide-top;
179
+ border-radius: 0 0 var(--icen-radius-xl) var(--icen-radius-xl);
180
+ --modal-enter-transform: translateY(-16px);
172
181
  }
173
- .modal--sheet-bottom {
174
- bottom: 0; left: 0; right: 0;
182
+ .icen-modal--sheet-bottom {
183
+ bottom: 0; inset-inline: 0;
175
184
  width: 100%;
176
185
  height: 300px;
177
- border-radius: var(--radius-xl) var(--radius-xl) 0 0;
178
- animation-name: icen-modal-slide-bottom;
186
+ border-radius: var(--icen-radius-xl) var(--icen-radius-xl) 0 0;
187
+ --modal-enter-transform: translateY(16px);
179
188
  }
180
- .modal--sheet-left.modal--sm, .modal--sheet-right.modal--sm { width: 280px; }
181
- .modal--sheet-left.modal--lg, .modal--sheet-right.modal--lg { width: 480px; }
182
- .modal--sheet-top.modal--sm, .modal--sheet-bottom.modal--sm { height: 200px; }
183
- .modal--sheet-top.modal--lg, .modal--sheet-bottom.modal--lg { height: 50vh; }
189
+ .icen-modal--sheet-left.icen-modal--sm, .icen-modal--sheet-right.icen-modal--sm { width: 280px; }
190
+ .icen-modal--sheet-left.icen-modal--lg, .icen-modal--sheet-right.icen-modal--lg { width: 480px; }
191
+ .icen-modal--sheet-top.icen-modal--sm, .icen-modal--sheet-bottom.icen-modal--sm { height: 200px; }
192
+ .icen-modal--sheet-top.icen-modal--lg, .icen-modal--sheet-bottom.icen-modal--lg { height: 50vh; }
184
193
 
185
- /* ── 进场动画 ── */
186
- @keyframes icen-modal-fade-in {
187
- from { opacity: 0; }
188
- to { opacity: 1; }
189
- }
190
- @keyframes icen-modal-scale-in {
191
- from { opacity: 0; transform: scale(0.96) translateY(8px); }
192
- to { opacity: 1; transform: scale(1) translateY(0); }
193
- }
194
- @keyframes icen-modal-slide-left {
195
- from { opacity: 0; transform: translateX(-40px); }
196
- to { opacity: 1; transform: translateX(0); }
194
+ /* Hidden keeps native semantics while display transitions retire the surface.
195
+ Unsupported browsers fall back to immediate hide; no JS timing owns visibility. */
196
+ .icen-modal-backdrop[hidden] .icen-modal { opacity: 0; transform: var(--modal-enter-transform); }
197
+ @starting-style {
198
+ .icen-modal-backdrop:not([hidden]) { opacity: 0; }
199
+ .icen-modal-backdrop:not([hidden]) .icen-modal { opacity: 0; transform: var(--modal-enter-transform); }
197
200
  }
198
- @keyframes icen-modal-slide-right {
199
- from { opacity: 0; transform: translateX(40px); }
200
- to { opacity: 1; transform: translateX(0); }
201
+ @media (pointer: coarse) {
202
+ .icen-modal-close { min-inline-size: 44px; min-block-size: 44px; }
201
203
  }
202
- @keyframes icen-modal-slide-top {
203
- from { opacity: 0; transform: translateY(-40px); }
204
- to { opacity: 1; transform: translateY(0); }
205
- }
206
- @keyframes icen-modal-slide-bottom {
207
- from { opacity: 0; transform: translateY(40px); }
208
- to { opacity: 1; transform: translateY(0); }
204
+ @media (prefers-reduced-motion: reduce) {
205
+ .icen-modal-backdrop, .icen-modal { transition: none; }
209
206
  }
210
207
 
211
- @media (prefers-reduced-motion: reduce) {
212
- .modal-backdrop, .modal { animation: none; }
213
208
  }