@taskon/widget-react 0.0.1-beta.2 → 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 (44) hide show
  1. package/README.md +56 -17
  2. package/dist/CommunityTaskList.css +1593 -1741
  3. package/dist/EligibilityInfo.css +1275 -582
  4. package/dist/LeaderboardWidget.css +355 -152
  5. package/dist/PageBuilder.css +0 -2
  6. package/dist/Quest.css +1140 -903
  7. package/dist/TaskOnProvider.css +50 -31
  8. package/dist/UserCenterWidget.css +108 -237
  9. package/dist/UserCenterWidget2.css +2016 -711
  10. package/dist/chunks/{CommunityTaskList-BlH1Wdd5.js → CommunityTaskList-C9Gv8KOF.js} +962 -827
  11. package/dist/chunks/{EligibilityInfo-C7GZ2G5u.js → EligibilityInfo-D-Fuy9GE.js} +1137 -449
  12. package/dist/chunks/{LeaderboardWidget-CmYfDeHV.js → LeaderboardWidget-BV2D2q1N.js} +15 -10
  13. package/dist/chunks/{PageBuilder-Bw0zSkFh.js → PageBuilder-DQoU4Mwf.js} +5 -5
  14. package/dist/chunks/{Quest-DKFZ-pPU.js → Quest-B5NyVr3o.js} +516 -325
  15. package/dist/chunks/{TaskOnProvider-BD6Vp2x8.js → TaskOnProvider-93UxARFo.js} +2 -207
  16. package/dist/chunks/{ThemeProvider-wnSXrNQb.js → ThemeProvider-CPI_roeh.js} +249 -57
  17. package/dist/chunks/{UserCenterWidget-Cw6h_5hT.js → UserCenterWidget-BRtigY_S.js} +206 -1002
  18. package/dist/chunks/UserCenterWidget-cADBSVg7.js +8358 -0
  19. package/dist/chunks/{WidgetShell-D_5OjvNZ.js → dynamic-import-helper-DwXlQC0S.js} +607 -40
  20. package/dist/chunks/useToast-CaRkylKe.js +304 -0
  21. package/dist/chunks/{usercenter-ja-uu-XfVF9.js → usercenter-ja-B2465c1O.js} +4 -10
  22. package/dist/chunks/{usercenter-ko-DYgUOVzd.js → usercenter-ko-xAEYxqLg.js} +4 -10
  23. package/dist/community-task.d.ts +34 -3
  24. package/dist/community-task.js +1 -1
  25. package/dist/core.d.ts +40 -3
  26. package/dist/core.js +9 -10
  27. package/dist/dynamic-import-helper.css +596 -289
  28. package/dist/index.d.ts +207 -10
  29. package/dist/index.js +21 -19
  30. package/dist/leaderboard.d.ts +8 -1
  31. package/dist/leaderboard.js +2 -2
  32. package/dist/page-builder.js +1 -1
  33. package/dist/quest.d.ts +8 -2
  34. package/dist/quest.js +1 -1
  35. package/dist/user-center.d.ts +20 -136
  36. package/dist/user-center.js +19 -236
  37. package/package.json +10 -2
  38. package/dist/TipPopover.css +0 -210
  39. package/dist/WidgetShell.css +0 -182
  40. package/dist/chunks/TipPopover-BrW8jo71.js +0 -2926
  41. package/dist/chunks/UserCenterWidget-BE329iS7.js +0 -3546
  42. package/dist/chunks/dynamic-import-helper-DxEFwm31.js +0 -537
  43. package/dist/chunks/useToast-B-wyO5zL.js +0 -93
  44. package/dist/chunks/useWidgetLocale-JDelxtt8.js +0 -74
@@ -1,3 +1,178 @@
1
+ /**
2
+ * ConfirmNoticeDialog styles
3
+ *
4
+ * @description
5
+ * Reproduces the visual rhythm of taskon-website ConfirmNotice:
6
+ * icon -> title -> description -> actions,
7
+ * while intentionally removing the glow background layer.
8
+ */
9
+
10
+ /*
11
+ * Responsive base styles
12
+ *
13
+ * Keep mobile breakpoints and fallback patterns centralized here.
14
+ * Components should reuse these mixins instead of duplicating query logic.
15
+ */
16
+
17
+ /*
18
+ * Desktop-up mixin:
19
+ * 1) Enable desktop enhancement in wider containers
20
+ * 2) Keep viewport media query as fallback
21
+ */
22
+
23
+ /* Narrow the default dialog body padding for this notice layout */
24
+
25
+ .taskon-confirm-notice-dialog .taskon-dialog-body {
26
+ padding: 0;
27
+ }
28
+
29
+ /* ConfirmNotice content root */
30
+
31
+ .taskon-confirm-notice {
32
+ position: relative;
33
+ width: auto;
34
+ max-width: none;
35
+ padding: var(--taskon-spacing-xl) var(--taskon-spacing-lg) var(--taskon-spacing-lg);
36
+ background: var(--taskon-color-bg-floating);
37
+ color: var(--taskon-color-text);
38
+ border-radius: var(--taskon-border-radius-lg);
39
+ text-align: center;
40
+ box-sizing: border-box;
41
+ }
42
+
43
+ /* Status icon */
44
+
45
+ .taskon-confirm-notice-icon {
46
+ width: 46px;
47
+ height: 46px;
48
+ display: block;
49
+ margin: 0 auto;
50
+ }
51
+
52
+ /* Title */
53
+
54
+ .taskon-confirm-notice-title {
55
+ margin: 20px 0 0;
56
+ font-weight: 600;
57
+ font-size: 22px;
58
+ line-height: 28px;
59
+ color: var(--taskon-color-text);
60
+ white-space: pre-wrap;
61
+ }
62
+
63
+ /* Description */
64
+
65
+ .taskon-confirm-notice-desc {
66
+ margin: 10px 0 0;
67
+ font-size: 16px;
68
+ line-height: 20px;
69
+ color: var(--taskon-color-text-secondary);
70
+ white-space: pre-wrap;
71
+ }
72
+
73
+ /* Action container */
74
+
75
+ .taskon-confirm-notice-buttons {
76
+ margin-top: 20px;
77
+ display: flex;
78
+ flex-direction: column;
79
+ align-items: stretch;
80
+ justify-content: center;
81
+ gap: 10px;
82
+ }
83
+
84
+ .taskon-confirm-notice-buttons--col {
85
+ flex-wrap: wrap;
86
+ }
87
+
88
+ /* Base action button style */
89
+
90
+ .taskon-confirm-notice-button {
91
+ width: 100%;
92
+ min-width: 100%;
93
+ height: 36px;
94
+ padding: 0 16px;
95
+ border-radius: 8px;
96
+ border: 1px solid transparent;
97
+ font-size: 14px;
98
+ font-weight: 600;
99
+ line-height: 36px;
100
+ text-align: center;
101
+ cursor: pointer;
102
+ transition: all 0.2s ease;
103
+ }
104
+
105
+ .taskon-confirm-notice-button:disabled {
106
+ opacity: 0.5;
107
+ cursor: not-allowed;
108
+ }
109
+
110
+ /* Cancel button */
111
+
112
+ .taskon-confirm-notice-button--cancel {
113
+ color: var(--taskon-color-text);
114
+ background: var(--taskon-color-bg-surface-subtle);
115
+ border-color: var(--taskon-color-border);
116
+ }
117
+
118
+ .taskon-confirm-notice-button--cancel:hover:not(:disabled),
119
+ .taskon-confirm-notice-button--cancel:focus-visible:not(:disabled) {
120
+ background: var(--taskon-color-bg-surface);
121
+ }
122
+
123
+ /* Confirm button */
124
+
125
+ .taskon-confirm-notice-button--confirm {
126
+ color: var(--taskon-color-text-on-primary);
127
+ background: var(--taskon-color-primary);
128
+ }
129
+
130
+ .taskon-confirm-notice-button--confirm:hover:not(:disabled),
131
+ .taskon-confirm-notice-button--confirm:focus-visible:not(:disabled) {
132
+ background: var(--taskon-color-primary-hover);
133
+ }
134
+
135
+ /* Desktop 增强 */
136
+
137
+ @supports (container-type: inline-size) {
138
+ @container (min-width: 751px) {
139
+ .taskon-confirm-notice {
140
+ width: 100%;
141
+ max-width: 470px;
142
+ padding: 40px 55px;
143
+ }
144
+
145
+ .taskon-confirm-notice-buttons {
146
+ flex-direction: row;
147
+ align-items: center;
148
+ }
149
+
150
+ .taskon-confirm-notice-button {
151
+ width: auto;
152
+ min-width: 161px;
153
+ }
154
+ }
155
+ }
156
+
157
+ @supports not (container-type: inline-size) {
158
+ @media (min-width: 751px) {
159
+ .taskon-confirm-notice {
160
+ width: 100%;
161
+ max-width: 470px;
162
+ padding: 40px 55px;
163
+ }
164
+
165
+ .taskon-confirm-notice-buttons {
166
+ flex-direction: row;
167
+ align-items: center;
168
+ }
169
+
170
+ .taskon-confirm-notice-button {
171
+ width: auto;
172
+ min-width: 161px;
173
+ }
174
+ }
175
+ }
1
176
  /**
2
177
  * Textarea 通用组件样式
3
178
  * @description 复刻 Vue 版本 BaseTextareaPro.vue 样式
@@ -5,21 +180,23 @@
5
180
  */
6
181
 
7
182
  /* ==================== 容器 ==================== */
183
+
8
184
  .taskon-textarea-wrap {
9
185
  position: relative;
10
186
  font-size: 0;
11
187
  }
12
188
 
13
189
  /* ==================== 文本域 ==================== */
