@icen.ai/ui 0.2.0 → 0.3.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 (103) hide show
  1. package/README.md +29 -16
  2. package/dist/base.css +389 -48
  3. package/dist/behaviors/accordion.mjs +20 -0
  4. package/dist/behaviors/carousel.mjs +30 -1
  5. package/dist/behaviors/charts.mjs +168 -0
  6. package/dist/behaviors/copy.mjs +4 -3
  7. package/dist/behaviors/datatable.mjs +748 -0
  8. package/dist/behaviors/input.mjs +20 -1
  9. package/dist/behaviors/modal.mjs +15 -1
  10. package/dist/behaviors/nav.mjs +31 -4
  11. package/dist/behaviors/sidebar.mjs +12 -0
  12. package/dist/behaviors/slider.mjs +35 -3
  13. package/dist/behaviors/tabs.mjs +100 -9
  14. package/dist/behaviors/tag-input.mjs +11 -0
  15. package/dist/behaviors/theme.mjs +26 -0
  16. package/dist/behaviors/toast.mjs +83 -15
  17. package/dist/behaviors/tree.mjs +57 -1
  18. package/dist/behaviors/upload.mjs +2 -3
  19. package/dist/cli.mjs +74 -0
  20. package/dist/components/accordion.mjs +3 -0
  21. package/dist/components/alert.mjs +2 -0
  22. package/dist/components/avatar.mjs +2 -0
  23. package/dist/components/breadcrumb.css +91 -18
  24. package/dist/components/breadcrumb.mjs +2 -0
  25. package/dist/components/btn.css +174 -14
  26. package/dist/components/btn.mjs +2 -0
  27. package/dist/components/card.css +118 -18
  28. package/dist/components/card.mjs +2 -0
  29. package/dist/components/carousel.mjs +3 -0
  30. package/dist/components/charts.css +225 -33
  31. package/dist/components/charts.mjs +3 -0
  32. package/dist/components/content.css +256 -74
  33. package/dist/components/context-menu.mjs +3 -0
  34. package/dist/components/datatable.css +343 -0
  35. package/dist/components/datatable.mjs +4 -0
  36. package/dist/components/desc.mjs +2 -0
  37. package/dist/components/dropdown.mjs +3 -0
  38. package/dist/components/empty.css +50 -10
  39. package/dist/components/empty.mjs +2 -0
  40. package/dist/components/feedback.css +158 -47
  41. package/dist/components/form.css +139 -22
  42. package/dist/components/input.css +165 -45
  43. package/dist/components/input.mjs +3 -0
  44. package/dist/components/kbd.mjs +2 -0
  45. package/dist/components/layout.mjs +2 -0
  46. package/dist/components/list.mjs +2 -0
  47. package/dist/components/media-card.mjs +2 -0
  48. package/dist/components/media.css +187 -40
  49. package/dist/components/menu.css +159 -32
  50. package/dist/components/modal.css +140 -34
  51. package/dist/components/modal.mjs +3 -0
  52. package/dist/components/nav.css +134 -32
  53. package/dist/components/nav.mjs +3 -0
  54. package/dist/components/pagination.css +105 -19
  55. package/dist/components/pagination.mjs +2 -0
  56. package/dist/components/panel.css +61 -6
  57. package/dist/components/panel.mjs +2 -0
  58. package/dist/components/pill.css +74 -14
  59. package/dist/components/pill.mjs +2 -0
  60. package/dist/components/popover.css +109 -7
  61. package/dist/components/popover.mjs +3 -0
  62. package/dist/components/progress.mjs +2 -0
  63. package/dist/components/rating.mjs +2 -0
  64. package/dist/components/result.mjs +2 -0
  65. package/dist/components/segmented.css +199 -50
  66. package/dist/components/segmented.mjs +2 -0
  67. package/dist/components/select.css +140 -39
  68. package/dist/components/select.mjs +3 -0
  69. package/dist/components/sidebar.css +162 -34
  70. package/dist/components/sidebar.mjs +3 -0
  71. package/dist/components/skeleton.mjs +2 -0
  72. package/dist/components/slider.css +169 -31
  73. package/dist/components/slider.mjs +3 -0
  74. package/dist/components/spinner.mjs +2 -0
  75. package/dist/components/stat.css +103 -8
  76. package/dist/components/stat.mjs +2 -0
  77. package/dist/components/steps.css +105 -31
  78. package/dist/components/steps.mjs +2 -0
  79. package/dist/components/switch.css +171 -54
  80. package/dist/components/switch.mjs +2 -0
  81. package/dist/components/table.css +114 -12
  82. package/dist/components/table.mjs +2 -0
  83. package/dist/components/tabs.css +104 -17
  84. package/dist/components/tabs.mjs +3 -0
  85. package/dist/components/tag-input.css +119 -23
  86. package/dist/components/tag-input.mjs +3 -0
  87. package/dist/components/timeline.mjs +2 -0
  88. package/dist/components/toast.css +85 -12
  89. package/dist/components/toast.mjs +3 -0
  90. package/dist/components/tooltip.css +86 -26
  91. package/dist/components/tooltip.mjs +2 -0
  92. package/dist/components/tree.mjs +3 -0
  93. package/dist/components/upload.css +144 -17
  94. package/dist/components/upload.mjs +3 -0
  95. package/dist/index.mjs +629 -48
  96. package/dist/registry.json +197 -2
  97. package/dist/retro-effects.css +264 -0
  98. package/dist/tokens/colors.css +18 -90
  99. package/dist/tokens/retro-effects.css +264 -0
  100. package/dist/tokens/style-profiles.css +47 -47
  101. package/dist/tokens.css +65 -137
  102. package/dist/ui.css +4861 -1019
  103. package/package.json +9 -1
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@icen.ai/ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "tokens": [
5
5
  "colors.css",
6
6
  "style-profiles.css",
7
7
  "typography.css"
8
8
  ],
