langcoach 0.1.0 → 0.3.0

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.
@@ -0,0 +1,1729 @@
1
+ :root {
2
+ --bg: #f7f9fc;
3
+ --surface: #ffffff;
4
+ --surface-muted: #eef2f8;
5
+ --border: #d8e0ed;
6
+ --text: #161d2b;
7
+ --text-muted: #556178;
8
+ --primary: #1a56db;
9
+ --primary-hover: #1545b5;
10
+ --primary-soft: #e7effd;
11
+ --success: #0f7b4c;
12
+ --success-soft: #e3f6ed;
13
+ --warning: #b45309;
14
+ --danger: #c81e1e;
15
+ --danger-soft: #fde8e8;
16
+ --radius: 12px;
17
+ --shadow: 0 2px 10px rgba(15, 23, 42, 0.06);
18
+ }
19
+
20
+ @media (prefers-color-scheme: dark) {
21
+ :root {
22
+ --bg: #11151f;
23
+ --surface: #1b2232;
24
+ --surface-muted: #242d42;
25
+ --border: #323e59;
26
+ --text: #eef2f9;
27
+ --text-muted: #9da9c2;
28
+ --primary: #5b8def;
29
+ --primary-hover: #7aa4f5;
30
+ --primary-soft: #223254;
31
+ --success: #34d399;
32
+ --success-soft: #14382c;
33
+ --warning: #fbbf24;
34
+ --danger: #f87171;
35
+ --danger-soft: #3b1c22;
36
+ --shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
37
+ }
38
+ }
39
+
40
+ * {
41
+ box-sizing: border-box;
42
+ }
43
+
44
+ body {
45
+ margin: 0;
46
+ font: 400 14px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
47
+ background: var(--bg);
48
+ color: var(--text);
49
+ min-width: 280px;
50
+ }
51
+
52
+ .panel-shell {
53
+ display: flex;
54
+ flex-direction: column;
55
+ min-height: 100vh;
56
+ max-width: 520px;
57
+ margin: 0 auto;
58
+ }
59
+
60
+ .panel-header {
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: space-between;
64
+ padding: 12px 16px;
65
+ background: var(--surface);
66
+ border-bottom: 1px solid var(--border);
67
+ position: sticky;
68
+ top: 0;
69
+ z-index: 10;
70
+ }
71
+
72
+ .brand {
73
+ font-weight: 700;
74
+ font-size: 16px;
75
+ letter-spacing: -0.01em;
76
+ }
77
+
78
+ .header-pills {
79
+ display: flex;
80
+ gap: 8px;
81
+ align-items: center;
82
+ font-weight: 600;
83
+ font-size: 13px;
84
+ }
85
+
86
+ .pill {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ gap: 4px;
90
+ padding: 4px 10px;
91
+ border-radius: 999px;
92
+ background: var(--surface-muted);
93
+ }
94
+
95
+ .tab-bar {
96
+ display: grid;
97
+ grid-template-columns: repeat(6, 1fr);
98
+ gap: 4px;
99
+ padding: 6px 10px;
100
+ background: var(--surface);
101
+ border-bottom: 1px solid var(--border);
102
+ }
103
+
104
+ .tab-btn {
105
+ appearance: none;
106
+ border: none;
107
+ background: transparent;
108
+ color: var(--text-muted);
109
+ font: inherit;
110
+ font-size: 12px;
111
+ font-weight: 600;
112
+ padding: 8px 4px;
113
+ border-radius: 8px;
114
+ cursor: pointer;
115
+ text-align: center;
116
+ overflow-wrap: anywhere;
117
+ }
118
+
119
+ .tab-btn[aria-current="page"] {
120
+ background: var(--primary-soft);
121
+ color: var(--primary);
122
+ }
123
+
124
+ .panel-main {
125
+ flex: 1;
126
+ padding: 16px;
127
+ display: flex;
128
+ flex-direction: column;
129
+ gap: 14px;
130
+ }
131
+
132
+ .card {
133
+ background: var(--surface);
134
+ border: 1px solid var(--border);
135
+ border-radius: var(--radius);
136
+ padding: 14px;
137
+ box-shadow: var(--shadow);
138
+ }
139
+
140
+ h1, h2, h3 {
141
+ margin: 0 0 6px;
142
+ line-height: 1.25;
143
+ }
144
+
145
+ h1 { font-size: 18px; }
146
+ h2 { font-size: 15px; }
147
+ h3 { font-size: 14px; }
148
+
149
+ .muted {
150
+ color: var(--text-muted);
151
+ font-size: 13px;
152
+ margin: 0;
153
+ }
154
+
155
+ .form-grid {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: 12px;
159
+ }
160
+
161
+ .field {
162
+ display: flex;
163
+ flex-direction: column;
164
+ gap: 4px;
165
+ }
166
+
167
+ .field label {
168
+ font-weight: 600;
169
+ font-size: 13px;
170
+ }
171
+
172
+ .field-row {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 8px;
176
+ }
177
+
178
+ select, input[type="text"], input[type="time"] {
179
+ width: 100%;
180
+ padding: 8px 10px;
181
+ border-radius: 8px;
182
+ border: 1px solid var(--border);
183
+ background: var(--surface);
184
+ color: var(--text);
185
+ font: inherit;
186
+ }
187
+
188
+ button {
189
+ font: inherit;
190
+ font-weight: 600;
191
+ border-radius: 8px;
192
+ padding: 8px 12px;
193
+ cursor: pointer;
194
+ border: 1px solid var(--border);
195
+ background: var(--surface-muted);
196
+ color: var(--text);
197
+ }
198
+
199
+ button.primary {
200
+ background: var(--primary);
201
+ color: #ffffff;
202
+ border-color: var(--primary);
203
+ }
204
+
205
+ button.primary:hover {
206
+ background: var(--primary-hover);
207
+ }
208
+
209
+ button.danger {
210
+ background: var(--danger-soft);
211
+ color: var(--danger);
212
+ border-color: var(--danger);
213
+ }
214
+
215
+ button:focus-visible, select:focus-visible, input:focus-visible {
216
+ outline: 3px solid var(--primary);
217
+ outline-offset: 2px;
218
+ }
219
+
220
+ .today-summary {
221
+ display: flex;
222
+ align-items: center;
223
+ justify-content: space-between;
224
+ gap: 12px;
225
+ }
226
+
227
+ .ring-badge {
228
+ display: inline-flex;
229
+ align-items: center;
230
+ justify-content: center;
231
+ min-width: 56px;
232
+ height: 56px;
233
+ border-radius: 50%;
234
+ border: 4px solid var(--primary);
235
+ font-weight: 700;
236
+ font-size: 15px;
237
+ }
238
+
239
+ .task-list {
240
+ display: flex;
241
+ flex-direction: column;
242
+ gap: 8px;
243
+ list-style: none;
244
+ padding: 0;
245
+ margin: 0;
246
+ }
247
+
248
+ .task-item {
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: space-between;
252
+ gap: 10px;
253
+ padding: 10px 12px;
254
+ border-radius: 10px;
255
+ border: 1px solid var(--border);
256
+ background: var(--surface);
257
+ }
258
+
259
+ .task-item.done {
260
+ background: var(--success-soft);
261
+ border-color: var(--success);
262
+ }
263
+
264
+ .theme-chip {
265
+ display: flex;
266
+ flex-direction: column;
267
+ gap: 8px;
268
+ }
269
+
270
+ .theme-actions {
271
+ display: flex;
272
+ gap: 8px;
273
+ flex-wrap: wrap;
274
+ }
275
+
276
+ .flashcard {
277
+ display: flex;
278
+ flex-direction: column;
279
+ gap: 12px;
280
+ padding: 18px;
281
+ min-height: 180px;
282
+ }
283
+
284
+ .card-term {
285
+ font-size: 24px;
286
+ font-weight: 700;
287
+ overflow-wrap: anywhere;
288
+ }
289
+
290
+ .card-pron {
291
+ font-size: 14px;
292
+ color: var(--text-muted);
293
+ }
294
+
295
+ .card-back {
296
+ border-top: 1px solid var(--border);
297
+ padding-top: 12px;
298
+ display: flex;
299
+ flex-direction: column;
300
+ gap: 8px;
301
+ }
302
+
303
+ .rating-grid {
304
+ display: grid;
305
+ grid-template-columns: repeat(4, 1fr);
306
+ gap: 6px;
307
+ }
308
+
309
+ .stats-grid {
310
+ display: grid;
311
+ grid-template-columns: repeat(2, 1fr);
312
+ gap: 10px;
313
+ }
314
+
315
+ .stat-box {
316
+ padding: 12px;
317
+ border-radius: 10px;
318
+ border: 1px solid var(--border);
319
+ background: var(--surface);
320
+ }
321
+
322
+ .stat-value {
323
+ font-size: 20px;
324
+ font-weight: 700;
325
+ }
326
+
327
+ .ach-grid {
328
+ display: grid;
329
+ grid-template-columns: repeat(2, 1fr);
330
+ gap: 8px;
331
+ }
332
+
333
+ .ach-item {
334
+ padding: 10px;
335
+ border-radius: 10px;
336
+ border: 1px solid var(--border);
337
+ background: var(--surface-muted);
338
+ opacity: 0.7;
339
+ }
340
+
341
+ .ach-item.unlocked {
342
+ background: var(--success-soft);
343
+ border-color: var(--success);
344
+ opacity: 1;
345
+ }
346
+
347
+ .progress-bar {
348
+ height: 8px;
349
+ border-radius: 999px;
350
+ background: var(--surface-muted);
351
+ overflow: hidden;
352
+ margin-top: 6px;
353
+ }
354
+
355
+ .progress-fill {
356
+ height: 100%;
357
+ background: var(--primary);
358
+ }
359
+
360
+ /* Segmented control (List vs Cards toggle) */
361
+ .segmented-control {
362
+ display: grid;
363
+ grid-template-columns: 1fr 1fr;
364
+ gap: 4px;
365
+ background: var(--surface-muted);
366
+ padding: 4px;
367
+ border-radius: 10px;
368
+ border: 1px solid var(--border);
369
+ }
370
+
371
+ .segmented-btn {
372
+ background: transparent;
373
+ color: var(--text-muted);
374
+ border: none;
375
+ border-radius: 8px;
376
+ padding: 8px;
377
+ font-weight: 600;
378
+ cursor: pointer;
379
+ transition: all 0.15s ease;
380
+ }
381
+
382
+ .segmented-btn:hover {
383
+ color: var(--text);
384
+ background: rgba(0, 0, 0, 0.04);
385
+ }
386
+
387
+ .segmented-btn.active {
388
+ background: var(--surface);
389
+ color: var(--text);
390
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
391
+ }
392
+
393
+ /* Vocabulary List View */
394
+ .vocab-section {
395
+ padding: 12px;
396
+ }
397
+
398
+ .vocab-list {
399
+ display: flex;
400
+ flex-direction: column;
401
+ gap: 10px;
402
+ }
403
+
404
+ .vocab-item {
405
+ padding: 12px;
406
+ border-radius: 10px;
407
+ border: 1px solid var(--border);
408
+ background: var(--surface-muted);
409
+ display: flex;
410
+ flex-direction: column;
411
+ gap: 6px;
412
+ }
413
+
414
+ .vocab-row {
415
+ display: flex;
416
+ align-items: center;
417
+ justify-content: space-between;
418
+ gap: 8px;
419
+ }
420
+
421
+ .vocab-term-group {
422
+ display: flex;
423
+ align-items: center;
424
+ gap: 8px;
425
+ flex-wrap: wrap;
426
+ }
427
+
428
+ .vocab-term {
429
+ font-size: 16px;
430
+ font-weight: 700;
431
+ color: var(--text);
432
+ }
433
+
434
+ .status-tag {
435
+ font-size: 11px;
436
+ font-weight: 600;
437
+ padding: 2px 8px;
438
+ border-radius: 999px;
439
+ border: 1px solid var(--border);
440
+ }
441
+
442
+ .status-tag.learned {
443
+ background: var(--success-soft);
444
+ color: var(--success);
445
+ border-color: var(--success);
446
+ }
447
+
448
+ .status-tag.new {
449
+ background: var(--primary-soft);
450
+ color: var(--primary);
451
+ border-color: var(--primary);
452
+ }
453
+
454
+ .vocab-trans-row {
455
+ display: flex;
456
+ align-items: center;
457
+ justify-content: space-between;
458
+ gap: 8px;
459
+ padding: 4px 0;
460
+ }
461
+
462
+ .vocab-trans {
463
+ font-size: 14px;
464
+ font-weight: 500;
465
+ color: var(--text);
466
+ }
467
+
468
+ .vocab-meanings,
469
+ .card-meanings {
470
+ display: flex;
471
+ flex-direction: column;
472
+ gap: 2px;
473
+ min-width: 0;
474
+ }
475
+
476
+ .vocab-native {
477
+ font-size: 14px;
478
+ font-weight: 600;
479
+ color: var(--text);
480
+ }
481
+
482
+ .vocab-trans.secondary {
483
+ font-size: 12px;
484
+ font-weight: 400;
485
+ color: var(--text-muted);
486
+ }
487
+
488
+ .native-banner progress {
489
+ width: 100%;
490
+ }
491
+
492
+ .btn-subtle {
493
+ background: transparent;
494
+ border: none;
495
+ color: var(--primary);
496
+ font-size: 12px;
497
+ font-weight: 600;
498
+ cursor: pointer;
499
+ padding: 2px 6px;
500
+ border-radius: 6px;
501
+ }
502
+
503
+ .btn-subtle:hover {
504
+ background: var(--primary-soft);
505
+ }
506
+
507
+ .vocab-example {
508
+ font-size: 12px;
509
+ font-style: italic;
510
+ padding-left: 8px;
511
+ border-left: 2px solid var(--border);
512
+ }
513
+
514
+ .vocab-footer {
515
+ display: flex;
516
+ justify-content: flex-end;
517
+ margin-top: 4px;
518
+ }
519
+
520
+ .btn-sm {
521
+ font-size: 12px;
522
+ padding: 4px 10px;
523
+ border-radius: 6px;
524
+ }
525
+
526
+ .icon-btn {
527
+ background: transparent;
528
+ border: none;
529
+ font-size: 14px;
530
+ cursor: pointer;
531
+ padding: 2px 4px;
532
+ border-radius: 4px;
533
+ }
534
+
535
+ .icon-btn:hover {
536
+ background: var(--surface);
537
+ }
538
+
539
+ .error-text {
540
+ margin: 0;
541
+ color: var(--danger);
542
+ font-weight: 600;
543
+ }
544
+
545
+ .notice {
546
+ margin: 0;
547
+ padding: 8px 10px;
548
+ border-radius: 8px;
549
+ background: var(--surface-muted);
550
+ }
551
+
552
+ .notice.error {
553
+ background: var(--danger-soft);
554
+ color: var(--danger);
555
+ }
556
+
557
+ .confirm-box {
558
+ display: grid;
559
+ gap: 8px;
560
+ padding: 10px;
561
+ border: 1px solid var(--danger);
562
+ border-radius: 8px;
563
+ background: var(--danger-soft);
564
+ }
565
+
566
+ .mono {
567
+ font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
568
+ word-break: break-all;
569
+ }
570
+
571
+ /* ---------- Practice ---------- */
572
+ :root {
573
+ --px-green: #16a34a;
574
+ --px-green-soft: #dcfce7;
575
+ --px-green-ink: #14532d;
576
+ --px-red: #dc2626;
577
+ --px-red-soft: #fee2e2;
578
+ --px-red-ink: #7f1d1d;
579
+ --px-amber: #b45309;
580
+ --px-amber-soft: #fef3c7;
581
+ --px-amber-ink: #78350f;
582
+ --px-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
583
+ }
584
+
585
+ @media (prefers-color-scheme: dark) {
586
+ :root {
587
+ --px-green: #4ade80;
588
+ --px-green-soft: #12301f;
589
+ --px-green-ink: #bbf7d0;
590
+ --px-red: #f87171;
591
+ --px-red-soft: #3b1719;
592
+ --px-red-ink: #fecaca;
593
+ --px-amber: #fbbf24;
594
+ --px-amber-soft: #3a2a0c;
595
+ --px-amber-ink: #fde68a;
596
+ }
597
+ }
598
+
599
+ .practice-host[hidden] {
600
+ display: none;
601
+ }
602
+
603
+ .practice-cta {
604
+ display: flex;
605
+ align-items: center;
606
+ gap: 12px;
607
+ width: 100%;
608
+ min-height: 64px;
609
+ padding: 12px 16px;
610
+ border: none;
611
+ border-radius: 16px;
612
+ background: linear-gradient(135deg, #1a56db, #7c3aed);
613
+ color: #fff;
614
+ text-align: start;
615
+ box-shadow: 0 4px 0 rgba(0, 0, 0, 0.18);
616
+ transition: transform 150ms var(--px-ease), box-shadow 150ms var(--px-ease);
617
+ }
618
+ .practice-cta:hover {
619
+ transform: translateY(-1px);
620
+ }
621
+ .practice-cta:active {
622
+ transform: translateY(3px);
623
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.18);
624
+ }
625
+ .practice-cta-icon {
626
+ font-size: 28px;
627
+ }
628
+ .practice-cta-text {
629
+ display: flex;
630
+ flex-direction: column;
631
+ flex: 1;
632
+ gap: 2px;
633
+ }
634
+ .practice-cta-text strong {
635
+ font-size: 16px;
636
+ }
637
+ .practice-cta-text span {
638
+ font-weight: 500;
639
+ opacity: 0.92;
640
+ font-size: 13px;
641
+ }
642
+ .practice-cta-arrow {
643
+ font-size: 20px;
644
+ }
645
+
646
+ .px-start,
647
+ .px-end,
648
+ .px-empty {
649
+ display: flex;
650
+ flex-direction: column;
651
+ align-items: center;
652
+ text-align: center;
653
+ gap: 12px;
654
+ padding: 22px 18px;
655
+ border-radius: 18px;
656
+ position: relative;
657
+ overflow: hidden;
658
+ }
659
+ .px-hero,
660
+ .px-empty-icon {
661
+ font-size: 44px;
662
+ line-height: 1;
663
+ animation: px-pop 320ms var(--px-ease) both;
664
+ }
665
+ .px-stats,
666
+ .px-end-stats {
667
+ display: grid;
668
+ grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
669
+ gap: 10px;
670
+ width: 100%;
671
+ }
672
+ .px-stat,
673
+ .px-end-stat {
674
+ display: flex;
675
+ flex-direction: column;
676
+ gap: 2px;
677
+ padding: 10px 8px;
678
+ border-radius: 14px;
679
+ background: var(--surface-muted);
680
+ }
681
+ .px-stat strong,
682
+ .px-end-stat strong {
683
+ font-size: 24px;
684
+ line-height: 1.1;
685
+ }
686
+ .px-end-stat.xp strong {
687
+ color: var(--px-amber);
688
+ }
689
+ .px-end-stat .muted,
690
+ .px-stat .muted {
691
+ font-size: 12px;
692
+ }
693
+ .px-desc {
694
+ margin: 0;
695
+ max-width: 34ch;
696
+ }
697
+ .px-kinds {
698
+ list-style: none;
699
+ margin: 0;
700
+ padding: 0;
701
+ display: flex;
702
+ flex-wrap: wrap;
703
+ justify-content: center;
704
+ gap: 6px;
705
+ }
706
+ .px-kinds li {
707
+ font-size: 12px;
708
+ font-weight: 600;
709
+ padding: 4px 10px;
710
+ border-radius: 999px;
711
+ background: var(--primary-soft);
712
+ color: var(--primary);
713
+ }
714
+ .px-big-btn {
715
+ width: 100%;
716
+ min-height: 48px;
717
+ font-size: 16px;
718
+ border-radius: 14px;
719
+ box-shadow: 0 4px 0 rgba(0, 0, 0, 0.15);
720
+ transition: transform 150ms var(--px-ease), box-shadow 150ms var(--px-ease), background 150ms;
721
+ }
722
+ .px-big-btn:active:not(:disabled) {
723
+ transform: translateY(3px);
724
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.15);
725
+ }
726
+ /* Focused by script (tabindex=-1) so it is announced; no ring unless the keyboard put it there. */
727
+ .px-end-title:focus:not(:focus-visible) {
728
+ outline: none;
729
+ }
730
+ .px-end-actions {
731
+ display: grid;
732
+ gap: 10px;
733
+ width: 100%;
734
+ }
735
+ .px-goal {
736
+ display: flex;
737
+ align-items: center;
738
+ gap: 12px;
739
+ width: 100%;
740
+ padding: 10px 12px;
741
+ border-radius: 14px;
742
+ background: var(--surface-muted);
743
+ text-align: start;
744
+ }
745
+ .goal-ring-track {
746
+ fill: none;
747
+ stroke: var(--border);
748
+ }
749
+ .goal-ring-fill {
750
+ fill: none;
751
+ stroke: var(--primary);
752
+ stroke-linecap: round;
753
+ transition: stroke-dashoffset 600ms var(--px-ease);
754
+ }
755
+ .goal-ring.is-met .goal-ring-fill {
756
+ stroke: var(--px-green);
757
+ }
758
+ .goal-ring {
759
+ position: relative;
760
+ flex: none;
761
+ display: inline-grid;
762
+ place-items: center;
763
+ }
764
+ .goal-ring svg {
765
+ position: absolute;
766
+ inset: 0;
767
+ }
768
+ .goal-ring-text {
769
+ position: relative;
770
+ font-size: 12px;
771
+ font-weight: 800;
772
+ color: var(--text);
773
+ }
774
+ .goal-ring.is-met .goal-ring-text {
775
+ color: var(--px-green, var(--success));
776
+ }
777
+
778
+ /* run */
779
+ .px-run {
780
+ display: flex;
781
+ flex-direction: column;
782
+ gap: 12px;
783
+ /* room for the feedback sheet, so nothing jumps when it opens */
784
+ padding-bottom: 190px;
785
+ }
786
+ .px-top {
787
+ display: flex;
788
+ align-items: center;
789
+ gap: 10px;
790
+ min-height: 44px;
791
+ }
792
+ .px-quit {
793
+ min-width: 44px;
794
+ min-height: 44px;
795
+ font-size: 18px;
796
+ color: var(--text-muted);
797
+ }
798
+ .px-progress {
799
+ flex: 1;
800
+ height: 14px;
801
+ border-radius: 999px;
802
+ background: var(--surface-muted);
803
+ overflow: hidden;
804
+ }
805
+ .px-progress-fill {
806
+ height: 100%;
807
+ border-radius: 999px;
808
+ background: linear-gradient(90deg, var(--px-green), #22c55e);
809
+ transition: width 250ms var(--px-ease);
810
+ }
811
+ .px-combo {
812
+ font-size: 12px;
813
+ font-weight: 700;
814
+ color: var(--px-amber);
815
+ white-space: nowrap;
816
+ }
817
+ .px-combo.is-on {
818
+ animation: px-pop 250ms var(--px-ease) both;
819
+ }
820
+ .px-retry-tag {
821
+ margin: 0;
822
+ align-self: flex-start;
823
+ font-size: 12px;
824
+ font-weight: 700;
825
+ color: var(--px-amber-ink);
826
+ background: var(--px-amber-soft);
827
+ padding: 3px 10px;
828
+ border-radius: 999px;
829
+ }
830
+ .px-card {
831
+ border-radius: 18px;
832
+ padding: 18px 16px;
833
+ min-height: 360px;
834
+ animation: px-in 220ms var(--px-ease) both;
835
+ }
836
+ .ex {
837
+ display: flex;
838
+ flex-direction: column;
839
+ gap: 14px;
840
+ }
841
+ .ex-ask {
842
+ margin: 0;
843
+ font-weight: 700;
844
+ font-size: 15px;
845
+ color: var(--text-muted);
846
+ }
847
+ .ex-prompt {
848
+ display: flex;
849
+ flex-direction: column;
850
+ align-items: center;
851
+ gap: 4px;
852
+ min-height: 84px;
853
+ justify-content: center;
854
+ text-align: center;
855
+ }
856
+ .prompt-row {
857
+ display: flex;
858
+ align-items: center;
859
+ gap: 8px;
860
+ }
861
+ .prompt-term {
862
+ font-size: 28px;
863
+ font-weight: 800;
864
+ line-height: 1.2;
865
+ overflow-wrap: anywhere;
866
+ }
867
+ .prompt-meaning {
868
+ font-size: 22px;
869
+ }
870
+ .prompt-pron {
871
+ color: var(--text-muted);
872
+ font-style: italic;
873
+ }
874
+ .prompt-sentence {
875
+ margin: 0;
876
+ font-size: 19px;
877
+ font-weight: 600;
878
+ line-height: 1.5;
879
+ }
880
+ .prompt-sentence .gap {
881
+ display: inline-block;
882
+ min-width: 3em;
883
+ border-bottom: 3px solid var(--primary);
884
+ margin: 0 4px;
885
+ }
886
+ .prompt-hint {
887
+ margin: 0;
888
+ font-size: 13px;
889
+ }
890
+ .speak-btn {
891
+ font-size: 20px;
892
+ min-width: 44px;
893
+ min-height: 44px;
894
+ }
895
+ .play-big {
896
+ width: 84px;
897
+ height: 84px;
898
+ border-radius: 50%;
899
+ border: none;
900
+ font-size: 34px;
901
+ background: var(--primary);
902
+ color: #fff;
903
+ box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2);
904
+ transition: transform 150ms var(--px-ease);
905
+ }
906
+ .play-big:active {
907
+ transform: translateY(3px) scale(0.98);
908
+ }
909
+
910
+ .option-grid {
911
+ display: grid;
912
+ grid-template-columns: 1fr 1fr;
913
+ gap: 10px;
914
+ }
915
+ .option {
916
+ position: relative;
917
+ display: flex;
918
+ align-items: center;
919
+ gap: 8px;
920
+ min-height: 56px;
921
+ padding: 10px 12px;
922
+ border-radius: 14px;
923
+ border: 2px solid var(--border);
924
+ border-bottom-width: 4px;
925
+ background: var(--surface);
926
+ color: var(--text);
927
+ text-align: start;
928
+ font-size: 15px;
929
+ transition: transform 150ms var(--px-ease), border-color 150ms, background 150ms, opacity 200ms;
930
+ }
931
+ .option:hover:not(:disabled) {
932
+ background: var(--surface-muted);
933
+ }
934
+ .option:active:not(:disabled) {
935
+ transform: translateY(2px);
936
+ }
937
+ .option.is-selected {
938
+ border-color: var(--primary);
939
+ background: var(--primary-soft);
940
+ }
941
+ .option.is-correct {
942
+ border-color: var(--px-green);
943
+ background: var(--px-green-soft);
944
+ color: var(--px-green-ink);
945
+ }
946
+ .option.is-wrong {
947
+ border-color: var(--px-red);
948
+ background: var(--px-red-soft);
949
+ color: var(--px-red-ink);
950
+ animation: px-shake 380ms ease both;
951
+ }
952
+ .option.is-dim {
953
+ opacity: 0.55;
954
+ }
955
+ .option:disabled {
956
+ cursor: default;
957
+ }
958
+ .option-key {
959
+ flex: none;
960
+ display: inline-grid;
961
+ place-items: center;
962
+ width: 22px;
963
+ height: 22px;
964
+ border-radius: 6px;
965
+ border: 1px solid var(--border);
966
+ font-size: 11px;
967
+ color: var(--text-muted);
968
+ }
969
+ .option-text {
970
+ overflow-wrap: anywhere;
971
+ }
972
+ .btn-check {
973
+ min-height: 48px;
974
+ font-size: 16px;
975
+ border-radius: 14px;
976
+ }
977
+ .btn-check:disabled {
978
+ opacity: 0.5;
979
+ cursor: default;
980
+ }
981
+
982
+ .match-grid {
983
+ display: grid;
984
+ grid-template-columns: 1fr 1fr;
985
+ gap: 10px;
986
+ }
987
+ .match-col {
988
+ display: flex;
989
+ flex-direction: column;
990
+ gap: 8px;
991
+ }
992
+ .match-item {
993
+ justify-content: center;
994
+ text-align: center;
995
+ min-height: 48px;
996
+ }
997
+ .match-item.is-matched {
998
+ opacity: 0;
999
+ transform: scale(0.94);
1000
+ pointer-events: none;
1001
+ transition: opacity 250ms var(--px-ease), transform 250ms var(--px-ease);
1002
+ }
1003
+ .match-item.is-shake {
1004
+ border-color: var(--px-red);
1005
+ background: var(--px-red-soft);
1006
+ animation: px-shake 380ms ease both;
1007
+ }
1008
+
1009
+ .type-input {
1010
+ width: 100%;
1011
+ min-height: 52px;
1012
+ font-size: 18px;
1013
+ padding: 10px 14px;
1014
+ border-radius: 14px;
1015
+ border: 2px solid var(--border);
1016
+ background: var(--surface);
1017
+ color: var(--text);
1018
+ }
1019
+ .type-input:focus {
1020
+ border-color: var(--primary);
1021
+ outline: none;
1022
+ }
1023
+
1024
+ /* feedback sheet */
1025
+ .px-sheet {
1026
+ position: fixed;
1027
+ left: 0;
1028
+ right: 0;
1029
+ bottom: 0;
1030
+ z-index: 20;
1031
+ max-width: 520px;
1032
+ margin: 0 auto;
1033
+ padding: 16px 18px calc(16px + env(safe-area-inset-bottom, 0px));
1034
+ border-radius: 18px 18px 0 0;
1035
+ background: var(--surface);
1036
+ border-top: 1px solid var(--border);
1037
+ box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.12);
1038
+ transform: translateY(105%);
1039
+ visibility: hidden;
1040
+ transition: transform 220ms var(--px-ease), visibility 0s linear 220ms, background 150ms;
1041
+ }
1042
+ .px-sheet.is-open {
1043
+ transform: translateY(0);
1044
+ visibility: visible;
1045
+ transition: transform 220ms var(--px-ease), visibility 0s, background 150ms;
1046
+ }
1047
+ .px-sheet.is-correct {
1048
+ background: var(--px-green-soft);
1049
+ color: var(--px-green-ink);
1050
+ }
1051
+ .px-sheet.is-wrong {
1052
+ background: var(--px-red-soft);
1053
+ color: var(--px-red-ink);
1054
+ }
1055
+ .px-sheet.is-almost {
1056
+ background: var(--px-amber-soft);
1057
+ color: var(--px-amber-ink);
1058
+ }
1059
+ .px-sheet-head {
1060
+ display: flex;
1061
+ align-items: center;
1062
+ gap: 10px;
1063
+ font-size: 18px;
1064
+ }
1065
+ .px-sheet-icon {
1066
+ display: inline-grid;
1067
+ place-items: center;
1068
+ width: 32px;
1069
+ height: 32px;
1070
+ border-radius: 50%;
1071
+ font-weight: 800;
1072
+ color: #fff;
1073
+ background: var(--primary);
1074
+ }
1075
+ .px-sheet.is-correct .px-sheet-icon {
1076
+ background: var(--px-green);
1077
+ }
1078
+ .px-sheet.is-wrong .px-sheet-icon {
1079
+ background: var(--px-red);
1080
+ }
1081
+ .px-sheet.is-almost .px-sheet-icon {
1082
+ background: var(--px-amber);
1083
+ }
1084
+ .px-sheet-line {
1085
+ margin: 8px 0 0;
1086
+ }
1087
+ .px-answer {
1088
+ font-weight: 800;
1089
+ }
1090
+ .px-card-line {
1091
+ display: flex;
1092
+ flex-wrap: wrap;
1093
+ align-items: center;
1094
+ gap: 4px 8px;
1095
+ margin-top: 8px;
1096
+ }
1097
+ .px-term {
1098
+ font-weight: 800;
1099
+ font-size: 16px;
1100
+ }
1101
+ .px-card-line .icon-btn {
1102
+ min-width: 36px;
1103
+ min-height: 36px;
1104
+ font-size: 16px;
1105
+ }
1106
+ .px-continue {
1107
+ margin-top: 12px;
1108
+ width: 100%;
1109
+ min-height: 48px;
1110
+ font-size: 16px;
1111
+ border: none;
1112
+ border-radius: 14px;
1113
+ color: #fff;
1114
+ background: var(--primary);
1115
+ box-shadow: 0 4px 0 rgba(0, 0, 0, 0.18);
1116
+ }
1117
+ .px-sheet.is-correct .px-continue {
1118
+ background: var(--px-green);
1119
+ }
1120
+ .px-sheet.is-wrong .px-continue {
1121
+ background: var(--px-red);
1122
+ }
1123
+ .px-sheet.is-almost .px-continue {
1124
+ background: var(--px-amber);
1125
+ }
1126
+ @media (prefers-color-scheme: dark) {
1127
+ .px-continue,
1128
+ .px-sheet-icon {
1129
+ color: #0b1020;
1130
+ }
1131
+ }
1132
+
1133
+ /* confetti */
1134
+ .confetti {
1135
+ position: absolute;
1136
+ inset: 0;
1137
+ pointer-events: none;
1138
+ overflow: hidden;
1139
+ }
1140
+ .confetti-piece {
1141
+ position: absolute;
1142
+ top: -12px;
1143
+ height: 12px;
1144
+ border-radius: 2px;
1145
+ opacity: 0;
1146
+ animation: px-confetti 1.5s cubic-bezier(0.25, 0.6, 0.4, 1) forwards;
1147
+ }
1148
+
1149
+ @keyframes px-confetti {
1150
+ 0% {
1151
+ opacity: 1;
1152
+ transform: translate(0, 0) rotate(0);
1153
+ }
1154
+ 100% {
1155
+ opacity: 0;
1156
+ transform: translate(var(--drift, 0px), 420px) rotate(var(--spin, 360deg));
1157
+ }
1158
+ }
1159
+ @keyframes px-pop {
1160
+ 0% {
1161
+ transform: scale(0.6);
1162
+ opacity: 0;
1163
+ }
1164
+ 70% {
1165
+ transform: scale(1.08);
1166
+ opacity: 1;
1167
+ }
1168
+ 100% {
1169
+ transform: scale(1);
1170
+ }
1171
+ }
1172
+ @keyframes px-in {
1173
+ from {
1174
+ opacity: 0;
1175
+ transform: translateY(6px);
1176
+ }
1177
+ to {
1178
+ opacity: 1;
1179
+ transform: none;
1180
+ }
1181
+ }
1182
+ @keyframes px-shake {
1183
+ 0%,
1184
+ 100% {
1185
+ transform: translateX(0);
1186
+ }
1187
+ 20% {
1188
+ transform: translateX(-6px);
1189
+ }
1190
+ 40% {
1191
+ transform: translateX(6px);
1192
+ }
1193
+ 60% {
1194
+ transform: translateX(-4px);
1195
+ }
1196
+ 80% {
1197
+ transform: translateX(4px);
1198
+ }
1199
+ }
1200
+
1201
+ @media (prefers-reduced-motion: reduce) {
1202
+ .px-hero,
1203
+ .px-empty-icon,
1204
+ .px-combo.is-on,
1205
+ .px-card,
1206
+ .option.is-wrong,
1207
+ .match-item.is-shake {
1208
+ animation: none;
1209
+ }
1210
+ .px-sheet,
1211
+ .px-sheet.is-open,
1212
+ .px-progress-fill,
1213
+ .option,
1214
+ .match-item.is-matched,
1215
+ .goal-ring-fill,
1216
+ .practice-cta,
1217
+ .px-big-btn {
1218
+ transition: none;
1219
+ }
1220
+ .confetti {
1221
+ display: none;
1222
+ }
1223
+ }
1224
+
1225
+ /* ───────────── v2 Task 6: tokens, Words hub, Today, Progress, goal picker ───────────── */
1226
+ :root {
1227
+ --radius-lg: 18px;
1228
+ --accent-orange: #c2410c;
1229
+ --accent-orange-soft: #ffedd5;
1230
+ --accent-ice: #0369a1;
1231
+ --accent-ice-soft: #e0f2fe;
1232
+ --accent-violet: #6d28d9;
1233
+ --accent-violet-soft: #ede9fe;
1234
+ --star: #b45309;
1235
+ --focus: var(--primary);
1236
+ --brand-gradient: linear-gradient(135deg, #1a56db 0%, #7c3aed 100%);
1237
+ }
1238
+ @media (prefers-color-scheme: dark) {
1239
+ :root {
1240
+ --accent-orange: #fb923c;
1241
+ --accent-orange-soft: #3a2414;
1242
+ --accent-ice: #38bdf8;
1243
+ --accent-ice-soft: #0f2e42;
1244
+ --accent-violet: #a78bfa;
1245
+ --accent-violet-soft: #2a2148;
1246
+ --star: #fbbf24;
1247
+ --brand-gradient: linear-gradient(135deg, #6b93f0 0%, #a78bfa 100%);
1248
+ }
1249
+ }
1250
+
1251
+ .sr-only {
1252
+ position: absolute !important;
1253
+ width: 1px;
1254
+ height: 1px;
1255
+ padding: 0;
1256
+ margin: -1px;
1257
+ overflow: hidden;
1258
+ clip: rect(0 0 0 0);
1259
+ white-space: nowrap;
1260
+ border: 0;
1261
+ }
1262
+
1263
+ /* Cohesive surfaces and targets */
1264
+ .card {
1265
+ border-radius: var(--radius-lg);
1266
+ }
1267
+ .brand {
1268
+ background: var(--brand-gradient);
1269
+ -webkit-background-clip: text;
1270
+ background-clip: text;
1271
+ color: transparent;
1272
+ font-weight: 800;
1273
+ }
1274
+ button,
1275
+ .tab-btn,
1276
+ .chip {
1277
+ min-height: 44px;
1278
+ }
1279
+ .icon-btn {
1280
+ min-width: 44px;
1281
+ min-height: 44px;
1282
+ font-size: 18px;
1283
+ display: inline-grid;
1284
+ place-items: center;
1285
+ }
1286
+ button.primary {
1287
+ border-radius: 12px;
1288
+ font-weight: 700;
1289
+ }
1290
+ button:focus-visible,
1291
+ select:focus-visible,
1292
+ input:focus-visible,
1293
+ a:focus-visible,
1294
+ .goal-option:focus-within {
1295
+ outline: 3px solid var(--focus);
1296
+ outline-offset: 2px;
1297
+ }
1298
+ button:disabled {
1299
+ cursor: not-allowed;
1300
+ opacity: 0.65;
1301
+ }
1302
+ .section-head {
1303
+ display: flex;
1304
+ align-items: center;
1305
+ justify-content: space-between;
1306
+ gap: 8px;
1307
+ }
1308
+ .empty-state {
1309
+ text-align: center;
1310
+ display: grid;
1311
+ gap: 8px;
1312
+ justify-items: center;
1313
+ }
1314
+ .empty-icon {
1315
+ font-size: 40px;
1316
+ }
1317
+
1318
+ /* Words hub */
1319
+ .words-tools {
1320
+ display: grid;
1321
+ gap: 10px;
1322
+ }
1323
+ .words-search {
1324
+ width: 100%;
1325
+ min-height: 44px;
1326
+ padding: 8px 14px;
1327
+ border-radius: 999px;
1328
+ border: 1px solid var(--border);
1329
+ background: var(--surface);
1330
+ color: var(--text);
1331
+ font: inherit;
1332
+ }
1333
+ .chip-row {
1334
+ display: flex;
1335
+ flex-wrap: wrap;
1336
+ gap: 6px;
1337
+ }
1338
+ .chip {
1339
+ border-radius: 999px;
1340
+ padding: 6px 12px;
1341
+ background: var(--surface);
1342
+ border: 1px solid var(--border);
1343
+ color: var(--text);
1344
+ font-size: 13px;
1345
+ }
1346
+ .chip.active {
1347
+ background: var(--primary);
1348
+ border-color: var(--primary);
1349
+ color: #fff;
1350
+ }
1351
+ .chip-count {
1352
+ display: inline-block;
1353
+ min-width: 20px;
1354
+ margin-inline-start: 4px;
1355
+ padding: 0 6px;
1356
+ border-radius: 999px;
1357
+ background: var(--surface-muted);
1358
+ color: var(--text);
1359
+ font-size: 12px;
1360
+ }
1361
+ .chip.active .chip-count {
1362
+ background: rgba(255, 255, 255, 0.25);
1363
+ color: #fff;
1364
+ }
1365
+ .words-group h2 {
1366
+ margin-bottom: 8px;
1367
+ }
1368
+ .words-group-count {
1369
+ font-weight: 500;
1370
+ font-size: 13px;
1371
+ }
1372
+ .vocab-list {
1373
+ list-style: none;
1374
+ margin: 0;
1375
+ padding: 0;
1376
+ }
1377
+ .word-actions {
1378
+ display: flex;
1379
+ gap: 2px;
1380
+ }
1381
+ .star {
1382
+ color: var(--text-muted);
1383
+ }
1384
+ .star.on {
1385
+ color: var(--star);
1386
+ }
1387
+ .word-footer {
1388
+ display: flex;
1389
+ align-items: center;
1390
+ justify-content: space-between;
1391
+ gap: 8px;
1392
+ margin-top: 8px;
1393
+ }
1394
+ .btn-know {
1395
+ border-radius: 999px;
1396
+ background: var(--success-soft);
1397
+ color: var(--success);
1398
+ border-color: transparent;
1399
+ }
1400
+ .btn-know.done,
1401
+ .btn-know:disabled {
1402
+ background: var(--surface-muted);
1403
+ color: var(--text-muted);
1404
+ opacity: 1;
1405
+ }
1406
+ .word-edit {
1407
+ margin-top: 8px;
1408
+ }
1409
+ .word-edit input {
1410
+ width: 100%;
1411
+ }
1412
+ .strength {
1413
+ display: inline-flex;
1414
+ gap: 3px;
1415
+ align-items: flex-end;
1416
+ }
1417
+ .strength-bar {
1418
+ width: 6px;
1419
+ height: 14px;
1420
+ border-radius: 3px;
1421
+ background: var(--border);
1422
+ }
1423
+ .strength-bar:nth-child(1) { height: 6px; }
1424
+ .strength-bar:nth-child(2) { height: 8px; }
1425
+ .strength-bar:nth-child(3) { height: 10px; }
1426
+ .strength-bar:nth-child(4) { height: 12px; }
1427
+ .strength.s1 .strength-bar.on,
1428
+ .strength.s2 .strength-bar.on { background: var(--accent-orange); }
1429
+ .strength.s3 .strength-bar.on { background: var(--primary); }
1430
+ .strength.s4 .strength-bar.on,
1431
+ .strength.s5 .strength-bar.on { background: var(--success); }
1432
+ .show-more {
1433
+ width: 100%;
1434
+ border-radius: 12px;
1435
+ background: var(--primary-soft);
1436
+ color: var(--primary);
1437
+ border-color: transparent;
1438
+ }
1439
+
1440
+ /* Today */
1441
+ .rollover-banner {
1442
+ display: flex;
1443
+ align-items: center;
1444
+ gap: 10px;
1445
+ padding: 4px 4px 4px 14px;
1446
+ border-radius: 14px;
1447
+ background: var(--accent-ice-soft);
1448
+ color: var(--text);
1449
+ border: 1px solid var(--accent-ice);
1450
+ animation: px-in 300ms var(--px-ease) both;
1451
+ }
1452
+ .rollover-text {
1453
+ flex: 1;
1454
+ font-weight: 600;
1455
+ }
1456
+ .today-hero {
1457
+ display: flex;
1458
+ align-items: center;
1459
+ justify-content: space-between;
1460
+ gap: 12px;
1461
+ background: linear-gradient(160deg, var(--surface) 55%, var(--primary-soft) 100%);
1462
+ }
1463
+ .today-goal {
1464
+ display: grid;
1465
+ justify-items: center;
1466
+ gap: 4px;
1467
+ text-align: center;
1468
+ }
1469
+ .today-goal-text {
1470
+ font-size: 12px;
1471
+ font-weight: 700;
1472
+ color: var(--text-muted);
1473
+ }
1474
+ .goal-met-pill {
1475
+ font-size: 12px;
1476
+ font-weight: 700;
1477
+ color: var(--success);
1478
+ }
1479
+ .streak-box {
1480
+ display: flex;
1481
+ align-items: center;
1482
+ gap: 8px;
1483
+ margin-top: 8px;
1484
+ }
1485
+ .streak-flame {
1486
+ font-size: 30px;
1487
+ line-height: 1;
1488
+ display: inline-block;
1489
+ transform-origin: 50% 90%;
1490
+ }
1491
+ .streak-flame.off {
1492
+ filter: grayscale(1);
1493
+ opacity: 0.5;
1494
+ }
1495
+ .streak-flame.animated {
1496
+ animation: lc-flicker 1.6s ease-in-out infinite;
1497
+ }
1498
+ .streak-text {
1499
+ display: grid;
1500
+ line-height: 1.1;
1501
+ }
1502
+ .streak-count {
1503
+ font-size: 22px;
1504
+ color: var(--accent-orange);
1505
+ }
1506
+ .freeze-pill {
1507
+ margin-inline-start: 8px;
1508
+ padding: 4px 10px;
1509
+ border-radius: 999px;
1510
+ background: var(--accent-ice-soft);
1511
+ color: var(--text);
1512
+ font-weight: 700;
1513
+ font-size: 13px;
1514
+ }
1515
+ .practice-cta.fresh {
1516
+ background: var(--accent-violet-soft);
1517
+ border-color: var(--accent-violet);
1518
+ }
1519
+ .scenario-list {
1520
+ list-style: none;
1521
+ padding: 0;
1522
+ margin: 8px 0 0;
1523
+ display: grid;
1524
+ gap: 8px;
1525
+ }
1526
+ .scenario-card {
1527
+ display: grid;
1528
+ gap: 8px;
1529
+ padding: 12px;
1530
+ border-radius: 14px;
1531
+ border: 1px solid var(--border);
1532
+ border-inline-start: 5px solid var(--primary);
1533
+ background: var(--surface);
1534
+ }
1535
+ .scenario-card.tone-1 { border-inline-start-color: var(--accent-orange); }
1536
+ .scenario-card.tone-2 { border-inline-start-color: var(--accent-violet); }
1537
+ .scenario-theme {
1538
+ font-weight: 700;
1539
+ font-size: 15px;
1540
+ }
1541
+ .scenario-status {
1542
+ margin: 0;
1543
+ font-size: 13px;
1544
+ color: var(--success);
1545
+ }
1546
+ .scenario-status:empty {
1547
+ display: none;
1548
+ }
1549
+ .scenario-status.warn {
1550
+ color: var(--warning);
1551
+ }
1552
+
1553
+ /* Progress */
1554
+ .level-card {
1555
+ display: flex;
1556
+ gap: 14px;
1557
+ align-items: center;
1558
+ }
1559
+ .level-badge {
1560
+ flex: none;
1561
+ width: 64px;
1562
+ height: 64px;
1563
+ border-radius: 20px;
1564
+ display: grid;
1565
+ place-items: center;
1566
+ background: var(--brand-gradient);
1567
+ color: #fff;
1568
+ font-size: 28px;
1569
+ font-weight: 800;
1570
+ box-shadow: var(--shadow);
1571
+ }
1572
+ .level-body {
1573
+ flex: 1;
1574
+ display: grid;
1575
+ gap: 4px;
1576
+ }
1577
+ .level-kicker {
1578
+ margin: 0;
1579
+ font-size: 12px;
1580
+ text-transform: uppercase;
1581
+ letter-spacing: 0.04em;
1582
+ }
1583
+ .level-name {
1584
+ margin: 0;
1585
+ font-size: 20px;
1586
+ }
1587
+ .level-bar {
1588
+ height: 10px;
1589
+ }
1590
+ .week-chart-wrap {
1591
+ margin: 8px 0 0;
1592
+ }
1593
+ .week-chart {
1594
+ position: relative;
1595
+ display: grid;
1596
+ grid-template-columns: repeat(7, 1fr);
1597
+ gap: 6px;
1598
+ height: 140px;
1599
+ align-items: end;
1600
+ }
1601
+ .week-goal-line {
1602
+ position: absolute;
1603
+ left: 0;
1604
+ right: 0;
1605
+ border-top: 2px dashed var(--accent-orange);
1606
+ pointer-events: none;
1607
+ }
1608
+ .week-col {
1609
+ display: grid;
1610
+ grid-template-rows: auto 1fr auto;
1611
+ justify-items: center;
1612
+ height: 100%;
1613
+ gap: 2px;
1614
+ }
1615
+ .week-bar {
1616
+ align-self: end;
1617
+ width: 70%;
1618
+ border-radius: 8px 8px 3px 3px;
1619
+ background: var(--primary-soft);
1620
+ border: 1px solid var(--primary);
1621
+ }
1622
+ .week-col.met .week-bar {
1623
+ background: var(--success);
1624
+ border-color: var(--success);
1625
+ }
1626
+ .week-col.today .week-day {
1627
+ color: var(--primary);
1628
+ font-weight: 800;
1629
+ }
1630
+ .week-xp,
1631
+ .week-day {
1632
+ font-size: 11px;
1633
+ color: var(--text-muted);
1634
+ }
1635
+ .week-xp {
1636
+ font-weight: 700;
1637
+ }
1638
+ ul.ach-grid {
1639
+ list-style: none;
1640
+ margin: 0;
1641
+ padding: 0;
1642
+ }
1643
+ .ach-item {
1644
+ display: flex;
1645
+ gap: 10px;
1646
+ align-items: flex-start;
1647
+ }
1648
+ .ach-icon {
1649
+ font-size: 22px;
1650
+ }
1651
+ .ach-item:not(.unlocked) .ach-icon {
1652
+ filter: grayscale(1);
1653
+ opacity: 0.6;
1654
+ }
1655
+ .ach-title {
1656
+ font-weight: 700;
1657
+ }
1658
+ .ach-bar {
1659
+ height: 6px;
1660
+ margin: 4px 0;
1661
+ }
1662
+
1663
+ /* Daily goal picker */
1664
+ .goal-picker {
1665
+ border: none;
1666
+ margin: 0;
1667
+ padding: 0;
1668
+ display: grid;
1669
+ grid-template-columns: repeat(2, 1fr);
1670
+ gap: 8px;
1671
+ }
1672
+ .goal-picker legend {
1673
+ font-weight: 700;
1674
+ margin-bottom: 6px;
1675
+ }
1676
+ .goal-option {
1677
+ position: relative;
1678
+ display: grid;
1679
+ gap: 2px;
1680
+ padding: 10px 12px;
1681
+ min-height: 44px;
1682
+ border-radius: 14px;
1683
+ border: 2px solid var(--border);
1684
+ background: var(--surface);
1685
+ cursor: pointer;
1686
+ }
1687
+ .goal-option input {
1688
+ position: absolute;
1689
+ opacity: 0;
1690
+ inset: 0;
1691
+ margin: 0;
1692
+ cursor: pointer;
1693
+ }
1694
+ .goal-option.active {
1695
+ border-color: var(--primary);
1696
+ background: var(--primary-soft);
1697
+ }
1698
+ .goal-icon {
1699
+ font-size: 20px;
1700
+ }
1701
+ .goal-name {
1702
+ font-weight: 700;
1703
+ }
1704
+ .goal-xp {
1705
+ font-size: 12px;
1706
+ }
1707
+
1708
+ .px-perfect-bonus {
1709
+ margin: 0;
1710
+ font-weight: 800;
1711
+ color: var(--px-green, var(--success));
1712
+ }
1713
+
1714
+ @keyframes lc-flicker {
1715
+ 0%,
1716
+ 100% {
1717
+ transform: scale(1) rotate(-2deg);
1718
+ }
1719
+ 50% {
1720
+ transform: scale(1.08) rotate(2deg);
1721
+ }
1722
+ }
1723
+
1724
+ @media (prefers-reduced-motion: reduce) {
1725
+ .streak-flame.animated,
1726
+ .rollover-banner {
1727
+ animation: none;
1728
+ }
1729
+ }