cacode commited on
Commit
36b4039
·
verified ·
1 Parent(s): cfce07c

Upload 67 files

Browse files
Files changed (2) hide show
  1. app/static/style.css +759 -1317
  2. app/templates/admin_activities.html +48 -52
app/static/style.css CHANGED
@@ -1,1320 +1,762 @@
1
- :root {
2
- --bg: #eef8ef;
3
- --bg-deep: #d7edd7;
4
- --surface: rgba(255, 255, 255, 0.75);
5
- --surface-strong: rgba(255, 255, 255, 0.9);
6
- --border: rgba(98, 146, 104, 0.22);
7
- --text: #173622;
8
- --muted: #5d7865;
9
- --primary: #4e9461;
10
- --primary-deep: #2e6a44;
11
- --primary-soft: #e6f4e5;
12
- --accent: #f6b85b;
13
- --danger: #d95b67;
14
- --shadow: 0 24px 70px rgba(53, 98, 62, 0.12);
15
- --radius-lg: 28px;
16
- --radius-md: 20px;
17
- --radius-sm: 14px;
18
- }
19
-
20
- * {
21
- box-sizing: border-box;
22
- }
23
-
24
- html {
25
- scroll-behavior: smooth;
26
- }
27
-
28
- body {
29
- margin: 0;
30
- font-family: "Segoe UI Variable", "PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif;
31
- color: var(--text);
32
- background: linear-gradient(180deg, #f5fbf2 0%, #e7f6e8 35%, #e1f0e0 100%);
33
- min-height: 100vh;
34
- }
35
-
36
- .page-backdrop {
37
- position: fixed;
38
- inset: 0;
39
- pointer-events: none;
40
- background:
41
- radial-gradient(circle at 12% 20%, rgba(246, 184, 91, 0.16), transparent 22%),
42
- radial-gradient(circle at 82% 14%, rgba(112, 188, 128, 0.18), transparent 20%),
43
- radial-gradient(circle at 50% 100%, rgba(120, 180, 139, 0.18), transparent 28%);
44
- }
45
-
46
- img {
47
- display: block;
48
- max-width: 100%;
49
- }
50
-
51
- .shell {
52
- position: relative;
53
- width: min(1200px, calc(100% - 32px));
54
- margin: 0 auto;
55
- padding: 28px 0 44px;
56
- }
57
-
58
- .content-shell {
59
- display: flex;
60
- flex-direction: column;
61
- gap: 24px;
62
- }
63
-
64
- .topbar {
65
- position: sticky;
66
- top: 18px;
67
- z-index: 20;
68
- display: flex;
69
- align-items: center;
70
- justify-content: space-between;
71
- gap: 20px;
72
- padding: 18px 22px;
73
- margin-bottom: 24px;
74
- border: 1px solid var(--border);
75
- border-radius: 999px;
76
- background: rgba(255, 255, 255, 0.7);
77
- backdrop-filter: blur(14px);
78
- box-shadow: var(--shadow);
79
- }
80
-
81
- .brand-block {
82
- display: flex;
83
- align-items: center;
84
- gap: 14px;
85
- }
86
-
87
- .brand-mark {
88
- width: 52px;
89
- height: 52px;
90
- display: grid;
91
- place-items: center;
92
- border-radius: 18px;
93
- background: linear-gradient(135deg, #63b67c, #88ca99);
94
- color: white;
95
- font-size: 1.4rem;
96
- font-weight: 700;
97
- box-shadow: 0 18px 26px rgba(76, 134, 91, 0.25);
98
- }
99
-
100
- .eyebrow {
101
- margin: 0 0 6px;
102
- color: var(--primary);
103
- font-size: 0.78rem;
104
- letter-spacing: 0.14em;
105
- text-transform: uppercase;
106
- }
107
-
108
- .brand-title,
109
- .hero-card h2,
110
- .glass-card h3,
111
- .login-copy h1,
112
- .login-panel h2 {
113
- margin: 0;
114
- font-family: "Georgia", "STKaiti", "KaiTi", serif;
115
- letter-spacing: 0.02em;
116
- }
117
-
118
- .topnav {
119
- display: flex;
120
- flex-wrap: wrap;
121
- justify-content: flex-end;
122
- gap: 10px;
123
- }
124
-
125
- .topnav a,
126
- .ghost-link {
127
- color: var(--primary-deep);
128
- text-decoration: none;
129
- padding: 10px 14px;
130
- border-radius: 999px;
131
- transition: transform 0.25s ease, background 0.25s ease, color 0.25s ease;
132
- }
133
-
134
- .topnav a:hover,
135
- .ghost-link:hover {
136
- background: rgba(78, 148, 97, 0.12);
137
- transform: translateY(-1px);
138
- }
139
-
140
- .hero-card,
141
- .glass-card,
142
- .login-panel,
143
- .login-copy {
144
- position: relative;
145
- overflow: hidden;
146
- border: 1px solid var(--border);
147
- border-radius: var(--radius-lg);
148
- background: linear-gradient(180deg, var(--surface-strong), var(--surface));
149
- backdrop-filter: blur(16px);
150
- box-shadow: var(--shadow);
151
- }
152
-
153
- .hero-card {
154
- display: flex;
155
- align-items: flex-start;
156
- justify-content: space-between;
157
- gap: 24px;
158
- padding: 30px;
159
- animation: rise-in 0.7s ease both;
160
- }
161
-
162
- .hero-card::after,
163
- .glass-card::after,
164
- .login-panel::after,
165
- .login-copy::after {
166
- content: "";
167
- position: absolute;
168
- inset: auto -12% -50% auto;
169
- width: 180px;
170
- height: 180px;
171
- border-radius: 50%;
172
- background: radial-gradient(circle, rgba(246, 184, 91, 0.18), transparent 70%);
173
- }
174
-
175
- .hero-badges,
176
- .chip-row,
177
- .feature-list,
178
- .action-grid,
179
- .task-status-row {
180
- display: flex;
181
- flex-wrap: wrap;
182
- gap: 10px;
183
- }
184
-
185
- .pill,
186
- .chip,
187
- .status-badge {
188
- display: inline-flex;
189
- align-items: center;
190
- gap: 8px;
191
- padding: 8px 12px;
192
- border-radius: 999px;
193
- font-size: 0.92rem;
194
- background: rgba(255, 255, 255, 0.72);
195
- border: 1px solid rgba(78, 148, 97, 0.16);
196
- }
197
-
198
- .status-approved {
199
- background: rgba(78, 148, 97, 0.14);
200
- color: var(--primary-deep);
201
- }
202
-
203
- .status-rejected {
204
- background: rgba(217, 91, 103, 0.14);
205
- color: #9b3144;
206
- }
207
-
208
- .lead,
209
- .muted,
210
- .mini-note,
211
- label span,
212
- .meta-grid span,
213
- .data-table th {
214
- color: var(--muted);
215
- }
216
-
217
- .lead {
218
- font-size: 1.02rem;
219
- line-height: 1.7;
220
- }
221
-
222
- .muted,
223
- .mini-note,
224
- .feedback-box {
225
- line-height: 1.6;
226
- }
227
-
228
- .flash-stack {
229
- display: grid;
230
- gap: 12px;
231
- margin-bottom: 20px;
232
- }
233
-
234
- .flash {
235
- display: flex;
236
- align-items: center;
237
- gap: 12px;
238
- padding: 14px 18px;
239
- border-radius: 18px;
240
- border: 1px solid var(--border);
241
- background: rgba(255, 255, 255, 0.85);
242
- box-shadow: 0 14px 34px rgba(88, 132, 95, 0.08);
243
- }
244
-
245
- .flash-dot {
246
- width: 10px;
247
- height: 10px;
248
- border-radius: 50%;
249
- background: var(--primary);
250
- }
251
-
252
- .flash-error .flash-dot {
253
- background: var(--danger);
254
- }
255
-
256
- .flash-success .flash-dot {
257
- background: #58a46b;
258
- }
259
-
260
- .flash p {
261
- margin: 0;
262
- }
263
-
264
- .card-grid,
265
- .stats-grid,
266
- .task-grid,
267
- .review-grid {
268
- display: grid;
269
- gap: 20px;
270
- }
271
-
272
- .activity-grid {
273
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
274
- }
275
-
276
- .group-grid,
277
- .review-grid {
278
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
279
- }
280
-
281
- .task-grid {
282
- grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
283
- }
284
-
285
- .stats-grid {
286
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
287
- }
288
-
289
- .page-grid,
290
- .two-column-layout {
291
- display: grid;
292
- grid-template-columns: minmax(280px, 360px) 1fr;
293
- gap: 22px;
294
- }
295
-
296
- .admin-activity-grid {
297
- grid-template-columns: 1.4fr 1fr;
298
- }
299
-
300
- .glass-card,
301
- .form-panel,
302
- .table-panel,
303
- .quick-panel {
304
- padding: 24px;
305
- animation: rise-in 0.7s ease both;
306
- }
307
-
308
- .activity-card h3,
309
- .task-card h3,
310
- .review-card h3,
311
- .group-card h3,
312
- .stat-card strong {
313
- margin: 0 0 10px;
314
- }
315
-
316
- .meta-grid {
317
- display: grid;
318
- grid-template-columns: repeat(2, minmax(0, 1fr));
319
- gap: 12px;
320
- margin: 18px 0;
321
- }
322
-
323
- .meta-grid div {
324
- padding: 12px 14px;
325
- border-radius: var(--radius-sm);
326
- background: rgba(255, 255, 255, 0.65);
327
- }
328
-
329
- .meta-grid strong {
330
- display: block;
331
- margin-top: 6px;
332
- }
333
-
334
- .progress-line {
335
- height: 9px;
336
- margin: 16px 0 14px;
337
- background: rgba(78, 148, 97, 0.12);
338
- border-radius: 999px;
339
- overflow: hidden;
340
- }
341
-
342
- .progress-line div {
343
- height: 100%;
344
- border-radius: inherit;
345
- background: linear-gradient(90deg, #62b176, #8ac798, #f1c16b);
346
- }
347
-
348
- .card-footer,
349
- .card-topline,
350
- .section-head,
351
- .stack-item,
352
- .builder-title-row {
353
- display: flex;
354
- align-items: center;
355
- justify-content: space-between;
356
- gap: 12px;
357
- }
358
-
359
- .section-head {
360
- margin-bottom: 18px;
361
- }
362
-
363
- .tight-head {
364
- margin-top: 8px;
365
- }
366
-
367
- .stack-list {
368
- display: grid;
369
- gap: 14px;
370
- }
371
-
372
- .stack-item {
373
- padding: 14px 16px;
374
- border-radius: 18px;
375
- background: rgba(255, 255, 255, 0.62);
376
- border: 1px solid rgba(78, 148, 97, 0.14);
377
- }
378
-
379
- .stack-item-block {
380
- align-items: flex-start;
381
- }
382
-
383
- .form-stack,
384
- .compact-form {
385
- display: grid;
386
- gap: 14px;
387
- }
388
-
389
- .form-grid {
390
- display: grid;
391
- gap: 14px;
392
- }
393
-
394
- .cols-2 {
395
- grid-template-columns: repeat(2, minmax(0, 1fr));
396
- }
397
-
398
- .cols-3 {
399
- grid-template-columns: repeat(3, minmax(0, 1fr));
400
- }
401
-
402
- .full-span {
403
- grid-column: 1 / -1;
404
- }
405
-
406
- label {
407
- display: grid;
408
- gap: 8px;
409
- }
410
-
411
- input,
412
- select,
413
- textarea,
414
- button {
415
- font: inherit;
416
- }
417
-
418
- input,
419
- select,
420
- textarea {
421
- width: 100%;
422
- padding: 14px 16px;
423
- border-radius: 16px;
424
- border: 1px solid rgba(91, 141, 99, 0.22);
425
- background: rgba(255, 255, 255, 0.88);
426
- color: var(--text);
427
- transition: border-color 0.24s ease, box-shadow 0.24s ease, transform 0.24s ease;
428
- }
429
-
430
- input:focus,
431
- select:focus,
432
- textarea:focus {
433
- outline: none;
434
- border-color: rgba(78, 148, 97, 0.5);
435
- box-shadow: 0 0 0 4px rgba(78, 148, 97, 0.12);
436
- transform: translateY(-1px);
437
- }
438
-
439
- textarea {
440
- resize: vertical;
441
- min-height: 120px;
442
- }
443
-
444
- .btn {
445
- display: inline-flex;
446
- align-items: center;
447
- justify-content: center;
448
- gap: 8px;
449
- padding: 12px 18px;
450
- border-radius: 999px;
451
- border: none;
452
- cursor: pointer;
453
- text-decoration: none;
454
- transition: transform 0.24s ease, box-shadow 0.24s ease, background 0.24s ease;
455
- }
456
-
457
- .btn:hover:not(:disabled) {
458
- transform: translateY(-2px);
459
- }
460
-
461
- .btn:disabled {
462
- opacity: 0.5;
463
- cursor: not-allowed;
464
- }
465
-
466
- .btn-primary {
467
- color: white;
468
- background: linear-gradient(135deg, #4c9460, #70ba80);
469
- box-shadow: 0 16px 28px rgba(76, 148, 96, 0.24);
470
- }
471
-
472
- .btn-secondary {
473
- color: var(--primary-deep);
474
- background: rgba(78, 148, 97, 0.14);
475
- }
476
-
477
- .btn-danger {
478
- color: white;
479
- background: linear-gradient(135deg, #cf5a68, #e57b84);
480
- }
481
-
482
- .btn-ghost,
483
- .full-width-btn {
484
- color: var(--primary-deep);
485
- background: rgba(255, 255, 255, 0.72);
486
- border: 1px solid rgba(78, 148, 97, 0.16);
487
- }
488
-
489
- .small-btn {
490
- padding: 10px 14px;
491
- font-size: 0.92rem;
492
- }
493
-
494
- .full-width-btn {
495
- width: 100%;
496
- }
497
-
498
- .login-body {
499
- display: grid;
500
- place-items: center;
501
- padding: 30px 16px;
502
- }
503
-
504
- .login-page {
505
- position: relative;
506
- display: grid;
507
- grid-template-columns: 1.1fr minmax(320px, 420px);
508
- width: min(1120px, 100%);
509
- gap: 24px;
510
- }
511
-
512
- .compact-login-page {
513
- grid-template-columns: 1fr minmax(320px, 420px);
514
- }
515
-
516
- .login-copy,
517
- .login-panel {
518
- padding: 34px;
519
- }
520
-
521
- .spring-copy {
522
- min-height: 520px;
523
- background:
524
- radial-gradient(circle at 16% 20%, rgba(255, 255, 255, 0.88), transparent 42%),
525
- linear-gradient(145deg, rgba(125, 195, 137, 0.22), rgba(246, 184, 91, 0.18));
526
- }
527
-
528
- .admin-copy {
529
- min-height: 420px;
530
- }
531
-
532
- .feature-list {
533
- margin-top: 26px;
534
- }
535
-
536
- .feature-list span,
537
- .info-box,
538
- .feedback-box {
539
- padding: 10px 14px;
540
- border-radius: 16px;
541
- background: rgba(255, 255, 255, 0.62);
542
- border: 1px solid rgba(78, 148, 97, 0.12);
543
- }
544
-
545
- .panel-glow {
546
- position: absolute;
547
- inset: auto auto -50px -30px;
548
- width: 140px;
549
- height: 140px;
550
- border-radius: 50%;
551
- background: radial-gradient(circle, rgba(246, 184, 91, 0.25), transparent 68%);
552
- }
553
-
554
- .task-card {
555
- display: flex;
556
- flex-direction: column;
557
- gap: 14px;
558
- }
559
-
560
- .task-card-head {
561
- display: flex;
562
- align-items: flex-start;
563
- justify-content: space-between;
564
- gap: 14px;
565
- }
566
-
567
- .task-description {
568
- min-height: 50px;
569
- }
570
-
571
- .task-media-wrap,
572
- .submission-preview {
573
- display: grid;
574
- gap: 10px;
575
- }
576
-
577
- .task-media,
578
- .submission-preview img,
579
- .review-image {
580
- width: 100%;
581
- aspect-ratio: 4 / 3;
582
- object-fit: cover;
583
- border-radius: 22px;
584
- border: 1px solid rgba(78, 148, 97, 0.16);
585
- box-shadow: 0 12px 30px rgba(86, 127, 93, 0.12);
586
- }
587
-
588
- .clue-toggle {
589
- width: 48px;
590
- height: 48px;
591
- display: grid;
592
- place-items: center;
593
- border: none;
594
- border-radius: 18px;
595
- font-size: 1.2rem;
596
- background: rgba(246, 184, 91, 0.14);
597
- color: #c88929;
598
- transition: transform 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
599
- }
600
-
601
- .clue-toggle.is-ready {
602
- background: rgba(246, 184, 91, 0.26);
603
- box-shadow: 0 14px 26px rgba(233, 173, 75, 0.22);
604
- }
605
-
606
- .clue-toggle.is-clue-view {
607
- transform: rotate(-10deg) scale(1.04);
608
- }
609
-
610
- .release-note {
611
- font-size: 0.88rem;
612
- color: var(--muted);
613
- }
614
-
615
- .upload-form,
616
- .inline-form {
617
- display: flex;
618
- flex-wrap: wrap;
619
- gap: 12px;
620
- align-items: end;
621
- }
622
-
623
- .inline-form-wide {
624
- flex-direction: column;
625
- align-items: stretch;
626
- }
627
-
628
- .visibility-form {
629
- justify-content: flex-end;
630
- }
631
-
632
- .upload-label {
633
- flex: 1 1 220px;
634
- }
635
-
636
- .feedback-box {
637
- color: var(--text);
638
- }
639
-
640
- .leaderboard-card {
641
- padding: 26px;
642
- }
643
-
644
- .rank-table-wrap,
645
- .table-shell {
646
- overflow-x: auto;
647
- }
648
-
649
- .rank-table,
650
- .data-table {
651
- width: 100%;
652
- border-collapse: collapse;
653
- }
654
-
655
- .rank-table th,
656
- .rank-table td,
657
- .data-table th,
658
- .data-table td {
659
- padding: 14px 12px;
660
- border-bottom: 1px solid rgba(78, 148, 97, 0.12);
661
- text-align: left;
662
- }
663
-
664
- .rank-table tbody tr:hover,
665
- .data-table tbody tr:hover {
666
- background: rgba(78, 148, 97, 0.05);
667
- }
668
-
669
- .stat-card {
670
- min-height: 130px;
671
- display: flex;
672
- flex-direction: column;
673
- justify-content: space-between;
674
- }
675
-
676
- .stat-card strong {
677
- font-size: 2rem;
678
- color: var(--primary-deep);
679
- }
680
-
681
- .info-box {
682
- margin-top: 18px;
683
- display: grid;
684
- gap: 12px;
685
- }
686
-
687
- .member-list {
688
- display: grid;
689
- gap: 10px;
690
- margin: 16px 0;
691
- }
692
-
693
- .member-row {
694
- display: flex;
695
- align-items: center;
696
- justify-content: space-between;
697
- gap: 12px;
698
- padding: 12px 14px;
699
- border-radius: 16px;
700
- background: rgba(255, 255, 255, 0.62);
701
- }
702
-
703
- .checkbox-row {
704
- display: inline-flex;
705
- align-items: center;
706
- gap: 10px;
707
- }
708
-
709
- .checkbox-row input {
710
- width: 18px;
711
- height: 18px;
712
- padding: 0;
713
- }
714
-
715
- .compact-checkbox {
716
- padding: 0;
717
- }
718
-
719
- .task-builder {
720
- display: grid;
721
- gap: 16px;
722
- }
723
-
724
- .task-builder-card {
725
- padding: 18px;
726
- border-radius: 22px;
727
- background: rgba(255, 255, 255, 0.64);
728
- border: 1px dashed rgba(78, 148, 97, 0.24);
729
- display: grid;
730
- gap: 14px;
731
- }
732
-
733
- .review-card {
734
- display: grid;
735
- gap: 14px;
736
- }
737
-
738
- .review-filter-form {
739
- align-items: end;
740
- }
741
-
742
- .review-filter-action {
743
- justify-content: end;
744
- }
745
-
746
- .empty-state {
747
- padding: 32px;
748
- border-radius: var(--radius-lg);
749
- background: rgba(255, 255, 255, 0.68);
750
- border: 1px dashed rgba(78, 148, 97, 0.24);
751
- text-align: center;
752
- }
753
-
754
- .pulse-highlight {
755
- animation: pulse-glow 1.8s ease;
756
- }
757
-
758
- @keyframes rise-in {
759
- from {
760
- opacity: 0;
761
- transform: translateY(18px);
762
- }
763
- to {
764
- opacity: 1;
765
- transform: translateY(0);
766
- }
767
- }
768
-
769
- @keyframes pulse-glow {
770
- 0% {
771
- box-shadow: var(--shadow);
772
- }
773
- 35% {
774
- box-shadow: 0 0 0 8px rgba(246, 184, 91, 0.18), var(--shadow);
775
- }
776
- 100% {
777
- box-shadow: var(--shadow);
778
- }
779
- }
780
-
781
- @media (max-width: 980px) {
782
- .topbar,
783
- .hero-card,
784
- .page-grid,
785
- .two-column-layout,
786
- .login-page,
787
- .compact-login-page,
788
- .admin-activity-grid {
789
- grid-template-columns: 1fr;
790
- flex-direction: column;
791
- }
792
-
793
- .topbar {
794
- border-radius: 28px;
795
- align-items: flex-start;
796
- }
797
-
798
- .topnav {
799
- width: 100%;
800
- justify-content: flex-start;
801
- }
802
-
803
- .login-copy {
804
- min-height: auto;
805
- }
806
- }
807
-
808
- @media (max-width: 720px) {
809
- .shell {
810
- width: min(100% - 20px, 1200px);
811
- padding-top: 18px;
812
- }
813
-
814
- .topbar,
815
- .hero-card,
816
- .glass-card,
817
- .login-copy,
818
- .login-panel {
819
- padding: 20px;
820
- }
821
-
822
- .cols-2,
823
- .cols-3,
824
- .meta-grid {
825
- grid-template-columns: 1fr;
826
- }
827
-
828
- .activity-grid,
829
- .task-grid,
830
- .group-grid,
831
- .review-grid,
832
- .stats-grid {
833
- grid-template-columns: 1fr;
834
- }
835
-
836
- .upload-form,
837
- .inline-form,
838
- .card-footer,
839
- .section-head,
840
- .stack-item,
841
- .builder-title-row,
842
- .task-card-head,
843
- .task-status-row {
844
- flex-direction: column;
845
- align-items: stretch;
846
- }
847
-
848
- .btn,
849
- .full-width-btn {
850
- width: 100%;
851
- }
852
- }
853
-
854
- .activity-actions,
855
- .task-editor-list {
856
- display: grid;
857
- gap: 14px;
858
- }
859
-
860
- .activity-catalog-panel {
861
- overflow: hidden;
862
- }
863
-
864
- .activity-catalog-head {
865
- margin-bottom: 20px;
866
- }
867
-
868
- .published-activity-list {
869
- display: grid;
870
- gap: 20px;
871
- }
872
-
873
- .published-activity-card {
874
- position: relative;
875
- display: grid;
876
- grid-template-columns: minmax(0, 1.55fr) minmax(290px, 0.9fr);
877
- gap: 22px;
878
- padding: 22px;
879
- border-radius: 30px;
880
- background:
881
- radial-gradient(circle at 100% 0%, rgba(241, 193, 107, 0.18), transparent 28%),
882
- linear-gradient(135deg, rgba(255, 255, 255, 0.92), rgba(236, 248, 239, 0.9));
883
- border: 1px solid rgba(78, 148, 97, 0.16);
884
- box-shadow: 0 20px 38px rgba(86, 127, 93, 0.12);
885
- }
886
-
887
- .published-activity-card::before {
888
- content: "";
889
- position: absolute;
890
- inset: 0 auto auto 24px;
891
- width: 110px;
892
- height: 5px;
893
- border-radius: 999px;
894
- background: linear-gradient(90deg, rgba(96, 175, 114, 0.9), rgba(241, 193, 107, 0.82));
895
- }
896
-
897
- .published-activity-main,
898
- .published-activity-side,
899
- .published-activity-form {
900
- display: grid;
901
- gap: 16px;
902
- }
903
-
904
- .published-activity-main {
905
- min-width: 0;
906
- align-content: start;
907
- }
908
-
909
- .published-activity-head {
910
- display: flex;
911
- align-items: flex-start;
912
- justify-content: space-between;
913
- gap: 16px;
914
- }
915
-
916
- .published-activity-title {
917
- margin: 4px 0 0;
918
- font-size: 1.8rem;
919
- line-height: 1.12;
920
- }
921
-
922
- .published-activity-badges {
923
- display: flex;
924
- flex-wrap: wrap;
925
- justify-content: flex-end;
926
- gap: 10px;
927
- }
928
-
929
- .published-activity-metrics,
930
- .published-activity-notes {
931
- display: grid;
932
- gap: 14px;
933
- }
934
-
935
- .published-activity-metrics {
936
- grid-template-columns: repeat(3, minmax(0, 1fr));
937
- }
938
-
939
- .published-activity-notes {
940
- grid-template-columns: repeat(2, minmax(0, 1fr));
941
- }
942
-
943
- .activity-metric-card,
944
- .activity-note-card {
945
- padding: 16px 18px;
946
- border-radius: 22px;
947
- border: 1px solid rgba(78, 148, 97, 0.12);
948
- }
949
-
950
- .activity-metric-card {
951
- background: rgba(255, 255, 255, 0.78);
952
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.68);
953
- }
954
-
955
- .activity-note-card {
956
- background: rgba(244, 250, 245, 0.88);
957
- }
958
-
959
- .activity-metric-card span,
960
- .activity-note-card span {
961
- display: block;
962
- font-size: 0.8rem;
963
- letter-spacing: 0.08em;
964
- text-transform: uppercase;
965
- color: var(--muted);
966
- }
967
-
968
- .activity-metric-card strong,
969
- .activity-note-card strong {
970
- display: block;
971
- margin-top: 8px;
972
- line-height: 1.45;
973
- color: var(--primary-deep);
974
- }
975
-
976
- .activity-metric-card strong {
977
- font-size: 1.02rem;
978
- }
979
-
980
- .published-activity-side {
981
- align-content: start;
982
- padding: 18px;
983
- border-radius: 26px;
984
- background: linear-gradient(180deg, rgba(247, 252, 248, 0.94), rgba(229, 244, 233, 0.88));
985
- border: 1px solid rgba(78, 148, 97, 0.14);
986
- }
987
-
988
- .published-activity-side .btn,
989
- .published-delete-form .btn {
990
- width: 100%;
991
- justify-content: center;
992
- }
993
-
994
- .published-toggle-row {
995
- display: flex;
996
- align-items: center;
997
- justify-content: space-between;
998
- gap: 14px;
999
- padding: 14px 16px;
1000
- border-radius: 20px;
1001
- background: rgba(255, 255, 255, 0.78);
1002
- border: 1px solid rgba(78, 148, 97, 0.12);
1003
- }
1004
-
1005
- .published-toggle-row > div {
1006
- display: grid;
1007
- gap: 4px;
1008
- }
1009
-
1010
- .published-toggle-row strong {
1011
- font-size: 1rem;
1012
- color: var(--primary-deep);
1013
- }
1014
-
1015
- .published-toggle-row span {
1016
- font-size: 0.88rem;
1017
- line-height: 1.45;
1018
- color: var(--muted);
1019
- }
1020
-
1021
- .published-toggle-row input {
1022
- width: 20px;
1023
- height: 20px;
1024
- padding: 0;
1025
- margin: 0;
1026
- flex: 0 0 auto;
1027
- }
1028
-
1029
- .task-editor-card {
1030
- gap: 16px;
1031
- }
1032
-
1033
- .editor-preview-grid {
1034
- display: grid;
1035
- grid-template-columns: repeat(2, minmax(0, 1fr));
1036
- gap: 16px;
1037
- }
1038
-
1039
- .editor-thumb,
1040
- .empty-thumb {
1041
- width: 100%;
1042
- aspect-ratio: 4 / 3;
1043
- object-fit: cover;
1044
- border-radius: 20px;
1045
- border: 1px solid rgba(78, 148, 97, 0.16);
1046
- background: rgba(255, 255, 255, 0.6);
1047
- }
1048
-
1049
- .empty-thumb {
1050
- display: grid;
1051
- place-items: center;
1052
- color: var(--muted);
1053
- }
1054
-
1055
- .align-end-checkbox {
1056
- align-self: end;
1057
- }
1058
-
1059
- @media (max-width: 720px) {
1060
- .editor-preview-grid {
1061
- grid-template-columns: 1fr;
1062
- }
1063
- }
1064
-
1065
- .users-admin-grid,
1066
- .presence-admin-grid,
1067
- .review-live-grid {
1068
- grid-template-columns: 1fr 1fr;
1069
- }
1070
-
1071
- .bulk-toolbar {
1072
- display: grid;
1073
- grid-template-columns: 1fr 1fr auto;
1074
- gap: 14px;
1075
- margin-bottom: 18px;
1076
- align-items: end;
1077
- }
1078
-
1079
- .leaderboard-hero {
1080
- align-items: stretch;
1081
- }
1082
-
1083
- .hero-split-main {
1084
- display: grid;
1085
- gap: 14px;
1086
- flex: 1 1 55%;
1087
- }
1088
-
1089
- .hero-side-rank {
1090
- width: min(420px, 100%);
1091
- padding: 18px 20px;
1092
- }
1093
-
1094
- .inset-rank-card {
1095
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(231, 248, 233, 0.82));
1096
- }
1097
-
1098
- .compact-head {
1099
- margin-bottom: 12px;
1100
- }
1101
-
1102
- .task-carousel-shell {
1103
- display: grid;
1104
- gap: 18px;
1105
- }
1106
-
1107
- .task-carousel-head {
1108
- display: flex;
1109
- align-items: center;
1110
- justify-content: space-between;
1111
- gap: 14px;
1112
- }
1113
-
1114
- .carousel-controls {
1115
- display: flex;
1116
- align-items: center;
1117
- gap: 10px;
1118
- }
1119
-
1120
- .task-flip-book {
1121
- position: relative;
1122
- min-height: 720px;
1123
- }
1124
-
1125
- .task-page {
1126
- position: absolute;
1127
- inset: 0;
1128
- opacity: 0;
1129
- pointer-events: none;
1130
- transform: perspective(1200px) rotateY(10deg) translateX(24px) scale(0.98);
1131
- transition: opacity 0.45s ease, transform 0.45s ease;
1132
- }
1133
-
1134
- .task-page.is-active {
1135
- opacity: 1;
1136
- pointer-events: auto;
1137
- transform: perspective(1200px) rotateY(0deg) translateX(0) scale(1);
1138
- z-index: 2;
1139
- }
1140
-
1141
- .task-page.is-left {
1142
- transform: perspective(1200px) rotateY(-12deg) translateX(-26px) scale(0.97);
1143
- }
1144
-
1145
- .task-page-inner {
1146
- display: grid;
1147
- gap: 18px;
1148
- }
1149
-
1150
- .task-page-grid {
1151
- display: grid;
1152
- grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
1153
- gap: 22px;
1154
- }
1155
-
1156
- .task-page-content {
1157
- display: grid;
1158
- gap: 14px;
1159
- align-content: start;
1160
- }
1161
-
1162
- .task-page-media {
1163
- display: grid;
1164
- gap: 12px;
1165
- }
1166
-
1167
- .is-hidden {
1168
- display: none !important;
1169
- }
1170
-
1171
- .clue-modal {
1172
- position: fixed;
1173
- inset: 0;
1174
- display: none;
1175
- align-items: center;
1176
- justify-content: center;
1177
- z-index: 50;
1178
- padding: 24px;
1179
- }
1180
-
1181
- .clue-modal.is-open {
1182
- display: flex;
1183
- }
1184
-
1185
- .clue-modal-backdrop {
1186
- position: absolute;
1187
- inset: 0;
1188
- background: linear-gradient(135deg, rgba(24, 57, 34, 0.78), rgba(76, 148, 97, 0.48), rgba(246, 184, 91, 0.42));
1189
- backdrop-filter: blur(16px);
1190
- }
1191
-
1192
- .clue-modal-dialog {
1193
- position: relative;
1194
- z-index: 1;
1195
- width: min(760px, 100%);
1196
- display: grid;
1197
- gap: 12px;
1198
- }
1199
-
1200
- .clue-close-btn {
1201
- justify-self: end;
1202
- }
1203
-
1204
- .clue-gradient-panel {
1205
- padding: 18px;
1206
- border-radius: 30px;
1207
- background: linear-gradient(145deg, rgba(255, 255, 255, 0.94), rgba(223, 245, 228, 0.86), rgba(255, 241, 214, 0.9));
1208
- box-shadow: 0 30px 90px rgba(20, 51, 29, 0.28);
1209
- }
1210
-
1211
- .clue-gradient-panel img {
1212
- width: 100%;
1213
- border-radius: 24px;
1214
- max-height: 72vh;
1215
- object-fit: contain;
1216
- background: rgba(255, 255, 255, 0.72);
1217
- }
1218
-
1219
- .review-live-grid .review-grid {
1220
- grid-template-columns: 1fr;
1221
- }
1222
-
1223
- .presence-item,
1224
- .activity-actions {
1225
- display: flex;
1226
- align-items: center;
1227
- justify-content: space-between;
1228
- gap: 12px;
1229
- }
1230
-
1231
- .inset-rank-card::after,
1232
- .hero-side-rank::after {
1233
- display: none;
1234
- }
1235
-
1236
- @media (max-width: 1080px) {
1237
- .leaderboard-hero,
1238
- .task-page-grid,
1239
- .users-admin-grid,
1240
- .presence-admin-grid,
1241
- .review-live-grid,
1242
- .published-activity-card {
1243
- grid-template-columns: 1fr;
1244
- }
1245
-
1246
- .hero-side-rank {
1247
- width: 100%;
1248
- }
1249
- }
1250
-
1251
- @media (max-width: 720px) {
1252
- .bulk-toolbar,
1253
- .task-carousel-head,
1254
- .carousel-controls,
1255
- .presence-item,
1256
- .activity-actions,
1257
- .published-activity-head,
1258
- .published-toggle-row {
1259
- grid-template-columns: 1fr;
1260
- flex-direction: column;
1261
- align-items: stretch;
1262
- }
1263
-
1264
- .published-activity-metrics,
1265
- .published-activity-notes {
1266
- grid-template-columns: 1fr;
1267
- }
1268
-
1269
- .published-activity-badges {
1270
- justify-content: flex-start;
1271
- }
1272
-
1273
- .task-flip-book {
1274
- min-height: 900px;
1275
- }
1276
- }
1277
-
1278
- .image-library-grid {
1279
- display: grid;
1280
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
1281
- gap: 18px;
1282
- }
1283
-
1284
- .image-library-card {
1285
- display: grid;
1286
- gap: 14px;
1287
- padding: 16px;
1288
- }
1289
-
1290
- .image-library-thumb {
1291
- width: 100%;
1292
- aspect-ratio: 4 / 3;
1293
- object-fit: cover;
1294
- border-radius: 22px;
1295
- background: rgba(255, 255, 255, 0.74);
1296
- border: 1px solid rgba(78, 148, 97, 0.14);
1297
- }
1298
-
1299
- .image-library-body {
1300
- display: grid;
1301
- gap: 12px;
1302
- }
1303
-
1304
- .image-library-path {
1305
- word-break: break-all;
1306
- }
1307
-
1308
- .image-library-actions {
1309
- align-items: center;
1310
- }
1311
-
1312
- .compact-stack-list {
1313
- gap: 8px;
1314
- }
1315
-
1316
- .compact-stack-item {
1317
- padding: 10px 12px;
1318
  }
1319
 
1320
 
 
1
+ :root {
2
+ --bg: #eef8ef;
3
+ --bg-deep: #d7edd7;
4
+ --surface: rgba(255, 255, 255, 0.75);
5
+ --surface-strong: rgba(255, 255, 255, 0.9);
6
+ --border: rgba(98, 146, 104, 0.22);
7
+ --text: #173622;
8
+ --muted: #5d7865;
9
+ --primary: #4e9461;
10
+ --primary-deep: #2e6a44;
11
+ --primary-soft: #e6f4e5;
12
+ --accent: #f6b85b;
13
+ --danger: #d95b67;
14
+ --shadow: 0 24px 70px rgba(53, 98, 62, 0.12);
15
+ --radius-lg: 28px;
16
+ --radius-md: 20px;
17
+ --radius-sm: 14px;
18
+ }
19
+
20
+ * {
21
+ box-sizing: border-box;
22
+ }
23
+
24
+ html {
25
+ scroll-behavior: smooth;
26
+ }
27
+
28
+ body {
29
+ margin: 0;
30
+ font-family: "Segoe UI Variable", "PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif;
31
+ color: var(--text);
32
+ background: linear-gradient(180deg, #f5fbf2 0%, #e7f6e8 35%, #e1f0e0 100%);
33
+ min-height: 100vh;
34
+ }
35
+
36
+ .page-backdrop {
37
+ position: fixed;
38
+ inset: 0;
39
+ pointer-events: none;
40
+ background:
41
+ radial-gradient(circle at 12% 20%, rgba(246, 184, 91, 0.16), transparent 22%),
42
+ radial-gradient(circle at 82% 14%, rgba(112, 188, 128, 0.18), transparent 20%),
43
+ radial-gradient(circle at 50% 100%, rgba(120, 180, 139, 0.18), transparent 28%);
44
+ }
45
+
46
+ img {
47
+ display: block;
48
+ max-width: 100%;
49
+ }
50
+
51
+ .shell {
52
+ position: relative;
53
+ width: min(1200px, calc(100% - 32px));
54
+ margin: 0 auto;
55
+ padding: 28px 0 44px;
56
+ }
57
+
58
+ .content-shell {
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 24px;
62
+ }
63
+
64
+ .topbar {
65
+ position: sticky;
66
+ top: 18px;
67
+ z-index: 20;
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: space-between;
71
+ gap: 20px;
72
+ padding: 18px 22px;
73
+ margin-bottom: 24px;
74
+ border: 1px solid var(--border);
75
+ border-radius: 999px;
76
+ background: rgba(255, 255, 255, 0.7);
77
+ backdrop-filter: blur(14px);
78
+ box-shadow: var(--shadow);
79
+ }
80
+
81
+ .brand-block {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 14px;
85
+ }
86
+
87
+ .brand-mark {
88
+ width: 52px;
89
+ height: 52px;
90
+ display: grid;
91
+ place-items: center;
92
+ border-radius: 18px;
93
+ background: linear-gradient(135deg, #63b67c, #88ca99);
94
+ color: white;
95
+ font-size: 1.4rem;
96
+ font-weight: 700;
97
+ box-shadow: 0 18px 26px rgba(76, 134, 91, 0.25);
98
+ }
99
+
100
+ .eyebrow {
101
+ margin: 0 0 6px;
102
+ color: var(--primary);
103
+ font-size: 0.78rem;
104
+ letter-spacing: 0.14em;
105
+ text-transform: uppercase;
106
+ }
107
+
108
+ .brand-title,
109
+ .hero-card h2,
110
+ .glass-card h3,
111
+ .login-copy h1,
112
+ .login-panel h2 {
113
+ margin: 0;
114
+ font-family: "Georgia", "STKaiti", "KaiTi", serif;
115
+ letter-spacing: 0.02em;
116
+ }
117
+
118
+ .topnav {
119
+ display: flex;
120
+ flex-wrap: wrap;
121
+ justify-content: flex-end;
122
+ gap: 10px;
123
+ }
124
+
125
+ .topnav a,
126
+ .ghost-link {
127
+ color: var(--primary-deep);
128
+ text-decoration: none;
129
+ padding: 10px 14px;
130
+ border-radius: 999px;
131
+ transition: transform 0.25s ease, background 0.25s ease, color 0.25s ease;
132
+ }
133
+
134
+ .topnav a:hover,
135
+ .ghost-link:hover {
136
+ background: rgba(78, 148, 97, 0.12);
137
+ transform: translateY(-1px);
138
+ }
139
+
140
+ .hero-card,
141
+ .glass-card,
142
+ .login-panel,
143
+ .login-copy {
144
+ position: relative;
145
+ overflow: hidden;
146
+ border: 1px solid var(--border);
147
+ border-radius: var(--radius-lg);
148
+ background: linear-gradient(180deg, var(--surface-strong), var(--surface));
149
+ backdrop-filter: blur(16px);
150
+ box-shadow: var(--shadow);
151
+ }
152
+
153
+ .hero-card {
154
+ display: flex;
155
+ align-items: flex-start;
156
+ justify-content: space-between;
157
+ gap: 24px;
158
+ padding: 30px;
159
+ animation: rise-in 0.7s ease both;
160
+ }
161
+
162
+ .hero-card::after,
163
+ .glass-card::after,
164
+ .login-panel::after,
165
+ .login-copy::after {
166
+ content: "";
167
+ position: absolute;
168
+ inset: auto -12% -50% auto;
169
+ width: 180px;
170
+ height: 180px;
171
+ border-radius: 50%;
172
+ background: radial-gradient(circle, rgba(246, 184, 91, 0.18), transparent 70%);
173
+ }
174
+
175
+ .hero-badges,
176
+ .chip-row,
177
+ .feature-list,
178
+ .action-grid,
179
+ .task-status-row {
180
+ display: flex;
181
+ flex-wrap: wrap;
182
+ gap: 10px;
183
+ }
184
+
185
+ .pill,
186
+ .chip,
187
+ .status-badge {
188
+ display: inline-flex;
189
+ align-items: center;
190
+ gap: 8px;
191
+ padding: 8px 12px;
192
+ border-radius: 999px;
193
+ font-size: 0.92rem;
194
+ background: rgba(255, 255, 255, 0.72);
195
+ border: 1px solid rgba(78, 148, 97, 0.16);
196
+ }
197
+
198
+ .status-approved {
199
+ background: rgba(78, 148, 97, 0.14);
200
+ color: var(--primary-deep);
201
+ }
202
+
203
+ .status-rejected {
204
+ background: rgba(217, 91, 103, 0.14);
205
+ color: #9b3144;
206
+ }
207
+
208
+ .lead,
209
+ .muted,
210
+ .mini-note,
211
+ label span,
212
+ .meta-grid span,
213
+ .data-table th {
214
+ color: var(--muted);
215
+ }
216
+
217
+ .lead {
218
+ font-size: 1.02rem;
219
+ line-height: 1.7;
220
+ }
221
+
222
+ .muted,
223
+ .mini-note,
224
+ .feedback-box {
225
+ line-height: 1.6;
226
+ }
227
+
228
+ .flash-stack {
229
+ display: grid;
230
+ gap: 12px;
231
+ margin-bottom: 20px;
232
+ }
233
+
234
+ .flash {
235
+ display: flex;
236
+ align-items: center;
237
+ gap: 12px;
238
+ padding: 14px 18px;
239
+ border-radius: 18px;
240
+ border: 1px solid var(--border);
241
+ background: rgba(255, 255, 255, 0.85);
242
+ box-shadow: 0 14px 34px rgba(88, 132, 95, 0.08);
243
+ }
244
+
245
+ .flash-dot {
246
+ width: 10px;
247
+ height: 10px;
248
+ border-radius: 50%;
249
+ background: var(--primary);
250
+ }
251
+
252
+ .flash-error .flash-dot {
253
+ background: var(--danger);
254
+ }
255
+
256
+ .flash-success .flash-dot {
257
+ background: #58a46b;
258
+ }
259
+
260
+ .flash p {
261
+ margin: 0;
262
+ }
263
+
264
+ .card-grid,
265
+ .stats-grid,
266
+ .task-grid,
267
+ .review-grid {
268
+ display: grid;
269
+ gap: 20px;
270
+ }
271
+
272
+ .activity-grid {
273
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
274
+ }
275
+
276
+ .group-grid,
277
+ .review-grid {
278
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
279
+ }
280
+
281
+ .task-grid {
282
+ grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
283
+ }
284
+
285
+ .stats-grid {
286
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
287
+ }
288
+
289
+ .page-grid,
290
+ .two-column-layout {
291
+ display: grid;
292
+ grid-template-columns: minmax(280px, 360px) 1fr;
293
+ gap: 22px;
294
+ }
295
+
296
+ .admin-activity-grid {
297
+ grid-template-columns: 1fr;
298
+ }
299
+
300
+ .activity-actions,
301
+ .task-editor-list {
302
+ display: grid;
303
+ gap: 14px;
304
+ }
305
+
306
+ .activity-catalog-panel {
307
+ overflow: hidden;
308
+ }
309
+
310
+ .activity-catalog-head {
311
+ margin-bottom: 20px;
312
+ }
313
+
314
+ .published-activity-list {
315
+ display: grid;
316
+ gap: 20px;
317
+ }
318
+
319
+ .published-activity-card {
320
+ position: relative;
321
+ display: grid;
322
+ gap: 18px;
323
+ padding: 24px;
324
+ border-radius: 30px;
325
+ background:
326
+ radial-gradient(circle at 100% 0%, rgba(241, 193, 107, 0.18), transparent 28%),
327
+ linear-gradient(135deg, rgba(255, 255, 255, 0.94), rgba(236, 248, 239, 0.9));
328
+ border: 1px solid rgba(78, 148, 97, 0.16);
329
+ box-shadow: 0 20px 38px rgba(86, 127, 93, 0.12);
330
+ }
331
+
332
+ .published-activity-card::before {
333
+ content: "";
334
+ position: absolute;
335
+ inset: 0 auto auto 24px;
336
+ width: 120px;
337
+ height: 5px;
338
+ border-radius: 999px;
339
+ background: linear-gradient(90deg, rgba(96, 175, 114, 0.9), rgba(241, 193, 107, 0.82));
340
+ }
341
+
342
+ .published-activity-hero,
343
+ .published-settings-form,
344
+ .published-delete-form,
345
+ .published-toggle-grid {
346
+ display: grid;
347
+ gap: 16px;
348
+ }
349
+
350
+ .published-activity-hero {
351
+ grid-template-columns: minmax(0, 1fr) auto;
352
+ align-items: start;
353
+ }
354
+
355
+ .published-activity-title-wrap {
356
+ min-width: 0;
357
+ }
358
+
359
+ .published-activity-title {
360
+ margin: 4px 0 0;
361
+ font-size: 1.8rem;
362
+ line-height: 1.1;
363
+ }
364
+
365
+ .published-activity-badges {
366
+ display: flex;
367
+ flex-wrap: wrap;
368
+ justify-content: flex-end;
369
+ gap: 10px;
370
+ }
371
+
372
+ .published-activity-metrics {
373
+ display: grid;
374
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
375
+ gap: 14px;
376
+ }
377
+
378
+ .activity-metric-card {
379
+ min-width: 0;
380
+ padding: 16px 18px;
381
+ border-radius: 22px;
382
+ border: 1px solid rgba(78, 148, 97, 0.12);
383
+ background: rgba(255, 255, 255, 0.8);
384
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.68);
385
+ }
386
+
387
+ .activity-metric-card span {
388
+ display: block;
389
+ font-size: 0.8rem;
390
+ letter-spacing: 0.08em;
391
+ text-transform: uppercase;
392
+ color: var(--muted);
393
+ }
394
+
395
+ .activity-metric-card strong {
396
+ display: block;
397
+ margin-top: 8px;
398
+ line-height: 1.45;
399
+ color: var(--primary-deep);
400
+ font-size: 1rem;
401
+ word-break: break-word;
402
+ }
403
+
404
+ .published-settings-form {
405
+ padding: 18px;
406
+ border-radius: 26px;
407
+ background: linear-gradient(180deg, rgba(247, 252, 248, 0.94), rgba(229, 244, 233, 0.88));
408
+ border: 1px solid rgba(78, 148, 97, 0.14);
409
+ }
410
+
411
+ .published-toggle-grid {
412
+ grid-template-columns: repeat(2, minmax(0, 1fr));
413
+ }
414
+
415
+ .published-toggle-card {
416
+ display: grid;
417
+ grid-template-columns: minmax(0, 1fr) auto;
418
+ align-items: center;
419
+ gap: 16px;
420
+ padding: 16px 18px;
421
+ border-radius: 22px;
422
+ background: rgba(255, 255, 255, 0.82);
423
+ border: 1px solid rgba(78, 148, 97, 0.12);
424
+ }
425
+
426
+ .published-toggle-copy {
427
+ display: grid;
428
+ gap: 6px;
429
+ min-width: 0;
430
+ }
431
+
432
+ .published-toggle-copy strong {
433
+ font-size: 1rem;
434
+ color: var(--primary-deep);
435
+ }
436
+
437
+ .published-toggle-copy span {
438
+ font-size: 0.9rem;
439
+ line-height: 1.5;
440
+ color: var(--muted);
441
+ }
442
+
443
+ .published-toggle-card input {
444
+ width: 20px;
445
+ height: 20px;
446
+ padding: 0;
447
+ margin: 0;
448
+ flex: 0 0 auto;
449
+ }
450
+
451
+ .published-action-row {
452
+ display: flex;
453
+ flex-wrap: wrap;
454
+ gap: 14px;
455
+ }
456
+
457
+ .published-action-row .btn {
458
+ flex: 1 1 220px;
459
+ justify-content: center;
460
+ }
461
+
462
+ .published-delete-form .btn {
463
+ width: 100%;
464
+ justify-content: center;
465
+ }
466
+
467
+ .task-editor-card {
468
+ gap: 16px;
469
+ }
470
+
471
+ .editor-preview-grid {
472
+ display: grid;
473
+ grid-template-columns: repeat(2, minmax(0, 1fr));
474
+ gap: 16px;
475
+ }
476
+
477
+ .editor-thumb,
478
+ .empty-thumb {
479
+ width: 100%;
480
+ aspect-ratio: 4 / 3;
481
+ object-fit: cover;
482
+ border-radius: 20px;
483
+ border: 1px solid rgba(78, 148, 97, 0.16);
484
+ background: rgba(255, 255, 255, 0.6);
485
+ }
486
+
487
+ .empty-thumb {
488
+ display: grid;
489
+ place-items: center;
490
+ color: var(--muted);
491
+ }
492
+
493
+ .align-end-checkbox {
494
+ align-self: end;
495
+ }
496
+
497
+ @media (max-width: 720px) {
498
+ .editor-preview-grid {
499
+ grid-template-columns: 1fr;
500
+ }
501
+ }
502
+
503
+ .users-admin-grid,
504
+ .presence-admin-grid,
505
+ .review-live-grid {
506
+ grid-template-columns: 1fr 1fr;
507
+ }
508
+
509
+ .bulk-toolbar {
510
+ display: grid;
511
+ grid-template-columns: 1fr 1fr auto;
512
+ gap: 14px;
513
+ margin-bottom: 18px;
514
+ align-items: end;
515
+ }
516
+
517
+ .leaderboard-hero {
518
+ align-items: stretch;
519
+ }
520
+
521
+ .hero-split-main {
522
+ display: grid;
523
+ gap: 14px;
524
+ flex: 1 1 55%;
525
+ }
526
+
527
+ .hero-side-rank {
528
+ width: min(420px, 100%);
529
+ padding: 18px 20px;
530
+ }
531
+
532
+ .inset-rank-card {
533
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.82), rgba(231, 248, 233, 0.82));
534
+ }
535
+
536
+ .compact-head {
537
+ margin-bottom: 12px;
538
+ }
539
+
540
+ .task-carousel-shell {
541
+ display: grid;
542
+ gap: 18px;
543
+ }
544
+
545
+ .task-carousel-head {
546
+ display: flex;
547
+ align-items: center;
548
+ justify-content: space-between;
549
+ gap: 14px;
550
+ }
551
+
552
+ .carousel-controls {
553
+ display: flex;
554
+ align-items: center;
555
+ gap: 10px;
556
+ }
557
+
558
+ .task-flip-book {
559
+ position: relative;
560
+ min-height: 720px;
561
+ }
562
+
563
+ .task-page {
564
+ position: absolute;
565
+ inset: 0;
566
+ opacity: 0;
567
+ pointer-events: none;
568
+ transform: perspective(1200px) rotateY(10deg) translateX(24px) scale(0.98);
569
+ transition: opacity 0.45s ease, transform 0.45s ease;
570
+ }
571
+
572
+ .task-page.is-active {
573
+ opacity: 1;
574
+ pointer-events: auto;
575
+ transform: perspective(1200px) rotateY(0deg) translateX(0) scale(1);
576
+ z-index: 2;
577
+ }
578
+
579
+ .task-page.is-left {
580
+ transform: perspective(1200px) rotateY(-12deg) translateX(-26px) scale(0.97);
581
+ }
582
+
583
+ .task-page-inner {
584
+ display: grid;
585
+ gap: 18px;
586
+ }
587
+
588
+ .task-page-grid {
589
+ display: grid;
590
+ grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
591
+ gap: 22px;
592
+ }
593
+
594
+ .task-page-content {
595
+ display: grid;
596
+ gap: 14px;
597
+ align-content: start;
598
+ }
599
+
600
+ .task-page-media {
601
+ display: grid;
602
+ gap: 12px;
603
+ }
604
+
605
+ .is-hidden {
606
+ display: none !important;
607
+ }
608
+
609
+ .clue-modal {
610
+ position: fixed;
611
+ inset: 0;
612
+ display: none;
613
+ align-items: center;
614
+ justify-content: center;
615
+ z-index: 50;
616
+ padding: 24px;
617
+ }
618
+
619
+ .clue-modal.is-open {
620
+ display: flex;
621
+ }
622
+
623
+ .clue-modal-backdrop {
624
+ position: absolute;
625
+ inset: 0;
626
+ background: linear-gradient(135deg, rgba(24, 57, 34, 0.78), rgba(76, 148, 97, 0.48), rgba(246, 184, 91, 0.42));
627
+ backdrop-filter: blur(16px);
628
+ }
629
+
630
+ .clue-modal-dialog {
631
+ position: relative;
632
+ z-index: 1;
633
+ width: min(760px, 100%);
634
+ display: grid;
635
+ gap: 12px;
636
+ }
637
+
638
+ .clue-close-btn {
639
+ justify-self: end;
640
+ }
641
+
642
+ .clue-gradient-panel {
643
+ padding: 18px;
644
+ border-radius: 30px;
645
+ background: linear-gradient(145deg, rgba(255, 255, 255, 0.94), rgba(223, 245, 228, 0.86), rgba(255, 241, 214, 0.9));
646
+ box-shadow: 0 30px 90px rgba(20, 51, 29, 0.28);
647
+ }
648
+
649
+ .clue-gradient-panel img {
650
+ width: 100%;
651
+ border-radius: 24px;
652
+ max-height: 72vh;
653
+ object-fit: contain;
654
+ background: rgba(255, 255, 255, 0.72);
655
+ }
656
+
657
+ .review-live-grid .review-grid {
658
+ grid-template-columns: 1fr;
659
+ }
660
+
661
+ .presence-item,
662
+ .activity-actions {
663
+ display: flex;
664
+ align-items: center;
665
+ justify-content: space-between;
666
+ gap: 12px;
667
+ }
668
+
669
+ .inset-rank-card::after,
670
+ .hero-side-rank::after {
671
+ display: none;
672
+ }
673
+
674
+ @media (max-width: 1080px) {
675
+ .leaderboard-hero,
676
+ .task-page-grid,
677
+ .users-admin-grid,
678
+ .presence-admin-grid,
679
+ .review-live-grid {
680
+ grid-template-columns: 1fr;
681
+ }
682
+
683
+ .published-toggle-grid {
684
+ grid-template-columns: 1fr;
685
+ }
686
+
687
+ .hero-side-rank {
688
+ width: 100%;
689
+ }
690
+ }
691
+
692
+ @media (max-width: 720px) {
693
+ .bulk-toolbar,
694
+ .task-carousel-head,
695
+ .carousel-controls,
696
+ .presence-item,
697
+ .activity-actions,
698
+ .published-activity-hero,
699
+ .published-toggle-card,
700
+ .published-action-row {
701
+ grid-template-columns: 1fr;
702
+ flex-direction: column;
703
+ align-items: stretch;
704
+ }
705
+
706
+ .published-activity-metrics,
707
+ .published-toggle-grid {
708
+ grid-template-columns: 1fr;
709
+ }
710
+
711
+ .published-activity-badges {
712
+ justify-content: flex-start;
713
+ }
714
+
715
+ .task-flip-book {
716
+ min-height: 900px;
717
+ }
718
+ }
719
+
720
+ .image-library-grid {
721
+ display: grid;
722
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
723
+ gap: 18px;
724
+ }
725
+
726
+ .image-library-card {
727
+ display: grid;
728
+ gap: 14px;
729
+ padding: 16px;
730
+ }
731
+
732
+ .image-library-thumb {
733
+ width: 100%;
734
+ aspect-ratio: 4 / 3;
735
+ object-fit: cover;
736
+ border-radius: 22px;
737
+ background: rgba(255, 255, 255, 0.74);
738
+ border: 1px solid rgba(78, 148, 97, 0.14);
739
+ }
740
+
741
+ .image-library-body {
742
+ display: grid;
743
+ gap: 12px;
744
+ }
745
+
746
+ .image-library-path {
747
+ word-break: break-all;
748
+ }
749
+
750
+ .image-library-actions {
751
+ align-items: center;
752
+ }
753
+
754
+ .compact-stack-list {
755
+ gap: 8px;
756
+ }
757
+
758
+ .compact-stack-item {
759
+ padding: 10px 12px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760
  }
761
 
762
 
app/templates/admin_activities.html CHANGED
@@ -85,85 +85,81 @@
85
  <div>
86
  <p class="eyebrow">Published Activities</p>
87
  <h3>已发布活动</h3>
88
- <p class="mini-note">活动信息、可见性开关和危险操作分展示,管理起来会更清晰。</p>
89
  </div>
90
  </div>
91
  <div class="published-activity-list">
92
  {% for activity in activities %}
93
  <article class="published-activity-card">
94
- <div class="published-activity-main">
95
- <div class="published-activity-head">
96
- <div>
97
- <p class="eyebrow">Activity {{ loop.index }}</p>
98
- <h3 class="published-activity-title">{{ activity.title }}</h3>
99
- </div>
100
- <div class="published-activity-badges">
101
- <span class="status-badge {% if activity.is_visible %}status-approved{% else %}status-rejected{% endif %}">
102
- {{ '活动可见' if activity.is_visible else '活动隐藏' }}
103
- </span>
104
- <span class="status-badge {% if activity.leaderboard_visible %}status-approved{% else %}status-rejected{% endif %}">
105
- {{ '排行可见' if activity.leaderboard_visible else '排行隐藏' }}
106
- </span>
107
- </div>
108
  </div>
109
-
110
- <div class="published-activity-metrics">
111
- <div class="activity-metric-card">
112
- <span>开始时间</span>
113
- <strong>{{ activity.start_at|datetime_local }}</strong>
114
- </div>
115
- <div class="activity-metric-card">
116
- <span>截止时间</span>
117
- <strong>{{ activity.deadline_at|datetime_local }}</strong>
118
- </div>
119
- <div class="activity-metric-card">
120
- <span>任务数量</span>
121
- <strong>{{ activity.tasks|length }} 个任务</strong>
122
- </div>
123
  </div>
 
124
 
125
- <div class="published-activity-notes">
126
- <div class="activity-note-card">
127
- <span>创建人</span>
128
- <strong>{{ activity.created_by.display_name }}</strong>
129
- </div>
130
- <div class="activity-note-card">
131
- <span>线索</span>
132
- <strong>{{ activity.clue_interval_minutes if activity.clue_interval_minutes is not none else '与活动开始同步' }}</strong>
133
- </div>
 
 
 
 
 
 
 
 
 
 
 
134
  </div>
135
  </div>
136
 
137
- <aside class="published-activity-side">
138
- <a class="btn btn-primary" href="/admin/activities/{{ activity.id }}/edit">编辑活动</a>
139
-
140
- <form method="post" action="/admin/activities/{{ activity.id }}/visibility" class="published-activity-form">
141
- <label class="published-toggle-row">
142
- <div>
143
  <strong>活动对用户可见</strong>
144
  <span>关闭后,用户端不会显示,也不能直接进入此活动。</span>
145
  </div>
146
  <input type="checkbox" name="is_visible" {% if activity.is_visible %}checked{% endif %} />
147
  </label>
148
- <label class="published-toggle-row">
149
- <div>
150
  <strong>排行榜对用户可见</strong>
151
  <span>管理员始终可见,这里只控制普通用户是否能看到排行榜。</span>
152
  </div>
153
  <input type="checkbox" name="leaderboard_visible" {% if activity.leaderboard_visible %}checked{% endif %} />
154
  </label>
 
 
 
155
  <button class="btn btn-secondary" type="submit">保存显示设置</button>
156
- </form>
 
157
 
158
- <form method="post" action="/admin/activities/{{ activity.id }}/delete" class="published-delete-form">
159
- <button class="btn btn-danger" type="submit" onclick="return confirm('确定删除这个活动吗?相关任务、审核记录和本地提交图片都会一并删除。');">删除活动</button>
160
- </form>
161
- </aside>
162
  </article>
163
  {% else %}
164
  <article class="empty-state">
165
  <h3>还没有活动</h3>
166
- <p>先在左侧发布一个活动,这里会自动整理成清晰的管理卡片。</p>
167
  </article>
168
  {% endfor %}
169
  </div>
 
85
  <div>
86
  <p class="eyebrow">Published Activities</p>
87
  <h3>已发布活动</h3>
88
+ <p class="mini-note">活动信息、显示设置和危险操作分展示,避免按钮和内容互相挤压。</p>
89
  </div>
90
  </div>
91
  <div class="published-activity-list">
92
  {% for activity in activities %}
93
  <article class="published-activity-card">
94
+ <div class="published-activity-hero">
95
+ <div class="published-activity-title-wrap">
96
+ <p class="eyebrow">Activity {{ loop.index }}</p>
97
+ <h3 class="published-activity-title">{{ activity.title }}</h3>
 
 
 
 
 
 
 
 
 
 
98
  </div>
99
+ <div class="published-activity-badges">
100
+ <span class="status-badge {% if activity.is_visible %}status-approved{% else %}status-rejected{% endif %}">
101
+ {{ '活动可见' if activity.is_visible else '活动隐藏' }}
102
+ </span>
103
+ <span class="status-badge {% if activity.leaderboard_visible %}status-approved{% else %}status-rejected{% endif %}">
104
+ {{ '排行可见' if activity.leaderboard_visible else '排行隐藏' }}
105
+ </span>
 
 
 
 
 
 
 
106
  </div>
107
+ </div>
108
 
109
+ <div class="published-activity-metrics">
110
+ <div class="activity-metric-card">
111
+ <span>开始时间</span>
112
+ <strong>{{ activity.start_at|datetime_local }}</strong>
113
+ </div>
114
+ <div class="activity-metric-card">
115
+ <span>截止时间</span>
116
+ <strong>{{ activity.deadline_at|datetime_local }}</strong>
117
+ </div>
118
+ <div class="activity-metric-card">
119
+ <span>任务数量</span>
120
+ <strong>{{ activity.tasks|length }} 个任务</strong>
121
+ </div>
122
+ <div class="activity-metric-card">
123
+ <span>创建人</span>
124
+ <strong>{{ activity.created_by.display_name }}</strong>
125
+ </div>
126
+ <div class="activity-metric-card">
127
+ <span>线索间隔</span>
128
+ <strong>{{ activity.clue_interval_minutes if activity.clue_interval_minutes is not none else '与活动开始同步' }}</strong>
129
  </div>
130
  </div>
131
 
132
+ <form method="post" action="/admin/activities/{{ activity.id }}/visibility" class="published-settings-form">
133
+ <div class="published-toggle-grid">
134
+ <label class="published-toggle-card">
135
+ <div class="published-toggle-copy">
 
 
136
  <strong>活动对用户可见</strong>
137
  <span>关闭后,用户端不会显示,也不能直接进入此活动。</span>
138
  </div>
139
  <input type="checkbox" name="is_visible" {% if activity.is_visible %}checked{% endif %} />
140
  </label>
141
+ <label class="published-toggle-card">
142
+ <div class="published-toggle-copy">
143
  <strong>排行榜对用户可见</strong>
144
  <span>管理员始终可见,这里只控制普通用户是否能看到排行榜。</span>
145
  </div>
146
  <input type="checkbox" name="leaderboard_visible" {% if activity.leaderboard_visible %}checked{% endif %} />
147
  </label>
148
+ </div>
149
+ <div class="published-action-row">
150
+ <a class="btn btn-primary" href="/admin/activities/{{ activity.id }}/edit">编辑活动</a>
151
  <button class="btn btn-secondary" type="submit">保存显示设置</button>
152
+ </div>
153
+ </form>
154
 
155
+ <form method="post" action="/admin/activities/{{ activity.id }}/delete" class="published-delete-form">
156
+ <button class="btn btn-danger" type="submit" onclick="return confirm('确定删除这个活动吗?相关任务、审核记录和本地提交图片都会一并删除。');">删除活动</button>
157
+ </form>
 
158
  </article>
159
  {% else %}
160
  <article class="empty-state">
161
  <h3>还没有活动</h3>
162
+ <p>先在上方发布一个活动,这里会自动整理成清晰的管理卡片。</p>
163
  </article>
164
  {% endfor %}
165
  </div>