9
+ "tokensExtras": [
10
+ "retro-effects.css"
11
+ ],
9
12
  "base": "base.css",
10
13
  "components": [
11
14
  "breadcrumb",
@@ -13,6 +16,7 @@
13
16
  "card",
14
17
  "charts",
15
18
  "content",
19
+ "datatable",
16
20
  "empty",
17
21
  "feedback",
18
22
  "form",
@@ -46,6 +50,7 @@
46
50
  "charts",
47
51
  "context-menu",
48
52
  "copy",
53
+ "datatable",
49
54
  "dropdown",
50
55
  "input",
51
56
  "modal",
@@ -60,5 +65,195 @@
60
65
  "toast",
61
66
  "tree",
62
67
  "upload"
63
- ]
68
+ ],
69
+ "slugs": {
70
+ "btn": {
71
+ "css": "btn.css"
72
+ },
73
+ "panel": {
74
+ "css": "panel.css"
75
+ },
76
+ "pill": {
77
+ "css": "pill.css"
78
+ },
79
+ "tabs": {
80
+ "css": "tabs.css",
81
+ "behavior": "tabs",
82
+ "init": "initTabs"
83
+ },
84
+ "stat": {
85
+ "css": "stat.css"
86
+ },
87
+ "table": {
88
+ "css": "table.css"
89
+ },
90
+ "toast": {
91
+ "css": "toast.css",
92
+ "behavior": "toast",
93
+ "exports": [
94
+ "toast"
95
+ ]
96
+ },
97
+ "input": {
98
+ "css": "input.css",
99
+ "behavior": "input",
100
+ "init": "initInput"
101
+ },
102
+ "select": {
103
+ "css": "select.css",
104
+ "behavior": "select",
105
+ "init": "initSelect"
106
+ },
107
+ "slider": {
108
+ "css": "slider.css",
109
+ "behavior": "slider",
110
+ "init": "initSlider"
111
+ },
112
+ "tag-input": {
113
+ "css": "tag-input.css",
114
+ "behavior": "tag-input",
115
+ "init": "initTagInput"
116
+ },
117
+ "switch": {
118
+ "css": "switch.css"
119
+ },
120
+ "segmented": {
121
+ "css": "segmented.css"
122
+ },
123
+ "upload": {
124
+ "css": "upload.css",
125
+ "behavior": "upload",
126
+ "init": "initUpload"
127
+ },
128
+ "modal": {
129
+ "css": "modal.css",
130
+ "behavior": "modal",
131
+ "init": "initModal"
132
+ },
133
+ "dropdown": {
134
+ "css": "menu.css",
135
+ "behavior": "dropdown",
136
+ "init": "initDropdown"
137
+ },
138
+ "context-menu": {
139
+ "css": "menu.css",
140
+ "behavior": "context-menu",
141
+ "init": "initContextMenu"
142
+ },
143
+ "popover": {
144
+ "css": "popover.css",
145
+ "behavior": "popover",
146
+ "exports": [
147
+ "openPopover",
148
+ "closePopover",
149
+ "computePopoverLayout"
150
+ ]
151
+ },
152
+ "tooltip": {
153
+ "css": "tooltip.css"
154
+ },
155
+ "card": {
156
+ "css": "card.css"
157
+ },
158
+ "empty": {
159
+ "css": "empty.css"
160
+ },
161
+ "alert": {
162
+ "css": "feedback.css"
163
+ },
164
+ "result": {
165
+ "css": "feedback.css"
166
+ },
167
+ "progress": {
168
+ "css": "feedback.css"
169
+ },
170
+ "spinner": {
171
+ "css": "feedback.css"
172
+ },
173
+ "skeleton": {
174
+ "css": "feedback.css"
175
+ },
176
+ "avatar": {
177
+ "css": "media.css"
178
+ },
179
+ "media-card": {
180
+ "css": "media.css"
181
+ },
182
+ "rating": {
183
+ "css": "media.css"
184
+ },
185
+ "kbd": {
186
+ "css": "content.css"
187
+ },
188
+ "list": {
189
+ "css": "content.css"
190
+ },
191
+ "accordion": {
192
+ "css": "content.css",
193
+ "behavior": "accordion",
194
+ "init": "initAccordion"
195
+ },
196
+ "timeline": {
197
+ "css": "content.css"
198
+ },
199
+ "desc": {
200
+ "css": "content.css"
201
+ },
202
+ "tree": {
203
+ "css": "content.css",
204
+ "behavior": "tree",
205
+ "init": "initTree"
206
+ },
207
+ "carousel": {
208
+ "css": "media.css",
209
+ "behavior": "carousel",
210
+ "init": "initCarousel"
211
+ },
212
+ "charts": {
213
+ "css": "charts.css",
214
+ "behavior": "charts",
215
+ "exports": [
216
+ "renderVBar",
217
+ "renderHBar",
218
+ "renderStack",
219
+ "renderDonut",
220
+ "renderLine",
221
+ "renderHeatmap",
222
+ "renderSparkline",
223
+ "renderGauge"
224
+ ]
225
+ },
226
+ "datatable": {
227
+ "css": "datatable.css",
228
+ "extraCss": [
229
+ "menu.css"
230
+ ],
231
+ "behavior": "datatable",
232
+ "exports": [
233
+ "createTable"
234
+ ]
235
+ },
236
+ "nav": {
237
+ "css": "nav.css",
238
+ "behavior": "nav",
239
+ "init": "initNav"
240
+ },
241
+ "sidebar": {
242
+ "css": "sidebar.css",
243
+ "behavior": "sidebar",
244
+ "init": "initSidebar"
245
+ },
246
+ "breadcrumb": {
247
+ "css": "breadcrumb.css"
248
+ },
249
+ "pagination": {
250
+ "css": "pagination.css"
251
+ },
252
+ "steps": {
253
+ "css": "steps.css"
254
+ },
255
+ "layout": {
256
+ "css": "layout.css"
257
+ }
258
+ }
64
259
  }
