@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.
- package/AGENTS.md +138 -80
- package/README.md +66 -91
- package/dist/base.css +208 -179
- package/dist/behaviors/accordion.mjs +8 -8
- package/dist/behaviors/ai-branch.d.mts +1 -1
- package/dist/behaviors/ai-branch.mjs +1010 -94
- package/dist/behaviors/ai-chat.d.mts +7 -7
- package/dist/behaviors/ai-chat.mjs +1071 -161
- package/dist/behaviors/ai-composer.d.mts +44 -12
- package/dist/behaviors/ai-composer.mjs +1997 -524
- package/dist/behaviors/ai-core.d.mts +1 -1
- package/dist/behaviors/ai-core.mjs +1016 -107
- package/dist/behaviors/ai-diff.mjs +1019 -127
- package/dist/behaviors/ai-feedback.d.mts +1 -1
- package/dist/behaviors/ai-feedback.mjs +1035 -126
- package/dist/behaviors/ai-panel.d.mts +8 -8
- package/dist/behaviors/ai-panel.mjs +1284 -266
- package/dist/behaviors/ai-provider.mjs +1003 -101
- package/dist/behaviors/ai-threads.d.mts +1 -1
- package/dist/behaviors/ai-threads.mjs +1068 -154
- package/dist/behaviors/ai-tool.d.mts +2 -2
- package/dist/behaviors/ai-tool.mjs +2037 -396
- package/dist/behaviors/ai-tools.d.mts +89 -16
- package/dist/behaviors/ai-tools.mjs +4448 -372
- package/dist/behaviors/autocomplete.d.mts +53 -0
- package/dist/behaviors/autocomplete.mjs +1600 -0
- package/dist/behaviors/back-top.d.mts +1 -1
- package/dist/behaviors/back-top.mjs +951 -14
- package/dist/behaviors/carousel.d.mts +1 -1
- package/dist/behaviors/carousel.mjs +906 -11
- package/dist/behaviors/cascader.d.mts +48 -0
- package/dist/behaviors/cascader.mjs +1853 -0
- package/dist/behaviors/charts.d.mts +72 -8
- package/dist/behaviors/charts.mjs +1901 -256
- package/dist/behaviors/code-block.d.mts +36 -0
- package/dist/behaviors/code-block.mjs +1611 -0
- package/dist/behaviors/command-palette.d.mts +9 -6
- package/dist/behaviors/command-palette.mjs +161 -59
- package/dist/behaviors/context-menu.d.mts +9 -8
- package/dist/behaviors/context-menu.mjs +1112 -44
- package/dist/behaviors/controls.d.mts +13 -13
- package/dist/behaviors/controls.mjs +989 -130
- package/dist/behaviors/copy.d.mts +21 -2
- package/dist/behaviors/copy.mjs +1206 -42
- package/dist/behaviors/datatable.d.mts +53 -3
- package/dist/behaviors/datatable.mjs +1963 -207
- package/dist/behaviors/date-picker.d.mts +0 -1
- package/dist/behaviors/date-picker.mjs +1340 -293
- package/dist/behaviors/design.d.mts +54 -0
- package/dist/behaviors/design.mjs +109 -0
- package/dist/behaviors/dropdown.d.mts +5 -6
- package/dist/behaviors/dropdown.mjs +262 -110
- package/dist/behaviors/events.d.mts +120 -3
- package/dist/behaviors/events.mjs +47 -2
- package/dist/behaviors/feedback.d.mts +30 -0
- package/dist/behaviors/feedback.mjs +296 -0
- package/dist/behaviors/focus.d.mts +8 -0
- package/dist/behaviors/focus.mjs +24 -0
- package/dist/behaviors/form-validate.d.mts +102 -0
- package/dist/behaviors/form-validate.mjs +6091 -0
- package/dist/behaviors/i18n.d.mts +789 -0
- package/dist/behaviors/i18n.mjs +1711 -0
- package/dist/behaviors/icons.d.mts +93 -0
- package/dist/behaviors/icons.mjs +113 -0
- package/dist/behaviors/input.d.mts +9 -1
- package/dist/behaviors/input.mjs +1056 -60
- package/dist/behaviors/kb-access.d.mts +1 -1
- package/dist/behaviors/kb-access.mjs +2129 -239
- package/dist/behaviors/kb-acl.d.mts +6 -6
- package/dist/behaviors/kb-acl.mjs +1119 -179
- package/dist/behaviors/kb-answer.mjs +2070 -418
- package/dist/behaviors/kb-audit.d.mts +1 -1
- package/dist/behaviors/kb-audit.mjs +1076 -154
- package/dist/behaviors/kb-canvas.mjs +1100 -177
- package/dist/behaviors/kb-chain.mjs +1022 -100
- package/dist/behaviors/kb-checkpoint.d.mts +1 -1
- package/dist/behaviors/kb-checkpoint.mjs +1319 -169
- package/dist/behaviors/kb-chunks.mjs +1152 -213
- package/dist/behaviors/kb-citation.d.mts +1 -1
- package/dist/behaviors/kb-citation.mjs +1201 -179
- package/dist/behaviors/kb-clarify.mjs +1058 -130
- package/dist/behaviors/kb-conflict.mjs +1041 -119
- package/dist/behaviors/kb-connector.mjs +1104 -176
- package/dist/behaviors/kb-core.d.mts +6 -1
- package/dist/behaviors/kb-core.mjs +1077 -162
- package/dist/behaviors/kb-eval.mjs +1971 -144
- package/dist/behaviors/kb-explain.d.mts +1 -1
- package/dist/behaviors/kb-explain.mjs +1024 -102
- package/dist/behaviors/kb-filter.mjs +2008 -178
- package/dist/behaviors/kb-gap.d.mts +1 -1
- package/dist/behaviors/kb-gap.mjs +1043 -121
- package/dist/behaviors/kb-hittest.d.mts +1 -1
- package/dist/behaviors/kb-hittest.mjs +1093 -150
- package/dist/behaviors/kb-metadata.mjs +1052 -130
- package/dist/behaviors/kb-passage.d.mts +2 -2
- package/dist/behaviors/kb-passage.mjs +1101 -161
- package/dist/behaviors/kb-pipeline.d.mts +2 -2
- package/dist/behaviors/kb-pipeline.mjs +1082 -162
- package/dist/behaviors/kb-qa.mjs +1088 -160
- package/dist/behaviors/kb-rerank.mjs +1047 -114
- package/dist/behaviors/kb-retrieval.mjs +2063 -224
- package/dist/behaviors/kb-review.mjs +1990 -159
- package/dist/behaviors/kb-sandbox.d.mts +1 -1
- package/dist/behaviors/kb-sandbox.mjs +1026 -104
- package/dist/behaviors/kb-segment.mjs +1111 -179
- package/dist/behaviors/kb-select.d.mts +24 -0
- package/dist/behaviors/kb-select.mjs +1989 -0
- package/dist/behaviors/kb-sources.d.mts +1 -1
- package/dist/behaviors/kb-sources.mjs +1084 -170
- package/dist/behaviors/kb-sql.d.mts +1 -1
- package/dist/behaviors/kb-sql.mjs +1143 -226
- package/dist/behaviors/kb-trace.d.mts +1 -1
- package/dist/behaviors/kb-trace.mjs +1042 -128
- package/dist/behaviors/kb-visibility.mjs +1086 -158
- package/dist/behaviors/kb-who-can.mjs +1974 -137
- package/dist/behaviors/mentions.d.mts +93 -0
- package/dist/behaviors/mentions.mjs +2152 -0
- package/dist/behaviors/modal.d.mts +4 -3
- package/dist/behaviors/modal.mjs +1055 -33
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +6 -6
- package/dist/behaviors/notification.d.mts +16 -8
- package/dist/behaviors/notification.mjs +1615 -265
- package/dist/behaviors/panel.d.mts +4 -0
- package/dist/behaviors/panel.mjs +994 -0
- package/dist/behaviors/popover.d.mts +28 -5
- package/dist/behaviors/popover.mjs +225 -24
- package/dist/behaviors/select.d.mts +5 -2
- package/dist/behaviors/select.mjs +1410 -117
- package/dist/behaviors/sidebar.d.mts +1 -1
- package/dist/behaviors/sidebar.mjs +13 -13
- package/dist/behaviors/slider.d.mts +1 -1
- package/dist/behaviors/slider.mjs +9 -9
- package/dist/behaviors/split-pane.d.mts +1 -1
- package/dist/behaviors/split-pane.mjs +7 -7
- package/dist/behaviors/suggestions.d.mts +27 -0
- package/dist/behaviors/suggestions.mjs +1089 -0
- package/dist/behaviors/svg-parse.d.mts +14 -0
- package/dist/behaviors/svg-parse.mjs +37 -0
- package/dist/behaviors/tabs.d.mts +2 -2
- package/dist/behaviors/tabs.mjs +25 -25
- package/dist/behaviors/tag-input.d.mts +23 -5
- package/dist/behaviors/tag-input.mjs +1359 -104
- package/dist/behaviors/theme-switcher.d.mts +24 -0
- package/dist/behaviors/theme-switcher.mjs +1981 -0
- package/dist/behaviors/theme.d.mts +15 -8
- package/dist/behaviors/theme.mjs +390 -28
- package/dist/behaviors/toast.d.mts +24 -25
- package/dist/behaviors/toast.mjs +1266 -88
- package/dist/behaviors/tooltip.d.mts +4 -0
- package/dist/behaviors/tooltip.mjs +378 -0
- package/dist/behaviors/tree-select.d.mts +69 -0
- package/dist/behaviors/tree-select.mjs +1907 -0
- package/dist/behaviors/tree.d.mts +1 -1
- package/dist/behaviors/tree.mjs +15 -15
- package/dist/behaviors/upload.d.mts +3 -2
- package/dist/behaviors/upload.mjs +1076 -66
- package/dist/cli.mjs +5 -6
- package/dist/components/ai-chat.css +666 -573
- package/dist/components/ai-diff.css +153 -132
- package/dist/components/ai-panel.css +351 -343
- package/dist/components/ai-tool.css +393 -238
- package/dist/components/autocomplete.css +61 -0
- package/dist/components/autocomplete.mjs +3 -0
- package/dist/components/back-top.css +34 -31
- package/dist/components/badge.css +44 -41
- package/dist/components/breadcrumb.css +67 -46
- package/dist/components/btn.css +80 -74
- package/dist/components/card.css +117 -106
- package/dist/components/cascader.css +311 -0
- package/dist/components/cascader.mjs +3 -0
- package/dist/components/chart-area.css +8 -2
- package/dist/components/chart-bar.css +95 -33
- package/dist/components/chart-gauge.css +14 -11
- package/dist/components/chart-graph.css +20 -17
- package/dist/components/chart-heatmap.css +96 -90
- package/dist/components/chart-line.css +8 -3
- package/dist/components/chart-pie.css +9 -6
- package/dist/components/chart-radar.css +8 -5
- package/dist/components/chart-scatter.css +9 -6
- package/dist/components/chart-sparkline.css +5 -2
- package/dist/components/chart-stack.css +14 -11
- package/dist/components/charts.css +164 -73
- package/dist/components/code-block.css +418 -0
- package/dist/components/code-block.mjs +4 -0
- package/dist/components/command-palette.css +138 -117
- package/dist/components/content.css +257 -251
- package/dist/components/copy.css +72 -44
- package/dist/components/datatable.css +423 -181
- package/dist/components/date-picker.css +135 -104
- package/dist/components/empty.css +68 -65
- package/dist/components/feedback.css +201 -183
- package/dist/components/form-validate.css +120 -0
- package/dist/components/form-validate.mjs +3 -0
- package/dist/components/form.css +150 -127
- package/dist/components/icon.css +102 -0
- package/dist/components/icon.mjs +3 -0
- package/dist/components/input.css +159 -104
- package/dist/components/kb-agent.css +188 -173
- package/dist/components/kb-data.css +257 -253
- package/dist/components/kb-ground.css +197 -185
- package/dist/components/kb-ingest.css +334 -350
- package/dist/components/kb-ops.css +265 -259
- package/dist/components/kb-perm.css +260 -271
- package/dist/components/kb-search.css +317 -360
- package/dist/components/kb.css +120 -109
- package/dist/components/layout.css +85 -82
- package/dist/components/material-chinese.css +73 -0
- package/dist/components/material-soviet.css +76 -0
- package/dist/components/material.css +275 -0
- package/dist/components/media.css +220 -166
- package/dist/components/mentions.css +189 -0
- package/dist/components/mentions.mjs +3 -0
- package/dist/components/menu.css +113 -105
- package/dist/components/modal.css +107 -112
- package/dist/components/nav.css +118 -115
- package/dist/components/notification.css +238 -174
- package/dist/components/pagination.css +56 -53
- package/dist/components/panel.css +66 -63
- package/dist/components/panel.mjs +1 -0
- package/dist/components/pill.css +81 -71
- package/dist/components/popover.css +67 -53
- package/dist/components/scroll-area.css +113 -110
- package/dist/components/segmented.css +146 -143
- package/dist/components/select.css +206 -186
- package/dist/components/sidebar.css +137 -127
- package/dist/components/slider.css +117 -114
- package/dist/components/split-pane.css +112 -109
- package/dist/components/stat.css +112 -106
- package/dist/components/steps.css +109 -103
- package/dist/components/switch.css +138 -134
- package/dist/components/table.css +131 -107
- package/dist/components/tabs.css +114 -108
- package/dist/components/tag-input.css +48 -133
- package/dist/components/tag.css +81 -71
- package/dist/components/theme-switcher.css +105 -0
- package/dist/components/theme-switcher.mjs +3 -0
- package/dist/components/toast.css +100 -86
- package/dist/components/toolbar.css +45 -42
- package/dist/components/tooltip.css +102 -43
- package/dist/components/tooltip.mjs +1 -0
- package/dist/components/tree-select.css +416 -0
- package/dist/components/tree-select.mjs +3 -0
- package/dist/components/upload.css +135 -92
- package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
- package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
- package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
- package/dist/fonts/OFL.txt +96 -0
- package/dist/fonts/README.md +14 -0
- package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
- package/dist/index.d.mts +28 -14
- package/dist/index.mjs +20705 -9601
- package/dist/react.d.mts +91 -0
- package/dist/react.mjs +8208 -0
- package/dist/registry.json +130 -13
- package/dist/tokens/chinese.css +44 -0
- package/dist/tokens/colors.css +365 -1222
- package/dist/tokens/design.css +109 -0
- package/dist/tokens/dtcg.json +11198 -0
- package/dist/tokens/figma.variables.json +7017 -0
- package/dist/tokens/icon-masks.css +78 -0
- package/dist/tokens/pixel.css +50 -0
- package/dist/tokens/soviet.css +44 -0
- package/dist/tokens/style-profiles.css +36 -547
- package/dist/tokens/themes.json +308 -0
- package/dist/tokens/tokens-studio.json +6728 -0
- package/dist/tokens/typography.css +21 -18
- package/dist/tokens.css +1555 -1801
- package/dist/ui.css +11975 -9831
- package/dist/vue.d.mts +344 -0
- package/dist/vue.mjs +7781 -0
- package/docs/spec/ai-input-experience.md +75 -0
- package/docs/spec/ai-native.md +238 -147
- package/docs/spec/design-philosophy.md +189 -0
- package/docs/spec/design-primitives.md +196 -0
- package/docs/spec/kb-family.md +147 -115
- package/package.json +43 -8
- package/dist/retro-effects.css +0 -255
- package/dist/tokens/retro-effects.css +0 -255
- package/docs/research/2026-10-03-ai-kb-components.md +0 -392
- package/docs/research/2026-10-03-kb-permissions.md +0 -992
package/dist/base.css
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
@layer icen.base {
|
|
1
2
|
/*
|
|
2
3
|
* @icen.ai/ui — Base(元素基线 + 交互基元 + 统一抽象层 + 滚动条)
|
|
3
4
|
*
|
|
4
|
-
* 全部消费 --token-*;任何 preset / 明暗 / style profile 下自洽。
|
|
5
|
+
* 全部消费 --icen-token-*;任何 preset / 明暗 / style profile 下自洽。
|
|
5
6
|
* 在 tokens 之后、components 之前引入。
|
|
6
7
|
*
|
|
7
8
|
* ════════════════════════════════════════════════════════════════════════
|
|
@@ -19,18 +20,18 @@
|
|
|
19
20
|
* --icen-tx-fast / -normal / -slow ← 统一过渡时长+缓动
|
|
20
21
|
*
|
|
21
22
|
* 组件直接写:
|
|
22
|
-
* .btn:focus-visible { box-shadow: var(--icen-ring); }
|
|
23
|
-
* .btn:disabled { opacity: var(--icen-disabled-opacity); }
|
|
23
|
+
* .icen-btn:focus-visible { box-shadow: var(--icen-ring); }
|
|
24
|
+
* .icen-btn:disabled { opacity: var(--icen-disabled-opacity); }
|
|
24
25
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
26
|
+
* 原语覆盖反馈配方:
|
|
27
|
+
* [data-icen-style="chinese"] { --icen-press: scale(.995); --icen-hover-border: var(--icen-token-line); }
|
|
27
28
|
*
|
|
28
29
|
* ── 层 2:6 个交互基元 class(HTML 显式组合 API)
|
|
29
|
-
* .pressable / .control / .field / .lift / .surface-elevated / .focus-ring
|
|
30
|
+
* .icen-pressable / .icen-control / .icen-field / .icen-lift / .icen-surface-elevated / .icen-focus-ring
|
|
30
31
|
*
|
|
31
32
|
* 用法(任选其一):
|
|
32
|
-
* <button class="btn pressable focus-ring"> ← 类组合,体积最小
|
|
33
|
-
* <button class="btn"> ← 自洽,CSS 引用同一原语 token
|
|
33
|
+
* <button class="icen-btn icen-pressable icen-focus-ring"> ← 类组合,体积最小
|
|
34
|
+
* <button class="icen-btn"> ← 自洽,CSS 引用同一原语 token
|
|
34
35
|
*
|
|
35
36
|
* ── 命名约定(所有组件统一)
|
|
36
37
|
* 根类: .component
|
|
@@ -38,64 +39,66 @@
|
|
|
38
39
|
* 尺寸: .component--sm / --lg / --xl
|
|
39
40
|
* 状态: .is-loading / .is-error / .is-disabled / .is-open / .is-selected /
|
|
40
41
|
* .is-focused / .is-active / .is-empty / .is-filled
|
|
41
|
-
* aria 等价: [aria-busy=true]↔.is-loading、[data-invalid=true]↔.is-error、
|
|
42
|
-
* [aria-disabled=true]/[data-disabled]↔.is-disabled、
|
|
42
|
+
* aria 等价: [aria-busy=true]↔.is-loading、[data-icen-invalid=true]↔.is-error、
|
|
43
|
+
* [aria-disabled=true]/[data-icen-disabled]↔.is-disabled、
|
|
43
44
|
* [aria-expanded=true]↔.is-open、[aria-selected=true]/[aria-current=page]↔.is-active
|
|
44
45
|
*
|
|
45
46
|
* ── Token 纪律
|
|
46
|
-
* 颜色: 仅 --token-success / -warning / -error / -info / -accent(语义)
|
|
47
|
-
* 间距: --density-space-*
|
|
48
|
-
* 字号: --density-font-size-*
|
|
49
|
-
* 控件高度: --density-input-height-*
|
|
50
|
-
* 圆角: --radius-*
|
|
51
|
-
* 阴影: --token-shadow-*
|
|
52
|
-
* 时长/缓动: --duration-* / --ease-*(或直接用 --icen-tx-*)
|
|
53
|
-
* z-index: --z-*
|
|
47
|
+
* 颜色: 仅 --icen-token-success / -warning / -error / -info / -accent(语义)
|
|
48
|
+
* 间距: --icen-density-space-*
|
|
49
|
+
* 字号: --icen-density-font-size-*
|
|
50
|
+
* 控件高度: --icen-density-input-height-*
|
|
51
|
+
* 圆角: --icen-radius-*
|
|
52
|
+
* 阴影: --icen-token-shadow-*
|
|
53
|
+
* 时长/缓动: --icen-duration-* / --icen-ease-*(或直接用 --icen-tx-*)
|
|
54
|
+
* z-index: --icen-z-*
|
|
54
55
|
*
|
|
55
56
|
* 暴露的契约:
|
|
56
57
|
* - 元素基线:box-sizing / body / a / code / pre / img / ::selection
|
|
57
|
-
* - 滚动条:贴 --token-scrollbar
|
|
58
|
-
* - 工具类:.mono / .serif / .dim / .faint / .numeric / .sr-only / .skip-link
|
|
59
|
-
* - z-index 标尺:--z-* (浮层一律 portal 到 body)
|
|
58
|
+
* - 滚动条:贴 --icen-token-scrollbar-*
|
|
59
|
+
* - 工具类:.icen-mono / .icen-serif / .icen-dim / .icen-faint / .icen-numeric / .icen-sr-only / .icen-skip-link
|
|
60
|
+
* - z-index 标尺:--icen-z-* (浮层一律 portal 到 body)
|
|
60
61
|
* - 共享 keyframes:icen-pop-in(弹层进场)/ icen-spin(旋转)/ icen-skeleton-pulse(骨架脉冲)
|
|
61
|
-
* - 交互基元 class:.pressable / .control / .field / .lift / .surface-elevated / .focus-ring / .motion
|
|
62
|
-
* - 状态约定:[aria-disabled] / [aria-busy] / [data-loading] / [data-disabled] / [data-invalid]
|
|
62
|
+
* - 交互基元 class:.icen-pressable / .icen-control / .icen-field / .icen-lift / .icen-surface-elevated / .icen-focus-ring / .icen-motion
|
|
63
|
+
* - 状态约定:[aria-disabled] / [aria-busy] / [data-icen-loading] / [data-icen-disabled] / [data-icen-invalid]
|
|
64
|
+
* - 触屏底线:@media (pointer: coarse) 下交互基元与控件目标尺寸 ≥40px
|
|
65
|
+
* (min-block/inline-size: max(var(--icen-density-input-height-md), 40px);WCAG 2.5.5 的工程折中)
|
|
66
|
+
* - 悬停守卫:.icen-lift 的 hover 抬升包在 @media (hover: hover) and (pointer: fine)(触屏关闭)
|
|
63
67
|
*/
|
|
64
68
|
|
|
65
69
|
/* ══════════════════════════════════════════════════════════════
|
|
66
70
|
icen 统一抽象层(--icen-* 原语 token)
|
|
67
71
|
───────────────────────────────────────────────────────────────
|
|
68
72
|
所有组件消费的"原语级"变量:聚焦环、悬停、按下、禁用、过渡。
|
|
69
|
-
|
|
70
|
-
即可让 56 个组件整体换肤;组件自身无需感知风格切换。
|
|
73
|
+
原语只需覆盖这里的少数变量即可让组件整体换肤;组件自身无需感知风格切换。
|
|
71
74
|
══════════════════════════════════════════════════════════════ */
|
|
72
75
|
:root {
|
|
73
76
|
/* ── 聚焦环(focus-visible) ── */
|
|
74
|
-
--icen-ring: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-accent) 50%, transparent);
|
|
75
|
-
--icen-ring-soft: 0 0 0 3px color-mix(in srgb, var(--token-accent) 16%, transparent);
|
|
76
|
-
--icen-ring-error: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-error) 50%, transparent);
|
|
77
|
-
--icen-ring-success: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-success) 50%, transparent);
|
|
78
|
-
--icen-ring-warning: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-warning) 50%, transparent);
|
|
77
|
+
--icen-ring: 0 0 0 2px var(--icen-token-bg), 0 0 0 4px color-mix(in srgb, var(--icen-token-accent) 50%, transparent);
|
|
78
|
+
--icen-ring-soft: 0 0 0 3px color-mix(in srgb, var(--icen-token-accent) 16%, transparent);
|
|
79
|
+
--icen-ring-error: 0 0 0 2px var(--icen-token-bg), 0 0 0 4px color-mix(in srgb, var(--icen-token-error) 50%, transparent);
|
|
80
|
+
--icen-ring-success: 0 0 0 2px var(--icen-token-bg), 0 0 0 4px color-mix(in srgb, var(--icen-token-success) 50%, transparent);
|
|
81
|
+
--icen-ring-warning: 0 0 0 2px var(--icen-token-bg), 0 0 0 4px color-mix(in srgb, var(--icen-token-warning) 50%, transparent);
|
|
79
82
|
/* inset 聚焦环:空间受限的网格/表头单元格用内阴影聚焦(2px 内描边 + 3px 内光晕) */
|
|
80
|
-
--icen-ring-inset: inset 0 0 0 2px color-mix(in srgb, var(--token-accent) 50%, transparent), inset 0 0 0 5px color-mix(in srgb, var(--token-accent) 14%, transparent);
|
|
83
|
+
--icen-ring-inset: inset 0 0 0 2px color-mix(in srgb, var(--icen-token-accent) 50%, transparent), inset 0 0 0 5px color-mix(in srgb, var(--icen-token-accent) 14%, transparent);
|
|
81
84
|
|
|
82
85
|
/* ── 悬停 / 按下 / 禁用 ── */
|
|
83
|
-
--icen-hover-border: color-mix(in srgb, var(--token-accent) 30%, var(--token-line));
|
|
84
|
-
--icen-hover-border-strong: color-mix(in srgb, var(--token-accent) 55%, var(--token-line));
|
|
86
|
+
--icen-hover-border: color-mix(in srgb, var(--icen-token-accent) 30%, var(--icen-token-line));
|
|
87
|
+
--icen-hover-border-strong: color-mix(in srgb, var(--icen-token-accent) 55%, var(--icen-token-line));
|
|
85
88
|
--icen-press: translateY(1px) scale(0.985);
|
|
86
89
|
--icen-press-soft: translateY(1px);
|
|
87
90
|
--icen-disabled-opacity: 0.5;
|
|
88
91
|
|
|
89
92
|
/* ── 表单控件聚焦(wrapper 视角) ── */
|
|
90
|
-
--icen-control-focus-shadow: var(--token-shadow-inset), 0 0 0 3px color-mix(in srgb, var(--token-accent) 14%, transparent);
|
|
91
|
-
--icen-control-focus-border: color-mix(in srgb, var(--token-accent) 55%, var(--token-line));
|
|
92
|
-
--icen-control-error-shadow: var(--token-shadow-inset), 0 0 0 3px color-mix(in srgb, var(--token-error) 16%, transparent);
|
|
93
|
+
--icen-control-focus-shadow: var(--icen-token-shadow-inset), 0 0 0 3px color-mix(in srgb, var(--icen-token-accent) 14%, transparent);
|
|
94
|
+
--icen-control-focus-border: color-mix(in srgb, var(--icen-token-accent) 55%, var(--icen-token-line));
|
|
95
|
+
--icen-control-error-shadow: var(--icen-token-shadow-inset), 0 0 0 3px color-mix(in srgb, var(--icen-token-error) 16%, transparent);
|
|
93
96
|
|
|
94
97
|
/* ── 统一过渡(时长 + 缓动打包) ── */
|
|
95
|
-
--icen-tx-fast: var(--duration-fast) var(--ease-out);
|
|
96
|
-
--icen-tx-normal: var(--duration-normal) var(--ease-out);
|
|
97
|
-
--icen-tx-slow: var(--duration-slow) var(--ease-out);
|
|
98
|
-
--icen-tx-bounce: var(--duration-normal) var(--ease-bounce);
|
|
98
|
+
--icen-tx-fast: var(--icen-duration-fast) var(--icen-ease-out);
|
|
99
|
+
--icen-tx-normal: var(--icen-duration-normal) var(--icen-ease-out);
|
|
100
|
+
--icen-tx-slow: var(--icen-duration-slow) var(--icen-ease-out);
|
|
101
|
+
--icen-tx-bounce: var(--icen-duration-normal) var(--icen-ease-bounce);
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
/* ══════════════════════════════════════════════════════════════
|
|
@@ -113,11 +116,11 @@ html {
|
|
|
113
116
|
}
|
|
114
117
|
|
|
115
118
|
body {
|
|
116
|
-
background: var(--token-bg);
|
|
117
|
-
color: var(--token-text);
|
|
118
|
-
font-family: "Numeric Math", var(--font-body);
|
|
119
|
+
background: var(--icen-token-bg);
|
|
120
|
+
color: var(--icen-token-text);
|
|
121
|
+
font-family: "Numeric Math", var(--icen-font-body);
|
|
119
122
|
font-size: 14px;
|
|
120
|
-
line-height: var(--line-height-body, 1.6);
|
|
123
|
+
line-height: var(--icen-line-height-body, 1.6);
|
|
121
124
|
min-height: 100vh;
|
|
122
125
|
-webkit-font-smoothing: antialiased;
|
|
123
126
|
-moz-osx-font-smoothing: grayscale;
|
|
@@ -127,21 +130,21 @@ body {
|
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
a {
|
|
130
|
-
color: var(--token-accent);
|
|
133
|
+
color: var(--icen-token-accent-text);
|
|
131
134
|
text-decoration: none;
|
|
132
|
-
transition: color var(--duration-fast) var(--ease-out);
|
|
135
|
+
transition: color var(--icen-duration-fast) var(--icen-ease-out);
|
|
133
136
|
}
|
|
134
137
|
a:hover { text-decoration: underline; text-underline-offset: 3px; }
|
|
135
138
|
a:focus-visible {
|
|
136
|
-
outline: 2px solid var(--token-accent);
|
|
139
|
+
outline: 2px solid var(--icen-token-accent);
|
|
137
140
|
outline-offset: 2px;
|
|
138
|
-
border-radius: var(--radius-xs);
|
|
141
|
+
border-radius: var(--icen-radius-xs);
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
code, pre {
|
|
142
|
-
font-family: var(--font-mono);
|
|
143
|
-
background: var(--token-bg-soft);
|
|
144
|
-
border-radius: var(--radius-xs);
|
|
145
|
+
font-family: var(--icen-font-mono);
|
|
146
|
+
background: var(--icen-token-bg-soft);
|
|
147
|
+
border-radius: var(--icen-radius-xs);
|
|
145
148
|
}
|
|
146
149
|
code { padding: 1px 5px; }
|
|
147
150
|
pre { padding: 12px 14px; overflow-x: auto; }
|
|
@@ -155,38 +158,37 @@ input, button, textarea, select { font: inherit; color: inherit; }
|
|
|
155
158
|
/* 标题用 heading 栈(typography.css 已声明,这里只兜底防缺字体场景) */
|
|
156
159
|
h1, h2, h3, h4, h5, h6 {
|
|
157
160
|
margin: 0;
|
|
158
|
-
line-height: var(--line-height-heading, 1.2);
|
|
161
|
+
line-height: var(--icen-line-height-heading, 1.2);
|
|
159
162
|
}
|
|
160
163
|
|
|
161
164
|
/* 段落兜底(消费项目可以覆盖) */
|
|
162
165
|
p { margin: 0 0 1em; }
|
|
163
166
|
|
|
164
|
-
/*
|
|
167
|
+
/* 选区随当前主题强调色变化;深色提高覆盖度。 */
|
|
165
168
|
::selection {
|
|
166
|
-
background: color-mix(in srgb, var(--token-accent) 25%, transparent);
|
|
169
|
+
background: color-mix(in srgb, var(--icen-token-accent) 25%, transparent);
|
|
167
170
|
color: inherit;
|
|
168
171
|
}
|
|
169
|
-
|
|
170
|
-
background: color-mix(in srgb, var(--token-accent) 35%, transparent);
|
|
172
|
+
[data-icen-theme="dark"] ::selection {
|
|
173
|
+
background: color-mix(in srgb, var(--icen-token-accent) 35%, transparent);
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
/* ══════════════════════════════════════════════════════════════
|
|
174
177
|
全局滚动条:细薄、无上下箭头、贴 token
|
|
175
|
-
尺寸/轨道/滑块/按钮全部走 --token-scrollbar-*,
|
|
176
|
-
|
|
177
|
-
.style-retro 在 style-profiles.css 里另有像素化硬覆盖。
|
|
178
|
+
尺寸/轨道/滑块/按钮全部走 --icen-token-scrollbar-*,
|
|
179
|
+
每个色彩预设可在自己的块里覆盖以表达品牌色差。
|
|
178
180
|
══════════════════════════════════════════════════════════════ */
|
|
179
181
|
|
|
180
|
-
::-webkit-scrollbar { width: var(--token-scrollbar-size); height: var(--token-scrollbar-size); }
|
|
181
|
-
::-webkit-scrollbar-track { background: var(--token-scrollbar-track); }
|
|
182
|
+
::-webkit-scrollbar { width: var(--icen-token-scrollbar-size); height: var(--icen-token-scrollbar-size); }
|
|
183
|
+
::-webkit-scrollbar-track { background: var(--icen-token-scrollbar-track); }
|
|
182
184
|
::-webkit-scrollbar-thumb {
|
|
183
|
-
background: var(--token-scrollbar-thumb);
|
|
184
|
-
border-radius:
|
|
185
|
+
background: var(--icen-token-scrollbar-thumb);
|
|
186
|
+
border-radius: var(--icen-radius-full);
|
|
185
187
|
border: 2px solid transparent;
|
|
186
188
|
background-clip: padding-box;
|
|
187
189
|
}
|
|
188
190
|
::-webkit-scrollbar-thumb:hover {
|
|
189
|
-
background: var(--token-scrollbar-thumb-hover);
|
|
191
|
+
background: var(--icen-token-scrollbar-thumb-hover);
|
|
190
192
|
background-clip: padding-box;
|
|
191
193
|
}
|
|
192
194
|
::-webkit-scrollbar-button,
|
|
@@ -194,26 +196,26 @@ p { margin: 0 0 1em; }
|
|
|
194
196
|
::-webkit-scrollbar-corner { background: transparent; }
|
|
195
197
|
html {
|
|
196
198
|
scrollbar-width: thin;
|
|
197
|
-
scrollbar-color: var(--token-scrollbar-thumb) var(--token-scrollbar-track);
|
|
199
|
+
scrollbar-color: var(--icen-token-scrollbar-thumb) var(--icen-token-scrollbar-track);
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
/* ══════════════════════════════════════════════════════════════
|
|
201
203
|
通用工具类
|
|
202
204
|
══════════════════════════════════════════════════════════════ */
|
|
203
205
|
|
|
204
|
-
.mono { font-family: var(--font-mono); }
|
|
205
|
-
.dim { color: var(--token-text-muted); }
|
|
206
|
-
.faint { color: var(--token-text-faint); }
|
|
207
|
-
.serif { font-family: var(--font-heading); }
|
|
206
|
+
.icen-mono { font-family: var(--icen-font-mono); }
|
|
207
|
+
.icen-dim { color: var(--icen-token-text-muted); }
|
|
208
|
+
.icen-faint { color: var(--icen-token-text-faint); }
|
|
209
|
+
.icen-serif { font-family: var(--icen-font-heading); }
|
|
208
210
|
|
|
209
211
|
/* 数字密集区:tabular-nums + 数学字体 */
|
|
210
|
-
.numeric {
|
|
211
|
-
font-family: "Numeric Math", var(--font-mono);
|
|
212
|
+
.icen-numeric {
|
|
213
|
+
font-family: "Numeric Math", var(--icen-font-mono);
|
|
212
214
|
font-variant-numeric: lining-nums tabular-nums;
|
|
213
215
|
}
|
|
214
216
|
|
|
215
217
|
/* 无障碍:屏幕阅读器可见、视觉隐藏 */
|
|
216
|
-
.sr-only {
|
|
218
|
+
.icen-sr-only {
|
|
217
219
|
position: absolute;
|
|
218
220
|
width: 1px; height: 1px;
|
|
219
221
|
padding: 0; margin: -1px;
|
|
@@ -225,23 +227,23 @@ html {
|
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
/* 跳转链接:默认视觉隐藏,聚焦时显形(无障碍要求) */
|
|
228
|
-
.skip-link {
|
|
230
|
+
.icen-skip-link {
|
|
229
231
|
position: fixed;
|
|
230
|
-
top: var(--density-space-sm, 8px);
|
|
231
|
-
left: var(--density-space-sm, 8px);
|
|
232
|
-
z-index: var(--z-tooltip);
|
|
232
|
+
top: var(--icen-density-space-sm, 8px);
|
|
233
|
+
left: var(--icen-density-space-sm, 8px);
|
|
234
|
+
z-index: var(--icen-z-tooltip);
|
|
233
235
|
padding: 8px 14px;
|
|
234
|
-
background: var(--token-surface);
|
|
235
|
-
color: var(--token-text);
|
|
236
|
-
border: 1px solid var(--token-line);
|
|
237
|
-
border-radius: var(--radius-sm);
|
|
238
|
-
box-shadow: var(--token-shadow-elevated);
|
|
236
|
+
background: var(--icen-token-surface);
|
|
237
|
+
color: var(--icen-token-text);
|
|
238
|
+
border: 1px solid var(--icen-token-line);
|
|
239
|
+
border-radius: var(--icen-radius-sm);
|
|
240
|
+
box-shadow: var(--icen-token-shadow-elevated);
|
|
239
241
|
transform: translateY(-150%);
|
|
240
|
-
transition: transform var(--duration-normal) var(--ease-out);
|
|
242
|
+
transition: transform var(--icen-duration-normal) var(--icen-ease-out);
|
|
241
243
|
}
|
|
242
|
-
.skip-link:focus {
|
|
244
|
+
.icen-skip-link:focus {
|
|
243
245
|
transform: translateY(0);
|
|
244
|
-
outline: 2px solid var(--token-accent);
|
|
246
|
+
outline: 2px solid var(--icen-token-accent);
|
|
245
247
|
outline-offset: 2px;
|
|
246
248
|
}
|
|
247
249
|
|
|
@@ -257,19 +259,19 @@ html {
|
|
|
257
259
|
dialog → 模态对话框 + backdrop
|
|
258
260
|
popover → 弹出层/下拉菜单(高于 dialog 因为常常 portal 出去)
|
|
259
261
|
tooltip → 工具提示
|
|
260
|
-
fx →
|
|
262
|
+
fx → 效果层(永远在最上)
|
|
261
263
|
══════════════════════════════════════════════════════════════ */
|
|
262
264
|
:root {
|
|
263
|
-
--z-base: 0;
|
|
264
|
-
--z-raised: 10;
|
|
265
|
-
--z-sticky: 50;
|
|
266
|
-
--z-chrome: 200;
|
|
267
|
-
--z-toast: 400;
|
|
268
|
-
--z-banner: 450;
|
|
269
|
-
--z-dialog: 500;
|
|
270
|
-
--z-popover: 620;
|
|
271
|
-
--z-tooltip: 700;
|
|
272
|
-
--z-fx: 1000;
|
|
265
|
+
--icen-z-base: 0;
|
|
266
|
+
--icen-z-raised: 10;
|
|
267
|
+
--icen-z-sticky: 50;
|
|
268
|
+
--icen-z-chrome: 200;
|
|
269
|
+
--icen-z-toast: 400;
|
|
270
|
+
--icen-z-banner: 450;
|
|
271
|
+
--icen-z-dialog: 500;
|
|
272
|
+
--icen-z-popover: 620;
|
|
273
|
+
--icen-z-tooltip: 700;
|
|
274
|
+
--icen-z-fx: 1000;
|
|
273
275
|
}
|
|
274
276
|
|
|
275
277
|
/* ══════════════════════════════════════════════════════════════
|
|
@@ -277,12 +279,12 @@ html {
|
|
|
277
279
|
icen-pop-in → 弹层进场(scale .96 + translateY -4px)
|
|
278
280
|
icen-spin → 旋转(spinner / 加载态)
|
|
279
281
|
icen-skeleton-pulse → 骨架脉冲
|
|
280
|
-
注:menu.css / popover.css 保留自己的 scale(.
|
|
281
|
-
(方向语义不同:按 data-side 反向位移),不并入 icen-pop-in。
|
|
282
|
+
注:menu.css / popover.css 保留自己的 scale(.985)±3px 四方向版
|
|
283
|
+
(方向语义不同:按 data-icen-side 反向位移),不并入 icen-pop-in。
|
|
282
284
|
══════════════════════════════════════════════════════════════ */
|
|
283
285
|
@keyframes icen-pop-in {
|
|
284
|
-
from { opacity: 0;
|
|
285
|
-
to { opacity: 1;
|
|
286
|
+
from { opacity: 0; }
|
|
287
|
+
to { opacity: 1; }
|
|
286
288
|
}
|
|
287
289
|
@keyframes icen-spin {
|
|
288
290
|
to { transform: rotate(360deg); }
|
|
@@ -295,14 +297,13 @@ html {
|
|
|
295
297
|
/* ══════════════════════════════════════════════════════════════
|
|
296
298
|
交互基元(全组件地基)
|
|
297
299
|
规格:源 self-contained,命名空间不含 opengal 的 og-/vn- 前缀。
|
|
298
|
-
|
|
299
|
-
这些类名施加像素化覆盖;改名前请同步修 style-profiles.css。
|
|
300
|
+
原语通过 --icen-* 反馈变量覆盖这些基元,类名契约保持稳定。
|
|
300
301
|
══════════════════════════════════════════════════════════════ */
|
|
301
302
|
|
|
302
|
-
/* ── .pressable — 可按压(按钮、卡片按钮、tag close 等)
|
|
303
|
+
/* ── .icen-pressable — 可按压(按钮、卡片按钮、tag close 等)
|
|
303
304
|
hover:顶部高光 ::after 渐入;focus-visible:同样高光 + 描边
|
|
304
305
|
active:下陷 + 微缩;aria-busy:减淡;disabled / aria-disabled:50% + 禁手势 */
|
|
305
|
-
.pressable {
|
|
306
|
+
.icen-pressable {
|
|
306
307
|
position: relative;
|
|
307
308
|
overflow: hidden;
|
|
308
309
|
will-change: transform;
|
|
@@ -314,7 +315,7 @@ html {
|
|
|
314
315
|
opacity var(--icen-tx-normal),
|
|
315
316
|
transform var(--icen-tx-normal);
|
|
316
317
|
}
|
|
317
|
-
.pressable::after {
|
|
318
|
+
.icen-pressable::after {
|
|
318
319
|
content: '';
|
|
319
320
|
position: absolute;
|
|
320
321
|
inset: 0;
|
|
@@ -322,129 +323,136 @@ html {
|
|
|
322
323
|
opacity: 0;
|
|
323
324
|
pointer-events: none;
|
|
324
325
|
background: linear-gradient(180deg,
|
|
325
|
-
color-mix(in srgb, var(--token-surface) 24%, transparent),
|
|
326
|
+
color-mix(in srgb, var(--icen-token-surface) 24%, transparent),
|
|
326
327
|
transparent 46%);
|
|
327
328
|
transition: opacity var(--icen-tx-normal);
|
|
328
329
|
}
|
|
329
|
-
.pressable:hover::after,
|
|
330
|
-
.pressable:focus-visible::after { opacity: 1; }
|
|
331
|
-
.pressable:focus-visible {
|
|
330
|
+
.icen-pressable:hover::after,
|
|
331
|
+
.icen-pressable:focus-visible::after { opacity: 1; }
|
|
332
|
+
.icen-pressable:focus-visible {
|
|
332
333
|
outline: none;
|
|
333
334
|
box-shadow: var(--icen-ring);
|
|
334
335
|
}
|
|
335
|
-
.pressable:active {
|
|
336
|
+
.icen-pressable:active {
|
|
336
337
|
transform: var(--icen-press);
|
|
337
338
|
}
|
|
338
|
-
.pressable[aria-busy='true'],
|
|
339
|
-
.pressable[data-loading] {
|
|
339
|
+
.icen-pressable[aria-busy='true'],
|
|
340
|
+
.icen-pressable[data-icen-loading] {
|
|
340
341
|
cursor: progress;
|
|
341
342
|
opacity: 0.7;
|
|
342
343
|
pointer-events: none;
|
|
343
344
|
}
|
|
344
|
-
.pressable:disabled,
|
|
345
|
-
.pressable[aria-disabled='true'],
|
|
346
|
-
.pressable[data-disabled] {
|
|
345
|
+
.icen-pressable:disabled,
|
|
346
|
+
.icen-pressable[aria-disabled='true'],
|
|
347
|
+
.icen-pressable[data-icen-disabled] {
|
|
347
348
|
transform: none;
|
|
348
349
|
opacity: var(--icen-disabled-opacity);
|
|
349
350
|
cursor: not-allowed;
|
|
350
351
|
pointer-events: none;
|
|
351
352
|
}
|
|
352
|
-
.pressable:disabled::after,
|
|
353
|
-
.pressable[aria-disabled='true']::after,
|
|
354
|
-
.pressable[data-disabled]::after { display: none; }
|
|
353
|
+
.icen-pressable:disabled::after,
|
|
354
|
+
.icen-pressable[aria-disabled='true']::after,
|
|
355
|
+
.icen-pressable[data-icen-disabled]::after { display: none; }
|
|
355
356
|
|
|
356
|
-
/* ── .control — 表单控件 wrapper 基元(包裹原生 input/textarea/select)
|
|
357
|
+
/* ── .icen-control — 表单控件 wrapper 基元(包裹原生 input/textarea/select)
|
|
357
358
|
hover:边框稍深;focus-within:内嵌阴影 + accent 3px 光晕
|
|
358
|
-
:invalid / [data-invalid]:error 色边框 + error 色光晕 */
|
|
359
|
-
.control {
|
|
359
|
+
:invalid / [data-icen-invalid]:error 色边框 + error 色光晕 */
|
|
360
|
+
.icen-control {
|
|
360
361
|
transition: background-color var(--icen-tx-normal),
|
|
361
362
|
border-color var(--icen-tx-normal),
|
|
362
363
|
box-shadow var(--icen-tx-normal);
|
|
363
364
|
}
|
|
364
|
-
.control:hover {
|
|
365
|
+
.icen-control:hover {
|
|
365
366
|
border-color: var(--icen-hover-border);
|
|
366
367
|
}
|
|
367
|
-
.control:focus-within {
|
|
368
|
+
.icen-control:focus-within {
|
|
368
369
|
box-shadow: var(--icen-control-focus-shadow);
|
|
369
370
|
border-color: var(--icen-control-focus-border);
|
|
370
371
|
}
|
|
371
|
-
.control:where(:has(:invalid), [data-invalid='true']) {
|
|
372
|
-
border-color: var(--token-error);
|
|
372
|
+
.icen-control:where(:has(:invalid), [data-icen-invalid='true']) {
|
|
373
|
+
border-color: var(--icen-token-error);
|
|
373
374
|
}
|
|
374
|
-
.control:where(:has(:invalid), [data-invalid='true']):focus-within {
|
|
375
|
+
.icen-control:where(:has(:invalid), [data-icen-invalid='true']):focus-within {
|
|
375
376
|
box-shadow: var(--icen-control-error-shadow);
|
|
376
|
-
border-color: var(--token-error);
|
|
377
|
+
border-color: var(--icen-token-error);
|
|
377
378
|
}
|
|
378
379
|
/* 内部裸 input/textarea/select 不再有自己的边框/阴影,交给 wrapper 表达 */
|
|
379
|
-
.control > input:not([type='checkbox']):not([type='radio']):not([type='file']),
|
|
380
|
-
.control > textarea,
|
|
381
|
-
.control > select {
|
|
380
|
+
.icen-control > input:not([type='checkbox']):not([type='radio']):not([type='file']),
|
|
381
|
+
.icen-control > textarea,
|
|
382
|
+
.icen-control > select {
|
|
382
383
|
background: transparent;
|
|
383
384
|
border: 0;
|
|
384
385
|
outline: none;
|
|
385
386
|
box-shadow: none;
|
|
386
387
|
}
|
|
387
388
|
|
|
388
|
-
/* ── .field — 带 label / hint / error
|
|
389
|
+
/* ── .icen-field — 带 label / hint / error 的表单字段容器
|
|
389
390
|
契约:
|
|
390
|
-
<label class="field">
|
|
391
|
-
<span class="field-label">姓名</span>
|
|
392
|
-
<span class="control"><input /></span>
|
|
393
|
-
<span class="field-hint">必填</span>
|
|
394
|
-
<span class="field-error">错误</span>
|
|
391
|
+
<label class="icen-field">
|
|
392
|
+
<span class="icen-field-label">姓名</span>
|
|
393
|
+
<span class="icen-control"><icen-input /></span>
|
|
394
|
+
<span class="icen-field-hint">必填</span>
|
|
395
|
+
<span class="icen-field-error">错误</span>
|
|
395
396
|
</label> */
|
|
396
|
-
.field {
|
|
397
|
+
.icen-field {
|
|
397
398
|
display: flex;
|
|
398
399
|
flex-direction: column;
|
|
399
|
-
gap: var(--density-space-xs);
|
|
400
|
+
gap: var(--icen-density-space-xs);
|
|
400
401
|
}
|
|
401
|
-
.field-label {
|
|
402
|
-
font-size: var(--density-font-size-sm);
|
|
403
|
-
color: var(--token-text-muted);
|
|
402
|
+
.icen-field-label {
|
|
403
|
+
font-size: var(--icen-density-font-size-sm);
|
|
404
|
+
color: var(--icen-token-text-muted);
|
|
404
405
|
letter-spacing: 0.02em;
|
|
405
406
|
}
|
|
406
|
-
.field-hint {
|
|
407
|
-
font-size: var(--density-font-size-xs);
|
|
408
|
-
color: var(--token-text-faint);
|
|
407
|
+
.icen-field-hint {
|
|
408
|
+
font-size: var(--icen-density-font-size-xs);
|
|
409
|
+
color: var(--icen-token-text-faint);
|
|
409
410
|
}
|
|
410
|
-
.field-error {
|
|
411
|
-
font-size: var(--density-font-size-xs);
|
|
412
|
-
color: var(--token-error);
|
|
411
|
+
.icen-field-error {
|
|
412
|
+
font-size: var(--icen-density-font-size-xs);
|
|
413
|
+
color: var(--icen-token-error);
|
|
413
414
|
}
|
|
414
|
-
.field[data-invalid='true'] .field-label { color: var(--token-error); }
|
|
415
|
+
.icen-field[data-icen-invalid='true'] .icen-field-label { color: var(--icen-token-error); }
|
|
415
416
|
|
|
416
|
-
/* ── .lift — 可交互卡片悬停浮起(pressable 的轻量版,无 ::after 高光)
|
|
417
|
-
hover
|
|
418
|
-
|
|
417
|
+
/* ── .icen-lift — 可交互卡片悬停浮起(pressable 的轻量版,无 ::after 高光)
|
|
418
|
+
hover:仅在可悬停设备生效(触屏关闭抬升,AGENTS 动效守卫);
|
|
419
|
+
focus-within:全设备生效(键盘/触屏焦点同样给浮起反馈) */
|
|
420
|
+
.icen-lift {
|
|
419
421
|
transition: border-color var(--icen-tx-slow),
|
|
420
422
|
box-shadow var(--icen-tx-slow),
|
|
421
423
|
transform var(--icen-tx-slow);
|
|
422
424
|
}
|
|
423
|
-
|
|
424
|
-
.lift:
|
|
425
|
+
@media (hover: hover) and (pointer: fine) {
|
|
426
|
+
.icen-lift:hover {
|
|
427
|
+
transform: translateY(-1px);
|
|
428
|
+
border-color: color-mix(in srgb, var(--icen-token-accent) 26%, var(--icen-token-outline-soft));
|
|
429
|
+
box-shadow: var(--icen-token-shadow-card);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
.icen-lift:focus-within {
|
|
425
433
|
transform: translateY(-1px);
|
|
426
|
-
border-color: color-mix(in srgb, var(--token-accent) 26%, var(--token-outline-soft));
|
|
427
|
-
box-shadow: var(--token-shadow-card);
|
|
434
|
+
border-color: color-mix(in srgb, var(--icen-token-accent) 26%, var(--icen-token-outline-soft));
|
|
435
|
+
box-shadow: var(--icen-token-shadow-card);
|
|
428
436
|
}
|
|
429
437
|
|
|
430
|
-
/* ── .surface-elevated — 提升的静态表面(非交互卡片)
|
|
438
|
+
/* ── .icen-surface-elevated — 提升的静态表面(非交互卡片)
|
|
431
439
|
用于不需要 hover 反馈但需要脱离背景的面板/对话框内嵌区域 */
|
|
432
|
-
.surface-elevated {
|
|
433
|
-
background: var(--token-surface);
|
|
434
|
-
border: 1px solid var(--token-line-soft);
|
|
435
|
-
border-radius: var(--radius-md);
|
|
436
|
-
box-shadow: var(--token-shadow-card);
|
|
440
|
+
.icen-surface-elevated {
|
|
441
|
+
background: var(--icen-token-surface);
|
|
442
|
+
border: 1px solid var(--icen-token-line-soft);
|
|
443
|
+
border-radius: var(--icen-radius-md);
|
|
444
|
+
box-shadow: var(--icen-token-shadow-card);
|
|
437
445
|
}
|
|
438
446
|
|
|
439
|
-
/* ── .focus-ring — 显式聚焦环工具类(ring-2 + offset-1 等价) */
|
|
440
|
-
.focus-ring:focus-visible {
|
|
447
|
+
/* ── .icen-focus-ring — 显式聚焦环工具类(ring-2 + offset-1 等价) */
|
|
448
|
+
.icen-focus-ring:focus-visible {
|
|
441
449
|
outline: none;
|
|
442
450
|
box-shadow: var(--icen-ring);
|
|
443
451
|
}
|
|
444
452
|
|
|
445
|
-
/* ── .motion — 显式动画工具类(仅在 prefers-reduced-motion: no-preference 时生效) */
|
|
453
|
+
/* ── .icen-motion — 显式动画工具类(仅在 prefers-reduced-motion: no-preference 时生效) */
|
|
446
454
|
@media (prefers-reduced-motion: no-preference) {
|
|
447
|
-
.motion { transition: all var(--icen-tx-normal); }
|
|
455
|
+
.icen-motion { transition: all var(--icen-tx-normal); }
|
|
448
456
|
}
|
|
449
457
|
|
|
450
458
|
/* ══════════════════════════════════════════════════════════════
|
|
@@ -454,26 +462,25 @@ html {
|
|
|
454
462
|
/* reduced-motion:所有动画/过渡压缩到 ~0ms(保留可访问性最小可视信号) */
|
|
455
463
|
@media (prefers-reduced-motion: reduce) {
|
|
456
464
|
*, *::before, *::after {
|
|
457
|
-
animation-duration: 0.01ms !important;
|
|
458
|
-
animation-iteration-count: 1 !important;
|
|
459
|
-
transition-duration: 0.01ms !important;
|
|
460
|
-
scroll-behavior: auto !important;
|
|
465
|
+
animation-duration: 0.01ms !important; /* guard:allow-important 动效守卫:降级媒体查询需压制组件动画 */
|
|
466
|
+
animation-iteration-count: 1 !important; /* guard:allow-important 动效守卫:降级媒体查询需压制组件动画 */
|
|
467
|
+
transition-duration: 0.01ms !important; /* guard:allow-important 动效守卫:降级媒体查询需压制组件动画 */
|
|
468
|
+
scroll-behavior: auto !important; /* guard:allow-important 动效守卫:降级媒体查询需压制组件动画 */
|
|
461
469
|
}
|
|
462
470
|
}
|
|
463
471
|
|
|
464
|
-
/*
|
|
472
|
+
/* 触屏设备(无精细指针):压低 pressable 按下形变(hover 抬升已由 hover 守卫关闭) */
|
|
465
473
|
@media (pointer: coarse) {
|
|
466
|
-
.
|
|
467
|
-
.pressable:active { transform: translateY(0) scale(0.99); }
|
|
474
|
+
.icen-pressable:active { transform: translateY(0) scale(0.99); }
|
|
468
475
|
}
|
|
469
476
|
|
|
470
477
|
/* 高对比度模式(Windows High Contrast / 强制 colors) */
|
|
471
478
|
@media (forced-colors: active) {
|
|
472
|
-
.pressable, .control, .lift, .surface-elevated, .focus-ring:focus-visible {
|
|
479
|
+
.icen-pressable, .icen-control, .icen-lift, .icen-surface-elevated, .icen-focus-ring:focus-visible {
|
|
473
480
|
forced-color-adjust: none;
|
|
474
481
|
}
|
|
475
|
-
.focus-ring:focus-visible,
|
|
476
|
-
.pressable:focus-visible {
|
|
482
|
+
.icen-focus-ring:focus-visible,
|
|
483
|
+
.icen-pressable:focus-visible {
|
|
477
484
|
outline: 2px solid Highlight;
|
|
478
485
|
outline-offset: 2px;
|
|
479
486
|
}
|
|
@@ -482,15 +489,37 @@ html {
|
|
|
482
489
|
/* 打印:去掉阴影/背景/动效,节约墨水并避免打印截断 */
|
|
483
490
|
@media print {
|
|
484
491
|
*, *::before, *::after {
|
|
485
|
-
background: transparent !important;
|
|
486
|
-
color: #000 !important;
|
|
487
|
-
box-shadow: none !important;
|
|
488
|
-
text-shadow: none !important;
|
|
492
|
+
background: transparent !important; /* guard:allow-important 打印样式需确定性覆盖 */
|
|
493
|
+
color: #000 !important; /* guard:allow-important 打印样式需确定性覆盖 */
|
|
494
|
+
box-shadow: none !important; /* guard:allow-important 打印样式需确定性覆盖 */
|
|
495
|
+
text-shadow: none !important; /* guard:allow-important 打印样式需确定性覆盖 */
|
|
489
496
|
}
|
|
490
497
|
body { font-size: 12pt; line-height: 1.4; }
|
|
491
498
|
a, a:visited { text-decoration: underline; }
|
|
492
499
|
a[href]::after { content: ' (' attr(href) ')'; font-size: 90%; }
|
|
493
500
|
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
|
494
501
|
h1, h2, h3 { page-break-after: avoid; }
|
|
495
|
-
.pressable, .lift, .surface-elevated { box-shadow: none !important; transform: none !important; }
|
|
502
|
+
.icen-pressable, .icen-lift, .icen-surface-elevated { box-shadow: none !important; /* guard:allow-important 状态/守卫覆盖需压制变体优先级 */ transform: none !important; }
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/* ══════════════════════════════════════════════════════════════
|
|
506
|
+
触屏目标尺寸底线(@media pointer: coarse)
|
|
507
|
+
───────────────────────────────────────────────────────────────
|
|
508
|
+
交互基元与控件的可点区域在触屏下抬到 ≥40px:WCAG 2.5.5(Target
|
|
509
|
+
Size AAA 44px)的工程折中。用 max() 保住密度 token 的调节权——
|
|
510
|
+
密度档高于 40px 时仍按 token 走;逻辑属性形态(block/inline)
|
|
511
|
+
与全库书写方向自洽。块与内联同时给底线(方形命中区)。
|
|
512
|
+
══════════════════════════════════════════════════════════════ */
|
|
513
|
+
@media (pointer: coarse) {
|
|
514
|
+
.icen-pressable,
|
|
515
|
+
.icen-control,
|
|
516
|
+
.icen-field,
|
|
517
|
+
.icen-lift,
|
|
518
|
+
button.icen-btn,
|
|
519
|
+
a[role='button'] {
|
|
520
|
+
min-block-size: max(var(--icen-density-input-height-md), 40px);
|
|
521
|
+
min-inline-size: max(var(--icen-density-input-height-md), 40px);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
496
525
|
}
|