@icen.ai/ui 0.8.1 → 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 (335) hide show
  1. package/AGENTS.md +176 -75
  2. package/README.md +66 -88
  3. package/dist/base.css +208 -179
  4. package/dist/behaviors/accordion.mjs +8 -8
  5. package/dist/behaviors/ai-branch.d.mts +19 -0
  6. package/dist/behaviors/ai-branch.mjs +1133 -0
  7. package/dist/behaviors/ai-chat.d.mts +12 -10
  8. package/dist/behaviors/ai-chat.mjs +1125 -155
  9. package/dist/behaviors/ai-composer.d.mts +44 -12
  10. package/dist/behaviors/ai-composer.mjs +2084 -523
  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 +26 -0
  15. package/dist/behaviors/ai-feedback.mjs +1212 -0
  16. package/dist/behaviors/ai-panel.d.mts +21 -7
  17. package/dist/behaviors/ai-panel.mjs +1308 -264
  18. package/dist/behaviors/ai-provider.mjs +1003 -101
  19. package/dist/behaviors/ai-threads.d.mts +38 -0
  20. package/dist/behaviors/ai-threads.mjs +1233 -0
  21. package/dist/behaviors/ai-tool.d.mts +2 -2
  22. package/dist/behaviors/ai-tool.mjs +2042 -396
  23. package/dist/behaviors/ai-tools.d.mts +89 -16
  24. package/dist/behaviors/ai-tools.mjs +4453 -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 +174 -8
  34. package/dist/behaviors/charts.mjs +2632 -192
  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 +313 -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 +34 -0
  68. package/dist/behaviors/kb-access.mjs +2459 -0
  69. package/dist/behaviors/kb-acl.d.mts +50 -0
  70. package/dist/behaviors/kb-acl.mjs +1345 -0
  71. package/dist/behaviors/kb-answer.d.mts +38 -0
  72. package/dist/behaviors/kb-answer.mjs +3707 -0
  73. package/dist/behaviors/kb-audit.d.mts +23 -0
  74. package/dist/behaviors/kb-audit.mjs +1297 -0
  75. package/dist/behaviors/kb-canvas.d.mts +44 -0
  76. package/dist/behaviors/kb-canvas.mjs +1512 -0
  77. package/dist/behaviors/kb-chain.d.mts +15 -0
  78. package/dist/behaviors/kb-chain.mjs +1192 -0
  79. package/dist/behaviors/kb-checkpoint.d.mts +16 -0
  80. package/dist/behaviors/kb-checkpoint.mjs +1492 -0
  81. package/dist/behaviors/kb-chunks.d.mts +31 -0
  82. package/dist/behaviors/kb-chunks.mjs +1414 -0
  83. package/dist/behaviors/kb-citation.d.mts +38 -0
  84. package/dist/behaviors/kb-citation.mjs +1699 -0
  85. package/dist/behaviors/kb-clarify.d.mts +20 -0
  86. package/dist/behaviors/kb-clarify.mjs +1176 -0
  87. package/dist/behaviors/kb-conflict.d.mts +22 -0
  88. package/dist/behaviors/kb-conflict.mjs +1206 -0
  89. package/dist/behaviors/kb-connector.d.mts +17 -0
  90. package/dist/behaviors/kb-connector.mjs +1303 -0
  91. package/dist/behaviors/kb-core.d.mts +534 -0
  92. package/dist/behaviors/kb-core.mjs +1805 -0
  93. package/dist/behaviors/kb-eval.d.mts +22 -0
  94. package/dist/behaviors/kb-eval.mjs +2235 -0
  95. package/dist/behaviors/kb-explain.d.mts +11 -0
  96. package/dist/behaviors/kb-explain.mjs +1165 -0
  97. package/dist/behaviors/kb-filter.d.mts +31 -0
  98. package/dist/behaviors/kb-filter.mjs +2417 -0
  99. package/dist/behaviors/kb-gap.d.mts +27 -0
  100. package/dist/behaviors/kb-gap.mjs +1195 -0
  101. package/dist/behaviors/kb-hittest.d.mts +34 -0
  102. package/dist/behaviors/kb-hittest.mjs +1352 -0
  103. package/dist/behaviors/kb-metadata.d.mts +29 -0
  104. package/dist/behaviors/kb-metadata.mjs +1248 -0
  105. package/dist/behaviors/kb-passage.d.mts +41 -0
  106. package/dist/behaviors/kb-passage.mjs +1469 -0
  107. package/dist/behaviors/kb-pipeline.d.mts +18 -0
  108. package/dist/behaviors/kb-pipeline.mjs +1301 -0
  109. package/dist/behaviors/kb-qa.d.mts +26 -0
  110. package/dist/behaviors/kb-qa.mjs +1260 -0
  111. package/dist/behaviors/kb-rerank.d.mts +20 -0
  112. package/dist/behaviors/kb-rerank.mjs +1248 -0
  113. package/dist/behaviors/kb-retrieval.d.mts +49 -0
  114. package/dist/behaviors/kb-retrieval.mjs +2585 -0
  115. package/dist/behaviors/kb-review.d.mts +44 -0
  116. package/dist/behaviors/kb-review.mjs +2282 -0
  117. package/dist/behaviors/kb-sandbox.d.mts +33 -0
  118. package/dist/behaviors/kb-sandbox.mjs +1247 -0
  119. package/dist/behaviors/kb-segment.d.mts +32 -0
  120. package/dist/behaviors/kb-segment.mjs +1431 -0
  121. package/dist/behaviors/kb-select.d.mts +24 -0
  122. package/dist/behaviors/kb-select.mjs +1989 -0
  123. package/dist/behaviors/kb-sources.d.mts +27 -0
  124. package/dist/behaviors/kb-sources.mjs +1287 -0
  125. package/dist/behaviors/kb-sql.d.mts +43 -0
  126. package/dist/behaviors/kb-sql.mjs +1865 -0
  127. package/dist/behaviors/kb-trace.d.mts +16 -0
  128. package/dist/behaviors/kb-trace.mjs +1328 -0
  129. package/dist/behaviors/kb-visibility.d.mts +44 -0
  130. package/dist/behaviors/kb-visibility.mjs +1331 -0
  131. package/dist/behaviors/kb-who-can.d.mts +32 -0
  132. package/dist/behaviors/kb-who-can.mjs +2216 -0
  133. package/dist/behaviors/mentions.d.mts +93 -0
  134. package/dist/behaviors/mentions.mjs +2152 -0
  135. package/dist/behaviors/modal.d.mts +4 -3
  136. package/dist/behaviors/modal.mjs +1055 -33
  137. package/dist/behaviors/nav.d.mts +1 -1
  138. package/dist/behaviors/nav.mjs +6 -6
  139. package/dist/behaviors/notification.d.mts +16 -8
  140. package/dist/behaviors/notification.mjs +1615 -265
  141. package/dist/behaviors/panel.d.mts +4 -0
  142. package/dist/behaviors/panel.mjs +994 -0
  143. package/dist/behaviors/popover.d.mts +28 -5
  144. package/dist/behaviors/popover.mjs +225 -24
  145. package/dist/behaviors/select.d.mts +5 -2
  146. package/dist/behaviors/select.mjs +1410 -117
  147. package/dist/behaviors/sidebar.d.mts +1 -1
  148. package/dist/behaviors/sidebar.mjs +13 -13
  149. package/dist/behaviors/slider.d.mts +1 -1
  150. package/dist/behaviors/slider.mjs +9 -9
  151. package/dist/behaviors/split-pane.d.mts +1 -1
  152. package/dist/behaviors/split-pane.mjs +7 -7
  153. package/dist/behaviors/suggestions.d.mts +27 -0
  154. package/dist/behaviors/suggestions.mjs +1089 -0
  155. package/dist/behaviors/svg-parse.d.mts +14 -0
  156. package/dist/behaviors/svg-parse.mjs +37 -0
  157. package/dist/behaviors/tabs.d.mts +2 -2
  158. package/dist/behaviors/tabs.mjs +25 -25
  159. package/dist/behaviors/tag-input.d.mts +23 -5
  160. package/dist/behaviors/tag-input.mjs +1359 -104
  161. package/dist/behaviors/theme-switcher.d.mts +24 -0
  162. package/dist/behaviors/theme-switcher.mjs +1981 -0
  163. package/dist/behaviors/theme.d.mts +15 -8
  164. package/dist/behaviors/theme.mjs +390 -28
  165. package/dist/behaviors/toast.d.mts +24 -25
  166. package/dist/behaviors/toast.mjs +1266 -88
  167. package/dist/behaviors/tooltip.d.mts +4 -0
  168. package/dist/behaviors/tooltip.mjs +378 -0
  169. package/dist/behaviors/tree-select.d.mts +69 -0
  170. package/dist/behaviors/tree-select.mjs +1907 -0
  171. package/dist/behaviors/tree.d.mts +1 -1
  172. package/dist/behaviors/tree.mjs +15 -15
  173. package/dist/behaviors/upload.d.mts +3 -2
  174. package/dist/behaviors/upload.mjs +1076 -66
  175. package/dist/cli.mjs +5 -6
  176. package/dist/components/ai-branch.mjs +3 -0
  177. package/dist/components/ai-chat.css +846 -458
  178. package/dist/components/ai-diff.css +153 -132
  179. package/dist/components/ai-feedback.mjs +3 -0
  180. package/dist/components/ai-panel.css +495 -270
  181. package/dist/components/ai-threads.mjs +3 -0
  182. package/dist/components/ai-tool.css +393 -238
  183. package/dist/components/autocomplete.css +61 -0
  184. package/dist/components/autocomplete.mjs +3 -0
  185. package/dist/components/back-top.css +34 -31
  186. package/dist/components/badge.css +44 -41
  187. package/dist/components/breadcrumb.css +67 -46
  188. package/dist/components/btn.css +80 -74
  189. package/dist/components/card.css +117 -106
  190. package/dist/components/cascader.css +311 -0
  191. package/dist/components/cascader.mjs +3 -0
  192. package/dist/components/chart-area.css +8 -2
  193. package/dist/components/chart-bar.css +95 -33
  194. package/dist/components/chart-gauge.css +14 -11
  195. package/dist/components/chart-graph.css +60 -0
  196. package/dist/components/chart-graph.mjs +4 -0
  197. package/dist/components/chart-heatmap.css +96 -90
  198. package/dist/components/chart-line.css +8 -3
  199. package/dist/components/chart-map.mjs +3 -0
  200. package/dist/components/chart-pie.css +9 -6
  201. package/dist/components/chart-radar.css +8 -5
  202. package/dist/components/chart-scatter.css +9 -6
  203. package/dist/components/chart-scatter.mjs +1 -1
  204. package/dist/components/chart-sparkline.css +5 -2
  205. package/dist/components/chart-stack.css +14 -11
  206. package/dist/components/charts.css +190 -67
  207. package/dist/components/charts.mjs +1 -0
  208. package/dist/components/code-block.css +418 -0
  209. package/dist/components/code-block.mjs +4 -0
  210. package/dist/components/command-palette.css +138 -117
  211. package/dist/components/content.css +257 -251
  212. package/dist/components/copy.css +72 -44
  213. package/dist/components/datatable.css +423 -181
  214. package/dist/components/date-picker.css +135 -104
  215. package/dist/components/empty.css +68 -65
  216. package/dist/components/feedback.css +201 -183
  217. package/dist/components/form-validate.css +120 -0
  218. package/dist/components/form-validate.mjs +3 -0
  219. package/dist/components/form.css +150 -127
  220. package/dist/components/icon.css +102 -0
  221. package/dist/components/icon.mjs +3 -0
  222. package/dist/components/input.css +159 -104
  223. package/dist/components/kb-access.mjs +4 -0
  224. package/dist/components/kb-acl.mjs +4 -0
  225. package/dist/components/kb-agent.css +496 -0
  226. package/dist/components/kb-answer.mjs +4 -0
  227. package/dist/components/kb-audit.mjs +4 -0
  228. package/dist/components/kb-canvas.mjs +4 -0
  229. package/dist/components/kb-chain.mjs +4 -0
  230. package/dist/components/kb-checkpoint.mjs +4 -0
  231. package/dist/components/kb-chunks.mjs +4 -0
  232. package/dist/components/kb-citation.mjs +4 -0
  233. package/dist/components/kb-clarify.mjs +4 -0
  234. package/dist/components/kb-conflict.mjs +4 -0
  235. package/dist/components/kb-connector.mjs +4 -0
  236. package/dist/components/kb-data.css +653 -0
  237. package/dist/components/kb-eval.mjs +4 -0
  238. package/dist/components/kb-explain.mjs +4 -0
  239. package/dist/components/kb-filter.mjs +4 -0
  240. package/dist/components/kb-gap.mjs +4 -0
  241. package/dist/components/kb-ground.css +578 -0
  242. package/dist/components/kb-hittest.mjs +4 -0
  243. package/dist/components/kb-ingest.css +882 -0
  244. package/dist/components/kb-metadata.mjs +4 -0
  245. package/dist/components/kb-ops.css +554 -0
  246. package/dist/components/kb-passage.mjs +4 -0
  247. package/dist/components/kb-perm.css +433 -0
  248. package/dist/components/kb-pipeline.mjs +4 -0
  249. package/dist/components/kb-qa.mjs +4 -0
  250. package/dist/components/kb-rerank.mjs +4 -0
  251. package/dist/components/kb-retrieval.mjs +4 -0
  252. package/dist/components/kb-review.mjs +4 -0
  253. package/dist/components/kb-sandbox.mjs +4 -0
  254. package/dist/components/kb-search.css +897 -0
  255. package/dist/components/kb-segment.mjs +4 -0
  256. package/dist/components/kb-sources.mjs +4 -0
  257. package/dist/components/kb-sql.mjs +4 -0
  258. package/dist/components/kb-trace.mjs +4 -0
  259. package/dist/components/kb-visibility.mjs +4 -0
  260. package/dist/components/kb-who-can.mjs +4 -0
  261. package/dist/components/kb.css +263 -0
  262. package/dist/components/kb.mjs +9 -0
  263. package/dist/components/layout.css +85 -82
  264. package/dist/components/material-chinese.css +73 -0
  265. package/dist/components/material-soviet.css +76 -0
  266. package/dist/components/material.css +275 -0
  267. package/dist/components/media.css +220 -166
  268. package/dist/components/mentions.css +189 -0
  269. package/dist/components/mentions.mjs +3 -0
  270. package/dist/components/menu.css +113 -105
  271. package/dist/components/modal.css +107 -112
  272. package/dist/components/nav.css +118 -115
  273. package/dist/components/notification.css +238 -174
  274. package/dist/components/pagination.css +56 -53
  275. package/dist/components/panel.css +66 -63
  276. package/dist/components/panel.mjs +1 -0
  277. package/dist/components/pill.css +81 -71
  278. package/dist/components/popover.css +67 -53
  279. package/dist/components/scroll-area.css +113 -110
  280. package/dist/components/segmented.css +146 -143
  281. package/dist/components/select.css +206 -186
  282. package/dist/components/sidebar.css +137 -127
  283. package/dist/components/slider.css +117 -114
  284. package/dist/components/split-pane.css +112 -109
  285. package/dist/components/stat.css +112 -106
  286. package/dist/components/steps.css +109 -103
  287. package/dist/components/switch.css +138 -134
  288. package/dist/components/table.css +131 -107
  289. package/dist/components/tabs.css +114 -108
  290. package/dist/components/tag-input.css +48 -133
  291. package/dist/components/tag.css +81 -71
  292. package/dist/components/theme-switcher.css +105 -0
  293. package/dist/components/theme-switcher.mjs +3 -0
  294. package/dist/components/toast.css +100 -86
  295. package/dist/components/toolbar.css +45 -42
  296. package/dist/components/tooltip.css +102 -43
  297. package/dist/components/tooltip.mjs +1 -0
  298. package/dist/components/tree-select.css +416 -0
  299. package/dist/components/tree-select.mjs +3 -0
  300. package/dist/components/upload.css +135 -92
  301. package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
  302. package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
  303. package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
  304. package/dist/fonts/OFL.txt +96 -0
  305. package/dist/fonts/README.md +14 -0
  306. package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
  307. package/dist/index.d.mts +64 -15
  308. package/dist/index.mjs +28049 -8595
  309. package/dist/react.d.mts +91 -0
  310. package/dist/react.mjs +8208 -0
  311. package/dist/registry.json +454 -15
  312. package/dist/tokens/chinese.css +44 -0
  313. package/dist/tokens/colors.css +365 -1222
  314. package/dist/tokens/design.css +109 -0
  315. package/dist/tokens/dtcg.json +11198 -0
  316. package/dist/tokens/figma.variables.json +7017 -0
  317. package/dist/tokens/icon-masks.css +78 -0
  318. package/dist/tokens/pixel.css +50 -0
  319. package/dist/tokens/soviet.css +44 -0
  320. package/dist/tokens/style-profiles.css +36 -547
  321. package/dist/tokens/themes.json +308 -0
  322. package/dist/tokens/tokens-studio.json +6728 -0
  323. package/dist/tokens/typography.css +21 -18
  324. package/dist/tokens.css +1555 -1801
  325. package/dist/ui.css +16147 -8597
  326. package/dist/vue.d.mts +344 -0
  327. package/dist/vue.mjs +7781 -0
  328. package/docs/spec/ai-input-experience.md +75 -0
  329. package/docs/spec/ai-native.md +238 -147
  330. package/docs/spec/design-philosophy.md +189 -0
  331. package/docs/spec/design-primitives.md +196 -0
  332. package/docs/spec/kb-family.md +475 -0
  333. package/package.json +42 -7
  334. package/dist/retro-effects.css +0 -255
  335. package/dist/tokens/retro-effects.css +0 -255