@@ -0,0 +1,264 @@
1
+ /*
2
+ * @icen.ai/ui — Retro 效果层(按需引入)
3
+ *
4
+ * 与 tokens.css 不同,本文件 **不** 进 tokens.css 拼合,需显式 import:
5
+ * import '@icen.ai/ui/retro-effects.css';
6
+ *
7
+ * 仅在 <html class="style-retro">(或叠加 .dark)激活时生效,对其它风格无副作用:
8
+ * - CRT 扫描线 + 暗角 + 颗粒噪点
9
+ * - 屏幕闪烁 / 抖动 / 游走扫描光
10
+ * - RGB 色散 / 霓虹发光(暗色)
11
+ * - 像素边框 / 像素按钮 / 像素分隔线工具类
12
+ * - 开机自检 / 打字机光标 / 页面闪白动画
13
+ *
14
+ * 所有动画尊重 prefers-reduced-motion:在 reduce 下由 base.css 的全局兜底降为 0.01ms。
15
+ */
16
+
17
+ /* ══════════════════════════════════════════════════════════════
18
+ CRT 显示器效果
19
+ ══════════════════════════════════════════════════════════════ */
20
+
21
+ /* CRT 扫描线 overlay */
22
+ .style-retro body::before {
23
+ content: "";
24
+ position: fixed;
25
+ inset: 0;
26
+ pointer-events: none;
27
+ z-index: 9999;
28
+ opacity: 0.14;
29
+ background:
30
+ repeating-linear-gradient(
31
+ 0deg,
32
+ transparent,
33
+ transparent 2px,
34
+ rgba(0, 0, 0, 0.35) 2px,
35
+ rgba(0, 0, 0, 0.35) 4px
36
+ );
37
+ mix-blend-mode: multiply;
38
+ }
39
+
40
+ .style-retro.dark body::before {
41
+ opacity: 0.22;
42
+ mix-blend-mode: screen;
43
+ }
44
+
45
+ /* CRT 暗角 + 轻微曲面 */
46
+ .style-retro body::after {
47
+ content: "";
48
+ position: fixed;
49
+ inset: 0;
50
+ pointer-events: none;
51
+ z-index: 9998;
52
+ background:
53
+ radial-gradient(
54
+ ellipse at center,
55
+ transparent 55%,
56
+ rgba(0, 0, 0, 0.18) 100%
57
+ );
58
+ opacity: 0.55;
59
+ }
60
+
61
+ /* 屏幕闪烁(备用工具类,需要时挂在元素上) */
62
+ @keyframes retro-flicker {
63
+ 0%, 100% { opacity: 1; }
64
+ 50% { opacity: 0.985; }
65
+ }
66
+
67
+ /* 屏幕轻微抖动(备用工具类) */
68
+ @keyframes retro-jitter {
69
+ 0%, 100% { transform: translate(0, 0); }
70
+ 25% { transform: translate(0.5px, 0); }
71
+ 50% { transform: translate(-0.5px, 0.5px); }
72
+ 75% { transform: translate(0, -0.5px); }
73
+ }
74
+
75
+ /* CRT 颗粒噪点 */
76
+ @keyframes retro-grain {
77
+ 0%, 100% { background-position: 0 0; }
78
+ 10% { background-position: -5% -10%; }
79
+ 20% { background-position: -15% 5%; }
80
+ 30% { background-position: 7% -25%; }
81
+ 40% { background-position: -5% 25%; }
82
+ 50% { background-position: -15% 10%; }
83
+ 60% { background-position: 15% 0%; }
84
+ 70% { background-position: 0% 15%; }
85
+ 80% { background-position: 3% 35%; }
86
+ 90% { background-position: -10% 10%; }
87
+ }
88
+
89
+ .style-retro .retro-crt-grain {
90
+ position: fixed;
91
+ inset: 0;
92
+ pointer-events: none;
93
+ z-index: 9997;
94
+ opacity: 0.06;
95
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
96
+ animation: retro-grain 0.5s steps(10) infinite;
97
+ }
98
+
99
+ /* ══════════════════════════════════════════════════════════════
100
+ 全局动画关键帧 + 游走扫描光
101
+ ══════════════════════════════════════════════════════════════ */
102
+
103
+ @keyframes retro-blink {
104
+ 0%, 49% { opacity: 1; }
105
+ 50%, 100% { opacity: 0; }
106
+ }
107
+
108
+ @keyframes retro-scanline-slide {
109
+ 0% { transform: translateY(-100%); }
110
+ 100% { transform: translateY(100vh); }
111
+ }
112
+
113
+ /* 游走的扫描线(偶尔闪过)—— 挂到 .style-retro 下的显式节点 */
114
+ .style-retro .retro-scanline-beam,
115
+ .retro-scanline-beam {
116
+ position: fixed;
117
+ left: 0;
118
+ right: 0;
119
+ height: 4px;
120
+ background: linear-gradient(
121
+ 180deg,
122
+ transparent,
123
+ color-mix(in srgb, var(--token-accent) 30%, transparent),
124
+ transparent
125
+ );
126
+ pointer-events: none;
127
+ z-index: 9996;
128
+ opacity: 0.4;
129
+ animation: retro-scanline-slide 4s linear infinite;
130
+ }
131
+
132
+ /* ══════════════════════════════════════════════════════════════
133
+ 开机自检 / 打字机效果
134
+ ══════════════════════════════════════════════════════════════ */
135
+
136
+ @keyframes retro-boot-text {
137
+ 0% { opacity: 0; transform: translateY(4px); }
138
+ 10% { opacity: 1; transform: translateY(0); }
139
+ 90% { opacity: 1; transform: translateY(0); }
140
+ 100% { opacity: 0; transform: translateY(-4px); }
141
+ }
142
+
143
+ .retro-boot-line {
144
+ opacity: 0;
145
+ animation: retro-boot-text 0.3s steps(1) forwards;
146
+ }
147
+
148
+ .retro-boot-line:nth-child(1) { animation-delay: 0.1s; }
149
+ .retro-boot-line:nth-child(2) { animation-delay: 0.25s; }
150
+ .retro-boot-line:nth-child(3) { animation-delay: 0.4s; }
151
+ .retro-boot-line:nth-child(4) { animation-delay: 0.55s; }
152
+ .retro-boot-line:nth-child(5) { animation-delay: 0.7s; }
153
+
154
+ /* 打字机光标 */
155
+ .retro-cursor::after {
156
+ content: "█";
157
+ display: inline-block;
158
+ margin-left: 2px;
159
+ color: var(--token-accent);
160
+ animation: retro-blink 1s step-end infinite;
161
+ }
162
+
163
+ /* ══════════════════════════════════════════════════════════════
164
+ RGB 色散 / 霓虹发光(暗色下尤其出彩)
165
+ ══════════════════════════════════════════════════════════════ */
166
+
167
+ .style-retro.dark .retro-glow {
168
+ text-shadow:
169
+ -1px 0 0 rgba(255, 0, 0, 0.4),
170
+ 1px 0 0 rgba(0, 255, 255, 0.4),
171
+ 0 0 2px var(--token-accent),
172
+ 0 0 8px var(--token-accent);
173
+ }
174
+
175
+ .style-retro.dark .retro-glow-cold {
176
+ text-shadow:
177
+ -1px 0 0 rgba(255, 0, 0, 0.4),
178
+ 1px 0 0 rgba(0, 255, 255, 0.4),
179
+ 0 0 2px var(--token-accent-cold),
180
+ 0 0 8px var(--token-accent-cold);
181
+ }
182
+
183
+ /* 亮色模式下发光退化为单层硬投影,保持像素感而不刺眼 */
184
+ .style-retro:not(.dark) .retro-glow {
185
+ text-shadow:
186
+ 1px 1px 0 color-mix(in srgb, var(--token-accent) 30%, transparent);
187
+ }
188
+
189
+ /* ══════════════════════════════════════════════════════════════
190
+ 像素边框工具类(任意风格下可用,但与 retro 最契合)
191
+ ══════════════════════════════════════════════════════════════ */
192
+
193
+ .retro-pixel-border {
194
+ border: 2px solid var(--token-line);
195
+ box-shadow:
196
+ 2px 2px 0 var(--token-line-strong),
197
+ inset 2px 2px 0 var(--token-surface-strong),
198
+ inset -2px -2px 0 var(--token-line-soft);
199
+ }
200
+
201
+ .retro-pixel-border-accent {
202
+ border: 2px solid var(--token-accent);
203
+ box-shadow:
204
+ 2px 2px 0 var(--token-accent-cold),
205
+ inset 2px 2px 0 color-mix(in srgb, var(--token-accent) 20%, transparent),
206
+ inset -2px -2px 0 color-mix(in srgb, var(--token-accent) 40%, transparent);
207
+ }
208
+
209
+ /* 像素按钮:硬投影 + 按下内移 */
210
+ .retro-pixel-button {
211
+ position: relative;
212
+ border: 2px solid var(--token-line-strong);
213
+ box-shadow:
214
+ inset -2px -2px 0 var(--token-line-soft),
215
+ inset 2px 2px 0 var(--token-surface-strong),
216
+ 2px 2px 0 var(--token-line);
217
+ transition: none;
218
+ }
219
+
220
+ .retro-pixel-button:active {
221
+ transform: translate(2px, 2px);
222
+ box-shadow:
223
+ inset -2px -2px 0 var(--token-line-soft),
224
+ inset 2px 2px 0 var(--token-surface-strong);
225
+ }
226
+
227
+ /* ══════════════════════════════════════════════════════════════
228
+ 选中文字 / 像素分隔线
229
+ ══════════════════════════════════════════════════════════════ */
230
+
231
+ .style-retro ::selection {
232
+ background: var(--token-accent);
233
+ color: var(--token-on-accent);
234
+ }
235
+
236
+ .retro-pixel-rule {
237
+ height: 0;
238
+ border: 0;
239
+ border-top: 2px dashed var(--token-line);
240
+ image-rendering: pixelated;
241
+ }
242
+
243
+ /* ══════════════════════════════════════════════════════════════
244
+ 页面切换 / 闪白效果
245
+ ══════════════════════════════════════════════════════════════ */
246
+
247
+ @keyframes retro-flash {
248
+ 0% { opacity: 0; }
249
+ 10% { opacity: 0.8; }
250
+ 100% { opacity: 0; }
251
+ }
252
+
253
+ .retro-page-flash {
254
+ position: fixed;
255
+ inset: 0;
256
+ pointer-events: none;
257
+ z-index: 10000;
258
+ background: var(--token-bg);
259
+ opacity: 0;
260
+ }
261
+
262
+ .retro-page-flash.active {
263
+ animation: retro-flash 0.2s steps(3) forwards;
264
+ }
@@ -1,10 +1,15 @@
1
1
  /*
2
2
  * Icen Design System — 色彩 Tokens
3
3
  *
4
- * 5 体系 × 2 模式 = 10 套完整配色
5
- * 每套: 12 base + 4 glow + 8 derived + 8 semantic + 8 fill + 4 border + 2 shadow + n bridge
4
+ * 6 预设 × 2 模式 = 12 套完整配色
5
+ * clay(默认)/ piano / art / vangogh / ink / retro
6
6
  *
7
- * 用法: import "./colors.css";
7
+ * 每套包含:
8
+ * 12 base + 2 glow + 6 derived + 6 semantic + 4 fill + 2 shadow + 3 outline
9
+ * + depth 层级(canvas/sidebar/panel/card/control)+ scrollbar + bridge 别名
10
+ *
11
+ * 用法: import "./colors.css"; —— 挂在 <html> 的 preset 类决定 base 取值,
12
+ * .dark 类切换明暗,二者正交组合。
8
13
  */
