@cyberpunk-vue/theme-chalk 1.14.0 → 1.14.2

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 (47) hide show
  1. package/dist/index.css +1 -1
  2. package/dist/index.css.map +1 -1
  3. package/package.json +1 -1
  4. package/src/common/var.scss +247 -247
  5. package/src/components/avatar-group.scss +113 -113
  6. package/src/components/avatar.scss +123 -123
  7. package/src/components/badge.scss +210 -210
  8. package/src/components/breadcrumb.scss +203 -203
  9. package/src/components/button.scss +975 -975
  10. package/src/components/card.scss +699 -696
  11. package/src/components/checkbox-group.scss +22 -22
  12. package/src/components/checkbox.scss +320 -320
  13. package/src/components/col.scss +43 -43
  14. package/src/components/dialog.scss +360 -360
  15. package/src/components/divider.scss +250 -250
  16. package/src/components/empty.scss +99 -99
  17. package/src/components/form-item.scss +189 -189
  18. package/src/components/form.scss +59 -59
  19. package/src/components/icon.scss +83 -83
  20. package/src/components/image-preview.scss +147 -147
  21. package/src/components/image.scss +351 -351
  22. package/src/components/input-number.scss +129 -129
  23. package/src/components/input.scss +362 -362
  24. package/src/components/loading.scss +64 -64
  25. package/src/components/notification.scss +348 -348
  26. package/src/components/pagination.scss +287 -280
  27. package/src/components/pattern-background.scss +18 -18
  28. package/src/components/popover.scss +438 -438
  29. package/src/components/progress.scss +438 -438
  30. package/src/components/radio-group.scss +22 -22
  31. package/src/components/radio.scss +286 -286
  32. package/src/components/row.scss +12 -12
  33. package/src/components/scrollbar.scss +40 -40
  34. package/src/components/segmented.scss +566 -566
  35. package/src/components/select.scss +15 -1
  36. package/src/components/slider.scss +421 -421
  37. package/src/components/status-indicator.scss +206 -206
  38. package/src/components/switch.scss +405 -405
  39. package/src/components/table.scss +474 -474
  40. package/src/components/tag.scss +416 -416
  41. package/src/components/text.scss +310 -271
  42. package/src/components/textarea.scss +106 -104
  43. package/src/components/timeline.scss +379 -379
  44. package/src/components/tree.scss +397 -397
  45. package/src/components/upload.scss +509 -509
  46. package/src/index.scss +60 -60
  47. package/src/mixins/mixins.scss +156 -156
