@taskon/widget-react 0.0.1-beta.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 (48) hide show
  1. package/README.md +1065 -0
  2. package/dist/CommunityTaskList.css +4893 -0
  3. package/dist/EligibilityInfo.css +2337 -0
  4. package/dist/LeaderboardWidget.css +815 -0
  5. package/dist/PageBuilder.css +54 -0
  6. package/dist/Quest.css +4214 -0
  7. package/dist/TaskOnProvider.css +163 -0
  8. package/dist/TipPopover.css +210 -0
  9. package/dist/UserCenterWidget.css +297 -0
  10. package/dist/UserCenterWidget2.css +3519 -0
  11. package/dist/WidgetShell.css +182 -0
  12. package/dist/chunks/CommunityTaskList-DoPGZsw1.js +6813 -0
  13. package/dist/chunks/EligibilityInfo-C7GZ2G5u.js +22228 -0
  14. package/dist/chunks/LeaderboardWidget-CmYfDeHV.js +1068 -0
  15. package/dist/chunks/PageBuilder-Tmhf2GTS.js +150 -0
  16. package/dist/chunks/Quest-DKFZ-pPU.js +8839 -0
  17. package/dist/chunks/TaskOnProvider-BD6Vp2x8.js +1435 -0
  18. package/dist/chunks/ThemeProvider-wnSXrNQb.js +1118 -0
  19. package/dist/chunks/TipPopover-BrW8jo71.js +2926 -0
  20. package/dist/chunks/UserCenterWidget-BE329iS7.js +3546 -0
  21. package/dist/chunks/UserCenterWidget-BVw_IEEd.js +3989 -0
  22. package/dist/chunks/WidgetShell-D_5OjvNZ.js +1517 -0
  23. package/dist/chunks/common-ja-DWhTaFHb.js +23 -0
  24. package/dist/chunks/common-ko-80ezXsMG.js +23 -0
  25. package/dist/chunks/dynamic-import-helper-DxEFwm31.js +537 -0
  26. package/dist/chunks/index-CwMvO_wZ.js +777 -0
  27. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +119 -0
  28. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +119 -0
  29. package/dist/chunks/useToast-B-wyO5zL.js +93 -0
  30. package/dist/chunks/useWidgetLocale-JDelxtt8.js +74 -0
  31. package/dist/chunks/usercenter-ja-uu-XfVF9.js +332 -0
  32. package/dist/chunks/usercenter-ko-DYgUOVzd.js +332 -0
  33. package/dist/community-task.d.ts +451 -0
  34. package/dist/community-task.js +9 -0
  35. package/dist/core.d.ts +803 -0
  36. package/dist/core.js +22 -0
  37. package/dist/dynamic-import-helper.css +389 -0
  38. package/dist/index.d.ts +1660 -0
  39. package/dist/index.js +41 -0
  40. package/dist/leaderboard.d.ts +547 -0
  41. package/dist/leaderboard.js +18 -0
  42. package/dist/page-builder.d.ts +20 -0
  43. package/dist/page-builder.js +4 -0
  44. package/dist/quest.d.ts +400 -0
  45. package/dist/quest.js +8 -0
  46. package/dist/user-center.d.ts +1780 -0
  47. package/dist/user-center.js +713 -0
  48. package/package.json +105 -0
