@taskon/widget-react 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.
Files changed (37) hide show
  1. package/README.md +1064 -0
  2. package/dist/CommunityTaskList.css +5010 -0
  3. package/dist/EligibilityInfo.css +1966 -0
  4. package/dist/LeaderboardWidget.css +815 -0
  5. package/dist/Quest.css +4584 -0
  6. package/dist/Table.css +389 -0
  7. package/dist/TaskOnProvider.css +163 -0
  8. package/dist/WidgetShell.css +182 -0
  9. package/dist/chunks/CommunityTaskList-CrH6r4Av.js +6886 -0
  10. package/dist/chunks/EligibilityInfo-DesW9-k9.js +24900 -0
  11. package/dist/chunks/LeaderboardWidget-BSGpHKTk.js +1156 -0
  12. package/dist/chunks/Quest-uSIVq78I.js +8581 -0
  13. package/dist/chunks/Table-CWGf2FKV.js +449 -0
  14. package/dist/chunks/TaskOnProvider-QMwxGL44.js +1435 -0
  15. package/dist/chunks/ThemeProvider-Cs8IUVQj.js +1118 -0
  16. package/dist/chunks/WidgetShell-NlOgn1x5.js +1517 -0
  17. package/dist/chunks/common-ja-DWhTaFHb.js +23 -0
  18. package/dist/chunks/common-ko-80ezXsMG.js +23 -0
  19. package/dist/chunks/index-CwMvO_wZ.js +777 -0
  20. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +119 -0
  21. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +119 -0
  22. package/dist/chunks/useToast-BGJhd3BX.js +93 -0
  23. package/dist/chunks/useWidgetLocale-BVcopbZS.js +74 -0
  24. package/dist/chunks/usercenter-ja-DBj_dtuz.js +329 -0
  25. package/dist/chunks/usercenter-ko-DYTkHAld.js +329 -0
  26. package/dist/community-task.d.ts +451 -0
  27. package/dist/community-task.js +9 -0
  28. package/dist/core.d.ts +803 -0
  29. package/dist/core.js +22 -0
  30. package/dist/index.css +3662 -0
  31. package/dist/index.d.ts +1627 -0
  32. package/dist/index.js +7372 -0
  33. package/dist/leaderboard.d.ts +547 -0
  34. package/dist/leaderboard.js +17 -0
  35. package/dist/quest.d.ts +389 -0
  36. package/dist/quest.js +8 -0
  37. package/package.json +97 -0