9
14
 
10
15
  /* ══════════════════════════════════════════════════════════════
@@ -1137,6 +1142,16 @@
1137
1142
  --token-shadow-card: 0 1px 2px color-mix(in srgb, var(--token-text) 5%, transparent), 0 6px 18px color-mix(in srgb, var(--token-text) 5%, transparent);
1138
1143
  --token-shadow-inset: inset 0 1px 1px color-mix(in srgb, var(--token-surface) 42%, transparent), inset 0 -1px 1px color-mix(in srgb, var(--token-text) 4%, transparent);
1139
1144
  --token-top-highlight: color-mix(in srgb, var(--token-surface) 36%, transparent);
1145
+
1146
+ /* ── Scrollbar ──
1147
+ 由 base.css 的全局滚动条消费;每个预设可在自己的块里覆盖这 5 个 token,
1148
+ 以表达品牌色差(如 piano 用金、ink 用青)。retro/terminal 风格在
1149
+ style-profiles.css 里另有像素化硬覆盖。 */
1150
+ --token-scrollbar-size: 8px;
1151
+ --token-scrollbar-track: transparent;
1152
+ --token-scrollbar-thumb: color-mix(in srgb, var(--token-text) 16%, transparent);
1153
+ --token-scrollbar-thumb-hover: color-mix(in srgb, var(--token-accent) 50%, transparent);
1154
+ --token-scrollbar-button: transparent;
1140
1155
  }
