@taskon/widget-react 0.0.1-beta.3 → 0.0.1-beta.4

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