@@ -0,0 +1,2337 @@
1
+ /**
2
+ * Textarea 通用组件样式
3
+ * @description 复刻 Vue 版本 BaseTextareaPro.vue 样式
4
+ * 使用 taskon-textarea 命名空间
5
+ */
6
+
7
+ /* ==================== 容器 ==================== */
8
+ .taskon-textarea-wrap {
9
+ position: relative;
10
+ font-size: 0;
11
+ }
12
+
13
+ /* ==================== 文本域 ==================== */
14
+ .taskon-textarea {
15
+ width: 100%;
16
+ min-height: 100px;
17
+ padding: 12px;
18
+ padding-bottom: 36px; /* 给计数器留空间 */
19
+ border-radius: 6px;
20
+ border: 1px solid rgba(255, 255, 255, 0.1);
21
+ background: rgba(255, 255, 255, 0.04);
22
+ color: var(--taskon-color-text, #fff);
23
+ font-size: 14px;
24
+ line-height: 1.5;
25
+ resize: none;
26
+ outline: none;
27
+ transition: border-color 0.2s;
28
+ }
29
+
30
+ .taskon-textarea:focus {
31
+ border-color: var(--taskon-color-primary, #cbff01);
32
+ }
33
+
34
+ .taskon-textarea:disabled {
35
+ opacity: 0.6;
36
+ cursor: not-allowed;
37
+ }
38
+
39
+ .taskon-textarea--error {
40
+ border-color: #eb5757;
41
+ }
42
+
43
+ .taskon-textarea::placeholder {
44
+ color: var(--taskon-color-text-tertiary, #666);
45
+ }
46
+
47
+ /* ==================== 字数统计 ==================== */
48
+ .taskon-textarea-count {
49
+ position: absolute;
50
+ right: 20px;
51
+ bottom: 12px;
52
+ font-weight: 400;
53
+ font-size: 14px;
54
+ line-height: 20px;
55
+ color: rgba(255, 255, 255, 0.6);
56
+ }
57
+
58
+ .taskon-textarea-count-current {
59
+ color: #fff;
60
+ }
61
+
62
+ /* ==================== 响应式 ==================== */
63
+ @media (max-width: 750px) {
64
+ .taskon-textarea {
65
+ min-height: 26.667vw;
66
+ padding: 3.2vw;
67
+ padding-bottom: 8vw; /* 给计数器留空间 */
68
+ font-size: 3.733vw;
69
+ }
70
+
71
+ .taskon-textarea-count {
72
+ right: 2.933vw;
73
+ bottom: 2.667vw;
74
+ font-size: 2.933vw;
75
+ line-height: 2.667vw;
76
+ }
77
+ }
78
+ /**
79
+ * TitleExpress 组件样式
80
+ * @module components/TitleExpress
81
+ */
82
+
83
+ /* 可点击链接 - 统一蓝色加下划线样式 */
84
+ .taskon-title-express-link {
85
+ display: inline;
86
+ color: #54aeff;
87
+ cursor: pointer;
88
+ text-decoration: underline;
89
+ transition: opacity 0.2s ease;
90
+ }
91
+
92
+ .taskon-title-express-link:hover {
93
+ opacity: 0.8;
94
+ }
95
+
96
+ /* 可复制文本 */
97
+ .taskon-title-express-copy {
98
+ display: inline;
99
+ color: var(--taskon-color-secondary, #cbff01);
100
+ cursor: pointer;
101
+ }
102
+
103
+ /* Radix Popover 内容 */
104
+ .taskon-title-express-popover-content {
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+ gap: 6px;
109
+ padding: 8px 12px;
110
+ background: var(--taskon-color-bg-popover, #2a2a2a);
111
+ border-radius: 8px;
112
+ border: none;
113
+ outline: none;
114
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
115
+ cursor: pointer;
116
+ font-size: 14px;
117
+ font-weight: 500;
118
+ line-height: 18px;
119
+ color: var(--taskon-color-text, #fff);
120
+ z-index: 9999;
121
+ animation: taskon-popover-fade-in 0.15s ease;
122
+ }
123
+
124
+ .taskon-title-express-popover-content:focus {
125
+ outline: none;
126
+ }
127
+
128
+ .taskon-title-express-popover-content:hover {
129
+ background: var(--taskon-color-bg-popover-hover, #3a3a3a);
130
+ }
131
+
132
+ /* 复制图标 */
133
+ .taskon-title-express-copy-icon {
134
+ width: 14px;
135
+ height: 14px;
136
+ flex-shrink: 0;
137
+ }
138
+
139
+ /* Radix Popover 箭头 */
140
+ .taskon-title-express-popover-arrow {
141
+ fill: var(--taskon-color-bg-popover, #2a2a2a);
142
+ }
143
+
144
+ /* 动画 */
145
+ @keyframes taskon-popover-fade-in {
146
+ from {
147
+ opacity: 0;
148
+ transform: translateY(2px);
149
+ }
150
+ to {
151
+ opacity: 1;
152
+ transform: translateY(0);
153
+ }
154
+ }
155
+
156
+ /* 响应式样式(移动端) */
157
+ @media (max-width: 750px) {
158
+ .taskon-title-express-popover-content {
159
+ padding: 2.13vw 3.2vw;
160
+ font-size: 3.73vw;
161
+ line-height: 4.8vw;
162
+ border-radius: 2.13vw;
163
+ gap: 1.6vw;
164
+ }
165
+
166
+ .taskon-title-express-copy-icon {
167
+ width: 3.73vw;
168
+ height: 3.73vw;
169
+ }
170
+ }
171
+ /**
172
+ * PowTask Styles
173
+ * @description POW 任务样式
174
+ * 遵循 Widget 命名规范:.taskon-{widget-name}-{element}
175
+ */
176
+
177
+ /* ============================================
178
+ * POW Task Container
179
+ * ============================================ */
180
+ .taskon-pow-task {
181
+ /* 继承 TaskCardBase 的样式 */
182
+ }
183
+
184
+ /* ============================================
185
+ * POW Description
186
+ * ============================================ */
187
+ .taskon-pow-desc {
188
+ font-size: 14px;
189
+ line-height: 21px;
190
+ color: rgba(255, 255, 255, 0.8);
191
+ word-break: break-word;
192
+ }
193
+
194
+ .taskon-pow-desc a {
195
+ color: var(--taskon-primary-color, #3b82f6);
196
+ text-decoration: none;
197
+ }
198
+
199
+ .taskon-pow-desc a:hover {
200
+ text-decoration: underline;
201
+ }
202
+
203
+ /* ============================================
204
+ * POW Input Area
205
+ * ============================================ */
206
+ .taskon-pow-input-area {
207
+ margin-top: 15px;
208
+ }
209
+
210
+ /* ============================================
211
+ * URL Input Row
212
+ * ============================================ */
213
+ .taskon-pow-url-row {
214
+ display: flex;
215
+ align-items: center;
216
+ gap: 15px;
217
+ }
218
+
219
+ .taskon-pow-input {
220
+ flex: 1;
221
+ padding: 10px 12px;
222
+ border: 1px solid rgba(255, 255, 255, 0.2);
223
+ border-radius: 6px;
224
+ background: rgba(255, 255, 255, 0.05);
225
+ color: #fff;
226
+ font-size: 14px;
227
+ outline: none;
228
+ transition: border-color 0.2s ease;
229
+ }
230
+
231
+ .taskon-pow-input:focus {
232
+ border-color: var(--taskon-primary-color, #3b82f6);
233
+ }
234
+
235
+ .taskon-pow-input:disabled {
236
+ opacity: 0.5;
237
+ cursor: not-allowed;
238
+ }
239
+
240
+ .taskon-pow-input::placeholder {
241
+ color: rgba(255, 255, 255, 0.4);
242
+ }
243
+
244
+ /* ============================================
245
+ * Text Input Row
246
+ * ============================================ */
247
+ .taskon-pow-text-row {
248
+ display: flex;
249
+ align-items: flex-end;
250
+ gap: 15px;
251
+ }
252
+
253
+ .taskon-pow-text-row .taskon-textarea-wrap {
254
+ flex: 1;
255
+ }
256
+
257
+ /* ============================================
258
+ * Image Upload Area - 与 Vue 版本 PowImageUploader 一致
259
+ * ============================================ */
260
+ .taskon-pow-image-uploader {
261
+ margin-top: 20px;
262
+ display: flex;
263
+ align-items: center;
264
+ }
265
+
266
+ .taskon-pow-image-upload-area {
267
+ flex: 1;
268
+ position: relative;
269
+ display: flex;
270
+ flex-direction: column;
271
+ align-items: center;
272
+ justify-content: center;
273
+ min-height: 128px;
274
+ text-align: center;
275
+ font-size: 0;
276
+ overflow: hidden;
277
+ border: 1px solid rgba(255, 255, 255, 0.2);
278
+ border-radius: 8px;
279
+ background: rgba(255, 255, 255, 0.05);
280
+ cursor: pointer;
281
+ transition: border-color 0.2s ease;
282
+ }
283
+
284
+ .taskon-pow-image-upload-area:hover:not(.taskon-pow-image-upload-area--disabled) {
285
+ border-color: var(--taskon-primary-color, #3b82f6);
286
+ }
287
+
288
+ .taskon-pow-image-upload-area:focus {
289
+ outline: none;
290
+ border-color: var(--taskon-primary-color, #3b82f6);
291
+ }
292
+
293
+ .taskon-pow-image-upload-area--disabled {
294
+ opacity: 0.5;
295
+ cursor: not-allowed;
296
+ }
297
+
298
+ .taskon-pow-image-upload-icon {
299
+ width: 18px;
300
+ height: 18px;
301
+ color: rgba(255, 255, 255, 0.6);
302
+ }
303
+
304
+ .taskon-pow-image-upload-tip {
305
+ margin-top: 13px;
306
+ font-size: 14px;
307
+ line-height: 20px;
308
+ letter-spacing: 0.04em;
309
+ text-transform: uppercase;
310
+ white-space: pre-wrap;
311
+ color: rgba(255, 255, 255, 0.6);
312
+ }
313
+
314
+ .taskon-pow-image-preview {
315
+ border-radius: 4px;
316
+ margin: 20px 0;
317
+ max-width: 100%;
318
+ max-height: 300px;
319
+ }
320
+
321
+ /* Hover mask overlay */
322
+ .taskon-pow-image-mask {
323
+ display: none;
324
+ position: absolute;
325
+ inset: 0;
326
+ z-index: 2;
327
+ align-items: center;
328
+ justify-content: center;
329
+ flex-direction: column;
330
+ background: rgba(0, 0, 0, 0.8);
331
+ }
332
+
333
+ .taskon-pow-image-upload-area:hover .taskon-pow-image-mask,
334
+ .taskon-pow-image-upload-area:focus .taskon-pow-image-mask {
335
+ display: flex;
336
+ }
337
+
338
+ .taskon-pow-image-mask .taskon-pow-image-upload-icon {
339
+ color: #fff;
340
+ }
341
+
342
+ .taskon-pow-image-mask .taskon-pow-image-upload-tip {
343
+ color: #fff;
344
+ opacity: 1;
345
+ }
346
+
347
+ /* Progress bar at bottom */
348
+ .taskon-pow-image-progress-bar {
349
+ z-index: 3;
350
+ position: absolute;
351
+ right: 0;
352
+ bottom: 0;
353
+ left: 0;
354
+ background: rgba(255, 255, 255, 0.1);
355
+ height: 6px;
356
+ }
357
+
358
+ .taskon-pow-image-progress-fill {
359
+ background: var(--taskon-primary-color, #3b82f6);
360
+ height: 100%;
361
+ border-radius: 4px;
362
+ transition: width 0.2s ease;
363
+ }
364
+
365
+ /* ============================================
366
+ * Error Message
367
+ * ============================================ */
368
+ .taskon-pow-error {
369
+ margin-top: 10px;
370
+ font-size: 14px;
371
+ color: #ef4444;
372
+ }
373
+
374
+ /* ============================================
375
+ * Average Review Time
376
+ * ============================================ */
377
+ /* 与 Vue 版本 AverageReview.vue 样式一致 */
378
+ .taskon-pow-review-time {
379
+ margin-top: 10px;
380
+ color: rgba(255, 212, 101, 0.6);
381
+ font-size: 13px;
382
+ font-weight: 500;
383
+ line-height: 16px;
384
+ }
385
+
386
+ /* ============================================
387
+ * Responsive Styles
388
+ * ============================================ */
389
+ @media (max-width: 750px) {
390
+ .taskon-pow-url-row,
391
+ .taskon-pow-text-row {
392
+ flex-direction: column;
393
+ gap: 10px;
394
+ }
395
+
396
+ .taskon-pow-input {
397
+ width: 100%;
398
+ }
399
+
400
+ .taskon-pow-url-row .taskon-verify-btn,
401
+ .taskon-pow-text-row .taskon-verify-btn {
402
+ width: 100%;
403
+ }
404
+
405
+ .taskon-pow-image-uploader {
406
+ margin-top: 2.67vw;
407
+ }
408
+
409
+ .taskon-pow-image-upload-area {
410
+ min-height: 17.07vw;
411
+ }
412
+
413
+ .taskon-pow-image-upload-icon {
414
+ width: 2.4vw;
415
+ height: 2.4vw;
416
+ }
417
+
418
+ .taskon-pow-image-upload-tip {
419
+ margin-top: 1.33vw;
420
+ font-size: 1.6vw;
421
+ line-height: 2.67vw;
422
+ }
423
+
424
+ .taskon-pow-image-preview {
425
+ max-height: 32vw;
426
+ }
427
+ }
428
+ /**
429
+ * ContractInteractiveTask Styles
430
+ */
431
+
432
+ .taskon-contract-task {
433
+ /* 继承 TaskCardBase 样式 */
434
+ }
435
+
436
+ .taskon-contract-desc {
437
+ font-size: 14px;
438
+ line-height: 21px;
439
+ color: rgba(255, 255, 255, 0.8);
440
+ word-break: break-word;
441
+ }
442
+
443
+ .taskon-contract-desc a {
444
+ color: var(--taskon-primary-color, #3b82f6);
445
+ text-decoration: none;
446
+ }
447
+
448
+ .taskon-contract-desc a:hover {
449
+ text-decoration: underline;
450
+ }
451
+ /* ============================================
452
+ DynamicPoints Component Styles
453
+ 与 Vue 版本 BaseDynamicPoint.vue 样式一致
454
+ ============================================ */
455
+
456
+ .taskon-dynamic-points {
457
+ display: inline-flex;
458
+ align-items: center;
459
+ gap: 8px;
460
+ padding: 8px 12px;
461
+ background: rgba(255, 255, 255, 0.04);
462
+ border-radius: 8px;
463
+ }
464
+
465
+ .taskon-dynamic-points-value-wrap {
466
+ display: flex;
467
+ align-items: center;
468
+ gap: 8px;
469
+ flex-shrink: 0;
470
+ }
471
+
472
+ .taskon-dynamic-points-value {
473
+ font-size: 16px;
474
+ font-weight: 600;
475
+ color: var(--taskon-task-text-primary, #fff);
476
+ }
477
+
478
+ .taskon-dynamic-points-value--highlight {
479
+ color: #00ffa3 !important;
480
+ }
481
+
482
+ .taskon-dynamic-points-max {
483
+ font-size: 14px;
484
+ font-weight: 500;
485
+ color: var(--taskon-task-text-secondary, rgba(255, 255, 255, 0.6));
486
+ text-transform: capitalize;
487
+ }
488
+
489
+ .taskon-dynamic-points-info {
490
+ display: inline-flex;
491
+ align-items: center;
492
+ justify-content: center;
493
+ color: var(--taskon-task-text-secondary, rgba(255, 255, 255, 0.6));
494
+ cursor: pointer;
495
+ }
496
+
497
+ .taskon-dynamic-points-info:hover {
498
+ color: var(--taskon-task-text-primary, #fff);
499
+ }
500
+
501
+ .taskon-dynamic-points-refresh {
502
+ display: inline-flex;
503
+ align-items: center;
504
+ justify-content: center;
505
+ width: 24px;
506
+ height: 24px;
507
+ padding: 0;
508
+ margin-left: 4px;
509
+ background: transparent;
510
+ border: none;
511
+ border-radius: 4px;
512
+ color: #54aeff;
513
+ cursor: pointer;
514
+ transition: opacity 0.2s, transform 0.2s;
515
+ }
516
+
517
+ .taskon-dynamic-points-refresh:hover:not(:disabled) {
518
+ opacity: 0.8;
519
+ }
520
+
521
+ .taskon-dynamic-points-refresh--disabled {
522
+ opacity: 0.6;
523
+ cursor: not-allowed;
524
+ }
525
+
526
+ .taskon-dynamic-points-refresh--animating {
527
+ filter: drop-shadow(0 0 4px rgba(84, 174, 255, 0.8));
528
+ }
529
+
530
+ .taskon-dynamic-points-refresh-icon {
531
+ width: 16px;
532
+ height: 16px;
533
+ }
534
+
535
+ .taskon-dynamic-points-refresh-icon--spin {
536
+ animation: taskon-spin 1s linear infinite;
537
+ }
538
+
539
+ @keyframes taskon-spin {
540
+ from {
541
+ transform: rotate(0deg);
542
+ }
543
+ to {
544
+ transform: rotate(360deg);
545
+ }
546
+ }
547
+
548
+ .taskon-dynamic-points-cooldown {
549
+ font-size: 14px;
550
+ font-weight: 500;
551
+ color: #54aeff !important;
552
+ font-family: Menlo, Consolas, "Liberation Mono", "Courier New", Courier, monospace;
553
+ }
554
+ /**
555
+ * SwapDexTask Styles
556
+ * 与原版 Vue SwapDexContractInteractive + SwapDexVolumeRules 样式一致
557
+ */
558
+
559
+ .taskon-swap-task {
560
+ /* 继承 TaskCardBase 样式 */
561
+ }
562
+
563
+ /* Content wrapper */
564
+ .taskon-swap-content {
565
+ display: flex;
566
+ flex-direction: column;
567
+ gap: 16px;
568
+ }
569
+
570
+ /* Rules section - 动态积分规则区域 */
571
+ .taskon-swap-rules-section {
572
+ display: flex;
573
+ flex-direction: column;
574
+ gap: 8px;
575
+ }
576
+
577
+ .taskon-swap-rules-title {
578
+ font-size: 14px;
579
+ font-weight: 500;
580
+ color: rgba(255, 255, 255, 0.6);
581
+ margin-bottom: 8px;
582
+ }
583
+
584
+ .taskon-swap-rules-content {
585
+ display: flex;
586
+ flex-wrap: wrap;
587
+ align-items: center;
588
+ gap: 4px;
589
+ padding: 12px;
590
+ border-radius: 8px;
591
+ background: rgba(255, 255, 255, 0.05);
592
+ font-size: 14px;
593
+ font-weight: 500;
594
+ color: rgba(255, 255, 255, 0.6);
595
+ }
596
+
597
+ .taskon-swap-rules-highlight {
598
+ color: var(--taskon-secondary-color, #00ffa3);
599
+ }
600
+
601
+ .taskon-swap-rules-point-name {
602
+ color: rgba(255, 255, 255, 0.4);
603
+ }
604
+
605
+ /* Instructions section - 任务描述区域 */
606
+ .taskon-swap-instructions-section {
607
+ display: flex;
608
+ flex-direction: column;
609
+ gap: 8px;
610
+ }
611
+
612
+ .taskon-swap-instructions-title {
613
+ font-size: 14px;
614
+ font-weight: 500;
615
+ color: rgba(255, 255, 255, 0.6);
616
+ margin-bottom: 8px;
617
+ }
618
+
619
+ .taskon-swap-instructions-content {
620
+ padding: 12px;
621
+ border-radius: 8px;
622
+ background: rgba(255, 255, 255, 0.05);
623
+ }
624
+
625
+ .taskon-swap-desc {
626
+ font-size: 14px;
627
+ line-height: 21px;
628
+ color: rgba(255, 255, 255, 0.8);
629
+ word-break: break-word;
630
+ }
631
+
632
+ .taskon-swap-desc a {
633
+ color: var(--taskon-primary-color, #3b82f6);
634
+ text-decoration: none;
635
+ }
636
+
637
+ .taskon-swap-desc a:hover {
638
+ text-decoration: underline;
639
+ }
640
+ /**
641
+ * OuterPointAPITask Styles
642
+ * 与 Vue 版本 OuterPointVerify + CustomizedSubmitDialog 样式一致
643
+ */
644
+
645
+ .taskon-outer-point-api-task {
646
+ /* 继承 TaskCardBase 样式 */
647
+ }
648
+
649
+ /* ==================== Description Area ==================== */
650
+ .taskon-outer-point-api-desc {
651
+ font-size: 14px;
652
+ line-height: 21px;
653
+ color: rgba(255, 255, 255, 0.8);
654
+ word-break: break-word;
655
+ }
656
+
657
+ .taskon-outer-point-api-desc a {
658
+ color: var(--taskon-primary-color, #3b82f6);
659
+ text-decoration: none;
660
+ }
661
+
662
+ .taskon-outer-point-api-desc a:hover {
663
+ text-decoration: underline;
664
+ }
665
+
666
+ /* ==================== Customized Param Dialog ==================== */
667
+ .taskon-outer-point-api-dialog {
668
+ display: flex;
669
+ flex-direction: column;
670
+ gap: 16px;
671
+ }
672
+
673
+ /* Dialog title */
674
+ .taskon-outer-point-api-dialog-title {
675
+ font-size: 18px;
676
+ font-weight: 600;
677
+ color: #fff;
678
+ margin: 0;
679
+ }
680
+
681
+ /* Warning message */
682
+ .taskon-outer-point-api-dialog-warning {
683
+ display: flex;
684
+ align-items: center;
685
+ gap: 8px;
686
+ padding: 12px;
687
+ border-radius: 8px;
688
+ background: rgba(255, 171, 0, 0.1);
689
+ color: #ffab00;
690
+ font-size: 14px;
691
+ line-height: 20px;
692
+ }
693
+
694
+ .taskon-outer-point-api-dialog-warning-icon {
695
+ flex-shrink: 0;
696
+ width: 20px;
697
+ height: 20px;
698
+ }
699
+
700
+ /* Description text */
701
+ .taskon-outer-point-api-dialog-desc {
702
+ font-size: 14px;
703
+ line-height: 20px;
704
+ color: rgba(255, 255, 255, 0.6);
705
+ }
706
+
707
+ /* Input area */
708
+ .taskon-outer-point-api-dialog-input-wrap {
709
+ display: flex;
710
+ flex-direction: column;
711
+ gap: 8px;
712
+ }
713
+
714
+ .taskon-outer-point-api-dialog-label {
715
+ font-size: 14px;
716
+ font-weight: 500;
717
+ color: rgba(255, 255, 255, 0.8);
718
+ }
719
+
720
+ .taskon-outer-point-api-dialog-input {
721
+ width: 100%;
722
+ padding: 10px 12px;
723
+ border-radius: 8px;
724
+ border: 1px solid rgba(255, 255, 255, 0.15);
725
+ background: rgba(255, 255, 255, 0.05);
726
+ color: #fff;
727
+ font-size: 14px;
728
+ line-height: 20px;
729
+ outline: none;
730
+ transition: border-color 0.2s ease;
731
+ box-sizing: border-box;
732
+ }
733
+
734
+ .taskon-outer-point-api-dialog-input::placeholder {
735
+ color: rgba(255, 255, 255, 0.3);
736
+ }
737
+
738
+ .taskon-outer-point-api-dialog-input:focus {
739
+ border-color: var(--taskon-primary-color, #3b82f6);
740
+ }
741
+
742
+ .taskon-outer-point-api-dialog-input--error {
743
+ border-color: #ff4d4f;
744
+ }
745
+
746
+ .taskon-outer-point-api-dialog-error {
747
+ font-size: 12px;
748
+ color: #ff4d4f;
749
+ }
750
+
751
+ /* Action buttons */
752
+ .taskon-outer-point-api-dialog-actions {
753
+ display: flex;
754
+ justify-content: flex-end;
755
+ gap: 12px;
756
+ margin-top: 8px;
757
+ }
758
+
759
+ .taskon-outer-point-api-dialog-btn {
760
+ padding: 8px 24px;
761
+ border-radius: 8px;
762
+ font-size: 14px;
763
+ font-weight: 500;
764
+ cursor: pointer;
765
+ transition: all 0.2s ease;
766
+ border: none;
767
+ }
768
+
769
+ .taskon-outer-point-api-dialog-btn--cancel {
770
+ background: rgba(255, 255, 255, 0.1);
771
+ color: rgba(255, 255, 255, 0.8);
772
+ }
773
+
774
+ .taskon-outer-point-api-dialog-btn--cancel:hover {
775
+ background: rgba(255, 255, 255, 0.15);
776
+ }
777
+
778
+ .taskon-outer-point-api-dialog-btn--confirm {
779
+ background: var(--taskon-primary-color, #3b82f6);
780
+ color: #fff;
781
+ }
782
+
783
+ .taskon-outer-point-api-dialog-btn--confirm:hover {
784
+ opacity: 0.9;
785
+ }
786
+
787
+ .taskon-outer-point-api-dialog-btn--confirm:disabled {
788
+ opacity: 0.5;
789
+ cursor: not-allowed;
790
+ }
791
+ /**
792
+ * TaskWidget Styles
793
+ * @description 任务列表组件样式(与 taskon-website BaseTask.vue 保持一致)
794
+ *
795
+ * 命名规范:.taskon-task-{component}-{element}--{modifier}
796
+ */
797
+
798
+ /* ============================================
799
+ CSS Variables (可被项目方覆盖)
800
+ ============================================ */
801
+ :root {
802
+ /* Task card colors (dark theme, same as taskon-website) */
803
+ --taskon-task-bg: #1d2123;
804
+ --taskon-task-border: #1d2123;
805
+ --taskon-task-border-hover: #41494b;
806
+ --taskon-task-radius: 10px;
807
+
808
+ /* Text colors */
809
+ --taskon-task-text: #ffffff;
810
+ --taskon-task-text-secondary: #9ca3af;
811
+ --taskon-task-text-muted: #6b7280;
812
+
813
+ /* Status colors */
814
+ --taskon-color-primary: #3b82f6;
815
+ --taskon-color-success: #22c55e;
816
+ --taskon-color-warning: #f59e0b;
817
+ --taskon-color-error: #ef4444;
818
+
819
+ /* Recurrence badge color */
820
+ --taskon-recurrence-color: #9aff73;
821
+
822
+ /* Spacing */
823
+ --taskon-task-spacing-xs: 4px;
824
+ --taskon-task-spacing-sm: 8px;
825
+ --taskon-task-spacing-md: 12px;
826
+ --taskon-task-spacing-lg: 16px;
827
+ --taskon-task-spacing-xl: 24px;
828
+
829
+ /* Transitions */
830
+ --taskon-task-transition: 0.2s ease;
831
+ }
832
+
833
+ /* ============================================
834
+ TaskList Styles
835
+ 与 Vue 版本 TaskList.vue + TaskType.vue 一致
836
+ ============================================ */
837
+ .taskon-task-list {
838
+ display: flex;
839
+ flex-direction: column;
840
+ gap: var(--taskon-task-spacing-lg);
841
+ }
842
+
843
+ /* Progress section */
844
+ .taskon-task-list-progress-wrap {
845
+ margin-bottom: var(--taskon-task-spacing-sm);
846
+ }
847
+
848
+ /* Section styles */
849
+ .taskon-task-list-section {
850
+ display: flex;
851
+ flex-direction: column;
852
+ }
853
+
854
+ .taskon-task-list-section-header {
855
+ display: flex;
856
+ justify-content: space-between;
857
+ align-items: center;
858
+ margin-top: 30px;
859
+ margin-bottom: 22px;
860
+ }
861
+
862
+ .taskon-task-list-section-label {
863
+ display: flex;
864
+ align-items: center;
865
+ gap: 6px;
866
+ }
867
+
868
+ .taskon-task-list-section-title {
869
+ font-size: 22px;
870
+ font-weight: 600;
871
+ line-height: 21px;
872
+ color: var(--taskon-task-text);
873
+ }
874
+
875
+ .taskon-task-list-section-hint {
876
+ font-size: 14px;
877
+ color: rgba(255, 255, 255, 0.6);
878
+ }
879
+
880
+ .taskon-task-list-section-hint-em {
881
+ font-weight: 600;
882
+ color: rgba(0, 255, 163, 1);
883
+ }
884
+
885
+ .taskon-task-list-items {
886
+ display: flex;
887
+ flex-direction: column;
888
+ gap: 20px;
889
+ }
890
+
891
+ /* First section header doesn't need top margin */
892
+ .taskon-task-list-section:first-child .taskon-task-list-section-header {
893
+ margin-top: 0;
894
+ }
895
+
896
+ /* Empty state */
897
+ .taskon-task-list-empty {
898
+ padding: var(--taskon-task-spacing-xl);
899
+ text-align: center;
900
+ color: var(--taskon-task-text-muted);
901
+ }
902
+
903
+ /* Mobile responsive */
904
+ @media (max-width: 750px) {
905
+ .taskon-task-list-section-header {
906
+ display: block;
907
+ margin-top: 5.6vw;
908
+ margin-bottom: 4vw;
909
+ }
910
+
911
+ .taskon-task-list-section-label {
912
+ flex-wrap: wrap;
913
+ gap: 1.6vw;
914
+ }
915
+
916
+ .taskon-task-list-section-title {
917
+ font-size: 4.8vw;
918
+ line-height: 6vw;
919
+ }
920
+
921
+ .taskon-completed-count {
922
+ margin-top: 2.67vw;
923
+ justify-content: flex-start;
924
+ }
925
+
926
+ .taskon-completed-count-check {
927
+ width: 3.2vw;
928
+ height: 2.4vw;
929
+ margin-right: 2.13vw;
930
+ }
931
+
932
+ .taskon-completed-count-text {
933
+ font-size: 3.47vw;
934
+ line-height: 4.4vw;
935
+ }
936
+
937
+ .taskon-task-list-items {
938
+ gap: 3.07vw;
939
+ }
940
+ }
941
+
942
+ /* ============================================
943
+ TaskProgress Styles
944
+ ============================================ */
945
+ .taskon-task-progress {
946
+ display: flex;
947
+ flex-direction: column;
948
+ gap: var(--taskon-task-spacing-sm);
949
+ }
950
+
951
+ .taskon-task-progress-bar {
952
+ height: 6px;
953
+ background: rgba(255, 255, 255, 0.1);
954
+ border-radius: 3px;
955
+ overflow: hidden;
956
+ }
957
+
958
+ .taskon-task-progress-bar-fill {
959
+ height: 100%;
960
+ background: var(--taskon-color-primary);
961
+ border-radius: 3px;
962
+ transition: width var(--taskon-task-transition);
963
+ }
964
+
965
+ .taskon-task-progress--completed .taskon-task-progress-bar-fill {
966
+ background: var(--taskon-color-success);
967
+ }
968
+
969
+ .taskon-task-progress-text {
970
+ display: flex;
971
+ align-items: center;
972
+ gap: var(--taskon-task-spacing-xs);
973
+ font-size: 13px;
974
+ color: var(--taskon-task-text-secondary);
975
+ }
976
+
977
+ .taskon-task-progress--completed .taskon-task-progress-text {
978
+ color: var(--taskon-color-success);
979
+ }
980
+
981
+ .taskon-task-progress-icon {
982
+ display: inline-flex;
983
+ align-items: center;
984
+ justify-content: center;
985
+ }
986
+
987
+ /* ============================================
988
+ TaskItem Styles
989
+ ============================================ */
990
+ .taskon-task-item {
991
+ position: relative;
992
+ padding: 16px 20px;
993
+ background: var(--taskon-task-bg);
994
+ border-radius: var(--taskon-task-radius);
995
+ border: 1px solid var(--taskon-task-border);
996
+ transition: border-color var(--taskon-task-transition);
997
+ }
998
+
999
+ .taskon-task-item:hover {
1000
+ border-color: var(--taskon-task-border-hover);
1001
+ }
1002
+
1003
+ /* ============================================
1004
+ 左上角浮标:周期标签 / 冷却倒计时
1005
+ 与 Vue 版本 RecurrenceStatus.vue 样式一致
1006
+ ============================================ */
1007
+ .taskon-task-item-recurrence {
1008
+ position: absolute;
1009
+ top: -6px;
1010
+ left: 12px;
1011
+ /* 与 Vue 版本一致:使用 SVG 背景 */
1012
+ background: url("data:image/svg+xml,%3csvg%20width='69'%20height='20'%20viewBox='0%200%2069%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20filter='url(%23filter0_i_10913_141293)'%3e%3cpath%20d='M67.9996%204.5C67.9996%202.5%2066.7705%201%2064.1369%201H3.42655C0.791465%201%200%203%200%204.64199L67.9996%204.5Z'%20fill='%2328491F'/%3e%3c/g%3e%3cg%20filter='url(%23filter1_d_10913_141293)'%3e%3cpath%20d='M2.99902%201H11.242H65.999V1C64.6983%201%2063.6439%202.05443%2063.6439%203.35514V13C63.6439%2015.2091%2061.853%2017%2059.6439%2017H11.1205C8.91138%2017%207.12052%2015.2091%207.12052%2013V5.1215C7.12052%202.84526%205.27526%201%202.99902%201V1Z'%20fill='%232D422A'/%3e%3c/g%3e%3cdefs%3e%3cfilter%20id='filter0_i_10913_141293'%20x='0'%20y='1'%20width='67.9996'%20height='4.64197'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'%3e%3cfeFlood%20flood-opacity='0'%20result='BackgroundImageFix'/%3e%3cfeBlend%20mode='normal'%20in='SourceGraphic'%20in2='BackgroundImageFix'%20result='shape'/%3e%3cfeColorMatrix%20in='SourceAlpha'%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%20127%200'%20result='hardAlpha'/%3e%3cfeOffset%20dy='1'/%3e%3cfeGaussianBlur%20stdDeviation='4.1'/%3e%3cfeComposite%20in2='hardAlpha'%20operator='arithmetic'%20k2='-1'%20k3='1'/%3e%3cfeColorMatrix%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.8%200'/%3e%3cfeBlend%20mode='normal'%20in2='shape'%20result='effect1_innerShadow_10913_141293'/%3e%3c/filter%3e%3cfilter%20id='filter1_d_10913_141293'%20x='1.99902'%20y='0'%20width='67'%20height='20'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'%3e%3cfeFlood%20flood-opacity='0'%20result='BackgroundImageFix'/%3e%3cfeColorMatrix%20in='SourceAlpha'%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%20127%200'%20result='hardAlpha'/%3e%3cfeOffset%20dx='1'%20dy='1'/%3e%3cfeGaussianBlur%20stdDeviation='1'/%3e%3cfeComposite%20in2='hardAlpha'%20operator='out'/%3e%3cfeColorMatrix%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.25%200'/%3e%3cfeBlend%20mode='normal'%20in2='BackgroundImageFix'%20result='effect1_dropShadow_10913_141293'/%3e%3cfeBlend%20mode='normal'%20in='SourceGraphic'%20in2='effect1_dropShadow_10913_141293'%20result='shape'/%3e%3c/filter%3e%3c/defs%3e%3c/svg%3e") no-repeat center center;
1013
+ background-size: cover;
1014
+ /* 固定尺寸与 Vue 版本一致 */
1015
+ width: 78px;
1016
+ height: 20px;
1017
+ /* 文字样式 */
1018
+ color: var(--taskon-recurrence-color);
1019
+ font-size: 12px;
1020
+ line-height: 16px;
1021
+ font-weight: 500;
1022
+ text-align: center;
1023
+ display: flex;
1024
+ align-items: center;
1025
+ justify-content: center;
1026
+ }
1027
+
1028
+ /* 冷却倒计时样式 - 继承标签样式 */
1029
+ .taskon-task-item-recurrence .taskon-cooldown-timer {
1030
+ color: var(--taskon-recurrence-color);
1031
+ font-size: 12px;
1032
+ line-height: 16px;
1033
+ font-weight: 500;
1034
+ }
1035
+
1036
+ /* ============================================
1037
+ 第一行:图标 + 标题 + 右侧内容
1038
+ ============================================ */
1039
+ .taskon-task-item-row {
1040
+ display: flex;
1041
+ align-items: center;
1042
+ }
1043
+
1044
+ /* Left section: Icon + Title */
1045
+ .taskon-task-item-left {
1046
+ display: flex;
1047
+ align-items: center;
1048
+ flex: 1;
1049
+ min-width: 0;
1050
+ }
1051
+
1052
+ .taskon-task-item-icon {
1053
+ flex-shrink: 0;
1054
+ display: flex;
1055
+ align-items: center;
1056
+ justify-content: center;
1057
+ margin-right: 16px;
1058
+ color: var(--taskon-task-text-secondary);
1059
+ }
1060
+
1061
+ .taskon-task-item--completed .taskon-task-item-icon {
1062
+ color: var(--taskon-color-success);
1063
+ }
1064
+
1065
+ /* Title wrapper - 与 Vue 版本 TitleRow 结构一致 */
1066
+ /* 普通 block flow,标题 inline,TotalEarnPoint 作为 block div 自然换行 */
1067
+ .taskon-task-item-title-wrap {
1068
+ flex: 1;
1069
+ min-width: 0;
1070
+ }
1071
+
1072
+ .taskon-task-item-title {
1073
+ display: inline;
1074
+ font-size: 18px;
1075
+ font-weight: 500;
1076
+ color: var(--taskon-task-text);
1077
+ line-height: 23px;
1078
+ overflow-wrap: break-word;
1079
+ }
1080
+
1081
+ /* Title as link - 参考 Vue 版本 TitleRow.vue 的 OutLink 样式 */
1082
+ .taskon-task-item-title--link {
1083
+ color: #54aeff;
1084
+ text-decoration: underline;
1085
+ transition: opacity var(--taskon-task-transition);
1086
+ }
1087
+
1088
+ .taskon-task-item-title--link:hover {
1089
+ opacity: 0.8;
1090
+ }
1091
+
1092
+ .taskon-task-item--completed .taskon-task-item-title {
1093
+ color: var(--taskon-task-text-secondary);
1094
+ }
1095
+
1096
+ /* Links in title - 统一蓝色加下划线样式 */
1097
+ .taskon-task-item-link {
1098
+ color: #54aeff;
1099
+ text-decoration: underline;
1100
+ transition: opacity var(--taskon-task-transition);
1101
+ }
1102
+
1103
+ .taskon-task-item-link:hover {
1104
+ opacity: 0.8;
1105
+ }
1106
+
1107
+ /* Title tip icon */
1108
+ .taskon-task-item-title-tip {
1109
+ display: inline-flex;
1110
+ align-items: center;
1111
+ justify-content: center;
1112
+ margin-left: 6px;
1113
+ color: rgba(255, 255, 255, 0.4);
1114
+ cursor: help;
1115
+ flex-shrink: 0;
1116
+ }
1117
+
1118
+ .taskon-task-item-title-tip:hover {
1119
+ color: rgba(255, 255, 255, 0.6);
1120
+ }
1121
+
1122
+ /* Right section: Points + Total + Verify */
1123
+ .taskon-task-item-right {
1124
+ display: flex;
1125
+ align-items: center;
1126
+ gap: var(--taskon-task-spacing-md);
1127
+ flex-shrink: 0;
1128
+ margin-left: 10px;
1129
+ }
1130
+
1131
+ /* Points display - 参考 TaskPoint.vue */
1132
+ .taskon-task-item-points {
1133
+ min-width: 40px;
1134
+ height: 34px;
1135
+ padding: 0 10px;
1136
+ display: flex;
1137
+ align-items: center;
1138
+ justify-content: center;
1139
+ gap: 2px;
1140
+ background: rgba(255, 255, 255, 0.04);
1141
+ border-radius: 6px;
1142
+ font-size: 16px;
1143
+ font-weight: 500;
1144
+ }
1145
+
1146
+ .taskon-task-item-points-value {
1147
+ color: #ffffff;
1148
+ }
1149
+
1150
+ /* Points value when task is completed - green color like Vue version */
1151
+ .taskon-task-item-points-value--completed {
1152
+ color: #00ffa3;
1153
+ }
1154
+
1155
+ .taskon-task-item-points-time {
1156
+ font-size: 12px;
1157
+ color: rgba(255, 255, 255, 0.6);
1158
+ }
1159
+
1160
+ /* Tip icon next to points (margin controlled externally) */
1161
+ .taskon-task-item-tip {
1162
+ margin-left: 10px;
1163
+ }
1164
+
1165
+ /* Total points */
1166
+ .taskon-task-item-total-points {
1167
+ font-size: 12px;
1168
+ color: var(--taskon-task-text-muted);
1169
+ }
1170
+
1171
+ /* ============================================
1172
+ TotalEarnPoint Styles
1173
+ 与 Vue 版本 TotalEarnPoint.vue 样式一致
1174
+ ============================================ */
1175
+ .taskon-task-item-total-earn {
1176
+ display: flex;
1177
+ align-items: center;
1178
+ }
1179
+
1180
+ .taskon-task-item-total-earn-text {
1181
+ color: rgba(255, 255, 255, 0.6);
1182
+ font-size: 14px;
1183
+ }
1184
+
1185
+ .taskon-task-item-total-earn-value {
1186
+ color: #9aff73;
1187
+ font-size: 14px;
1188
+ margin: 0 4px;
1189
+ }
1190
+
1191
+ /* ============================================
1192
+ 第二行:内容区域(始终显示)
1193
+ ============================================ */
1194
+ .taskon-task-item-body {
1195
+ margin-left: 50px;
1196
+ margin-top: 10px;
1197
+ }
1198
+
1199
+ .taskon-task-item-content {
1200
+ display: flex;
1201
+ flex-direction: column;
1202
+ gap: var(--taskon-task-spacing-md);
1203
+ }
1204
+
1205
+ .taskon-task-item-desc {
1206
+ font-size: 14px;
1207
+ line-height: 21px;
1208
+ color: var(--taskon-task-text-secondary);
1209
+ word-break: break-all;
1210
+ white-space: pre-wrap;
1211
+ }
1212
+
1213
+ .taskon-task-item-desc span {
1214
+ color: var(--taskon-task-text);
1215
+ word-break: break-all;
1216
+ }
1217
+
1218
+ /* Rich text content - 参考 Vue 版本 TextPreview.vue */
1219
+ .taskon-task-item-rich-text {
1220
+ font-size: 14px;
1221
+ line-height: 21px;
1222
+ color: var(--taskon-task-text-secondary);
1223
+ word-break: break-word;
1224
+ }
1225
+
1226
+ .taskon-task-item-rich-text p {
1227
+ margin: 0 0 0.5em 0;
1228
+ }
1229
+
1230
+ .taskon-task-item-rich-text p:last-child {
1231
+ margin-bottom: 0;
1232
+ }
1233
+
1234
+ .taskon-task-item-rich-text a {
1235
+ color: #54aeff;
1236
+ text-decoration: underline;
1237
+ }
1238
+
1239
+ .taskon-task-item-rich-text a:hover {
1240
+ opacity: 0.8;
1241
+ }
1242
+
1243
+ .taskon-task-item-rich-text strong,
1244
+ .taskon-task-item-rich-text b {
1245
+ font-weight: 600;
1246
+ color: var(--taskon-task-text);
1247
+ }
1248
+
1249
+ .taskon-task-item-rich-text em,
1250
+ .taskon-task-item-rich-text i {
1251
+ font-style: italic;
1252
+ }
1253
+
1254
+ .taskon-task-item-rich-text ul,
1255
+ .taskon-task-item-rich-text ol {
1256
+ margin: 0.5em 0;
1257
+ padding-left: 1.5em;
1258
+ }
1259
+
1260
+ .taskon-task-item-rich-text li {
1261
+ margin: 0.25em 0;
1262
+ }
1263
+
1264
+ .taskon-task-item-rich-text code {
1265
+ background: rgba(255, 255, 255, 0.1);
1266
+ padding: 0.2em 0.4em;
1267
+ border-radius: 3px;
1268
+ font-size: 0.9em;
1269
+ }
1270
+
1271
+ .taskon-task-item-rich-text pre {
1272
+ background: rgba(255, 255, 255, 0.05);
1273
+ padding: 0.75em 1em;
1274
+ border-radius: 6px;
1275
+ overflow-x: auto;
1276
+ margin: 0.5em 0;
1277
+ }
1278
+
1279
+ .taskon-task-item-rich-text blockquote {
1280
+ border-left: 3px solid var(--taskon-color-primary);
1281
+ padding-left: 1em;
1282
+ margin: 0.5em 0;
1283
+ color: var(--taskon-task-text-muted);
1284
+ }
1285
+
1286
+ .taskon-task-item-rich-text img {
1287
+ max-width: 100%;
1288
+ height: auto;
1289
+ border-radius: 6px;
1290
+ }
1291
+
1292
+ /* Description fields */
1293
+ .taskon-task-item-fields {
1294
+ display: flex;
1295
+ flex-direction: column;
1296
+ gap: var(--taskon-task-spacing-xs);
1297
+ }
1298
+
1299
+ .taskon-task-item-field {
1300
+ display: flex;
1301
+ align-items: baseline;
1302
+ gap: var(--taskon-task-spacing-sm);
1303
+ font-size: 13px;
1304
+ }
1305
+
1306
+ .taskon-task-item-field-key {
1307
+ color: var(--taskon-task-text-muted);
1308
+ flex-shrink: 0;
1309
+ }
1310
+
1311
+ .taskon-task-item-field-value {
1312
+ color: var(--taskon-task-text);
1313
+ word-break: break-all;
1314
+ }
1315
+
1316
+ .taskon-task-item-field-value--link {
1317
+ color: #54aeff;
1318
+ text-decoration: underline;
1319
+ transition: opacity var(--taskon-task-transition);
1320
+ }
1321
+
1322
+ .taskon-task-item-field-value--link:hover {
1323
+ opacity: 0.8;
1324
+ }
1325
+
1326
+ /* Action link */
1327
+ .taskon-task-item-action-link {
1328
+ display: inline-flex;
1329
+ align-items: center;
1330
+ padding: var(--taskon-task-spacing-sm) var(--taskon-task-spacing-md);
1331
+ font-size: 13px;
1332
+ font-weight: 500;
1333
+ color: var(--taskon-color-primary);
1334
+ background: transparent;
1335
+ border: 1px solid var(--taskon-color-primary);
1336
+ border-radius: 6px;
1337
+ text-decoration: none;
1338
+ transition: all var(--taskon-task-transition);
1339
+ align-self: flex-start;
1340
+ }
1341
+
1342
+ .taskon-task-item-action-link:hover {
1343
+ background: var(--taskon-color-primary);
1344
+ color: white;
1345
+ }
1346
+
1347
+ /* Spinner animation */
1348
+ @keyframes taskon-spin {
1349
+ from {
1350
+ transform: rotate(0deg);
1351
+ }
1352
+ to {
1353
+ transform: rotate(360deg);
1354
+ }
1355
+ }
1356
+
1357
+ .taskon-task-item-spinner {
1358
+ animation: taskon-spin 1s linear infinite;
1359
+ }
1360
+
1361
+ /* ============================================
1362
+ TaskIcon Styles
1363
+ ============================================ */
1364
+ .taskon-task-icon {
1365
+ display: inline-flex;
1366
+ align-items: center;
1367
+ justify-content: center;
1368
+ flex-shrink: 0;
1369
+ }
1370
+
1371
+ .taskon-task-icon-img {
1372
+ border-radius: 50%;
1373
+ object-fit: cover;
1374
+ }
1375
+
1376
+ /* ============================================
1377
+ CooldownTimer Styles
1378
+ ============================================ */
1379
+ .taskon-cooldown-timer {
1380
+ display: inline-flex;
1381
+ align-items: center;
1382
+ gap: var(--taskon-task-spacing-xs);
1383
+ font-size: 13px;
1384
+ color: var(--taskon-color-warning);
1385
+ }
1386
+
1387
+ /* ============================================
1388
+ VerifyButton Styles
1389
+ ============================================ */
1390
+ .taskon-verify-btn {
1391
+ display: inline-flex;
1392
+ align-items: center;
1393
+ justify-content: center;
1394
+ gap: 4px;
1395
+ height: 34px;
1396
+ padding: 0 12px;
1397
+ font-size: 14px;
1398
+ font-weight: 500;
1399
+ line-height: 20px;
1400
+ color: #fff;
1401
+ background: transparent;
1402
+ border: 1px solid rgba(255, 255, 255, 0.1);
1403
+ border-radius: 6px;
1404
+ cursor: pointer;
1405
+ transition: all var(--taskon-task-transition);
1406
+ white-space: nowrap;
1407
+ flex-shrink: 0;
1408
+ }
1409
+
1410
+ .taskon-verify-btn:hover:not(:disabled) {
1411
+ border-color: rgba(255, 255, 255, 0.3);
1412
+ }
1413
+
1414
+ .taskon-verify-btn:disabled {
1415
+ opacity: 0.5;
1416
+ cursor: not-allowed;
1417
+ }
1418
+
1419
+ .taskon-verify-btn--loading {
1420
+ pointer-events: none;
1421
+ }
1422
+
1423
+ .taskon-verify-btn-spinner {
1424
+ width: 16px;
1425
+ height: 16px;
1426
+ animation: taskon-spin 1s linear infinite;
1427
+ }
1428
+
1429
+ /* ============================================
1430
+ ExpandableContent Styles
1431
+ ============================================ */
1432
+ .taskon-expandable {
1433
+ display: flex;
1434
+ flex-direction: column;
1435
+ }
1436
+
1437
+ .taskon-expandable-content {
1438
+ position: relative;
1439
+ }
1440
+
1441
+ .taskon-expandable-toggle {
1442
+ display: inline-flex;
1443
+ align-items: center;
1444
+ gap: 4px;
1445
+ padding: 0;
1446
+ margin-top: 8px;
1447
+ font-size: 13px;
1448
+ font-weight: 500;
1449
+ color: #ffffff;
1450
+ background: transparent;
1451
+ border: none;
1452
+ cursor: pointer;
1453
+ transition: opacity var(--taskon-task-transition);
1454
+ align-self: flex-start;
1455
+ }
1456
+
1457
+ .taskon-expandable-toggle:hover {
1458
+ opacity: 0.8;
1459
+ }
1460
+
1461
+ .taskon-expandable-toggle-text {
1462
+ line-height: 1;
1463
+ }
1464
+
1465
+ .taskon-expandable-toggle-icon {
1466
+ transition: transform var(--taskon-task-transition);
1467
+ flex-shrink: 0;
1468
+ }
1469
+
1470
+ .taskon-expandable-toggle-icon--expanded {
1471
+ transform: rotate(180deg);
1472
+ }
1473
+
1474
+ /* ============================================
1475
+ Responsive Styles
1476
+ ============================================ */
1477
+ @media (max-width: 750px) {
1478
+ .taskon-task-item {
1479
+ padding: 4vw;
1480
+ }
1481
+
1482
+ .taskon-task-item-body {
1483
+ margin-left: 9.333vw;
1484
+ }
1485
+
1486
+ .taskon-task-item-icon {
1487
+ margin-right: 2.667vw;
1488
+ }
1489
+
1490
+ .taskon-task-item-right {
1491
+ margin-left: 2.67vw;
1492
+ }
1493
+
1494
+ .taskon-task-item-title {
1495
+ font-weight: 400;
1496
+ font-size: 3.733vw;
1497
+ line-height: 4.667vw;
1498
+ }
1499
+
1500
+ .taskon-task-item-desc {
1501
+ font-size: 3.2vw;
1502
+ line-height: 4vw;
1503
+ }
1504
+
1505
+ .taskon-task-icon-img {
1506
+ width: 6.667vw !important;
1507
+ height: 6.667vw !important;
1508
+ }
1509
+
1510
+ /* Points display mobile - 参考 TaskPoint.vue */
1511
+ .taskon-task-item-points {
1512
+ min-width: 6.8vw;
1513
+ height: 6.67vw;
1514
+ padding: 0 2vw;
1515
+ font-size: 2.93vw;
1516
+ border-radius: 0.91vw;
1517
+ }
1518
+
1519
+ .taskon-task-item-points-time {
1520
+ font-size: 1.85vw;
1521
+ }
1522
+ }
1523
+
1524
+ /* ============================================
1525
+ TimeRange Styles
1526
+ 与 Vue 版本 TimeRange.vue 样式一致
1527
+ ============================================ */
1528
+ .taskon-task-time-range {
1529
+ font-size: 14px;
1530
+ line-height: 18px;
1531
+ margin-top: 14px;
1532
+ }
1533
+
1534
+ .taskon-task-time-range-label {
1535
+ color: var(--taskon-task-text-secondary);
1536
+ }
1537
+
1538
+ .taskon-task-time-range-value {
1539
+ display: inline-block;
1540
+ color: rgba(255, 212, 101, 1);
1541
+ }
1542
+
1543
+ /* ============================================
1544
+ VerifyButton Cooldown Progress Bar
1545
+ 与 Vue 版本 VerifyButton.vue 冷却进度条样式一致
1546
+ ============================================ */
1547
+ .taskon-verify-btn-wrap {
1548
+ position: relative;
1549
+ display: inline-block;
1550
+ overflow: hidden;
1551
+ border-radius: 6px;
1552
+ }
1553
+
1554
+ .taskon-verify-btn-progress {
1555
+ position: absolute;
1556
+ bottom: 0;
1557
+ left: 0;
1558
+ right: 0;
1559
+ height: 3px;
1560
+ }
1561
+
1562
+ .taskon-verify-btn-progress-bar {
1563
+ height: 100%;
1564
+ border-radius: 6px;
1565
+ background: linear-gradient(to right, #cbff01, #00ffa3);
1566
+ }
1567
+ /**
1568
+ * BlindBox 盲盒组件样式
1569
+ * @module widgets/Quest/components/BlindBox/styles/blind-box.css
1570
+ *
1571
+ * Migrated from Vue version with Tailwind classes converted to CSS
1572
+ */
1573
+
1574
+ /* ============================================================================
1575
+ BlindBox Dialog - 开盲盒交互弹窗
1576
+ ============================================================================ */
1577
+
1578
+ .taskon-quest-blindbox-dialog {
1579
+ position: relative;
1580
+ width: min(520px, 92vw);
1581
+ overflow: hidden;
1582
+ padding-top: 40px;
1583
+ }
1584
+
1585
+ .taskon-quest-blindbox-dialog-title {
1586
+ margin: 0 0 16px;
1587
+ padding: 0 40px;
1588
+ font-size: 22px;
1589
+ font-weight: 600;
1590
+ line-height: 1.4;
1591
+ color: #fff;
1592
+ }
1593
+
1594
+ /* Stage container - centered square area for animation */
1595
+ .taskon-quest-blindbox-stage {
1596
+ position: relative;
1597
+ display: flex;
1598
+ align-items: center;
1599
+ justify-content: center;
1600
+ width: 100%;
1601
+ max-width: 420px;
1602
+ margin: 0 auto;
1603
+ aspect-ratio: 1;
1604
+ overflow: visible;
1605
+ border-radius: 32px;
1606
+ background: transparent;
1607
+ }
1608
+
1609
+ /* Background spinning light */
1610
+ .taskon-quest-blindbox-bg {
1611
+ position: absolute;
1612
+ left: 50%;
1613
+ top: calc(40% + 20px);
1614
+ width: min(80%, 340px);
1615
+ transform: translate(-50%, -50%);
1616
+ pointer-events: none;
1617
+ opacity: 0.75;
1618
+ animation: taskon-blindbox-spin 14s linear infinite;
1619
+ }
1620
+
1621
+ .taskon-quest-blindbox-bg img {
1622
+ width: 100%;
1623
+ height: auto;
1624
+ }
1625
+
1626
+ @keyframes taskon-blindbox-spin {
1627
+ from {
1628
+ transform: translate(-50%, -50%) rotate(0deg);
1629
+ }
1630
+ to {
1631
+ transform: translate(-50%, -50%) rotate(360deg);
1632
+ }
1633
+ }
1634
+
1635
+ /* Drop zone - collision detection area */
1636
+ .taskon-quest-blindbox-dropzone {
1637
+ position: absolute;
1638
+ left: 50%;
1639
+ top: calc(40% + 20px);
1640
+ width: min(33%, 145px);
1641
+ height: min(33%, 145px);
1642
+ transform: translate(-50%, -50%);
1643
+ pointer-events: none;
1644
+ }
1645
+
1646
+ /* Chest container */
1647
+ .taskon-quest-blindbox-chest {
1648
+ position: absolute;
1649
+ left: 50%;
1650
+ top: 40%;
1651
+ width: min(75%, 350px);
1652
+ height: auto;
1653
+ transform: translate(-50%, -50%);
1654
+ pointer-events: none;
1655
+ transition: filter 0.2s ease;
1656
+ }
1657
+
1658
+ .taskon-quest-blindbox-chest--highlighted {
1659
+ filter: drop-shadow(0 0 16px rgba(233, 168, 30, 0.55));
1660
+ }
1661
+
1662
+ .taskon-quest-blindbox-chest--open {
1663
+ filter: drop-shadow(0 0 22px rgba(255, 205, 112, 0.75));
1664
+ }
1665
+
1666
+ /* Ensure Lottie SVG fills container */
1667
+ .taskon-quest-blindbox-chest svg {
1668
+ width: 100% !important;
1669
+ height: auto !important;
1670
+ }
1671
+
1672
+ /* Key image */
1673
+ .taskon-quest-blindbox-key {
1674
+ position: absolute;
1675
+ width: clamp(80px, 16vw, 100px);
1676
+ transform: translate(-50%, -50%);
1677
+ cursor: grab;
1678
+ touch-action: none;
1679
+ user-select: none;
1680
+ transition: transform 0.2s ease, filter 0.2s ease;
1681
+ pointer-events: auto;
1682
+ }
1683
+
1684
+ .taskon-quest-blindbox-key--dragging {
1685
+ transform: translate(-50%, -50%) scale(1.04);
1686
+ cursor: grabbing;
1687
+ }
1688
+
1689
+ .taskon-quest-blindbox-key--hovering {
1690
+ filter: drop-shadow(0 0 18px rgba(255, 211, 103, 0.8));
1691
+ }
1692
+
1693
+ .taskon-quest-blindbox-key--disabled {
1694
+ pointer-events: none;
1695
+ opacity: 0.6;
1696
+ }
1697
+
1698
+ /* ============================================================================
1699
+ BlindBox Reward Dialog - 奖励结果展示弹窗
1700
+ ============================================================================ */
1701
+
1702
+ .taskon-quest-blindbox-reward {
1703
+ position: relative;
1704
+ width: 510px;
1705
+ max-width: 92vw;
1706
+ padding: 64px 40px;
1707
+ text-align: center;
1708
+ color: #fff;
1709
+ overflow: hidden;
1710
+ }
1711
+
1712
+ /* Light background effect */
1713
+ .taskon-quest-blindbox-reward-light {
1714
+ position: absolute;
1715
+ top: 0;
1716
+ left: 50%;
1717
+ width: 120%;
1718
+ max-width: none;
1719
+ transform: translateX(-50%);
1720
+ object-fit: contain;
1721
+ pointer-events: none;
1722
+ opacity: 0;
1723
+ animation: taskon-blindbox-light-appear 2s ease-out forwards;
1724
+ }
1725
+
1726
+ @keyframes taskon-blindbox-light-appear {
1727
+ to {
1728
+ opacity: 1;
1729
+ }
1730
+ }
1731
+
1732
+ /* Title */
1733
+ .taskon-quest-blindbox-reward-title {
1734
+ font-size: 32px;
1735
+ font-weight: 600;
1736
+ line-height: 40px;
1737
+ margin: 0;
1738
+ }
1739
+
1740
+ /* Subtitle */
1741
+ .taskon-quest-blindbox-reward-subtitle {
1742
+ margin-top: 12px;
1743
+ font-size: 16px;
1744
+ line-height: 1.5;
1745
+ color: rgba(255, 255, 255, 0.7);
1746
+ }
1747
+
1748
+ /* Rewards container - Green border and background like Vue version */
1749
+ .taskon-quest-blindbox-reward-list {
1750
+ display: inline-flex;
1751
+ flex-wrap: wrap;
1752
+ justify-content: center;
1753
+ align-items: center;
1754
+ margin-top: 24px;
1755
+ gap: 8px;
1756
+ padding: 12px 16px;
1757
+ border-radius: 8px;
1758
+ border: 1px solid rgba(60, 232, 155, 0.2);
1759
+ background: rgba(0, 255, 163, 0.1);
1760
+ }
1761
+
1762
+ /* Single reward card - transparent background */
1763
+ .taskon-quest-blindbox-reward-card {
1764
+ display: flex;
1765
+ flex-direction: column;
1766
+ align-items: center;
1767
+ justify-content: center;
1768
+ padding: 12px 16px;
1769
+ background: transparent;
1770
+ border-radius: 0;
1771
+ min-width: 60px;
1772
+ min-height: 80px;
1773
+ gap: 8px;
1774
+ }
1775
+
1776
+ .taskon-quest-blindbox-reward-card-icon {
1777
+ width: 32px;
1778
+ height: 32px;
1779
+ object-fit: contain;
1780
+ border-radius: 50%;
1781
+ }
1782
+
1783
+ /* Token amount with orange color and underline like Vue version */
1784
+ .taskon-quest-blindbox-reward-card-amount {
1785
+ font-size: 18px;
1786
+ font-weight: 600;
1787
+ color: #fbb15a;
1788
+ text-decoration: underline;
1789
+ }
1790
+
1791
+ .taskon-quest-blindbox-reward-card-name {
1792
+ font-size: 14px;
1793
+ color: #fbb15a;
1794
+ text-decoration: underline;
1795
+ }
1796
+
1797
+ .taskon-quest-blindbox-reward-card-value {
1798
+ font-size: 12px;
1799
+ color: rgba(255, 255, 255, 0.5);
1800
+ margin-top: 2px;
1801
+ }
1802
+
1803
+ /* Back button */
1804
+ .taskon-quest-blindbox-reward-btn-wrap {
1805
+ display: flex;
1806
+ justify-content: center;
1807
+ margin-top: 60px;
1808
+ }
1809
+
1810
+ /* Back button - matches Vue g-button--light-border */
1811
+ .taskon-quest-blindbox-reward-btn {
1812
+ height: 36px;
1813
+ padding: 0 24px;
1814
+ font-size: 14px;
1815
+ font-weight: 500;
1816
+ color: #fff;
1817
+ background: transparent;
1818
+ border: 1px solid #fff;
1819
+ border-radius: 8px;
1820
+ cursor: pointer;
1821
+ transition: opacity 0.2s ease;
1822
+ }
1823
+
1824
+ .taskon-quest-blindbox-reward-btn:hover {
1825
+ opacity: 0.8;
1826
+ }
1827
+
1828
+ .taskon-quest-blindbox-reward-btn:disabled {
1829
+ opacity: 0.5;
1830
+ cursor: not-allowed;
1831
+ }
1832
+
1833
+ /* ============================================================================
1834
+ OperateFooter - 开盲盒按钮
1835
+ ============================================================================ */
1836
+
1837
+ .taskon-quest-footer-blindbox-btn {
1838
+ display: flex;
1839
+ align-items: center;
1840
+ justify-content: center;
1841
+ gap: 8px;
1842
+ width: 100%;
1843
+ padding: 14px 24px;
1844
+ font-size: 16px;
1845
+ font-weight: 600;
1846
+ color: #000;
1847
+ background: linear-gradient(135deg, #ffd700 0%, #ffaa00 100%);
1848
+ border: none;
1849
+ border-radius: 12px;
1850
+ cursor: pointer;
1851
+ transition: all 0.2s ease;
1852
+ }
1853
+
1854
+ .taskon-quest-footer-blindbox-btn:hover {
1855
+ transform: translateY(-1px);
1856
+ box-shadow: 0 4px 16px rgba(255, 215, 0, 0.4);
1857
+ }
1858
+
1859
+ .taskon-quest-footer-blindbox-btn:active {
1860
+ transform: translateY(0);
1861
+ }
1862
+
1863
+ .taskon-quest-footer-blindbox-btn-icon {
1864
+ width: 24px;
1865
+ height: 24px;
1866
+ }
1867
+
1868
+ /* ============================================================================
1869
+ Mobile Responsive
1870
+ ============================================================================ */
1871
+
1872
+ @media (max-width: 768px) {
1873
+ .taskon-quest-blindbox-dialog {
1874
+ padding-top: 24px;
1875
+ }
1876
+
1877
+ .taskon-quest-blindbox-dialog-title {
1878
+ padding: 0 24px;
1879
+ font-size: 18px;
1880
+ }
1881
+
1882
+ .taskon-quest-blindbox-reward {
1883
+ padding: 48px 24px;
1884
+ }
1885
+
1886
+ .taskon-quest-blindbox-reward-title {
1887
+ font-size: 24px;
1888
+ line-height: 32px;
1889
+ }
1890
+
1891
+ .taskon-quest-blindbox-reward-btn-wrap {
1892
+ margin-top: 40px;
1893
+ }
1894
+ }
1895
+ /**
1896
+ * Eligibility (资格验证) 组件样式
1897
+ * @description Standalone CSS for EligibilityInfo component, usable in any widget context.
1898
+ *
1899
+ * CSS variable fallbacks ensure correct rendering even outside Quest widget
1900
+ * (e.g., when used in TaskChain). When rendered inside .taskon-quest,
1901
+ * the Quest-defined variables take precedence.
1902
+ */
1903
+
1904
+ /* ============================================================================
1905
+ Eligibility 主容器
1906
+ ============================================================================ */
1907
+
1908
+ .taskon-quest-eligs {
1909
+ margin-top: 25px;
1910
+ padding: 0 18px;
1911
+ border: 1px solid var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
1912
+ border-radius: 10px;
1913
+ }
1914
+
1915
+ /* 动画效果 - 用于引导用户注意 */
1916
+ .taskon-quest-eligs--animate {
1917
+ animation: taskon-quest-eligs-glow 800ms ease-out infinite alternate;
1918
+ }
1919
+
1920
+ @keyframes taskon-quest-eligs-glow {
1921
+ 0% {
1922
+ border-color: var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
1923
+ }
1924
+ 100% {
1925
+ border-color: rgba(255, 255, 255, 0.4);
1926
+ }
1927
+ }
1928
+
1929
+ /* ============================================================================
1930
+ 折叠头部
1931
+ ============================================================================ */
1932
+
1933
+ .taskon-quest-eligs-header {
1934
+ height: 60px;
1935
+ display: flex;
1936
+ align-items: center;
1937
+ gap: 10px;
1938
+ font-size: 16px;
1939
+ line-height: 20px;
1940
+ cursor: pointer;
1941
+ user-select: none;
1942
+ }
1943
+
1944
+ .taskon-quest-eligs-header:hover {
1945
+ opacity: 0.9;
1946
+ }
1947
+
1948
+ /* 状态图标 */
1949
+ .taskon-quest-eligs-header-status {
1950
+ flex-shrink: 0;
1951
+ }
1952
+
1953
+ /* 头部文本 */
1954
+ .taskon-quest-eligs-header-text {
1955
+ flex: 1;
1956
+ color: var(--taskon-quest-text-lightest, #ffffff);
1957
+ }
1958
+
1959
+ /* 高亮表达式 (all/any) */
1960
+ .taskon-quest-eligs-header-express {
1961
+ color: var(--taskon-quest-secondary, #1affab);
1962
+ }
1963
+
1964
+ /* ============================================================================
1965
+ 刷新按钮
1966
+ ============================================================================ */
1967
+
1968
+ .taskon-quest-eligs-refresh {
1969
+ display: flex;
1970
+ align-items: center;
1971
+ justify-content: center;
1972
+ width: 32px;
1973
+ height: 32px;
1974
+ padding: 0;
1975
+ margin-left: auto;
1976
+ background: transparent;
1977
+ border: 1px solid var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
1978
+ border-radius: 6px;
1979
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
1980
+ cursor: pointer;
1981
+ transition: all 0.2s;
1982
+ }
1983
+
1984
+ .taskon-quest-eligs-refresh:hover:not(:disabled) {
1985
+ border-color: var(--taskon-quest-text-light, rgba(255, 255, 255, 0.6));
1986
+ color: var(--taskon-quest-text-lightest, #ffffff);
1987
+ }
1988
+
1989
+ .taskon-quest-eligs-refresh:disabled {
1990
+ opacity: 0.5;
1991
+ cursor: not-allowed;
1992
+ }
1993
+
1994
+ .taskon-quest-eligs-refresh--loading .taskon-quest-eligs-refresh-icon {
1995
+ animation: taskon-quest-eligs-spin 1s linear infinite;
1996
+ }
1997
+
1998
+ @keyframes taskon-quest-eligs-spin {
1999
+ to {
2000
+ transform: rotate(360deg);
2001
+ }
2002
+ }
2003
+
2004
+ /* ============================================================================
2005
+ 箭头图标
2006
+ ============================================================================ */
2007
+
2008
+ .taskon-quest-eligs-header-arrow {
2009
+ flex-shrink: 0;
2010
+ width: 6px;
2011
+ height: 10px;
2012
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2013
+ transform: rotate(90deg);
2014
+ transition: transform 0.3s;
2015
+ }
2016
+
2017
+ .taskon-quest-eligs-header-arrow--expanded {
2018
+ transform: rotate(-90deg);
2019
+ }
2020
+
2021
+ /* ============================================================================
2022
+ 列表
2023
+ ============================================================================ */
2024
+
2025
+ .taskon-quest-eligs-list {
2026
+ text-align: left;
2027
+ padding: 20px 0;
2028
+ margin: 0;
2029
+ list-style: none;
2030
+ border-top: 1px solid var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
2031
+ }
2032
+
2033
+ /* 单项 */
2034
+ .taskon-quest-eligs-item {
2035
+ line-height: 18px;
2036
+ }
2037
+
2038
+ .taskon-quest-eligs-item + .taskon-quest-eligs-item {
2039
+ margin-top: 24px;
2040
+ }
2041
+
2042
+ .taskon-quest-eligs-item-container {
2043
+ display: flex;
2044
+ align-items: flex-start;
2045
+ }
2046
+
2047
+ /* 状态图标 */
2048
+ .taskon-quest-eligs-item-icon {
2049
+ flex-shrink: 0;
2050
+ margin-right: 10px;
2051
+ margin-top: 2px;
2052
+ opacity: 0;
2053
+ }
2054
+
2055
+ .taskon-quest-eligs-item-icon-placeholder {
2056
+ flex-shrink: 0;
2057
+ width: 16px;
2058
+ height: 16px;
2059
+ margin-right: 10px;
2060
+ margin-top: 2px;
2061
+ }
2062
+
2063
+ .taskon-quest-eligs-item--passed .taskon-quest-eligs-item-icon,
2064
+ .taskon-quest-eligs-item--failed .taskon-quest-eligs-item-icon {
2065
+ opacity: 1;
2066
+ }
2067
+
2068
+ /* 内容区 */
2069
+ .taskon-quest-eligs-item-content {
2070
+ flex: 1;
2071
+ font-size: 14px;
2072
+ line-height: 18px;
2073
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2074
+ }
2075
+
2076
+ /* ============================================================================
2077
+ 类型组件样式
2078
+ ============================================================================ */
2079
+
2080
+ .taskon-quest-eligs-type {
2081
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2082
+ }
2083
+
2084
+ .taskon-quest-eligs-type--tooltip {
2085
+ position: relative;
2086
+ cursor: help;
2087
+ }
2088
+
2089
+ /* 高亮文本 */
2090
+ .taskon-quest-eligs-highlight {
2091
+ color: var(--taskon-quest-primary, #cbff01);
2092
+ }
2093
+
2094
+ /* 链接样式 */
2095
+ .taskon-quest-eligs-link {
2096
+ color: var(--taskon-quest-link, #58afff);
2097
+ text-decoration: underline;
2098
+ }
2099
+
2100
+ .taskon-quest-eligs-link:hover {
2101
+ opacity: 0.8;
2102
+ }
2103
+
2104
+ /* Tooltip */
2105
+ .taskon-quest-eligs-tooltip {
2106
+ position: absolute;
2107
+ top: 100%;
2108
+ left: 0;
2109
+ z-index: 10;
2110
+ margin-top: 4px;
2111
+ padding: 8px 12px;
2112
+ max-width: 300px;
2113
+ font-size: 12px;
2114
+ line-height: 16px;
2115
+ color: var(--taskon-quest-text-lightest, #ffffff);
2116
+ background-color: rgba(0, 0, 0, 0.9);
2117
+ border-radius: 6px;
2118
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2119
+ white-space: normal;
2120
+ word-break: break-word;
2121
+ }
2122
+
2123
+ /* ============================================================================
2124
+ 子条件容器
2125
+ ============================================================================ */
2126
+
2127
+ .taskon-quest-eligs-sub {
2128
+ width: 100%;
2129
+ }
2130
+
2131
+ .taskon-quest-eligs-sub-header {
2132
+ display: flex;
2133
+ align-items: center;
2134
+ justify-content: space-between;
2135
+ font-weight: 600;
2136
+ cursor: pointer;
2137
+ }
2138
+
2139
+ .taskon-quest-eligs-sub-header:hover {
2140
+ opacity: 0.9;
2141
+ }
2142
+
2143
+ .taskon-quest-eligs-sub-label {
2144
+ flex: 1;
2145
+ }
2146
+
2147
+ .taskon-quest-eligs-sub-arrow {
2148
+ flex-shrink: 0;
2149
+ width: 8px;
2150
+ height: 8px;
2151
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2152
+ transform: rotate(-90deg);
2153
+ transition: transform 0.3s;
2154
+ }
2155
+
2156
+ .taskon-quest-eligs-sub-arrow--expanded {
2157
+ transform: rotate(90deg);
2158
+ }
2159
+
2160
+ .taskon-quest-eligs-sub-list {
2161
+ margin-top: 10px;
2162
+ padding-left: 14px;
2163
+ list-style: disc;
2164
+ display: flex;
2165
+ flex-direction: column;
2166
+ gap: 8px;
2167
+ }
2168
+
2169
+ .taskon-quest-eligs-sub-list li {
2170
+ font-size: 14px;
2171
+ line-height: 18px;
2172
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2173
+ }
2174
+
2175
+ /* ============================================================================
2176
+ Eligibility 响应式样式
2177
+ ============================================================================ */
2178
+
2179
+ @media (max-width: 750px) {
2180
+ .taskon-quest-eligs {
2181
+ margin-top: 5.07vw;
2182
+ padding: 0 4vw;
2183
+ }
2184
+
2185
+ .taskon-quest-eligs-header {
2186
+ height: 12vw;
2187
+ font-size: 3.47vw;
2188
+ line-height: 4.4vw;
2189
+ }
2190
+
2191
+ .taskon-quest-eligs-header-arrow {
2192
+ width: 1.2vw;
2193
+ height: 2.4vw;
2194
+ }
2195
+
2196
+ .taskon-quest-eligs-list {
2197
+ padding: 3.73vw 0;
2198
+ }
2199
+
2200
+ .taskon-quest-eligs-item + .taskon-quest-eligs-item {
2201
+ margin-top: 3.73vw;
2202
+ }
2203
+
2204
+ .taskon-quest-eligs-item-icon,
2205
+ .taskon-quest-eligs-item-icon-placeholder {
2206
+ margin-top: 0.8vw;
2207
+ margin-right: 1.87vw;
2208
+ width: 3.2vw;
2209
+ height: 3.2vw;
2210
+ }
2211
+
2212
+ .taskon-quest-eligs-item-content {
2213
+ font-size: 3.47vw;
2214
+ line-height: 4.4vw;
2215
+ }
2216
+ }
2217
+
2218
+ /* ============================================================================
2219
+ OnChainVerify Tooltip Styles
2220
+ ============================================================================ */
2221
+
2222
+ .taskon-quest-eligs-onchain-item {
2223
+ display: inline;
2224
+ }
2225
+
2226
+ .taskon-quest-eligs-onchain-link {
2227
+ position: relative;
2228
+ display: inline;
2229
+ text-decoration: underline;
2230
+ cursor: pointer;
2231
+ color: var(--taskon-quest-text-lightest, #ffffff);
2232
+ }
2233
+
2234
+ .taskon-quest-eligs-onchain-link:hover {
2235
+ color: var(--taskon-quest-link, #58afff);
2236
+ }
2237
+
2238
+ .taskon-quest-eligs-onchain-tooltip {
2239
+ position: absolute;
2240
+ bottom: calc(100% + 8px);
2241
+ left: 0;
2242
+ min-width: 260px;
2243
+ padding: 12px 16px;
2244
+ background-color: #222222;
2245
+ border: 1px solid rgba(255, 255, 255, 0.1);
2246
+ border-radius: var(--taskon-quest-radius-l, 8px);
2247
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
2248
+ z-index: 100;
2249
+ font-size: 14px;
2250
+ line-height: 1.5;
2251
+ }
2252
+
2253
+ .taskon-quest-eligs-onchain-tooltip::before {
2254
+ content: "";
2255
+ position: absolute;
2256
+ bottom: -6px;
2257
+ left: 16px;
2258
+ width: 12px;
2259
+ height: 12px;
2260
+ background-color: #222222;
2261
+ border-right: 1px solid rgba(255, 255, 255, 0.1);
2262
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
2263
+ transform: rotate(45deg);
2264
+ }
2265
+
2266
+ .taskon-quest-eligs-onchain-tooltip p {
2267
+ margin: 0 0 8px 0;
2268
+ color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2269
+ }
2270
+
2271
+ .taskon-quest-eligs-onchain-tooltip ul {
2272
+ margin: 0;
2273
+ padding: 0;
2274
+ list-style: disc;
2275
+ list-style-position: inside;
2276
+ }
2277
+
2278
+ .taskon-quest-eligs-onchain-tooltip ul li {
2279
+ margin: 4px 0;
2280
+ }
2281
+
2282
+ .taskon-quest-eligs-onchain-tooltip-link {
2283
+ color: var(--taskon-quest-link, #58afff);
2284
+ text-decoration: underline;
2285
+ font-size: 14px;
2286
+ line-height: 18px;
2287
+ }
2288
+
2289
+ .taskon-quest-eligs-onchain-tooltip-link:hover {
2290
+ color: var(--taskon-quest-text-lightest, #ffffff);
2291
+ }
2292
+
2293
+ /* ============================================================================
2294
+ Poh / NFT / Copy Styles
2295
+ ============================================================================ */
2296
+
2297
+ .taskon-quest-eligs-poh-provider {
2298
+ font-weight: 500;
2299
+ }
2300
+
2301
+ .taskon-quest-eligs-nft-name {
2302
+ position: relative;
2303
+ display: inline;
2304
+ color: var(--taskon-quest-secondary, #1affab);
2305
+ cursor: pointer;
2306
+ text-decoration: underline;
2307
+ }
2308
+
2309
+ .taskon-quest-eligs-nft-name:hover {
2310
+ color: var(--taskon-quest-link, #58afff);
2311
+ }
2312
+
2313
+ .taskon-quest-eligs-copied {
2314
+ position: absolute;
2315
+ bottom: calc(100% + 4px);
2316
+ left: 50%;
2317
+ transform: translateX(-50%);
2318
+ padding: 4px 8px;
2319
+ background-color: #222222;
2320
+ border-radius: var(--taskon-quest-radius-s, 4px);
2321
+ font-size: 12px;
2322
+ color: var(--taskon-quest-secondary, #1affab);
2323
+ white-space: nowrap;
2324
+ pointer-events: none;
2325
+ animation: taskon-quest-eligs-fade-in 0.2s ease-out;
2326
+ }
2327
+
2328
+ @keyframes taskon-quest-eligs-fade-in {
2329
+ from {
2330
+ opacity: 0;
2331
+ transform: translateX(-50%) translateY(4px);
2332
+ }
2333
+ to {
2334
+ opacity: 1;
2335
+ transform: translateX(-50%) translateY(0);
2336
+ }
2337
+ }