@@ -1,975 +1,975 @@
1
- // CpButton 组件样式
2
- // 赛博朋克/机甲风格
3
-
4
- @use '../common/var' as *;
5
- @use '../mixins/mixins' as *;
6
-
7
- @include b(button) {
8
- // 基础样式
9
- position: relative;
10
- display: inline-flex;
11
- align-items: center;
12
- justify-content: center;
13
- // 注意:不使用 gap,因为 loader 需要动画 margin 来实现平滑过渡
14
- padding: 0 var(--cp-spacing-lg);
15
-
16
- font-family: var(--cp-font-family-display);
17
- font-weight: 600;
18
- text-transform: uppercase;
19
- letter-spacing: 0.05em;
20
- cursor: pointer;
21
- border: 1px solid transparent;
22
- outline: none;
23
- background: transparent;
24
- color: var(--cp-text-primary);
25
- z-index: 1;
26
- transition: all 0.2s ease;
27
- user-select: none;
28
-
29
- --cp-button-clip-size: 10px;
30
-
31
- // 机甲风切角 (Top-Left, Bottom-Right)
32
- clip-path: polygon(var(--cp-button-clip-size) 0,
33
- 100% 0,
34
- 100% calc(100% - var(--cp-button-clip-size)),
35
- calc(100% - var(--cp-button-clip-size)) 100%,
36
- 0 100%,
37
- 0 var(--cp-button-clip-size));
38
-
39
- // 装饰性小方块 (右上角)
40
- &::after {
41
- content: '';
42
- position: absolute;
43
- top: 0;
44
- right: 0;
45
- width: 8px;
46
- height: 8px;
47
- background: currentColor;
48
- opacity: 0.5;
49
- z-index: 2;
50
- transition: all 0.2s ease;
51
- }
52
-
53
- // 小尺寸下缩小装饰性小方块,防止遮挡内容
54
- @include when(small-size) {
55
- &::after {
56
- width: 4px;
57
- height: 4px;
58
- }
59
- }
60
-
61
- // 隐藏装饰性小方块
62
- @include when(no-decoration) {
63
- &::after {
64
- display: none;
65
- }
66
- }
67
-
68
- // 点击动画
69
- &:active:not(.is-disabled) {
70
- transform: scale(0.96);
71
- transition: transform 0.1s ease;
72
- }
73
-
74
- // ===== 尺寸 =====
75
- @include m(sm) {
76
- height: var(--cp-button-height-sm);
77
- font-size: var(--cp-font-size-sm);
78
- padding: 0 var(--cp-spacing-md);
79
- --cp-button-clip-size: 8px;
80
- }
81
-
82
- @include m(md) {
83
- height: var(--cp-button-height-md);
84
- font-size: var(--cp-font-size-md);
85
- }
86
-
87
- @include m(lg) {
88
- height: var(--cp-button-height-lg);
89
- font-size: var(--cp-font-size-lg);
90
- padding: 0 var(--cp-spacing-xl);
91
- }
92
-
93
- // 自定义尺寸
94
- @include when(custom-size) {
95
- height: var(--cp-button-height);
96
- }
97
-
98
- // ===== Solid 变体 =====
99
- @include m(solid) {
100
- &.cp-button--primary {
101
- background: var(--cp-color-primary);
102
- border-color: var(--cp-color-primary);
103
- color: var(--cp-color-primary-text);
104
-
105
- &::after {
106
- background: rgba(0, 0, 0, 0.3);
107
- }
108
-
109
- &:hover:not(.is-disabled) {
110
- filter: brightness(1.2);
111
- box-shadow: 0 0 20px var(--cp-color-primary-light), 0 0 40px var(--cp-color-primary-light);
112
-
113
- &::after {
114
- opacity: 0.8;
115
- }
116
- }
117
- }
118
-
119
- &.cp-button--success {
120
- background: var(--cp-color-success);
121
- border-color: var(--cp-color-success);
122
- color: var(--cp-color-success-text);
123
-
124
- &::after {
125
- background: rgba(0, 0, 0, 0.3);
126
- }
127
-
128
- &:hover:not(.is-disabled) {
129
- filter: brightness(1.2);
130
- box-shadow: 0 0 20px var(--cp-color-success-light), 0 0 40px var(--cp-color-success-light);
131
-
132
- &::after {
133
- opacity: 0.8;
134
- }
135
- }
136
- }
137
-
138
- &.cp-button--warning {
139
- background: var(--cp-color-warning);
140
- border-color: var(--cp-color-warning);
141
- color: var(--cp-color-warning-text);
142
-
143
- &::after {
144
- background: rgba(0, 0, 0, 0.3);
145
- }
146
-
147
- &:hover:not(.is-disabled) {
148
- filter: brightness(1.2);
149
- box-shadow: 0 0 20px var(--cp-color-warning-light), 0 0 40px var(--cp-color-warning-light);
150
-
151
- &::after {
152
- opacity: 0.8;
153
- }
154
- }
155
- }
156
-
157
- &.cp-button--error {
158
- background: var(--cp-color-error);
159
- border-color: var(--cp-color-error);
160
- color: var(--cp-color-error-text);
161
-
162
- &::after {
163
- background: rgba(0, 0, 0, 0.3);
164
- }
165
-
166
- &:hover:not(.is-disabled) {
167
- filter: brightness(1.2);
168
- box-shadow: 0 0 20px var(--cp-color-error-light), 0 0 40px var(--cp-color-error-light);
169
-
170
- &::after {
171
- opacity: 0.8;
172
- }
173
- }
174
- }
175
-
176
- &.cp-button--info {
177
- background: var(--cp-color-info);
178
- border-color: var(--cp-color-info);
179
- color: var(--cp-color-info-text);
180
-
181
- &::after {
182
- background: rgba(0, 0, 0, 0.3);
183
- }
184
-
185
- &:hover:not(.is-disabled) {
186
- filter: brightness(1.2);
187
- box-shadow: 0 0 20px var(--cp-color-info-light), 0 0 40px var(--cp-color-info-light);
188
-
189
- &::after {
190
- opacity: 0.8;
191
- }
192
- }
193
- }
194
-
195
- &.cp-button--default {
196
- background: var(--cp-bg-elevated);
197
- border-color: var(--cp-border);
198
- color: var(--cp-text-primary);
199
-
200
- &::after {
201
- background: var(--cp-border);
202
- }
203
-
204
- &:hover:not(.is-disabled) {
205
- background: var(--cp-border);
206
- border-color: var(--cp-text-secondary);
207
- }
208
- }
209
- }
210
-
211
- // ===== Outline 变体 =====
212
- @include m(outline) {
213
- &.cp-button--primary {
214
- background: transparent;
215
- border-color: var(--cp-color-primary);
216
- color: var(--cp-color-primary);
217
-
218
- &:hover:not(.is-disabled) {
219
- background: var(--cp-color-primary-light);
220
- box-shadow: 0 0 15px var(--cp-color-primary-light);
221
- }
222
- }
223
-
224
- &.cp-button--success {
225
- background: transparent;
226
- border-color: var(--cp-color-success);
227
- color: var(--cp-color-success);
228
-
229
- &:hover:not(.is-disabled) {
230
- background: var(--cp-color-success-light);
231
- box-shadow: 0 0 15px var(--cp-color-success-light);
232
- }
233
- }
234
-
235
- &.cp-button--warning {
236
- background: transparent;
237
- border-color: var(--cp-color-warning);
238
- color: var(--cp-color-warning);
239
-
240
- &:hover:not(.is-disabled) {
241
- background: var(--cp-color-warning-light);
242
- box-shadow: 0 0 15px var(--cp-color-warning-light);
243
- }
244
- }
245
-
246
- &.cp-button--error {
247
- background: transparent;
248
- border-color: var(--cp-color-error);
249
- color: var(--cp-color-error);
250
-
251
- &:hover:not(.is-disabled) {
252
- background: var(--cp-color-error-light);
253
- box-shadow: 0 0 15px var(--cp-color-error-light);
254
- }
255
- }
256
-
257
- &.cp-button--info {
258
- background: transparent;
259
- border-color: var(--cp-color-info);
260
- color: var(--cp-color-info);
261
-
262
- &:hover:not(.is-disabled) {
263
- background: var(--cp-color-info-light);
264
- box-shadow: 0 0 15px var(--cp-color-info-light);
265
- }
266
- }
267
-
268
- &.cp-button--default {
269
- background: transparent;
270
- border-color: var(--cp-border);
271
- color: var(--cp-text-secondary);
272
-
273
- &:hover:not(.is-disabled) {
274
- background: var(--cp-bg-elevated);
275
- border-color: var(--cp-text-secondary);
276
- }
277
- }
278
- }
279
-
280
- // ===== Semi 变体 (半填充) =====
281
- @include m(semi) {
282
- &.cp-button--primary {
283
- background: var(--cp-color-primary-light);
284
- border-color: var(--cp-color-primary);
285
- color: var(--cp-color-primary);
286
-
287
- &::after {
288
- background: var(--cp-color-primary);
289
- opacity: 0.8;
290
- }
291
-
292
- &:hover:not(.is-disabled) {
293
- filter: brightness(1.3);
294
- box-shadow: 0 0 20px var(--cp-color-primary-light);
295
- text-shadow: 0 0 8px var(--cp-color-primary);
296
- }
297
- }
298
-
299
- &.cp-button--success {
300
- background: var(--cp-color-success-light);
301
- border-color: var(--cp-color-success);
302
- color: var(--cp-color-success);
303
-
304
- &::after {
305
- background: var(--cp-color-success);
306
- opacity: 0.8;
307
- }
308
-
309
- &:hover:not(.is-disabled) {
310
- filter: brightness(1.3);
311
- box-shadow: 0 0 20px var(--cp-color-success-light);
312
- text-shadow: 0 0 8px var(--cp-color-success);
313
- }
314
- }
315
-
316
- &.cp-button--warning {
317
- background: var(--cp-color-warning-light);
318
- border-color: var(--cp-color-warning);
319
- color: var(--cp-color-warning);
320
-
321
- &::after {
322
- background: var(--cp-color-warning);
323
- opacity: 0.8;
324
- }
325
-
326
- &:hover:not(.is-disabled) {
327
- filter: brightness(1.3);
328
- box-shadow: 0 0 20px var(--cp-color-warning-light);
329
- text-shadow: 0 0 8px var(--cp-color-warning);
330
- }
331
- }
332
-
333
- &.cp-button--error {
334
- background: var(--cp-color-error-light);
335
- border-color: var(--cp-color-error);
336
- color: var(--cp-color-error);
337
-
338
- &::after {
339
- background: var(--cp-color-error);
340
- opacity: 0.8;
341
- }
342
-
343
- &:hover:not(.is-disabled) {
344
- filter: brightness(1.3);
345
- box-shadow: 0 0 20px var(--cp-color-error-light);
346
- text-shadow: 0 0 8px var(--cp-color-error);
347
- }
348
- }
349
-
350
- &.cp-button--info {
351
- background: var(--cp-color-info-light);
352
- border-color: var(--cp-color-info);
353
- color: var(--cp-color-info);
354
-
355
- &::after {
356
- background: var(--cp-color-info);
357
- opacity: 0.8;
358
- }
359
-
360
- &:hover:not(.is-disabled) {
361
- filter: brightness(1.3);
362
- box-shadow: 0 0 20px var(--cp-color-info-light);
363
- text-shadow: 0 0 8px var(--cp-color-info);
364
- }
365
- }
366
-
367
- &.cp-button--default {
368
- background: color-mix(in srgb, var(--cp-border) 30%, transparent);
369
- border-color: var(--cp-border);
370
- color: var(--cp-text-secondary);
371
-
372
- &::after {
373
- background: var(--cp-border);
374
- opacity: 0.8;
375
- }
376
-
377
- &:hover:not(.is-disabled) {
378
- filter: brightness(1.2);
379
- background: color-mix(in srgb, var(--cp-border) 50%, transparent);
380
- }
381
- }
382
- }
383
-
384
- // ===== Ghost 变体 =====
385
- @include m(ghost) {
386
- &.cp-button--primary {
387
- background: transparent;
388
- border-color: transparent;
389
- color: var(--cp-color-primary);
390
-
391
- &::after {
392
- display: none;
393
- }
394
-
395
- &:hover:not(.is-disabled) {
396
- background: var(--cp-color-primary-light);
397
- text-shadow: 0 0 5px var(--cp-color-primary);
398
- }
399
- }
400
-
401
- &.cp-button--success {
402
- background: transparent;
403
- border-color: transparent;
404
- color: var(--cp-color-success);
405
-
406
- &::after {
407
- display: none;
408
- }
409
-
410
- &:hover:not(.is-disabled) {
411
- background: var(--cp-color-success-light);
412
- text-shadow: 0 0 5px var(--cp-color-success);
413
- }
414
- }
415
-
416
- &.cp-button--warning {
417
- background: transparent;
418
- border-color: transparent;
419
- color: var(--cp-color-warning);
420
-
421
- &::after {
422
- display: none;
423
- }
424
-
425
- &:hover:not(.is-disabled) {
426
- background: var(--cp-color-warning-light);
427
- text-shadow: 0 0 5px var(--cp-color-warning);
428
- }
429
- }
430
-
431
- &.cp-button--error {
432
- background: transparent;
433
- border-color: transparent;
434
- color: var(--cp-color-error);
435
-
436
- &::after {
437
- display: none;
438
- }
439
-
440
- &:hover:not(.is-disabled) {
441
- background: var(--cp-color-error-light);
442
- text-shadow: 0 0 5px var(--cp-color-error);
443
- }
444
- }
445
-
446
- &.cp-button--info {
447
- background: transparent;
448
- border-color: transparent;
449
- color: var(--cp-color-info);
450
-
451
- &::after {
452
- display: none;
453
- }
454
-
455
- &:hover:not(.is-disabled) {
456
- background: var(--cp-color-info-light);
457
- text-shadow: 0 0 5px var(--cp-color-info);
458
- }
459
- }
460
-
461
- &.cp-button--default {
462
- background: transparent;
463
- border-color: transparent;
464
- color: var(--cp-text-secondary);
465
-
466
- &::after {
467
- display: none;
468
- }
469
-
470
- &:hover:not(.is-disabled) {
471
- background: var(--cp-bg-elevated);
472
- color: var(--cp-text-primary);
473
- }
474
- }
475
- }
476
-
477
- // ===== Neon 变体 (霓虹发光) =====
478
- @include m(neon) {
479
- &.cp-button--primary {
480
- background: transparent;
481
- border-color: var(--cp-color-primary);
482
- color: var(--cp-color-primary);
483
- box-shadow: 0 0 5px var(--cp-color-primary), inset 0 0 5px var(--cp-color-primary-light);
484
- text-shadow: 0 0 5px var(--cp-color-primary);
485
- animation: neon-pulse-primary 2s ease-in-out infinite;
486
-
487
- &::after {
488
- background: var(--cp-color-primary);
489
- box-shadow: 0 0 5px var(--cp-color-primary);
490
- }
491
-
492
- &:hover:not(.is-disabled) {
493
- background: var(--cp-color-primary-light);
494
- box-shadow: 0 0 15px var(--cp-color-primary), 0 0 30px var(--cp-color-primary-light), inset 0 0 10px var(--cp-color-primary-light);
495
- }
496
- }
497
-
498
- &.cp-button--success {
499
- background: transparent;
500
- border-color: var(--cp-color-success);
501
- color: var(--cp-color-success);
502
- box-shadow: 0 0 5px var(--cp-color-success), inset 0 0 5px var(--cp-color-success-light);
503
- text-shadow: 0 0 5px var(--cp-color-success);
504
- animation: neon-pulse-success 2s ease-in-out infinite;
505
-
506
- &::after {
507
- background: var(--cp-color-success);
508
- box-shadow: 0 0 5px var(--cp-color-success);
509
- }
510
-
511
- &:hover:not(.is-disabled) {
512
- background: var(--cp-color-success-light);
513
- box-shadow: 0 0 15px var(--cp-color-success), 0 0 30px var(--cp-color-success-light), inset 0 0 10px var(--cp-color-success-light);
514
- }
515
- }
516
-
517
- &.cp-button--warning {
518
- background: transparent;
519
- border-color: var(--cp-color-warning);
520
- color: var(--cp-color-warning);
521
- box-shadow: 0 0 5px var(--cp-color-warning), inset 0 0 5px var(--cp-color-warning-light);
522
- text-shadow: 0 0 5px var(--cp-color-warning);
523
- animation: neon-pulse-warning 2s ease-in-out infinite;
524
-
525
- &::after {
526
- background: var(--cp-color-warning);
527
- box-shadow: 0 0 5px var(--cp-color-warning);
528
- }
529
-
530
- &:hover:not(.is-disabled) {
531
- background: var(--cp-color-warning-light);
532
- box-shadow: 0 0 15px var(--cp-color-warning), 0 0 30px var(--cp-color-warning-light), inset 0 0 10px var(--cp-color-warning-light);
533
- }
534
- }
535
-
536
- &.cp-button--error {
537
- background: transparent;
538
- border-color: var(--cp-color-error);
539
- color: var(--cp-color-error);
540
- box-shadow: 0 0 5px var(--cp-color-error), inset 0 0 5px var(--cp-color-error-light);
541
- text-shadow: 0 0 5px var(--cp-color-error);
542
- animation: neon-pulse-error 2s ease-in-out infinite;
543
-
544
- &::after {
545
- background: var(--cp-color-error);
546
- box-shadow: 0 0 5px var(--cp-color-error);
547
- }
548
-
549
- &:hover:not(.is-disabled) {
550
- background: var(--cp-color-error-light);
551
- box-shadow: 0 0 15px var(--cp-color-error), 0 0 30px var(--cp-color-error-light), inset 0 0 10px var(--cp-color-error-light);
552
- }
553
- }
554
-
555
- &.cp-button--info {
556
- background: transparent;
557
- border-color: var(--cp-color-info);
558
- color: var(--cp-color-info);
559
- box-shadow: 0 0 5px var(--cp-color-info), inset 0 0 5px var(--cp-color-info-light);
560
- text-shadow: 0 0 5px var(--cp-color-info);
561
- animation: neon-pulse-info 2s ease-in-out infinite;
562
-
563
- &::after {
564
- background: var(--cp-color-info);
565
- box-shadow: 0 0 5px var(--cp-color-info);
566
- }
567
-
568
- &:hover:not(.is-disabled) {
569
- background: var(--cp-color-info-light);
570
- box-shadow: 0 0 15px var(--cp-color-info), 0 0 30px var(--cp-color-info-light), inset 0 0 10px var(--cp-color-info-light);
571
- }
572
- }
573
-
574
- &.cp-button--default {
575
- background: transparent;
576
- border-color: var(--cp-border);
577
- color: var(--cp-text-secondary);
578
- box-shadow: 0 0 5px var(--cp-border);
579
-
580
- &::after {
581
- background: var(--cp-border);
582
- }
583
-
584
- &:hover:not(.is-disabled) {
585
- background: var(--cp-bg-elevated);
586
- box-shadow: 0 0 10px var(--cp-border);
587
- }
588
- }
589
- }
590
-
591
- // ===== 状态 =====
592
- @include when(disabled) {
593
- cursor: not-allowed;
594
- opacity: 0.5;
595
- filter: grayscale(0.5);
596
- }
597
-
598
- @include when(loading) {
599
- cursor: wait;
600
- pointer-events: none;
601
- }
602
-
603
- @include when(block) {
604
- display: flex;
605
- width: 100%;
606
- }
607
-
608
- // ===== 形状模式 =====
609
- // clip 是默认,已在基础样式中定义
610
-
611
- // no-clip (直角)
612
- @include m(shape-no-clip) {
613
- clip-path: none;
614
- border-radius: 0;
615
-
616
- &::after {
617
- display: none;
618
- }
619
- }
620
-
621
- // round (圆角)
622
- @include m(shape-round) {
623
- clip-path: none;
624
- border-radius: var(--cp-radius-lg);
625
-
626
- &::after {
627
- display: none;
628
- }
629
- }
630
-
631
- // circle (胶囊/全圆)
632
- @include m(shape-circle) {
633
- clip-path: none;
634
- border-radius: 9999px;
635
-
636
- &::after {
637
- display: none;
638
- }
639
- }
640
-
641
- // 虚线边框
642
- @include when(dashed) {
643
- border-style: dashed;
644
- }
645
-
646
- // 自定义颜色
647
- @include when(custom-color) {
648
-
649
- // Solid
650
- &.cp-button--solid {
651
- background: var(--cp-button-custom-color);
652
- border-color: var(--cp-button-custom-color);
653
- color: var(--cp-bg-deep);
654
-
655
- &::after {
656
- background: rgba(0, 0, 0, 0.3);
657
- }
658
-
659
- &:hover:not(.is-disabled) {
660
- background: var(--cp-button-custom-color);
661
- border-color: var(--cp-button-custom-color);
662
- color: var(--cp-bg-deep);
663
- filter: brightness(1.2);
664
- box-shadow: 0 0 20px var(--cp-button-custom-color-light), 0 0 40px var(--cp-button-custom-color-light);
665
- }
666
- }
667
-
668
- // Outline
669
- &.cp-button--outline {
670
- background: transparent;
671
- border-color: var(--cp-button-custom-color);
672
- color: var(--cp-button-custom-color);
673
-
674
- &:hover:not(.is-disabled) {
675
- background: var(--cp-button-custom-color-light);
676
- border-color: var(--cp-button-custom-color);
677
- color: var(--cp-button-custom-color);
678
- box-shadow: 0 0 15px var(--cp-button-custom-color-light);
679
- }
680
- }
681
-
682
- // Semi
683
- &.cp-button--semi {
684
- background: var(--cp-button-custom-color-light);
685
- border-color: var(--cp-button-custom-color);
686
- color: var(--cp-button-custom-color);
687
-
688
- &::after {
689
- background: var(--cp-button-custom-color);
690
- opacity: 0.8;
691
- }
692
-
693
- &:hover:not(.is-disabled) {
694
- background: var(--cp-button-custom-color-light);
695
- border-color: var(--cp-button-custom-color);
696
- color: var(--cp-button-custom-color);
697
- filter: brightness(1.3);
698
- box-shadow: 0 0 20px var(--cp-button-custom-color-light);
699
- text-shadow: 0 0 8px var(--cp-button-custom-color);
700
- }
701
- }
702
-
703
- // Ghost
704
- &.cp-button--ghost {
705
- background: transparent;
706
- border-color: transparent;
707
- color: var(--cp-button-custom-color);
708
-
709
- &::after {
710
- display: none;
711
- }
712
-
713
- &:hover:not(.is-disabled) {
714
- background: var(--cp-button-custom-color-light);
715
- border-color: transparent;
716
- color: var(--cp-button-custom-color);
717
- text-shadow: 0 0 5px var(--cp-button-custom-color);
718
- }
719
- }
720
-
721
- // Neon
722
- &.cp-button--neon {
723
- background: transparent;
724
- border-color: var(--cp-button-custom-color);
725
- color: var(--cp-button-custom-color);
726
- box-shadow: 0 0 5px var(--cp-button-custom-color);
727
- text-shadow: 0 0 5px var(--cp-button-custom-color);
728
-
729
- &::after {
730
- background: var(--cp-button-custom-color);
731
- box-shadow: 0 0 5px var(--cp-button-custom-color);
732
- }
733
-
734
- &:hover:not(.is-disabled) {
735
- background: var(--cp-button-custom-color-light);
736
- border-color: var(--cp-button-custom-color);
737
- color: var(--cp-button-custom-color);
738
- box-shadow: 0 0 15px var(--cp-button-custom-color), 0 0 30px var(--cp-button-custom-color-light), inset 0 0 10px var(--cp-button-custom-color-light);
739
- }
740
- }
741
- }
742
-
743
- // ===== 内部元素 =====
744
- @include e(prefix) {
745
- display: inline-flex;
746
- align-items: center;
747
- margin-right: 0.35em; // 紧凑间距,保持视觉平衡
748
- }
749
-
750
- @include e(suffix) {
751
- display: inline-flex;
752
- align-items: center;
753
- margin-left: 0.35em; // 紧凑间距,保持视觉平衡
754
- }
755
-
756
- @include e(content) {
757
- display: inline-flex;
758
- align-items: center;
759
- gap: var(--cp-spacing-sm);
760
- }
761
-
762
- @include e(loader) {
763
- display: inline-flex;
764
- align-items: center;
765
- justify-content: center;
766
- margin-right: 0.75em; // 再次增加间距
767
- flex-shrink: 0;
768
- }
769
-
770
- // loading-placeholder 模式:通过平衡 padding 预留空间
771
- @include when(loading-placeholder) {
772
- position: relative;
773
-
774
- // 计算预留的总宽度 = Loader宽度(1.1em * 1.1 font-size) + 间距(0.75em)
775
- $reserved-width: calc(1.21em + 0.75em);
776
-
777
- // 非加载状态:左右各分担一半预留宽度,使文字居中
778
- padding-left: calc(var(--cp-spacing-lg) + #{$reserved-width} / 2);
779
- padding-right: calc(var(--cp-spacing-lg) + #{$reserved-width} / 2);
780
- transition: padding-left 0.25s ease, padding-right 0.25s ease;
781
-
782
- .cp-button__loader {
783
- position: absolute;
784
- left: var(--cp-spacing-lg); // Loader 始终位于左侧标准位置
785
- top: 50%;
786
- transform: translateY(-50%);
787
- margin-right: 0;
788
- opacity: 0;
789
- transition: opacity 0.2s ease;
790
- }
791
-
792
- // 加载状态:左侧占据全部预留宽度,右侧恢复标准
793
- &.is-loading {
794
- padding-left: calc(var(--cp-spacing-lg) + #{$reserved-width});
795
- padding-right: var(--cp-spacing-lg);
796
- .cp-button__loader {
797
- opacity: 1;
798
- }
799
- }
800
- }
801
-
802
- // ===== Icon-only 模式 (正方形图标按钮) =====
803
- @include when(icon-only) {
804
- padding: 0;
805
- aspect-ratio: 1;
806
-
807
- // 图标居中
808
- .cp-icon,
809
- .cp-loading {
810
- display: flex;
811
- align-items: center;
812
- justify-content: center;
813
- }
814
-
815
- // 不同尺寸的正方形大小
816
- &.cp-button--sm {
817
- width: var(--cp-button-height-sm);
818
- height: var(--cp-button-height-sm);
819
- }
820
-
821
- &.cp-button--md {
822
- width: var(--cp-button-height-md);
823
- height: var(--cp-button-height-md);
824
- }
825
-
826
- &.cp-button--lg {
827
- width: var(--cp-button-height-lg);
828
- height: var(--cp-button-height-lg);
829
- }
830
-
831
- &.is-custom-size {
832
- width: var(--cp-button-height);
833
- height: var(--cp-button-height);
834
- }
835
- }
836
-
837
- // ===== 减淡模式 (Dimmed Mode) =====
838
- // 减淡模式:平常以无颜色的默认形态展示,hover 时显示真正的主题色
839
- @include when(dimmed) {
840
- &:not(:hover) {
841
- // Solid 变体
842
- &.cp-button--solid:not(.cp-button--default) {
843
- background: var(--cp-bg-elevated);
844
- border-color: var(--cp-border);
845
- color: var(--cp-text-primary);
846
-
847
- &::after {
848
- background: var(--cp-border);
849
- }
850
- }
851
-
852
- // Outline 变体
853
- &.cp-button--outline:not(.cp-button--default) {
854
- background: transparent;
855
- border-color: var(--cp-border);
856
- color: var(--cp-text-secondary);
857
- }
858
-
859
- // Semi 变体
860
- &.cp-button--semi:not(.cp-button--default) {
861
- background: color-mix(in srgb, var(--cp-border) 30%, transparent);
862
- border-color: var(--cp-border);
863
- color: var(--cp-text-secondary);
864
-
865
- &::after {
866
- background: var(--cp-border);
867
- opacity: 0.8;
868
- }
869
- }
870
-
871
- // Ghost 变体
872
- &.cp-button--ghost:not(.cp-button--default) {
873
- background: transparent;
874
- border-color: transparent;
875
- color: var(--cp-text-secondary);
876
-
877
- &::after {
878
- display: none;
879
- }
880
- }
881
-
882
- // Neon 变体
883
- &.cp-button--neon:not(.cp-button--default) {
884
- background: transparent;
885
- border-color: var(--cp-border);
886
- color: var(--cp-text-secondary);
887
- box-shadow: 0 0 5px var(--cp-border);
888
- text-shadow: none;
889
- animation: none;
890
-
891
- &::after {
892
- background: var(--cp-border);
893
- box-shadow: none;
894
- }
895
- }
896
- }
897
- }
898
- }
899
-
900
- // Vue Transition 样式 - Loader 入场/离场动画 (仅用于非占位模式)
901
- .cp-loader-enter-active,
902
- .cp-loader-leave-active {
903
- transition: width 0.25s ease, margin 0.25s ease, opacity 0.2s ease;
904
- }
905
-
906
- .cp-loader-enter-from,
907
- .cp-loader-leave-to {
908
- width: 0 !important;
909
- margin-right: 0 !important;
910
- opacity: 0 !important;
911
- }
912
-
913
-
914
-
915
-
916
-
917
- @keyframes neon-pulse-primary {
918
-
919
- 0%,
920
- 100% {
921
- box-shadow: 0 0 5px var(--cp-color-primary);
922
- }
923
-
924
- 50% {
925
- box-shadow: 0 0 15px var(--cp-color-primary), 0 0 25px var(--cp-color-primary);
926
- }
927
- }
928
-
929
- @keyframes neon-pulse-success {
930
-
931
- 0%,
932
- 100% {
933
- box-shadow: 0 0 5px var(--cp-color-success);
934
- }
935
-
936
- 50% {
937
- box-shadow: 0 0 15px var(--cp-color-success), 0 0 25px var(--cp-color-success);
938
- }
939
- }
940
-
941
- @keyframes neon-pulse-warning {
942
-
943
- 0%,
944
- 100% {
945
- box-shadow: 0 0 5px var(--cp-color-warning);
946
- }
947
-
948
- 50% {
949
- box-shadow: 0 0 15px var(--cp-color-warning), 0 0 25px var(--cp-color-warning);
950
- }
951
- }
952
-
953
- @keyframes neon-pulse-error {
954
-
955
- 0%,
956
- 100% {
957
- box-shadow: 0 0 5px var(--cp-color-error);
958
- }
959
-
960
- 50% {
961
- box-shadow: 0 0 15px var(--cp-color-error), 0 0 25px var(--cp-color-error);
962
- }
963
- }
964
-
965
- @keyframes neon-pulse-info {
966
-
967
- 0%,
968
- 100% {
969
- box-shadow: 0 0 5px var(--cp-color-info);
970
- }
971
-
972
- 50% {
973
- box-shadow: 0 0 15px var(--cp-color-info), 0 0 25px var(--cp-color-info);
974
- }
975
- }
1
+ // CpButton 组件样式
2
+ // 赛博朋克/机甲风格
3
+
4
+ @use '../common/var' as *;
5
+ @use '../mixins/mixins' as *;
6
+
7
+ @include b(button) {
8
+ // 基础样式
9
+ position: relative;
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ // 注意:不使用 gap,因为 loader 需要动画 margin 来实现平滑过渡
14
+ padding: 0 var(--cp-spacing-lg);
15
+
16
+ font-family: var(--cp-font-family-display);
17
+ font-weight: 600;
18
+ text-transform: uppercase;
19
+ letter-spacing: 0.05em;
20
+ cursor: pointer;
21
+ border: 1px solid transparent;
22
+ outline: none;
23
+ background: transparent;
24
+ color: var(--cp-text-primary);
25
+ z-index: 1;
26
+ transition: all 0.2s ease;
27
+ user-select: none;
28
+
29
+ --cp-button-clip-size: 10px;
30
+
31
+ // 机甲风切角 (Top-Left, Bottom-Right)
32
+ clip-path: polygon(var(--cp-button-clip-size) 0,
33
+ 100% 0,
34
+ 100% calc(100% - var(--cp-button-clip-size)),
35
+ calc(100% - var(--cp-button-clip-size)) 100%,
36
+ 0 100%,
37
+ 0 var(--cp-button-clip-size));
38
+
39
+ // 装饰性小方块 (右上角)
40
+ &::after {
41
+ content: '';
42
+ position: absolute;
43
+ top: 0;
44
+ right: 0;
45
+ width: 8px;
46
+ height: 8px;
47
+ background: currentColor;
48
+ opacity: 0.5;
49
+ z-index: 2;
50
+ transition: all 0.2s ease;
51
+ }
52
+
53
+ // 小尺寸下缩小装饰性小方块,防止遮挡内容
54
+ @include when(small-size) {
55
+ &::after {
56
+ width: 4px;
57
+ height: 4px;
58
+ }
59
+ }
60
+
61
+ // 隐藏装饰性小方块
62
+ @include when(no-decoration) {
63
+ &::after {
64
+ display: none;
65
+ }
66
+ }
67
+
68
+ // 点击动画
69
+ &:active:not(.is-disabled) {
70
+ transform: scale(0.96);
71
+ transition: transform 0.1s ease;
72
+ }
73
+
74
+ // ===== 尺寸 =====
75
+ @include m(sm) {
76
+ height: var(--cp-button-height-sm);
77
+ font-size: var(--cp-font-size-sm);
78
+ padding: 0 var(--cp-spacing-md);
79
+ --cp-button-clip-size: 8px;
80
+ }
81
+
82
+ @include m(md) {
83
+ height: var(--cp-button-height-md);
84
+ font-size: var(--cp-font-size-md);
85
+ }
86
+
87
+ @include m(lg) {
88
+ height: var(--cp-button-height-lg);
89
+ font-size: var(--cp-font-size-lg);
90
+ padding: 0 var(--cp-spacing-xl);
91
+ }
92
+
93
+ // 自定义尺寸
94
+ @include when(custom-size) {
95
+ height: var(--cp-button-height);
96
+ }
97
+
98
+ // ===== Solid 变体 =====
99
+ @include m(solid) {
100
+ &.cp-button--primary {
101
+ background: var(--cp-color-primary);
102
+ border-color: var(--cp-color-primary);
103
+ color: var(--cp-color-primary-text);
104
+
105
+ &::after {
106
+ background: rgba(0, 0, 0, 0.3);
107
+ }
108
+
109
+ &:hover:not(.is-disabled) {
110
+ filter: brightness(1.2);
111
+ box-shadow: 0 0 20px var(--cp-color-primary-light), 0 0 40px var(--cp-color-primary-light);
112
+
113
+ &::after {
114
+ opacity: 0.8;
115
+ }
116
+ }
117
+ }
118
+
119
+ &.cp-button--success {
120
+ background: var(--cp-color-success);
121
+ border-color: var(--cp-color-success);
122
+ color: var(--cp-color-success-text);
123
+
124
+ &::after {
125
+ background: rgba(0, 0, 0, 0.3);
126
+ }
127
+
128
+ &:hover:not(.is-disabled) {
129
+ filter: brightness(1.2);
130
+ box-shadow: 0 0 20px var(--cp-color-success-light), 0 0 40px var(--cp-color-success-light);
131
+
132
+ &::after {
133
+ opacity: 0.8;
134
+ }
135
+ }
136
+ }
137
+
138
+ &.cp-button--warning {
139
+ background: var(--cp-color-warning);
140
+ border-color: var(--cp-color-warning);
141
+ color: var(--cp-color-warning-text);
142
+
143
+ &::after {
144
+ background: rgba(0, 0, 0, 0.3);
145
+ }
146
+
147
+ &:hover:not(.is-disabled) {
148
+ filter: brightness(1.2);
149
+ box-shadow: 0 0 20px var(--cp-color-warning-light), 0 0 40px var(--cp-color-warning-light);
150
+
151
+ &::after {
152
+ opacity: 0.8;
153
+ }
154
+ }
155
+ }
156
+
157
+ &.cp-button--error {
158
+ background: var(--cp-color-error);
159
+ border-color: var(--cp-color-error);
160
+ color: var(--cp-color-error-text);
161
+
162
+ &::after {
163
+ background: rgba(0, 0, 0, 0.3);
164
+ }
165
+
166
+ &:hover:not(.is-disabled) {
167
+ filter: brightness(1.2);
168
+ box-shadow: 0 0 20px var(--cp-color-error-light), 0 0 40px var(--cp-color-error-light);
169
+
170
+ &::after {
171
+ opacity: 0.8;
172
+ }
173
+ }
174
+ }
175
+
176
+ &.cp-button--info {
177
+ background: var(--cp-color-info);
178
+ border-color: var(--cp-color-info);
179
+ color: var(--cp-color-info-text);
180
+
181
+ &::after {
182
+ background: rgba(0, 0, 0, 0.3);
183
+ }
184
+
185
+ &:hover:not(.is-disabled) {
186
+ filter: brightness(1.2);
187
+ box-shadow: 0 0 20px var(--cp-color-info-light), 0 0 40px var(--cp-color-info-light);
188
+
189
+ &::after {
190
+ opacity: 0.8;
191
+ }
192
+ }
193
+ }
194
+
195
+ &.cp-button--default {
196
+ background: var(--cp-bg-elevated);
197
+ border-color: var(--cp-border);
198
+ color: var(--cp-text-primary);
199
+
200
+ &::after {
201
+ background: var(--cp-border);
202
+ }
203
+
204
+ &:hover:not(.is-disabled) {
205
+ background: var(--cp-border);
206
+ border-color: var(--cp-text-secondary);
207
+ }
208
+ }
209
+ }
210
+
211
+ // ===== Outline 变体 =====
212
+ @include m(outline) {
213
+ &.cp-button--primary {
214
+ background: transparent;
215
+ border-color: var(--cp-color-primary);
216
+ color: var(--cp-color-primary);
217
+
218
+ &:hover:not(.is-disabled) {
219
+ background: var(--cp-color-primary-light);
220
+ box-shadow: 0 0 15px var(--cp-color-primary-light);
221
+ }
222
+ }
223
+
224
+ &.cp-button--success {
225
+ background: transparent;
226
+ border-color: var(--cp-color-success);
227
+ color: var(--cp-color-success);
228
+
229
+ &:hover:not(.is-disabled) {
230
+ background: var(--cp-color-success-light);
231
+ box-shadow: 0 0 15px var(--cp-color-success-light);
232
+ }
233
+ }
234
+
235
+ &.cp-button--warning {
236
+ background: transparent;
237
+ border-color: var(--cp-color-warning);
238
+ color: var(--cp-color-warning);
239
+
240
+ &:hover:not(.is-disabled) {
241
+ background: var(--cp-color-warning-light);
242
+ box-shadow: 0 0 15px var(--cp-color-warning-light);
243
+ }
244
+ }
245
+
246
+ &.cp-button--error {
247
+ background: transparent;
248
+ border-color: var(--cp-color-error);
249
+ color: var(--cp-color-error);
250
+
251
+ &:hover:not(.is-disabled) {
252
+ background: var(--cp-color-error-light);
253
+ box-shadow: 0 0 15px var(--cp-color-error-light);
254
+ }
255
+ }
256
+
257
+ &.cp-button--info {
258
+ background: transparent;
259
+ border-color: var(--cp-color-info);
260
+ color: var(--cp-color-info);
261
+
262
+ &:hover:not(.is-disabled) {
263
+ background: var(--cp-color-info-light);
264
+ box-shadow: 0 0 15px var(--cp-color-info-light);
265
+ }
266
+ }
267
+
268
+ &.cp-button--default {
269
+ background: transparent;
270
+ border-color: var(--cp-border);
271
+ color: var(--cp-text-secondary);
272
+
273
+ &:hover:not(.is-disabled) {
274
+ background: var(--cp-bg-elevated);
275
+ border-color: var(--cp-text-secondary);
276
+ }
277
+ }
278
+ }
279
+
280
+ // ===== Semi 变体 (半填充) =====
281
+ @include m(semi) {
282
+ &.cp-button--primary {
283
+ background: var(--cp-color-primary-light);
284
+ border-color: var(--cp-color-primary);
285
+ color: var(--cp-color-primary);
286
+
287
+ &::after {
288
+ background: var(--cp-color-primary);
289
+ opacity: 0.8;
290
+ }
291
+
292
+ &:hover:not(.is-disabled) {
293
+ filter: brightness(1.3);
294
+ box-shadow: 0 0 20px var(--cp-color-primary-light);
295
+ text-shadow: 0 0 8px var(--cp-color-primary);
296
+ }
297
+ }
298
+
299
+ &.cp-button--success {
300
+ background: var(--cp-color-success-light);
301
+ border-color: var(--cp-color-success);
302
+ color: var(--cp-color-success);
303
+
304
+ &::after {
305
+ background: var(--cp-color-success);
306
+ opacity: 0.8;
307
+ }
308
+
309
+ &:hover:not(.is-disabled) {
310
+ filter: brightness(1.3);
311
+ box-shadow: 0 0 20px var(--cp-color-success-light);
312
+ text-shadow: 0 0 8px var(--cp-color-success);
313
+ }
314
+ }
315
+
316
+ &.cp-button--warning {
317
+ background: var(--cp-color-warning-light);
318
+ border-color: var(--cp-color-warning);
319
+ color: var(--cp-color-warning);
320
+
321
+ &::after {
322
+ background: var(--cp-color-warning);
323
+ opacity: 0.8;
324
+ }
325
+
326
+ &:hover:not(.is-disabled) {
327
+ filter: brightness(1.3);
328
+ box-shadow: 0 0 20px var(--cp-color-warning-light);
329
+ text-shadow: 0 0 8px var(--cp-color-warning);
330
+ }
331
+ }
332
+
333
+ &.cp-button--error {
334
+ background: var(--cp-color-error-light);
335
+ border-color: var(--cp-color-error);
336
+ color: var(--cp-color-error);
337
+
338
+ &::after {
339
+ background: var(--cp-color-error);
340
+ opacity: 0.8;
341
+ }
342
+
343
+ &:hover:not(.is-disabled) {
344
+ filter: brightness(1.3);
345
+ box-shadow: 0 0 20px var(--cp-color-error-light);
346
+ text-shadow: 0 0 8px var(--cp-color-error);
347
+ }
348
+ }
349
+
350
+ &.cp-button--info {
351
+ background: var(--cp-color-info-light);
352
+ border-color: var(--cp-color-info);
353
+ color: var(--cp-color-info);
354
+
355
+ &::after {
356
+ background: var(--cp-color-info);
357
+ opacity: 0.8;
358
+ }
359
+
360
+ &:hover:not(.is-disabled) {
361
+ filter: brightness(1.3);
362
+ box-shadow: 0 0 20px var(--cp-color-info-light);
363
+ text-shadow: 0 0 8px var(--cp-color-info);
364
+ }
365
+ }
366
+
367
+ &.cp-button--default {
368
+ background: color-mix(in srgb, var(--cp-border) 30%, transparent);
369
+ border-color: var(--cp-border);
370
+ color: var(--cp-text-secondary);
371
+
372
+ &::after {
373
+ background: var(--cp-border);
374
+ opacity: 0.8;
375
+ }
376
+
377
+ &:hover:not(.is-disabled) {
378
+ filter: brightness(1.2);
379
+ background: color-mix(in srgb, var(--cp-border) 50%, transparent);
380
+ }
381
+ }
382
+ }
383
+
384
+ // ===== Ghost 变体 =====
385
+ @include m(ghost) {
386
+ &.cp-button--primary {
387
+ background: transparent;
388
+ border-color: transparent;
389
+ color: var(--cp-color-primary);
390
+
391
+ &::after {
392
+ display: none;
393
+ }
394
+
395
+ &:hover:not(.is-disabled) {
396
+ background: var(--cp-color-primary-light);
397
+ text-shadow: 0 0 5px var(--cp-color-primary);
398
+ }
399
+ }
400
+
401
+ &.cp-button--success {
402
+ background: transparent;
403
+ border-color: transparent;
404
+ color: var(--cp-color-success);
405
+
406
+ &::after {
407
+ display: none;
408
+ }
409
+
410
+ &:hover:not(.is-disabled) {
411
+ background: var(--cp-color-success-light);
412
+ text-shadow: 0 0 5px var(--cp-color-success);
413
+ }
414
+ }
415
+
416
+ &.cp-button--warning {
417
+ background: transparent;
418
+ border-color: transparent;
419
+ color: var(--cp-color-warning);
420
+
421
+ &::after {
422
+ display: none;
423
+ }
424
+
425
+ &:hover:not(.is-disabled) {
426
+ background: var(--cp-color-warning-light);
427
+ text-shadow: 0 0 5px var(--cp-color-warning);
428
+ }
429
+ }
430
+
431
+ &.cp-button--error {
432
+ background: transparent;
433
+ border-color: transparent;
434
+ color: var(--cp-color-error);
435
+
436
+ &::after {
437
+ display: none;
438
+ }
439
+
440
+ &:hover:not(.is-disabled) {
441
+ background: var(--cp-color-error-light);
442
+ text-shadow: 0 0 5px var(--cp-color-error);
443
+ }
444
+ }
445
+
446
+ &.cp-button--info {
447
+ background: transparent;
448
+ border-color: transparent;
449
+ color: var(--cp-color-info);
450
+
451
+ &::after {
452
+ display: none;
453
+ }
454
+
455
+ &:hover:not(.is-disabled) {
456
+ background: var(--cp-color-info-light);
457
+ text-shadow: 0 0 5px var(--cp-color-info);
458
+ }
459
+ }
460
+
461
+ &.cp-button--default {
462
+ background: transparent;
463
+ border-color: transparent;
464
+ color: var(--cp-text-secondary);
465
+
466
+ &::after {
467
+ display: none;
468
+ }
469
+
470
+ &:hover:not(.is-disabled) {
471
+ background: var(--cp-bg-elevated);
472
+ color: var(--cp-text-primary);
473
+ }
474
+ }
475
+ }
476
+
477
+ // ===== Neon 变体 (霓虹发光) =====
478
+ @include m(neon) {
479
+ &.cp-button--primary {
480
+ background: transparent;
481
+ border-color: var(--cp-color-primary);
482
+ color: var(--cp-color-primary);
483
+ box-shadow: 0 0 5px var(--cp-color-primary), inset 0 0 5px var(--cp-color-primary-light);
484
+ text-shadow: 0 0 5px var(--cp-color-primary);
485
+ animation: neon-pulse-primary 2s ease-in-out infinite;
486
+
487
+ &::after {
488
+ background: var(--cp-color-primary);
489
+ box-shadow: 0 0 5px var(--cp-color-primary);
490
+ }
491
+
492
+ &:hover:not(.is-disabled) {
493
+ background: var(--cp-color-primary-light);
494
+ box-shadow: 0 0 15px var(--cp-color-primary), 0 0 30px var(--cp-color-primary-light), inset 0 0 10px var(--cp-color-primary-light);
495
+ }
496
+ }
497
+
498
+ &.cp-button--success {
499
+ background: transparent;
500
+ border-color: var(--cp-color-success);
501
+ color: var(--cp-color-success);
502
+ box-shadow: 0 0 5px var(--cp-color-success), inset 0 0 5px var(--cp-color-success-light);
503
+ text-shadow: 0 0 5px var(--cp-color-success);
504
+ animation: neon-pulse-success 2s ease-in-out infinite;
505
+
506
+ &::after {
507
+ background: var(--cp-color-success);
508
+ box-shadow: 0 0 5px var(--cp-color-success);
509
+ }
510
+
511
+ &:hover:not(.is-disabled) {
512
+ background: var(--cp-color-success-light);
513
+ box-shadow: 0 0 15px var(--cp-color-success), 0 0 30px var(--cp-color-success-light), inset 0 0 10px var(--cp-color-success-light);
514
+ }
515
+ }
516
+
517
+ &.cp-button--warning {
518
+ background: transparent;
519
+ border-color: var(--cp-color-warning);
520
+ color: var(--cp-color-warning);
521
+ box-shadow: 0 0 5px var(--cp-color-warning), inset 0 0 5px var(--cp-color-warning-light);
522
+ text-shadow: 0 0 5px var(--cp-color-warning);
523
+ animation: neon-pulse-warning 2s ease-in-out infinite;
524
+
525
+ &::after {
526
+ background: var(--cp-color-warning);
527
+ box-shadow: 0 0 5px var(--cp-color-warning);
528
+ }
529
+
530
+ &:hover:not(.is-disabled) {
531
+ background: var(--cp-color-warning-light);
532
+ box-shadow: 0 0 15px var(--cp-color-warning), 0 0 30px var(--cp-color-warning-light), inset 0 0 10px var(--cp-color-warning-light);
533
+ }
534
+ }
535
+
536
+ &.cp-button--error {
537
+ background: transparent;
538
+ border-color: var(--cp-color-error);
539
+ color: var(--cp-color-error);
540
+ box-shadow: 0 0 5px var(--cp-color-error), inset 0 0 5px var(--cp-color-error-light);
541
+ text-shadow: 0 0 5px var(--cp-color-error);
542
+ animation: neon-pulse-error 2s ease-in-out infinite;
543
+
544
+ &::after {
545
+ background: var(--cp-color-error);
546
+ box-shadow: 0 0 5px var(--cp-color-error);
547
+ }
548
+
549
+ &:hover:not(.is-disabled) {
550
+ background: var(--cp-color-error-light);
551
+ box-shadow: 0 0 15px var(--cp-color-error), 0 0 30px var(--cp-color-error-light), inset 0 0 10px var(--cp-color-error-light);
552
+ }
553
+ }
554
+
555
+ &.cp-button--info {
556
+ background: transparent;
557
+ border-color: var(--cp-color-info);
558
+ color: var(--cp-color-info);
559
+ box-shadow: 0 0 5px var(--cp-color-info), inset 0 0 5px var(--cp-color-info-light);
560
+ text-shadow: 0 0 5px var(--cp-color-info);
561
+ animation: neon-pulse-info 2s ease-in-out infinite;
562
+
563
+ &::after {
564
+ background: var(--cp-color-info);
565
+ box-shadow: 0 0 5px var(--cp-color-info);
566
+ }
567
+
568
+ &:hover:not(.is-disabled) {
569
+ background: var(--cp-color-info-light);
570
+ box-shadow: 0 0 15px var(--cp-color-info), 0 0 30px var(--cp-color-info-light), inset 0 0 10px var(--cp-color-info-light);
571
+ }
572
+ }
573
+
574
+ &.cp-button--default {
575
+ background: transparent;
576
+ border-color: var(--cp-border);
577
+ color: var(--cp-text-secondary);
578
+ box-shadow: 0 0 5px var(--cp-border);
579
+
580
+ &::after {
581
+ background: var(--cp-border);
582
+ }
583
+
584
+ &:hover:not(.is-disabled) {
585
+ background: var(--cp-bg-elevated);
586
+ box-shadow: 0 0 10px var(--cp-border);
587
+ }
588
+ }
589
+ }
590
+
591
+ // ===== 状态 =====
592
+ @include when(disabled) {
593
+ cursor: not-allowed;
594
+ opacity: 0.5;
595
+ filter: grayscale(0.5);
596
+ }
597
+
598
+ @include when(loading) {
599
+ cursor: wait;
600
+ pointer-events: none;
601
+ }
602
+
603
+ @include when(block) {
604
+ display: flex;
605
+ width: 100%;
606
+ }
607
+
608
+ // ===== 形状模式 =====
609
+ // clip 是默认,已在基础样式中定义
610
+
611
+ // no-clip (直角)
612
+ @include m(shape-no-clip) {
613
+ clip-path: none;
614
+ border-radius: 0;
615
+
616
+ &::after {
617
+ display: none;
618
+ }
619
+ }
620
+
621
+ // round (圆角)
622
+ @include m(shape-round) {
623
+ clip-path: none;
624
+ border-radius: var(--cp-radius-lg);
625
+
626
+ &::after {
627
+ display: none;
628
+ }
629
+ }
630
+
631
+ // circle (胶囊/全圆)
632
+ @include m(shape-circle) {
633
+ clip-path: none;
634
+ border-radius: 9999px;
635
+
636
+ &::after {
637
+ display: none;
638
+ }
639
+ }
640
+
641
+ // 虚线边框
642
+ @include when(dashed) {
643
+ border-style: dashed;
644
+ }
645
+
646
+ // 自定义颜色
647
+ @include when(custom-color) {
648
+
649
+ // Solid
650
+ &.cp-button--solid {
651
+ background: var(--cp-button-custom-color);
652
+ border-color: var(--cp-button-custom-color);
653
+ color: var(--cp-bg-deep);
654
+
655
+ &::after {
656
+ background: rgba(0, 0, 0, 0.3);
657
+ }
658
+
659
+ &:hover:not(.is-disabled) {
660
+ background: var(--cp-button-custom-color);
661
+ border-color: var(--cp-button-custom-color);
662
+ color: var(--cp-bg-deep);
663
+ filter: brightness(1.2);
664
+ box-shadow: 0 0 20px var(--cp-button-custom-color-light), 0 0 40px var(--cp-button-custom-color-light);
665
+ }
666
+ }
667
+
668
+ // Outline
669
+ &.cp-button--outline {
670
+ background: transparent;
671
+ border-color: var(--cp-button-custom-color);
672
+ color: var(--cp-button-custom-color);
673
+
674
+ &:hover:not(.is-disabled) {
675
+ background: var(--cp-button-custom-color-light);
676
+ border-color: var(--cp-button-custom-color);
677
+ color: var(--cp-button-custom-color);
678
+ box-shadow: 0 0 15px var(--cp-button-custom-color-light);
679
+ }
680
+ }
681
+
682
+ // Semi
683
+ &.cp-button--semi {
684
+ background: var(--cp-button-custom-color-light);
685
+ border-color: var(--cp-button-custom-color);
686
+ color: var(--cp-button-custom-color);
687
+
688
+ &::after {
689
+ background: var(--cp-button-custom-color);
690
+ opacity: 0.8;
691
+ }
692
+
693
+ &:hover:not(.is-disabled) {
694
+ background: var(--cp-button-custom-color-light);
695
+ border-color: var(--cp-button-custom-color);
696
+ color: var(--cp-button-custom-color);
697
+ filter: brightness(1.3);
698
+ box-shadow: 0 0 20px var(--cp-button-custom-color-light);
699
+ text-shadow: 0 0 8px var(--cp-button-custom-color);
700
+ }
701
+ }
702
+
703
+ // Ghost
704
+ &.cp-button--ghost {
705
+ background: transparent;
706
+ border-color: transparent;
707
+ color: var(--cp-button-custom-color);
708
+
709
+ &::after {
710
+ display: none;
711
+ }
712
+
713
+ &:hover:not(.is-disabled) {
714
+ background: var(--cp-button-custom-color-light);
715
+ border-color: transparent;
716
+ color: var(--cp-button-custom-color);
717
+ text-shadow: 0 0 5px var(--cp-button-custom-color);
718
+ }
719
+ }
720
+
721
+ // Neon
722
+ &.cp-button--neon {
723
+ background: transparent;
724
+ border-color: var(--cp-button-custom-color);
725
+ color: var(--cp-button-custom-color);
726
+ box-shadow: 0 0 5px var(--cp-button-custom-color);
727
+ text-shadow: 0 0 5px var(--cp-button-custom-color);
728
+
729
+ &::after {
730
+ background: var(--cp-button-custom-color);
731
+ box-shadow: 0 0 5px var(--cp-button-custom-color);
732
+ }
733
+
734
+ &:hover:not(.is-disabled) {
735
+ background: var(--cp-button-custom-color-light);
736
+ border-color: var(--cp-button-custom-color);
737
+ color: var(--cp-button-custom-color);
738
+ box-shadow: 0 0 15px var(--cp-button-custom-color), 0 0 30px var(--cp-button-custom-color-light), inset 0 0 10px var(--cp-button-custom-color-light);
739
+ }
740
+ }
741
+ }
742
+
743
+ // ===== 内部元素 =====
744
+ @include e(prefix) {
745
+ display: inline-flex;
746
+ align-items: center;
747
+ margin-right: 0.35em; // 紧凑间距,保持视觉平衡
748
+ }
749
+
750
+ @include e(suffix) {
751
+ display: inline-flex;
752
+ align-items: center;
753
+ margin-left: 0.35em; // 紧凑间距,保持视觉平衡
754
+ }
755
+
756
+ @include e(content) {
757
+ display: inline-flex;
758
+ align-items: center;
759
+ gap: var(--cp-spacing-sm);
760
+ }
761
+
762
+ @include e(loader) {
763
+ display: inline-flex;
764
+ align-items: center;
765
+ justify-content: center;
766
+ margin-right: 0.75em; // 再次增加间距
767
+ flex-shrink: 0;
768
+ }
769
+
770
+ // loading-placeholder 模式:通过平衡 padding 预留空间
771
+ @include when(loading-placeholder) {
772
+ position: relative;
773
+
774
+ // 计算预留的总宽度 = Loader宽度(1.1em * 1.1 font-size) + 间距(0.75em)
775
+ $reserved-width: calc(1.21em + 0.75em);
776
+
777
+ // 非加载状态:左右各分担一半预留宽度,使文字居中
778
+ padding-left: calc(var(--cp-spacing-lg) + #{$reserved-width} / 2);
779
+ padding-right: calc(var(--cp-spacing-lg) + #{$reserved-width} / 2);
780
+ transition: padding-left 0.25s ease, padding-right 0.25s ease;
781
+
782
+ .cp-button__loader {
783
+ position: absolute;
784
+ left: var(--cp-spacing-lg); // Loader 始终位于左侧标准位置
785
+ top: 50%;
786
+ transform: translateY(-50%);
787
+ margin-right: 0;
788
+ opacity: 0;
789
+ transition: opacity 0.2s ease;
790
+ }
791
+
792
+ // 加载状态:左侧占据全部预留宽度,右侧恢复标准
793
+ &.is-loading {
794
+ padding-left: calc(var(--cp-spacing-lg) + #{$reserved-width});
795
+ padding-right: var(--cp-spacing-lg);
796
+ .cp-button__loader {
797
+ opacity: 1;
798
+ }
799
+ }
800
+ }
801
+
802
+ // ===== Icon-only 模式 (正方形图标按钮) =====
803
+ @include when(icon-only) {
804
+ padding: 0;
805
+ aspect-ratio: 1;
806
+
807
+ // 图标居中
808
+ .cp-icon,
809
+ .cp-loading {
810
+ display: flex;
811
+ align-items: center;
812
+ justify-content: center;
813
+ }
814
+
815
+ // 不同尺寸的正方形大小
816
+ &.cp-button--sm {
817
+ width: var(--cp-button-height-sm);
818
+ height: var(--cp-button-height-sm);
819
+ }
820
+
821
+ &.cp-button--md {
822
+ width: var(--cp-button-height-md);
823
+ height: var(--cp-button-height-md);
824
+ }
825
+
826
+ &.cp-button--lg {
827
+ width: var(--cp-button-height-lg);
828
+ height: var(--cp-button-height-lg);
829
+ }
830
+
831
+ &.is-custom-size {
832
+ width: var(--cp-button-height);
833
+ height: var(--cp-button-height);
834
+ }
835
+ }
836
+
837
+ // ===== 减淡模式 (Dimmed Mode) =====
838
+ // 减淡模式:平常以无颜色的默认形态展示,hover 时显示真正的主题色
839
+ @include when(dimmed) {
840
+ &:not(:hover) {
841
+ // Solid 变体
842
+ &.cp-button--solid:not(.cp-button--default) {
843
+ background: var(--cp-bg-elevated);
844
+ border-color: var(--cp-border);
845
+ color: var(--cp-text-primary);
846
+
847
+ &::after {
848
+ background: var(--cp-border);
849
+ }
850
+ }
851
+
852
+ // Outline 变体
853
+ &.cp-button--outline:not(.cp-button--default) {
854
+ background: transparent;
855
+ border-color: var(--cp-border);
856
+ color: var(--cp-text-secondary);
857
+ }
858
+
859
+ // Semi 变体
860
+ &.cp-button--semi:not(.cp-button--default) {
861
+ background: color-mix(in srgb, var(--cp-border) 30%, transparent);
862
+ border-color: var(--cp-border);
863
+ color: var(--cp-text-secondary);
864
+
865
+ &::after {
866
+ background: var(--cp-border);
867
+ opacity: 0.8;
868
+ }
869
+ }
870
+
871
+ // Ghost 变体
872
+ &.cp-button--ghost:not(.cp-button--default) {
873
+ background: transparent;
874
+ border-color: transparent;
875
+ color: var(--cp-text-secondary);
876
+
877
+ &::after {
878
+ display: none;
879
+ }
880
+ }
881
+
882
+ // Neon 变体
883
+ &.cp-button--neon:not(.cp-button--default) {
884
+ background: transparent;
885
+ border-color: var(--cp-border);
886
+ color: var(--cp-text-secondary);
887
+ box-shadow: 0 0 5px var(--cp-border);
888
+ text-shadow: none;
889
+ animation: none;
890
+
891
+ &::after {
892
+ background: var(--cp-border);
893
+ box-shadow: none;
894
+ }
895
+ }
896
+ }
897
+ }
898
+ }
899
+
900
+ // Vue Transition 样式 - Loader 入场/离场动画 (仅用于非占位模式)
901
+ .cp-loader-enter-active,
902
+ .cp-loader-leave-active {
903
+ transition: width 0.25s ease, margin 0.25s ease, opacity 0.2s ease;
904
+ }
905
+
906
+ .cp-loader-enter-from,
907
+ .cp-loader-leave-to {
908
+ width: 0 !important;
909
+ margin-right: 0 !important;
910
+ opacity: 0 !important;
911
+ }
912
+
913
+
914
+
915
+
916
+
917
+ @keyframes neon-pulse-primary {
918
+
919
+ 0%,
920
+ 100% {
921
+ box-shadow: 0 0 5px var(--cp-color-primary);
922
+ }
923
+
924
+ 50% {
925
+ box-shadow: 0 0 15px var(--cp-color-primary), 0 0 25px var(--cp-color-primary);
926
+ }
927
+ }
928
+
929
+ @keyframes neon-pulse-success {
930
+
931
+ 0%,
932
+ 100% {
933
+ box-shadow: 0 0 5px var(--cp-color-success);
934
+ }
935
+
936
+ 50% {
937
+ box-shadow: 0 0 15px var(--cp-color-success), 0 0 25px var(--cp-color-success);
938
+ }
939
+ }
940
+
941
+ @keyframes neon-pulse-warning {
942
+
943
+ 0%,
944
+ 100% {
945
+ box-shadow: 0 0 5px var(--cp-color-warning);
946
+ }
947
+
948
+ 50% {
949
+ box-shadow: 0 0 15px var(--cp-color-warning), 0 0 25px var(--cp-color-warning);
950
+ }
951
+ }
952
+
953
+ @keyframes neon-pulse-error {
954
+
955
+ 0%,
956
+ 100% {
957
+ box-shadow: 0 0 5px var(--cp-color-error);
958
+ }
959
+
960
+ 50% {
961
+ box-shadow: 0 0 15px var(--cp-color-error), 0 0 25px var(--cp-color-error);
962
+ }
963
+ }
964
+
965
+ @keyframes neon-pulse-info {
966
+
967
+ 0%,
968
+ 100% {
969
+ box-shadow: 0 0 5px var(--cp-color-info);
970
+ }
971
+
972
+ 50% {
973
+ box-shadow: 0 0 15px var(--cp-color-info), 0 0 25px var(--cp-color-info);
974
+ }
975
+ }