@@ -1,129 +1,134 @@
1
+ @layer icen.components {
1
2
  /*
2
3
  * @icen.ai/ui — Component: notification(通知栈 v2,与 behaviors/notification 配套)
3
4
  *
4
5
  * 与 toast / alert 的差异(三件正交):
5
- * - toast = 瞬时轻提示(2.6s 自动消失),右下角
6
+ * - toast = 瞬时轻提示(2.6s 自动消失),行内末端下角(LTR 右下 / RTL 镜像左下)
6
7
  * - alert = 内嵌警示条(页面流内,非浮层)
7
- * - notification = 持久通知栈(右上角),工程级:
8
+ * - notification = 持久通知栈(行内末端上角,RTL 镜像左上),工程级:
8
9
  * 进度条 / 倒计时 / 头像 / 多按钮 / 已读未读 / 优先级 / hover 暂停 / 详情链接 / 折叠堆叠
9
10
  *
10
11
  * 完整契约(由 behavior 渲染):
11
- * <div class="notification-container" role="region" aria-label="通知" data-position="top-right">
12
- * <div class="notification [notification--success|warning|error]
12
+ * <div class="icen-notification-container" role="region" aria-label="通知" data-icen-position="top-right">
13
+ * <div class="icen-notification [icen-notification--success|warning|error]
13
14
  * [.is-priority] [.is-unread] [.is-progress] [.is-clickable] [.is-paused]
14
- * [.has-avatar]" role="alert|button">
15
- * <span class="notification-icon">…svg 或 img.notification-avatar…</span>
16
- * <div class="notification-content">
17
- * <p class="notification-title">标题</p>
18
- * <p class="notification-message">正文(支持换行)</p>
19
- * <div class="notification-actions">
20
- * <button class="notification-action [--primary|--danger]">按钮</button>
15
+ * [.icen-has-avatar]" role="alert|button">
16
+ * <span class="icen-notification-icon">…svg 或 img.icen-notification-avatar…</span>
17
+ * <div class="icen-notification-content">
18
+ * <p class="icen-notification-title">标题</p>
19
+ * <p class="icen-notification-message">正文(支持换行)</p>
20
+ * <div class="icen-notification-actions">
21
+ * <button class="icen-notification-action [--primary|--danger]">按钮</button>
21
22
  * </div>
22
- * <div class="notification-link-wrap">
23
- * <a class="notification-link" href="…">查看详情</a>
23
+ * <div class="icen-notification-link-wrap">
24
+ * <a class="icen-notification-link" href="…">查看详情</a>
24
25
  * </div>
25
- * <div class="notification-progress">
26
- * <div class="notification-progress-bar" style="width:64%"></div>
27
- * <span class="notification-progress-label">64%</span>
26
+ * <div class="icen-notification-progress">
27
+ * <div class="icen-notification-progress-bar" style="width:64%"></div>
28
+ * <span class="icen-notification-progress-label">64%</span>
28
29
  * </div>
29
30
  * </div>
30
- * <button class="notification-close" aria-label="关闭">×</button>
31
- * <div class="notification-countdown">
32
- * <div class="notification-countdown-fill" style="animation-duration:5000ms"></div>
31
+ * <button class="icen-notification-close" aria-label="关闭">×</button>
32
+ * <div class="icen-notification-countdown">
33
+ * <div class="icen-notification-countdown-fill" style="animation-duration:5000ms"></div>
33
34
  * </div>
34
35
  * </div>
35
36
  * </div>
36
37
  */
37
38
 
38
- .notification-container {
39
+ .icen-notification-container {
39
40
  position: fixed;
40
- top: var(--density-space-md);
41
- right: var(--density-space-md);
42
- z-index: var(--z-toast);
41
+ top: var(--icen-density-space-md);
42
+ inset-inline-end: var(--icen-density-space-md);
43
+ z-index: var(--icen-z-toast);
43
44
  display: flex;
44
45
  flex-direction: column;
45
- gap: var(--density-space-sm);
46
- width: 360px;
47
- max-width: calc(100vw - var(--density-space-lg));
46
+ gap: var(--icen-density-space-sm);
47
+ inline-size: 360px;
48
+ max-inline-size: calc(100vw - var(--icen-density-space-lg));
48
49
  pointer-events: none;
49
50
  }
50
- .notification-container[data-position='top-left'] {
51
- right: auto;
52
- left: var(--density-space-md);
51
+ .icen-notification-container[data-icen-position='top-left'] {
52
+ right: auto; /* guard:allow-physical 物理角位置变体 top-left */
53
+ left: var(--icen-density-space-md); /* guard:allow-physical 物理角位置变体 top-left */
53
54
  }
54
- .notification-container[data-position='bottom-left'] {
55
+ .icen-notification-container[data-icen-position='bottom-left'] {
55
56
  top: auto;
56
- bottom: var(--density-space-md);
57
- right: auto;
58
- left: var(--density-space-md);
57
+ bottom: var(--icen-density-space-md);
58
+ right: auto; /* guard:allow-physical 物理角位置变体 bottom-left */
59
+ left: var(--icen-density-space-md); /* guard:allow-physical 物理角位置变体 bottom-left */
59
60
  }
60
- .notification-container[data-position='bottom-right'] {
61
+ .icen-notification-container[data-icen-position='bottom-right'] {
61
62
  top: auto;
62
- bottom: var(--density-space-md);
63
+ bottom: var(--icen-density-space-md);
63
64
  }
64
65
 
65
- .notification {
66
+ .icen-notification {
66
67
  pointer-events: auto;
67
68
  position: relative;
68
69
  display: flex;
69
70
  align-items: flex-start;
70
- gap: var(--density-space-sm);
71
- background: var(--token-card-strong);
72
- color: var(--token-text);
73
- border: 1px solid var(--token-outline-soft);
74
- border-left: 3px solid var(--token-info);
75
- border-radius: var(--radius-md);
76
- box-shadow: var(--token-shadow-overlay);
77
- padding: var(--density-space-md) var(--density-space-md) var(--density-space-md) var(--density-space-sm);
71
+ gap: var(--icen-density-space-sm);
72
+ background: var(--icen-token-card-strong);
73
+ color: var(--icen-token-text);
74
+ border: 1px solid var(--icen-token-outline-soft);
75
+ border-inline-start: 3px solid var(--icen-token-info);
76
+ border-radius: var(--icen-radius-md);
77
+ box-shadow: var(--icen-token-shadow-overlay);
78
+ padding-block: var(--icen-density-space-md);
79
+ padding-inline: var(--icen-density-space-sm) var(--icen-density-space-md);
78
80
  overflow: hidden; /* 倒计时进度条贴底 */
79
81
  animation: icen-notif-in var(--icen-tx-normal);
80
82
  }
81
- .notification.notification--success { border-left-color: var(--token-success); }
82
- .notification.notification--warning { border-left-color: var(--token-warning); }
83
- .notification.notification--error { border-left-color: var(--token-error); }
84
- /* info 为基类默认配色(基类左侧边即 --token-info),无修饰类 */
83
+ .icen-notification.icen-notification--success { border-inline-start-color: var(--icen-token-success); }
84
+ .icen-notification.icen-notification--warning { border-inline-start-color: var(--icen-token-warning); }
85
+ .icen-notification.icen-notification--error { border-inline-start-color: var(--icen-token-error); }
86
+ /* info 为基类默认配色(基类起始缘边即 --icen-token-info),无修饰类 */
85
87
 
86
- /* ── 优先级:高优先级强调(左侧加粗 + 更强阴影)── */
87
- .notification.is-priority {
88
- border-left-width: 4px;
89
- box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-accent) 24%, transparent);
90
- }
91
- .notification.is-priority.notification--success { box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-success) 28%, transparent); }
92
- .notification.is-priority.notification--warning { box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-warning) 28%, transparent); }
93
- .notification.is-priority.notification--error { box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-error) 28%, transparent); }
88
+ /* ── 优先级:高优先级强调(起始缘加粗 + 更强阴影)── */
89
+ .icen-notification.is-priority {
90
+ border-inline-start-width: 4px;
91
+ box-shadow: var(--icen-token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--icen-token-accent) 24%, transparent);
92
+ }
93
+ .icen-notification.is-priority.icen-notification--success { box-shadow: var(--icen-token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--icen-token-success) 28%, transparent); }
94
+ .icen-notification.is-priority.icen-notification--warning { box-shadow: var(--icen-token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--icen-token-warning) 28%, transparent); }
95
+ .icen-notification.is-priority.icen-notification--error { box-shadow: var(--icen-token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--icen-token-error) 28%, transparent); }
94
96
 
