@daowolf/system-design-quest 0.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css ADDED
@@ -0,0 +1,792 @@
1
+ :host {
2
+ --bg: #f6f5fb;
3
+ --panel: #ffffff;
4
+ --ink: #1d1b2e;
5
+ --muted: #5e5a78;
6
+ --line: #dcd8ec;
7
+ --accent: #5b3fd4;
8
+ --accent-ink: #ffffff;
9
+ --soft: #ece8fb;
10
+ --good: #1f8a4c;
11
+ --good-soft: #dff3e6;
12
+ --bad: #c0392b;
13
+ --bad-soft: #fbe3e0;
14
+ --part: #b7791f;
15
+ --part-soft: #fdf0d8;
16
+ --gold: #e0a106;
17
+ --slot: #8a84a8;
18
+ --shadow: 0 2px 10px rgba(30, 20, 80, 0.08);
19
+ --radius: 14px;
20
+ --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
21
+ }
22
+ @media (prefers-color-scheme: dark) {
23
+ :host(:not([theme="light"])) {
24
+ --bg: #14121f;
25
+ --panel: #1e1b2e;
26
+ --ink: #ece9f8;
27
+ --muted: #a8a3c4;
28
+ --line: #34304b;
29
+ --accent: #8f7bff;
30
+ --accent-ink: #120f22;
31
+ --soft: #2a2545;
32
+ --good: #48c27c;
33
+ --good-soft: #17352a;
34
+ --bad: #ef6f62;
35
+ --bad-soft: #3c1d1d;
36
+ --part: #e7b14f;
37
+ --part-soft: #3a2e17;
38
+ --gold: #f2c23c;
39
+ --slot: #8d87ad;
40
+ --shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
41
+ }
42
+ }
43
+ :host([theme="dark"]) {
44
+ --bg: #14121f;
45
+ --panel: #1e1b2e;
46
+ --ink: #ece9f8;
47
+ --muted: #a8a3c4;
48
+ --line: #34304b;
49
+ --accent: #8f7bff;
50
+ --accent-ink: #120f22;
51
+ --soft: #2a2545;
52
+ --good: #48c27c;
53
+ --good-soft: #17352a;
54
+ --bad: #ef6f62;
55
+ --bad-soft: #3c1d1d;
56
+ --part: #e7b14f;
57
+ --part-soft: #3a2e17;
58
+ --gold: #f2c23c;
59
+ --slot: #8d87ad;
60
+ --shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
61
+ }
62
+ * {
63
+ box-sizing: border-box;
64
+ }
65
+ :host {
66
+ display: block;
67
+ background: var(--bg);
68
+ color: var(--ink);
69
+ font: 16px/1.5 var(--font);
70
+ text-align: left;
71
+ }
72
+ button {
73
+ font: inherit;
74
+ color: inherit;
75
+ cursor: pointer;
76
+ }
77
+ button:focus-visible,
78
+ input:focus-visible,
79
+ textarea:focus-visible,
80
+ select:focus-visible {
81
+ outline: 3px solid var(--accent);
82
+ outline-offset: 2px;
83
+ }
84
+ a {
85
+ color: var(--accent);
86
+ }
87
+
88
+ .top {
89
+ position: sticky;
90
+ top: 0;
91
+ z-index: 5;
92
+ display: flex;
93
+ gap: 12px;
94
+ align-items: center;
95
+ justify-content: space-between;
96
+ padding: 10px 16px;
97
+ background: var(--panel);
98
+ border-bottom: 1px solid var(--line);
99
+ }
100
+ .brand {
101
+ border: 0;
102
+ background: none;
103
+ font-weight: 800;
104
+ font-size: 18px;
105
+ padding: 4px 6px;
106
+ border-radius: 8px;
107
+ }
108
+ .stats {
109
+ display: flex;
110
+ flex-wrap: wrap;
111
+ gap: 8px;
112
+ justify-content: flex-end;
113
+ }
114
+ .stat {
115
+ background: var(--soft);
116
+ border-radius: 999px;
117
+ padding: 3px 12px;
118
+ font-size: 14px;
119
+ white-space: nowrap;
120
+ }
121
+ .stat b {
122
+ font-variant-numeric: tabular-nums;
123
+ }
124
+ .you {
125
+ border: 1px solid var(--line);
126
+ background: var(--panel);
127
+ border-radius: 999px;
128
+ padding: 4px 12px;
129
+ font-size: 14px;
130
+ font-weight: 600;
131
+ white-space: nowrap;
132
+ }
133
+
134
+ .layout {
135
+ display: grid;
136
+ grid-template-columns: minmax(0, 1fr);
137
+ gap: 16px;
138
+ max-width: 1180px;
139
+ margin: 0 auto;
140
+ padding: 16px;
141
+ }
142
+ .layout.with-coach {
143
+ grid-template-columns: minmax(0, 1fr) 320px;
144
+ }
145
+ @media (max-width: 900px) {
146
+ .layout.with-coach {
147
+ grid-template-columns: minmax(0, 1fr);
148
+ }
149
+ }
150
+ #screen {
151
+ min-width: 0;
152
+ outline: none;
153
+ }
154
+
155
+ .card {
156
+ background: var(--panel);
157
+ border: 1px solid var(--line);
158
+ border-radius: var(--radius);
159
+ box-shadow: var(--shadow);
160
+ padding: 20px;
161
+ }
162
+ .muted {
163
+ color: var(--muted);
164
+ }
165
+ h1,
166
+ h2,
167
+ h3 {
168
+ line-height: 1.25;
169
+ margin: 0 0 8px;
170
+ }
171
+ h1 {
172
+ font-size: 26px;
173
+ }
174
+ h2 {
175
+ font-size: 21px;
176
+ }
177
+ h3 {
178
+ font-size: 17px;
179
+ }
180
+
181
+ /* map */
182
+ .hero {
183
+ display: flex;
184
+ flex-wrap: wrap;
185
+ justify-content: space-between;
186
+ gap: 12px;
187
+ align-items: center;
188
+ margin-bottom: 16px;
189
+ }
190
+ .next-up {
191
+ display: flex;
192
+ gap: 12px;
193
+ align-items: center;
194
+ justify-content: space-between;
195
+ flex-wrap: wrap;
196
+ margin-bottom: 16px;
197
+ border-left: 5px solid var(--accent);
198
+ }
199
+ .chapters {
200
+ display: grid;
201
+ grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
202
+ gap: 14px;
203
+ }
204
+ .chapter {
205
+ display: flex;
206
+ flex-direction: column;
207
+ gap: 6px;
208
+ position: relative;
209
+ }
210
+ .chapter .emoji {
211
+ font-size: 30px;
212
+ }
213
+ /* Locked: fade the decoration only, so the text keeps full contrast. */
214
+ .chapter.locked {
215
+ border-style: dashed;
216
+ }
217
+ .chapter.locked .emoji,
218
+ .chapter.locked .stars,
219
+ .chapter.locked .bar {
220
+ opacity: 0.5;
221
+ }
222
+ .chapter .stars {
223
+ color: var(--gold);
224
+ letter-spacing: 2px;
225
+ font-size: 18px;
226
+ }
227
+ .pill {
228
+ display: inline-block;
229
+ font-size: 12px;
230
+ padding: 2px 9px;
231
+ border-radius: 999px;
232
+ background: var(--soft);
233
+ color: var(--muted);
234
+ }
235
+ .badges {
236
+ display: flex;
237
+ flex-wrap: wrap;
238
+ gap: 6px;
239
+ }
240
+ .bar {
241
+ height: 8px;
242
+ border-radius: 99px;
243
+ background: var(--soft);
244
+ overflow: hidden;
245
+ }
246
+ .bar > i {
247
+ display: block;
248
+ height: 100%;
249
+ background: var(--accent);
250
+ border-radius: 99px;
251
+ }
252
+
253
+ .btn {
254
+ border: 0;
255
+ border-radius: 10px;
256
+ padding: 10px 18px;
257
+ font-weight: 700;
258
+ background: var(--accent);
259
+ color: var(--accent-ink);
260
+ }
261
+ .btn:disabled {
262
+ opacity: 0.45;
263
+ cursor: not-allowed;
264
+ }
265
+ .btn.ghost {
266
+ background: transparent;
267
+ color: var(--ink);
268
+ border: 1px solid var(--line);
269
+ font-weight: 600;
270
+ }
271
+ .btn.small {
272
+ padding: 6px 12px;
273
+ font-size: 14px;
274
+ }
275
+ .row {
276
+ display: flex;
277
+ flex-wrap: wrap;
278
+ gap: 10px;
279
+ align-items: center;
280
+ }
281
+ .spread {
282
+ justify-content: space-between;
283
+ }
284
+
285
+ /* play */
286
+ .runbar {
287
+ display: flex;
288
+ gap: 10px;
289
+ align-items: center;
290
+ justify-content: space-between;
291
+ flex-wrap: wrap;
292
+ margin-bottom: 12px;
293
+ }
294
+ .dots {
295
+ display: flex;
296
+ gap: 4px;
297
+ flex-wrap: wrap;
298
+ }
299
+ .dots i {
300
+ width: 10px;
301
+ height: 10px;
302
+ border-radius: 50%;
303
+ background: var(--line);
304
+ }
305
+ .dots i.right {
306
+ background: var(--good);
307
+ }
308
+ .dots i.wrong {
309
+ background: var(--bad);
310
+ }
311
+ .dots i.part {
312
+ background: var(--part);
313
+ }
314
+ .dots i.now {
315
+ outline: 2px solid var(--accent);
316
+ }
317
+ .combo {
318
+ font-weight: 800;
319
+ color: var(--part);
320
+ }
321
+ .challenge .kind {
322
+ display: flex;
323
+ gap: 8px;
324
+ align-items: center;
325
+ flex-wrap: wrap;
326
+ margin-bottom: 10px;
327
+ }
328
+ .boss-tag {
329
+ background: var(--bad);
330
+ color: #fff;
331
+ }
332
+ .prompt {
333
+ font-size: 19px;
334
+ font-weight: 650;
335
+ margin: 4px 0 14px;
336
+ }
337
+ .group {
338
+ margin: 12px 0;
339
+ }
340
+ .group > .label {
341
+ font-size: 13px;
342
+ text-transform: uppercase;
343
+ letter-spacing: 0.06em;
344
+ color: var(--muted);
345
+ margin-bottom: 6px;
346
+ }
347
+ .options {
348
+ display: grid;
349
+ gap: 8px;
350
+ }
351
+ .opt {
352
+ text-align: left;
353
+ padding: 11px 14px;
354
+ border-radius: 10px;
355
+ border: 2px solid var(--line);
356
+ background: var(--panel);
357
+ }
358
+ .opt:hover:not(:disabled) {
359
+ border-color: var(--accent);
360
+ }
361
+ .opt.sel {
362
+ border-color: var(--accent);
363
+ background: var(--soft);
364
+ }
365
+ .opt.right {
366
+ border-color: var(--good);
367
+ background: var(--good-soft);
368
+ }
369
+ .opt.wrong {
370
+ border-color: var(--bad);
371
+ background: var(--bad-soft);
372
+ }
373
+ .opt.missed {
374
+ border-style: dashed;
375
+ border-color: var(--good);
376
+ }
377
+ .conf {
378
+ display: flex;
379
+ gap: 6px;
380
+ flex-wrap: wrap;
381
+ align-items: center;
382
+ margin: 4px 0 12px;
383
+ font-size: 14px;
384
+ }
385
+ .conf button {
386
+ border: 1px solid var(--line);
387
+ background: var(--panel);
388
+ border-radius: 999px;
389
+ padding: 4px 12px;
390
+ }
391
+ .conf button.sel {
392
+ background: var(--accent);
393
+ color: var(--accent-ink);
394
+ border-color: var(--accent);
395
+ }
396
+ textarea,
397
+ input[type="number"],
398
+ input[type="text"],
399
+ input[type="date"],
400
+ select {
401
+ width: 100%;
402
+ font: inherit;
403
+ color: inherit;
404
+ background: var(--bg);
405
+ border: 1px solid var(--line);
406
+ border-radius: 10px;
407
+ padding: 10px 12px;
408
+ }
409
+ textarea {
410
+ min-height: 110px;
411
+ resize: vertical;
412
+ }
413
+ /* you: the optional profile */
414
+ .fields {
415
+ display: grid;
416
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
417
+ gap: 12px;
418
+ margin: 12px 0;
419
+ }
420
+ .field {
421
+ display: grid;
422
+ gap: 4px;
423
+ font-size: 14px;
424
+ color: var(--muted);
425
+ }
426
+ .field.inline {
427
+ grid-template-columns: auto 160px;
428
+ align-items: center;
429
+ }
430
+ .field input,
431
+ .field select {
432
+ color: var(--ink);
433
+ font-size: 16px;
434
+ }
435
+ .hint {
436
+ margin-bottom: 16px;
437
+ padding: 12px 16px;
438
+ gap: 10px;
439
+ flex-wrap: wrap;
440
+ align-items: center;
441
+ }
442
+ .hold {
443
+ padding: 10px 0;
444
+ border-top: 1px solid var(--line);
445
+ gap: 10px;
446
+ flex-wrap: wrap;
447
+ }
448
+ #screen > .card + .card {
449
+ margin-top: 16px;
450
+ }
451
+
452
+ .chips {
453
+ display: flex;
454
+ flex-wrap: wrap;
455
+ gap: 8px;
456
+ margin: 10px 0;
457
+ }
458
+ .chip {
459
+ border: 2px solid var(--line);
460
+ background: var(--panel);
461
+ border-radius: 999px;
462
+ padding: 6px 13px;
463
+ font-weight: 600;
464
+ font-size: 14px;
465
+ }
466
+ .chip.sel {
467
+ border-color: var(--accent);
468
+ background: var(--accent);
469
+ color: var(--accent-ink);
470
+ }
471
+ .chip.used {
472
+ opacity: 0.5;
473
+ }
474
+ .orderlist {
475
+ list-style: none;
476
+ padding: 0;
477
+ margin: 0;
478
+ display: grid;
479
+ gap: 8px;
480
+ }
481
+ .orderlist li {
482
+ display: flex;
483
+ gap: 8px;
484
+ align-items: center;
485
+ padding: 8px 10px;
486
+ border: 2px solid var(--line);
487
+ border-radius: 10px;
488
+ background: var(--panel);
489
+ }
490
+ .orderlist li.right {
491
+ border-color: var(--good);
492
+ background: var(--good-soft);
493
+ }
494
+ .orderlist li.wrong {
495
+ border-color: var(--bad);
496
+ background: var(--bad-soft);
497
+ }
498
+ .orderlist li .txt {
499
+ flex: 1;
500
+ }
501
+ .orderlist li button {
502
+ border: 1px solid var(--line);
503
+ background: var(--bg);
504
+ border-radius: 6px;
505
+ width: 32px;
506
+ height: 30px;
507
+ }
508
+ .timer {
509
+ font-variant-numeric: tabular-nums;
510
+ font-weight: 800;
511
+ font-size: 18px;
512
+ padding: 2px 12px;
513
+ border-radius: 999px;
514
+ background: var(--soft);
515
+ }
516
+ .timer.low {
517
+ background: var(--bad);
518
+ color: #fff;
519
+ }
520
+ .bigtimer {
521
+ font-size: 56px;
522
+ font-weight: 800;
523
+ font-variant-numeric: tabular-nums;
524
+ text-align: center;
525
+ margin: 10px 0;
526
+ }
527
+ .lightning-q {
528
+ font-size: 20px;
529
+ font-weight: 700;
530
+ min-height: 60px;
531
+ }
532
+ .flash-right {
533
+ animation: fr 0.35s;
534
+ }
535
+ .flash-wrong {
536
+ animation: fw 0.35s;
537
+ }
538
+ @keyframes fr {
539
+ 50% {
540
+ background: var(--good-soft);
541
+ }
542
+ }
543
+ @keyframes fw {
544
+ 50% {
545
+ background: var(--bad-soft);
546
+ }
547
+ }
548
+
549
+ /* diagrams */
550
+ .diagram {
551
+ width: 100%;
552
+ height: auto;
553
+ display: block;
554
+ margin: 8px 0;
555
+ background: var(--bg);
556
+ border-radius: 12px;
557
+ border: 1px solid var(--line);
558
+ }
559
+ .diagram .node rect {
560
+ fill: var(--panel);
561
+ stroke: var(--ink);
562
+ stroke-width: 1.5;
563
+ }
564
+ .diagram .node text {
565
+ fill: var(--ink);
566
+ font: 600 13px var(--font);
567
+ }
568
+ .diagram .node.slot rect {
569
+ stroke: var(--slot);
570
+ stroke-dasharray: 6 4;
571
+ fill: var(--soft);
572
+ }
573
+ .diagram .node.filled rect {
574
+ stroke: var(--accent);
575
+ stroke-dasharray: none;
576
+ }
577
+ .diagram .node.clickable {
578
+ cursor: pointer;
579
+ }
580
+ .diagram .node.clickable:hover rect {
581
+ stroke: var(--accent);
582
+ stroke-width: 2.5;
583
+ }
584
+ .diagram .node.picked rect {
585
+ stroke: var(--accent);
586
+ stroke-width: 3.5;
587
+ }
588
+ .diagram .node.right rect {
589
+ stroke: var(--good);
590
+ stroke-width: 3;
591
+ fill: var(--good-soft);
592
+ }
593
+ .diagram .node.wrong rect {
594
+ stroke: var(--bad);
595
+ stroke-width: 3;
596
+ fill: var(--bad-soft);
597
+ }
598
+ .diagram .edge {
599
+ stroke: var(--muted);
600
+ stroke-width: 1.6;
601
+ fill: none;
602
+ }
603
+ .diagram .edge-label {
604
+ fill: var(--muted);
605
+ font: 11px var(--font);
606
+ }
607
+ .diagram .tag {
608
+ font: 700 10.5px var(--font);
609
+ }
610
+ .diagram .tag.ok {
611
+ fill: var(--good);
612
+ }
613
+ .diagram .tag.no {
614
+ fill: var(--bad);
615
+ }
616
+ .diagram .tag.miss {
617
+ fill: var(--part);
618
+ }
619
+ .diagram .tag.plain {
620
+ fill: var(--accent);
621
+ }
622
+ .diagram marker path {
623
+ fill: var(--muted);
624
+ }
625
+
626
+ /* feedback */
627
+ .feedback {
628
+ margin-top: 16px;
629
+ border-radius: 12px;
630
+ padding: 14px 16px;
631
+ border: 2px solid var(--line);
632
+ position: relative;
633
+ }
634
+ .feedback.right {
635
+ border-color: var(--good);
636
+ background: var(--good-soft);
637
+ }
638
+ .feedback.part {
639
+ border-color: var(--part);
640
+ background: var(--part-soft);
641
+ }
642
+ .feedback.wrong {
643
+ border-color: var(--bad);
644
+ background: var(--bad-soft);
645
+ }
646
+ .feedback .verdict {
647
+ font-weight: 800;
648
+ font-size: 18px;
649
+ }
650
+ .answerbox {
651
+ margin: 8px 0;
652
+ padding: 10px 12px;
653
+ border-radius: 10px;
654
+ background: var(--soft);
655
+ }
656
+ .plus {
657
+ position: absolute;
658
+ right: 16px;
659
+ top: 10px;
660
+ font-weight: 900;
661
+ font-size: 22px;
662
+ color: var(--accent);
663
+ animation: pop 1.1s ease-out;
664
+ }
665
+ @keyframes pop {
666
+ 0% {
667
+ transform: translateY(8px) scale(0.6);
668
+ opacity: 0;
669
+ }
670
+ 30% {
671
+ transform: translateY(-4px) scale(1.25);
672
+ opacity: 1;
673
+ }
674
+ 100% {
675
+ transform: translateY(0) scale(1);
676
+ }
677
+ }
678
+ .source {
679
+ font-size: 13px;
680
+ }
681
+
682
+ /* results */
683
+ .big {
684
+ font-size: 44px;
685
+ font-weight: 900;
686
+ color: var(--accent);
687
+ }
688
+ .confetti {
689
+ position: fixed;
690
+ inset: 0;
691
+ pointer-events: none;
692
+ overflow: hidden;
693
+ z-index: 20;
694
+ }
695
+ .confetti span {
696
+ position: absolute;
697
+ top: -40px;
698
+ font-size: 26px;
699
+ animation: fall 2.4s linear forwards;
700
+ }
701
+ @keyframes fall {
702
+ to {
703
+ transform: translateY(110vh) rotate(540deg);
704
+ }
705
+ }
706
+
707
+ /* coach */
708
+ .coach {
709
+ background: var(--panel);
710
+ border: 1px solid var(--line);
711
+ border-radius: var(--radius);
712
+ box-shadow: var(--shadow);
713
+ padding: 14px;
714
+ align-self: start;
715
+ position: sticky;
716
+ top: 70px;
717
+ max-height: calc(100vh - 90px);
718
+ display: flex;
719
+ flex-direction: column;
720
+ gap: 10px;
721
+ }
722
+ .coach .msgs {
723
+ overflow-y: auto;
724
+ display: grid;
725
+ gap: 8px;
726
+ }
727
+ .coach .msg {
728
+ background: var(--soft);
729
+ border-radius: 10px;
730
+ padding: 9px 11px;
731
+ font-size: 14.5px;
732
+ }
733
+ .coach .msg .t {
734
+ font-size: 11px;
735
+ color: var(--muted);
736
+ }
737
+ .coach .assigned {
738
+ border: 2px dashed var(--accent);
739
+ border-radius: 10px;
740
+ padding: 9px 11px;
741
+ font-size: 14px;
742
+ }
743
+
744
+ .toasts {
745
+ position: fixed;
746
+ right: 16px;
747
+ bottom: 16px;
748
+ display: grid;
749
+ gap: 8px;
750
+ z-index: 30;
751
+ }
752
+ .toast {
753
+ background: var(--ink);
754
+ color: var(--bg);
755
+ padding: 10px 16px;
756
+ border-radius: 12px;
757
+ box-shadow: var(--shadow);
758
+ font-weight: 700;
759
+ animation: pop 0.5s ease-out;
760
+ }
761
+ @media (max-width: 600px) {
762
+ .layout {
763
+ padding: 12px 12px 80px;
764
+ }
765
+ .card {
766
+ padding: 16px;
767
+ }
768
+ .prompt {
769
+ font-size: 17px;
770
+ }
771
+ .brand span {
772
+ display: none;
773
+ }
774
+ }
775
+
776
+ /* map halves */
777
+ h2.section {
778
+ margin: 22px 0 10px;
779
+ display: flex;
780
+ flex-wrap: wrap;
781
+ gap: 8px;
782
+ align-items: baseline;
783
+ }
784
+ .small {
785
+ font-size: 14px;
786
+ font-weight: 400;
787
+ }
788
+ .pill.ready {
789
+ background: var(--good-soft);
790
+ color: var(--good);
791
+ margin-right: 4px;
792
+ }