1141
1156
 
1142
1157
  .dark {
@@ -1219,93 +1234,6 @@
1219
1234
  --token-top-highlight: color-mix(in srgb, var(--token-surface) 18%, transparent);
1220
1235
  }
1221
1236
 
1222
- /* ── Workbench Chrome Tokens ──
1223
- Shared spatial hierarchy for Studio and Creation editors. These sit on top
1224
- of theme depth tokens so light/dark and style profiles keep their own voice
1225
- while still exposing clear IDE-like regions. */
1226
- :root {
1227
- --token-workbench-canvas: color-mix(in srgb, var(--token-bg-soft) 78%, var(--token-line-soft) 22%);
1228
- --token-workbench-sidebar: color-mix(in srgb, var(--token-bg) 76%, var(--token-surface) 24%);
1229
- --token-workbench-editor: color-mix(in srgb, var(--token-bg) 82%, var(--token-surface) 18%);
1230
- --token-workbench-panel: color-mix(in srgb, var(--token-card) 82%, var(--token-surface) 18%);
1231
- --token-workbench-panel-strong: color-mix(in srgb, var(--token-card-strong) 78%, var(--token-surface) 22%);
1232
- --token-workbench-chrome: color-mix(in srgb, var(--token-workbench-panel) 86%, var(--token-surface) 14%);
1233
- --token-workbench-rail: color-mix(in srgb, var(--token-sidebar) 84%, var(--token-bg) 16%);
1234
- --token-workbench-gutter: color-mix(in srgb, var(--token-line-soft) 30%, transparent);
1235
- --token-workbench-edge: color-mix(in srgb, var(--token-text) 10%, transparent);
1236
- --token-workbench-edge-soft: color-mix(in srgb, var(--token-text) 7%, transparent);
1237
- --token-workbench-shadow: 0 1px 1px color-mix(in srgb, var(--token-text) 3%, transparent), 0 8px 22px color-mix(in srgb, var(--token-text) 4%, transparent);
1238
- --token-workbench-shadow-inset: inset 0 1px 0 color-mix(in srgb, var(--token-surface) 28%, transparent);
1239
- --token-editor-paper: #f5efe5;
1240
- --token-editor-paper-soft: color-mix(in srgb, var(--token-editor-paper) 88%, var(--token-bg-soft) 12%);
1241
- --token-editor-paper-chrome: color-mix(in srgb, var(--token-editor-paper) 92%, var(--token-surface) 8%);
1242
- --token-editor-paper-edge: color-mix(in srgb, var(--token-text) 7%, transparent);
1243
- }
1244
-
1245
- .dark {
1246
- --token-workbench-canvas: color-mix(in srgb, var(--token-bg) 72%, black 28%);
1247
- --token-workbench-sidebar: color-mix(in srgb, var(--token-bg-soft) 72%, black 28%);
1248
- --token-workbench-editor: color-mix(in srgb, var(--token-bg) 84%, black 16%);
1249
- --token-workbench-panel: color-mix(in srgb, var(--token-panel) 82%, black 18%);
1250
- --token-workbench-panel-strong: color-mix(in srgb, var(--token-card-strong) 82%, black 18%);
1251
- --token-workbench-chrome: color-mix(in srgb, var(--token-workbench-panel) 78%, black 22%);
1252
- --token-workbench-rail: color-mix(in srgb, var(--token-sidebar) 76%, black 24%);
1253
- --token-workbench-gutter: color-mix(in srgb, var(--token-line-soft) 44%, transparent);
1254
- --token-workbench-edge: color-mix(in srgb, var(--token-text) 11%, transparent);
1255
- --token-workbench-edge-soft: color-mix(in srgb, var(--token-text) 8%, transparent);
1256
- --token-workbench-shadow: 0 1px 1px rgba(0,0,0,.16), 0 10px 26px rgba(0,0,0,.18);
1257
- --token-workbench-shadow-inset: inset 0 1px 0 color-mix(in srgb, var(--token-text) 4%, transparent);
1258
- --token-editor-paper: #26211b;
1259
- --token-editor-paper-soft: color-mix(in srgb, var(--token-editor-paper) 88%, var(--token-bg-soft) 12%);
1260
- --token-editor-paper-chrome: color-mix(in srgb, var(--token-editor-paper) 90%, var(--token-surface-strong) 10%);
1261
- --token-editor-paper-edge: color-mix(in srgb, var(--token-text) 8%, transparent);
1262
- }
1263
-
1264
- .piano {
1265
- --token-editor-paper: #fbf8ef;
1266
- }
1267
-
1268
- .piano.dark {
1269
- --token-editor-paper: #1d1b17;
1270
- }
1271
-
1272
- .art {
1273
- --token-editor-paper: #e9f2ed;
1274
- }
1275
-
1276
- .art.dark {
1277
- --token-editor-paper: #203a34;
1278
- }
1279
-
1280
- .vangogh {
1281
- --token-editor-paper: #eee5bf;
1282
- }
1283
-
1284
- .vangogh.dark {
1285
- --token-editor-paper: #172742;
1286
- }
1287
-
1288
- .ink {
1289
- --token-editor-paper: #fbf8f1;
1290
- }
1291
-
1292
- .ink.dark {
1293
- --token-editor-paper: #1b221e;
1294
- }
1295
-
1296
- .retro {
1297
- --token-editor-paper: #f4f4ea;
1298
- }
1299
-
1300
- .retro.dark {
1301
- --token-editor-paper: #24243f;
1302
- }
1303
-
1304
- .style-retro {
1305
- --token-workbench-shadow: var(--token-shadow-card);
1306
- --token-workbench-shadow-inset: var(--token-shadow-inset);
1307
- }
1308
-
1309
1237
  /* ── 动画 ── */
1310
1238
  @keyframes blink {
1311
1239
  0%, 100% { opacity: 1; }