95
- /* ── 未读:标题左侧 4px 强调点 + 加粗 ── */
96
- .notification.is-unread .notification-title::before {
97
+ /* ── 未读:标题起始缘侧 4px 强调点(inline-block 点,margin-inline-end 与文本同向推开) + 加粗 ── */
98
+ .icen-notification.is-unread .icen-notification-title::before {
97
99
  content: '';
98
100
  display: inline-block;
99
101
  width: 6px;
100
102
  height: 6px;
101
- margin-right: 6px;
103
+ margin-inline-end: 6px;
102
104
  margin-bottom: 1px;
103
105
  vertical-align: middle;
104
- border-radius: var(--radius-full);
105
- background: var(--token-accent);
106
+ border-radius: var(--icen-radius-full);
107
+ background: var(--icen-token-accent);
106
108
  flex-shrink: 0;
107
109
  }
108
- .notification.is-unread.notification--success .notification-title::before { background: var(--token-success); }
109
- .notification.is-unread.notification--warning .notification-title::before { background: var(--token-warning); }
110
- .notification.is-unread.notification--error .notification-title::before { background: var(--token-error); }
110
+ .icen-notification.is-unread.icen-notification--success .icen-notification-title::before { background: var(--icen-token-success); }
111
+ .icen-notification.is-unread.icen-notification--warning .icen-notification-title::before { background: var(--icen-token-warning); }
112
+ .icen-notification.is-unread.icen-notification--error .icen-notification-title::before { background: var(--icen-token-error); }
111
113
 
112
114
  /* ── 可点击:整条 hover 抬升 ── */
113
- .notification.is-clickable {
115
+ .icen-notification.is-clickable {
114
116
  cursor: pointer;
115
117
  transition:
116
118
  transform var(--icen-tx-fast),
117
119
  border-color var(--icen-tx-fast),
118
120
  box-shadow var(--icen-tx-fast);
119
121
  }
120
- .notification.is-clickable:hover {
121
- transform: translateY(-1px);
122
- border-color: var(--token-accent);
122
+ /* 整条 hover 抬升仅可悬停设备生效(触屏关闭,AGENTS 动效守卫) */
123
+ @media (hover: hover) and (pointer: fine) {
124
+ .icen-notification.is-clickable:hover {
125
+ transform: translateY(-1px);
126
+ border-color: var(--icen-token-accent);
127
+ }
123
128
  }
124
129
 
125
130
  /* ── 图标 ── */
126
- .notification-icon {
131
+ .icen-notification-icon {
127
132
  display: inline-flex;
128
133
  align-items: center;
129
134
  justify-content: center;
@@ -131,168 +136,168 @@
131
136
  width: 22px;
132
137
  height: 22px;
133
138
  margin-top: 1px;
134
- border-radius: var(--radius-full);
135
- color: var(--token-text-faint);
139
+ border-radius: var(--icen-radius-full);
140
+ color: var(--icen-token-text-faint);
136
141
  }
137
- .notification-icon svg { width: 16px; height: 16px; }
138
- .notification--success .notification-icon { color: var(--token-success); }
139
- .notification--warning .notification-icon { color: var(--token-warning); }
140
- .notification--error .notification-icon { color: var(--token-error); }
142
+ .icen-notification-icon svg { width: 16px; height: 16px; }
143
+ .icen-notification--success .icen-notification-icon { color: var(--icen-token-success); }
144
+ .icen-notification--warning .icen-notification-icon { color: var(--icen-token-warning); }
145
+ .icen-notification--error .icen-notification-icon { color: var(--icen-token-error); }
141
146
 
142
147
  /* 头像(圆形图) */
143
- .notification-avatar {
148
+ .icen-notification-avatar {
144
149
  width: 28px;
145
150
  height: 28px;
146
- border-radius: var(--radius-full);
151
+ border-radius: var(--icen-radius-full);
147
152
  object-fit: cover;
148
153
  display: block;
149
154
  }
150
- .notification.has-avatar .notification-icon {
155
+ .icen-notification.icen-has-avatar .icen-notification-icon {
151
156
  width: 28px;
152
157
  height: 28px;
153
158
  margin-top: 0;
154
159
  }
155
160
 
156
161
  /* 进度通知的图标默认走品牌色 */
157
- .notification.is-progress:not(.notification--success):not(.notification--warning):not(.notification--error) .notification-icon {
158
- color: var(--token-accent);
162
+ .icen-notification.is-progress:not(.is-complete):not(.icen-notification--success):not(.icen-notification--warning):not(.icen-notification--error) .icen-notification-icon {
163
+ color: var(--icen-token-accent);
159
164
  }
160
165
 
161
166
  /* ── 内容区 ── */
162
- .notification-content {
167
+ .icen-notification-content {
163
168
  flex: 1;
164
169
  min-width: 0;
165
170
  display: flex;
166
171
  flex-direction: column;
167
172
  gap: 2px;
168
173
  }
169
- .notification-title {
174
+ .icen-notification-title {
170
175
  margin: 0;
171
- font-size: var(--density-font-size-md);
176
+ font-size: var(--icen-density-font-size-md);
172
177
  font-weight: 600;
173
178
  line-height: 1.4;
174
179
  overflow: hidden;
175
180
  text-overflow: ellipsis;
176
181
  }
177
- .notification.is-unread .notification-title {
182
+ .icen-notification.is-unread .icen-notification-title {
178
183
  font-weight: 700;
179
184
  }
180
- .notification-message {
185
+ .icen-notification-message {
181
186
  margin: 0;
182
- font-size: var(--density-font-size-sm);
183
- color: var(--token-text-muted);
187
+ font-size: var(--icen-density-font-size-sm);
188
+ color: var(--icen-token-text-muted);
184
189
  line-height: 1.5;
185
190
  word-break: break-word;
186
191
  }
187
192
 
188
193
  /* ── 多动作按钮 ── */
189
- .notification-actions {
194
+ .icen-notification-actions {
190
195
  display: flex;
191
196
  flex-wrap: wrap;
192
- gap: var(--density-space-xs);
193
- margin-top: var(--density-space-sm);
197
+ gap: var(--icen-density-space-xs);
198
+ margin-top: var(--icen-density-space-sm);
194
199
  }
195
- .notification-action {
200
+ .icen-notification-action {
196
201
  display: inline-flex;
197
202
  align-items: center;
198
203
  height: 24px;
199
- padding: 0 var(--density-space-sm);
200
- border: 1px solid var(--token-outline-soft);
201
- border-radius: var(--radius-sm);
202
- background: var(--token-fill-1);
203
- color: var(--token-text-muted);
204
+ padding: 0 var(--icen-density-space-sm);
205
+ border: 1px solid var(--icen-token-outline-soft);
206
+ border-radius: var(--icen-radius-sm);
207
+ background: var(--icen-token-fill-1);
208
+ color: var(--icen-token-text-muted);
204
209
  font: inherit;
205
- font-size: var(--density-font-size-xs);
210
+ font-size: var(--icen-density-font-size-xs);
206
211
  font-weight: 500;
207
212
  cursor: pointer;
208
213
  -webkit-tap-highlight-color: transparent;
209
214
  transition: background-color var(--icen-tx-fast), color var(--icen-tx-fast), border-color var(--icen-tx-fast);
210
215
  }
211
- .notification-action:hover {
212
- background: var(--token-fill-2);
213
- color: var(--token-text);
214
- border-color: var(--token-accent);
216
+ .icen-notification-action:hover {
217
+ background: var(--icen-token-fill-2);
218
+ color: var(--icen-token-text);
219
+ border-color: var(--icen-token-accent);
215
220
  }
216
- .notification-action:focus-visible {
221
+ .icen-notification-action:focus-visible {
217
222
  outline: none;
218
223
  box-shadow: var(--icen-ring);
219
224
  }
220
225
  /* primary:实底 accent */
221
- .notification-action--primary {
222
- background: var(--token-accent);
223
- color: var(--token-on-accent);
224
- border-color: var(--token-accent);
226
+ .icen-notification-action--primary {
227
+ background: var(--icen-token-accent-strong);
228
+ color: var(--icen-token-on-accent);
229
+ border-color: var(--icen-token-accent-strong);
225
230
  }
226
- .notification-action--primary:hover {
227
- background: var(--token-accent-deep, var(--token-accent));
228
- color: var(--token-on-accent);
229
- border-color: var(--token-accent-deep, var(--token-accent));
231
+ .icen-notification-action--primary:hover {
232
+ background: var(--icen-token-accent-deep, var(--icen-token-accent));
233
+ color: var(--icen-token-on-accent);
234
+ border-color: var(--icen-token-accent-deep, var(--icen-token-accent));
230
235
  }
231
236
  /* danger:实底 error */
232
- .notification-action--danger {
233
- background: var(--token-error);
234
- color: var(--token-on-accent);
235
- border-color: var(--token-error);
237
+ .icen-notification-action--danger {
238
+ background: var(--icen-token-error);
239
+ color: var(--icen-token-on-accent);
240
+ border-color: var(--icen-token-error);
236
241
  }
237
- .notification-action--danger:hover {
242
+ .icen-notification-action--danger:hover {
238
243
  filter: brightness(0.92);
239
- color: var(--token-on-accent);
240
- border-color: var(--token-error);
244
+ color: var(--icen-token-on-accent);
245
+ border-color: var(--icen-token-error);
241
246
  }
242
247
 
243
248
  /* ── 详情链接 ── */
244
- .notification-link-wrap {
245
- margin-top: var(--density-space-xs);
249
+ .icen-notification-link-wrap {
250
+ margin-top: var(--icen-density-space-xs);
246
251
  }
247
- .notification-link {
248
- font-size: var(--density-font-size-sm);
249
- color: var(--token-accent);
252
+ .icen-notification-link {
253
+ font-size: var(--icen-density-font-size-sm);
254
+ color: var(--icen-token-accent);
250
255
  text-decoration: none;
251
- border-bottom: 1px dashed color-mix(in srgb, var(--token-accent) 40%, transparent);
256
+ border-bottom: 1px dashed color-mix(in srgb, var(--icen-token-accent) 40%, transparent);
252
257
  transition: color var(--icen-tx-fast), border-color var(--icen-tx-fast);
253
258
  }
254
- .notification-link:hover {
255
- color: var(--token-accent-deep, var(--token-accent));
259
+ .icen-notification-link:hover {
260
+ color: var(--icen-token-accent-deep, var(--icen-token-accent));
256
261
  border-bottom-style: solid;
257
262
  }
258
- .notification-link:focus-visible {
263
+ .icen-notification-link:focus-visible {
259
264
  outline: none;
260
- border-radius: var(--radius-xs);
265
+ border-radius: var(--icen-radius-xs);
261
266
  box-shadow: var(--icen-ring);
262
267
  }
263
268
 
264
269
  /* ── 进度条 ── */
265
- .notification-progress {
270
+ .icen-notification-progress {
266
271
  display: flex;
267
272
  align-items: center;
268
- gap: var(--density-space-sm);
269
- margin-top: var(--density-space-sm);
273
+ gap: var(--icen-density-space-sm);
274
+ margin-top: var(--icen-density-space-sm);
270
275
  }
271
- .notification-progress-track {
276
+ .icen-notification-progress-track {
272
277
  flex: 1 1 auto;
273
278
  height: 4px;
274
- background: var(--token-fill-2);
275
- border-radius: var(--radius-full);
279
+ background: var(--icen-token-fill-2);
280
+ border-radius: var(--icen-radius-full);
276
281
  overflow: hidden;
277
282
  }
278
- .notification-progress-bar {
283
+ .icen-notification-progress-bar {
279
284
  height: 100%;
280
- background: var(--token-accent);
281
- border-radius: var(--radius-full);
282
- transition: width var(--icen-tx-normal) var(--ease-out);
283
- }
284
- .notification.notification--success .notification-progress-bar { background: var(--token-success); }
285
- .notification.notification--warning .notification-progress-bar { background: var(--token-warning); }
286
- .notification.notification--error .notification-progress-bar { background: var(--token-error); }
287
- .notification-progress-label {
285
+ background: var(--icen-token-accent);
286
+ border-radius: var(--icen-radius-full);
287
+ transition: width var(--icen-tx-normal) var(--icen-ease-out);
288
+ }
289
+ .icen-notification.icen-notification--success .icen-notification-progress-bar { background: var(--icen-token-success); }
290
+ .icen-notification.icen-notification--warning .icen-notification-progress-bar { background: var(--icen-token-warning); }
291
+ .icen-notification.icen-notification--error .icen-notification-progress-bar { background: var(--icen-token-error); }
292
+ .icen-notification-progress-label {
288
293
  flex: 0 0 auto;
289
- font-size: var(--density-font-size-xs);
290
- color: var(--token-text-muted);
294
+ font-size: var(--icen-density-font-size-xs);
295
+ color: var(--icen-token-text-muted);
291
296
  font-variant-numeric: tabular-nums;
292
297
  }
293
298
 
294
299
  /* ── 关闭按钮 ── */
295
- .notification-close {
300
+ .icen-notification-close {
296
301
  display: inline-flex;
297
302
  align-items: center;
298
303
  justify-content: center;
@@ -301,48 +306,47 @@
301
306
  height: 20px;
302
307
  padding: 0;
303
308
  border: 0;
304
- border-radius: var(--radius-xs);
309
+ border-radius: var(--icen-radius-xs);
305
310
  background: transparent;
306
- color: var(--token-text-faint);
311
+ color: var(--icen-token-text-faint);
307
312
  cursor: pointer;
308
313
  -webkit-tap-highlight-color: transparent;
309
314
  transition: color var(--icen-tx-fast), background-color var(--icen-tx-fast);
310
315
  }
311
- .notification-close:hover {
312
- color: var(--token-text);
313
- background: var(--token-fill-1);
316
+ .icen-notification-close:hover {
317
+ color: var(--icen-token-text);
318
+ background: var(--icen-token-fill-1);
314
319
  }
315
- .notification-close:focus-visible {
320
+ .icen-notification-close:focus-visible {
316
321
  outline: none;
317
322
  box-shadow: var(--icen-ring);
318
323
  }
319
- .notification-close svg { width: 12px; height: 12px; }
324
+ .icen-notification-close svg { width: 12px; height: 12px; }
320
325
 
321
326
  /* ── 倒计时进度条(底部贴边) ── */
322
- .notification-countdown {
327
+ .icen-notification-countdown {
323
328
  position: absolute;
324
- left: 0;
325
- right: 0;
329
+ inset-inline: 0;
326
330
  bottom: 0;
327
331
  height: 2px;
328
332
  background: transparent;
329
333
  overflow: hidden;
330
334
  }
331
- .notification-countdown-fill {
335
+ .icen-notification-countdown-fill {
332
336
  height: 100%;
333
337
  width: 100%;
334
- transform-origin: left;
335
- background: var(--token-text-faint);
338
+ transform-origin: left; /* guard:allow-physical 倒计时压缩方向是动画语义(LTR 自左向右消减),RTL 下保持同一物理节奏 */
339
+ background: var(--icen-token-text-faint);
336
340
  opacity: 0.35;
337
341
  animation-name: icen-notif-countdown;
338
342
  animation-timing-function: linear;
339
343
  animation-fill-mode: forwards;
340
344
  animation-play-state: running;
341
345
  }
342
- .notification.notification--success .notification-countdown-fill { background: var(--token-success); opacity: 0.6; }
343
- .notification.notification--warning .notification-countdown-fill { background: var(--token-warning); opacity: 0.6; }
344
- .notification.notification--error .notification-countdown-fill { background: var(--token-error); opacity: 0.6; }
345
- .notification.is-paused .notification-countdown-fill {
346
+ .icen-notification.icen-notification--success .icen-notification-countdown-fill { background: var(--icen-token-success); opacity: 0.6; }
347
+ .icen-notification.icen-notification--warning .icen-notification-countdown-fill { background: var(--icen-token-warning); opacity: 0.6; }
348
+ .icen-notification.icen-notification--error .icen-notification-countdown-fill { background: var(--icen-token-error); opacity: 0.6; }
349
+ .icen-notification.is-paused .icen-notification-countdown-fill {
346
350
  animation-play-state: paused;
347
351
  }
348
352
  @keyframes icen-notif-countdown {
@@ -351,12 +355,12 @@
351
355
  }
352
356
 
353
357
  /* ── 暂停态(hover 时) ── */
354
- .notification.is-paused {
355
- box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-accent) 14%, transparent);
358
+ .icen-notification.is-paused {
359
+ box-shadow: var(--icen-token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--icen-token-accent) 14%, transparent);
356
360
  }
357
361
 
358
362
  /* ── 退场动画 ── */
359
- .notification.is-leaving {
363
+ .icen-notification.is-leaving {
360
364
  opacity: 0;
361
365
  transform: translateX(20px);
362
366
  transition:
@@ -370,17 +374,77 @@
370
374
  }
371
375
 
372
376
  @media (max-width: 480px) {
373
- .notification-container {
374
- width: auto;
375
- left: var(--density-space-sm);
376
- right: var(--density-space-sm);
377
+ .icen-notification-container {
378
+ inline-size: auto;
379
+ inset-inline: var(--icen-density-space-sm);
380
+ }
381
+ .icen-notification {
382
+ padding-block: var(--icen-density-space-sm);
383
+ padding-inline: 10px var(--icen-density-space-sm);
377
384
  }
378
- .notification { padding: var(--density-space-sm) var(--density-space-sm) var(--density-space-sm) 10px; }
379
385
  }
380
386
 
381
387
  @media (prefers-reduced-motion: reduce) {
382
- .notification { animation: none; }
383
- .notification.is-leaving { transform: none; }
384
- .notification-countdown-fill { animation: none; transform-origin: left; }
385
- .notification-progress-bar { transition: none; }
388
+ .icen-notification { animation: none; }
389
+ .icen-notification.is-leaving { transform: none; }
390
+ .icen-notification-countdown-fill { animation: none; transform-origin: left; /* guard:allow-physical 倒计时压缩方向是动画语义(LTR 自左向右消减),RTL 下保持同一物理节奏 */ }
391
+ .icen-notification-progress-bar { transition: none; }
392
+ }
393
+
394
+ /* Quiet close shares the same fixed action slot as other interface controls. */
395
+ .icen-notification-close.icen-icon-action { inline-size: var(--icen-density-input-height-sm); block-size: var(--icen-density-input-height-sm); }
396
+ .icen-notification-close.icen-icon-action > svg { inline-size: 14px; block-size: 14px; }
397
+ .icen-notification-close:focus-visible { outline: 2px solid var(--icen-token-accent); outline-offset: 1px; }
398
+ @media (pointer: coarse) { .icen-notification-close.icen-icon-action { min-inline-size: 44px; min-block-size: 44px; } }
399
+
400
+ .icen-notification-action { min-block-size: var(--icen-density-input-height-sm); block-size: auto; }
401
+ @media (pointer: coarse) { .icen-notification-action { min-inline-size: 44px; min-block-size: 44px; } }
402
+
403
+ .icen-notification-busy-symbol { animation: icen-spin calc(var(--icen-duration-normal) * 4) linear infinite; }
404
+ .icen-notification.is-complete:not(.icen-notification--warning):not(.icen-notification--error) .icen-notification-icon { color: var(--icen-token-success); }
405
+ @media (prefers-reduced-motion: reduce) { .icen-notification-busy-symbol { animation: none; } }
406
+
407
+ .icen-notification.is-complete:not(.icen-notification--warning):not(.icen-notification--error) { border-inline-start-color: var(--icen-token-success); }
408
+ .icen-notification.is-complete:not(.icen-notification--warning):not(.icen-notification--error) .icen-notification-progress-bar { background: var(--icen-token-success); }
409
+
410
+ /* The card body is clickable, while its title is a real keyboard action.
411
+ Sibling action/close buttons never live inside a synthetic parent button. */
412
+ .icen-notification-open { display: block; inline-size: 100%; padding: 0; border: 0; border-radius: var(--icen-radius-xs); background: transparent; color: inherit; font: inherit; line-height: inherit; text-align: start; cursor: pointer; }
413
+ .icen-notification-open:hover { color: var(--icen-token-accent); }
414
+ .icen-notification-open:focus-visible { outline: 2px solid var(--icen-token-accent); outline-offset: -2px; }
415
+ :root[data-icen-style="pixel"] .icen-notification-busy-symbol { animation-timing-function: steps(8,end); }
416
+
417
+ /* Disclosure is a quiet, permanent summary action. Hidden cards leave both the
418
+ layout and tab sequence; each keeps its own callbacks, progress and identity. */
419
+ .icen-notification[hidden] { display: none !important; } /* guard:allow-important native hidden must win the flex card layout */
420
+ .icen-notification.is-group-revealing { animation: icen-pop-in var(--icen-tx-fast); }
421
+ .icen-notification-group-toggle {
422
+ display: inline-flex;
423
+ align-items: center;
424
+ justify-content: space-between;
425
+ align-self: stretch;
426
+ gap: var(--icen-density-space-sm);
427
+ min-block-size: var(--icen-density-input-height-sm);
428
+ margin-block-start: var(--icen-density-space-sm);
429
+ padding-block: var(--icen-density-space-xs);
430
+ padding-inline: var(--icen-density-space-sm);
431
+ border: 1px solid var(--icen-token-outline-soft);
432
+ border-radius: var(--icen-radius-sm);
433
+ background: var(--icen-token-fill-1);
434
+ color: var(--icen-token-text-muted);
435
+ font: inherit;
436
+ font-size: var(--icen-density-font-size-xs);
437
+ text-align: start;
438
+ cursor: pointer;
439
+ transition: color var(--icen-tx-fast), background-color var(--icen-tx-fast);
440
+ }
441
+ .icen-notification-group-toggle > svg { inline-size: 16px; block-size: 16px; flex: 0 0 16px; transition: transform var(--icen-tx-fast); }
442
+ .icen-notification-group-toggle[aria-expanded="true"] > svg { transform: rotate(180deg); }
443
+ .icen-notification-group-toggle[aria-disabled="true"] { cursor: default; }
444
+ .icen-notification-group-toggle:focus-visible { outline: 2px solid var(--icen-token-accent); outline-offset: 2px; }
445
+ @media (hover: hover) and (pointer: fine) { .icen-notification-group-toggle:not([aria-disabled="true"]):hover { color: var(--icen-token-text); background: var(--icen-token-fill-2); } }
446
+ @media (pointer: coarse) { .icen-notification-group-toggle { min-block-size: 44px; } }
447
+ @media (prefers-reduced-motion: reduce) { .icen-notification-group-toggle, .icen-notification-group-toggle > svg { transition: none; } .icen-notification.is-group-revealing { animation: none; } }
448
+ :root[data-icen-style="pixel"] .icen-notification.is-group-revealing { animation-timing-function: steps(2,end); }
449
+
386
450
  }