@@ -0,0 +1,5010 @@
1
+ /**
2
+ * CardSelector 组件样式
3
+ * 完全复刻 taskon-website 的 CmCardRadio 样式
4
+ * 直接使用 dark 模式颜色值,不使用 CSS 变量
5
+ * 使用 taskon- 前缀避免与项目方样式冲突
6
+ */
7
+
8
+ /* 选择器容器 */
9
+ .taskon-card-selector {
10
+ display: flex;
11
+ gap: 10px;
12
+ flex-wrap: wrap;
13
+ }
14
+
15
+ /* 选择器选项 */
16
+ .taskon-card-selector-item {
17
+ flex-shrink: 0;
18
+ padding: 10px 20px;
19
+ border-radius: 6px;
20
+ border: 1px solid rgba(255, 255, 255, 0.1);
21
+ background: #252a2c;
22
+ color: rgba(255, 255, 255, 0.8);
23
+ font-size: 16px;
24
+ line-height: 24px;
25
+ letter-spacing: 0.36px;
26
+ cursor: pointer;
27
+ transition: all 0.2s ease-in-out;
28
+ white-space: nowrap;
29
+ backdrop-filter: blur(10px);
30
+ max-width: 100%;
31
+ text-overflow: ellipsis;
32
+ overflow: hidden;
33
+
34
+ /* 移除默认按钮样式 */
35
+ outline: none;
36
+ user-select: none;
37
+ -webkit-tap-highlight-color: transparent;
38
+ }
39
+
40
+ /* Hover 状态 */
41
+ .taskon-card-selector-item:hover {
42
+ border-color: rgba(255, 255, 255, 0.15);
43
+ }
44
+
45
+ /* 选中状态 */
46
+ .taskon-card-selector-item--selected {
47
+ background: #fff;
48
+ color: #0d0d0d;
49
+ }
50
+
51
+ .taskon-card-selector-item--selected:hover {
52
+ background: #fff;
53
+ }
54
+
55
+ /* Focus 状态(键盘导航) */
56
+ .taskon-card-selector-item:focus-visible {
57
+ outline: 2px solid rgba(255, 255, 255, 0.5);
58
+ outline-offset: 2px;
59
+ }
60
+
61
+ /* 响应式样式(移动端) */
62
+ @media (max-width: 750px) {
63
+ .taskon-card-selector {
64
+ gap: 2.13vw;
65
+ }
66
+
67
+ .taskon-card-selector-item {
68
+ padding: 2.4vw 3.2vw;
69
+ border-radius: 1.07vw;
70
+ font-size: 3.73vw;
71
+ line-height: 4.53vw;
72
+ backdrop-filter: blur(1.33vw);
73
+ }
74
+ }
75
+ /**
76
+ * Input 通用组件样式
77
+ * @description 复刻 Vue 版本 BaseInputPro.vue 样式
78
+ * 使用 taskon-input 命名空间
79
+ */
80
+
81
+ /* ==================== 输入框 ==================== */
82
+ .taskon-input {
83
+ width: 100%;
84
+ height: 40px;
85
+ padding: 0 12px;
86
+ border-radius: 6px;
87
+ border: 1px solid rgba(255, 255, 255, 0.1);
88
+ background: rgba(255, 255, 255, 0.04);
89
+ color: var(--taskon-color-text, #fff);
90
+ font-size: 14px;
91
+ line-height: 40px;
92
+ letter-spacing: 0.04em;
93
+ outline: none;
94
+ transition: border-color 0.2s;
95
+ }
96
+
97
+ .taskon-input:focus {
98
+ border-color: var(--taskon-color-primary, #cbff01);
99
+ }
100
+
101
+ .taskon-input:disabled {
102
+ opacity: 0.6;
103
+ cursor: not-allowed;
104
+ }
105
+
106
+ .taskon-input--error {
107
+ border-color: #eb5757;
108
+ }
109
+
110
+ .taskon-input::placeholder {
111
+ color: var(--taskon-color-text-tertiary, #666);
112
+ font-weight: 400;
113
+ }
114
+
115
+ /* ==================== 包装器(用于 rightSlot 和 error) ==================== */
116
+ .taskon-input-wrapper {
117
+ width: 100%;
118
+ }
119
+
120
+ /* ==================== 容器(包含输入框和右侧插槽) ==================== */
121
+ .taskon-input-container {
122
+ display: flex;
123
+ align-items: center;
124
+ gap: 8px;
125
+ padding-right: 12px;
126
+ border-radius: 6px;
127
+ border: 1px solid rgba(255, 255, 255, 0.1);
128
+ background: rgba(255, 255, 255, 0.04);
129
+ transition: border-color 0.2s;
130
+ }
131
+
132
+ .taskon-input-container:focus-within {
133
+ border-color: var(--taskon-color-primary, #cbff01);
134
+ }
135
+
136
+ .taskon-input-container--error {
137
+ border-color: #eb5757;
138
+ }
139
+
140
+ /* 容器内的输入框样式重置 */
141
+ .taskon-input--in-container {
142
+ flex: 1;
143
+ border: none;
144
+ background: transparent;
145
+ border-radius: 0;
146
+ }
147
+
148
+ .taskon-input--in-container:focus {
149
+ border-color: transparent;
150
+ }
151
+
152
+ /* ==================== 右侧插槽 ==================== */
153
+ .taskon-input-slot {
154
+ flex-shrink: 0;
155
+ display: flex;
156
+ align-items: center;
157
+ }
158
+
159
+ /* MAX 按钮样式(通用样式) */
160
+ .taskon-input-slot button {
161
+ padding: 4px 8px;
162
+ font-size: 12px;
163
+ font-weight: 600;
164
+ color: var(--taskon-color-primary, #cbff01);
165
+ background: transparent;
166
+ border: 1px solid var(--taskon-color-primary, #cbff01);
167
+ border-radius: 4px;
168
+ cursor: pointer;
169
+ transition: all 0.2s;
170
+ }
171
+
172
+ .taskon-input-slot button:hover:not(:disabled) {
173
+ background: rgba(203, 255, 1, 0.1);
174
+ }
175
+
176
+ .taskon-input-slot button:disabled {
177
+ opacity: 0.5;
178
+ cursor: not-allowed;
179
+ }
180
+
181
+ /* ==================== 错误信息 ==================== */
182
+ .taskon-input-error {
183
+ margin: 4px 0 0 0;
184
+ font-size: 12px;
185
+ color: #eb5757;
186
+ line-height: 1.4;
187
+ }
188
+
189
+ /* ==================== 响应式 ==================== */
190
+ @media (max-width: 750px) {
191
+ .taskon-input {
192
+ height: 10.667vw;
193
+ padding: 0 3.2vw;
194
+ font-size: 3.733vw;
195
+ line-height: 10.667vw;
196
+ }
197
+
198
+ .taskon-input-container {
199
+ padding-right: 3.2vw;
200
+ gap: 2.133vw;
201
+ }
202
+
203
+ .taskon-input-slot button {
204
+ padding: 1.067vw 2.133vw;
205
+ font-size: 3.2vw;
206
+ }
207
+
208
+ .taskon-input-error {
209
+ margin-top: 1.067vw;
210
+ font-size: 3.2vw;
211
+ }
212
+ }
213
+ /**
214
+ * BindWalletDialog 组件样式
215
+ * 使用 taskon-bind-wallet-* 命名空间
216
+ * 与 taskon-website 保持一致
217
+ */
218
+
219
+ /* ==================== 容器 ==================== */
220
+ .taskon-bind-wallet-dialog {
221
+ position: relative;
222
+ display: flex;
223
+ flex-direction: column;
224
+ }
225
+
226
+ /* ==================== 标题 ==================== */
227
+ .taskon-bind-wallet-dialog-title {
228
+ margin: 0;
229
+ font-size: 22px;
230
+ font-weight: 700;
231
+ line-height: 28px;
232
+ color: var(--taskon-color-text, #ffffff);
233
+ }
234
+
235
+ /* ==================== 链类型标签 ==================== */
236
+ .taskon-bind-wallet-dialog-chain-label {
237
+ margin-top: 20px;
238
+ font-size: 16px;
239
+ font-weight: 500;
240
+ line-height: 20px;
241
+ color: var(--taskon-color-text, #ffffff);
242
+ }
243
+
244
+ /* ==================== 钱包网格 ==================== */
245
+ .taskon-bind-wallet-dialog-grid {
246
+ margin-top: 10px;
247
+ display: grid;
248
+ grid-template-columns: 1fr 1fr;
249
+ gap: 18px;
250
+ }
251
+
252
+ /* ==================== 钱包项 ==================== */
253
+ .taskon-bind-wallet-item {
254
+ position: relative;
255
+ display: flex;
256
+ align-items: center;
257
+ justify-content: center;
258
+ height: 50px;
259
+ padding: 0 12px;
260
+
261
+ background: transparent;
262
+ border: 1px solid var(--taskon-color-border, rgba(255, 255, 255, 0.15));
263
+ border-radius: 8px;
264
+ cursor: pointer;
265
+ transition: all 0.2s ease;
266
+ }
267
+
268
+ .taskon-bind-wallet-item:hover,
269
+ .taskon-bind-wallet-item:focus {
270
+ background: var(--taskon-color-bg-hover, rgba(255, 255, 255, 0.1));
271
+ }
272
+
273
+ .taskon-bind-wallet-item:active {
274
+ transform: scale(0.98);
275
+ }
276
+
277
+ /* 钱包图标 */
278
+ .taskon-bind-wallet-item-icon {
279
+ display: flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ width: 24px;
283
+ height: 24px;
284
+ flex-shrink: 0;
285
+ }
286
+
287
+ .taskon-bind-wallet-item-icon svg {
288
+ width: 24px;
289
+ height: 24px;
290
+ }
291
+
292
+ /* 钱包名称 */
293
+ .taskon-bind-wallet-item-name {
294
+ margin-left: 10px;
295
+ font-size: 18px;
296
+ font-weight: 600;
297
+ line-height: 20px;
298
+ color: var(--taskon-color-text, #ffffff);
299
+ }
300
+
301
+ /* 已安装标签 */
302
+ .taskon-bind-wallet-item-installed {
303
+ position: absolute;
304
+ right: 0;
305
+ bottom: 0;
306
+ padding: 4px 8px;
307
+ font-size: 10px;
308
+ line-height: 14px;
309
+ color: var(--taskon-color-secondary, #22c55e);
310
+ background: var(--taskon-color-secondary-bg, rgba(34, 197, 94, 0.1));
311
+ border-radius: 8px 0;
312
+ transform-origin: bottom right;
313
+ }
314
+
315
+ /* ==================== 连接中状态 ==================== */
316
+ .taskon-bind-wallet-item--connecting {
317
+ opacity: 0.7;
318
+ cursor: wait;
319
+ }
320
+
321
+ .taskon-bind-wallet-item--connecting:hover,
322
+ .taskon-bind-wallet-item--connecting:focus {
323
+ background: transparent;
324
+ }
325
+
326
+ /* ==================== 禁用状态 ==================== */
327
+ .taskon-bind-wallet-item--disabled {
328
+ opacity: 0.5;
329
+ cursor: not-allowed;
330
+ }
331
+
332
+ .taskon-bind-wallet-item--disabled:hover,
333
+ .taskon-bind-wallet-item--disabled:focus {
334
+ background: transparent;
335
+ }
336
+
337
+ .taskon-bind-wallet-item--disabled:active {
338
+ transform: none;
339
+ }
340
+
341
+ /* 不可用标签 */
342
+ .taskon-bind-wallet-item-unavailable {
343
+ position: absolute;
344
+ right: 0;
345
+ bottom: 0;
346
+ padding: 4px 8px;
347
+ font-size: 10px;
348
+ line-height: 14px;
349
+ color: var(--taskon-color-text-tertiary, #71717a);
350
+ background: var(--taskon-color-bg-secondary, rgba(255, 255, 255, 0.05));
351
+ border-radius: 8px 0;
352
+ }
353
+
354
+ /* 连接中 spinner */
355
+ .taskon-bind-wallet-item-connecting {
356
+ position: absolute;
357
+ right: 8px;
358
+ display: flex;
359
+ align-items: center;
360
+ justify-content: center;
361
+ }
362
+
363
+ .taskon-bind-wallet-spinner {
364
+ width: 16px;
365
+ height: 16px;
366
+ color: var(--taskon-color-primary, #6366f1);
367
+ animation: taskon-bind-wallet-spin 1s linear infinite;
368
+ }
369
+
370
+ @keyframes taskon-bind-wallet-spin {
371
+ from {
372
+ transform: rotate(0deg);
373
+ }
374
+ to {
375
+ transform: rotate(360deg);
376
+ }
377
+ }
378
+
379
+ /* ==================== 提示文字 ==================== */
380
+ .taskon-bind-wallet-dialog-tip {
381
+ margin: 20px 0 0;
382
+ font-size: 14px;
383
+ line-height: 1.5;
384
+ color: var(--taskon-color-text-tertiary, #71717a);
385
+ text-align: center;
386
+ }
387
+
388
+ /* ==================== 响应式 ==================== */
389
+ @media (max-width: 750px) {
390
+ .taskon-bind-wallet-dialog-title {
391
+ font-size: 3.8vw;
392
+ line-height: 4vw;
393
+ }
394
+
395
+ .taskon-bind-wallet-dialog-chain-label {
396
+ margin-top: 4vw;
397
+ font-size: 4vw;
398
+ line-height: 5.6vw;
399
+ }
400
+
401
+ .taskon-bind-wallet-dialog-grid {
402
+ margin-top: 2.667vw;
403
+ grid-template-columns: 1fr;
404
+ gap: 4vw;
405
+ }
406
+
407
+ .taskon-bind-wallet-item {
408
+ height: 12vw;
409
+ }
410
+
411
+ .taskon-bind-wallet-item-icon {
412
+ width: 6.4vw;
413
+ height: 6.4vw;
414
+ }
415
+
416
+ .taskon-bind-wallet-item-icon svg {
417
+ width: 6.4vw;
418
+ height: 6.4vw;
419
+ }
420
+
421
+ .taskon-bind-wallet-item-name {
422
+ margin-left: 2.667vw;
423
+ font-size: 3.733vw;
424
+ line-height: 4.667vw;
425
+ }
426
+
427
+ .taskon-bind-wallet-dialog-tip {
428
+ margin-top: 4vw;
429
+ font-size: 3vw;
430
+ }
431
+ }
432
+
433
+ /* ==================== 连接中遮层 ==================== */
434
+ .taskon-bind-wallet-loading-overlay {
435
+ position: absolute;
436
+ /* 使用负值覆盖 Dialog body 的 padding */
437
+ inset: -24px;
438
+ display: flex;
439
+ flex-direction: column;
440
+ align-items: center;
441
+ justify-content: center;
442
+ background: rgba(255, 255, 255, 0.1);
443
+ backdrop-filter: blur(4px);
444
+ border-radius: 16px;
445
+ }
446
+
447
+ .taskon-bind-wallet-loading-spinner {
448
+ width: 40px;
449
+ height: 40px;
450
+ color: var(--taskon-color-text-secondary, #a1a1aa);
451
+ animation: taskon-bind-wallet-spin 1s linear infinite;
452
+ }
453
+
454
+ .taskon-bind-wallet-loading-text {
455
+ margin: 20px 0 0;
456
+ max-width: 60%;
457
+ font-size: 16px;
458
+ line-height: 20px;
459
+ color: var(--taskon-color-text-secondary, #a1a1aa);
460
+ text-align: center;
461
+ }
462
+
463
+ @media (max-width: 750px) {
464
+ .taskon-bind-wallet-loading-overlay {
465
+ inset: -20px;
466
+ border-radius: 12px;
467
+ }
468
+
469
+ .taskon-bind-wallet-loading-spinner {
470
+ width: 8vw;
471
+ height: 8vw;
472
+ }
473
+
474
+ .taskon-bind-wallet-loading-text {
475
+ margin-top: 4vw;
476
+ font-size: 3.5vw;
477
+ line-height: 5vw;
478
+ }
479
+ }
480
+ /**
481
+ * CardDescExpress 组件样式
482
+ * @module components/CardDescExpress
483
+ */
484
+
485
+ .taskon-card-desc-rich {
486
+ max-height: 60px;
487
+ overflow: hidden;
488
+ font-size: 14px;
489
+ line-height: 21px;
490
+ color: rgb(255 255 255 / 60%); /* --color-light */
491
+ white-space: pre-wrap;
492
+ word-break: break-word;
493
+ overflow-wrap: break-word;
494
+ }
495
+
496
+ /* 处理富文本中的常见元素 */
497
+ .taskon-card-desc-rich p {
498
+ margin: 0;
499
+ }
500
+
501
+ .taskon-card-desc-rich a {
502
+ color: #cbff01; /* --secondary-100 */
503
+ text-decoration: none;
504
+ }
505
+
506
+ .taskon-card-desc-rich a:hover {
507
+ text-decoration: underline;
508
+ }
509
+
510
+ .taskon-card-desc-rich strong,
511
+ .taskon-card-desc-rich b {
512
+ font-weight: 600;
513
+ }
514
+
515
+ .taskon-card-desc-rich em,
516
+ .taskon-card-desc-rich i {
517
+ font-style: italic;
518
+ }
519
+
520
+ .taskon-card-desc-rich ul,
521
+ .taskon-card-desc-rich ol {
522
+ margin: 0;
523
+ padding-left: 1.5em;
524
+ }
525
+
526
+ .taskon-card-desc-rich pre {
527
+ text-wrap: initial;
528
+ }
529
+
530
+ /* ========== 响应式样式(移动端) ========== */
531
+ @media (max-width: 750px) {
532
+ .taskon-card-desc-rich {
533
+ max-height: 18vw;
534
+ font-size: 3.733vw;
535
+ line-height: normal;
536
+ }
537
+ }
538
+ /**
539
+ * ClaimButton 组件样式
540
+ * 复刻原版 ClaimButton.vue 样式
541
+ * 使用 Widget 命名空间扁平化方案
542
+ */
543
+
544
+ /* Claim 按钮基础样式 */
545
+ .taskon-community-task-claim {
546
+ min-width: 77px;
547
+ height: 34px;
548
+ display: flex;
549
+ align-items: center;
550
+ justify-content: center;
551
+ padding: 0 10px;
552
+ text-align: center;
553
+ border-radius: 6px;
554
+ border: 1px solid rgb(255 255 255 / 100%);
555
+ background: transparent;
556
+ color: rgb(255 255 255 / 100%);
557
+ font-size: 14px;
558
+ font-weight: 500;
559
+ line-height: 18px;
560
+ cursor: pointer;
561
+ transition: opacity 0.2s ease;
562
+ white-space: nowrap;
563
+ }
564
+
565
+ .taskon-community-task-claim:hover:not(:disabled) {
566
+ opacity: 0.8;
567
+ }
568
+
569
+ /* 深色样式(弹窗内使用) */
570
+ .taskon-community-task-claim--dark {
571
+ height: 40px;
572
+ background: rgb(255 255 255 / 100%);
573
+ color: rgb(0 0 0 / 100%);
574
+ font-weight: 600;
575
+ border: none;
576
+ }
577
+
578
+ /* 禁用状态 */
579
+ .taskon-community-task-claim--disabled {
580
+ opacity: 0.2;
581
+ cursor: not-allowed;
582
+ }
583
+
584
+ /* 加载状态 */
585
+ .taskon-community-task-claim--loading {
586
+ background: rgb(255 255 255 / 20%);
587
+ border: none;
588
+ cursor: wait;
589
+ }
590
+
591
+ .taskon-community-task-claim--loading:hover {
592
+ opacity: 1;
593
+ }
594
+
595
+ /* 加载动画容器 */
596
+ .taskon-community-task-claim-loading {
597
+ display: flex;
598
+ align-items: center;
599
+ justify-content: center;
600
+ }
601
+
602
+ /* 加载动画 spinner */
603
+ .taskon-community-task-claim-spinner {
604
+ width: 22px;
605
+ height: 22px;
606
+ animation: taskon-claim-spin 1s linear infinite;
607
+ }
608
+
609
+ /* Mini 按钮样式(Unlimited 任务已有积分时使用)*/
610
+ /* 复刻 Vue 版本 ClaimButton.vue 中的 .mini-btn 样式 */
611
+ .taskon-community-task-claim-mini {
612
+ height: 20px;
613
+ padding: 0 4px;
614
+ display: flex;
615
+ align-items: center;
616
+ justify-content: center;
617
+ border-radius: 4px;
618
+ border: none;
619
+ background: rgb(255 255 255 / 10%);
620
+ color: rgb(255 255 255 / 100%);
621
+ font-size: 12px;
622
+ font-weight: 500;
623
+ line-height: 16px;
624
+ cursor: pointer;
625
+ transition: opacity 0.2s ease;
626
+ white-space: nowrap;
627
+ }
628
+
629
+ .taskon-community-task-claim-mini:hover:not(:disabled) {
630
+ opacity: 0.8;
631
+ }
632
+
633
+ /* Mini 按钮禁用状态 */
634
+ .taskon-community-task-claim-mini--disabled {
635
+ opacity: 0.4;
636
+ cursor: not-allowed;
637
+ }
638
+
639
+ /* Mini 按钮加载状态 */
640
+ .taskon-community-task-claim-mini--loading {
641
+ cursor: wait;
642
+ }
643
+
644
+ .taskon-community-task-claim-mini--loading:hover {
645
+ opacity: 1;
646
+ }
647
+
648
+ /* Mini 按钮加载动画容器 */
649
+ .taskon-community-task-claim-mini-loading {
650
+ display: flex;
651
+ align-items: center;
652
+ justify-content: center;
653
+ }
654
+
655
+ /* Mini 按钮 spinner */
656
+ .taskon-community-task-claim-mini-spinner {
657
+ width: 14px;
658
+ height: 14px;
659
+ animation: taskon-claim-spin 1s linear infinite;
660
+ }
661
+
662
+ @keyframes taskon-claim-spin {
663
+ from {
664
+ transform: rotate(0deg);
665
+ }
666
+ to {
667
+ transform: rotate(360deg);
668
+ }
669
+ }
670
+
671
+ /* 响应式 - 移动端 */
672
+ @media (max-width: 750px) {
673
+ .taskon-community-task-claim {
674
+ min-width: 13.333vw;
675
+ height: 9.333vw;
676
+ padding: 0 2.667vw;
677
+ font-size: 3.733vw;
678
+ line-height: 4.667vw;
679
+ }
680
+
681
+ .taskon-community-task-claim--dark {
682
+ height: 9.333vw;
683
+ }
684
+
685
+ .taskon-community-task-claim-spinner {
686
+ width: 5.333vw;
687
+ height: 5.333vw;
688
+ }
689
+
690
+ /* Mini 按钮响应式 */
691
+ .taskon-community-task-claim-mini {
692
+ height: 6.933vw;
693
+ padding: 0 1.6vw;
694
+ font-size: 3.2vw;
695
+ line-height: 3.733vw;
696
+ }
697
+
698
+ .taskon-community-task-claim-mini-spinner {
699
+ width: 3.733vw;
700
+ height: 3.733vw;
701
+ }
702
+ }
703
+ /**
704
+ * ClaimRetry 组件样式
705
+ * 复刻原版 ClaimRetry.vue 的样式
706
+ */
707
+
708
+ /* 冷却倒计时容器 */
709
+ .taskon-community-task-retry {
710
+ display: flex;
711
+ align-items: center;
712
+ justify-content: center;
713
+ min-width: 77px;
714
+ height: 34px;
715
+ padding: 0 12px;
716
+ border-radius: 6px;
717
+ border: 1px solid rgba(255, 255, 255, 0.5);
718
+ color: rgba(255, 255, 255, 0.5);
719
+ font-size: 14px;
720
+ font-weight: 500;
721
+ line-height: 18px;
722
+ cursor: not-allowed;
723
+ white-space: nowrap;
724
+ }
725
+
726
+ /* ========== 响应式样式(移动端) ========== */
727
+ @media (max-width: 750px) {
728
+ .taskon-community-task-retry {
729
+ min-width: 20vw;
730
+ height: 9.33vw;
731
+ padding: 0 3.2vw;
732
+ border-radius: 1.6vw;
733
+ font-size: 3.73vw;
734
+ line-height: 4.67vw;
735
+ }
736
+ }
737
+ /**
738
+ * DoneCountdown 组件样式
739
+ * 复刻原版 DoneCountdown.vue 的样式
740
+ */
741
+
742
+ /* 完成倒计时容器 - 复刻原版 var(--color-dark) */
743
+ .taskon-community-task-done-countdown {
744
+ margin-top: 10px;
745
+ color: rgba(255, 255, 255, 0.4);
746
+ font-size: 14px;
747
+ line-height: 18px;
748
+ }
749
+
750
+ /* 倒计时行 */
751
+ .taskon-community-task-done-countdown-timer {
752
+ margin-top: 4px;
753
+ }
754
+
755
+ /* 倒计时数字 - 复刻原版 var(--color-lighter) */
756
+ .taskon-community-task-done-countdown-time {
757
+ margin-left: 4px;
758
+ color: rgba(255, 255, 255, 0.8);
759
+ }
760
+
761
+ /* ========== 响应式样式(移动端) ========== */
762
+ @media (max-width: 750px) {
763
+ .taskon-community-task-done-countdown {
764
+ margin-top: 2.67vw;
765
+ font-size: 3.73vw;
766
+ line-height: 4.8vw;
767
+ }
768
+
769
+ .taskon-community-task-done-countdown-timer {
770
+ margin-top: 1.07vw;
771
+ }
772
+
773
+ .taskon-community-task-done-countdown-time {
774
+ margin-left: 1.07vw;
775
+ }
776
+ }
777
+ /**
778
+ * ValidationTimeTip 组件样式
779
+ * 复刻原版 ValidationTimeTip.vue 的样式
780
+ */
781
+
782
+ .taskon-community-validation-tip {
783
+ display: flex;
784
+ align-items: flex-start;
785
+ margin-top: 10px;
786
+ margin-bottom: 6px;
787
+ gap: 4px;
788
+ }
789
+
790
+ .taskon-community-validation-tip-icon {
791
+ width: 14px;
792
+ height: 14px;
793
+ flex-shrink: 0;
794
+ }
795
+
796
+ .taskon-community-validation-tip-text {
797
+ margin: 0;
798
+ /* 复刻原版 --text-info-warning-60 颜色: rgb(255 212 101 / 60%) */
799
+ color: var(--taskon-color-warning-60, rgba(255, 212, 101, 0.6));
800
+ font-size: 12px;
801
+ font-style: normal;
802
+ font-weight: 400;
803
+ line-height: normal;
804
+ }
805
+
806
+ /* 移动端适配 */
807
+ @media (max-width: 750px) {
808
+ .taskon-community-validation-tip {
809
+ margin-top: 2.667vw;
810
+ margin-bottom: 2.667vw;
811
+ }
812
+
813
+ .taskon-community-validation-tip-icon {
814
+ width: 2.933vw;
815
+ height: 2.933vw;
816
+ }
817
+
818
+ .taskon-community-validation-tip-text {
819
+ font-size: 3.2vw;
820
+ }
821
+ }
822
+ /**
823
+ * CheckProgressTip 组件样式
824
+ * 复刻原版 CheckProgressTip.vue 的样式
825
+ */
826
+
827
+ /* 进度提示容器 */
828
+ .taskon-community-task-progress-tip {
829
+ margin-top: 8px;
830
+ font-size: 12px;
831
+ line-height: 16px;
832
+ color: #f5a623; /* warn color */
833
+ }
834
+
835
+ /* 可点击的社区链接 */
836
+ .taskon-community-task-progress-tip-link {
837
+ text-decoration: underline;
838
+ cursor: pointer;
839
+ color: #f5a623;
840
+ }
841
+
842
+ .taskon-community-task-progress-tip-link:hover {
843
+ opacity: 0.8;
844
+ }
845
+
846
+ /* 不可点击的社区名称 */
847
+ .taskon-community-task-progress-tip-name {
848
+ font-weight: 500;
849
+ }
850
+
851
+ /* ========== 响应式样式(移动端) ========== */
852
+ @media (max-width: 750px) {
853
+ .taskon-community-task-progress-tip {
854
+ margin-top: 2.13vw;
855
+ font-size: 3.2vw;
856
+ line-height: 4.27vw;
857
+ }
858
+ }
859
+ /**
860
+ * ProgressUi 组件样式
861
+ * 复刻 Vue 版本 ProgressUi.vue 的样式
862
+ */
863
+
864
+ .taskon-community-task-progress-ui {
865
+ display: flex;
866
+ align-items: center;
867
+ width: 200px;
868
+ height: 4px;
869
+ max-width: 100%;
870
+ background: rgba(255, 255, 255, 0.1);
871
+ border-radius: 30px;
872
+ }
873
+
874
+ .taskon-community-task-progress-ui__bar {
875
+ height: 100%;
876
+ background: linear-gradient(
877
+ 89.87deg,
878
+ var(--taskon-color-secondary, #00ffa3) 0.13%,
879
+ var(--taskon-color-primary, #cbff01) 99.92%
880
+ );
881
+ border-radius: 30px;
882
+ }
883
+
884
+ /* ==================== 响应式 ==================== */
885
+ @media (max-width: 750px) {
886
+ .taskon-community-task-progress-ui {
887
+ width: 100%;
888
+ height: 1.067vw;
889
+ border-radius: 4vw;
890
+ }
891
+
892
+ .taskon-community-task-progress-ui__bar {
893
+ border-radius: 4vw;
894
+ }
895
+ }
896
+ /**
897
+ * BaseTask 组件样式
898
+ * 复刻原版 CmBaseTask.vue 的样式
899
+ * 使用 Widget 命名空间扁平化方案
900
+ * 所有类名使用 .taskon-community-* 前缀,避免跨 Widget 冲突
901
+ * 直接使用 dark 模式颜色值
902
+ */
903
+
904
+ /* 卡片外层容器 */
905
+ .taskon-community-task-wrap {
906
+ height: 100%;
907
+ }
908
+
909
+ /* 卡片主体 */
910
+ .taskon-community-task {
911
+ position: relative;
912
+ display: flex;
913
+ flex-direction: column;
914
+ padding: 20px;
915
+ border-radius: 10px;
916
+ border: 1px solid rgb(255 255 255 / 4%);
917
+ background: #1f1f1f;
918
+ min-height: 230px;
919
+ height: 100%;
920
+ cursor: pointer;
921
+ overflow: hidden;
922
+ transition: all 0.2s ease-in-out;
923
+ }
924
+
925
+ /* 完成状态卡片样式 */
926
+ .taskon-community-task--won {
927
+ border-color: rgb(203 255 1 / 20%);
928
+ background: rgb(203 255 1 / 4%);
929
+ min-height: 184px;
930
+ }
931
+
932
+ /* 禁用状态 */
933
+ .taskon-community-task--disabled {
934
+ cursor: not-allowed;
935
+ opacity: 0.6;
936
+ }
937
+
938
+ /* 禁用遮罩 */
939
+ .taskon-community-task-disabled-mask {
940
+ position: absolute;
941
+ inset: 0;
942
+ background: transparent;
943
+ z-index: 2;
944
+ }
945
+
946
+ /* 周期标签 */
947
+ .taskon-community-task-badge {
948
+ position: absolute;
949
+ top: 10px;
950
+ right: 10px;
951
+ padding: 2px 6px;
952
+ border-radius: 4px;
953
+ background: rgb(255 255 255 / 4%);
954
+ color: rgb(255 255 255 / 60%);
955
+ font-size: 13px;
956
+ line-height: 16px;
957
+ z-index: 1;
958
+ }
959
+
960
+ /* 内容容器 - 占据剩余空间 */
961
+ .taskon-community-task-container {
962
+ flex: 1;
963
+ }
964
+
965
+ /* 任务标题 */
966
+ .taskon-community-task-title {
967
+ margin: 0;
968
+ padding-right: 50px;
969
+ font-size: 16px;
970
+ font-weight: 600;
971
+ line-height: 20px;
972
+ color: rgba(255, 255, 255, 0.95);
973
+ word-break: break-word;
974
+ }
975
+
976
+ /* 任务标题 - 链接样式 */
977
+ .taskon-community-task-title--link {
978
+ display: block;
979
+ text-decoration: none;
980
+ color: var(--taskon-color-primary, #6366f1);
981
+ transition: color 0.2s ease;
982
+ }
983
+
984
+ .taskon-community-task-title--link:hover {
985
+ color: var(--taskon-color-primary-hover, #818cf8);
986
+ text-decoration: underline;
987
+ }
988
+
989
+ /* 有效时间 */
990
+ .taskon-community-task-time {
991
+ margin-top: 10px;
992
+ font-size: 14px;
993
+ line-height: 16px;
994
+ }
995
+
996
+ .taskon-community-task-time-label {
997
+ color: rgba(255, 255, 255, 0.5);
998
+ }
999
+
1000
+ .taskon-community-task-time-value {
1001
+ margin-left: 4px;
1002
+ color: rgba(255, 255, 255, 0.8);
1003
+ }
1004
+
1005
+ /* Action 按钮区域 */
1006
+ .taskon-community-task-action-wrap {
1007
+ margin-top: 10px;
1008
+ }
1009
+
1010
+ /* Action 按钮 - 复刻原版 ActionButton.vue */
1011
+ .taskon-community-task-action {
1012
+ width: 100%;
1013
+ height: 34px;
1014
+ padding: 0 16px;
1015
+ display: flex;
1016
+ align-items: center;
1017
+ justify-content: center;
1018
+ border-radius: 6px;
1019
+ border: none;
1020
+ background: rgb(203 255 1 / 12%);
1021
+ color: #cbff01;
1022
+ font-size: 14px;
1023
+ font-weight: 500;
1024
+ line-height: 34px;
1025
+ cursor: pointer;
1026
+ transition: all 0.2s ease-in-out;
1027
+ white-space: nowrap;
1028
+ overflow: hidden;
1029
+ text-overflow: ellipsis;
1030
+ }
1031
+
1032
+ .taskon-community-task-action:hover {
1033
+ background: #cbff01;
1034
+ color: #0d0d0d;
1035
+ }
1036
+
1037
+ .taskon-community-task-action:active {
1038
+ transform: scale(0.98);
1039
+ }
1040
+
1041
+ /* 底部区域 */
1042
+ .taskon-community-task-footer {
1043
+ margin-top: 10px;
1044
+ }
1045
+
1046
+ /* Claim 按钮区域 */
1047
+ .taskon-community-task-claim-wrap {
1048
+ display: flex;
1049
+ align-items: center;
1050
+ justify-content: flex-end;
1051
+ }
1052
+
1053
+ /* Claim 按钮 - 复刻原版 ClaimButton.vue */
1054
+ .taskon-community-task-claim {
1055
+ min-width: 77px;
1056
+ height: 34px;
1057
+ display: flex;
1058
+ align-items: center;
1059
+ justify-content: center;
1060
+ padding: 0 10px;
1061
+ border-radius: 6px;
1062
+ border: 1px solid rgba(255, 255, 255, 0.9);
1063
+ background: transparent;
1064
+ color: rgba(255, 255, 255, 0.9);
1065
+ font-size: 14px;
1066
+ font-weight: 500;
1067
+ line-height: 18px;
1068
+ cursor: pointer;
1069
+ transition: all 0.2s ease-in-out;
1070
+ }
1071
+
1072
+ .taskon-community-task-claim:hover:not(:disabled) {
1073
+ opacity: 0.8;
1074
+ }
1075
+
1076
+ .taskon-community-task-claim:active:not(:disabled) {
1077
+ transform: scale(0.98);
1078
+ }
1079
+
1080
+ .taskon-community-task-claim--loading {
1081
+ background: rgba(255, 255, 255, 0.1);
1082
+ border: none;
1083
+ cursor: not-allowed;
1084
+ }
1085
+
1086
+ .taskon-community-task-claim:disabled {
1087
+ opacity: 0.2;
1088
+ cursor: not-allowed;
1089
+ }
1090
+
1091
+ /* 冷却文本 */
1092
+ .taskon-community-task-cooldown {
1093
+ color: rgba(255, 255, 255, 0.6);
1094
+ font-size: 14px;
1095
+ line-height: 18px;
1096
+ text-align: right;
1097
+ }
1098
+
1099
+ /* ClaimRow - 未完成状态底部:奖励信息 + Claim 按钮 */
1100
+ .taskon-community-task-claim-row {
1101
+ display: flex;
1102
+ align-items: center;
1103
+ justify-content: space-between;
1104
+ }
1105
+
1106
+ /* Unlimited 任务已有积分时的 refresh 样式 */
1107
+ /* 复刻 Vue 版本 ClaimRow.vue 中的 .refresh-bg 样式 */
1108
+ .taskon-community-task-claim-row--refresh {
1109
+ background: rgb(255 255 255 / 4%);
1110
+ padding-right: 10px;
1111
+ border-radius: 6px;
1112
+ }
1113
+
1114
+ /* refresh 模式下左侧奖励信息样式 */
1115
+ .taskon-community-task-claim-row--refresh .taskon-community-task-reward {
1116
+ background: transparent;
1117
+ }
1118
+
1119
+ /* 奖励信息(ClaimRow 左侧) */
1120
+ .taskon-community-task-reward {
1121
+ max-width: 100%;
1122
+ height: 34px;
1123
+ padding: 0 10px;
1124
+ display: flex;
1125
+ align-items: center;
1126
+ border-radius: 6px;
1127
+ background: rgb(255 255 255 / 4%);
1128
+ font-size: 14px;
1129
+ font-weight: 600;
1130
+ line-height: 18px;
1131
+ }
1132
+
1133
+ .taskon-community-task-reward-icon {
1134
+ width: 18px;
1135
+ height: 18px;
1136
+ margin-right: 4px;
1137
+ object-fit: contain;
1138
+ }
1139
+
1140
+ .taskon-community-task-reward-amount {
1141
+ color: #cbff01; /* secondary-100 */
1142
+ }
1143
+
1144
+ .taskon-community-task-reward-name {
1145
+ margin-left: 4px;
1146
+ overflow: hidden;
1147
+ text-overflow: ellipsis;
1148
+ white-space: nowrap;
1149
+ color: rgba(255, 255, 255, 0.9);
1150
+ }
1151
+
1152
+ /* Token 链图标 */
1153
+ .taskon-community-task-reward-chain {
1154
+ display: inline-block;
1155
+ width: 12px;
1156
+ height: 12px;
1157
+ margin: 0 2px 0 4px;
1158
+ object-fit: cover;
1159
+ }
1160
+
1161
+ /* Token 奖励容器(需要 relative 定位) */
1162
+ .taskon-community-task-reward--token {
1163
+ position: relative;
1164
+ }
1165
+
1166
+ /* Token 进度条(底部绝对定位,翻转显示) */
1167
+ .taskon-community-task-reward-progress {
1168
+ position: absolute;
1169
+ left: 0;
1170
+ bottom: 0;
1171
+ width: 100%;
1172
+ transform: rotate(180deg);
1173
+ }
1174
+
1175
+ /* 完成状态奖励展示 */
1176
+ .taskon-community-task-won {
1177
+ display: flex;
1178
+ align-items: center;
1179
+ font-size: 16px;
1180
+ line-height: 20px;
1181
+ min-height: 27px;
1182
+ }
1183
+
1184
+ /* IconCheckedTask 图标 - 复刻原版 won__checked */
1185
+ .taskon-community-task-won-checked {
1186
+ width: 20px;
1187
+ height: 20px;
1188
+ color: #cbff01; /* primary-100 */
1189
+ flex-shrink: 0;
1190
+ }
1191
+
1192
+ /* 非周期任务完成状态 - ✓ 数量 名称 Won */
1193
+ .taskon-community-task-won-check {
1194
+ width: 20px;
1195
+ height: 20px;
1196
+ color: #cbff01;
1197
+ font-weight: bold;
1198
+ }
1199
+
1200
+ .taskon-community-task-won-amount {
1201
+ margin-left: 6px;
1202
+ color: #cbff01;
1203
+ font-weight: 700;
1204
+ }
1205
+
1206
+ /* 名称 + pointIcon 的容器 - 复刻原版 won__text-wrapper */
1207
+ .taskon-community-task-won-text-wrapper {
1208
+ display: flex;
1209
+ align-items: center;
1210
+ gap: 4px;
1211
+ }
1212
+
1213
+ .taskon-community-task-won-name {
1214
+ margin-left: 4px;
1215
+ font-weight: 600;
1216
+ color: rgba(255, 255, 255, 0.9);
1217
+ }
1218
+
1219
+ /* pointIcon - 复刻原版 won__icon */
1220
+ .taskon-community-task-won-point-icon {
1221
+ width: 12px;
1222
+ height: 12px;
1223
+ }
1224
+
1225
+ /* Bling 闪烁图标 - 复刻原版 won__bling */
1226
+ .taskon-community-task-won-bling {
1227
+ margin-left: 4px;
1228
+ width: 27px;
1229
+ height: 27px;
1230
+ flex-shrink: 0;
1231
+ }
1232
+
1233
+ .taskon-community-task-won-icon {
1234
+ width: 12px;
1235
+ height: 12px;
1236
+ margin-left: 4px;
1237
+ }
1238
+
1239
+ .taskon-community-task-won-status {
1240
+ margin-left: auto;
1241
+ color: #27ae60;
1242
+ font-size: 14px;
1243
+ font-weight: 600;
1244
+ line-height: 18px;
1245
+ }
1246
+
1247
+ /* 周期任务完成状态 - 单次奖励 + 累计奖励 */
1248
+ .taskon-community-task-won--periodic {
1249
+ gap: 0;
1250
+ }
1251
+
1252
+ .taskon-community-task-won-single {
1253
+ font-weight: 600;
1254
+ color: rgba(255, 255, 255, 0.9);
1255
+ }
1256
+
1257
+ .taskon-community-task-won-label {
1258
+ margin-left: 4px;
1259
+ color: rgba(255, 255, 255, 0.6);
1260
+ }
1261
+
1262
+ .taskon-community-task-won-total {
1263
+ margin-left: 6px;
1264
+ color: #cbff01;
1265
+ font-weight: 700;
1266
+ }
1267
+
1268
+ .taskon-community-task-won-earned {
1269
+ margin-left: 4px;
1270
+ font-weight: 600;
1271
+ overflow: hidden;
1272
+ text-overflow: ellipsis;
1273
+ white-space: nowrap;
1274
+ color: rgba(255, 255, 255, 0.9);
1275
+ }
1276
+
1277
+ /* 兼容旧样式 */
1278
+ .taskon-community-task-won-text {
1279
+ color: rgba(255, 255, 255, 0.6);
1280
+ font-size: 14px;
1281
+ line-height: 18px;
1282
+ }
1283
+
1284
+ .taskon-community-task-won-reward {
1285
+ display: flex;
1286
+ align-items: center;
1287
+ gap: 4px;
1288
+ }
1289
+
1290
+ /* ========== 审核状态样式 ========== */
1291
+ /* 复刻原版 CmBaseTask.vue 的 won__status 样式 */
1292
+
1293
+ /* 审核状态基础样式 */
1294
+ .taskon-community-task-review-status {
1295
+ display: flex;
1296
+ align-items: center;
1297
+ justify-content: center;
1298
+ min-width: 77px;
1299
+ height: 34px;
1300
+ padding: 0 10px;
1301
+ border-radius: 6px;
1302
+ font-size: 14px;
1303
+ font-weight: 500;
1304
+ line-height: 18px;
1305
+ }
1306
+
1307
+ /* 审核失败:红色样式 - 复刻原版 #eb5757 */
1308
+ .taskon-community-task-review-status--failed {
1309
+ background: rgba(235, 87, 87, 0.1);
1310
+ color: #eb5757;
1311
+ }
1312
+
1313
+ /* 审核中:紫色样式 - 复刻原版 #9b51e0 */
1314
+ .taskon-community-task-review-status--review {
1315
+ background: rgba(155, 81, 224, 0.1);
1316
+ color: #9b51e0;
1317
+ }
1318
+
1319
+ /* ========== 响应式样式(移动端) ========== */
1320
+ @media (max-width: 750px) {
1321
+ .taskon-community-task {
1322
+ padding: 6vw;
1323
+ min-height: 60vw;
1324
+ border-radius: 2.67vw;
1325
+ }
1326
+
1327
+ .taskon-community-task--won {
1328
+ min-height: 46vw;
1329
+ }
1330
+
1331
+ .taskon-community-task-badge {
1332
+ top: 2.67vw;
1333
+ right: 2.67vw;
1334
+ padding: 0.53vw 1.87vw;
1335
+ font-size: 3.47vw;
1336
+ line-height: 4.4vw;
1337
+ border-radius: 1.07vw;
1338
+ }
1339
+
1340
+ .taskon-community-task-title {
1341
+ font-size: 4.8vw;
1342
+ line-height: 6vw;
1343
+ padding-right: 13.33vw;
1344
+ }
1345
+
1346
+ .taskon-community-task-time {
1347
+ margin-top: 2.67vw;
1348
+ font-size: 3.73vw;
1349
+ line-height: 4.67vw;
1350
+ }
1351
+
1352
+ .taskon-community-task-time-value {
1353
+ margin-left: 1.07vw;
1354
+ }
1355
+
1356
+ .taskon-community-task-action-wrap {
1357
+ margin-top: 2.67vw;
1358
+ }
1359
+
1360
+ .taskon-community-task-action {
1361
+ height: 9.33vw;
1362
+ padding: 0 4vw;
1363
+ border-radius: 1.6vw;
1364
+ font-size: 3.73vw;
1365
+ line-height: 9.33vw;
1366
+ }
1367
+
1368
+ .taskon-community-task-footer {
1369
+ margin-top: 2.67vw;
1370
+ }
1371
+
1372
+ .taskon-community-task-claim {
1373
+ min-width: 13.33vw;
1374
+ height: 9.33vw;
1375
+ padding: 0 2.67vw;
1376
+ border-radius: 1.6vw;
1377
+ font-size: 3.73vw;
1378
+ line-height: 4.67vw;
1379
+ }
1380
+
1381
+ .taskon-community-task-cooldown {
1382
+ font-size: 3.73vw;
1383
+ line-height: 4.67vw;
1384
+ }
1385
+
1386
+ .taskon-community-task-reward {
1387
+ height: 9.33vw;
1388
+ padding: 0 2.67vw;
1389
+ font-size: 3.73vw;
1390
+ line-height: 4.67vw;
1391
+ }
1392
+
1393
+ .taskon-community-task-reward-icon {
1394
+ width: 4.67vw;
1395
+ height: 4.67vw;
1396
+ margin-right: 0.8vw;
1397
+ }
1398
+
1399
+ .taskon-community-task-reward-name {
1400
+ margin-left: 0.8vw;
1401
+ }
1402
+
1403
+ .taskon-community-task-won {
1404
+ gap: 2.13vw;
1405
+ }
1406
+
1407
+ .taskon-community-task-won-checked {
1408
+ width: 5.33vw;
1409
+ height: 5.33vw;
1410
+ }
1411
+
1412
+ .taskon-community-task-won-text {
1413
+ font-size: 3.73vw;
1414
+ line-height: 4.67vw;
1415
+ }
1416
+
1417
+ .taskon-community-task-won-amount {
1418
+ margin-left: 1.6vw;
1419
+ font-size: 4.27vw;
1420
+ line-height: 5.33vw;
1421
+ }
1422
+
1423
+ .taskon-community-task-won-text-wrapper {
1424
+ gap: 1.07vw;
1425
+ }
1426
+
1427
+ .taskon-community-task-won-name {
1428
+ margin-left: 1.07vw;
1429
+ font-size: 4.27vw;
1430
+ line-height: 5.33vw;
1431
+ }
1432
+
1433
+ .taskon-community-task-won-point-icon {
1434
+ width: 3.2vw;
1435
+ height: 3.2vw;
1436
+ }
1437
+
1438
+ .taskon-community-task-won-bling {
1439
+ margin-left: 1.07vw;
1440
+ width: 7.2vw;
1441
+ height: 7.2vw;
1442
+ }
1443
+
1444
+ .taskon-community-task-won-reward {
1445
+ gap: 1.07vw;
1446
+ }
1447
+
1448
+ .taskon-community-task-won-icon {
1449
+ width: 5.33vw;
1450
+ height: 5.33vw;
1451
+ }
1452
+
1453
+ /* 审核状态移动端样式 */
1454
+ .taskon-community-task-review-status {
1455
+ min-width: 13.33vw;
1456
+ height: 9.33vw;
1457
+ padding: 0 2.67vw;
1458
+ border-radius: 1.6vw;
1459
+ font-size: 3.73vw;
1460
+ line-height: 4.67vw;
1461
+ }
1462
+ }
1463
+
1464
+ /* ========== 登录遮层(复刻原版 login-mask) ========== */
1465
+ .taskon-community-task-login-mask {
1466
+ position: absolute;
1467
+ inset: 0;
1468
+ background: transparent;
1469
+ cursor: pointer;
1470
+ z-index: 3;
1471
+ }
1472
+ /**
1473
+ * CardField 组件样式
1474
+ * 复刻原版 CardField.vue 的样式
1475
+ */
1476
+
1477
+ .taskon-community-task-field {
1478
+ margin-top: 10px;
1479
+ font-size: 14px;
1480
+ line-height: 18px;
1481
+ display: flex;
1482
+ align-items: center;
1483
+ gap: 4px;
1484
+ word-break: break-word;
1485
+ overflow-wrap: break-word;
1486
+ }
1487
+
1488
+ .taskon-community-task-field-label {
1489
+ color: rgb(255 255 255 / 40%); /* --color-dark */
1490
+ white-space: pre-wrap;
1491
+ word-break: break-word;
1492
+ overflow-wrap: break-word;
1493
+ }
1494
+
1495
+ .taskon-community-task-field-link {
1496
+ color: rgb(255 255 255 / 80%); /* --color-lighter,与 value 颜色一致 */
1497
+ text-decoration: none;
1498
+ cursor: pointer;
1499
+ word-break: break-all;
1500
+ overflow-wrap: break-word;
1501
+ }
1502
+
1503
+ .taskon-community-task-field-link:hover {
1504
+ text-decoration: underline;
1505
+ }
1506
+
1507
+ .taskon-community-task-field-value {
1508
+ color: rgb(255 255 255 / 80%); /* --color-lighter */
1509
+ word-break: break-word;
1510
+ overflow-wrap: break-word;
1511
+ }
1512
+
1513
+ /* ========== 复制按钮样式 ========== */
1514
+ .taskon-community-task-field-copy {
1515
+ display: inline-flex;
1516
+ align-items: center;
1517
+ justify-content: center;
1518
+ padding: 0;
1519
+ border: none;
1520
+ background: transparent;
1521
+ cursor: pointer;
1522
+ transition: opacity 0.2s;
1523
+ flex-shrink: 0; /* 防止按钮被压缩 */
1524
+ }
1525
+
1526
+ .taskon-community-task-field-copy:hover {
1527
+ opacity: 0.7;
1528
+ }
1529
+
1530
+ .taskon-community-task-field-copy-icon {
1531
+ width: 14px;
1532
+ height: 14px;
1533
+ color: rgb(255 255 255 / 60%); /* --color-darker */
1534
+ }
1535
+
1536
+ .taskon-community-task-field-copy--copied .taskon-community-task-field-copy-icon {
1537
+ color: #cbff01; /* --link-color / --secondary-100 */
1538
+ }
1539
+
1540
+ /* ========== 响应式样式(移动端) ========== */
1541
+ @media (max-width: 750px) {
1542
+ .taskon-community-task-field {
1543
+ margin-top: 2.67vw;
1544
+ font-size: 3.73vw;
1545
+ line-height: 4.67vw;
1546
+ gap: 1.07vw;
1547
+ }
1548
+
1549
+ .taskon-community-task-field-copy-icon {
1550
+ width: 3.73vw;
1551
+ height: 3.73vw;
1552
+ }
1553
+ }
1554
+ /**
1555
+ * UserEligibilityMask 样式
1556
+ * 复刻 Vue 版本的样式,遵循项目 CSS 命名规范
1557
+ */
1558
+
1559
+ /* ==================== 根元素 ==================== */
1560
+ .taskon-eligibility-mask {
1561
+ position: absolute;
1562
+ inset: 0;
1563
+ -webkit-backdrop-filter: blur(14px);
1564
+ backdrop-filter: blur(14px);
1565
+ z-index: 10;
1566
+ padding: 20px;
1567
+ border: 1px solid var(--taskon-border-color, rgba(255, 255, 255, 0.1));
1568
+ border-radius: 10px;
1569
+ box-sizing: border-box;
1570
+ }
1571
+
1572
+ /* ==================== 奖励信息区 ==================== */
1573
+ .taskon-eligibility-mask-head {
1574
+ display: flex;
1575
+ align-items: center;
1576
+ gap: 10px;
1577
+ color: var(--taskon-color-lighter, #999);
1578
+ font-size: 16px;
1579
+ font-style: normal;
1580
+ font-weight: 600;
1581
+ line-height: normal;
1582
+ }
1583
+
1584
+ .taskon-eligibility-mask-lock-icon {
1585
+ width: 22px;
1586
+ height: 22px;
1587
+ flex-shrink: 0;
1588
+ }
1589
+
1590
+ .taskon-eligibility-mask-highlight {
1591
+ color: var(--taskon-secondary-100, #6366f1);
1592
+ }
1593
+
1594
+ /* ==================== 任务名称 ==================== */
1595
+ .taskon-eligibility-mask-title {
1596
+ overflow: hidden;
1597
+ white-space: nowrap;
1598
+ text-overflow: ellipsis;
1599
+ margin: 10px 0 0;
1600
+ font-size: 16px;
1601
+ font-style: normal;
1602
+ font-weight: 600;
1603
+ line-height: normal;
1604
+ color: var(--taskon-text-color, #fff);
1605
+ }
1606
+
1607
+ /* ==================== 条件提示行 ==================== */
1608
+ .taskon-eligibility-mask-tip {
1609
+ display: flex;
1610
+ align-items: center;
1611
+ justify-content: space-between;
1612
+ margin-top: 4px;
1613
+ gap: 10px;
1614
+ }
1615
+
1616
+ .taskon-eligibility-mask-cond-title {
1617
+ color: var(--taskon-color-lightest, #ccc);
1618
+ font-size: 14px;
1619
+ font-style: normal;
1620
+ font-weight: 500;
1621
+ line-height: normal;
1622
+ }
1623
+
1624
+ .taskon-eligibility-mask-cond-label {
1625
+ color: var(--taskon-secondary-100, #6366f1);
1626
+ }
1627
+
1628
+ /* Check 按钮 */
1629
+ .taskon-eligibility-mask-check-btn {
1630
+ display: flex;
1631
+ align-items: center;
1632
+ gap: 4px;
1633
+ background: var(--taskon-color-lightest, #ccc);
1634
+ color: var(--taskon-color-lightest-inverse, #000);
1635
+ padding: 2px 6px;
1636
+ border: none;
1637
+ border-radius: 4px;
1638
+ height: 22px;
1639
+ font-size: 12px;
1640
+ font-weight: 500;
1641
+ cursor: pointer;
1642
+ transition: opacity 0.2s;
1643
+ flex-shrink: 0;
1644
+ }
1645
+
1646
+ .taskon-eligibility-mask-check-btn:hover {
1647
+ opacity: 0.8;
1648
+ }
1649
+
1650
+ .taskon-eligibility-mask-check-btn--loading {
1651
+ cursor: not-allowed;
1652
+ opacity: 0.7;
1653
+ }
1654
+
1655
+ .taskon-eligibility-mask-check-btn--loading:hover {
1656
+ opacity: 0.7;
1657
+ }
1658
+
1659
+ .taskon-eligibility-mask-reload-icon {
1660
+ width: 12px;
1661
+ height: 12px;
1662
+ }
1663
+
1664
+ /* Loading 旋转动画 */
1665
+ .taskon-eligibility-mask-reload-icon--spinning {
1666
+ animation: taskon-eligibility-spin 1s linear infinite;
1667
+ }
1668
+
1669
+ @keyframes taskon-eligibility-spin {
1670
+ from {
1671
+ transform: rotate(0deg);
1672
+ }
1673
+ to {
1674
+ transform: rotate(360deg);
1675
+ }
1676
+ }
1677
+
1678
+ /* ==================== 分割线 ==================== */
1679
+ .taskon-eligibility-mask-divider {
1680
+ margin: 15px 0;
1681
+ height: 0;
1682
+ border: none;
1683
+ border-top: 0.5px dashed var(--taskon-color-darkest, #333);
1684
+ }
1685
+
1686
+ /* ==================== 条件列表 ==================== */
1687
+ .taskon-eligibility-mask-list {
1688
+ overflow: hidden auto;
1689
+ height: calc(100% - 100px);
1690
+ }
1691
+
1692
+ /* ==================== 条件项 ==================== */
1693
+ .taskon-eligibility-mask-item {
1694
+ display: flex;
1695
+ align-items: baseline;
1696
+ gap: 15px;
1697
+ height: 24px;
1698
+ margin-top: 6px;
1699
+ font-size: 14px;
1700
+ font-style: normal;
1701
+ font-weight: 500;
1702
+ line-height: normal;
1703
+ color: var(--taskon-text-color, #fff);
1704
+ }
1705
+
1706
+ .taskon-eligibility-mask-item:first-child {
1707
+ margin-top: 0;
1708
+ }
1709
+
1710
+ .taskon-eligibility-mask-item-icon {
1711
+ width: 10px;
1712
+ height: 10px;
1713
+ flex-shrink: 0;
1714
+ }
1715
+
1716
+ /* 条件文案 */
1717
+ .taskon-eligibility-mask-item-text {
1718
+ overflow: hidden;
1719
+ white-space: nowrap;
1720
+ text-overflow: ellipsis;
1721
+ flex: 1;
1722
+ }
1723
+
1724
+ /* 前置任务链接 */
1725
+ .taskon-eligibility-mask-item-link {
1726
+ color: inherit;
1727
+ text-decoration: underline;
1728
+ cursor: pointer;
1729
+ }
1730
+
1731
+ .taskon-eligibility-mask-item-link:hover {
1732
+ opacity: 0.8;
1733
+ }
1734
+
1735
+ /* ==================== 响应式(移动端) ==================== */
1736
+ @media (max-width: 750px) {
1737
+ .taskon-eligibility-mask {
1738
+ padding: 6vw;
1739
+ border-radius: 3.2vw;
1740
+ }
1741
+
1742
+ .taskon-eligibility-mask-item-icon {
1743
+ width: 1.867vw;
1744
+ height: 1.867vw;
1745
+ }
1746
+
1747
+ .taskon-eligibility-mask-head {
1748
+ font-size: 3.733vw;
1749
+ font-weight: 700;
1750
+ }
1751
+
1752
+ .taskon-eligibility-mask-lock-icon {
1753
+ width: 6.4vw;
1754
+ height: 6.4vw;
1755
+ }
1756
+
1757
+ .taskon-eligibility-mask-title {
1758
+ font-size: 3.733vw;
1759
+ margin-top: 1.333vw;
1760
+ }
1761
+
1762
+ .taskon-eligibility-mask-cond-title {
1763
+ font-size: 3.2vw;
1764
+ }
1765
+
1766
+ .taskon-eligibility-mask-check-btn {
1767
+ font-size: 3.2vw;
1768
+ height: 5.067vw;
1769
+ }
1770
+
1771
+ .taskon-eligibility-mask-reload-icon {
1772
+ width: 2.667vw;
1773
+ height: 2.667vw;
1774
+ }
1775
+
1776
+ .taskon-eligibility-mask-divider {
1777
+ margin-top: 3.067vw;
1778
+ margin-bottom: 3.067vw;
1779
+ }
1780
+
1781
+ .taskon-eligibility-mask-list {
1782
+ height: calc(100% - 20vw);
1783
+ }
1784
+
1785
+ .taskon-eligibility-mask-item {
1786
+ font-size: 3.2vw;
1787
+ gap: 2vw;
1788
+ }
1789
+ }
1790
+ /**
1791
+ * TemplateTask 组件样式
1792
+ * 通用模版任务样式,包含展开/收起功能
1793
+ */
1794
+
1795
+ /* 任务卡片包裹(用于遮罩场景) */
1796
+ .taskon-template-task-wrap {
1797
+ position: relative;
1798
+ }
1799
+
1800
+ /* 展开/收起按钮 */
1801
+ .taskon-community-task-expand-btn {
1802
+ display: inline-flex;
1803
+ align-items: center;
1804
+ gap: 4px;
1805
+ margin-top: 10px;
1806
+ padding: 0;
1807
+ border: none;
1808
+ background: transparent;
1809
+ color: rgba(255, 255, 255, 0.6);
1810
+ font-size: 13px;
1811
+ line-height: 16px;
1812
+ cursor: pointer;
1813
+ transition: color 0.2s ease;
1814
+ }
1815
+
1816
+ .taskon-community-task-expand-btn:hover {
1817
+ color: rgba(255, 255, 255, 0.9);
1818
+ }
1819
+
1820
+ .taskon-community-task-expand-text {
1821
+ text-decoration: underline;
1822
+ }
1823
+
1824
+ /* 展开图标 */
1825
+ .taskon-community-task-expand-icon {
1826
+ transition: transform 0.2s ease;
1827
+ }
1828
+
1829
+ /* 展开状态图标旋转 */
1830
+ .taskon-community-task-expand-icon--expanded {
1831
+ transform: rotate(180deg);
1832
+ }
1833
+
1834
+ /* 移动端适配 */
1835
+ @media (max-width: 750px) {
1836
+ .taskon-community-task-expand-btn {
1837
+ margin-top: 2.67vw;
1838
+ gap: 1.07vw;
1839
+ font-size: 3.47vw;
1840
+ line-height: 4.27vw;
1841
+ }
1842
+
1843
+ .taskon-community-task-expand-icon {
1844
+ width: 3.2vw;
1845
+ height: 3.2vw;
1846
+ }
1847
+ }
1848
+ /**
1849
+ * PowTask 组件样式
1850
+ * 使用 Widget 命名空间扁平化方案
1851
+ * 所有类名使用 .taskon-community-pow-* 前缀,避免冲突
1852
+ */
1853
+
1854
+ /* 任务卡片包裹(用于遮罩场景) */
1855
+ .taskon-pow-task-wrap {
1856
+ position: relative;
1857
+ }
1858
+
1859
+ /* 任务描述 */
1860
+ .taskon-community-pow-desc {
1861
+ margin-top: 12px;
1862
+ font-size: 14px;
1863
+ line-height: 20px;
1864
+ color: rgb(255 255 255 / 80%);
1865
+ }
1866
+
1867
+ /* 任务链接 */
1868
+ .taskon-community-pow-link {
1869
+ display: inline-block;
1870
+ margin-top: 8px;
1871
+ font-size: 14px;
1872
+ color: #cbff01;
1873
+ text-decoration: none;
1874
+ cursor: pointer;
1875
+ }
1876
+
1877
+ .taskon-community-pow-link:hover {
1878
+ text-decoration: underline;
1879
+ }
1880
+
1881
+ /* 审核状态文本(简化版,直接显示在卡片上) */
1882
+ .taskon-community-pow-review-status {
1883
+ margin-top: 12px;
1884
+ font-size: 14px;
1885
+ font-weight: 500;
1886
+ line-height: 20px;
1887
+ }
1888
+
1889
+ /* 审核中 */
1890
+ .taskon-community-pow-review-status--pending {
1891
+ color: #ffc107;
1892
+ }
1893
+
1894
+ /* 审核失败 */
1895
+ .taskon-community-pow-review-status--failed {
1896
+ color: #f44336;
1897
+ }
1898
+
1899
+ /* 响应式 */
1900
+ @media (max-width: 750px) {
1901
+ .taskon-community-pow-desc {
1902
+ font-size: 13px;
1903
+ line-height: 18px;
1904
+ }
1905
+
1906
+ .taskon-community-pow-review-status {
1907
+ font-size: 13px;
1908
+ }
1909
+ }
1910
+ /**
1911
+ * ContractInteractiveTask 组件样式
1912
+ * 使用 Widget 命名空间扁平化方案
1913
+ */
1914
+
1915
+ /* 任务卡片包裹(用于遮罩场景) */
1916
+ .taskon-contract-task-wrap {
1917
+ position: relative;
1918
+ }
1919
+ /**
1920
+ * SwapDexTask 组件样式
1921
+ * 使用 Widget 命名空间扁平化方案
1922
+ */
1923
+
1924
+ /* 任务卡片包裹(用于遮罩场景) */
1925
+ .taskon-swap-task-wrap {
1926
+ position: relative;
1927
+ }
1928
+ /**
1929
+ * CommunityTask 组件样式
1930
+ * 复刻原版 CmTaskCard.vue 的样式
1931
+ */
1932
+
1933
+ /* 任务卡片容器 */
1934
+ .taskon-community-task-item {
1935
+ position: relative;
1936
+ transition: all 0.3s;
1937
+ overflow: hidden;
1938
+ height: 100%;
1939
+ }
1940
+
1941
+ /* Hover 效果(PC 端) */
1942
+ @media (min-width: 751px) {
1943
+ .taskon-community-task-item--hover:hover .taskon-community-task {
1944
+ background: #2a2a2a; /* 卡片 hover 背景色 */
1945
+ }
1946
+
1947
+ .taskon-community-task-item--hover:hover .taskon-community-task--won {
1948
+ background: rgba(203, 255, 1, 0.08); /* 完成状态 hover 背景 */
1949
+ }
1950
+ }
1951
+
1952
+ /* 禁用状态 */
1953
+ .taskon-community-task-item--disabled {
1954
+ opacity: 0.4;
1955
+ }
1956
+
1957
+ /* 禁用遮罩 */
1958
+ .taskon-community-task-item-mask {
1959
+ position: absolute;
1960
+ inset: 0;
1961
+ cursor: not-allowed;
1962
+ z-index: 1;
1963
+ }
1964
+ /**
1965
+ * StepIndicator Styles
1966
+ * @description CSS for TaskChain step indicator component
1967
+ */
1968
+
1969
+ /* Container - flex layout with items aligned at bottom */
1970
+ .taskon-taskchain-step-indicator {
1971
+ display: flex;
1972
+ align-items: flex-end;
1973
+ gap: 8px;
1974
+ position: relative;
1975
+ }
1976
+
1977
+ /* Step bars container */
1978
+ .taskon-taskchain-step-indicator-bars {
1979
+ display: flex;
1980
+ flex: 1;
1981
+ align-items: center;
1982
+ gap: 8px;
1983
+ }
1984
+
1985
+ /* Individual step bar */
1986
+ .taskon-taskchain-step-bar {
1987
+ height: 6px;
1988
+ flex: 1;
1989
+ border-radius: 2px;
1990
+ transition: background-color 0.3s ease;
1991
+ }
1992
+
1993
+ /* Completed step - bright green */
1994
+ .taskon-taskchain-step-bar--completed {
1995
+ background-color: #cbff01;
1996
+ }
1997
+
1998
+ /* Pending step - dim green */
1999
+ .taskon-taskchain-step-bar--pending {
2000
+ background-color: rgb(203 255 1 / 20%);
2001
+ }
2002
+
2003
+ /* Flag icon at the end */
2004
+ .taskon-taskchain-step-indicator-flag {
2005
+ width: 24px;
2006
+ height: 24px;
2007
+ flex-shrink: 0;
2008
+ }
2009
+
2010
+ /* Mobile responsive styles */
2011
+ @media (max-width: 750px) {
2012
+ .taskon-taskchain-step-indicator {
2013
+ gap: 5vw;
2014
+ }
2015
+
2016
+ .taskon-taskchain-step-indicator-bars {
2017
+ gap: 5vw;
2018
+ }
2019
+
2020
+ .taskon-taskchain-step-bar {
2021
+ height: 1.333vw;
2022
+ }
2023
+
2024
+ .taskon-taskchain-step-indicator-flag {
2025
+ width: 10vw;
2026
+ height: 10vw;
2027
+ }
2028
+ }
2029
+ /**
2030
+ * TaskChainDetailTime Styles
2031
+ * @description Time range and spots display for TaskChain
2032
+ */
2033
+
2034
+ .taskon-taskchain-time {
2035
+ width: 100%;
2036
+ }
2037
+
2038
+ .taskon-taskchain-time-row {
2039
+ display: flex;
2040
+ align-items: center;
2041
+ gap: 24px;
2042
+ }
2043
+
2044
+ .taskon-taskchain-time-item {
2045
+ display: flex;
2046
+ align-items: center;
2047
+ gap: 8px;
2048
+ }
2049
+
2050
+ .taskon-taskchain-time-icon {
2051
+ width: 16px;
2052
+ height: 16px;
2053
+ color: var(--taskon-text-tertiary, #666);
2054
+ }
2055
+
2056
+ .taskon-taskchain-time-text {
2057
+ font-size: 14px;
2058
+ font-weight: 500;
2059
+ color: var(--taskon-text-secondary, #999);
2060
+ }
2061
+
2062
+ .taskon-taskchain-time-divider {
2063
+ width: 1px;
2064
+ height: 20px;
2065
+ background-color: var(--taskon-border-color, #333);
2066
+ }
2067
+
2068
+ .taskon-taskchain-time-label {
2069
+ font-size: 14px;
2070
+ font-weight: 500;
2071
+ color: var(--taskon-text-secondary, #999);
2072
+ }
2073
+
2074
+ .taskon-taskchain-time-value {
2075
+ font-size: 14px;
2076
+ font-weight: 500;
2077
+ color: var(--taskon-text-primary, #fff);
2078
+ }
2079
+
2080
+ /* Mobile styles */
2081
+ @media (max-width: 768px) {
2082
+ .taskon-taskchain-time-row {
2083
+ gap: 10px;
2084
+ }
2085
+
2086
+ .taskon-taskchain-time-item {
2087
+ gap: 4px;
2088
+ }
2089
+
2090
+ .taskon-taskchain-time-icon {
2091
+ width: 12px;
2092
+ height: 12px;
2093
+ }
2094
+
2095
+ .taskon-taskchain-time-text,
2096
+ .taskon-taskchain-time-label,
2097
+ .taskon-taskchain-time-value {
2098
+ font-size: 12px;
2099
+ }
2100
+
2101
+ .taskon-taskchain-time-divider {
2102
+ height: 12px;
2103
+ }
2104
+ }
2105
+ /**
2106
+ * RewardDisplay Styles
2107
+ * @description Reward preview badge styles
2108
+ */
2109
+
2110
+ .taskon-taskchain-reward-display {
2111
+ position: relative;
2112
+ }
2113
+
2114
+ .taskon-taskchain-reward-display-inner {
2115
+ position: relative;
2116
+ border-radius: 8px;
2117
+ background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.2));
2118
+ padding: 2px;
2119
+ }
2120
+
2121
+ .taskon-taskchain-reward-display-content {
2122
+ position: relative;
2123
+ display: flex;
2124
+ border-radius: 8px;
2125
+ background-color: #1a1a1a;
2126
+ }
2127
+
2128
+ .taskon-taskchain-reward-display-item {
2129
+ position: relative;
2130
+ display: flex;
2131
+ flex-direction: column;
2132
+ align-items: center;
2133
+ justify-content: center;
2134
+ gap: 8px;
2135
+ padding: 8px 12px;
2136
+ min-width: 60px;
2137
+ }
2138
+
2139
+ .taskon-taskchain-reward-display-icon {
2140
+ width: 24px;
2141
+ height: 24px;
2142
+ object-fit: contain;
2143
+ }
2144
+
2145
+ .taskon-taskchain-reward-display-icon--nft {
2146
+ border-radius: 50%;
2147
+ object-fit: cover;
2148
+ }
2149
+
2150
+ .taskon-taskchain-reward-display-text {
2151
+ font-size: 12px;
2152
+ text-align: center;
2153
+ white-space: nowrap;
2154
+ }
2155
+
2156
+ .taskon-taskchain-reward-display-text--token {
2157
+ color: #eeb803;
2158
+ }
2159
+
2160
+ .taskon-taskchain-reward-display-text--points {
2161
+ color: var(--taskon-secondary, #cbff01);
2162
+ }
2163
+
2164
+ .taskon-taskchain-reward-display-text--nft {
2165
+ color: #fff;
2166
+ max-width: 120px;
2167
+ overflow: hidden;
2168
+ text-overflow: ellipsis;
2169
+ }
2170
+
2171
+ .taskon-taskchain-reward-display-pointer {
2172
+ position: absolute;
2173
+ right: 20px;
2174
+ top: 100%;
2175
+ }
2176
+
2177
+ .taskon-taskchain-reward-display-pointer svg {
2178
+ display: block;
2179
+ }
2180
+ /**
2181
+ * TaskChainRewardStep Styles
2182
+ */
2183
+
2184
+ /* Container */
2185
+ .taskon-taskchain-reward-step {
2186
+ position: relative;
2187
+ display: flex;
2188
+ flex-direction: column;
2189
+ align-items: center;
2190
+ justify-content: center;
2191
+ width: 100%;
2192
+ max-width: 480px;
2193
+ margin: 0 auto;
2194
+ text-align: center;
2195
+ }
2196
+
2197
+ /* Content wrapper */
2198
+ .taskon-taskchain-reward-content {
2199
+ position: relative;
2200
+ z-index: 1;
2201
+ width: 100%;
2202
+ }
2203
+
2204
+ /* Title */
2205
+ .taskon-taskchain-reward-title {
2206
+ font-size: 32px;
2207
+ font-weight: 600;
2208
+ line-height: 40px;
2209
+ color: var(--taskon-text-primary, #fff);
2210
+ margin-bottom: 12px;
2211
+ }
2212
+
2213
+ /* Subtitle */
2214
+ .taskon-taskchain-reward-subtitle {
2215
+ font-size: 16px;
2216
+ color: var(--taskon-text-secondary, #999);
2217
+ }
2218
+
2219
+ /* ============================================================================
2220
+ * WinRewards - Scatter Layout (Unclaimed State)
2221
+ * Matches Vue: WinRewards.vue - absolute positioned cards with spread animation
2222
+ * ============================================================================ */
2223
+
2224
+ /* Container for scatter-positioned reward cards */
2225
+ .taskon-taskchain-win-rewards {
2226
+ position: relative;
2227
+ display: flex;
2228
+ align-items: center;
2229
+ justify-content: center;
2230
+ min-height: 240px;
2231
+ padding: 32px;
2232
+ margin-top: 16px;
2233
+ }
2234
+
2235
+ /* Individual scatter card - absolute positioned */
2236
+ .taskon-taskchain-win-reward-card {
2237
+ position: absolute;
2238
+ display: flex;
2239
+ flex-direction: column;
2240
+ align-items: center;
2241
+ gap: 12px;
2242
+ /* Initial state: centered, half scale, invisible */
2243
+ transform: translate(0px, 0px) scale(0.5);
2244
+ opacity: 0;
2245
+ transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
2246
+ }
2247
+
2248
+ /* Spread animation active - transform is set inline via style */
2249
+ .taskon-taskchain-win-reward-card--spread {
2250
+ opacity: 1;
2251
+ }
2252
+
2253
+ /* Large reward icon for scatter layout */
2254
+ .taskon-taskchain-win-reward-icon {
2255
+ width: 72px;
2256
+ height: 72px;
2257
+ border-radius: 50%;
2258
+ object-fit: cover;
2259
+ }
2260
+
2261
+ /* Reward text below icon */
2262
+ .taskon-taskchain-win-reward-text {
2263
+ font-size: 20px;
2264
+ font-weight: 500;
2265
+ color: var(--taskon-text-primary, #fff);
2266
+ max-width: 200px;
2267
+ overflow: visible;
2268
+ text-wrap: wrap;
2269
+ text-align: center;
2270
+ line-height: 1.3;
2271
+ }
2272
+
2273
+ /* Token amount color */
2274
+ .taskon-taskchain-win-reward-text--token {
2275
+ color: #fbb15a;
2276
+ }
2277
+
2278
+ /* Points amount color */
2279
+ .taskon-taskchain-win-reward-text--points {
2280
+ color: #4b5eff;
2281
+ }
2282
+
2283
+ /* ============================================================================
2284
+ * ClaimedRewards - Green Card (Claimed State)
2285
+ * Matches Vue: ClaimedRewards.vue - green-tinted card container
2286
+ * ============================================================================ */
2287
+
2288
+ /* Claimed rewards outer container (matches Vue: tw-flex tw-w-full tw-flex-col tw-gap-3) */
2289
+ .taskon-taskchain-claimed-rewards-wrap {
2290
+ display: flex;
2291
+ width: 100%;
2292
+ flex-direction: column;
2293
+ gap: 12px;
2294
+ margin-top: 16px;
2295
+ }
2296
+
2297
+ /* Green card container for non-NFT rewards */
2298
+ .taskon-taskchain-claimed-card {
2299
+ display: flex;
2300
+ align-items: center;
2301
+ justify-content: center;
2302
+ border-radius: 8px;
2303
+ border: 1px solid rgb(60 232 155 / 20%);
2304
+ background-color: rgb(0 255 163 / 10%);
2305
+ }
2306
+
2307
+ /* Multi-reward: flex-wrap centered layout */
2308
+ .taskon-taskchain-claimed-card--multi {
2309
+ display: inline-flex;
2310
+ flex-wrap: wrap;
2311
+ gap: 8px;
2312
+ }
2313
+
2314
+ /* Individual claimed reward item */
2315
+ .taskon-taskchain-claimed-item {
2316
+ display: flex;
2317
+ align-items: center;
2318
+ justify-content: center;
2319
+ gap: 8px;
2320
+ min-width: 60px;
2321
+ min-height: 80px;
2322
+ padding: 12px 16px;
2323
+ background-color: transparent;
2324
+ }
2325
+
2326
+ /* Multi-reward item: vertical layout */
2327
+ .taskon-taskchain-claimed-item--multi {
2328
+ flex-direction: column;
2329
+ gap: 8px;
2330
+ }
2331
+
2332
+ /* Claimed reward icon - single reward */
2333
+ .taskon-taskchain-claimed-icon {
2334
+ width: 32px;
2335
+ height: 32px;
2336
+ border-radius: 50%;
2337
+ object-fit: cover;
2338
+ }
2339
+
2340
+ /* Claimed reward icon - multi reward (smaller) */
2341
+ .taskon-taskchain-claimed-icon--multi {
2342
+ width: 24px;
2343
+ height: 24px;
2344
+ }
2345
+
2346
+ /* Claimed icon glow effects - matches Vue: showGlow when multi rewards */
2347
+ .taskon-taskchain-claimed-icon--glow-token {
2348
+ box-shadow: 0 -8px 30px 0 #f47d3b;
2349
+ }
2350
+
2351
+ .taskon-taskchain-claimed-icon--glow-points {
2352
+ box-shadow: 0 -8px 30px 0 #ff6b35;
2353
+ }
2354
+
2355
+ /* Claimed reward text - single reward */
2356
+ .taskon-taskchain-claimed-text {
2357
+ font-size: 18px;
2358
+ font-weight: 600;
2359
+ line-height: 24px;
2360
+ color: var(--taskon-text-primary, #fff);
2361
+ }
2362
+
2363
+ /* Claimed reward text - multi reward */
2364
+ .taskon-taskchain-claimed-text--multi {
2365
+ font-size: 14px;
2366
+ font-weight: 500;
2367
+ }
2368
+
2369
+ /* Token amount color in claimed state */
2370
+ .taskon-taskchain-claimed-text--token {
2371
+ color: #fbb15a;
2372
+ }
2373
+
2374
+ /* Points amount color in claimed state */
2375
+ .taskon-taskchain-claimed-text--points {
2376
+ color: #ff6b35;
2377
+ }
2378
+
2379
+ /* Token text with underline (matches Vue: tw-underline on token text) */
2380
+ .taskon-taskchain-claimed-text--token-link {
2381
+ text-decoration: underline;
2382
+ display: inline-flex;
2383
+ align-items: center;
2384
+ gap: 2px;
2385
+ white-space: nowrap;
2386
+ cursor: pointer;
2387
+ }
2388
+
2389
+ /* Right arrow icon for token link (matches Vue: tw-h-3 tw-w-3 = 12px) */
2390
+ .taskon-taskchain-claimed-arrow {
2391
+ color: #fbb15a;
2392
+ margin-left: 4px;
2393
+ width: 12px;
2394
+ height: 12px;
2395
+ flex-shrink: 0;
2396
+ }
2397
+
2398
+ /* Multi-reward smaller arrow (matches Vue: tw-h-2 tw-w-2 = 8px) */
2399
+ .taskon-taskchain-claimed-arrow--multi {
2400
+ width: 8px;
2401
+ height: 8px;
2402
+ }
2403
+
2404
+ /* ============================================================================
2405
+ * Token Tooltip Content
2406
+ * Matches Vue: TokenReward.vue tooltip (TipPopOver content)
2407
+ * ============================================================================ */
2408
+
2409
+ /* Tooltip container */
2410
+ .taskon-taskchain-token-tooltip {
2411
+ display: flex;
2412
+ flex-direction: column;
2413
+ gap: 8px;
2414
+ white-space: nowrap;
2415
+ padding: 4px;
2416
+ }
2417
+
2418
+ /* Tooltip row */
2419
+ .taskon-taskchain-token-tooltip-row {
2420
+ display: flex;
2421
+ width: 100%;
2422
+ align-items: center;
2423
+ justify-content: space-between;
2424
+ gap: 8px;
2425
+ }
2426
+
2427
+ /* Tooltip label (left side) */
2428
+ .taskon-taskchain-token-tooltip-label {
2429
+ font-size: 14px;
2430
+ color: var(--taskon-text-tertiary, rgba(255, 255, 255, 0.5));
2431
+ }
2432
+
2433
+ /* Tooltip value (right side, token amount) */
2434
+ .taskon-taskchain-token-tooltip-value {
2435
+ font-size: 14px;
2436
+ font-weight: 600;
2437
+ color: var(--taskon-text-primary, #fff);
2438
+ }
2439
+
2440
+ /* Tooltip USD value */
2441
+ .taskon-taskchain-token-tooltip-usd {
2442
+ font-size: 14px;
2443
+ font-weight: 500;
2444
+ color: #cbff01;
2445
+ }
2446
+
2447
+ /* Action buttons container */
2448
+ .taskon-taskchain-reward-actions {
2449
+ display: flex;
2450
+ justify-content: center;
2451
+ gap: 12px;
2452
+ margin-top: 60px;
2453
+ }
2454
+
2455
+ /* ============================================================================
2456
+ * Animation States
2457
+ * ============================================================================ */
2458
+
2459
+ /* Unclaimed content - exit animation */
2460
+ .taskon-taskchain-reward-unclaimed {
2461
+ opacity: 1;
2462
+ transform: translateY(0);
2463
+ transition: opacity 0.6s ease-out, transform 0.6s ease-out;
2464
+ }
2465
+
2466
+ .taskon-taskchain-reward-unclaimed--exit {
2467
+ opacity: 0;
2468
+ transform: translateY(-20px);
2469
+ }
2470
+
2471
+ /* Claim button exit animation (separate from rewards) */
2472
+ .taskon-taskchain-claim-btn-exit {
2473
+ opacity: 1;
2474
+ transform: translateY(0);
2475
+ transition: opacity 0.6s ease-out, transform 0.6s ease-out;
2476
+ }
2477
+
2478
+ .taskon-taskchain-claim-btn-exit--active {
2479
+ opacity: 0;
2480
+ transform: translateY(-20px);
2481
+ }
2482
+
2483
+ /* Claimed content - enter animation */
2484
+ .taskon-taskchain-reward-claimed {
2485
+ opacity: 1;
2486
+ transform: translateY(0);
2487
+ }
2488
+
2489
+ .taskon-taskchain-reward-claimed--animate {
2490
+ animation: taskon-taskchain-slide-up-fade-in 0.8s ease-out 0.2s both;
2491
+ }
2492
+
2493
+ @keyframes taskon-taskchain-slide-up-fade-in {
2494
+ from {
2495
+ opacity: 0;
2496
+ transform: translateY(40px);
2497
+ }
2498
+ to {
2499
+ opacity: 1;
2500
+ transform: translateY(0);
2501
+ }
2502
+ }
2503
+
2504
+ /* ============================================================================
2505
+ * Confetti Particles
2506
+ * ============================================================================ */
2507
+
2508
+ .taskon-taskchain-confetti-particle {
2509
+ position: absolute;
2510
+ top: 30%;
2511
+ width: 10px;
2512
+ height: 10px;
2513
+ border-radius: 2px;
2514
+ pointer-events: none;
2515
+ animation: taskon-taskchain-confetti-fall 1.5s ease-out forwards;
2516
+ }
2517
+
2518
+ @keyframes taskon-taskchain-confetti-fall {
2519
+ 0% {
2520
+ opacity: 1;
2521
+ transform: translateY(0) rotate(0deg) scale(1);
2522
+ }
2523
+ 100% {
2524
+ opacity: 0;
2525
+ transform: translateY(200px) rotate(720deg) scale(0.5);
2526
+ }
2527
+ }
2528
+
2529
+ /* Add some variety to particles */
2530
+ .taskon-taskchain-confetti-particle:nth-child(odd) {
2531
+ width: 8px;
2532
+ height: 12px;
2533
+ animation-name: taskon-taskchain-confetti-fall-alt;
2534
+ }
2535
+
2536
+ @keyframes taskon-taskchain-confetti-fall-alt {
2537
+ 0% {
2538
+ opacity: 1;
2539
+ transform: translateY(0) translateX(0) rotate(0deg) scale(1);
2540
+ }
2541
+ 100% {
2542
+ opacity: 0;
2543
+ transform: translateY(180px) translateX(50px) rotate(-540deg) scale(0.3);
2544
+ }
2545
+ }
2546
+
2547
+ .taskon-taskchain-confetti-particle:nth-child(3n) {
2548
+ animation-name: taskon-taskchain-confetti-fall-left;
2549
+ }
2550
+
2551
+ @keyframes taskon-taskchain-confetti-fall-left {
2552
+ 0% {
2553
+ opacity: 1;
2554
+ transform: translateY(0) translateX(0) rotate(0deg) scale(1);
2555
+ }
2556
+ 100% {
2557
+ opacity: 0;
2558
+ transform: translateY(160px) translateX(-40px) rotate(450deg) scale(0.4);
2559
+ }
2560
+ }
2561
+
2562
+ /* ============================================================================
2563
+ * Claimed NFT Cards (Separate from green card)
2564
+ * Matches Vue: ClaimedRewardsNftCard.vue
2565
+ * ============================================================================ */
2566
+
2567
+ /* NFT card list container */
2568
+ .taskon-taskchain-claimed-nft-list {
2569
+ display: flex;
2570
+ flex-direction: column;
2571
+ gap: 12px;
2572
+ }
2573
+
2574
+ /* Individual NFT claimed card */
2575
+ .taskon-taskchain-claimed-nft-card {
2576
+ display: flex;
2577
+ align-items: center;
2578
+ justify-content: space-between;
2579
+ border-radius: 8px;
2580
+ border: 1px solid rgb(60 232 155 / 20%);
2581
+ background-color: rgb(0 255 163 / 10%);
2582
+ padding: 12px 16px;
2583
+ }
2584
+
2585
+ /* NFT info section (image + text) */
2586
+ .taskon-taskchain-claimed-nft-info {
2587
+ display: flex;
2588
+ align-items: center;
2589
+ gap: 16px;
2590
+ min-width: 0;
2591
+ }
2592
+
2593
+ /* NFT image wrapper with chain badge */
2594
+ .taskon-taskchain-claimed-nft-image-wrap {
2595
+ position: relative;
2596
+ width: 56px;
2597
+ height: 56px;
2598
+ flex-shrink: 0;
2599
+ }
2600
+
2601
+ /* NFT image */
2602
+ .taskon-taskchain-claimed-nft-image {
2603
+ width: 100%;
2604
+ height: 100%;
2605
+ border-radius: 6px;
2606
+ object-fit: cover;
2607
+ }
2608
+
2609
+ /* NFT fallback image (no collection image available) */
2610
+ .taskon-taskchain-claimed-nft-image--fallback {
2611
+ background-color: #1f1f1f;
2612
+ }
2613
+
2614
+ /* Chain badge on NFT image (bottom-right corner) */
2615
+ .taskon-taskchain-claimed-nft-chain {
2616
+ position: absolute;
2617
+ bottom: -4px;
2618
+ right: -4px;
2619
+ width: 20px;
2620
+ height: 20px;
2621
+ border-radius: 50%;
2622
+ border: 1px solid rgba(0, 0, 0, 0.6);
2623
+ background-color: #fff;
2624
+ }
2625
+
2626
+ /* NFT text section */
2627
+ .taskon-taskchain-claimed-nft-text {
2628
+ display: flex;
2629
+ flex-direction: column;
2630
+ gap: 4px;
2631
+ min-width: 0;
2632
+ text-align: left;
2633
+ }
2634
+
2635
+ /* NFT label ("NFT" text) */
2636
+ .taskon-taskchain-claimed-nft-label {
2637
+ font-size: 14px;
2638
+ color: rgba(255, 255, 255, 0.6);
2639
+ }
2640
+
2641
+ /* NFT collection name */
2642
+ .taskon-taskchain-claimed-nft-name {
2643
+ font-size: 18px;
2644
+ font-weight: 600;
2645
+ color: #fff;
2646
+ overflow: hidden;
2647
+ text-overflow: ellipsis;
2648
+ white-space: nowrap;
2649
+ }
2650
+
2651
+ /* NFT CTA button (matches Vue: ClaimedRewardsNftCard button style) */
2652
+ .taskon-taskchain-claimed-nft-btn {
2653
+ flex-shrink: 0;
2654
+ padding: 8px 20px;
2655
+ font-size: 14px;
2656
+ font-weight: 600;
2657
+ color: #000;
2658
+ background-color: #cbff01;
2659
+ border: none;
2660
+ border-radius: 8px;
2661
+ cursor: pointer;
2662
+ transition: opacity 0.2s, transform 0.1s;
2663
+ white-space: nowrap;
2664
+ }
2665
+
2666
+ .taskon-taskchain-claimed-nft-btn:hover {
2667
+ opacity: 0.9;
2668
+ }
2669
+
2670
+ .taskon-taskchain-claimed-nft-btn:active {
2671
+ transform: scale(0.98);
2672
+ }
2673
+
2674
+ /* ============================================================================
2675
+ * Button Styles
2676
+ * ============================================================================ */
2677
+
2678
+ /* Button base */
2679
+ .taskon-taskchain-btn {
2680
+ padding: 12px 32px;
2681
+ font-size: 14px;
2682
+ font-weight: 600;
2683
+ border: none;
2684
+ border-radius: 8px;
2685
+ cursor: pointer;
2686
+ transition: opacity 0.2s, transform 0.1s;
2687
+ }
2688
+
2689
+ .taskon-taskchain-btn:hover {
2690
+ opacity: 0.9;
2691
+ }
2692
+
2693
+ .taskon-taskchain-btn:active {
2694
+ transform: scale(0.98);
2695
+ }
2696
+
2697
+ .taskon-taskchain-btn:disabled {
2698
+ opacity: 0.5;
2699
+ cursor: not-allowed;
2700
+ }
2701
+
2702
+ /* Primary button */
2703
+ .taskon-taskchain-btn--primary {
2704
+ color: #000;
2705
+ background-color: #cbff01;
2706
+ }
2707
+
2708
+ /* Secondary button */
2709
+ .taskon-taskchain-btn--secondary {
2710
+ color: var(--taskon-text-primary, #fff);
2711
+ background-color: transparent;
2712
+ border: 1px solid rgba(255, 255, 255, 0.2);
2713
+ }
2714
+
2715
+ .taskon-taskchain-btn--secondary:hover {
2716
+ background-color: rgba(255, 255, 255, 0.1);
2717
+ }
2718
+
2719
+ /* ============================================================================
2720
+ * Mobile Responsive
2721
+ * ============================================================================ */
2722
+
2723
+ @media (max-width: 750px) {
2724
+ .taskon-taskchain-reward-title {
2725
+ font-size: 24px;
2726
+ line-height: 32px;
2727
+ }
2728
+
2729
+ .taskon-taskchain-reward-subtitle {
2730
+ font-size: 14px;
2731
+ }
2732
+
2733
+ /* WinRewards mobile */
2734
+ .taskon-taskchain-win-rewards {
2735
+ min-height: 50vw;
2736
+ padding: 6vw;
2737
+ }
2738
+
2739
+ .taskon-taskchain-win-reward-icon {
2740
+ width: 16.267vw;
2741
+ height: 16.267vw;
2742
+ }
2743
+
2744
+ .taskon-taskchain-win-reward-text {
2745
+ max-width: 30vw;
2746
+ }
2747
+
2748
+ /* ClaimedRewards mobile */
2749
+ .taskon-taskchain-claimed-item {
2750
+ min-height: 18.267vw;
2751
+ }
2752
+
2753
+ /* Claimed NFT card mobile (matches Vue: mb: responsive values) */
2754
+ .taskon-taskchain-claimed-nft-card {
2755
+ gap: 2.133vw;
2756
+ border-radius: 1.333vw;
2757
+ padding: 2.72vw 3.626vw;
2758
+ }
2759
+
2760
+ .taskon-taskchain-claimed-nft-image-wrap {
2761
+ width: 12.693vw;
2762
+ height: 12.693vw;
2763
+ border-radius: 1.41vw;
2764
+ }
2765
+
2766
+ .taskon-taskchain-claimed-nft-image {
2767
+ border-radius: 1.41vw;
2768
+ }
2769
+
2770
+ .taskon-taskchain-claimed-nft-chain {
2771
+ bottom: -0.533vw;
2772
+ right: -0.533vw;
2773
+ width: 3.2vw;
2774
+ height: 3.2vw;
2775
+ }
2776
+
2777
+ .taskon-taskchain-claimed-nft-text {
2778
+ gap: 1vw;
2779
+ }
2780
+
2781
+ .taskon-taskchain-claimed-nft-label {
2782
+ font-size: 3.2vw;
2783
+ }
2784
+
2785
+ .taskon-taskchain-claimed-nft-name {
2786
+ font-size: 3.733vw;
2787
+ }
2788
+
2789
+ .taskon-taskchain-claimed-nft-btn {
2790
+ padding: 1.6vw 4vw;
2791
+ font-size: 2.933vw;
2792
+ border-radius: 1.333vw;
2793
+ }
2794
+ }
2795
+ /**
2796
+ * TaskChainBlindBoxStep Styles
2797
+ *
2798
+ * This component now reuses BlindBoxDialog and BlindBoxRewardDialog from Quest,
2799
+ * so most styles come from those components. Only container and helper styles here.
2800
+ */
2801
+
2802
+ /* Container */
2803
+ .taskon-taskchain-blindbox-step {
2804
+ position: relative;
2805
+ display: flex;
2806
+ flex-direction: column;
2807
+ align-items: center;
2808
+ justify-content: center;
2809
+ width: 100%;
2810
+ max-width: 480px;
2811
+ margin: 0 auto;
2812
+ padding: 20px;
2813
+ text-align: center;
2814
+ min-height: 400px;
2815
+ }
2816
+
2817
+ /* Error message */
2818
+ .taskon-taskchain-blindbox-error {
2819
+ margin-top: 16px;
2820
+ padding: 12px 16px;
2821
+ background-color: rgba(255, 107, 107, 0.1);
2822
+ border: 1px solid rgba(255, 107, 107, 0.3);
2823
+ border-radius: 8px;
2824
+ color: #ff6b6b;
2825
+ font-size: 14px;
2826
+ }
2827
+
2828
+ /* Loading state */
2829
+ .taskon-taskchain-blindbox-loading {
2830
+ display: flex;
2831
+ flex-direction: column;
2832
+ align-items: center;
2833
+ gap: 16px;
2834
+ color: var(--taskon-text-secondary, #999);
2835
+ }
2836
+
2837
+ /* Spinner */
2838
+ .taskon-taskchain-spinner {
2839
+ width: 32px;
2840
+ height: 32px;
2841
+ border: 3px solid rgba(255, 255, 255, 0.2);
2842
+ border-top-color: #cbff01;
2843
+ border-radius: 50%;
2844
+ animation: taskon-taskchain-spin 0.8s linear infinite;
2845
+ }
2846
+
2847
+ @keyframes taskon-taskchain-spin {
2848
+ to {
2849
+ transform: rotate(360deg);
2850
+ }
2851
+ }
2852
+
2853
+ /* Mobile responsive */
2854
+ @media (max-width: 750px) {
2855
+ .taskon-taskchain-blindbox-step {
2856
+ padding: 16px;
2857
+ min-height: 350px;
2858
+ }
2859
+ }
2860
+ /**
2861
+ * NotEligible Styles
2862
+ * @description Styles for NotEligible component in TaskChain
2863
+ */
2864
+
2865
+ .taskon-taskchain-not-eligible {
2866
+ display: flex;
2867
+ flex-direction: column;
2868
+ align-items: center;
2869
+ justify-content: center;
2870
+ flex: 1;
2871
+ padding: 40px 20px;
2872
+ text-align: center;
2873
+ }
2874
+
2875
+ .taskon-taskchain-not-eligible-oops {
2876
+ font-size: 32px;
2877
+ font-weight: 600;
2878
+ color: var(--taskon-text-primary, #fff);
2879
+ margin-bottom: 32px;
2880
+ }
2881
+
2882
+ .taskon-taskchain-not-eligible-emoji {
2883
+ font-size: 48px;
2884
+ margin-bottom: 16px;
2885
+ }
2886
+
2887
+ .taskon-taskchain-not-eligible-title {
2888
+ font-size: 18px;
2889
+ font-weight: 600;
2890
+ color: var(--taskon-text-primary, #fff);
2891
+ margin-bottom: 8px;
2892
+ }
2893
+
2894
+ .taskon-taskchain-not-eligible-desc {
2895
+ font-size: 14px;
2896
+ color: var(--taskon-text-secondary, #999);
2897
+ max-width: 300px;
2898
+ line-height: 1.5;
2899
+ }
2900
+
2901
+ .taskon-taskchain-not-eligible-panel {
2902
+ width: 508px;
2903
+ max-width: 100%;
2904
+ border-radius: 10px;
2905
+ background-color: rgba(255, 255, 255, 0.05);
2906
+ padding: 16px;
2907
+ }
2908
+
2909
+ /* Mobile responsive */
2910
+ @media (max-width: 750px) {
2911
+ .taskon-taskchain-not-eligible {
2912
+ padding: 20px 16px;
2913
+ }
2914
+
2915
+ .taskon-taskchain-not-eligible-oops {
2916
+ font-size: 24px;
2917
+ margin-bottom: 24px;
2918
+ }
2919
+
2920
+ .taskon-taskchain-not-eligible-panel {
2921
+ width: 100%;
2922
+ padding: 12px;
2923
+ }
2924
+ }
2925
+ /**
2926
+ * ActionEndedMask Styles
2927
+ */
2928
+
2929
+ .taskon-taskchain-ended-mask {
2930
+ position: absolute;
2931
+ inset: 0;
2932
+ display: flex;
2933
+ flex-direction: column;
2934
+ align-items: center;
2935
+ justify-content: center;
2936
+ background: rgba(0, 0, 0, 0.5);
2937
+ backdrop-filter: blur(10px);
2938
+ z-index: 10;
2939
+ border-radius: inherit;
2940
+ }
2941
+
2942
+ .taskon-taskchain-ended-mask-image {
2943
+ width: 72px;
2944
+ height: 72px;
2945
+ }
2946
+
2947
+ .taskon-taskchain-ended-mask-title {
2948
+ margin-top: 16px;
2949
+ text-align: center;
2950
+ font-size: 32px;
2951
+ font-weight: 700;
2952
+ line-height: 40px;
2953
+ color: #fff;
2954
+ }
2955
+
2956
+ /* Mobile responsive */
2957
+ @media (max-width: 750px) {
2958
+ .taskon-taskchain-ended-mask-image {
2959
+ width: 56px;
2960
+ height: 56px;
2961
+ }
2962
+
2963
+ .taskon-taskchain-ended-mask-title {
2964
+ font-size: 24px;
2965
+ line-height: 32px;
2966
+ }
2967
+ }
2968
+ /**
2969
+ * TaskChainDetail Styles
2970
+ *
2971
+ * Layout matches Vue original:
2972
+ * - Outer container: title, step indicator, content card, time info
2973
+ * - Content card (taskon-taskchain-detail-content): has visible card styles
2974
+ * with border, background, rounded corners, glow, and nav buttons inside
2975
+ */
2976
+
2977
+ /* Outer container - only vertical padding, no left/right (handled by dialog-content) */
2978
+ .taskon-taskchain-detail {
2979
+ position: relative;
2980
+ display: flex;
2981
+ flex-direction: column;
2982
+ width: 100%;
2983
+ padding-top: 38px;
2984
+ padding-bottom: 40px;
2985
+ }
2986
+
2987
+ /* Title */
2988
+ .taskon-taskchain-detail-title {
2989
+ font-size: 20px;
2990
+ font-weight: 600;
2991
+ margin: 0;
2992
+ word-break: break-word;
2993
+ color: var(--taskon-text-primary, #fff);
2994
+ }
2995
+
2996
+ /* Time info */
2997
+ .taskon-taskchain-detail-time {
2998
+ margin-top: 16px;
2999
+ }
3000
+
3001
+ /* Step indicator wrapper (for reward display positioning) */
3002
+ .taskon-taskchain-detail-steps-wrap {
3003
+ position: relative;
3004
+ margin-top: 30px;
3005
+ }
3006
+
3007
+ /* Reward display positioning */
3008
+ .taskon-taskchain-detail-reward-display {
3009
+ position: absolute;
3010
+ right: 0;
3011
+ bottom: 100%;
3012
+ margin-bottom: 8px;
3013
+ }
3014
+
3015
+ /* Step indicator area */
3016
+ .taskon-taskchain-detail-steps {
3017
+ width: 100%;
3018
+ }
3019
+
3020
+ /* Content card - matches Vue TaskChainMain root div styles */
3021
+ .taskon-taskchain-detail-content {
3022
+ position: relative;
3023
+ flex: 1;
3024
+ display: flex;
3025
+ flex-direction: column;
3026
+ align-items: center;
3027
+ min-height: 600px;
3028
+ margin-top: 16px;
3029
+ padding: 40px;
3030
+ border-radius: 10px;
3031
+ border: 1px solid rgba(255, 255, 255, 0.05);
3032
+ background: rgba(255, 255, 255, 0.05);
3033
+ overflow: hidden;
3034
+ }
3035
+
3036
+ /* Light glow effect - inside content card */
3037
+ .taskon-taskchain-detail-light {
3038
+ position: absolute;
3039
+ top: -272px;
3040
+ left: 50%;
3041
+ transform: translateX(-50%);
3042
+ width: 546px;
3043
+ height: 546px;
3044
+ border-radius: 50%;
3045
+ background: radial-gradient(
3046
+ 50% 50% at 50% 50%,
3047
+ rgb(82 82 82 / 30%) 0%,
3048
+ rgb(178 178 178 / 30%) 100%
3049
+ );
3050
+ filter: blur(134px);
3051
+ z-index: -1;
3052
+ pointer-events: none;
3053
+ }
3054
+
3055
+ /* Reward step light background - fills entire content card */
3056
+ .taskon-taskchain-reward-light {
3057
+ position: absolute;
3058
+ top: 0;
3059
+ left: 0;
3060
+ width: 100%;
3061
+ height: 100%;
3062
+ z-index: 0;
3063
+ opacity: 0;
3064
+ pointer-events: none;
3065
+ animation: taskon-taskchain-light-appear 2s ease-out forwards;
3066
+ }
3067
+
3068
+ @keyframes taskon-taskchain-light-appear {
3069
+ to {
3070
+ opacity: 1;
3071
+ }
3072
+ }
3073
+
3074
+ /* Inner content wrapper inside card */
3075
+ .taskon-taskchain-detail-inner {
3076
+ display: flex;
3077
+ flex-direction: column;
3078
+ flex: 1;
3079
+ width: 100%;
3080
+ height: 100%;
3081
+ }
3082
+
3083
+ /* Main content flex area */
3084
+ .taskon-taskchain-detail-main {
3085
+ display: flex;
3086
+ flex-direction: column;
3087
+ flex: 1;
3088
+ justify-content: center;
3089
+ }
3090
+
3091
+ /* Navigation buttons - inside content card */
3092
+ .taskon-taskchain-detail-nav {
3093
+ display: flex;
3094
+ justify-content: flex-end;
3095
+ gap: 8px;
3096
+ margin-top: 16px;
3097
+ }
3098
+
3099
+ /* Loading state */
3100
+ .taskon-taskchain-detail-loading {
3101
+ flex: 1;
3102
+ display: flex;
3103
+ flex-direction: column;
3104
+ align-items: center;
3105
+ justify-content: center;
3106
+ gap: 16px;
3107
+ color: var(--taskon-text-secondary, #999);
3108
+ }
3109
+
3110
+ /* Task content wrapper - matches Vue: tw-mx-auto tw-w-[800px] tw-max-w-full */
3111
+ .taskon-taskchain-main {
3112
+ width: 800px;
3113
+ max-width: 100%;
3114
+ margin: 0 auto;
3115
+ }
3116
+
3117
+ /* Mobile responsive */
3118
+ @media (max-width: 750px) {
3119
+ .taskon-taskchain-detail {
3120
+ padding-top: 32px;
3121
+ padding-bottom: 24px;
3122
+ }
3123
+
3124
+ .taskon-taskchain-detail-title {
3125
+ font-size: 18px;
3126
+ }
3127
+
3128
+ .taskon-taskchain-detail-steps-wrap {
3129
+ margin-top: 64px; /* More space on mobile for reward display */
3130
+ }
3131
+
3132
+ .taskon-taskchain-detail-content {
3133
+ margin-top: 24px;
3134
+ padding: 24px;
3135
+ min-height: auto;
3136
+ }
3137
+
3138
+ .taskon-taskchain-detail-nav {
3139
+ margin-top: 24px;
3140
+ }
3141
+ }
3142
+ /**
3143
+ * BottomDialog Styles
3144
+ * Bottom sheet dialog component - slides up from bottom
3145
+ * Migrated from Vue: taskon-website/apps/website/src/components/BottomDialog.vue
3146
+ */
3147
+
3148
+ /* ==================== Full screen overlay container ==================== */
3149
+ .taskon-bottom-dialog {
3150
+ position: fixed;
3151
+ inset: 0;
3152
+ z-index: 9998;
3153
+ }
3154
+
3155
+ /* ==================== Backdrop overlay ==================== */
3156
+ .taskon-bottom-dialog-overlay {
3157
+ position: absolute;
3158
+ inset: 0;
3159
+ background: var(--taskon-color-overlay, rgba(66, 66, 66, 0.5));
3160
+ backdrop-filter: blur(40px);
3161
+ }
3162
+
3163
+ /* Overlay enter animation */
3164
+ .taskon-bottom-dialog-overlay--enter {
3165
+ animation: taskon-bottom-dialog-overlay-in 0.3s ease-out forwards;
3166
+ }
3167
+
3168
+ /* Overlay exit animation */
3169
+ .taskon-bottom-dialog-overlay--exit {
3170
+ animation: taskon-bottom-dialog-overlay-out 0.25s ease-in forwards;
3171
+ }
3172
+
3173
+ @keyframes taskon-bottom-dialog-overlay-in {
3174
+ from {
3175
+ opacity: 0;
3176
+ }
3177
+ to {
3178
+ opacity: 1;
3179
+ }
3180
+ }
3181
+
3182
+ @keyframes taskon-bottom-dialog-overlay-out {
3183
+ from {
3184
+ opacity: 1;
3185
+ }
3186
+ to {
3187
+ opacity: 0;
3188
+ }
3189
+ }
3190
+
3191
+ /* ==================== Card (content area) ==================== */
3192
+ .taskon-bottom-dialog-card {
3193
+ position: fixed;
3194
+ right: 0;
3195
+ bottom: 0;
3196
+ left: 0;
3197
+ border-radius: 10px 10px 0 0;
3198
+ background: var(--taskon-color-bg-popup, #0d0d0d);
3199
+ overflow: auto;
3200
+ }
3201
+
3202
+ /* Card enter animation - slide up from bottom */
3203
+ .taskon-bottom-dialog-card--enter {
3204
+ animation: taskon-bottom-dialog-card-in 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
3205
+ }
3206
+
3207
+ /* Card exit animation - slide down to bottom */
3208
+ .taskon-bottom-dialog-card--exit {
3209
+ animation: taskon-bottom-dialog-card-out 0.25s cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
3210
+ }
3211
+
3212
+ @keyframes taskon-bottom-dialog-card-in {
3213
+ from {
3214
+ transform: translateY(100%);
3215
+ }
3216
+ to {
3217
+ transform: translateY(0);
3218
+ }
3219
+ }
3220
+
3221
+ @keyframes taskon-bottom-dialog-card-out {
3222
+ from {
3223
+ transform: translateY(0);
3224
+ }
3225
+ to {
3226
+ transform: translateY(100%);
3227
+ }
3228
+ }
3229
+
3230
+ /* ==================== Close button ==================== */
3231
+ .taskon-bottom-dialog-close {
3232
+ position: absolute;
3233
+ top: 24px;
3234
+ right: 24px;
3235
+ z-index: 10;
3236
+ display: flex;
3237
+ align-items: center;
3238
+ justify-content: center;
3239
+ width: 32px;
3240
+ height: 32px;
3241
+ padding: 0;
3242
+ background: rgba(255, 255, 255, 0.1);
3243
+ border: none;
3244
+ border-radius: 8px;
3245
+ color: var(--taskon-text-secondary, #999);
3246
+ cursor: pointer;
3247
+ transition: background-color 0.2s, color 0.2s;
3248
+ }
3249
+
3250
+ .taskon-bottom-dialog-close:hover {
3251
+ background-color: rgba(255, 255, 255, 0.2);
3252
+ color: var(--taskon-text-primary, #fff);
3253
+ }
3254
+
3255
+ /* ==================== Mobile responsive ==================== */
3256
+ @media (max-width: 750px) {
3257
+ .taskon-bottom-dialog-close {
3258
+ top: 5.333vw;
3259
+ right: 4vw;
3260
+ width: 24px;
3261
+ height: 24px;
3262
+ }
3263
+ }
3264
+ /**
3265
+ * TaskChainDialog Styles
3266
+ * Dialog UI (overlay, card, close button, animations) is handled by BottomDialog.
3267
+ * This file only contains styles for the inner content.
3268
+ */
3269
+
3270
+ /* Inner content wrapper - matches Vue g-safe-area layout */
3271
+ .taskon-taskchain-dialog-content {
3272
+ position: relative;
3273
+ width: 100%;
3274
+ max-width: 1580px;
3275
+ margin: 0 auto;
3276
+ padding-left: 20px;
3277
+ padding-right: 20px;
3278
+ }
3279
+
3280
+ @media (max-width: 1512px) {
3281
+ .taskon-taskchain-dialog-content {
3282
+ max-width: 1340px;
3283
+ }
3284
+ }
3285
+
3286
+ @media (max-width: 750px) {
3287
+ .taskon-taskchain-dialog-content {
3288
+ max-width: initial;
3289
+ padding-left: var(--taskon-m-padding, 4vw);
3290
+ padding-right: var(--taskon-m-padding, 4vw);
3291
+ }
3292
+ }
3293
+
3294
+ /* Error state */
3295
+ .taskon-taskchain-dialog-error {
3296
+ display: flex;
3297
+ flex-direction: column;
3298
+ align-items: center;
3299
+ justify-content: center;
3300
+ min-height: 400px;
3301
+ padding: 40px;
3302
+ text-align: center;
3303
+ color: var(--taskon-text-primary, #fff);
3304
+ }
3305
+
3306
+ .taskon-taskchain-dialog-error-detail {
3307
+ margin-top: 8px;
3308
+ font-size: 14px;
3309
+ color: var(--taskon-text-secondary, #999);
3310
+ }
3311
+ /**
3312
+ * RewardsRowHoverScroll Styles
3313
+ * Matches Vue version: RewardsRowHoverScroll.vue
3314
+ */
3315
+
3316
+ .taskon-rewards-row-carousel {
3317
+ display: flex;
3318
+ width: 100%;
3319
+ overflow: hidden;
3320
+ position: relative;
3321
+ text-align: left;
3322
+ }
3323
+
3324
+ .taskon-rewards-row-carousel:hover .taskon-rewards-row-inner--scrollable {
3325
+ animation: taskon-rewards-row-scroll var(--scroll-duration, 10s) linear infinite;
3326
+ }
3327
+
3328
+ .taskon-rewards-row-inner {
3329
+ display: inline-flex;
3330
+ flex-shrink: 0;
3331
+ gap: 6px;
3332
+ }
3333
+
3334
+ @keyframes taskon-rewards-row-scroll {
3335
+ 0% {
3336
+ transform: translateX(0);
3337
+ }
3338
+ 49.99% {
3339
+ transform: translateX(-101%);
3340
+ }
3341
+ 50% {
3342
+ transform: translateX(101%);
3343
+ }
3344
+ }
3345
+
3346
+ /* Mobile responsive */
3347
+ @media (max-width: 750px) {
3348
+ .taskon-rewards-row-inner {
3349
+ gap: 1.333vw;
3350
+ }
3351
+ }
3352
+ /**
3353
+ * TaskChainCard Styles
3354
+ */
3355
+
3356
+ /* Wrapper with stacked card effect */
3357
+ .taskon-taskchain-card-wrapper {
3358
+ position: relative;
3359
+ height: 100%;
3360
+ padding-top: 30px;
3361
+ }
3362
+
3363
+ /* Stacked cards behind main card */
3364
+ .taskon-taskchain-card-stack {
3365
+ position: absolute;
3366
+ border: 1px solid rgba(255, 255, 255, 0.08);
3367
+ border-radius: 10px;
3368
+ height: 40px;
3369
+ box-shadow: 0 -1px 2px 0 rgba(0, 0, 0, 0.1);
3370
+ }
3371
+
3372
+ .taskon-taskchain-card-stack--1 {
3373
+ left: 37px;
3374
+ right: 37px;
3375
+ top: 4px;
3376
+ background: #1a1a1a;
3377
+ }
3378
+
3379
+ .taskon-taskchain-card-stack--2 {
3380
+ left: 24px;
3381
+ right: 24px;
3382
+ top: 12px;
3383
+ background: #1f1f1f;
3384
+ }
3385
+
3386
+ .taskon-taskchain-card-stack--3 {
3387
+ left: 10px;
3388
+ right: 10px;
3389
+ top: 20px;
3390
+ background: #222222;
3391
+ }
3392
+
3393
+ /* Main card */
3394
+ .taskon-taskchain-card {
3395
+ position: relative;
3396
+ display: flex;
3397
+ flex-direction: column;
3398
+ min-height: 200px;
3399
+ padding: 20px;
3400
+ background-color: var(--taskon-bg-secondary, #252525);
3401
+ border-radius: 10px;
3402
+ cursor: pointer;
3403
+ overflow: hidden;
3404
+ transition: transform 0.2s, box-shadow 0.2s;
3405
+ }
3406
+
3407
+ .taskon-taskchain-card:hover {
3408
+ transform: translateY(-2px);
3409
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
3410
+ }
3411
+
3412
+ .taskon-taskchain-card--disabled {
3413
+ cursor: not-allowed;
3414
+ }
3415
+
3416
+ .taskon-taskchain-card--disabled:hover {
3417
+ transform: none;
3418
+ box-shadow: none;
3419
+ }
3420
+
3421
+ /* Card name */
3422
+ .taskon-taskchain-card-name {
3423
+ font-size: 16px;
3424
+ font-weight: 600;
3425
+ word-break: break-word;
3426
+ padding-right: 48px;
3427
+ color: var(--taskon-text-primary, #fff);
3428
+ }
3429
+
3430
+ /* Spots left */
3431
+ .taskon-taskchain-card-spots {
3432
+ display: flex;
3433
+ align-items: center;
3434
+ gap: 4px;
3435
+ margin-top: 10px;
3436
+ font-size: 14px;
3437
+ color: var(--taskon-text-primary, #fff);
3438
+ }
3439
+
3440
+ .taskon-taskchain-card-spots-label {
3441
+ color: var(--taskon-text-secondary, #999);
3442
+ }
3443
+
3444
+ /* Description */
3445
+ .taskon-taskchain-card-desc {
3446
+ margin-top: 8px;
3447
+ margin-bottom: 16px;
3448
+ font-size: 14px;
3449
+ color: var(--taskon-text-secondary, #999);
3450
+ line-height: 1.5;
3451
+ display: -webkit-box;
3452
+ -webkit-line-clamp: 2;
3453
+ -webkit-box-orient: vertical;
3454
+ overflow: hidden;
3455
+ }
3456
+
3457
+ /* Footer */
3458
+ .taskon-taskchain-card-footer {
3459
+ display: flex;
3460
+ align-items: center;
3461
+ margin-top: auto;
3462
+ }
3463
+
3464
+ /* Rewards container */
3465
+ .taskon-taskchain-card-rewards {
3466
+ display: flex;
3467
+ gap: 8px;
3468
+ flex: 1;
3469
+ min-width: 0;
3470
+ overflow: hidden;
3471
+ }
3472
+
3473
+ /* Individual reward item */
3474
+ .taskon-taskchain-card-reward-item {
3475
+ display: flex;
3476
+ align-items: center;
3477
+ gap: 4px;
3478
+ padding: 8px;
3479
+ background-color: rgba(255, 255, 255, 0.05);
3480
+ border-radius: 4px;
3481
+ flex-shrink: 0;
3482
+ }
3483
+
3484
+ /* Reward icon */
3485
+ .taskon-taskchain-card-reward-icon {
3486
+ width: 20px;
3487
+ height: 20px;
3488
+ border-radius: 50%;
3489
+ }
3490
+
3491
+ /* Reward amount */
3492
+ .taskon-taskchain-card-reward-amount {
3493
+ font-size: 14px;
3494
+ font-weight: 600;
3495
+ color: #eeb803;
3496
+ }
3497
+
3498
+ .taskon-taskchain-card-reward-amount--points {
3499
+ color: #00ffa3;
3500
+ }
3501
+
3502
+ /* Reward name */
3503
+ .taskon-taskchain-card-reward-name {
3504
+ font-size: 14px;
3505
+ color: var(--taskon-text-primary, #fff);
3506
+ }
3507
+
3508
+ /* NFT reward icon (rounded corners for NFT images) */
3509
+ .taskon-taskchain-card-reward-icon--nft {
3510
+ border-radius: 50%;
3511
+ object-fit: cover;
3512
+ }
3513
+
3514
+ /* NFT reward name (with truncation for long names) */
3515
+ .taskon-taskchain-card-reward-name--nft {
3516
+ max-width: 150px;
3517
+ white-space: nowrap;
3518
+ overflow: hidden;
3519
+ text-overflow: ellipsis;
3520
+ }
3521
+
3522
+ /* Won status */
3523
+ .taskon-taskchain-card-won {
3524
+ margin-left: 16px;
3525
+ font-size: 14px;
3526
+ font-weight: 600;
3527
+ color: #27ae60;
3528
+ flex-shrink: 0;
3529
+ }
3530
+
3531
+ /* Overlays */
3532
+ .taskon-taskchain-card-overlay {
3533
+ position: absolute;
3534
+ inset: 0;
3535
+ display: flex;
3536
+ align-items: center;
3537
+ justify-content: center;
3538
+ border-radius: inherit;
3539
+ }
3540
+
3541
+ .taskon-taskchain-card-overlay--ended {
3542
+ background-color: rgba(0, 0, 0, 0.7);
3543
+ }
3544
+
3545
+ .taskon-taskchain-card-overlay-text {
3546
+ font-size: 16px;
3547
+ font-weight: 600;
3548
+ color: #fff;
3549
+ text-transform: uppercase;
3550
+ }
3551
+
3552
+ .taskon-taskchain-card-overlay--locked {
3553
+ background-color: rgba(0, 0, 0, 0.5);
3554
+ backdrop-filter: blur(2px);
3555
+ }
3556
+
3557
+ /* Lock icon */
3558
+ .taskon-taskchain-card-lock-icon {
3559
+ width: 72px;
3560
+ height: 72px;
3561
+ }
3562
+
3563
+ /* Lock hover content */
3564
+ .taskon-taskchain-card-lock-hover {
3565
+ position: absolute;
3566
+ inset: 0;
3567
+ display: flex;
3568
+ flex-direction: column;
3569
+ align-items: center;
3570
+ justify-content: center;
3571
+ gap: 16px;
3572
+ background-color: rgba(255, 255, 255, 0.1);
3573
+ backdrop-filter: blur(10px);
3574
+ border-radius: inherit;
3575
+ opacity: 0;
3576
+ transition: opacity 0.2s;
3577
+ }
3578
+
3579
+ .taskon-taskchain-card-overlay--locked:hover .taskon-taskchain-card-lock-icon:first-child {
3580
+ display: none;
3581
+ }
3582
+
3583
+ .taskon-taskchain-card-overlay--locked:hover .taskon-taskchain-card-lock-hover {
3584
+ opacity: 1;
3585
+ }
3586
+
3587
+ .taskon-taskchain-card-lock-hover .taskon-taskchain-card-lock-icon {
3588
+ width: 64px;
3589
+ height: 64px;
3590
+ }
3591
+
3592
+ /* Lock text */
3593
+ .taskon-taskchain-card-lock-text {
3594
+ font-size: 14px;
3595
+ text-align: center;
3596
+ color: #fff;
3597
+ white-space: nowrap;
3598
+ }
3599
+
3600
+ .taskon-taskchain-card-lock-highlight {
3601
+ color: #00ffa3;
3602
+ text-transform: capitalize;
3603
+ }
3604
+
3605
+ /* Mobile responsive */
3606
+ @media (max-width: 750px) {
3607
+ .taskon-taskchain-card-wrapper {
3608
+ padding-top: 20px;
3609
+ }
3610
+
3611
+ .taskon-taskchain-card-stack {
3612
+ border-radius: 8px;
3613
+ height: 20px;
3614
+ }
3615
+
3616
+ .taskon-taskchain-card-stack--1 {
3617
+ left: 28px;
3618
+ right: 28px;
3619
+ top: 2px;
3620
+ }
3621
+
3622
+ .taskon-taskchain-card-stack--2 {
3623
+ left: 18px;
3624
+ right: 18px;
3625
+ top: 8px;
3626
+ }
3627
+
3628
+ .taskon-taskchain-card-stack--3 {
3629
+ left: 8px;
3630
+ right: 8px;
3631
+ top: 14px;
3632
+ }
3633
+
3634
+ .taskon-taskchain-card {
3635
+ min-height: 50vw;
3636
+ padding: 16px;
3637
+ border-radius: 8px;
3638
+ }
3639
+
3640
+ .taskon-taskchain-card-name {
3641
+ font-size: 14px;
3642
+ padding-right: 24px;
3643
+ }
3644
+
3645
+ .taskon-taskchain-card-spots {
3646
+ margin-top: 8px;
3647
+ font-size: 12px;
3648
+ }
3649
+
3650
+ .taskon-taskchain-card-desc {
3651
+ font-size: 12px;
3652
+ }
3653
+
3654
+ .taskon-taskchain-card-rewards {
3655
+ gap: 6px;
3656
+ }
3657
+
3658
+ .taskon-taskchain-card-reward-item {
3659
+ padding: 6px;
3660
+ }
3661
+
3662
+ .taskon-taskchain-card-reward-icon {
3663
+ width: 16px;
3664
+ height: 16px;
3665
+ }
3666
+
3667
+ .taskon-taskchain-card-reward-amount,
3668
+ .taskon-taskchain-card-reward-name {
3669
+ font-size: 12px;
3670
+ }
3671
+
3672
+ .taskon-taskchain-card-lock-icon {
3673
+ width: 48px;
3674
+ height: 48px;
3675
+ }
3676
+
3677
+ .taskon-taskchain-card-lock-hover .taskon-taskchain-card-lock-icon {
3678
+ width: 40px;
3679
+ height: 40px;
3680
+ }
3681
+
3682
+ .taskon-taskchain-card-lock-text {
3683
+ font-size: 12px;
3684
+ }
3685
+ }
3686
+ /**
3687
+ * SectorItem 组件样式
3688
+ * 完全复刻 taskon-website 的 SectorItem.vue 样式
3689
+ * 直接使用 dark 模式颜色值,不使用 CSS 变量
3690
+ * 使用 taskon-sector- 前缀避免与项目方样式冲突
3691
+ */
3692
+
3693
+ /* Sector 容器 */
3694
+ .taskon-sector-item {
3695
+ margin-top: 20px;
3696
+ border-radius: 12px;
3697
+ }
3698
+
3699
+ /* 多个 Sector 之间的间距 */
3700
+ .taskon-sector-item + .taskon-sector-item {
3701
+ margin-top: 60px;
3702
+ }
3703
+
3704
+ /* Sector 标题 */
3705
+ .taskon-sector-name {
3706
+ font-size: 24px;
3707
+ font-weight: 700;
3708
+ line-height: 40px;
3709
+ color: #ffffff;
3710
+ margin: 0;
3711
+ }
3712
+
3713
+ /* Sector 描述 */
3714
+ .taskon-sector-desc {
3715
+ margin-top: 4px;
3716
+ color: rgba(255, 255, 255, 0.6);
3717
+ font-size: 16px;
3718
+ line-height: 20px;
3719
+ white-space: pre-wrap;
3720
+ }
3721
+
3722
+ /* 总积分容器 */
3723
+ .taskon-sector-points-wrapper {
3724
+ margin-top: 10px;
3725
+ display: flex;
3726
+ flex-wrap: wrap;
3727
+ gap: 10px;
3728
+ }
3729
+
3730
+ /* 单个积分徽章 */
3731
+ .taskon-sector-point {
3732
+ display: inline-flex;
3733
+ align-items: center;
3734
+ padding: 4px 14px;
3735
+ border-radius: 48px;
3736
+ background: #cbff01; /* Primary 主题色 */
3737
+ color: #0d0d0d;
3738
+ font-size: 18px;
3739
+ font-weight: 500;
3740
+ line-height: 30px;
3741
+ }
3742
+
3743
+ .taskon-sector-point img {
3744
+ width: 24px;
3745
+ height: 24px;
3746
+ object-fit: contain;
3747
+ }
3748
+
3749
+ /* 任务列表 - 使用 grid 布局 */
3750
+ .taskon-sector-tasks {
3751
+ margin-top: 20px;
3752
+ display: grid;
3753
+ gap: 20px;
3754
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
3755
+ }
3756
+
3757
+ /* 已完成分隔符 */
3758
+ .taskon-sector-completed {
3759
+ margin-top: 22px;
3760
+ color: #ffffff;
3761
+ font-size: 16px;
3762
+ font-weight: 600;
3763
+ line-height: 20px;
3764
+ }
3765
+
3766
+ /* 已完成任务列表 */
3767
+ .taskon-sector-tasks-completed {
3768
+ margin-top: 22px;
3769
+ }
3770
+
3771
+ /* 任务卡片容器 - 用于包裹 BaseTask 组件 */
3772
+ .taskon-sector-task-card {
3773
+ height: 100%;
3774
+ }
3775
+
3776
+ /* 响应式样式(移动端) */
3777
+ @media (max-width: 750px) {
3778
+ .taskon-sector-item {
3779
+ margin-top: 5.33vw;
3780
+ border-radius: 1.87vw;
3781
+ }
3782
+
3783
+ .taskon-sector-item + .taskon-sector-item {
3784
+ margin-top: 8vw;
3785
+ }
3786
+
3787
+ .taskon-sector-name {
3788
+ font-size: 4.5vw;
3789
+ line-height: 6vw;
3790
+ }
3791
+
3792
+ .taskon-sector-desc {
3793
+ margin-top: 1.067vw;
3794
+ font-size: 3.2vw;
3795
+ line-height: 3.73vw;
3796
+ }
3797
+
3798
+ .taskon-sector-points-wrapper {
3799
+ margin-top: 3.2vw;
3800
+ gap: 2.67vw;
3801
+ }
3802
+
3803
+ .taskon-sector-point {
3804
+ margin-top: 3.2vw;
3805
+ font-size: 4.27vw;
3806
+ line-height: 5.6vw;
3807
+ }
3808
+
3809
+ .taskon-sector-point img {
3810
+ width: 4.27vw;
3811
+ height: 4.27vw;
3812
+ }
3813
+
3814
+ .taskon-sector-tasks {
3815
+ grid-template-columns: repeat(1, 1fr);
3816
+ gap: 4vw;
3817
+ margin-top: 5.333vw;
3818
+ }
3819
+
3820
+ .taskon-sector-completed {
3821
+ margin-top: 5.87vw;
3822
+ font-size: 4.27vw;
3823
+ line-height: 5.33vw;
3824
+ }
3825
+
3826
+ .taskon-sector-tasks-completed {
3827
+ margin-top: 5.87vw;
3828
+ }
3829
+ }
3830
+ /**
3831
+ * DialogPointReward 组件样式
3832
+ * 复刻 Vue 版本 DialogPointReward.vue 的样式
3833
+ * 使用 Widget 命名空间扁平化方案
3834
+ */
3835
+
3836
+ /* ==================== 周期模式 ==================== */
3837
+ .taskon-task-dialog-period {
3838
+ margin-top: 10px;
3839
+ display: flex;
3840
+ align-items: flex-end;
3841
+ color: var(--taskon-color-text, #fff);
3842
+ }
3843
+
3844
+ /* 周期模式 - 积分数量 */
3845
+ .taskon-task-dialog-period-amount {
3846
+ font-size: 32px;
3847
+ line-height: 40px;
3848
+ display: flex;
3849
+ align-items: center;
3850
+ }
3851
+
3852
+ /* 周期模式 - 累计积分强调 */
3853
+ .taskon-task-dialog-period-amount--em {
3854
+ margin-left: 15px;
3855
+ color: #00ffa3;
3856
+ }
3857
+
3858
+ /* 周期模式 - 积分图标 */
3859
+ .taskon-task-dialog-period-icon {
3860
+ display: inline-block;
3861
+ width: 24px;
3862
+ height: 24px;
3863
+ margin-right: 4px;
3864
+ vertical-align: baseline;
3865
+ }
3866
+
3867
+ /* 周期模式 - 标签文字 */
3868
+ .taskon-task-dialog-period-label {
3869
+ margin-left: 6px;
3870
+ font-size: 14px;
3871
+ font-weight: 600;
3872
+ line-height: 28px;
3873
+ }
3874
+
3875
+ /* 周期模式 - 累计标签强调 */
3876
+ .taskon-task-dialog-period-label--em {
3877
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.7));
3878
+ }
3879
+
3880
+ /* ==================== Unlimited 模式 ==================== */
3881
+ .taskon-task-dialog-uncertain-amount {
3882
+ color: #00ffa3;
3883
+ font-size: 32px;
3884
+ font-weight: 600;
3885
+ }
3886
+
3887
+ /* ==================== 社区信息 ==================== */
3888
+ .taskon-task-dialog-cm-logo {
3889
+ margin-left: auto;
3890
+ width: 16px;
3891
+ height: 16px;
3892
+ border-radius: 50%;
3893
+ object-fit: cover;
3894
+ }
3895
+
3896
+ .taskon-task-dialog-cm-name {
3897
+ margin-left: 6px;
3898
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.7));
3899
+ font-size: 14px;
3900
+ font-weight: 500;
3901
+ line-height: 18px;
3902
+ }
3903
+
3904
+ /* ==================== 响应式 ==================== */
3905
+ @media (max-width: 750px) {
3906
+ .taskon-task-dialog-period {
3907
+ margin-top: 2.667vw;
3908
+ }
3909
+
3910
+ .taskon-task-dialog-period-amount {
3911
+ font-size: 6.4vw;
3912
+ line-height: 8vw;
3913
+ }
3914
+
3915
+ .taskon-task-dialog-period-amount--em {
3916
+ margin-left: 4vw;
3917
+ }
3918
+
3919
+ .taskon-task-dialog-period-icon {
3920
+ width: 4.667vw;
3921
+ height: 4.667vw;
3922
+ margin-right: 0.8vw;
3923
+ }
3924
+
3925
+ .taskon-task-dialog-period-label {
3926
+ margin-left: 1.333vw;
3927
+ font-size: 3.2vw;
3928
+ line-height: 4vw;
3929
+ }
3930
+
3931
+ .taskon-task-dialog-uncertain-amount {
3932
+ font-size: 6.133vw;
3933
+ }
3934
+
3935
+ .taskon-task-dialog-cm-logo {
3936
+ width: 3.2vw;
3937
+ height: 3.2vw;
3938
+ }
3939
+
3940
+ .taskon-task-dialog-cm-name {
3941
+ margin-left: 1.2vw;
3942
+ font-size: 3.2vw;
3943
+ line-height: 4vw;
3944
+ }
3945
+ }
3946
+ /**
3947
+ * DialogTokenReward 组件样式
3948
+ * 复刻 Vue 版本 DialogTokenReward.vue 的样式
3949
+ * 使用 Widget 命名空间扁平化方案
3950
+ */
3951
+
3952
+ /* 链图标 */
3953
+ .taskon-task-dialog-token-chain-icon {
3954
+ display: inline-block;
3955
+ width: 12px;
3956
+ height: 12px;
3957
+ object-fit: cover;
3958
+ margin-left: 6px;
3959
+ }
3960
+
3961
+ /* Token 信息容器(图标 + 名称 + earned) */
3962
+ .taskon-task-dialog-token-info {
3963
+ display: flex;
3964
+ align-items: center;
3965
+ }
3966
+
3967
+ /* Token 奖励专用的 period-label(覆盖 DialogPointReward.css 的 6px) */
3968
+ .taskon-task-dialog-token-period-label {
3969
+ margin-left: 4px;
3970
+ font-size: 14px;
3971
+ font-weight: 600;
3972
+ line-height: 28px;
3973
+ }
3974
+
3975
+ .taskon-task-dialog-token-period-label--em {
3976
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.7));
3977
+ }
3978
+
3979
+ /* ==================== 响应式 ==================== */
3980
+ @media (max-width: 750px) {
3981
+ .taskon-task-dialog-token-chain-icon {
3982
+ width: 2.4vw;
3983
+ height: 2.4vw;
3984
+ margin-left: 1.2vw;
3985
+ }
3986
+
3987
+ .taskon-task-dialog-token-period-label {
3988
+ margin-left: 0.8vw;
3989
+ font-size: 3.2vw;
3990
+ line-height: 4vw;
3991
+ }
3992
+ }
3993
+ /**
3994
+ * ColorfulProgress 组件样式
3995
+ * 复刻 Vue 版本 ColorfulProgress.vue 的样式
3996
+ * 使用 Widget 命名空间扁平化方案
3997
+ */
3998
+
3999
+ /* 进度条容器 */
4000
+ .taskon-task-dialog-colorful-progress {
4001
+ position: relative;
4002
+ width: 100%;
4003
+ height: 8px;
4004
+ background-color: rgba(255, 255, 255, 0.2);
4005
+ border-radius: 2px;
4006
+ overflow: hidden;
4007
+ }
4008
+
4009
+ /* 进度条 - 渐变填充 */
4010
+ .taskon-task-dialog-colorful-progress__bar {
4011
+ position: absolute;
4012
+ right: 0;
4013
+ bottom: 0;
4014
+ height: 100%;
4015
+ display: flex;
4016
+ align-items: center;
4017
+ gap: 6px;
4018
+ /* 渐变背景: 绿色 -> 黄绿色 */
4019
+ background: linear-gradient(90deg, #00ffa3 -229.89%, #cbff01 100%);
4020
+ border-radius: 2px;
4021
+ overflow: hidden;
4022
+ }
4023
+
4024
+ /* 斜纹波浪 */
4025
+ .taskon-task-dialog-colorful-progress__wave {
4026
+ width: 3px;
4027
+ flex-shrink: 0;
4028
+ height: 200%;
4029
+ transform: rotate(45deg);
4030
+ background: rgba(0, 0, 0, 0.1);
4031
+ }
4032
+
4033
+ /* ==================== 响应式 ==================== */
4034
+ @media (max-width: 750px) {
4035
+ .taskon-task-dialog-colorful-progress {
4036
+ height: 1.6vw;
4037
+ }
4038
+ }
4039
+ /**
4040
+ * TokenStatusLeft 组件样式
4041
+ * 复刻 Vue 版本 TokenStatusLeft.vue 的样式
4042
+ * 使用 Widget 命名空间扁平化方案
4043
+ */
4044
+
4045
+ /* 容器 */
4046
+ .taskon-task-dialog-token-progress {
4047
+ display: flex;
4048
+ justify-content: flex-start;
4049
+ align-items: center;
4050
+ gap: 8px;
4051
+ }
4052
+
4053
+ /* 文字部分 */
4054
+ .taskon-task-dialog-token-progress__content {
4055
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.7));
4056
+ font-size: 14px;
4057
+ font-weight: 500;
4058
+ }
4059
+
4060
+ /* 高亮数字 */
4061
+ .taskon-task-dialog-token-progress__text {
4062
+ color: #00ffa3;
4063
+ }
4064
+
4065
+ /* 进度条容器 */
4066
+ .taskon-task-dialog-token-progress__bar {
4067
+ width: 66px;
4068
+ }
4069
+
4070
+ /* ==================== 响应式 ==================== */
4071
+ @media (max-width: 750px) {
4072
+ .taskon-task-dialog-token-progress__content {
4073
+ font-size: 3.2vw;
4074
+ }
4075
+
4076
+ .taskon-task-dialog-token-progress__bar {
4077
+ width: 12vw;
4078
+ }
4079
+ }
4080
+ /**
4081
+ * CloseIn 样式
4082
+ * 复刻 Vue 版本 CloseIn.vue 样式
4083
+ */
4084
+
4085
+ .taskon-close-in {
4086
+ margin-top: 30px;
4087
+ color: var(--taskon-primary-100, #6366f1);
4088
+ text-align: center;
4089
+ font-size: 14px;
4090
+ font-weight: 500;
4091
+ line-height: 18px;
4092
+ }
4093
+ /**
4094
+ * TaskDialogContent 组件样式
4095
+ * 复刻 Vue 版本 TaskDialog.vue 的样式
4096
+ * 使用 Widget 命名空间扁平化方案
4097
+ */
4098
+
4099
+ /* ==================== 左侧面板 ==================== */
4100
+ .taskon-task-dialog-left {
4101
+ width: 440px;
4102
+ display: flex;
4103
+ flex-direction: column;
4104
+ }
4105
+
4106
+ /* 主内容区 */
4107
+ .taskon-task-dialog-main {
4108
+ flex: 1;
4109
+ }
4110
+
4111
+ /* ==================== 周期标签 ==================== */
4112
+ .taskon-task-dialog-recurrence {
4113
+ display: inline-block;
4114
+ padding: 3px 12px;
4115
+ border-radius: 4px;
4116
+ background: rgba(255, 255, 255, 0.04);
4117
+ color: var(--taskon-color-text-secondary, #a0a0a0);
4118
+ font-size: 13px;
4119
+ line-height: 16px;
4120
+ }
4121
+
4122
+ /* ==================== 标题 ==================== */
4123
+ .taskon-task-dialog-title {
4124
+ margin: 20px 0 0 0;
4125
+ color: var(--taskon-color-text, #fff);
4126
+ font-size: 22px;
4127
+ font-weight: 600;
4128
+ line-height: 28px;
4129
+ }
4130
+
4131
+ /* 标题链接样式 */
4132
+ .taskon-task-dialog-title--link {
4133
+ display: block;
4134
+ text-decoration: none;
4135
+ color: var(--taskon-color-primary, #6366f1);
4136
+ transition: color 0.2s ease;
4137
+ }
4138
+
4139
+ .taskon-task-dialog-title--link:hover {
4140
+ color: var(--taskon-color-primary-hover, #818cf8);
4141
+ text-decoration: underline;
4142
+ }
4143
+
4144
+ /* ==================== 有效时间 - 复刻 Vue valid-util ==================== */
4145
+ .taskon-task-dialog-valid-time {
4146
+ margin-top: 10px;
4147
+ font-size: 14px;
4148
+ line-height: 18px;
4149
+ }
4150
+
4151
+ .taskon-task-dialog-valid-time-label {
4152
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.5));
4153
+ }
4154
+
4155
+ .taskon-task-dialog-valid-time-value {
4156
+ margin-left: 4px;
4157
+ color: var(--taskon-color-text, #fff);
4158
+ }
4159
+
4160
+ /* ==================== 描述区域 ==================== */
4161
+ .taskon-task-dialog-desc {
4162
+ margin-top: 15px;
4163
+ }
4164
+
4165
+ /* ==================== Action 按钮 - 复刻 Vue ActionButton ==================== */
4166
+ .taskon-task-dialog-action {
4167
+ margin-top: 30px;
4168
+ width: 100%;
4169
+ height: 40px;
4170
+ padding: 0 16px;
4171
+ display: flex;
4172
+ align-items: center;
4173
+ justify-content: center;
4174
+ border-radius: 6px;
4175
+ border: none;
4176
+ /* Vue: --primary-12 深蓝色背景 */
4177
+ background: rgba(203, 255, 1, 0.12);
4178
+ /* Vue: --primary-100 黄色文字 */
4179
+ color: var(--taskon-color-primary, #cbff01);
4180
+ font-size: 14px;
4181
+ font-weight: 500;
4182
+ line-height: 40px;
4183
+ cursor: pointer;
4184
+ transition: all 0.2s;
4185
+ }
4186
+
4187
+ .taskon-task-dialog-action:hover {
4188
+ background: var(--taskon-color-primary, #cbff01);
4189
+ color: #0d0d0d;
4190
+ }
4191
+
4192
+ /* ==================== 奖励卡片 ==================== */
4193
+ .taskon-task-dialog-reward-card {
4194
+ position: relative;
4195
+ margin-top: 30px;
4196
+ padding: 20px;
4197
+ border-radius: 10px;
4198
+ /* Vue: --color-invisible 在深色主题下是略亮的半透明 */
4199
+ background: rgba(255, 255, 255, 0.06);
4200
+ }
4201
+
4202
+ /* Max claim 标签 - 复刻 Vue rewards-max-claim */
4203
+ .taskon-task-dialog-max-claim {
4204
+ position: absolute;
4205
+ top: -24px;
4206
+ right: 6px;
4207
+ height: 24px;
4208
+ padding: 3px 12px;
4209
+ display: flex;
4210
+ align-items: center;
4211
+ gap: 4px;
4212
+ /* Vue: --color-lightest-inverse 深色文字 */
4213
+ color: var(--taskon-color-text-inverse, #0d0d0d);
4214
+ font-size: 14px;
4215
+ font-style: normal;
4216
+ font-weight: 600;
4217
+ line-height: normal;
4218
+ /* Vue: --color-lightest 亮色背景 */
4219
+ background: var(--taskon-color-bg-inverse, #fff);
4220
+ border-radius: 8px 8px 0 0;
4221
+ }
4222
+
4223
+ .taskon-task-dialog-max-claim--highlight {
4224
+ /* Vue: --secondary-100 高亮色 */
4225
+ color: var(--taskon-color-secondary, #7c3aed);
4226
+ }
4227
+
4228
+ /* 标签行 */
4229
+ .taskon-task-dialog-label-row {
4230
+ display: flex;
4231
+ align-items: center;
4232
+ justify-content: space-between;
4233
+ height: 24px;
4234
+ }
4235
+
4236
+ /* Rewards 标签 */
4237
+ .taskon-task-dialog-rewards-label {
4238
+ color: var(--taskon-color-text, #fff);
4239
+ font-size: 14px;
4240
+ line-height: 18px;
4241
+ font-weight: 600;
4242
+ }
4243
+
4244
+ /* Won 标签 */
4245
+ .taskon-task-dialog-won {
4246
+ margin-left: auto;
4247
+ border-radius: 4px;
4248
+ background: rgba(255, 255, 255, 0.04);
4249
+ padding: 3px 12px;
4250
+ color: #27ae60;
4251
+ font-size: 14px;
4252
+ font-weight: 600;
4253
+ line-height: 18px;
4254
+ }
4255
+
4256
+ /* Updated at 标签 - Unlimited 任务专用,复刻 Vue updated-label */
4257
+ .taskon-task-dialog-updated {
4258
+ margin-left: auto;
4259
+ /* Vue: --color-dark 半透明白色 */
4260
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.5));
4261
+ font-size: 12px;
4262
+ font-weight: 500;
4263
+ }
4264
+
4265
+ /* ==================== 周期任务倒计时 - 复刻 Vue periodic-done ==================== */
4266
+ .taskon-task-dialog-periodic-done {
4267
+ margin-left: auto;
4268
+ display: flex;
4269
+ align-items: center;
4270
+ color: var(--taskon-color-text-secondary, rgba(255, 255, 255, 0.7));
4271
+ font-size: 13px;
4272
+ line-height: 16px;
4273
+ }
4274
+
4275
+ /* 分隔线 */
4276
+ .taskon-task-dialog-periodic-done__line {
4277
+ margin: 0 6px;
4278
+ width: 1px;
4279
+ height: 10px;
4280
+ background: var(--taskon-color-border, rgba(255, 255, 255, 0.2));
4281
+ }
4282
+
4283
+ /* 倒计时数字 */
4284
+ .taskon-task-dialog-periodic-done__time {
4285
+ margin-left: 4px;
4286
+ /* Vue: --secondary-100 绿色强调 */
4287
+ color: #00ffa3;
4288
+ font-size: 14px;
4289
+ font-weight: 500;
4290
+ line-height: 18px;
4291
+ }
4292
+
4293
+ /* ==================== 积分展示 ==================== */
4294
+ .taskon-task-dialog-point-row {
4295
+ margin-top: 10px;
4296
+ display: flex;
4297
+ align-items: center;
4298
+ /* Vue: --color-light 白色 */
4299
+ color: var(--taskon-color-text, #fff);
4300
+ }
4301
+
4302
+ .taskon-task-dialog-point-icon {
4303
+ display: inline-block;
4304
+ width: 24px;
4305
+ height: 24px;
4306
+ margin-right: 4px;
4307
+ vertical-align: baseline;
4308
+ }
4309
+
4310
+ .taskon-task-dialog-point-amount {
4311
+ color: #00ffa3;
4312
+ font-size: 32px;
4313
+ font-weight: 600;
4314
+ line-height: 40px;
4315
+ }
4316
+
4317
+ .taskon-task-dialog-point-name {
4318
+ margin-left: auto;
4319
+ color: var(--taskon-color-text-secondary, #a0a0a0);
4320
+ font-size: 14px;
4321
+ font-weight: 500;
4322
+ line-height: 18px;
4323
+ }
4324
+
4325
+ /* ==================== Claim 按钮 ==================== */
4326
+ .taskon-task-dialog-claim {
4327
+ margin-top: 20px;
4328
+ }
4329
+
4330
+ /* Token 进度条容器 */
4331
+ .taskon-task-dialog-token-progress-wrap {
4332
+ margin-top: 10px;
4333
+ display: flex;
4334
+ align-items: center;
4335
+ justify-content: center;
4336
+ }
4337
+
4338
+ /* 弹窗内 Claim 按钮样式覆盖 */
4339
+ .taskon-task-dialog-claim .taskon-community-task-claim {
4340
+ width: 100%;
4341
+ padding: 12px 24px;
4342
+ font-size: 14px;
4343
+ font-weight: 600;
4344
+ }
4345
+
4346
+ /* ==================== 响应式 ==================== */
4347
+ @media (max-width: 750px) {
4348
+ .taskon-task-dialog-left {
4349
+ width: 100%;
4350
+ }
4351
+
4352
+ .taskon-task-dialog-recurrence {
4353
+ padding: 0.667vw 2.667vw;
4354
+ font-size: 2.667vw;
4355
+ line-height: 3.467vw;
4356
+ }
4357
+
4358
+ .taskon-task-dialog-title {
4359
+ margin-top: 4vw;
4360
+ font-size: 4.267vw;
4361
+ line-height: 5.333vw;
4362
+ }
4363
+
4364
+ .taskon-task-dialog-valid-time {
4365
+ margin-top: 2.667vw;
4366
+ font-size: 3.733vw;
4367
+ line-height: 4.667vw;
4368
+ }
4369
+
4370
+ .taskon-task-dialog-valid-time-value {
4371
+ margin-left: 1.067vw;
4372
+ }
4373
+
4374
+ .taskon-task-dialog-desc {
4375
+ margin-top: 2.667vw;
4376
+ }
4377
+
4378
+ .taskon-task-dialog-action {
4379
+ margin-top: 5.333vw;
4380
+ height: 11vw;
4381
+ padding: 0 4vw;
4382
+ font-size: 3.733vw;
4383
+ line-height: 11vw;
4384
+ }
4385
+
4386
+ .taskon-task-dialog-reward-card {
4387
+ margin-top: 5.333vw;
4388
+ padding: 4vw;
4389
+ }
4390
+
4391
+ .taskon-task-dialog-label-row {
4392
+ height: 4vw;
4393
+ }
4394
+
4395
+ .taskon-task-dialog-rewards-label {
4396
+ font-size: 3.2vw;
4397
+ line-height: 4vw;
4398
+ }
4399
+
4400
+ .taskon-task-dialog-won {
4401
+ font-size: 3.2vw;
4402
+ line-height: 4vw;
4403
+ padding: 0.533vw 2.4vw;
4404
+ }
4405
+
4406
+ .taskon-task-dialog-updated {
4407
+ font-size: 3.2vw;
4408
+ }
4409
+
4410
+ /* 周期任务倒计时响应式 */
4411
+ .taskon-task-dialog-periodic-done {
4412
+ font-size: 2.667vw;
4413
+ line-height: 3.467vw;
4414
+ }
4415
+
4416
+ .taskon-task-dialog-periodic-done__line {
4417
+ margin: 0 1.2vw;
4418
+ height: 2vw;
4419
+ }
4420
+
4421
+ .taskon-task-dialog-periodic-done__time {
4422
+ margin-left: 0.8vw;
4423
+ font-size: 3.2vw;
4424
+ line-height: 4vw;
4425
+ }
4426
+
4427
+ .taskon-task-dialog-point-row {
4428
+ margin-top: 2.667vw;
4429
+ }
4430
+
4431
+ .taskon-task-dialog-point-amount {
4432
+ font-size: 6.4vw;
4433
+ line-height: 8vw;
4434
+ }
4435
+
4436
+ .taskon-task-dialog-point-icon {
4437
+ width: 4.667vw;
4438
+ height: 4.667vw;
4439
+ margin-right: 0.8vw;
4440
+ }
4441
+
4442
+ .taskon-task-dialog-point-name {
4443
+ font-size: 3.2vw;
4444
+ line-height: 4vw;
4445
+ }
4446
+
4447
+ .taskon-task-dialog-claim {
4448
+ margin-top: 4vw;
4449
+ }
4450
+ }
4451
+ /**
4452
+ * PowImageUploader 组件样式
4453
+ * 使用 Widget 命名空间扁平化方案
4454
+ * 所有类名使用 .taskon-pow-uploader-* 前缀,避免跨 Widget 冲突
4455
+ */
4456
+
4457
+ .taskon-pow-uploader {
4458
+ margin-top: 20px;
4459
+ display: flex;
4460
+ align-items: center;
4461
+ }
4462
+
4463
+ .taskon-pow-uploader-area {
4464
+ flex: 1;
4465
+ position: relative;
4466
+ display: flex;
4467
+ flex-direction: column;
4468
+ align-items: center;
4469
+ justify-content: center;
4470
+ min-height: 128px;
4471
+ text-align: center;
4472
+ font-size: 0;
4473
+ overflow: hidden;
4474
+ border: 1px solid var(--taskon-color-border, #e2e8f0);
4475
+ border-radius: var(--taskon-border-radius, 8px);
4476
+ background: var(--taskon-color-bg, #ffffff);
4477
+ cursor: pointer;
4478
+ transition: border-color 0.2s ease, background-color 0.2s ease;
4479
+ }
4480
+
4481
+ .taskon-pow-uploader-area:hover,
4482
+ .taskon-pow-uploader-area:focus {
4483
+ border-color: var(--taskon-color-primary, #6366f1);
4484
+ outline: none;
4485
+ }
4486
+
4487
+ .taskon-pow-uploader-area:hover .taskon-pow-uploader-mask,
4488
+ .taskon-pow-uploader-area:focus .taskon-pow-uploader-mask {
4489
+ display: flex;
4490
+ }
4491
+
4492
+ .taskon-pow-uploader-area--disabled {
4493
+ cursor: not-allowed;
4494
+ opacity: 0.6;
4495
+ }
4496
+
4497
+ .taskon-pow-uploader-area--disabled:hover,
4498
+ .taskon-pow-uploader-area--disabled:focus {
4499
+ border-color: var(--taskon-color-border, #e2e8f0);
4500
+ }
4501
+
4502
+ /* 隐藏的文件输入 */
4503
+ .taskon-pow-uploader-input {
4504
+ display: none;
4505
+ }
4506
+
4507
+ /* 图片预览 */
4508
+ .taskon-pow-uploader-preview {
4509
+ border-radius: 4px;
4510
+ margin: 20px 0;
4511
+ max-width: 100%;
4512
+ max-height: 300px;
4513
+ object-fit: contain;
4514
+ }
4515
+
4516
+ /* 悬停遮罩 */
4517
+ .taskon-pow-uploader-mask {
4518
+ display: none;
4519
+ position: absolute;
4520
+ inset: 0;
4521
+ z-index: 2;
4522
+ align-items: center;
4523
+ justify-content: center;
4524
+ flex-direction: column;
4525
+ background: rgba(0, 0, 0, 0.8);
4526
+ }
4527
+
4528
+ /* 上传图标 */
4529
+ .taskon-pow-uploader-icon {
4530
+ width: 24px;
4531
+ height: 24px;
4532
+ color: #ffffff;
4533
+ }
4534
+
4535
+ .taskon-pow-uploader-icon--empty {
4536
+ opacity: 0.6;
4537
+ color: var(--taskon-color-text-secondary, #64748b);
4538
+ }
4539
+
4540
+ /* 提示文字 */
4541
+ .taskon-pow-uploader-tip {
4542
+ margin-top: 13px;
4543
+ font-size: 14px;
4544
+ line-height: 20px;
4545
+ letter-spacing: 0.04em;
4546
+ text-transform: uppercase;
4547
+ white-space: pre-wrap;
4548
+ color: #ffffff;
4549
+ }
4550
+
4551
+ .taskon-pow-uploader-tip--empty {
4552
+ opacity: 0.6;
4553
+ color: var(--taskon-color-text-secondary, #64748b);
4554
+ }
4555
+
4556
+ /* 上传进度条 */
4557
+ .taskon-pow-uploader-progress {
4558
+ z-index: 3;
4559
+ position: absolute;
4560
+ right: 0;
4561
+ bottom: 0;
4562
+ left: 0;
4563
+ background: rgba(255, 255, 255, 0.1);
4564
+ height: 6px;
4565
+ }
4566
+
4567
+ .taskon-pow-uploader-progress-bar {
4568
+ background: var(--taskon-color-primary, #6366f1);
4569
+ height: 100%;
4570
+ border-radius: 4px;
4571
+ transition: width 0.1s linear;
4572
+ }
4573
+
4574
+ /* 移动端适配 */
4575
+ @media (max-width: 750px) {
4576
+ .taskon-pow-uploader {
4577
+ margin-top: 2.67vw;
4578
+ }
4579
+
4580
+ .taskon-pow-uploader-area {
4581
+ min-height: 17.07vw;
4582
+ }
4583
+
4584
+ .taskon-pow-uploader-icon {
4585
+ width: 18px;
4586
+ height: 18px;
4587
+ }
4588
+
4589
+ .taskon-pow-uploader-tip {
4590
+ margin-top: 10px;
4591
+ font-size: 12px;
4592
+ line-height: 16px;
4593
+ }
4594
+
4595
+ .taskon-pow-uploader-preview {
4596
+ max-height: 200px;
4597
+ }
4598
+ }
4599
+ /**
4600
+ * PowTaskDialogContent 组件样式
4601
+ * 复刻 Vue 版本 PowTask.vue 弹窗样式
4602
+ */
4603
+
4604
+ /* ==================== 表单区域 ==================== */
4605
+ .taskon-pow-dialog-form {
4606
+ margin-top: 15px;
4607
+ }
4608
+
4609
+ /* ==================== 错误提示 ==================== */
4610
+ .taskon-pow-dialog-error {
4611
+ margin-top: 15px;
4612
+ color: #ff3a44;
4613
+ font-size: 14px;
4614
+ line-height: 20px;
4615
+ letter-spacing: 0.04em;
4616
+ text-align: left;
4617
+ white-space: nowrap;
4618
+ }
4619
+
4620
+ /* ==================== 提交按钮 ==================== */
4621
+ .taskon-pow-dialog-submit {
4622
+ margin-top: 30px;
4623
+ width: 100%;
4624
+ height: 40px;
4625
+ padding: 0 16px;
4626
+ display: flex;
4627
+ align-items: center;
4628
+ justify-content: center;
4629
+ border-radius: 6px;
4630
+ border: none;
4631
+ background: linear-gradient(270deg, #00ffa3 0%, #cbff01 100%);
4632
+ color: #0d0d0d;
4633
+ font-size: 14px;
4634
+ font-weight: 600;
4635
+ line-height: 40px;
4636
+ cursor: pointer;
4637
+ transition: opacity 0.2s;
4638
+ }
4639
+
4640
+ .taskon-pow-dialog-submit:hover {
4641
+ opacity: 0.9;
4642
+ }
4643
+
4644
+ .taskon-pow-dialog-submit:disabled {
4645
+ opacity: 0.6;
4646
+ cursor: not-allowed;
4647
+ }
4648
+
4649
+ /* ==================== 完成状态 ==================== */
4650
+ .taskon-pow-dialog-done {
4651
+ margin-top: 30px;
4652
+ padding: 12px 16px;
4653
+ border-radius: 6px;
4654
+ background: rgba(39, 174, 96, 0.1);
4655
+ color: #27ae60;
4656
+ font-size: 14px;
4657
+ font-weight: 500;
4658
+ text-align: center;
4659
+ }
4660
+
4661
+ /* ==================== 审核状态 ==================== */
4662
+ .taskon-pow-dialog-status--review {
4663
+ margin-left: auto;
4664
+ padding: 3px 12px;
4665
+ border-radius: 4px;
4666
+ background: rgba(255, 255, 255, 0.04);
4667
+ color: #9b51e0;
4668
+ font-size: 14px;
4669
+ font-weight: 600;
4670
+ line-height: 18px;
4671
+ }
4672
+
4673
+ .taskon-pow-dialog-status--failed {
4674
+ margin-left: auto;
4675
+ padding: 3px 12px;
4676
+ border-radius: 4px;
4677
+ background: rgba(255, 255, 255, 0.04);
4678
+ color: #eb5757;
4679
+ font-size: 14px;
4680
+ font-weight: 600;
4681
+ line-height: 18px;
4682
+ }
4683
+
4684
+ /* ==================== 响应式 ==================== */
4685
+ @media (max-width: 750px) {
4686
+ .taskon-pow-dialog-error {
4687
+ margin-top: 2.667vw;
4688
+ font-size: 2.933vw;
4689
+ line-height: 2.667vw;
4690
+ }
4691
+
4692
+ .taskon-pow-dialog-submit {
4693
+ margin-top: 5.333vw;
4694
+ height: 11vw;
4695
+ font-size: 3.733vw;
4696
+ line-height: 11vw;
4697
+ }
4698
+
4699
+ .taskon-pow-dialog-done {
4700
+ margin-top: 5.333vw;
4701
+ padding: 3.2vw 4.267vw;
4702
+ font-size: 3.733vw;
4703
+ }
4704
+
4705
+ .taskon-pow-dialog-status--review,
4706
+ .taskon-pow-dialog-status--failed {
4707
+ padding: 0.533vw 2.4vw;
4708
+ font-size: 3.2vw;
4709
+ line-height: 4vw;
4710
+ }
4711
+ }
4712
+ /**
4713
+ * SwapDexDialogContent 组件样式
4714
+ * 复刻 Vue 版本 SwapDexContractInteractive.vue 弹窗样式
4715
+ */
4716
+
4717
+ /* ==================== 进度显示 ==================== */
4718
+ .taskon-swap-dialog-progress {
4719
+ margin-left: auto;
4720
+ display: flex;
4721
+ align-items: center;
4722
+ gap: 4px;
4723
+ font-size: 16px;
4724
+ line-height: 20px;
4725
+ font-weight: 500;
4726
+ }
4727
+
4728
+ .taskon-swap-dialog-progress-current {
4729
+ color: #00ffa3;
4730
+ }
4731
+
4732
+ .taskon-swap-dialog-progress-separator {
4733
+ color: var(--taskon-color-text-secondary, #a0a0a0);
4734
+ margin: 0 2px;
4735
+ }
4736
+
4737
+ .taskon-swap-dialog-progress-total {
4738
+ color: var(--taskon-color-text-secondary, #a0a0a0);
4739
+ font-size: 14px;
4740
+ line-height: 18px;
4741
+ }
4742
+
4743
+ /* ==================== 内容区块 ==================== */
4744
+ .taskon-swap-dialog-section {
4745
+ margin-top: 16px;
4746
+ }
4747
+
4748
+ .taskon-swap-dialog-section-title {
4749
+ color: var(--taskon-color-text, #fff);
4750
+ font-size: 14px;
4751
+ font-weight: 600;
4752
+ line-height: 18px;
4753
+ }
4754
+
4755
+ .taskon-swap-dialog-section-content {
4756
+ margin-top: 8px;
4757
+ padding: 12px;
4758
+ border-radius: 8px;
4759
+ background: rgba(255, 255, 255, 0.04);
4760
+ color: var(--taskon-color-text, #fff);
4761
+ font-size: 14px;
4762
+ line-height: 18px;
4763
+ }
4764
+
4765
+ /* ==================== 响应式 ==================== */
4766
+ @media (max-width: 750px) {
4767
+ .taskon-swap-dialog-progress {
4768
+ gap: 1.067vw;
4769
+ font-size: 4.267vw;
4770
+ line-height: 5.333vw;
4771
+ }
4772
+
4773
+ .taskon-swap-dialog-progress-separator {
4774
+ margin: 0 0.533vw;
4775
+ }
4776
+
4777
+ .taskon-swap-dialog-progress-total {
4778
+ font-size: 3.733vw;
4779
+ line-height: 4.8vw;
4780
+ }
4781
+
4782
+ .taskon-swap-dialog-section {
4783
+ margin-top: 4.267vw;
4784
+ }
4785
+
4786
+ .taskon-swap-dialog-section-title {
4787
+ font-size: 3.733vw;
4788
+ line-height: 4.8vw;
4789
+ }
4790
+
4791
+ .taskon-swap-dialog-section-content {
4792
+ margin-top: 2.133vw;
4793
+ padding: 3.2vw;
4794
+ font-size: 3.2vw;
4795
+ line-height: 4.133vw;
4796
+ }
4797
+ }
4798
+ /**
4799
+ * DialogLoading 组件样式
4800
+ * 使用 Widget 命名空间扁平化方案
4801
+ */
4802
+
4803
+ .taskon-dialog-loading {
4804
+ display: flex;
4805
+ flex-direction: column;
4806
+ align-items: center;
4807
+ justify-content: center;
4808
+ min-height: 300px;
4809
+ width: 440px;
4810
+ gap: 16px;
4811
+ }
4812
+
4813
+ .taskon-dialog-loading-spinner {
4814
+ width: 40px;
4815
+ height: 40px;
4816
+ border: 3px solid rgba(255, 255, 255, 0.1);
4817
+ border-top-color: var(--taskon-color-primary, #cbff01);
4818
+ border-radius: 50%;
4819
+ animation: taskon-spin 1s linear infinite;
4820
+ }
4821
+
4822
+ .taskon-dialog-loading-text {
4823
+ color: var(--taskon-color-text-secondary, #888);
4824
+ font-size: 14px;
4825
+ }
4826
+
4827
+ @keyframes taskon-spin {
4828
+ to {
4829
+ transform: rotate(360deg);
4830
+ }
4831
+ }
4832
+ /**
4833
+ * DialogError 组件样式
4834
+ * 使用 Widget 命名空间扁平化方案
4835
+ */
4836
+
4837
+ .taskon-dialog-error {
4838
+ display: flex;
4839
+ flex-direction: column;
4840
+ align-items: center;
4841
+ justify-content: center;
4842
+ min-height: 300px;
4843
+ width: 440px;
4844
+ padding: 24px;
4845
+ text-align: center;
4846
+ }
4847
+
4848
+ .taskon-dialog-error-icon {
4849
+ font-size: 48px;
4850
+ margin-bottom: 16px;
4851
+ color: var(--taskon-color-text-secondary, #888);
4852
+ }
4853
+
4854
+ .taskon-dialog-error-message {
4855
+ color: var(--taskon-color-text-secondary, #888);
4856
+ margin-bottom: 16px;
4857
+ font-size: 14px;
4858
+ line-height: 1.5;
4859
+ max-width: 300px;
4860
+ }
4861
+
4862
+ .taskon-dialog-error-retry {
4863
+ padding: 10px 24px;
4864
+ background: var(--taskon-color-primary, #cbff01);
4865
+ color: #000;
4866
+ border: none;
4867
+ border-radius: 8px;
4868
+ cursor: pointer;
4869
+ font-size: 14px;
4870
+ font-weight: 500;
4871
+ transition: opacity 0.2s;
4872
+ }
4873
+
4874
+ .taskon-dialog-error-retry:hover {
4875
+ opacity: 0.9;
4876
+ }
4877
+
4878
+ .taskon-dialog-error-retry:active {
4879
+ opacity: 0.8;
4880
+ }
4881
+ /**
4882
+ * TaskDialog 组件样式
4883
+ * 复刻 Vue 版本 TaskDialog 结构
4884
+ * 使用 Widget 命名空间扁平化方案
4885
+ */
4886
+
4887
+ /* ==================== Dialog 容器覆盖 ==================== */
4888
+ .taskon-task-dialog {
4889
+ /* 复刻 Vue --bg-popup-basic-100: #0d0d0d */
4890
+ background: var(--taskon-color-bg-popup, #0d0d0d) !important;
4891
+ color: var(--taskon-color-text, #ffffff);
4892
+ }
4893
+
4894
+ /* 覆盖 Dialog body padding,让内容自己控制 */
4895
+ .taskon-task-dialog .taskon-dialog-body {
4896
+ padding: 0;
4897
+ }
4898
+
4899
+ /* 关闭按钮深色主题 */
4900
+ .taskon-task-dialog .taskon-dialog-close {
4901
+ background: rgba(255, 255, 255, 0.1);
4902
+ color: var(--taskon-color-text-secondary, #888);
4903
+ }
4904
+
4905
+ .taskon-task-dialog .taskon-dialog-close:hover {
4906
+ background: rgba(255, 255, 255, 0.2);
4907
+ color: var(--taskon-color-text, #fff);
4908
+ }
4909
+
4910
+ /* ==================== Wrapper: 复刻 Vue .task-dialog ==================== */
4911
+ .taskon-task-dialog-wrapper {
4912
+ display: flex;
4913
+ padding: 30px;
4914
+ }
4915
+
4916
+ /* ==================== 右侧面板 ==================== */
4917
+ .taskon-task-dialog-right {
4918
+ margin-left: 30px;
4919
+ padding-left: 30px;
4920
+ border-left: 1px solid rgba(255, 255, 255, 0.1);
4921
+ }
4922
+
4923
+ /* ==================== 验证成功提示(CloseIn) ==================== */
4924
+ .taskon-task-dialog-close-in {
4925
+ margin-top: 30px;
4926
+ color: var(--taskon-color-primary, #cbff01);
4927
+ text-align: center;
4928
+ font-size: 14px;
4929
+ font-weight: 500;
4930
+ line-height: 18px;
4931
+ }
4932
+
4933
+ /* ==================== 响应式 ==================== */
4934
+ @media (max-width: 750px) {
4935
+ .taskon-task-dialog-wrapper {
4936
+ flex-direction: column;
4937
+ padding: 5.333vw;
4938
+ }
4939
+
4940
+ .taskon-task-dialog-right {
4941
+ margin-left: 0;
4942
+ margin-top: 5.333vw;
4943
+ padding-left: 0;
4944
+ padding-top: 5.333vw;
4945
+ border-left: none;
4946
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
4947
+ }
4948
+
4949
+ .taskon-task-dialog-close-in {
4950
+ margin-top: 5.333vw;
4951
+ }
4952
+ }
4953
+ /**
4954
+ * CommunityTaskList 组件样式
4955
+ * 直接使用 dark 模式颜色值,不使用 CSS 变量
4956
+ * 使用 taskon-community-list- 前缀避免与项目方样式冲突
4957
+ */
4958
+
4959
+ /* 列表容器 */
4960
+ .taskon-community-list {
4961
+ width: 100%;
4962
+ }
4963
+
4964
+ /* Selector 样式 */
4965
+ .taskon-community-list-selector {
4966
+ margin-bottom: 24px;
4967
+ }
4968
+
4969
+ /* 内容区域 */
4970
+ .taskon-community-list-content {
4971
+ width: 100%;
4972
+ }
4973
+
4974
+ /* 加载状态 */
4975
+ .taskon-community-list-loading {
4976
+ padding: 40px;
4977
+ text-align: center;
4978
+ color: rgba(255, 255, 255, 0.6);
4979
+ font-size: 16px;
4980
+ }
4981
+
4982
+ /* 错误状态 */
4983
+ .taskon-community-list-error {
4984
+ padding: 40px;
4985
+ text-align: center;
4986
+ color: #ef4444;
4987
+ font-size: 16px;
4988
+ }
4989
+
4990
+ /* 空状态 */
4991
+ .taskon-community-list-empty {
4992
+ padding: 40px;
4993
+ text-align: center;
4994
+ color: rgba(255, 255, 255, 0.6);
4995
+ font-size: 16px;
4996
+ }
4997
+
4998
+ /* 响应式样式(移动端) */
4999
+ @media (max-width: 750px) {
5000
+ .taskon-community-list-selector {
5001
+ margin-bottom: 5.33vw;
5002
+ }
5003
+
5004
+ .taskon-community-list-loading,
5005
+ .taskon-community-list-error,
5006
+ .taskon-community-list-empty {
5007
+ padding: 10.67vw;
5008
+ font-size: 3.73vw;
5009
+ }
5010
+ }