@longzai-intelligence-liquid-glass/tokens 0.0.1

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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @longzai-intelligence-liquid-glass/tokens
2
+
3
+ Liquid Glass 设计令牌包:玻璃海拔分级(1–5)、OKLCH 语义色、折射边框、亮度适配、动效令牌与全部 keyframes,以纯 CSS 发布。
4
+
5
+ 衍生自 [glinui](https://github.com/glincker/glinui) 的 tokens 成果(MIT, Copyright (c) 2026 Glincker LLC),经系统性转译与 house 规范化。
6
+
7
+ ## 用法
8
+
9
+ ```tsx
10
+ import '@longzai-intelligence-liquid-glass/tokens/styles.css';
11
+ ```
12
+
13
+ - CSS 变量:`--glass-{1..5}-{blur,surface,shadow}`、`--color-*`、`--motion-*`、`--easing-*`
14
+ - 工具类:`.glass-1` … `.glass-5`(海拔三件套)、`.glass-gpu-hint` / `.glass-heavy`(性能提示)、`.anim-*`(keyframes 动画)
15
+ - 亮度适配:`.glass-adapt-{neutral,bright,dim}` 或 `data-glass-luminance` 属性
16
+ - 暗色模式:根节点 `.dark` 类;`prefers-reduced-transparency` / `prefers-reduced-motion` 自动降级
17
+ - TS 侧:`GlassElevationLevel`、`GLASS_ELEVATION_LEVELS`、`MOTION_DURATIONS`、`MOTION_EASINGS`
@@ -0,0 +1,79 @@
1
+ //#region src/elevation.types.d.ts
2
+ /**
3
+ * 玻璃海拔层级类型
4
+ *
5
+ * 对应 styles.css 中的 --glass-{level}-* 变量族(blur/surface/shadow 三件套)。
6
+ */
7
+ /**
8
+ * 玻璃海拔层级(1 最轻 → 5 最重)
9
+ */
10
+ type GlassElevationLevel = '1' | '2' | '3' | '4' | '5';
11
+ /**
12
+ * 背景亮度适配模式
13
+ */
14
+ type GlassLuminanceMode = 'neutral' | 'bright' | 'dim';
15
+ //#endregion
16
+ //#region src/elevation.constants.d.ts
17
+ /**
18
+ * 全部合法海拔层级(升序)
19
+ */
20
+ declare const GLASS_ELEVATION_LEVELS: readonly GlassElevationLevel[];
21
+ /**
22
+ * 全部合法背景亮度适配模式
23
+ */
24
+ declare const GLASS_LUMINANCE_MODES: readonly GlassLuminanceMode[];
25
+ /**
26
+ * 判断值是否为合法海拔层级
27
+ *
28
+ * @param value - 待校验值
29
+ * @returns 是合法层级时为 true
30
+ */
31
+ declare function isGlassElevationLevel(value: unknown): value is GlassElevationLevel;
32
+ //#endregion
33
+ //#region src/motion.constants.d.ts
34
+ /**
35
+ * 动效令牌常量
36
+ *
37
+ * 与 styles.css 中的 --motion-* / --easing-* CSS 变量保持同值,
38
+ * 供无法消费 CSS 变量的场景(canvas/Skia/测试断言)读取。
39
+ */
40
+ /**
41
+ * 动效时长令牌(毫秒)
42
+ */
43
+ declare const MOTION_DURATIONS: {
44
+ /**
45
+ * 快速(微交互反馈)
46
+ */
47
+ readonly fast: 150;
48
+ /**
49
+ * 常规(默认过渡)
50
+ */
51
+ readonly normal: 250;
52
+ /**
53
+ * 缓慢(大面积转场)
54
+ */
55
+ readonly slow: 400;
56
+ /**
57
+ * 弹簧(带回弹的物理动效)
58
+ */
59
+ readonly spring: 500;
60
+ };
61
+ /**
62
+ * 动效缓动令牌(cubic-bezier 参数)
63
+ */
64
+ declare const MOTION_EASINGS: {
65
+ /**
66
+ * 标准(减速为主,UI 进入常用)
67
+ */
68
+ readonly standard: 'cubic-bezier(0.2, 0, 0, 1)';
69
+ /**
70
+ * 弹簧(过冲回弹)
71
+ */
72
+ readonly spring: 'cubic-bezier(0.34, 1.56, 0.64, 1)';
73
+ /**
74
+ * 玻璃(对称缓入缓出)
75
+ */
76
+ readonly glass: 'cubic-bezier(0.4, 0, 0.2, 1)';
77
+ };
78
+ //#endregion
79
+ export { GLASS_ELEVATION_LEVELS, GLASS_LUMINANCE_MODES, type GlassElevationLevel, type GlassLuminanceMode, MOTION_DURATIONS, MOTION_EASINGS, isGlassElevationLevel };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ const e=[`1`,`2`,`3`,`4`,`5`],t=[`neutral`,`bright`,`dim`];function n(t){return e.includes(t)}const r={fast:150,normal:250,slow:400,spring:500},i={standard:`cubic-bezier(0.2, 0, 0, 1)`,spring:`cubic-bezier(0.34, 1.56, 0.64, 1)`,glass:`cubic-bezier(0.4, 0, 0.2, 1)`};export{e as GLASS_ELEVATION_LEVELS,t as GLASS_LUMINANCE_MODES,r as MOTION_DURATIONS,i as MOTION_EASINGS,n as isGlassElevationLevel};
@@ -0,0 +1,958 @@
1
+ /**
2
+ * Liquid Glass 设计令牌(玻璃海拔 / 光学色彩 / 动效)
3
+ *
4
+ * 衍生自 glinui tokens(MIT, Copyright (c) 2026 Glincker LLC),转译为纯 CSS 发布。
5
+ *
6
+ * 关键原则(源自 Apple Liquid Glass 规范):
7
+ * - saturate(180%) 始终与 blur 成对出现在 backdrop-filter 中
8
+ * - 表面不透明度高于传统玻璃拟态(Apple Beta 3+)
9
+ * - 暗色模式显著更不透明以保证可读性
10
+ * - 顶边框亮度高于侧边(光折射边缘)
11
+ * - 玻璃上文字对比度 4.5:1(WCAG AA)
12
+ */
13
+
14
+ :root {
15
+ /* ── 语义色 ─────────────────────────────── */
16
+ --color-background: oklch(0.985 0.002 240);
17
+ --color-foreground: oklch(0.23 0.01 248);
18
+ --color-surface: oklch(0.997 0.002 245);
19
+ --color-border: oklch(0.89 0.01 246);
20
+ --color-accent: oklch(0.2 0.005 250);
21
+ --color-accent-foreground: oklch(0.98 0.003 250);
22
+
23
+ /* ── 玻璃原语 ────────────────────────────── */
24
+ --glass-blur-sm: 8px;
25
+ --glass-blur-md: 16px;
26
+ --glass-blur-lg: 24px;
27
+ --glass-blur-xl: 40px;
28
+
29
+ --glass-adapt-surface-multiplier: 1;
30
+ --glass-adapt-border-multiplier: 1;
31
+ --glass-adapt-refraction-multiplier: 1;
32
+ --glass-adapt-saturate-multiplier: 1;
33
+
34
+ --glass-base-rgb: 255 255 255;
35
+ --glass-saturate-base: 180%;
36
+ --glass-saturate-subtle-base: 130%;
37
+ --glass-saturate: calc(var(--glass-saturate-base) * var(--glass-adapt-saturate-multiplier));
38
+ --glass-saturate-subtle: calc(
39
+ var(--glass-saturate-subtle-base) * var(--glass-adapt-saturate-multiplier)
40
+ );
41
+
42
+ --glass-border-alpha: 0.2;
43
+ --glass-border-strong-alpha: 0.35;
44
+ --glass-refraction-top-alpha: 0.4;
45
+ --glass-surface: rgb(var(--glass-base-rgb) / calc(0.18 * var(--glass-adapt-surface-multiplier)));
46
+ --glass-border: rgb(
47
+ 255 255 255 / calc(var(--glass-border-alpha) * var(--glass-adapt-border-multiplier))
48
+ );
49
+ --glass-border-strong: rgb(
50
+ 255 255 255 / calc(var(--glass-border-strong-alpha) * var(--glass-adapt-border-multiplier))
51
+ );
52
+ --glass-refraction-top: rgb(
53
+ 255 255 255 / calc(var(--glass-refraction-top-alpha) * var(--glass-adapt-refraction-multiplier))
54
+ );
55
+
56
+ /* ── 玻璃不透明度刻度(水晶 → 磨砂)───────── */
57
+ --glass-opacity-1: 0.06;
58
+ --glass-opacity-2: 0.08;
59
+ --glass-opacity-3: 0.1;
60
+ --glass-opacity-4: 0.12;
61
+ --glass-opacity-5: 0.16;
62
+ --glass-opacity-6: 0.18;
63
+ --glass-opacity-7: 0.22;
64
+ --glass-opacity-8: 0.25;
65
+ --glass-opacity-9: 0.3;
66
+ --glass-opacity-10: 0.35;
67
+
68
+ /* ── 玻璃性能提示 ─────────────────────────── */
69
+ --glass-gpu-transform: translateZ(0);
70
+ --glass-gpu-backface-visibility: hidden;
71
+ --glass-gpu-will-change: transform, opacity;
72
+ --glass-heavy-will-change: backdrop-filter, transform, opacity;
73
+ --glass-heavy-contain: paint;
74
+
75
+ /* ── 玻璃层级(blur + surface + shadow)──── */
76
+ --glass-1-blur: 8px;
77
+ --glass-1-opacity: var(--glass-opacity-2);
78
+ --glass-1-surface: rgb(
79
+ var(--glass-base-rgb) / calc(var(--glass-1-opacity) * var(--glass-adapt-surface-multiplier))
80
+ );
81
+ --glass-1-shadow: var(--shadow-glass-sm);
82
+
83
+ --glass-2-blur: 12px;
84
+ --glass-2-opacity: var(--glass-opacity-4);
85
+ --glass-2-surface: rgb(
86
+ var(--glass-base-rgb) / calc(var(--glass-2-opacity) * var(--glass-adapt-surface-multiplier))
87
+ );
88
+ --glass-2-shadow: var(--shadow-glass-sm);
89
+
90
+ --glass-3-blur: 16px;
91
+ --glass-3-opacity: var(--glass-opacity-6);
92
+ --glass-3-surface: rgb(
93
+ var(--glass-base-rgb) / calc(var(--glass-3-opacity) * var(--glass-adapt-surface-multiplier))
94
+ );
95
+ --glass-3-shadow: var(--shadow-glass-md);
96
+
97
+ --glass-4-blur: 24px;
98
+ --glass-4-opacity: var(--glass-opacity-8);
99
+ --glass-4-surface: rgb(
100
+ var(--glass-base-rgb) / calc(var(--glass-4-opacity) * var(--glass-adapt-surface-multiplier))
101
+ );
102
+ --glass-4-shadow: var(--shadow-glass-lg);
103
+
104
+ --glass-5-blur: 40px;
105
+ --glass-5-opacity: var(--glass-opacity-10);
106
+ --glass-5-surface: rgb(
107
+ var(--glass-base-rgb) / calc(var(--glass-5-opacity) * var(--glass-adapt-surface-multiplier))
108
+ );
109
+ --glass-5-shadow: var(--shadow-glass-lg);
110
+
111
+ /* ── 圆角 ──────────────────────────────── */
112
+ --radius-sm: 0.5rem;
113
+ --radius-md: 0.75rem;
114
+ --radius-lg: 1rem;
115
+ --radius-xl: 1.25rem;
116
+ --radius-2xl: 1.75rem;
117
+
118
+ /* ── 间距 ───────────────────────────────── */
119
+ --space-xs: 0.25rem;
120
+ --space-sm: 0.5rem;
121
+ --space-md: 0.75rem;
122
+ --space-lg: 1rem;
123
+ --space-xl: 1.5rem;
124
+ --space-2xl: 2rem;
125
+
126
+ /* ── 阴影 ───────────────────────────────── */
127
+ --shadow-glass-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
128
+ --shadow-glass-md: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);
129
+ --shadow-glass-lg: 0 16px 48px rgba(0, 0, 0, 0.16), 0 4px 8px rgba(0, 0, 0, 0.08);
130
+ --shadow-glass-inset: inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.05);
131
+
132
+ /* ── 动效 ───────────────────────────────── */
133
+ --motion-fast: 150ms;
134
+ --motion-normal: 250ms;
135
+ --motion-slow: 400ms;
136
+ --motion-spring: 500ms;
137
+ --easing-standard: cubic-bezier(0.2, 0, 0, 1);
138
+ --easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
139
+ --easing-glass: cubic-bezier(0.4, 0, 0.2, 1);
140
+
141
+ color-scheme: light;
142
+ }
143
+
144
+ .dark {
145
+ --color-background: oklch(0.18 0.01 250);
146
+ --color-foreground: oklch(0.95 0.01 247);
147
+ --color-surface: oklch(0.23 0.01 250);
148
+ --color-border: oklch(0.34 0.01 250);
149
+ --color-accent: oklch(0.92 0.005 250);
150
+ --color-accent-foreground: oklch(0.15 0.005 250);
151
+
152
+ --glass-base-rgb: 0 0 0;
153
+ --glass-border-alpha: 0.1;
154
+ --glass-border-strong-alpha: 0.18;
155
+ --glass-refraction-top-alpha: 0.15;
156
+ --glass-surface: rgb(var(--glass-base-rgb) / calc(0.4 * var(--glass-adapt-surface-multiplier)));
157
+
158
+ --glass-opacity-1: 0.16;
159
+ --glass-opacity-2: 0.2;
160
+ --glass-opacity-3: 0.25;
161
+ --glass-opacity-4: 0.3;
162
+ --glass-opacity-5: 0.35;
163
+ --glass-opacity-6: 0.4;
164
+ --glass-opacity-7: 0.48;
165
+ --glass-opacity-8: 0.55;
166
+ --glass-opacity-9: 0.62;
167
+ --glass-opacity-10: 0.7;
168
+
169
+ --glass-1-opacity: var(--glass-opacity-2);
170
+ --glass-1-surface: rgb(
171
+ var(--glass-base-rgb) / calc(var(--glass-1-opacity) * var(--glass-adapt-surface-multiplier))
172
+ );
173
+
174
+ --glass-2-opacity: var(--glass-opacity-4);
175
+ --glass-2-surface: rgb(
176
+ var(--glass-base-rgb) / calc(var(--glass-2-opacity) * var(--glass-adapt-surface-multiplier))
177
+ );
178
+
179
+ --glass-3-opacity: var(--glass-opacity-6);
180
+ --glass-3-surface: rgb(
181
+ var(--glass-base-rgb) / calc(var(--glass-3-opacity) * var(--glass-adapt-surface-multiplier))
182
+ );
183
+
184
+ --glass-4-opacity: var(--glass-opacity-8);
185
+ --glass-4-surface: rgb(
186
+ var(--glass-base-rgb) / calc(var(--glass-4-opacity) * var(--glass-adapt-surface-multiplier))
187
+ );
188
+
189
+ --glass-5-opacity: var(--glass-opacity-10);
190
+ --glass-5-surface: rgb(
191
+ var(--glass-base-rgb) / calc(var(--glass-5-opacity) * var(--glass-adapt-surface-multiplier))
192
+ );
193
+
194
+ color-scheme: dark;
195
+ }
196
+
197
+ /* ── 玻璃工具类 ────────────────────────────── */
198
+ .glass-surface,
199
+ .glass-1,
200
+ .glass-2,
201
+ .glass-3,
202
+ .glass-4,
203
+ .glass-5 {
204
+ border: 1px solid var(--glass-border);
205
+ border-top-color: var(--glass-refraction-top);
206
+ background-clip: padding-box;
207
+ }
208
+
209
+ .glass-surface,
210
+ .glass-3 {
211
+ background: var(--glass-3-surface);
212
+ backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-3-blur));
213
+ -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-3-blur));
214
+ box-shadow: var(--glass-3-shadow);
215
+ }
216
+
217
+ .glass-1 {
218
+ background: var(--glass-1-surface);
219
+ backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-1-blur));
220
+ -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-1-blur));
221
+ box-shadow: var(--glass-1-shadow);
222
+ }
223
+
224
+ .glass-2 {
225
+ background: var(--glass-2-surface);
226
+ backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-2-blur));
227
+ -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-2-blur));
228
+ box-shadow: var(--glass-2-shadow);
229
+ }
230
+
231
+ .glass-4 {
232
+ background: var(--glass-4-surface);
233
+ backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-4-blur));
234
+ -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-4-blur));
235
+ box-shadow: var(--glass-4-shadow);
236
+ }
237
+
238
+ .glass-5 {
239
+ background: var(--glass-5-surface);
240
+ backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-5-blur));
241
+ -webkit-backdrop-filter: saturate(var(--glass-saturate)) blur(var(--glass-5-blur));
242
+ box-shadow: var(--glass-5-shadow);
243
+ }
244
+
245
+ .glass-gpu-hint {
246
+ transform: var(--glass-gpu-transform);
247
+ backface-visibility: var(--glass-gpu-backface-visibility);
248
+ will-change: var(--glass-gpu-will-change);
249
+ }
250
+
251
+ .glass-heavy {
252
+ transform: var(--glass-gpu-transform);
253
+ backface-visibility: var(--glass-gpu-backface-visibility);
254
+ will-change: var(--glass-heavy-will-change);
255
+ contain: var(--glass-heavy-contain);
256
+ }
257
+
258
+ /* ── 背景亮度适配 ──────────────────────────── */
259
+ .glass-adapt-neutral,
260
+ [data-glass-luminance='neutral'] {
261
+ --glass-adapt-surface-multiplier: 1;
262
+ --glass-adapt-border-multiplier: 1;
263
+ --glass-adapt-refraction-multiplier: 1;
264
+ --glass-adapt-saturate-multiplier: 1;
265
+ }
266
+
267
+ .glass-adapt-bright,
268
+ [data-glass-luminance='bright'] {
269
+ --glass-adapt-surface-multiplier: 1.16;
270
+ --glass-adapt-border-multiplier: 1.08;
271
+ --glass-adapt-refraction-multiplier: 1.14;
272
+ --glass-adapt-saturate-multiplier: 1.04;
273
+ }
274
+
275
+ .glass-adapt-dim,
276
+ [data-glass-luminance='dim'] {
277
+ --glass-adapt-surface-multiplier: 0.9;
278
+ --glass-adapt-border-multiplier: 1.15;
279
+ --glass-adapt-refraction-multiplier: 1.22;
280
+ --glass-adapt-saturate-multiplier: 0.96;
281
+ }
282
+
283
+ /* ── 降低透明度偏好 ────────────────────────── */
284
+ @media (prefers-reduced-transparency: reduce) {
285
+ :root {
286
+ --glass-1-surface: rgba(255, 255, 255, 0.92);
287
+ --glass-2-surface: rgba(255, 255, 255, 0.94);
288
+ --glass-3-surface: rgba(255, 255, 255, 0.95);
289
+ --glass-4-surface: rgba(255, 255, 255, 0.96);
290
+ --glass-5-surface: rgba(255, 255, 255, 0.98);
291
+ }
292
+
293
+ .dark {
294
+ --glass-1-surface: rgba(0, 0, 0, 0.88);
295
+ --glass-2-surface: rgba(0, 0, 0, 0.9);
296
+ --glass-3-surface: rgba(0, 0, 0, 0.92);
297
+ --glass-4-surface: rgba(0, 0, 0, 0.94);
298
+ --glass-5-surface: rgba(0, 0, 0, 0.96);
299
+ }
300
+
301
+ .glass-surface,
302
+ .glass-1,
303
+ .glass-2,
304
+ .glass-3,
305
+ .glass-4,
306
+ .glass-5 {
307
+ backdrop-filter: none;
308
+ -webkit-backdrop-filter: none;
309
+ }
310
+ }
311
+
312
+ /* ── Keyframes ─────────────────────────────── */
313
+
314
+ @keyframes accordion-down {
315
+ from {
316
+ height: 0;
317
+ }
318
+
319
+ to {
320
+ height: var(--radix-accordion-content-height);
321
+ }
322
+ }
323
+
324
+ @keyframes accordion-up {
325
+ from {
326
+ height: var(--radix-accordion-content-height);
327
+ }
328
+
329
+ to {
330
+ height: 0;
331
+ }
332
+ }
333
+
334
+ @keyframes skeleton-shimmer {
335
+ 0% {
336
+ transform: translateX(-100%);
337
+ }
338
+
339
+ 100% {
340
+ transform: translateX(100%);
341
+ }
342
+ }
343
+
344
+ @keyframes border-beam {
345
+ 0% {
346
+ offset-distance: 0%;
347
+ }
348
+
349
+ 100% {
350
+ offset-distance: 100%;
351
+ }
352
+ }
353
+
354
+ @keyframes marquee-x {
355
+ 0% {
356
+ transform: translateX(0);
357
+ }
358
+
359
+ 100% {
360
+ transform: translateX(calc(-100% - var(--marquee-gap)));
361
+ }
362
+ }
363
+
364
+ @keyframes marquee-y {
365
+ 0% {
366
+ transform: translateY(0);
367
+ }
368
+
369
+ 100% {
370
+ transform: translateY(calc(-100% - var(--marquee-gap)));
371
+ }
372
+ }
373
+
374
+ @keyframes ripple-expand {
375
+ 0% {
376
+ transform: scale(0.8);
377
+ opacity: 1;
378
+ }
379
+
380
+ 100% {
381
+ transform: scale(1);
382
+ opacity: 0;
383
+ }
384
+ }
385
+
386
+ @keyframes meteor-fall {
387
+ 0% {
388
+ transform: rotate(var(--meteor-angle, 215deg)) translateX(0);
389
+ opacity: 1;
390
+ }
391
+
392
+ 70% {
393
+ opacity: 1;
394
+ }
395
+
396
+ 100% {
397
+ transform: rotate(var(--meteor-angle, 215deg)) translateX(600px);
398
+ opacity: 0;
399
+ }
400
+ }
401
+
402
+ @keyframes gradient-shift {
403
+ 0% {
404
+ background-position: 0% 50%;
405
+ }
406
+
407
+ 50% {
408
+ background-position: 100% 50%;
409
+ }
410
+
411
+ 100% {
412
+ background-position: 0% 50%;
413
+ }
414
+ }
415
+
416
+ @keyframes pulsate-ring {
417
+ 0% {
418
+ transform: scale(1);
419
+ opacity: 0.8;
420
+ }
421
+
422
+ 100% {
423
+ transform: scale(1.5);
424
+ opacity: 0;
425
+ }
426
+ }
427
+
428
+ @keyframes retro-grid-scroll {
429
+ 0% {
430
+ background-position: 0 0;
431
+ }
432
+
433
+ 100% {
434
+ background-position: 0 var(--retro-grid-cell, 60px);
435
+ }
436
+ }
437
+
438
+ @keyframes orbit {
439
+ 0% {
440
+ transform: rotate(calc(var(--orbit-start, 0) * 1deg))
441
+ translateY(calc(var(--orbit-radius, 100) * -1px)) rotate(calc(var(--orbit-start, 0) * -1deg));
442
+ }
443
+
444
+ 100% {
445
+ transform: rotate(calc(var(--orbit-start, 0) * 1deg + 360deg))
446
+ translateY(calc(var(--orbit-radius, 100) * -1px))
447
+ rotate(calc(var(--orbit-start, 0) * -1deg - 360deg));
448
+ }
449
+ }
450
+
451
+ @keyframes glow-rotate {
452
+ 0% {
453
+ transform: rotate(0deg);
454
+ }
455
+
456
+ 100% {
457
+ transform: rotate(360deg);
458
+ }
459
+ }
460
+
461
+ @keyframes word-rotate-in {
462
+ 0% {
463
+ transform: translateY(100%);
464
+ opacity: 0;
465
+ }
466
+
467
+ 100% {
468
+ transform: translateY(0);
469
+ opacity: 1;
470
+ }
471
+ }
472
+
473
+ @keyframes word-rotate-out {
474
+ 0% {
475
+ transform: translateY(0);
476
+ opacity: 1;
477
+ }
478
+
479
+ 100% {
480
+ transform: translateY(-100%);
481
+ opacity: 0;
482
+ }
483
+ }
484
+
485
+ @keyframes blink {
486
+ 0%,
487
+ 100% {
488
+ opacity: 1;
489
+ }
490
+
491
+ 50% {
492
+ opacity: 0;
493
+ }
494
+ }
495
+
496
+ @keyframes aurora-shift {
497
+ 0% {
498
+ transform: translate(0, 0) rotate(0deg) scale(1);
499
+ }
500
+
501
+ 33% {
502
+ transform: translate(30px, -50px) rotate(120deg) scale(1.1);
503
+ }
504
+
505
+ 66% {
506
+ transform: translate(-20px, 20px) rotate(240deg) scale(0.9);
507
+ }
508
+
509
+ 100% {
510
+ transform: translate(0, 0) rotate(360deg) scale(1);
511
+ }
512
+ }
513
+
514
+ @keyframes particle-float {
515
+ 0% {
516
+ transform: translateY(0) translateX(0);
517
+ opacity: 0;
518
+ }
519
+
520
+ 10% {
521
+ opacity: 1;
522
+ }
523
+
524
+ 90% {
525
+ opacity: 1;
526
+ }
527
+
528
+ 100% {
529
+ transform: translateY(var(--particle-distance, -200px)) translateX(var(--particle-drift, 20px));
530
+ opacity: 0;
531
+ }
532
+ }
533
+
534
+ @keyframes prism-rotate {
535
+ 0% {
536
+ background-position: 0% 50%;
537
+ }
538
+
539
+ 50% {
540
+ background-position: 100% 50%;
541
+ }
542
+
543
+ 100% {
544
+ background-position: 0% 50%;
545
+ }
546
+ }
547
+
548
+ @keyframes chromatic-shift {
549
+ 0% {
550
+ transform: translate(0, 0);
551
+ }
552
+
553
+ 25% {
554
+ transform: translate(var(--chromatic-offset, 2px), calc(var(--chromatic-offset, 2px) * -1));
555
+ }
556
+
557
+ 50% {
558
+ transform: translate(0, var(--chromatic-offset, 2px));
559
+ }
560
+
561
+ 75% {
562
+ transform: translate(calc(var(--chromatic-offset, 2px) * -1), 0);
563
+ }
564
+
565
+ 100% {
566
+ transform: translate(0, 0);
567
+ }
568
+ }
569
+
570
+ @keyframes morphing-indicator {
571
+ 0% {
572
+ transform: scaleX(0.8);
573
+ opacity: 0.6;
574
+ }
575
+
576
+ 100% {
577
+ transform: scaleX(1);
578
+ opacity: 1;
579
+ }
580
+ }
581
+
582
+ @keyframes dock-bounce {
583
+ 0% {
584
+ transform: translateY(0);
585
+ }
586
+
587
+ 50% {
588
+ transform: translateY(-6px);
589
+ }
590
+
591
+ 100% {
592
+ transform: translateY(0);
593
+ }
594
+ }
595
+
596
+ @keyframes mesh-shift {
597
+ 0% {
598
+ background-position: 0% 0%;
599
+ }
600
+
601
+ 25% {
602
+ background-position: 100% 0%;
603
+ }
604
+
605
+ 50% {
606
+ background-position: 100% 100%;
607
+ }
608
+
609
+ 75% {
610
+ background-position: 0% 100%;
611
+ }
612
+
613
+ 100% {
614
+ background-position: 0% 0%;
615
+ }
616
+ }
617
+
618
+ @keyframes ripple-press {
619
+ 0% {
620
+ transform: translate(-50%, -50%) scale(0);
621
+ opacity: 0.5;
622
+ }
623
+
624
+ 100% {
625
+ transform: translate(-50%, -50%) scale(4);
626
+ opacity: 0;
627
+ }
628
+ }
629
+
630
+ @keyframes liquid-fill {
631
+ 0% {
632
+ transform: translateX(-100%);
633
+ }
634
+
635
+ 100% {
636
+ transform: translateX(0);
637
+ }
638
+ }
639
+
640
+ @keyframes light-leak-drift {
641
+ 0% {
642
+ transform: translate(-30%, -30%) rotate(0deg);
643
+ opacity: 0;
644
+ }
645
+
646
+ 20% {
647
+ opacity: 1;
648
+ }
649
+
650
+ 80% {
651
+ opacity: 1;
652
+ }
653
+
654
+ 100% {
655
+ transform: translate(30%, 30%) rotate(45deg);
656
+ opacity: 0;
657
+ }
658
+ }
659
+
660
+ @keyframes reveal-wipe {
661
+ 0% {
662
+ clip-path: inset(0 100% 0 0);
663
+ }
664
+
665
+ 100% {
666
+ clip-path: inset(0 0 0 0);
667
+ }
668
+ }
669
+
670
+ @keyframes spotlight-pulse {
671
+ 0% {
672
+ opacity: 0.6;
673
+ transform: scale(1);
674
+ }
675
+
676
+ 50% {
677
+ opacity: 0.8;
678
+ transform: scale(1.05);
679
+ }
680
+
681
+ 100% {
682
+ opacity: 0.6;
683
+ transform: scale(1);
684
+ }
685
+ }
686
+
687
+ /* ── 动画工具类(组件与特效复用)──────────── */
688
+ .anim-accordion-down {
689
+ animation: accordion-down 200ms ease-out;
690
+ }
691
+
692
+ .anim-accordion-up {
693
+ animation: accordion-up 200ms ease-out;
694
+ }
695
+
696
+ .anim-border-beam {
697
+ animation: border-beam var(--border-beam-duration, 6s) linear infinite;
698
+ }
699
+
700
+ .anim-marquee-x {
701
+ animation: marquee-x var(--marquee-duration, 30s) linear infinite;
702
+ }
703
+
704
+ .anim-marquee-y {
705
+ animation: marquee-y var(--marquee-duration, 30s) linear infinite;
706
+ }
707
+
708
+ .anim-ripple-expand {
709
+ animation: ripple-expand var(--ripple-duration, 2s) ease-out infinite;
710
+ }
711
+
712
+ .anim-meteor-fall {
713
+ animation: meteor-fall var(--meteor-duration, 3s) linear infinite;
714
+ }
715
+
716
+ .anim-gradient-shift {
717
+ animation: gradient-shift var(--gradient-duration, 6s) ease infinite;
718
+ }
719
+
720
+ .anim-pulsate-ring {
721
+ animation: pulsate-ring var(--pulsate-duration, 2s) ease-out infinite;
722
+ }
723
+
724
+ .anim-retro-grid-scroll {
725
+ animation: retro-grid-scroll var(--retro-grid-duration, 10s) linear infinite;
726
+ }
727
+
728
+ .anim-orbit {
729
+ animation: orbit var(--orbit-duration, 20s) linear infinite;
730
+ }
731
+
732
+ .anim-glow-rotate {
733
+ animation: glow-rotate var(--glow-duration, 4s) linear infinite;
734
+ }
735
+
736
+ .anim-word-rotate-in {
737
+ animation: word-rotate-in var(--word-rotate-duration, 0.3s) ease-out forwards;
738
+ }
739
+
740
+ .anim-word-rotate-out {
741
+ animation: word-rotate-out var(--word-rotate-duration, 0.3s) ease-out forwards;
742
+ }
743
+
744
+ .anim-blink {
745
+ animation: blink 1s step-end infinite;
746
+ }
747
+
748
+ .anim-aurora-shift {
749
+ animation: aurora-shift var(--aurora-duration, 8s) ease-in-out infinite;
750
+ }
751
+
752
+ .anim-particle-float {
753
+ animation: particle-float var(--particle-duration, 5s) ease-out infinite;
754
+ }
755
+
756
+ .anim-prism-rotate {
757
+ animation: prism-rotate var(--prism-duration, 3s) linear infinite;
758
+ }
759
+
760
+ .anim-chromatic-shift {
761
+ animation: chromatic-shift var(--chromatic-duration, 4s) ease-in-out infinite;
762
+ }
763
+
764
+ .anim-morphing-indicator {
765
+ animation: morphing-indicator 0.2s ease-out;
766
+ }
767
+
768
+ .anim-dock-bounce {
769
+ animation: dock-bounce 0.4s ease-out;
770
+ }
771
+
772
+ .anim-mesh-shift {
773
+ animation: mesh-shift var(--mesh-duration, 10s) ease-in-out infinite;
774
+ }
775
+
776
+ .anim-ripple-press {
777
+ animation: ripple-press 0.6s ease-out forwards;
778
+ }
779
+
780
+ .anim-liquid-fill {
781
+ animation: liquid-fill 0.3s ease-out forwards;
782
+ }
783
+
784
+ .anim-light-leak-drift {
785
+ animation: light-leak-drift var(--light-leak-duration, 6s) ease-in-out infinite;
786
+ }
787
+
788
+ .anim-reveal-wipe {
789
+ animation: reveal-wipe var(--reveal-duration, 0.8s) ease-out forwards;
790
+ }
791
+
792
+ .anim-skeleton-shimmer {
793
+ animation: skeleton-shimmer 2s ease-in-out infinite;
794
+ }
795
+
796
+ .anim-spotlight-pulse {
797
+ animation: spotlight-pulse var(--spotlight-pulse-duration, 3s) ease-in-out infinite;
798
+ }
799
+
800
+ /* ── 降低动效偏好 ──────────────────────────── */
801
+ @media (prefers-reduced-motion: reduce) {
802
+ :root {
803
+ --motion-fast: 1ms;
804
+ --motion-normal: 1ms;
805
+ --motion-slow: 1ms;
806
+ --motion-spring: 1ms;
807
+ }
808
+ }
809
+
810
+ /* ── 对话框系 keyframes(modal/sheet/alert-dialog/command 共用)── */
811
+
812
+ @keyframes dialog-overlay-in {
813
+ from {
814
+ opacity: 0;
815
+ }
816
+
817
+ to {
818
+ opacity: 1;
819
+ }
820
+ }
821
+
822
+ @keyframes dialog-overlay-out {
823
+ from {
824
+ opacity: 1;
825
+ }
826
+
827
+ to {
828
+ opacity: 0;
829
+ }
830
+ }
831
+
832
+ @keyframes dialog-content-in {
833
+ from {
834
+ opacity: 0;
835
+ transform: translate(-50%, calc(-50% + 12px)) scale(0.95);
836
+ }
837
+
838
+ to {
839
+ opacity: 1;
840
+ transform: translate(-50%, -50%) scale(1);
841
+ }
842
+ }
843
+
844
+ @keyframes dialog-content-out {
845
+ from {
846
+ opacity: 1;
847
+ transform: translate(-50%, -50%) scale(1);
848
+ }
849
+
850
+ to {
851
+ opacity: 0;
852
+ transform: translate(-50%, calc(-50% + 8px)) scale(0.98);
853
+ }
854
+ }
855
+
856
+ @keyframes dialog-pop-in {
857
+ from {
858
+ opacity: 0;
859
+ transform: scale(0.95);
860
+ }
861
+
862
+ to {
863
+ opacity: 1;
864
+ transform: scale(1);
865
+ }
866
+ }
867
+
868
+ @keyframes dialog-pop-out {
869
+ from {
870
+ opacity: 1;
871
+ transform: scale(1);
872
+ }
873
+
874
+ to {
875
+ opacity: 0;
876
+ transform: scale(0.98);
877
+ }
878
+ }
879
+
880
+ @keyframes dialog-slide-in-top {
881
+ from {
882
+ transform: translateY(-100%);
883
+ }
884
+
885
+ to {
886
+ transform: translateY(0);
887
+ }
888
+ }
889
+
890
+ @keyframes dialog-slide-out-top {
891
+ from {
892
+ transform: translateY(0);
893
+ }
894
+
895
+ to {
896
+ transform: translateY(-100%);
897
+ }
898
+ }
899
+
900
+ @keyframes dialog-slide-in-right {
901
+ from {
902
+ transform: translateX(100%);
903
+ }
904
+
905
+ to {
906
+ transform: translateX(0);
907
+ }
908
+ }
909
+
910
+ @keyframes dialog-slide-out-right {
911
+ from {
912
+ transform: translateX(0);
913
+ }
914
+
915
+ to {
916
+ transform: translateX(100%);
917
+ }
918
+ }
919
+
920
+ @keyframes dialog-slide-in-bottom {
921
+ from {
922
+ transform: translateY(100%);
923
+ }
924
+
925
+ to {
926
+ transform: translateY(0);
927
+ }
928
+ }
929
+
930
+ @keyframes dialog-slide-out-bottom {
931
+ from {
932
+ transform: translateY(0);
933
+ }
934
+
935
+ to {
936
+ transform: translateY(100%);
937
+ }
938
+ }
939
+
940
+ @keyframes dialog-slide-in-left {
941
+ from {
942
+ transform: translateX(-100%);
943
+ }
944
+
945
+ to {
946
+ transform: translateX(0);
947
+ }
948
+ }
949
+
950
+ @keyframes dialog-slide-out-left {
951
+ from {
952
+ transform: translateX(0);
953
+ }
954
+
955
+ to {
956
+ transform: translateX(-100%);
957
+ }
958
+ }
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@longzai-intelligence-liquid-glass/tokens",
3
+ "version": "0.0.1",
4
+ "description": "Liquid Glass 设计令牌:玻璃海拔分级、光学色彩与动效令牌(纯 CSS,衍生自 glinui,MIT)",
5
+ "license": "UNLICENSED",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./styles.css": "./dist/styles.css"
18
+ },
19
+ "scripts": {
20
+ "build": "lzi-builder",
21
+ "build:prod": "NODE_ENV=production bun run build",
22
+ "prepublishOnly": "bun run build:prod",
23
+ "typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
24
+ "typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
25
+ "typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
26
+ "typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
27
+ "lint": "oxlint && oxfmt --check",
28
+ "lint:fix": "oxlint --fix && oxfmt",
29
+ "test": "lzi-bun-cli test",
30
+ "test:watch": "lzi-bun-cli test --watch",
31
+ "test:coverage": "lzi-bun-cli test --coverage",
32
+ "clean": "lzi-dev-cli clean"
33
+ },
34
+ "dependencies": {},
35
+ "packageManager": "bun@1.3.14"
36
+ }