190
+
14
191
  .taskon-textarea {
15
192
  width: 100%;
16
193
  min-height: 100px;
17
194
  padding: 12px;
18
195
  padding-bottom: 36px; /* 给计数器留空间 */
19
196
  border-radius: 6px;
20
- border: 1px solid rgba(255, 255, 255, 0.1);
21
- background: rgba(255, 255, 255, 0.04);
22
- color: var(--taskon-color-text, #fff);
197
+ border: 1px solid var(--taskon-color-border);
198
+ background: var(--taskon-color-bg-surface-subtle);
199
+ color: var(--taskon-color-text);
23
200
  font-size: 14px;
24
201
  line-height: 1.5;
25
202
  resize: none;
@@ -28,7 +205,7 @@
28
205
  }
29
206
 
30
207
  .taskon-textarea:focus {
31
- border-color: var(--taskon-color-primary, #cbff01);
208
+ border-color: var(--taskon-color-primary);
32
209
  }
33
210
 
34
211
  .taskon-textarea:disabled {
@@ -37,14 +214,15 @@
37
214
  }
38
215
 
39
216
  .taskon-textarea--error {
40
- border-color: #eb5757;
217
+ border-color: var(--taskon-color-error);
41
218
  }
42
219
 
43
220
  .taskon-textarea::placeholder {
44
- color: var(--taskon-color-text-tertiary, #666);
221
+ color: var(--taskon-color-text-tertiary);
45
222
  }
46
223
 
47
224
  /* ==================== 字数统计 ==================== */
225
+
48
226
  .taskon-textarea-count {
49
227
  position: absolute;
50
228
  right: 20px;
@@ -52,28 +230,11 @@
52
230
  font-weight: 400;
53
231
  font-size: 14px;
54
232
  line-height: 20px;
55
- color: rgba(255, 255, 255, 0.6);
233
+ color: var(--taskon-color-text-tertiary);
56
234
  }
57
235
 
58
236
  .taskon-textarea-count-current {
59
- color: #fff;
60
- }
61
-
62
- /* ==================== 响应式 ==================== */
63
- @media (max-width: 750px) {
64
- .taskon-textarea {
65
- min-height: 26.667vw;
66
- padding: 3.2vw;
67
- padding-bottom: 8vw; /* 给计数器留空间 */
68
- font-size: 3.733vw;
69
- }
70
-
71
- .taskon-textarea-count {
72
- right: 2.933vw;
73
- bottom: 2.667vw;
74
- font-size: 2.933vw;
75
- line-height: 2.667vw;
76
- }
237
+ color: var(--taskon-color-text);
77
238
  }
78
239
  /**
79
240
  * TitleExpress 组件样式
@@ -81,9 +242,10 @@
81
242
  */
82
243
 
83
244
  /* 可点击链接 - 统一蓝色加下划线样式 */
245
+
84
246
  .taskon-title-express-link {
85
247
  display: inline;
86
- color: #54aeff;
248
+ color: var(--taskon-color-link);
87
249
  cursor: pointer;
88
250
  text-decoration: underline;
89
251
  transition: opacity 0.2s ease;
@@ -94,29 +256,31 @@
94
256
  }
95
257
 
96
258
  /* 可复制文本 */
259
+
97
260
  .taskon-title-express-copy {
98
261
  display: inline;
99
- color: var(--taskon-color-secondary, #cbff01);
262
+ color: var(--taskon-color-secondary);
100
263
  cursor: pointer;
101
264
  }
102
265
 
103
266
  /* Radix Popover 内容 */
267
+
104
268
  .taskon-title-express-popover-content {
105
269
  display: flex;
106
270
  align-items: center;
107
271
  justify-content: center;
108
272
  gap: 6px;
109
273
  padding: 8px 12px;
110
- background: var(--taskon-color-bg-popover, #2a2a2a);
111
- border-radius: 8px;
274
+ background: var(--taskon-color-bg-floating);
275
+ border-radius: var(--taskon-border-radius-sm);
112
276
  border: none;
113
277
  outline: none;
114
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
278
+ box-shadow: 0 4px 12px var(--taskon-color-bg-mask);
115
279
  cursor: pointer;
116
280
  font-size: 14px;
117
281
  font-weight: 500;
118
282
  line-height: 18px;
119
- color: var(--taskon-color-text, #fff);
283
+ color: var(--taskon-color-text);
120
284
  z-index: 9999;
121
285
  animation: taskon-popover-fade-in 0.15s ease;
122
286
  }
@@ -126,10 +290,11 @@
126
290
  }
127
291
 
128
292
  .taskon-title-express-popover-content:hover {
129
- background: var(--taskon-color-bg-popover-hover, #3a3a3a);
293
+ background: var(--taskon-color-bg-surface);
130
294
  }
131
295
 
132
296
  /* 复制图标 */
297
+
133
298
  .taskon-title-express-copy-icon {
134
299
  width: 14px;
135
300
  height: 14px;
@@ -137,11 +302,13 @@
137
302
  }
138
303
 
139
304
  /* Radix Popover 箭头 */
305
+
140
306
  .taskon-title-express-popover-arrow {
141
- fill: var(--taskon-color-bg-popover, #2a2a2a);
307
+ fill: var(--taskon-color-bg-floating);
142
308
  }
143
309
 
144
310
  /* 动画 */
311
+
145
312
  @keyframes taskon-popover-fade-in {
146
313
  from {
147
314
  opacity: 0;
@@ -152,21 +319,501 @@
152
319
  transform: translateY(0);
153
320
  }
154
321
  }
322
+ /**
323
+ * CardDescExpress 组件样式
324
+ * @module components/CardDescExpress
325
+ *
326
+ * @description
327
+ * 对齐原版 TextPreview + Quill 富文本渲染思路:
328
+ * - 容器层控制截断与基础排版
329
+ * - 内容层按 Quill 语义处理列表/缩进/对齐
330
+ */
155
331
 
156
- /* 响应式样式(移动端) */
157
- @media (max-width: 750px) {
158
- .taskon-title-express-popover-content {
159
- padding: 2.13vw 3.2vw;
160
- font-size: 3.73vw;
161
- line-height: 4.8vw;
162
- border-radius: 2.13vw;
163
- gap: 1.6vw;
164
- }
332
+ .taskon-card-desc-rich {
333
+ max-height: 60px;
334
+ overflow: hidden;
335
+ font-size: 14px;
336
+ line-height: 21px;
337
+ color: var(--taskon-color-text-tertiary);
338
+ white-space: pre-wrap;
339
+ overflow-wrap: break-word;
340
+ word-break: break-word;
341
+ }
165
342
 
166
- .taskon-title-express-copy-icon {
167
- width: 3.73vw;
168
- height: 3.73vw;
169
- }
343
+ .taskon-card-desc-rich--no-max-height {
344
+ margin-top: 0;
345
+ max-height: none;
346
+ overflow: visible;
347
+ }
348
+
349
+ /* ========== 基础防护(降低宿主 reset 影响) ========== */
350
+
351
+ .taskon-card-desc-rich,
352
+ .taskon-card-desc-rich *,
353
+ .taskon-card-desc-rich *::before,
354
+ .taskon-card-desc-rich *::after {
355
+ box-sizing: border-box;
356
+ }
357
+
358
+ /* ========== 基础块元素(对齐 Quill 编辑器语义) ========== */
359
+
360
+ .taskon-card-desc-rich p,
361
+ .taskon-card-desc-rich ol,
362
+ .taskon-card-desc-rich ul,
363
+ .taskon-card-desc-rich pre,
364
+ .taskon-card-desc-rich blockquote,
365
+ .taskon-card-desc-rich h1,
366
+ .taskon-card-desc-rich h2,
367
+ .taskon-card-desc-rich h3,
368
+ .taskon-card-desc-rich h4,
369
+ .taskon-card-desc-rich h5,
370
+ .taskon-card-desc-rich h6 {
371
+ display: block;
372
+ margin: 0;
373
+ padding: 0;
374
+ counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
375
+ }
376
+
377
+ .taskon-card-desc-rich h1 {
378
+ font-size: 2rem;
379
+ line-height: 33px;
380
+ font-weight: 700;
381
+ color: var(--taskon-color-text);
382
+ }
383
+
384
+ .taskon-card-desc-rich h2 {
385
+ font-size: 1.5em;
386
+ }
387
+
388
+ .taskon-card-desc-rich h3 {
389
+ font-size: 1.17em;
390
+ }
391
+
392
+ .taskon-card-desc-rich h4 {
393
+ font-size: 1em;
394
+ }
395
+
396
+ .taskon-card-desc-rich h5 {
397
+ font-size: 0.83em;
398
+ }
399
+
400
+ .taskon-card-desc-rich h6 {
401
+ font-size: 0.67em;
402
+ }
403
+
404
+ /* ========== 列表(核心:确保圆点/编号稳定可见) ========== */
405
+
406
+ .taskon-card-desc-rich ol,
407
+ .taskon-card-desc-rich ul {
408
+ margin: 0.5em 0;
409
+ padding-left: 1.5em;
410
+ }
411
+
412
+ .taskon-card-desc-rich ol > li,
413
+ .taskon-card-desc-rich ul > li {
414
+ list-style-type: none;
415
+ }
416
+
417
+ .taskon-card-desc-rich li {
418
+ display: list-item;
419
+ }
420
+
421
+ .taskon-card-desc-rich ul > li::before {
422
+ content: "\2022";
423
+ }
424
+
425
+ .taskon-card-desc-rich ul[data-checked="true"],
426
+ .taskon-card-desc-rich ul[data-checked="false"] {
427
+ pointer-events: none;
428
+ }
429
+
430
+ .taskon-card-desc-rich ul[data-checked="true"] > li *,
431
+ .taskon-card-desc-rich ul[data-checked="false"] > li * {
432
+ pointer-events: all;
433
+ }
434
+
435
+ .taskon-card-desc-rich ul[data-checked="true"] > li::before,
436
+ .taskon-card-desc-rich ul[data-checked="false"] > li::before {
437
+ cursor: pointer;
438
+ pointer-events: all;
439
+ }
440
+
441
+ .taskon-card-desc-rich ul[data-checked="true"] > li::before {
442
+ content: "\2611";
443
+ }
444
+
445
+ .taskon-card-desc-rich ul[data-checked="false"] > li::before {
446
+ content: "\2610";
447
+ }
448
+
449
+ .taskon-card-desc-rich li::before {
450
+ display: inline-block;
451
+ width: 1.2em;
452
+ white-space: nowrap;
453
+ }
454
+
455
+ .taskon-card-desc-rich li:not(.ql-direction-rtl)::before {
456
+ margin-right: 0.3em;
457
+ margin-left: -1.5em;
458
+ text-align: right;
459
+ }
460
+
461
+ .taskon-card-desc-rich li.ql-direction-rtl::before {
462
+ margin-right: -1.5em;
463
+ margin-left: 0.3em;
464
+ }
465
+
466
+ .taskon-card-desc-rich ol li:not(.ql-direction-rtl),
467
+ .taskon-card-desc-rich ul li:not(.ql-direction-rtl) {
468
+ padding-left: 1.5em;
469
+ }
470
+
471
+ .taskon-card-desc-rich ol li.ql-direction-rtl,
472
+ .taskon-card-desc-rich ul li.ql-direction-rtl {
473
+ padding-right: 1.5em;
474
+ }
475
+
476
+ .taskon-card-desc-rich ol li {
477
+ counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
478
+ counter-increment: list-0;
479
+ }
480
+
481
+ .taskon-card-desc-rich ol li::before {
482
+ content: counter(list-0, decimal) ". ";
483
+ }
484
+
485
+ .taskon-card-desc-rich ol li.ql-indent-1 {
486
+ counter-increment: list-1;
487
+ counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
488
+ }
489
+
490
+ .taskon-card-desc-rich ol li.ql-indent-1::before {
491
+ content: counter(list-1, lower-alpha) ". ";
492
+ }
493
+
494
+ .taskon-card-desc-rich ol li.ql-indent-2 {
495
+ counter-increment: list-2;
496
+ counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
497
+ }
498
+
499
+ .taskon-card-desc-rich ol li.ql-indent-2::before {
500
+ content: counter(list-2, lower-roman) ". ";
501
+ }
502
+
503
+ .taskon-card-desc-rich ol li.ql-indent-3 {
504
+ counter-increment: list-3;
505
+ counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
506
+ }
507
+
508
+ .taskon-card-desc-rich ol li.ql-indent-3::before {
509
+ content: counter(list-3, decimal) ". ";
510
+ }
511
+
512
+ .taskon-card-desc-rich ol li.ql-indent-4 {
513
+ counter-increment: list-4;
514
+ counter-reset: list-5 list-6 list-7 list-8 list-9;
515
+ }
516
+
517
+ .taskon-card-desc-rich ol li.ql-indent-4::before {
518
+ content: counter(list-4, lower-alpha) ". ";
519
+ }
520
+
521
+ .taskon-card-desc-rich ol li.ql-indent-5 {
522
+ counter-increment: list-5;
523
+ counter-reset: list-6 list-7 list-8 list-9;
524
+ }
525
+
526
+ .taskon-card-desc-rich ol li.ql-indent-5::before {
527
+ content: counter(list-5, lower-roman) ". ";
528
+ }
529
+
530
+ .taskon-card-desc-rich ol li.ql-indent-6 {
531
+ counter-increment: list-6;
532
+ counter-reset: list-7 list-8 list-9;
533
+ }
534
+
535
+ .taskon-card-desc-rich ol li.ql-indent-6::before {
536
+ content: counter(list-6, decimal) ". ";
537
+ }
538
+
539
+ .taskon-card-desc-rich ol li.ql-indent-7 {
540
+ counter-increment: list-7;
541
+ counter-reset: list-8 list-9;
542
+ }
543
+
544
+ .taskon-card-desc-rich ol li.ql-indent-7::before {
545
+ content: counter(list-7, lower-alpha) ". ";
546
+ }
547
+
548
+ .taskon-card-desc-rich ol li.ql-indent-8 {
549
+ counter-increment: list-8;
550
+ counter-reset: list-9;
551
+ }
552
+
553
+ .taskon-card-desc-rich ol li.ql-indent-8::before {
554
+ content: counter(list-8, lower-roman) ". ";
555
+ }
556
+
557
+ .taskon-card-desc-rich ol li.ql-indent-9 {
558
+ counter-increment: list-9;
559
+ }
560
+
561
+ .taskon-card-desc-rich ol li.ql-indent-9::before {
562
+ content: counter(list-9, decimal) ". ";
563
+ }
564
+
565
+ /* ========== 缩进与对齐(对齐 Quill class 语义) ========== */
566
+
567
+ .taskon-card-desc-rich .ql-indent-1:not(.ql-direction-rtl) {
568
+ padding-left: 3em;
569
+ }
570
+
571
+ .taskon-card-desc-rich li.ql-indent-1:not(.ql-direction-rtl) {
572
+ padding-left: 4.5em;
573
+ }
574
+
575
+ .taskon-card-desc-rich .ql-indent-1.ql-direction-rtl.ql-align-right {
576
+ padding-right: 3em;
577
+ }
578
+
579
+ .taskon-card-desc-rich li.ql-indent-1.ql-direction-rtl.ql-align-right {
580
+ padding-right: 4.5em;
581
+ }
582
+
583
+ .taskon-card-desc-rich .ql-indent-2:not(.ql-direction-rtl) {
584
+ padding-left: 6em;
585
+ }
586
+
587
+ .taskon-card-desc-rich li.ql-indent-2:not(.ql-direction-rtl) {
588
+ padding-left: 7.5em;
589
+ }
590
+
591
+ .taskon-card-desc-rich .ql-indent-2.ql-direction-rtl.ql-align-right {
592
+ padding-right: 6em;
593
+ }
594
+
595
+ .taskon-card-desc-rich li.ql-indent-2.ql-direction-rtl.ql-align-right {
596
+ padding-right: 7.5em;
597
+ }
598
+
599
+ .taskon-card-desc-rich .ql-indent-3:not(.ql-direction-rtl) {
600
+ padding-left: 9em;
601
+ }
602
+
603
+ .taskon-card-desc-rich li.ql-indent-3:not(.ql-direction-rtl) {
604
+ padding-left: 10.5em;
605
+ }
606
+
607
+ .taskon-card-desc-rich .ql-indent-3.ql-direction-rtl.ql-align-right {
608
+ padding-right: 9em;
609
+ }
610
+
611
+ .taskon-card-desc-rich li.ql-indent-3.ql-direction-rtl.ql-align-right {
612
+ padding-right: 10.5em;
613
+ }
614
+
615
+ .taskon-card-desc-rich .ql-indent-4:not(.ql-direction-rtl) {
616
+ padding-left: 12em;
617
+ }
618
+
619
+ .taskon-card-desc-rich li.ql-indent-4:not(.ql-direction-rtl) {
620
+ padding-left: 13.5em;
621
+ }
622
+
623
+ .taskon-card-desc-rich .ql-indent-4.ql-direction-rtl.ql-align-right {
624
+ padding-right: 12em;
625
+ }
626
+
627
+ .taskon-card-desc-rich li.ql-indent-4.ql-direction-rtl.ql-align-right {
628
+ padding-right: 13.5em;
629
+ }
630
+
631
+ .taskon-card-desc-rich .ql-indent-5:not(.ql-direction-rtl) {
632
+ padding-left: 15em;
633
+ }
634
+
635
+ .taskon-card-desc-rich li.ql-indent-5:not(.ql-direction-rtl) {
636
+ padding-left: 16.5em;
637
+ }
638
+
639
+ .taskon-card-desc-rich .ql-indent-5.ql-direction-rtl.ql-align-right {
640
+ padding-right: 15em;
641
+ }
642
+
643
+ .taskon-card-desc-rich li.ql-indent-5.ql-direction-rtl.ql-align-right {
644
+ padding-right: 16.5em;
645
+ }
646
+
647
+ .taskon-card-desc-rich .ql-indent-6:not(.ql-direction-rtl) {
648
+ padding-left: 18em;
649
+ }
650
+
651
+ .taskon-card-desc-rich li.ql-indent-6:not(.ql-direction-rtl) {
652
+ padding-left: 19.5em;
653
+ }
654
+
655
+ .taskon-card-desc-rich .ql-indent-6.ql-direction-rtl.ql-align-right {
656
+ padding-right: 18em;
657
+ }
658
+
659
+ .taskon-card-desc-rich li.ql-indent-6.ql-direction-rtl.ql-align-right {
660
+ padding-right: 19.5em;
661
+ }
662
+
663
+ .taskon-card-desc-rich .ql-indent-7:not(.ql-direction-rtl) {
664
+ padding-left: 21em;
665
+ }
666
+
667
+ .taskon-card-desc-rich li.ql-indent-7:not(.ql-direction-rtl) {
668
+ padding-left: 22.5em;
669
+ }
670
+
671
+ .taskon-card-desc-rich .ql-indent-7.ql-direction-rtl.ql-align-right {
672
+ padding-right: 21em;
673
+ }
674
+
675
+ .taskon-card-desc-rich li.ql-indent-7.ql-direction-rtl.ql-align-right {
676
+ padding-right: 22.5em;
677
+ }
678
+
679
+ .taskon-card-desc-rich .ql-indent-8:not(.ql-direction-rtl) {
680
+ padding-left: 24em;
681
+ }
682
+
683
+ .taskon-card-desc-rich li.ql-indent-8:not(.ql-direction-rtl) {
684
+ padding-left: 25.5em;
685
+ }
686
+
687
+ .taskon-card-desc-rich .ql-indent-8.ql-direction-rtl.ql-align-right {
688
+ padding-right: 24em;
689
+ }
690
+
691
+ .taskon-card-desc-rich li.ql-indent-8.ql-direction-rtl.ql-align-right {
692
+ padding-right: 25.5em;
693
+ }
694
+
695
+ .taskon-card-desc-rich .ql-indent-9:not(.ql-direction-rtl) {
696
+ padding-left: 27em;
697
+ }
698
+
699
+ .taskon-card-desc-rich li.ql-indent-9:not(.ql-direction-rtl) {
700
+ padding-left: 28.5em;
701
+ }
702
+
703
+ .taskon-card-desc-rich .ql-indent-9.ql-direction-rtl.ql-align-right {
704
+ padding-right: 27em;
705
+ }
706
+
707
+ .taskon-card-desc-rich li.ql-indent-9.ql-direction-rtl.ql-align-right {
708
+ padding-right: 28.5em;
709
+ }
710
+
711
+ .taskon-card-desc-rich .ql-direction-rtl {
712
+ direction: rtl;
713
+ text-align: inherit;
714
+ }
715
+
716
+ .taskon-card-desc-rich .ql-align-center {
717
+ text-align: center;
718
+ }
719
+
720
+ .taskon-card-desc-rich .ql-align-right {
721
+ text-align: right;
722
+ }
723
+
724
+ .taskon-card-desc-rich .ql-align-justify {
725
+ text-align: justify;
726
+ }
727
+
728
+ /* ========== 常见富文本元素 ========== */
729
+
730
+ .taskon-card-desc-rich a {
731
+ color: var(--taskon-color-link);
732
+ text-decoration: underline;
733
+ }
734
+
735
+ .taskon-card-desc-rich a:hover {
736
+ opacity: 0.8;
737
+ }
738
+
739
+ .taskon-card-desc-rich strong,
740
+ .taskon-card-desc-rich b {
741
+ font-weight: 600;
742
+ color: var(--taskon-color-text);
743
+ }
744
+
745
+ .taskon-card-desc-rich em,
746
+ .taskon-card-desc-rich i {
747
+ font-style: italic;
748
+ }
749
+
750
+ .taskon-card-desc-rich u,
751
+ .taskon-card-desc-rich ins {
752
+ text-decoration: underline;
753
+ }
754
+
755
+ .taskon-card-desc-rich code {
756
+ padding: 0.2em 0.4em;
757
+ font-size: 0.9em;
758
+ background: var(--taskon-color-bg-surface-strong);
759
+ border-radius: 3px;
760
+ }
761
+
762
+ .taskon-card-desc-rich pre {
763
+ margin: 0.5em 0;
764
+ padding: 0.75em 1em;
765
+ overflow-x: auto;
766
+ text-wrap: initial;
767
+ background: var(--taskon-color-bg-surface-subtle);
768
+ border-radius: 6px;
769
+ }
770
+
771
+ .taskon-card-desc-rich blockquote {
772
+ margin: 0.5em 0;
773
+ padding-left: 1em;
774
+ color: var(--taskon-color-text-tertiary);
775
+ border-left: 3px solid var(--taskon-color-link);
776
+ }
777
+
778
+ .taskon-card-desc-rich img {
779
+ max-width: 100%;
780
+ height: auto;
781
+ border-radius: 6px;
782
+ }
783
+
784
+ .taskon-card-desc-rich iframe {
785
+ display: block;
786
+ width: 100%;
787
+ max-width: 100%;
788
+ }
789
+ /**
790
+ * TaskVerifyFailedDialog styles
791
+ * @description Match Vue ErrorInfo content rhythm and readability.
792
+ */
793
+
794
+ /*
795
+ * Responsive base styles
796
+ *
797
+ * Keep mobile breakpoints and fallback patterns centralized here.
798
+ * Components should reuse these mixins instead of duplicating query logic.
799
+ */
800
+
801
+ /*
802
+ * Desktop-up mixin:
803
+ * 1) Enable desktop enhancement in wider containers
804
+ * 2) Keep viewport media query as fallback
805
+ */
806
+
807
+ .taskon-task-verify-failed-dialog .taskon-dialog-body {
808
+ padding: 0;
809
+ }
810
+
811
+ .taskon-task-verify-failed-dialog-message {
812
+ margin-top: var(--taskon-spacing-sm);
813
+ font-size: 16px;
814
+ line-height: 20px;
815
+ color: var(--taskon-color-text-tertiary);
816
+ white-space: pre-wrap;
170
817
  }
171
818
  /**
172
819
  * PowTask Styles
@@ -174,62 +821,62 @@
174
821
  * 遵循 Widget 命名规范:.taskon-{widget-name}-{element}
175
822
  */
176
823
 
824
+ /*
825
+ * Responsive base styles
826
+ *
827
+ * Keep mobile breakpoints and fallback patterns centralized here.
828
+ * Components should reuse these mixins instead of duplicating query logic.
829
+ */
830
+
831
+ /*
832
+ * Desktop-up mixin:
833
+ * 1) Enable desktop enhancement in wider containers
834
+ * 2) Keep viewport media query as fallback
835
+ */
836
+
177
837
  /* ============================================
178
838
  * POW Task Container
179
839
  * ============================================ */
840
+
180
841
  .taskon-pow-task {
181
842
  /* 继承 TaskCardBase 的样式 */
182
843
  }
183
844
 
184
- /* ============================================
185
- * POW Description
186
- * ============================================ */
187
- .taskon-pow-desc {
188
- font-size: 14px;
189
- line-height: 21px;
190
- color: rgba(255, 255, 255, 0.8);
191
- word-break: break-word;
192
- }
193
-
194
- .taskon-pow-desc a {
195
- color: var(--taskon-primary-color, #3b82f6);
196
- text-decoration: none;
197
- }
198
-
199
- .taskon-pow-desc a:hover {
200
- text-decoration: underline;
201
- }
202
-
203
845
  /* ============================================
204
846
  * POW Input Area
205
847
  * ============================================ */
848
+
206
849
  .taskon-pow-input-area {
207
- margin-top: 15px;
850
+ margin-top: var(--taskon-spacing-md);
208
851
  }
209
852
 
210
853
  /* ============================================
211
854
  * URL Input Row
212
855
  * ============================================ */
856
+
213
857
  .taskon-pow-url-row {
214
858
  display: flex;
215
- align-items: center;
216
- gap: 15px;
859
+ flex-direction: column;
860
+ align-items: stretch;
861
+ gap: var(--taskon-spacing-sm);
217
862
  }
218
863
 
219
864
  .taskon-pow-input {
220
865
  flex: 1;
221
- padding: 10px 12px;
222
- border: 1px solid rgba(255, 255, 255, 0.2);
223
- border-radius: 6px;
224
- background: rgba(255, 255, 255, 0.05);
225
- color: #fff;
866
+ width: 100%;
867
+ padding: var(--taskon-spacing-sm)
868
+ var(--taskon-spacing-md);
869
+ border: 1px solid var(--taskon-color-border);
870
+ border-radius: var(--taskon-border-radius);
871
+ background: var(--taskon-color-bg-surface-subtle);
872
+ color: var(--taskon-color-text);
226
873
  font-size: 14px;
227
874
  outline: none;
228
875
  transition: border-color 0.2s ease;
229
876
  }
230
877
 
231
878
  .taskon-pow-input:focus {
232
- border-color: var(--taskon-primary-color, #3b82f6);
879
+ border-color: var(--taskon-color-primary);
233
880
  }
234
881
 
235
882
  .taskon-pow-input:disabled {
@@ -238,16 +885,18 @@
238
885
  }
239
886
 
240
887
  .taskon-pow-input::placeholder {
241
- color: rgba(255, 255, 255, 0.4);
888
+ color: var(--taskon-color-text-disabled);
242
889
  }
243
890
 
244
891
  /* ============================================
245
892
  * Text Input Row
246
893
  * ============================================ */
894
+
247
895
  .taskon-pow-text-row {
248
896
  display: flex;
249
- align-items: flex-end;
250
- gap: 15px;
897
+ flex-direction: column;
898
+ align-items: stretch;
899
+ gap: var(--taskon-spacing-sm);
251
900
  }
252
901
 
253
902
  .taskon-pow-text-row .taskon-textarea-wrap {
@@ -257,12 +906,18 @@
257
906
  /* ============================================
258
907
  * Image Upload Area - 与 Vue 版本 PowImageUploader 一致
259
908
  * ============================================ */
909
+
260
910
  .taskon-pow-image-uploader {
261
- margin-top: 20px;
911
+ margin-top: var(--taskon-spacing-md);
262
912
  display: flex;
263
913
  align-items: center;
264
914
  }
265
915
 
916
+ .taskon-pow-url-row .taskon-verify-btn,
917
+ .taskon-pow-text-row .taskon-verify-btn {
918
+ width: 100%;
919
+ }
920
+
266
921
  .taskon-pow-image-upload-area {
267
922
  flex: 1;
268
923
  position: relative;
@@ -274,20 +929,20 @@
274
929
  text-align: center;
275
930
  font-size: 0;
276
931
  overflow: hidden;
277
- border: 1px solid rgba(255, 255, 255, 0.2);
278
- border-radius: 8px;
279
- background: rgba(255, 255, 255, 0.05);
932
+ border: 1px solid var(--taskon-color-border);
933
+ border-radius: var(--taskon-border-radius);
934
+ background: var(--taskon-color-bg-surface-subtle);
280
935
  cursor: pointer;
281
936
  transition: border-color 0.2s ease;
282
937
  }
283
938
 
284
939
  .taskon-pow-image-upload-area:hover:not(.taskon-pow-image-upload-area--disabled) {
285
- border-color: var(--taskon-primary-color, #3b82f6);
940
+ border-color: var(--taskon-color-primary);
286
941
  }
287
942
 
288
943
  .taskon-pow-image-upload-area:focus {
289
944
  outline: none;
290
- border-color: var(--taskon-primary-color, #3b82f6);
945
+ border-color: var(--taskon-color-primary);
291
946
  }
292
947
 
293
948
  .taskon-pow-image-upload-area--disabled {
@@ -298,7 +953,7 @@
298
953
  .taskon-pow-image-upload-icon {
299
954
  width: 18px;
300
955
  height: 18px;
301
- color: rgba(255, 255, 255, 0.6);
956
+ color: var(--taskon-color-text-tertiary);
302
957
  }
303
958
 
304
959
  .taskon-pow-image-upload-tip {
@@ -308,17 +963,18 @@
308
963
  letter-spacing: 0.04em;
309
964
  text-transform: uppercase;
310
965
  white-space: pre-wrap;
311
- color: rgba(255, 255, 255, 0.6);
966
+ color: var(--taskon-color-text-tertiary);
312
967
  }
313
968
 
314
969
  .taskon-pow-image-preview {
315
- border-radius: 4px;
316
- margin: 20px 0;
970
+ border-radius: var(--taskon-border-radius-sm);
971
+ margin: var(--taskon-spacing-lg) 0;
317
972
  max-width: 100%;
318
973
  max-height: 300px;
319
974
  }
320
975
 
321
976
  /* Hover mask overlay */
977
+
322
978
  .taskon-pow-image-mask {
323
979
  display: none;
324
980
  position: absolute;
@@ -327,7 +983,7 @@
327
983
  align-items: center;
328
984
  justify-content: center;
329
985
  flex-direction: column;
330
- background: rgba(0, 0, 0, 0.8);
986
+ background: var(--taskon-color-bg-mask);
331
987
  }
332
988
 
333
989
  .taskon-pow-image-upload-area:hover .taskon-pow-image-mask,
@@ -336,118 +992,110 @@
336
992
  }
337
993
 
338
994
  .taskon-pow-image-mask .taskon-pow-image-upload-icon {
339
- color: #fff;
995
+ color: var(--taskon-color-secondary);
340
996
  }
341
997
 
342
998
  .taskon-pow-image-mask .taskon-pow-image-upload-tip {
343
- color: #fff;
999
+ color: var(--taskon-color-secondary);
344
1000
  opacity: 1;
345
1001
  }
346
1002
 
347
1003
  /* Progress bar at bottom */
1004
+
348
1005
  .taskon-pow-image-progress-bar {
349
1006
  z-index: 3;
350
1007
  position: absolute;
351
1008
  right: 0;
352
1009
  bottom: 0;
353
1010
  left: 0;
354
- background: rgba(255, 255, 255, 0.1);
1011
+ background: var(--taskon-color-bg-surface-strong);
355
1012
  height: 6px;
356
1013
  }
357
1014
 
358
1015
  .taskon-pow-image-progress-fill {
359
- background: var(--taskon-primary-color, #3b82f6);
1016
+ background: var(--taskon-color-primary);
360
1017
  height: 100%;
361
- border-radius: 4px;
1018
+ border-radius: var(--taskon-border-radius-sm);
362
1019
  transition: width 0.2s ease;
363
1020
  }
364
1021
 
365
1022
  /* ============================================
366
1023
  * Error Message
367
1024
  * ============================================ */
1025
+
368
1026
  .taskon-pow-error {
369
1027
  margin-top: 10px;
370
1028
  font-size: 14px;
371
- color: #ef4444;
1029
+ color: var(--taskon-color-error);
372
1030
  }
373
1031
 
374
1032
  /* ============================================
375
1033
  * Average Review Time
376
1034
  * ============================================ */
1035
+
377
1036
  /* 与 Vue 版本 AverageReview.vue 样式一致 */
1037
+
378
1038
  .taskon-pow-review-time {
379
1039
  margin-top: 10px;
380
- color: rgba(255, 212, 101, 0.6);
1040
+ color: var(--taskon-color-warning);
381
1041
  font-size: 13px;
382
1042
  font-weight: 500;
383
1043
  line-height: 16px;
384
1044
  }
385
1045
 
386
1046
  /* ============================================
387
- * Responsive Styles
1047
+ * Desktop 增强
388
1048
  * ============================================ */
389
- @media (max-width: 750px) {
390
- .taskon-pow-url-row,
391
- .taskon-pow-text-row {
392
- flex-direction: column;
393
- gap: 10px;
1049
+
1050
+ @supports (container-type: inline-size) {
1051
+ @container (min-width: 751px) {
1052
+ .taskon-pow-url-row {
1053
+ flex-direction: row;
1054
+ align-items: center;
1055
+ gap: var(--taskon-spacing-md);
394
1056
  }
395
1057
 
396
- .taskon-pow-input {
397
- width: 100%;
1058
+ .taskon-pow-text-row {
1059
+ flex-direction: row;
1060
+ align-items: flex-end;
1061
+ gap: var(--taskon-spacing-md);
398
1062
  }
399
1063
 
400
1064
  .taskon-pow-url-row .taskon-verify-btn,
401
1065
  .taskon-pow-text-row .taskon-verify-btn {
402
- width: 100%;
1066
+ width: auto;
403
1067
  }
404
1068
 
405
1069
  .taskon-pow-image-uploader {
406
- margin-top: 2.67vw;
1070
+ margin-top: var(--taskon-spacing-lg);
407
1071
  }
408
-
409
- .taskon-pow-image-upload-area {
410
- min-height: 17.07vw;
1072
+ }
411
1073
  }
412
1074
 
413
- .taskon-pow-image-upload-icon {
414
- width: 2.4vw;
415
- height: 2.4vw;
1075
+ @supports not (container-type: inline-size) {
1076
+ @media (min-width: 751px) {
1077
+ .taskon-pow-url-row {
1078
+ flex-direction: row;
1079
+ align-items: center;
1080
+ gap: var(--taskon-spacing-md);
416
1081
  }
417
1082
 
418
- .taskon-pow-image-upload-tip {
419
- margin-top: 1.33vw;
420
- font-size: 1.6vw;
421
- line-height: 2.67vw;
1083
+ .taskon-pow-text-row {
1084
+ flex-direction: row;
1085
+ align-items: flex-end;
1086
+ gap: var(--taskon-spacing-md);
422
1087
  }
423
1088
 
424
- .taskon-pow-image-preview {
425
- max-height: 32vw;
1089
+ .taskon-pow-url-row .taskon-verify-btn,
1090
+ .taskon-pow-text-row .taskon-verify-btn {
1091
+ width: auto;
426
1092
  }
427
- }
428
- /**
429
- * ContractInteractiveTask Styles
430
- */
431
-
432
- .taskon-contract-task {
433
- /* 继承 TaskCardBase 样式 */
434
- }
435
-
436
- .taskon-contract-desc {
437
- font-size: 14px;
438
- line-height: 21px;
439
- color: rgba(255, 255, 255, 0.8);
440
- word-break: break-word;
441
- }
442
-
443
- .taskon-contract-desc a {
444
- color: var(--taskon-primary-color, #3b82f6);
445
- text-decoration: none;
446
- }
447
1093
 
448
- .taskon-contract-desc a:hover {
449
- text-decoration: underline;
450
- }
1094
+ .taskon-pow-image-uploader {
1095
+ margin-top: var(--taskon-spacing-lg);
1096
+ }
1097
+ }
1098
+ }
451
1099
  /* ============================================
452
1100
  DynamicPoints Component Styles
453
1101
  与 Vue 版本 BaseDynamicPoint.vue 样式一致
@@ -456,33 +1104,33 @@
456
1104
  .taskon-dynamic-points {
457
1105
  display: inline-flex;
458
1106
  align-items: center;
459
- gap: 8px;
460
- padding: 8px 12px;
461
- background: rgba(255, 255, 255, 0.04);
462
- border-radius: 8px;
1107
+ gap: var(--taskon-spacing-sm);
1108
+ padding: var(--taskon-spacing-sm) var(--taskon-spacing-md);
1109
+ background: var(--taskon-color-bg-surface-subtle);
1110
+ border-radius: var(--taskon-border-radius);
463
1111
  }
464
1112
 
465
1113
  .taskon-dynamic-points-value-wrap {
466
1114
  display: flex;
467
1115
  align-items: center;
468
- gap: 8px;
1116
+ gap: var(--taskon-spacing-sm);
469
1117
  flex-shrink: 0;
470
1118
  }
471
1119
 
472
1120
  .taskon-dynamic-points-value {
473
1121
  font-size: 16px;
474
1122
  font-weight: 600;
475
- color: var(--taskon-task-text-primary, #fff);
1123
+ color: var(--taskon-color-text);
476
1124
  }
477
1125
 
478
1126
  .taskon-dynamic-points-value--highlight {
479
- color: #00ffa3 !important;
1127
+ color: var(--taskon-color-secondary);
480
1128
  }
481
1129
 
482
1130
  .taskon-dynamic-points-max {
483
1131
  font-size: 14px;
484
1132
  font-weight: 500;
485
- color: var(--taskon-task-text-secondary, rgba(255, 255, 255, 0.6));
1133
+ color: var(--taskon-color-text-tertiary);
486
1134
  text-transform: capitalize;
487
1135
  }
488
1136
 
@@ -490,12 +1138,12 @@
490
1138
  display: inline-flex;
491
1139
  align-items: center;
492
1140
  justify-content: center;
493
- color: var(--taskon-task-text-secondary, rgba(255, 255, 255, 0.6));
1141
+ color: var(--taskon-color-text-tertiary);
494
1142
  cursor: pointer;
495
1143
  }
496
1144
 
497
1145
  .taskon-dynamic-points-info:hover {
498
- color: var(--taskon-task-text-primary, #fff);
1146
+ color: var(--taskon-color-text);
499
1147
  }
500
1148
 
501
1149
  .taskon-dynamic-points-refresh {
@@ -505,11 +1153,11 @@
505
1153
  width: 24px;
506
1154
  height: 24px;
507
1155
  padding: 0;
508
- margin-left: 4px;
1156
+ margin-left: var(--taskon-spacing-xs);
509
1157
  background: transparent;
510
1158
  border: none;
511
- border-radius: 4px;
512
- color: #54aeff;
1159
+ border-radius: var(--taskon-border-radius-sm);
1160
+ color: var(--taskon-color-link);
513
1161
  cursor: pointer;
514
1162
  transition: opacity 0.2s, transform 0.2s;
515
1163
  }
@@ -524,7 +1172,7 @@
524
1172
  }
525
1173
 
526
1174
  .taskon-dynamic-points-refresh--animating {
527
- filter: drop-shadow(0 0 4px rgba(84, 174, 255, 0.8));
1175
+ filter: drop-shadow(0 0 4px var(--taskon-color-link));
528
1176
  }
529
1177
 
530
1178
  .taskon-dynamic-points-refresh-icon {
@@ -548,8 +1196,7 @@
548
1196
  .taskon-dynamic-points-cooldown {
549
1197
  font-size: 14px;
550
1198
  font-weight: 500;
551
- color: #54aeff !important;
552
- font-family: Menlo, Consolas, "Liberation Mono", "Courier New", Courier, monospace;
1199
+ color: var(--taskon-color-link);
553
1200
  }
554
1201
  /**
555
1202
  * SwapDexTask Styles
@@ -561,81 +1208,72 @@
561
1208
  }
562
1209
 
563
1210
  /* Content wrapper */
1211
+
564
1212
  .taskon-swap-content {
565
1213
  display: flex;
566
1214
  flex-direction: column;
567
- gap: 16px;
1215
+ gap: var(--taskon-spacing-md);
568
1216
  }
569
1217
 
570
1218
  /* Rules section - 动态积分规则区域 */
1219
+
571
1220
  .taskon-swap-rules-section {
572
1221
  display: flex;
573
1222
  flex-direction: column;
574
- gap: 8px;
1223
+ gap: var(--taskon-spacing-sm);
575
1224
  }
576
1225
 
577
1226
  .taskon-swap-rules-title {
578
1227
  font-size: 14px;
579
1228
  font-weight: 500;
580
- color: rgba(255, 255, 255, 0.6);
581
- margin-bottom: 8px;
1229
+ color: var(--taskon-color-text-tertiary);
1230
+ margin-bottom: var(--taskon-spacing-sm);
582
1231
  }
583
1232
 
584
1233
  .taskon-swap-rules-content {
585
1234
  display: flex;
586
1235
  flex-wrap: wrap;
587
1236
  align-items: center;
588
- gap: 4px;
589
- padding: 12px;
590
- border-radius: 8px;
591
- background: rgba(255, 255, 255, 0.05);
1237
+ gap: var(--taskon-spacing-xs);
1238
+ padding: var(--taskon-spacing-md);
1239
+ border-radius: var(--taskon-border-radius);
1240
+ background: var(--taskon-color-bg-surface-subtle);
592
1241
  font-size: 14px;
593
1242
  font-weight: 500;
594
- color: rgba(255, 255, 255, 0.6);
1243
+ color: var(--taskon-color-text-tertiary);
595
1244
  }
596
1245
 
597
1246
  .taskon-swap-rules-highlight {
598
- color: var(--taskon-secondary-color, #00ffa3);
1247
+ color: var(--taskon-color-secondary);
599
1248
  }
600
1249
 
601
1250
  .taskon-swap-rules-point-name {
602
- color: rgba(255, 255, 255, 0.4);
1251
+ color: var(--taskon-color-text-secondary);
1252
+ }
1253
+
1254
+ .taskon-swap-rules-max {
1255
+ color: var(--taskon-color-text-tertiary);
603
1256
  }
604
1257
 
605
1258
  /* Instructions section - 任务描述区域 */
1259
+
606
1260
  .taskon-swap-instructions-section {
607
1261
  display: flex;
608
1262
  flex-direction: column;
609
- gap: 8px;
1263
+ gap: var(--taskon-spacing-sm);
610
1264
  }
611
1265
 
612
1266
  .taskon-swap-instructions-title {
613
1267
  font-size: 14px;
614
1268
  font-weight: 500;
615
- color: rgba(255, 255, 255, 0.6);
616
- margin-bottom: 8px;
1269
+ color: var(--taskon-color-text-tertiary);
1270
+ margin-bottom: var(--taskon-spacing-sm);
617
1271
  }
618
1272
 
619
1273
  .taskon-swap-instructions-content {
620
- padding: 12px;
621
- border-radius: 8px;
622
- background: rgba(255, 255, 255, 0.05);
623
- }
624
-
625
- .taskon-swap-desc {
626
- font-size: 14px;
627
- line-height: 21px;
628
- color: rgba(255, 255, 255, 0.8);
629
- word-break: break-word;
630
- }
631
-
632
- .taskon-swap-desc a {
633
- color: var(--taskon-primary-color, #3b82f6);
634
- text-decoration: none;
635
- }
636
-
637
- .taskon-swap-desc a:hover {
638
- text-decoration: underline;
1274
+ padding: var(--taskon-spacing-md);
1275
+ border-radius: var(--taskon-border-radius);
1276
+ background: var(--taskon-color-bg-surface-subtle);
639
1277
  }
640
1278
  /**
641
1279
  * OuterPointAPITask Styles
@@ -646,47 +1284,33 @@
646
1284
  /* 继承 TaskCardBase 样式 */
647
1285
  }
648
1286
 
649
- /* ==================== Description Area ==================== */
650
- .taskon-outer-point-api-desc {
651
- font-size: 14px;
652
- line-height: 21px;
653
- color: rgba(255, 255, 255, 0.8);
654
- word-break: break-word;
655
- }
656
-
657
- .taskon-outer-point-api-desc a {
658
- color: var(--taskon-primary-color, #3b82f6);
659
- text-decoration: none;
660
- }
661
-
662
- .taskon-outer-point-api-desc a:hover {
663
- text-decoration: underline;
664
- }
665
-
666
1287
  /* ==================== Customized Param Dialog ==================== */
1288
+
667
1289
  .taskon-outer-point-api-dialog {
668
1290
  display: flex;
669
1291
  flex-direction: column;
670
- gap: 16px;
1292
+ gap: var(--taskon-spacing-md);
671
1293
  }
672
1294
 
673
1295
  /* Dialog title */
1296
+
674
1297
  .taskon-outer-point-api-dialog-title {
675
1298
  font-size: 18px;
676
1299
  font-weight: 600;
677
- color: #fff;
1300
+ color: var(--taskon-color-text);
678
1301
  margin: 0;
679
1302
  }
680
1303
 
681
1304
  /* Warning message */
1305
+
682
1306
  .taskon-outer-point-api-dialog-warning {
683
1307
  display: flex;
684
1308
  align-items: center;
685
- gap: 8px;
686
- padding: 12px;
687
- border-radius: 8px;
688
- background: rgba(255, 171, 0, 0.1);
689
- color: #ffab00;
1309
+ gap: var(--taskon-spacing-sm);
1310
+ padding: var(--taskon-spacing-md);
1311
+ border-radius: var(--taskon-border-radius);
1312
+ background: var(--taskon-color-warning-bg);
1313
+ color: var(--taskon-color-warning);
690
1314
  font-size: 14px;
691
1315
  line-height: 20px;
692
1316
  }
@@ -698,32 +1322,35 @@
698
1322
  }
699
1323
 
700
1324
  /* Description text */
1325
+
701
1326
  .taskon-outer-point-api-dialog-desc {
702
1327
  font-size: 14px;
703
1328
  line-height: 20px;
704
- color: rgba(255, 255, 255, 0.6);
1329
+ color: var(--taskon-color-text-tertiary);
705
1330
  }
706
1331
 
707
1332
  /* Input area */
1333
+
708
1334
  .taskon-outer-point-api-dialog-input-wrap {
709
1335
  display: flex;
710
1336
  flex-direction: column;
711
- gap: 8px;
1337
+ gap: var(--taskon-spacing-sm);
712
1338
  }
713
1339
 
714
1340
  .taskon-outer-point-api-dialog-label {
715
1341
  font-size: 14px;
716
1342
  font-weight: 500;
717
- color: rgba(255, 255, 255, 0.8);
1343
+ color: var(--taskon-color-text-secondary);
718
1344
  }
719
1345
 
720
1346
  .taskon-outer-point-api-dialog-input {
721
1347
  width: 100%;
722
- padding: 10px 12px;
723
- border-radius: 8px;
724
- border: 1px solid rgba(255, 255, 255, 0.15);
725
- background: rgba(255, 255, 255, 0.05);
726
- color: #fff;
1348
+ padding: var(--taskon-spacing-sm)
1349
+ var(--taskon-spacing-md);
1350
+ border-radius: var(--taskon-border-radius);
1351
+ border: 1px solid var(--taskon-color-border);
1352
+ background: var(--taskon-color-bg-surface-subtle);
1353
+ color: var(--taskon-color-text);
727
1354
  font-size: 14px;
728
1355
  line-height: 20px;
729
1356
  outline: none;
@@ -732,33 +1359,34 @@
732
1359
  }
733
1360
 
734
1361
  .taskon-outer-point-api-dialog-input::placeholder {
735
- color: rgba(255, 255, 255, 0.3);
1362
+ color: var(--taskon-color-text-disabled);
736
1363
  }
737
1364
 
738
1365
  .taskon-outer-point-api-dialog-input:focus {
739
- border-color: var(--taskon-primary-color, #3b82f6);
1366
+ border-color: var(--taskon-color-primary);
740
1367
  }
741
1368
 
742
1369
  .taskon-outer-point-api-dialog-input--error {
743
- border-color: #ff4d4f;
1370
+ border-color: var(--taskon-color-error);
744
1371
  }
745
1372
 
746
1373
  .taskon-outer-point-api-dialog-error {
747
1374
  font-size: 12px;
748
- color: #ff4d4f;
1375
+ color: var(--taskon-color-error);
749
1376
  }
750
1377
 
751
1378
  /* Action buttons */
1379
+
752
1380
  .taskon-outer-point-api-dialog-actions {
753
1381
  display: flex;
754
1382
  justify-content: flex-end;
755
- gap: 12px;
756
- margin-top: 8px;
1383
+ gap: var(--taskon-spacing-md);
1384
+ margin-top: var(--taskon-spacing-sm);
757
1385
  }
758
1386
 
759
1387
  .taskon-outer-point-api-dialog-btn {
760
- padding: 8px 24px;
761
- border-radius: 8px;
1388
+ padding: var(--taskon-spacing-sm) var(--taskon-spacing-lg);
1389
+ border-radius: var(--taskon-border-radius);
762
1390
  font-size: 14px;
763
1391
  font-weight: 500;
764
1392
  cursor: pointer;
@@ -767,17 +1395,17 @@
767
1395
  }
768
1396
 
769
1397
  .taskon-outer-point-api-dialog-btn--cancel {
770
- background: rgba(255, 255, 255, 0.1);
771
- color: rgba(255, 255, 255, 0.8);
1398
+ background: var(--taskon-color-bg-surface-strong);
1399
+ color: var(--taskon-color-text-secondary);
772
1400
  }
773
1401
 
774
1402
  .taskon-outer-point-api-dialog-btn--cancel:hover {
775
- background: rgba(255, 255, 255, 0.15);
1403
+ background: var(--taskon-color-bg-inset);
776
1404
  }
777
1405
 
778
1406
  .taskon-outer-point-api-dialog-btn--confirm {
779
- background: var(--taskon-primary-color, #3b82f6);
780
- color: #fff;
1407
+ background: var(--taskon-color-primary);
1408
+ color: var(--taskon-color-text-on-primary);
781
1409
  }
782
1410
 
783
1411
  .taskon-outer-point-api-dialog-btn--confirm:hover {
@@ -795,171 +1423,170 @@
795
1423
  * 命名规范:.taskon-task-{component}-{element}--{modifier}
796
1424
  */
797
1425
 
798
- /* ============================================
799
- CSS Variables (可被项目方覆盖)
800
- ============================================ */
801
- :root {
802
- /* Task card colors (dark theme, same as taskon-website) */
803
- --taskon-task-bg: #1d2123;
804
- --taskon-task-border: #1d2123;
805
- --taskon-task-border-hover: #41494b;
806
- --taskon-task-radius: 10px;
807
-
808
- /* Text colors */
809
- --taskon-task-text: #ffffff;
810
- --taskon-task-text-secondary: #9ca3af;
811
- --taskon-task-text-muted: #6b7280;
812
-
813
- /* Status colors */
814
- --taskon-color-primary: #3b82f6;
815
- --taskon-color-success: #22c55e;
816
- --taskon-color-warning: #f59e0b;
817
- --taskon-color-error: #ef4444;
818
-
819
- /* Recurrence badge color */
820
- --taskon-recurrence-color: #9aff73;
821
-
822
- /* Spacing */
823
- --taskon-task-spacing-xs: 4px;
824
- --taskon-task-spacing-sm: 8px;
825
- --taskon-task-spacing-md: 12px;
826
- --taskon-task-spacing-lg: 16px;
827
- --taskon-task-spacing-xl: 24px;
828
-
829
- /* Transitions */
830
- --taskon-task-transition: 0.2s ease;
831
- }
1426
+ /*
1427
+ * Responsive base styles
1428
+ *
1429
+ * Keep mobile breakpoints and fallback patterns centralized here.
1430
+ * Components should reuse these mixins instead of duplicating query logic.
1431
+ */
1432
+
1433
+ /*
1434
+ * Desktop-up mixin:
1435
+ * 1) Enable desktop enhancement in wider containers
1436
+ * 2) Keep viewport media query as fallback
1437
+ */
832
1438
 
833
1439
  /* ============================================
834
1440
  TaskList Styles
835
1441
  与 Vue 版本 TaskList.vue + TaskType.vue 一致
836
1442
  ============================================ */
1443
+
837
1444
  .taskon-task-list {
838
1445
  display: flex;
839
1446
  flex-direction: column;
840
- gap: var(--taskon-task-spacing-lg);
1447
+ gap: var(--taskon-spacing-md);
841
1448
  }
842
1449
 
843
1450
  /* Progress section */
1451
+
844
1452
  .taskon-task-list-progress-wrap {
845
- margin-bottom: var(--taskon-task-spacing-sm);
1453
+ margin-bottom: var(--taskon-spacing-sm);
846
1454
  }
847
1455
 
848
1456
  /* Section styles */
1457
+
849
1458
  .taskon-task-list-section {
850
1459
  display: flex;
851
1460
  flex-direction: column;
852
1461
  }
853
1462
 
854
1463
  .taskon-task-list-section-header {
855
- display: flex;
856
- justify-content: space-between;
857
- align-items: center;
858
- margin-top: 30px;
859
- margin-bottom: 22px;
1464
+ display: block;
1465
+ margin-top: var(--taskon-spacing-lg);
1466
+ margin-bottom: var(--taskon-spacing-md);
860
1467
  }
861
1468
 
862
1469
  .taskon-task-list-section-label {
863
1470
  display: flex;
864
1471
  align-items: center;
865
- gap: 6px;
1472
+ flex-wrap: wrap;
1473
+ gap: var(--taskon-spacing-sm);
866
1474
  }
867
1475
 
868
1476
  .taskon-task-list-section-title {
869
1477
  font-size: 22px;
870
1478
  font-weight: 600;
871
1479
  line-height: 21px;
872
- color: var(--taskon-task-text);
1480
+ color: var(--taskon-color-text);
873
1481
  }
874
1482
 
875
1483
  .taskon-task-list-section-hint {
876
1484
  font-size: 14px;
877
- color: rgba(255, 255, 255, 0.6);
1485
+ color: var(--taskon-color-text-tertiary);
878
1486
  }
879
1487
 
880
1488
  .taskon-task-list-section-hint-em {
881
1489
  font-weight: 600;
882
- color: rgba(0, 255, 163, 1);
1490
+ color: var(--taskon-color-secondary);
883
1491
  }
884
1492
 
885
1493
  .taskon-task-list-items {
886
1494
  display: flex;
887
1495
  flex-direction: column;
888
- gap: 20px;
1496
+ gap: var(--taskon-spacing-md);
889
1497
  }
890
1498
 
891
1499
  /* First section header doesn't need top margin */
1500
+
892
1501
  .taskon-task-list-section:first-child .taskon-task-list-section-header {
893
1502
  margin-top: 0;
894
1503
  }
895
1504
 
896
1505
  /* Empty state */
1506
+
897
1507
  .taskon-task-list-empty {
898
- padding: var(--taskon-task-spacing-xl);
1508
+ padding: var(--taskon-spacing-lg);
899
1509
  text-align: center;
900
- color: var(--taskon-task-text-muted);
1510
+ color: var(--taskon-color-text-disabled);
901
1511
  }
902
1512
 
903
- /* Mobile responsive */
904
- @media (max-width: 750px) {
1513
+ .taskon-completed-count {
1514
+ margin-top: var(--taskon-spacing-sm);
1515
+ justify-content: flex-start;
1516
+ }
1517
+
1518
+ @supports (container-type: inline-size) {
1519
+ @container (min-width: 751px) {
905
1520
  .taskon-task-list-section-header {
906
- display: block;
907
- margin-top: 5.6vw;
908
- margin-bottom: 4vw;
1521
+ display: flex;
1522
+ justify-content: space-between;
1523
+ align-items: center;
1524
+ margin-top: 30px;
1525
+ margin-bottom: 22px;
909
1526
  }
910
1527
 
911
1528
  .taskon-task-list-section-label {
912
- flex-wrap: wrap;
913
- gap: 1.6vw;
1529
+ flex-wrap: nowrap;
1530
+ gap: 6px;
914
1531
  }
915
1532
 
916
- .taskon-task-list-section-title {
917
- font-size: 4.8vw;
918
- line-height: 6vw;
1533
+ .taskon-completed-count {
1534
+ margin-top: 0;
919
1535
  }
920
1536
 
921
- .taskon-completed-count {
922
- margin-top: 2.67vw;
923
- justify-content: flex-start;
1537
+ .taskon-task-list-items {
1538
+ gap: 20px;
1539
+ }
1540
+ }
1541
+ }
1542
+
1543
+ @supports not (container-type: inline-size) {
1544
+ @media (min-width: 751px) {
1545
+ .taskon-task-list-section-header {
1546
+ display: flex;
1547
+ justify-content: space-between;
1548
+ align-items: center;
1549
+ margin-top: 30px;
1550
+ margin-bottom: 22px;
924
1551
  }
925
1552
 
926
- .taskon-completed-count-check {
927
- width: 3.2vw;
928
- height: 2.4vw;
929
- margin-right: 2.13vw;
1553
+ .taskon-task-list-section-label {
1554
+ flex-wrap: nowrap;
1555
+ gap: 6px;
930
1556
  }
931
1557
 
932
- .taskon-completed-count-text {
933
- font-size: 3.47vw;
934
- line-height: 4.4vw;
1558
+ .taskon-completed-count {
1559
+ margin-top: 0;
935
1560
  }
936
1561
 
937
1562
  .taskon-task-list-items {
938
- gap: 3.07vw;
1563
+ gap: 20px;
1564
+ }
1565
+ }
939
1566
  }
940
- }
941
1567
 
942
1568
  /* ============================================
943
1569
  TaskProgress Styles
944
1570
  ============================================ */
1571
+
945
1572
  .taskon-task-progress {
946
1573
  display: flex;
947
1574
  flex-direction: column;
948
- gap: var(--taskon-task-spacing-sm);
1575
+ gap: var(--taskon-spacing-sm);
949
1576
  }
950
1577
 
951
1578
  .taskon-task-progress-bar {
952
1579
  height: 6px;
953
- background: rgba(255, 255, 255, 0.1);
954
- border-radius: 3px;
1580
+ background: var(--taskon-color-bg-surface-strong);
1581
+ border-radius: var(--taskon-border-radius-sm);
955
1582
  overflow: hidden;
956
1583
  }
957
1584
 
958
1585
  .taskon-task-progress-bar-fill {
959
1586
  height: 100%;
960
1587
  background: var(--taskon-color-primary);
961
- border-radius: 3px;
962
- transition: width var(--taskon-task-transition);
1588
+ border-radius: var(--taskon-border-radius-sm);
1589
+ transition: width 0.2s ease;
963
1590
  }
964
1591
 
965
1592
  .taskon-task-progress--completed .taskon-task-progress-bar-fill {
@@ -969,9 +1596,9 @@
969
1596
  .taskon-task-progress-text {
970
1597
  display: flex;
971
1598
  align-items: center;
972
- gap: var(--taskon-task-spacing-xs);
1599
+ gap: var(--taskon-spacing-xs);
973
1600
  font-size: 13px;
974
- color: var(--taskon-task-text-secondary);
1601
+ color: var(--taskon-color-text-tertiary);
975
1602
  }
976
1603
 
977
1604
  .taskon-task-progress--completed .taskon-task-progress-text {
@@ -987,23 +1614,25 @@
987
1614
  /* ============================================
988
1615
  TaskItem Styles
989
1616
  ============================================ */
1617
+
990
1618
  .taskon-task-item {
991
1619
  position: relative;
992
- padding: 16px 20px;
993
- background: var(--taskon-task-bg);
994
- border-radius: var(--taskon-task-radius);
995
- border: 1px solid var(--taskon-task-border);
996
- transition: border-color var(--taskon-task-transition);
1620
+ padding: var(--taskon-spacing-md);
1621
+ background: var(--taskon-color-bg-surface-subtle);
1622
+ border-radius: var(--taskon-border-radius-lg);
1623
+ border: 1px solid var(--taskon-color-border-secondary);
1624
+ transition: border-color 0.2s ease;
997
1625
  }
998
1626
 
999
1627
  .taskon-task-item:hover {
1000
- border-color: var(--taskon-task-border-hover);
1628
+ border-color: var(--taskon-color-border);
1001
1629
  }
1002
1630
 
1003
1631
  /* ============================================
1004
1632
  左上角浮标:周期标签 / 冷却倒计时
1005
1633
  与 Vue 版本 RecurrenceStatus.vue 样式一致
1006
1634
  ============================================ */
1635
+
1007
1636
  .taskon-task-item-recurrence {
1008
1637
  position: absolute;
1009
1638
  top: -6px;
@@ -1015,7 +1644,7 @@
1015
1644
  width: 78px;
1016
1645
  height: 20px;
1017
1646
  /* 文字样式 */
1018
- color: var(--taskon-recurrence-color);
1647
+ color: var(--taskon-color-primary);
1019
1648
  font-size: 12px;
1020
1649
  line-height: 16px;
1021
1650
  font-weight: 500;
@@ -1026,8 +1655,9 @@
1026
1655
  }
1027
1656
 
1028
1657
  /* 冷却倒计时样式 - 继承标签样式 */
1658
+
1029
1659
  .taskon-task-item-recurrence .taskon-cooldown-timer {
1030
- color: var(--taskon-recurrence-color);
1660
+ color: var(--taskon-color-primary);
1031
1661
  font-size: 12px;
1032
1662
  line-height: 16px;
1033
1663
  font-weight: 500;
@@ -1036,12 +1666,15 @@
1036
1666
  /* ============================================
1037
1667
  第一行:图标 + 标题 + 右侧内容
1038
1668
  ============================================ */
1669
+
1039
1670
  .taskon-task-item-row {
1040
1671
  display: flex;
1041
- align-items: center;
1672
+ align-items: flex-start;
1673
+ gap: 8px;
1042
1674
  }
1043
1675
 
1044
1676
  /* Left section: Icon + Title */
1677
+
1045
1678
  .taskon-task-item-left {
1046
1679
  display: flex;
1047
1680
  align-items: center;
@@ -1054,8 +1687,8 @@
1054
1687
  display: flex;
1055
1688
  align-items: center;
1056
1689
  justify-content: center;
1057
- margin-right: 16px;
1058
- color: var(--taskon-task-text-secondary);
1690
+ margin-right: 10px;
1691
+ color: var(--taskon-color-text-tertiary);
1059
1692
  }
1060
1693
 
1061
1694
  .taskon-task-item--completed .taskon-task-item-icon {
@@ -1063,7 +1696,9 @@
1063
1696
  }
1064
1697
 
1065
1698
  /* Title wrapper - 与 Vue 版本 TitleRow 结构一致 */
1699
+
1066
1700
  /* 普通 block flow,标题 inline,TotalEarnPoint 作为 block div 自然换行 */
1701
+
1067
1702
  .taskon-task-item-title-wrap {
1068
1703
  flex: 1;
1069
1704
  min-width: 0;
@@ -1073,16 +1708,17 @@
1073
1708
  display: inline;
1074
1709
  font-size: 18px;
1075
1710
  font-weight: 500;
1076
- color: var(--taskon-task-text);
1711
+ color: var(--taskon-color-text);
1077
1712
  line-height: 23px;
1078
1713
  overflow-wrap: break-word;
1079
1714
  }
1080
1715
 
1081
1716
  /* Title as link - 参考 Vue 版本 TitleRow.vue 的 OutLink 样式 */
1717
+
1082
1718
  .taskon-task-item-title--link {
1083
- color: #54aeff;
1719
+ color: var(--taskon-color-link);
1084
1720
  text-decoration: underline;
1085
- transition: opacity var(--taskon-task-transition);
1721
+ transition: opacity 0.2s ease;
1086
1722
  }
1087
1723
 
1088
1724
  .taskon-task-item-title--link:hover {
@@ -1090,14 +1726,15 @@
1090
1726
  }
1091
1727
 
1092
1728
  .taskon-task-item--completed .taskon-task-item-title {
1093
- color: var(--taskon-task-text-secondary);
1729
+ color: var(--taskon-color-text-tertiary);
1094
1730
  }
1095
1731
 
1096
1732
  /* Links in title - 统一蓝色加下划线样式 */
1733
+
1097
1734
  .taskon-task-item-link {
1098
- color: #54aeff;
1735
+ color: var(--taskon-color-link);
1099
1736
  text-decoration: underline;
1100
- transition: opacity var(--taskon-task-transition);
1737
+ transition: opacity 0.2s ease;
1101
1738
  }
1102
1739
 
1103
1740
  .taskon-task-item-link:hover {
@@ -1105,30 +1742,34 @@
1105
1742
  }
1106
1743
 
1107
1744
  /* Title tip icon */
1745
+
1108
1746
  .taskon-task-item-title-tip {
1109
1747
  display: inline-flex;
1110
1748
  align-items: center;
1111
1749
  justify-content: center;
1112
1750
  margin-left: 6px;
1113
- color: rgba(255, 255, 255, 0.4);
1751
+ color: var(--taskon-color-text-disabled);
1114
1752
  cursor: help;
1115
1753
  flex-shrink: 0;
1116
1754
  }
1117
1755
 
1118
1756
  .taskon-task-item-title-tip:hover {
1119
- color: rgba(255, 255, 255, 0.6);
1757
+ color: var(--taskon-color-text-tertiary);
1120
1758
  }
1121
1759
 
1122
1760
  /* Right section: Points + Total + Verify */
1761
+
1123
1762
  .taskon-task-item-right {
1124
1763
  display: flex;
1125
- align-items: center;
1126
- gap: var(--taskon-task-spacing-md);
1764
+ flex-direction: column;
1765
+ align-items: flex-end;
1766
+ gap: 6px;
1127
1767
  flex-shrink: 0;
1128
- margin-left: 10px;
1768
+ margin-left: 8px;
1129
1769
  }
1130
1770
 
1131
1771
  /* Points display - 参考 TaskPoint.vue */
1772
+
1132
1773
  .taskon-task-item-points {
1133
1774
  min-width: 40px;
1134
1775
  height: 34px;
@@ -1137,53 +1778,57 @@
1137
1778
  align-items: center;
1138
1779
  justify-content: center;
1139
1780
  gap: 2px;
1140
- background: rgba(255, 255, 255, 0.04);
1141
- border-radius: 6px;
1781
+ background: var(--taskon-color-bg-surface-subtle);
1782
+ border-radius: var(--taskon-border-radius-sm);
1142
1783
  font-size: 16px;
1143
1784
  font-weight: 500;
1144
1785
  }
1145
1786
 
1146
1787
  .taskon-task-item-points-value {
1147
- color: #ffffff;
1788
+ color: var(--taskon-color-text);
1148
1789
  }
1149
1790
 
1150
1791
  /* Points value when task is completed - green color like Vue version */
1792
+
1151
1793
  .taskon-task-item-points-value--completed {
1152
- color: #00ffa3;
1794
+ color: var(--taskon-color-secondary);
1153
1795
  }
1154
1796
 
1155
1797
  .taskon-task-item-points-time {
1156
1798
  font-size: 12px;
1157
- color: rgba(255, 255, 255, 0.6);
1799
+ color: var(--taskon-color-text-tertiary);
1158
1800
  }
1159
1801
 
1160
1802
  /* Tip icon next to points (margin controlled externally) */
1803
+
1161
1804
  .taskon-task-item-tip {
1162
1805
  margin-left: 10px;
1163
1806
  }
1164
1807
 
1165
1808
  /* Total points */
1809
+
1166
1810
  .taskon-task-item-total-points {
1167
1811
  font-size: 12px;
1168
- color: var(--taskon-task-text-muted);
1812
+ color: var(--taskon-color-text-disabled);
1169
1813
  }
1170
1814
 
1171
1815
  /* ============================================
1172
1816
  TotalEarnPoint Styles
1173
1817
  与 Vue 版本 TotalEarnPoint.vue 样式一致
1174
1818
  ============================================ */
1819
+
1175
1820
  .taskon-task-item-total-earn {
1176
1821
  display: flex;
1177
1822
  align-items: center;
1178
1823
  }
1179
1824
 
1180
1825
  .taskon-task-item-total-earn-text {
1181
- color: rgba(255, 255, 255, 0.6);
1826
+ color: var(--taskon-color-text-tertiary);
1182
1827
  font-size: 14px;
1183
1828
  }
1184
1829
 
1185
1830
  .taskon-task-item-total-earn-value {
1186
- color: #9aff73;
1831
+ color: var(--taskon-color-primary);
1187
1832
  font-size: 14px;
1188
1833
  margin: 0 4px;
1189
1834
  }
@@ -1191,132 +1836,55 @@
1191
1836
  /* ============================================
1192
1837
  第二行:内容区域(始终显示)
1193
1838
  ============================================ */
1839
+
1194
1840
  .taskon-task-item-body {
1195
- margin-left: 50px;
1841
+ margin-left: 36px;
1196
1842
  margin-top: 10px;
1197
1843
  }
1198
1844
 
1199
1845
  .taskon-task-item-content {
1200
1846
  display: flex;
1201
1847
  flex-direction: column;
1202
- gap: var(--taskon-task-spacing-md);
1848
+ gap: var(--taskon-spacing-md);
1203
1849
  }
1204
1850
 
1205
1851
  .taskon-task-item-desc {
1206
1852
  font-size: 14px;
1207
1853
  line-height: 21px;
1208
- color: var(--taskon-task-text-secondary);
1209
- word-break: break-all;
1210
- white-space: pre-wrap;
1211
- }
1212
-
1213
- .taskon-task-item-desc span {
1214
- color: var(--taskon-task-text);
1215
- word-break: break-all;
1216
- }
1217
-
1218
- /* Rich text content - 参考 Vue 版本 TextPreview.vue */
1219
- .taskon-task-item-rich-text {
1220
- font-size: 14px;
1221
- line-height: 21px;
1222
- color: var(--taskon-task-text-secondary);
1854
+ color: var(--taskon-color-text-tertiary);
1223
1855
  word-break: break-word;
1224
- }
1225
-
1226
- .taskon-task-item-rich-text p {
1227
- margin: 0 0 0.5em 0;
1228
- }
1229
-
1230
- .taskon-task-item-rich-text p:last-child {
1231
- margin-bottom: 0;
1232
- }
1233
-
1234
- .taskon-task-item-rich-text a {
1235
- color: #54aeff;
1236
- text-decoration: underline;
1237
- }
1238
-
1239
- .taskon-task-item-rich-text a:hover {
1240
- opacity: 0.8;
1241
- }
1242
-
1243
- .taskon-task-item-rich-text strong,
1244
- .taskon-task-item-rich-text b {
1245
- font-weight: 600;
1246
- color: var(--taskon-task-text);
1247
- }
1248
-
1249
- .taskon-task-item-rich-text em,
1250
- .taskon-task-item-rich-text i {
1251
- font-style: italic;
1252
- }
1253
-
1254
- .taskon-task-item-rich-text ul,
1255
- .taskon-task-item-rich-text ol {
1256
- margin: 0.5em 0;
1257
- padding-left: 1.5em;
1258
- }
1259
-
1260
- .taskon-task-item-rich-text li {
1261
- margin: 0.25em 0;
1262
- }
1263
-
1264
- .taskon-task-item-rich-text code {
1265
- background: rgba(255, 255, 255, 0.1);
1266
- padding: 0.2em 0.4em;
1267
- border-radius: 3px;
1268
- font-size: 0.9em;
1269
- }
1270
-
1271
- .taskon-task-item-rich-text pre {
1272
- background: rgba(255, 255, 255, 0.05);
1273
- padding: 0.75em 1em;
1274
- border-radius: 6px;
1275
- overflow-x: auto;
1276
- margin: 0.5em 0;
1277
- }
1278
-
1279
- .taskon-task-item-rich-text blockquote {
1280
- border-left: 3px solid var(--taskon-color-primary);
1281
- padding-left: 1em;
1282
- margin: 0.5em 0;
1283
- color: var(--taskon-task-text-muted);
1284
- }
1285
-
1286
- .taskon-task-item-rich-text img {
1287
- max-width: 100%;
1288
- height: auto;
1289
- border-radius: 6px;
1856
+ white-space: pre-wrap;
1290
1857
  }
1291
1858
 
1292
1859
  /* Description fields */
1860
+
1293
1861
  .taskon-task-item-fields {
1294
1862
  display: flex;
1295
1863
  flex-direction: column;
1296
- gap: var(--taskon-task-spacing-xs);
1864
+ gap: var(--taskon-spacing-xs);
1297
1865
  }
1298
1866
 
1299
1867
  .taskon-task-item-field {
1300
1868
  display: flex;
1301
1869
  align-items: baseline;
1302
- gap: var(--taskon-task-spacing-sm);
1870
+ gap: var(--taskon-spacing-sm);
1303
1871
  font-size: 13px;
1304
1872
  }
1305
1873
 
1306
1874
  .taskon-task-item-field-key {
1307
- color: var(--taskon-task-text-muted);
1875
+ color: var(--taskon-color-text-disabled);
1308
1876
  flex-shrink: 0;
1309
1877
  }
1310
1878
 
1311
1879
  .taskon-task-item-field-value {
1312
- color: var(--taskon-task-text);
1880
+ color: var(--taskon-color-text);
1313
1881
  word-break: break-all;
1314
1882
  }
1315
1883
 
1316
1884
  .taskon-task-item-field-value--link {
1317
- color: #54aeff;
1885
+ color: var(--taskon-color-link);
1318
1886
  text-decoration: underline;
1319
- transition: opacity var(--taskon-task-transition);
1887
+ transition: opacity 0.2s ease;
1320
1888
  }
1321
1889
 
1322
1890
  .taskon-task-item-field-value--link:hover {
@@ -1324,27 +1892,29 @@
1324
1892
  }
1325
1893
 
1326
1894
  /* Action link */
1895
+
1327
1896
  .taskon-task-item-action-link {
1328
1897
  display: inline-flex;
1329
1898
  align-items: center;
1330
- padding: var(--taskon-task-spacing-sm) var(--taskon-task-spacing-md);
1899
+ padding: var(--taskon-spacing-sm) var(--taskon-spacing-md);
1331
1900
  font-size: 13px;
1332
1901
  font-weight: 500;
1333
1902
  color: var(--taskon-color-primary);
1334
1903
  background: transparent;
1335
1904
  border: 1px solid var(--taskon-color-primary);
1336
- border-radius: 6px;
1905
+ border-radius: var(--taskon-border-radius);
1337
1906
  text-decoration: none;
1338
- transition: all var(--taskon-task-transition);
1907
+ transition: all 0.2s ease;
1339
1908
  align-self: flex-start;
1340
1909
  }
1341
1910
 
1342
1911
  .taskon-task-item-action-link:hover {
1343
1912
  background: var(--taskon-color-primary);
1344
- color: white;
1913
+ color: var(--taskon-color-text-on-primary);
1345
1914
  }
1346
1915
 
1347
1916
  /* Spinner animation */
1917
+
1348
1918
  @keyframes taskon-spin {
1349
1919
  from {
1350
1920
  transform: rotate(0deg);
@@ -1361,6 +1931,7 @@
1361
1931
  /* ============================================
1362
1932
  TaskIcon Styles
1363
1933
  ============================================ */
1934
+
1364
1935
  .taskon-task-icon {
1365
1936
  display: inline-flex;
1366
1937
  align-items: center;
@@ -1376,10 +1947,11 @@
1376
1947
  /* ============================================
1377
1948
  CooldownTimer Styles
1378
1949
  ============================================ */
1950
+
1379
1951
  .taskon-cooldown-timer {
1380
1952
  display: inline-flex;
1381
1953
  align-items: center;
1382
- gap: var(--taskon-task-spacing-xs);
1954
+ gap: var(--taskon-spacing-xs);
1383
1955
  font-size: 13px;
1384
1956
  color: var(--taskon-color-warning);
1385
1957
  }
@@ -1387,28 +1959,29 @@
1387
1959
  /* ============================================
1388
1960
  VerifyButton Styles
1389
1961
  ============================================ */
1962
+
1390
1963
  .taskon-verify-btn {
1391
1964
  display: inline-flex;
1392
1965
  align-items: center;
1393
1966
  justify-content: center;
1394
- gap: 4px;
1967
+ gap: var(--taskon-spacing-xs);
1395
1968
  height: 34px;
1396
- padding: 0 12px;
1969
+ padding: 0 var(--taskon-spacing-md);
1397
1970
  font-size: 14px;
1398
1971
  font-weight: 500;
1399
1972
  line-height: 20px;
1400
- color: #fff;
1973
+ color: var(--taskon-color-text);
1401
1974
  background: transparent;
1402
- border: 1px solid rgba(255, 255, 255, 0.1);
1403
- border-radius: 6px;
1975
+ border: 1px solid var(--taskon-color-border);
1976
+ border-radius: var(--taskon-border-radius);
1404
1977
  cursor: pointer;
1405
- transition: all var(--taskon-task-transition);
1978
+ transition: all 0.2s ease;
1406
1979
  white-space: nowrap;
1407
1980
  flex-shrink: 0;
1408
1981
  }
1409
1982
 
1410
1983
  .taskon-verify-btn:hover:not(:disabled) {
1411
- border-color: rgba(255, 255, 255, 0.3);
1984
+ border-color: var(--taskon-color-text-disabled);
1412
1985
  }
1413
1986
 
1414
1987
  .taskon-verify-btn:disabled {
@@ -1429,6 +2002,7 @@
1429
2002
  /* ============================================
1430
2003
  ExpandableContent Styles
1431
2004
  ============================================ */
2005
+
1432
2006
  .taskon-expandable {
1433
2007
  display: flex;
1434
2008
  flex-direction: column;
@@ -1441,16 +2015,16 @@
1441
2015
  .taskon-expandable-toggle {
1442
2016
  display: inline-flex;
1443
2017
  align-items: center;
1444
- gap: 4px;
2018
+ gap: var(--taskon-spacing-xs);
1445
2019
  padding: 0;
1446
- margin-top: 8px;
2020
+ margin-top: var(--taskon-spacing-sm);
1447
2021
  font-size: 13px;
1448
2022
  font-weight: 500;
1449
- color: #ffffff;
2023
+ color: var(--taskon-color-text);
1450
2024
  background: transparent;
1451
2025
  border: none;
1452
2026
  cursor: pointer;
1453
- transition: opacity var(--taskon-task-transition);
2027
+ transition: opacity 0.2s ease;
1454
2028
  align-self: flex-start;
1455
2029
  }
1456
2030
 
@@ -1463,7 +2037,7 @@
1463
2037
  }
1464
2038
 
1465
2039
  .taskon-expandable-toggle-icon {
1466
- transition: transform var(--taskon-task-transition);
2040
+ transition: transform 0.2s ease;
1467
2041
  flex-shrink: 0;
1468
2042
  }
1469
2043
 
@@ -1472,59 +2046,70 @@
1472
2046
  }
1473
2047
 
1474
2048
  /* ============================================
1475
- Responsive Styles
2049
+ Desktop 增强
1476
2050
  ============================================ */
1477
- @media (max-width: 750px) {
2051
+
2052
+ @supports (container-type: inline-size) {
2053
+ @container (min-width: 751px) {
1478
2054
  .taskon-task-item {
1479
- padding: 4vw;
2055
+ padding: 16px 20px;
2056
+ }
2057
+
2058
+ .taskon-task-item-row {
2059
+ align-items: center;
2060
+ gap: 0;
1480
2061
  }
1481
2062
 
1482
2063
  .taskon-task-item-body {
1483
- margin-left: 9.333vw;
2064
+ margin-left: 50px;
1484
2065
  }
1485
2066
 
1486
2067
  .taskon-task-item-icon {
1487
- margin-right: 2.667vw;
2068
+ margin-right: 16px;
1488
2069
  }
1489
2070
 
1490
2071
  .taskon-task-item-right {
1491
- margin-left: 2.67vw;
2072
+ flex-direction: row;
2073
+ align-items: center;
2074
+ gap: 6px;
2075
+ margin-left: 8px;
2076
+ }
2077
+ }
1492
2078
  }
1493
2079
 
1494
- .taskon-task-item-title {
1495
- font-weight: 400;
1496
- font-size: 3.733vw;
1497
- line-height: 4.667vw;
2080
+ @supports not (container-type: inline-size) {
2081
+ @media (min-width: 751px) {
2082
+ .taskon-task-item {
2083
+ padding: 16px 20px;
1498
2084
  }
1499
2085
 
1500
- .taskon-task-item-desc {
1501
- font-size: 3.2vw;
1502
- line-height: 4vw;
2086
+ .taskon-task-item-row {
2087
+ align-items: center;
2088
+ gap: 0;
1503
2089
  }
1504
2090
 
1505
- .taskon-task-icon-img {
1506
- width: 6.667vw !important;
1507
- height: 6.667vw !important;
2091
+ .taskon-task-item-body {
2092
+ margin-left: 50px;
1508
2093
  }
1509
2094
 
1510
- /* Points display mobile - 参考 TaskPoint.vue */
1511
- .taskon-task-item-points {
1512
- min-width: 6.8vw;
1513
- height: 6.67vw;
1514
- padding: 0 2vw;
1515
- font-size: 2.93vw;
1516
- border-radius: 0.91vw;
2095
+ .taskon-task-item-icon {
2096
+ margin-right: 16px;
1517
2097
  }
1518
2098
 
1519
- .taskon-task-item-points-time {
1520
- font-size: 1.85vw;
2099
+ .taskon-task-item-right {
2100
+ flex-direction: row;
2101
+ align-items: center;
2102
+ gap: 6px;
2103
+ margin-left: 8px;
2104
+ }
2105
+ }
1521
2106
  }
1522
- }
1523
2107
 
1524
2108
  /* ============================================
1525
2109
  TimeRange Styles
1526
2110
  与 Vue 版本 TimeRange.vue 样式一致
1527
2111
  ============================================ */
2112
+
1528
2113
  .taskon-task-time-range {
1529
2114
  font-size: 14px;
1530
2115
  line-height: 18px;
@@ -1532,23 +2117,24 @@
1532
2117
  }
1533
2118
 
1534
2119
  .taskon-task-time-range-label {
1535
- color: var(--taskon-task-text-secondary);
2120
+ color: var(--taskon-color-text-tertiary);
1536
2121
  }
1537
2122
 
1538
2123
  .taskon-task-time-range-value {
1539
2124
  display: inline-block;
1540
- color: rgba(255, 212, 101, 1);
2125
+ color: var(--taskon-color-warning);
1541
2126
  }
1542
2127
 
1543
2128
  /* ============================================
1544
2129
  VerifyButton Cooldown Progress Bar
1545
2130
  与 Vue 版本 VerifyButton.vue 冷却进度条样式一致
1546
2131
  ============================================ */
2132
+
1547
2133
  .taskon-verify-btn-wrap {
1548
2134
  position: relative;
1549
2135
  display: inline-block;
1550
2136
  overflow: hidden;
1551
- border-radius: 6px;
2137
+ border-radius: var(--taskon-border-radius);
1552
2138
  }
1553
2139
 
1554
2140
  .taskon-verify-btn-progress {
@@ -1561,8 +2147,35 @@
1561
2147
 
1562
2148
  .taskon-verify-btn-progress-bar {
1563
2149
  height: 100%;
1564
- border-radius: 6px;
1565
- background: linear-gradient(to right, #cbff01, #00ffa3);
2150
+ border-radius: var(--taskon-border-radius);
2151
+ background: linear-gradient(
2152
+ to right,
2153
+ var(--taskon-color-primary),
2154
+ var(--taskon-color-secondary)
2155
+ );
2156
+ }
2157
+ /**
2158
+ * RewardModuleDialog styles
2159
+ * Scope UserCenter module styles inside Quest popup
2160
+ */
2161
+
2162
+ .taskon-quest-reward-dialog .taskon-user-center {
2163
+ padding: 32px 0 0 0;
2164
+ background: transparent;
2165
+ border-radius: 0;
2166
+ gap: 24px;
2167
+ }
2168
+
2169
+ .taskon-quest-reward-dialog .taskon-my-rewards {
2170
+ gap: 24px;
2171
+ }
2172
+
2173
+ .taskon-quest-reward-dialog .taskon-my-rewards__section {
2174
+ gap: 16px;
2175
+ }
2176
+
2177
+ .taskon-quest-reward-dialog .taskon-points-list {
2178
+ background: transparent;
1566
2179
  }
1567
2180
  /**
1568
2181
  * BlindBox 盲盒组件样式
@@ -1571,20 +2184,34 @@
1571
2184
  * Migrated from Vue version with Tailwind classes converted to CSS
1572
2185
  */
1573
2186
 
2187
+ /*
2188
+ * Responsive base styles
2189
+ *
2190
+ * Keep mobile breakpoints and fallback patterns centralized here.
2191
+ * Components should reuse these mixins instead of duplicating query logic.
2192
+ */
2193
+
2194
+ /*
2195
+ * Desktop-up mixin:
2196
+ * 1) Enable desktop enhancement in wider containers
2197
+ * 2) Keep viewport media query as fallback
2198
+ */
2199
+
1574
2200
  /* ============================================================================
1575
2201
  BlindBox Dialog - 开盲盒交互弹窗
1576
2202
  ============================================================================ */
1577
2203
 
1578
2204
  .taskon-quest-blindbox-dialog {
2205
+ container-type: inline-size;
1579
2206
  position: relative;
1580
2207
  width: min(520px, 92vw);
1581
2208
  overflow: hidden;
1582
- padding-top: 40px;
2209
+ padding-top: var(--taskon-spacing-lg);
1583
2210
  }
1584
2211
 
1585
2212
  .taskon-quest-blindbox-dialog-title {
1586
- margin: 0 0 16px;
1587
- padding: 0 40px;
2213
+ margin: 0 0 var(--taskon-spacing-md);
2214
+ padding: 0 var(--taskon-spacing-lg);
1588
2215
  font-size: 22px;
1589
2216
  font-weight: 600;
1590
2217
  line-height: 1.4;
@@ -1592,6 +2219,7 @@
1592
2219
  }
1593
2220
 
1594
2221
  /* Stage container - centered square area for animation */
2222
+
1595
2223
  .taskon-quest-blindbox-stage {
1596
2224
  position: relative;
1597
2225
  display: flex;
@@ -1607,6 +2235,7 @@
1607
2235
  }
1608
2236
 
1609
2237
  /* Background spinning light */
2238
+
1610
2239
  .taskon-quest-blindbox-bg {
1611
2240
  position: absolute;
1612
2241
  left: 50%;
@@ -1633,6 +2262,7 @@
1633
2262
  }
1634
2263
 
1635
2264
  /* Drop zone - collision detection area */
2265
+
1636
2266
  .taskon-quest-blindbox-dropzone {
1637
2267
  position: absolute;
1638
2268
  left: 50%;
@@ -1644,6 +2274,7 @@
1644
2274
  }
1645
2275
 
1646
2276
  /* Chest container */
2277
+
1647
2278
  .taskon-quest-blindbox-chest {
1648
2279
  position: absolute;
1649
2280
  left: 50%;
@@ -1664,15 +2295,17 @@
1664
2295
  }
1665
2296
 
1666
2297
  /* Ensure Lottie SVG fills container */
2298
+
1667
2299
  .taskon-quest-blindbox-chest svg {
1668
2300
  width: 100% !important;
1669
2301
  height: auto !important;
1670
2302
  }
1671
2303
 
1672
2304
  /* Key image */
2305
+
1673
2306
  .taskon-quest-blindbox-key {
1674
2307
  position: absolute;
1675
- width: clamp(80px, 16vw, 100px);
2308
+ width: clamp(80px, 25%, 100px);
1676
2309
  transform: translate(-50%, -50%);
1677
2310
  cursor: grab;
1678
2311
  touch-action: none;
@@ -1700,16 +2333,18 @@
1700
2333
  ============================================================================ */
1701
2334
 
1702
2335
  .taskon-quest-blindbox-reward {
2336
+ container-type: inline-size;
1703
2337
  position: relative;
1704
2338
  width: 510px;
1705
2339
  max-width: 92vw;
1706
- padding: 64px 40px;
2340
+ padding: 48px var(--taskon-spacing-lg);
1707
2341
  text-align: center;
1708
2342
  color: #fff;
1709
2343
  overflow: hidden;
1710
2344
  }
1711
2345
 
1712
2346
  /* Light background effect */
2347
+
1713
2348
  .taskon-quest-blindbox-reward-light {
1714
2349
  position: absolute;
1715
2350
  top: 0;
@@ -1730,6 +2365,7 @@
1730
2365
  }
1731
2366
 
1732
2367
  /* Title */
2368
+
1733
2369
  .taskon-quest-blindbox-reward-title {
1734
2370
  font-size: 32px;
1735
2371
  font-weight: 600;
@@ -1738,6 +2374,7 @@
1738
2374
  }
1739
2375
 
1740
2376
  /* Subtitle */
2377
+
1741
2378
  .taskon-quest-blindbox-reward-subtitle {
1742
2379
  margin-top: 12px;
1743
2380
  font-size: 16px;
@@ -1746,31 +2383,33 @@
1746
2383
  }
1747
2384
 
1748
2385
  /* Rewards container - Green border and background like Vue version */
2386
+
1749
2387
  .taskon-quest-blindbox-reward-list {
1750
2388
  display: inline-flex;
1751
2389
  flex-wrap: wrap;
1752
2390
  justify-content: center;
1753
2391
  align-items: center;
1754
- margin-top: 24px;
1755
- gap: 8px;
1756
- padding: 12px 16px;
1757
- border-radius: 8px;
2392
+ margin-top: var(--taskon-spacing-lg);
2393
+ gap: var(--taskon-spacing-sm);
2394
+ padding: 12px var(--taskon-spacing-md);
2395
+ border-radius: var(--taskon-border-radius);
1758
2396
  border: 1px solid rgba(60, 232, 155, 0.2);
1759
2397
  background: rgba(0, 255, 163, 0.1);
1760
2398
  }
1761
2399
 
1762
2400
  /* Single reward card - transparent background */
2401
+
1763
2402
  .taskon-quest-blindbox-reward-card {
1764
2403
  display: flex;
1765
2404
  flex-direction: column;
1766
2405
  align-items: center;
1767
2406
  justify-content: center;
1768
- padding: 12px 16px;
2407
+ padding: 12px var(--taskon-spacing-md);
1769
2408
  background: transparent;
1770
2409
  border-radius: 0;
1771
2410
  min-width: 60px;
1772
2411
  min-height: 80px;
1773
- gap: 8px;
2412
+ gap: var(--taskon-spacing-sm);
1774
2413
  }
1775
2414
 
1776
2415
  .taskon-quest-blindbox-reward-card-icon {
@@ -1781,6 +2420,7 @@
1781
2420
  }
1782
2421
 
1783
2422
  /* Token amount with orange color and underline like Vue version */
2423
+
1784
2424
  .taskon-quest-blindbox-reward-card-amount {
1785
2425
  font-size: 18px;
1786
2426
  font-weight: 600;
@@ -1801,13 +2441,15 @@
1801
2441
  }
1802
2442
 
1803
2443
  /* Back button */
2444
+
1804
2445
  .taskon-quest-blindbox-reward-btn-wrap {
1805
2446
  display: flex;
1806
2447
  justify-content: center;
1807
- margin-top: 60px;
2448
+ margin-top: 40px;
1808
2449
  }
1809
2450
 
1810
2451
  /* Back button - matches Vue g-button--light-border */
2452
+
1811
2453
  .taskon-quest-blindbox-reward-btn {
1812
2454
  height: 36px;
1813
2455
  padding: 0 24px;
@@ -1816,7 +2458,7 @@
1816
2458
  color: #fff;
1817
2459
  background: transparent;
1818
2460
  border: 1px solid #fff;
1819
- border-radius: 8px;
2461
+ border-radius: var(--taskon-border-radius);
1820
2462
  cursor: pointer;
1821
2463
  transition: opacity 0.2s ease;
1822
2464
  }
@@ -1846,7 +2488,7 @@
1846
2488
  color: #000;
1847
2489
  background: linear-gradient(135deg, #ffd700 0%, #ffaa00 100%);
1848
2490
  border: none;
1849
- border-radius: 12px;
2491
+ border-radius: var(--taskon-border-radius-lg);
1850
2492
  cursor: pointer;
1851
2493
  transition: all 0.2s ease;
1852
2494
  }
@@ -1865,40 +2507,61 @@
1865
2507
  height: 24px;
1866
2508
  }
1867
2509
 
1868
- /* ============================================================================
1869
- Mobile Responsive
1870
- ============================================================================ */
1871
-
1872
- @media (max-width: 768px) {
2510
+ @supports (container-type: inline-size) {
2511
+ @container (min-width: 751px) {
1873
2512
  .taskon-quest-blindbox-dialog {
1874
- padding-top: 24px;
2513
+ padding-top: 40px;
1875
2514
  }
1876
2515
 
1877
2516
  .taskon-quest-blindbox-dialog-title {
1878
- padding: 0 24px;
1879
- font-size: 18px;
2517
+ padding: 0 40px;
1880
2518
  }
1881
2519
 
1882
2520
  .taskon-quest-blindbox-reward {
1883
- padding: 48px 24px;
2521
+ padding: 64px 40px;
2522
+ }
2523
+
2524
+ .taskon-quest-blindbox-reward-btn-wrap {
2525
+ margin-top: 60px;
2526
+ }
2527
+ }
2528
+ }
2529
+
2530
+ @supports not (container-type: inline-size) {
2531
+ @media (min-width: 751px) {
2532
+ .taskon-quest-blindbox-dialog {
2533
+ padding-top: 40px;
1884
2534
  }
1885
2535
 
1886
- .taskon-quest-blindbox-reward-title {
1887
- font-size: 24px;
1888
- line-height: 32px;
2536
+ .taskon-quest-blindbox-dialog-title {
2537
+ padding: 0 40px;
2538
+ }
2539
+
2540
+ .taskon-quest-blindbox-reward {
2541
+ padding: 64px 40px;
1889
2542
  }
1890
2543
 
1891
2544
  .taskon-quest-blindbox-reward-btn-wrap {
1892
- margin-top: 40px;
2545
+ margin-top: 60px;
2546
+ }
2547
+ }
1893
2548
  }
1894
- }
1895
2549
  /**
1896
2550
  * Eligibility (资格验证) 组件样式
1897
2551
  * @description Standalone CSS for EligibilityInfo component, usable in any widget context.
2552
+ */
2553
+
2554
+ /*
2555
+ * Responsive base styles
1898
2556
  *
1899
- * CSS variable fallbacks ensure correct rendering even outside Quest widget
1900
- * (e.g., when used in TaskChain). When rendered inside .taskon-quest,
1901
- * the Quest-defined variables take precedence.
2557
+ * Keep mobile breakpoints and fallback patterns centralized here.
2558
+ * Components should reuse these mixins instead of duplicating query logic.
2559
+ */
2560
+
2561
+ /*
2562
+ * Desktop-up mixin:
2563
+ * 1) Enable desktop enhancement in wider containers
2564
+ * 2) Keep viewport media query as fallback
1902
2565
  */
1903
2566
 
1904
2567
  /* ============================================================================
@@ -1906,23 +2569,25 @@
1906
2569
  ============================================================================ */
1907
2570
 
1908
2571
  .taskon-quest-eligs {
1909
- margin-top: 25px;
1910
- padding: 0 18px;
1911
- border: 1px solid var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
1912
- border-radius: 10px;
2572
+ container-type: inline-size;
2573
+ margin-top: var(--taskon-spacing-md);
2574
+ padding: 0 var(--taskon-spacing-md);
2575
+ border: 1px solid var(--taskon-color-border);
2576
+ border-radius: var(--taskon-border-radius-lg);
1913
2577
  }
1914
2578
 
1915
2579
  /* 动画效果 - 用于引导用户注意 */
2580
+
1916
2581
  .taskon-quest-eligs--animate {
1917
2582
  animation: taskon-quest-eligs-glow 800ms ease-out infinite alternate;
1918
2583
  }
1919
2584
 
1920
2585
  @keyframes taskon-quest-eligs-glow {
1921
2586
  0% {
1922
- border-color: var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
2587
+ border-color: var(--taskon-color-border);
1923
2588
  }
1924
2589
  100% {
1925
- border-color: rgba(255, 255, 255, 0.4);
2590
+ border-color: var(--taskon-color-primary);
1926
2591
  }
1927
2592
  }
1928
2593
 
@@ -1946,19 +2611,22 @@
1946
2611
  }
1947
2612
 
1948
2613
  /* 状态图标 */
2614
+
1949
2615
  .taskon-quest-eligs-header-status {
1950
2616
  flex-shrink: 0;
1951
2617
  }
1952
2618
 
1953
2619
  /* 头部文本 */
2620
+
1954
2621
  .taskon-quest-eligs-header-text {
1955
2622
  flex: 1;
1956
- color: var(--taskon-quest-text-lightest, #ffffff);
2623
+ color: var(--taskon-color-text);
1957
2624
  }
1958
2625
 
1959
2626
  /* 高亮表达式 (all/any) */
2627
+
1960
2628
  .taskon-quest-eligs-header-express {
1961
- color: var(--taskon-quest-secondary, #1affab);
2629
+ color: var(--taskon-color-secondary);
1962
2630
  }
1963
2631
 
1964
2632
  /* ============================================================================
@@ -1974,16 +2642,16 @@
1974
2642
  padding: 0;
1975
2643
  margin-left: auto;
1976
2644
  background: transparent;
1977
- border: 1px solid var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
1978
- border-radius: 6px;
1979
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2645
+ border: 1px solid var(--taskon-color-border);
2646
+ border-radius: var(--taskon-border-radius-sm);
2647
+ color: var(--taskon-color-text-secondary);
1980
2648
  cursor: pointer;
1981
2649
  transition: all 0.2s;
1982
2650
  }
1983
2651
 
1984
2652
  .taskon-quest-eligs-refresh:hover:not(:disabled) {
1985
- border-color: var(--taskon-quest-text-light, rgba(255, 255, 255, 0.6));
1986
- color: var(--taskon-quest-text-lightest, #ffffff);
2653
+ border-color: var(--taskon-color-text-tertiary);
2654
+ color: var(--taskon-color-text);
1987
2655
  }
1988
2656
 
1989
2657
  .taskon-quest-eligs-refresh:disabled {
@@ -2009,7 +2677,7 @@
2009
2677
  flex-shrink: 0;
2010
2678
  width: 6px;
2011
2679
  height: 10px;
2012
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2680
+ color: var(--taskon-color-text-secondary);
2013
2681
  transform: rotate(90deg);
2014
2682
  transition: transform 0.3s;
2015
2683
  }
@@ -2024,19 +2692,20 @@
2024
2692
 
2025
2693
  .taskon-quest-eligs-list {
2026
2694
  text-align: left;
2027
- padding: 20px 0;
2695
+ padding: var(--taskon-spacing-md) 0;
2028
2696
  margin: 0;
2029
2697
  list-style: none;
2030
- border-top: 1px solid var(--taskon-quest-text-darkest, rgba(255, 255, 255, 0.1));
2698
+ border-top: 1px solid var(--taskon-color-border);
2031
2699
  }
2032
2700
 
2033
2701
  /* 单项 */
2702
+
2034
2703
  .taskon-quest-eligs-item {
2035
2704
  line-height: 18px;
2036
2705
  }
2037
2706
 
2038
2707
  .taskon-quest-eligs-item + .taskon-quest-eligs-item {
2039
- margin-top: 24px;
2708
+ margin-top: var(--taskon-spacing-md);
2040
2709
  }
2041
2710
 
2042
2711
  .taskon-quest-eligs-item-container {
@@ -2045,10 +2714,11 @@
2045
2714
  }
2046
2715
 
2047
2716
  /* 状态图标 */
2717
+
2048
2718
  .taskon-quest-eligs-item-icon {
2049
2719
  flex-shrink: 0;
2050
- margin-right: 10px;
2051
- margin-top: 2px;
2720
+ margin-right: var(--taskon-spacing-sm);
2721
+ margin-top: var(--taskon-spacing-xs);
2052
2722
  opacity: 0;
2053
2723
  }
2054
2724
 
@@ -2056,8 +2726,8 @@
2056
2726
  flex-shrink: 0;
2057
2727
  width: 16px;
2058
2728
  height: 16px;
2059
- margin-right: 10px;
2060
- margin-top: 2px;
2729
+ margin-right: var(--taskon-spacing-sm);
2730
+ margin-top: var(--taskon-spacing-xs);
2061
2731
  }
2062
2732
 
2063
2733
  .taskon-quest-eligs-item--passed .taskon-quest-eligs-item-icon,
@@ -2065,12 +2735,29 @@
2065
2735
  opacity: 1;
2066
2736
  }
2067
2737
 
2738
+ .taskon-quest-eligs-item-icon--passed {
2739
+ color: var(--taskon-color-success);
2740
+ }
2741
+
2742
+ .taskon-quest-eligs-item-icon--failed {
2743
+ color: var(--taskon-color-error);
2744
+ }
2745
+
2746
+ .taskon-quest-eligs-header-status--passed {
2747
+ color: var(--taskon-color-success);
2748
+ }
2749
+
2750
+ .taskon-quest-eligs-header-status--failed {
2751
+ color: var(--taskon-color-error);
2752
+ }
2753
+
2068
2754
  /* 内容区 */
2755
+
2069
2756
  .taskon-quest-eligs-item-content {
2070
2757
  flex: 1;
2071
2758
  font-size: 14px;
2072
2759
  line-height: 18px;
2073
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2760
+ color: var(--taskon-color-text-secondary);
2074
2761
  }
2075
2762
 
2076
2763
  /* ============================================================================
@@ -2078,7 +2765,7 @@
2078
2765
  ============================================================================ */
2079
2766
 
2080
2767
  .taskon-quest-eligs-type {
2081
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2768
+ color: var(--taskon-color-text-secondary);
2082
2769
  }
2083
2770
 
2084
2771
  .taskon-quest-eligs-type--tooltip {
@@ -2087,13 +2774,15 @@
2087
2774
  }
2088
2775
 
2089
2776
  /* 高亮文本 */
2777
+
2090
2778
  .taskon-quest-eligs-highlight {
2091
- color: var(--taskon-quest-primary, #cbff01);
2779
+ color: var(--taskon-color-primary);
2092
2780
  }
2093
2781
 
2094
2782
  /* 链接样式 */
2783
+
2095
2784
  .taskon-quest-eligs-link {
2096
- color: var(--taskon-quest-link, #58afff);
2785
+ color: var(--taskon-color-link);
2097
2786
  text-decoration: underline;
2098
2787
  }
2099
2788
 
@@ -2102,6 +2791,7 @@
2102
2791
  }
2103
2792
 
2104
2793
  /* Tooltip */
2794
+
2105
2795
  .taskon-quest-eligs-tooltip {
2106
2796
  position: absolute;
2107
2797
  top: 100%;
@@ -2112,10 +2802,10 @@
2112
2802
  max-width: 300px;
2113
2803
  font-size: 12px;
2114
2804
  line-height: 16px;
2115
- color: var(--taskon-quest-text-lightest, #ffffff);
2116
- background-color: rgba(0, 0, 0, 0.9);
2117
- border-radius: 6px;
2118
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2805
+ color: var(--taskon-color-text);
2806
+ background-color: var(--taskon-color-bg-floating);
2807
+ border-radius: var(--taskon-border-radius-sm);
2808
+ box-shadow: 0 2px 8px var(--taskon-color-bg-mask);
2119
2809
  white-space: normal;
2120
2810
  word-break: break-word;
2121
2811
  }
@@ -2148,7 +2838,7 @@
2148
2838
  flex-shrink: 0;
2149
2839
  width: 8px;
2150
2840
  height: 8px;
2151
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2841
+ color: var(--taskon-color-text-secondary);
2152
2842
  transform: rotate(-90deg);
2153
2843
  transition: transform 0.3s;
2154
2844
  }
@@ -2169,51 +2859,54 @@
2169
2859
  .taskon-quest-eligs-sub-list li {
2170
2860
  font-size: 14px;
2171
2861
  line-height: 18px;
2172
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2862
+ color: var(--taskon-color-text-secondary);
2173
2863
  }
2174
2864
 
2175
- /* ============================================================================
2176
- Eligibility 响应式样式
2177
- ============================================================================ */
2178
-
2179
- @media (max-width: 750px) {
2865
+ @supports (container-type: inline-size) {
2866
+ @container (min-width: 751px) {
2180
2867
  .taskon-quest-eligs {
2181
- margin-top: 5.07vw;
2182
- padding: 0 4vw;
2868
+ margin-top: var(--taskon-spacing-lg);
2869
+ padding: 0 var(--taskon-spacing-md);
2870
+ }
2871
+
2872
+ .taskon-quest-eligs-list {
2873
+ padding: 20px 0;
2874
+ }
2875
+
2876
+ .taskon-quest-eligs-item + .taskon-quest-eligs-item {
2877
+ margin-top: var(--taskon-spacing-lg);
2183
2878
  }
2184
2879
 
2185
- .taskon-quest-eligs-header {
2186
- height: 12vw;
2187
- font-size: 3.47vw;
2188
- line-height: 4.4vw;
2880
+ .taskon-quest-eligs-item-icon,
2881
+ .taskon-quest-eligs-item-icon-placeholder {
2882
+ margin-top: var(--taskon-spacing-xs);
2883
+ margin-right: var(--taskon-spacing-sm);
2884
+ }
2885
+ }
2189
2886
  }
2190
2887
 
2191
- .taskon-quest-eligs-header-arrow {
2192
- width: 1.2vw;
2193
- height: 2.4vw;
2888
+ @supports not (container-type: inline-size) {
2889
+ @media (min-width: 751px) {
2890
+ .taskon-quest-eligs {
2891
+ margin-top: var(--taskon-spacing-lg);
2892
+ padding: 0 var(--taskon-spacing-md);
2194
2893
  }
2195
2894
 
2196
2895
  .taskon-quest-eligs-list {
2197
- padding: 3.73vw 0;
2896
+ padding: 20px 0;
2198
2897
  }
2199
2898
 
2200
2899
  .taskon-quest-eligs-item + .taskon-quest-eligs-item {
2201
- margin-top: 3.73vw;
2900
+ margin-top: var(--taskon-spacing-lg);
2202
2901
  }
2203
2902
 
2204
2903
  .taskon-quest-eligs-item-icon,
2205
2904
  .taskon-quest-eligs-item-icon-placeholder {
2206
- margin-top: 0.8vw;
2207
- margin-right: 1.87vw;
2208
- width: 3.2vw;
2209
- height: 3.2vw;
2905
+ margin-top: var(--taskon-spacing-xs);
2906
+ margin-right: var(--taskon-spacing-sm);
2210
2907
  }
2211
-
2212
- .taskon-quest-eligs-item-content {
2213
- font-size: 3.47vw;
2214
- line-height: 4.4vw;
2908
+ }
2215
2909
  }
2216
- }
2217
2910
 
2218
2911
  /* ============================================================================
2219
2912
  OnChainVerify Tooltip Styles
@@ -2228,11 +2921,11 @@
2228
2921
  display: inline;
2229
2922
  text-decoration: underline;
2230
2923
  cursor: pointer;
2231
- color: var(--taskon-quest-text-lightest, #ffffff);
2924
+ color: var(--taskon-color-text);
2232
2925
  }
2233
2926
 
2234
2927
  .taskon-quest-eligs-onchain-link:hover {
2235
- color: var(--taskon-quest-link, #58afff);
2928
+ color: var(--taskon-color-link);
2236
2929
  }
2237
2930
 
2238
2931
  .taskon-quest-eligs-onchain-tooltip {
@@ -2241,10 +2934,10 @@
2241
2934
  left: 0;
2242
2935
  min-width: 260px;
2243
2936
  padding: 12px 16px;
2244
- background-color: #222222;
2245
- border: 1px solid rgba(255, 255, 255, 0.1);
2246
- border-radius: var(--taskon-quest-radius-l, 8px);
2247
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
2937
+ background-color: var(--taskon-color-bg-surface);
2938
+ border: 1px solid var(--taskon-color-border);
2939
+ border-radius: var(--taskon-border-radius);
2940
+ box-shadow: 0 4px 16px var(--taskon-color-bg-mask);
2248
2941
  z-index: 100;
2249
2942
  font-size: 14px;
2250
2943
  line-height: 1.5;
@@ -2257,15 +2950,15 @@
2257
2950
  left: 16px;
2258
2951
  width: 12px;
2259
2952
  height: 12px;
2260
- background-color: #222222;
2261
- border-right: 1px solid rgba(255, 255, 255, 0.1);
2262
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
2953
+ background-color: var(--taskon-color-bg-surface);
2954
+ border-right: 1px solid var(--taskon-color-border);
2955
+ border-bottom: 1px solid var(--taskon-color-border);
2263
2956
  transform: rotate(45deg);
2264
2957
  }
2265
2958
 
2266
2959
  .taskon-quest-eligs-onchain-tooltip p {
2267
2960
  margin: 0 0 8px 0;
2268
- color: var(--taskon-quest-text-lighter, rgba(255, 255, 255, 0.8));
2961
+ color: var(--taskon-color-text-secondary);
2269
2962
  }
2270
2963
 
2271
2964
  .taskon-quest-eligs-onchain-tooltip ul {
@@ -2280,14 +2973,14 @@
2280
2973
  }
2281
2974
 
2282
2975
  .taskon-quest-eligs-onchain-tooltip-link {
2283
- color: var(--taskon-quest-link, #58afff);
2976
+ color: var(--taskon-color-link);
2284
2977
  text-decoration: underline;
2285
2978
  font-size: 14px;
2286
2979
  line-height: 18px;
2287
2980
  }
2288
2981
 
2289
2982
  .taskon-quest-eligs-onchain-tooltip-link:hover {
2290
- color: var(--taskon-quest-text-lightest, #ffffff);
2983
+ color: var(--taskon-color-text);
2291
2984
  }
2292
2985
 
2293
2986
  /* ============================================================================
@@ -2301,13 +2994,13 @@
2301
2994
  .taskon-quest-eligs-nft-name {
2302
2995
  position: relative;
2303
2996
  display: inline;
2304
- color: var(--taskon-quest-secondary, #1affab);
2997
+ color: var(--taskon-color-secondary);
2305
2998
  cursor: pointer;
2306
2999
  text-decoration: underline;
2307
3000
  }
2308
3001
 
2309
3002
  .taskon-quest-eligs-nft-name:hover {
2310
- color: var(--taskon-quest-link, #58afff);
3003
+ color: var(--taskon-color-link);
2311
3004
  }
2312
3005
 
2313
3006
  .taskon-quest-eligs-copied {
@@ -2316,10 +3009,10 @@
2316
3009
  left: 50%;
2317
3010
  transform: translateX(-50%);
2318
3011
  padding: 4px 8px;
2319
- background-color: #222222;
2320
- border-radius: var(--taskon-quest-radius-s, 4px);
3012
+ background-color: var(--taskon-color-bg-surface);
3013
+ border-radius: var(--taskon-border-radius-sm);
2321
3014
  font-size: 12px;
2322
- color: var(--taskon-quest-secondary, #1affab);
3015
+ color: var(--taskon-color-secondary);
2323
3016
  white-space: nowrap;
2324
3017
  pointer-events: none;
2325
3018
  animation: taskon-quest-eligs-fade-in 0.2s ease-out;