doru 1.0.0 → 1.1.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.
@@ -1,82 +1,170 @@
1
1
  :root {
2
- /* base surfaces */
3
- --bg: #1a1a1f;
4
- --bg-alt: #202025;
5
- --surface: #26262c;
6
- --surface-2: #2e2e36;
2
+ /* ui-style-core §0.5 — DARK column (OKLCH, byte-exact spec values) */
3
+
4
+ /* base surfaces — neutral grays, chroma 0 */
5
+ --bg: oklch(16.5% 0 0);
6
+ --bg-alt: oklch(19% 0 0);
7
+ --surface: oklch(19% 0 0);
8
+ --surface-2: oklch(22.5% 0 0);
9
+ --surface-elevated: oklch(24.5% 0 0);
7
10
 
8
11
  /* borders */
9
- --border: #3a3a44;
10
- --border-hover: #4a4a56;
12
+ --border: oklch(25% 0 0);
13
+ --border-hover: oklch(30% 0 0);
11
14
 
12
15
  /* text hierarchy */
13
- --fg: #f5f5f7;
14
- --fg-2: #d0d0d8;
15
- --muted: #9090a0;
16
-
17
- /* accent - amber/orange */
18
- --accent: #f59e0b;
19
- --accent-dim: rgba(245, 158, 11, 0.18);
20
-
21
- /* semantic colors */
22
- --green: #34d399;
23
- --yellow: #fbbf24;
24
- --red: #f87171;
25
- --blue: #60a5fa;
26
-
27
- /* status icon colors (for CSS var fallbacks) */
28
- --color-success: #22c55e;
29
- --color-redirect: #3b82f6;
30
- --color-warning: #f59e0b;
31
- --color-error: #ef4444;
32
- --color-muted: #6b7280;
16
+ --fg: oklch(84% 0 0);
17
+ --fg-2: oklch(62% 0 0);
18
+ --muted: oklch(62% 0 0);
19
+ --fg-3: oklch(48% 0 0);
20
+
21
+ /* accent — desaturated violet (hue ~300, chroma <= 0.03) */
22
+ --accent: oklch(68% 0.025 300);
23
+ --accent-hover: oklch(74% 0.025 300);
24
+ --accent-fg: oklch(16.5% 0 0);
25
+ --accent-dim: oklch(25.5% 0.01 300);
26
+
27
+ /* primary / selection / focus */
28
+ --primary: oklch(68% 0.022 300);
29
+ --primary-hover: oklch(74% 0.022 300);
30
+ --primary-light: oklch(25.5% 0.01 300);
31
+ --focus: oklch(66% 0.018 300);
32
+ --overlay: oklch(0% 0 0 / 0.62);
33
+
34
+ /* dark mark on solid status-icon fills (constant across themes) */
35
+ --icon-mark: oklch(22% 0 0);
36
+
37
+ /* status — saturated chroma reserved for success/warning/error */
38
+ --green: oklch(73% 0.12 155);
39
+ --yellow: oklch(79% 0.115 75);
40
+ --red: oklch(72% 0.145 25);
41
+ --blue: oklch(68% 0.022 300);
42
+ --success-bg: oklch(27% 0.045 155);
43
+ --warning-bg: oklch(30% 0.045 75);
44
+ --error-bg: oklch(29% 0.055 25);
45
+ --green-dim: var(--success-bg);
46
+ --red-dim: var(--error-bg);
47
+
48
+ /* status icon colors — aliased to the semantic ramp (single source) */
49
+ --color-success: var(--green);
50
+ --color-redirect: var(--blue);
51
+ --color-warning: var(--yellow);
52
+ --color-error: var(--red);
53
+ --color-muted: var(--muted);
33
54
 
34
55
  /* derived */
35
- --pill: #3a3a44;
36
- --shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
37
-
38
- /* typography */
39
- --font-mono: "SF Mono", "Fira Code", "JetBrains Mono", ui-monospace, monospace;
40
- --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
56
+ --pill: oklch(22.5% 0 0);
57
+ --shadow: var(--shadow-popover);
58
+
59
+ /* typography — Inter (sans) + JetBrains Mono (identifiers/paths/counts) */
60
+ --font-mono: "JetBrains Mono", "SF Mono", "Menlo", ui-monospace, monospace;
61
+ --font-sans: "Inter", "Public Sans", "Avenir Next", system-ui, sans-serif;
62
+
63
+ /* motion */
64
+ --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
65
+
66
+ /* radius scale — default 6, chips/badges 4, dialogs 8 */
67
+ --radius-sm: 4px;
68
+ --radius: 6px;
69
+ --radius-lg: 8px;
70
+
71
+ /* spacing scale */
72
+ --sp-1: 4px;
73
+ --sp-2: 8px;
74
+ --sp-3: 12px;
75
+ --sp-4: 16px;
76
+ --sp-5: 24px;
77
+
78
+ /* type scale */
79
+ --text-2xs: 10px;
80
+ --text-xs: 11px;
81
+ --text-sm: 12px;
82
+ --text-base: 14px;
83
+ --text-lg: 18px;
84
+ --text-display: 24px;
85
+
86
+ /* elevation = surface steps + 1px borders; the only shadow is popover (floats) */
87
+ --shadow-popover: 0 20px 50px oklch(0% 0 0 / 0.34), 0 1px 0 oklch(100% 0 0 / 0.03) inset;
88
+
89
+ /* status badge pairs: fg on tinted bg */
90
+ --status-2xx-fg: var(--green);
91
+ --status-2xx-bg: var(--success-bg);
92
+ --status-3xx-fg: var(--primary);
93
+ --status-3xx-bg: var(--primary-light);
94
+ --status-4xx-fg: var(--yellow);
95
+ --status-4xx-bg: var(--warning-bg);
96
+ --status-5xx-fg: var(--red);
97
+ --status-5xx-bg: var(--error-bg);
41
98
  }
42
99
 
43
100
  /* light theme */
44
101
  [data-theme="light"] {
102
+ /* ui-style-core §0.5 — LIGHT column */
103
+
45
104
  /* base surfaces */
46
- --bg: #f5f5f7;
47
- --bg-alt: #eeeef0;
48
- --surface: #ffffff;
49
- --surface-2: #f0f0f2;
105
+ --bg: oklch(97.8% 0 0);
106
+ --bg-alt: oklch(100% 0 0);
107
+ --surface: oklch(100% 0 0);
108
+ --surface-2: oklch(96.3% 0 0);
109
+ --surface-elevated: oklch(100% 0 0);
50
110
 
51
111
  /* borders */
52
- --border: #d4d4d8;
53
- --border-hover: #a1a1aa;
112
+ --border: oklch(90% 0 0);
113
+ --border-hover: oklch(82% 0 0);
54
114
 
55
115
  /* text hierarchy */
56
- --fg: #18181b;
57
- --fg-2: #3f3f46;
58
- --muted: #71717a;
59
-
60
- /* accent - darker amber for light bg */
61
- --accent: #d97706;
62
- --accent-dim: rgba(217, 119, 6, 0.15);
63
-
64
- /* semantic colors - darker for light bg */
65
- --green: #16a34a;
66
- --yellow: #ca8a04;
67
- --red: #dc2626;
68
- --blue: #2563eb;
69
-
70
- /* status icon colors - adjusted for light bg */
71
- --color-success: #16a34a;
72
- --color-redirect: #2563eb;
73
- --color-warning: #d97706;
74
- --color-error: #dc2626;
75
- --color-muted: #71717a;
116
+ --fg: oklch(24% 0 0);
117
+ --fg-2: oklch(54% 0 0);
118
+ --muted: oklch(54% 0 0);
119
+ --fg-3: oklch(68% 0 0);
120
+
121
+ /* accent — desaturated violet */
122
+ --accent: oklch(52% 0.03 300);
123
+ --accent-hover: oklch(46% 0.03 300);
124
+ --accent-fg: oklch(100% 0 0);
125
+ --accent-dim: oklch(93% 0.008 300);
126
+
127
+ /* primary / selection / focus */
128
+ --primary: oklch(48% 0.025 300);
129
+ --primary-hover: oklch(42% 0.025 300);
130
+ --primary-light: oklch(93% 0.008 300);
131
+ --focus: oklch(60% 0.025 300);
132
+ --overlay: oklch(0% 0 0 / 0.42);
133
+
134
+ /* status */
135
+ --green: oklch(55% 0.13 155);
136
+ --yellow: oklch(64% 0.13 75);
137
+ --red: oklch(56% 0.16 25);
138
+ --blue: oklch(48% 0.025 300);
139
+ --success-bg: oklch(94.5% 0.045 155);
140
+ --warning-bg: oklch(95% 0.05 75);
141
+ --error-bg: oklch(94.5% 0.045 25);
142
+ --green-dim: var(--success-bg);
143
+ --red-dim: var(--error-bg);
144
+
145
+ /* status icon colors — aliased to the semantic ramp (single source) */
146
+ --color-success: var(--green);
147
+ --color-redirect: var(--blue);
148
+ --color-warning: var(--yellow);
149
+ --color-error: var(--red);
150
+ --color-muted: var(--muted);
76
151
 
77
152
  /* derived */
78
- --pill: #e4e4e7;
79
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
153
+ --pill: oklch(96.3% 0 0);
154
+ --shadow: var(--shadow-popover);
155
+
156
+ /* popover shadow — softer recipe on a light background */
157
+ --shadow-popover: 0 18px 45px oklch(20% 0 0 / 0.16), 0 2px 10px oklch(20% 0 0 / 0.07);
158
+
159
+ /* status badge pairs */
160
+ --status-2xx-fg: var(--green);
161
+ --status-2xx-bg: var(--success-bg);
162
+ --status-3xx-fg: var(--primary);
163
+ --status-3xx-bg: var(--primary-light);
164
+ --status-4xx-fg: var(--yellow);
165
+ --status-4xx-bg: var(--warning-bg);
166
+ --status-5xx-fg: var(--red);
167
+ --status-5xx-bg: var(--error-bg);
80
168
  }
81
169
 
82
170
  * {
@@ -93,12 +181,16 @@ body {
93
181
  margin: 0;
94
182
  background: var(--bg);
95
183
  color: var(--fg);
96
- font: 12px/1.5 var(--font-sans);
184
+ font: 14px/1.5 var(--font-sans);
97
185
  overflow: hidden;
98
186
  -webkit-font-smoothing: antialiased;
99
187
  -moz-osx-font-smoothing: grayscale;
100
188
  }
101
189
 
190
+ ::selection {
191
+ background: oklch(60% 0.02 300 / 0.18);
192
+ }
193
+
102
194
  #app {
103
195
  width: 100vw;
104
196
  height: 100vh;
@@ -137,7 +229,7 @@ header {
137
229
 
138
230
  header .brand {
139
231
  display: flex;
140
- gap: 8px;
232
+ gap: 9px;
141
233
  align-items: center;
142
234
  font-weight: 500;
143
235
  font-size: 13px;
@@ -145,25 +237,31 @@ header .brand {
145
237
  color: var(--fg-2);
146
238
  }
147
239
 
148
- .badge {
240
+ .brand--term .brand-term {
241
+ display: inline-flex;
242
+ align-items: center;
149
243
  font-family: var(--font-mono);
244
+ font-size: 15px;
150
245
  font-weight: 600;
151
- font-size: 11px;
152
- padding: 2px 6px;
153
- border-radius: 3px;
246
+ letter-spacing: 0.02em;
247
+ color: var(--fg);
248
+ }
249
+ .brand--term .term-prompt {
250
+ color: var(--accent);
251
+ font-weight: 700;
252
+ margin-right: 5px;
253
+ }
254
+ .brand--term .term-caret {
255
+ width: 7px;
256
+ height: 15px;
257
+ margin-left: 4px;
154
258
  background: var(--accent);
155
- color: var(--bg);
156
- text-transform: uppercase;
157
- letter-spacing: 0.5px;
259
+ animation: brand-caret 1.1s steps(1) infinite;
158
260
  }
159
-
160
- .brand-name {
161
- font-family: var(--font-mono);
162
- font-weight: 600;
163
- font-size: 12px;
164
- letter-spacing: 0.1em;
165
- text-transform: uppercase;
166
- color: var(--fg);
261
+ @keyframes brand-caret {
262
+ 50% {
263
+ opacity: 0;
264
+ }
167
265
  }
168
266
 
169
267
  .input,
@@ -193,14 +291,14 @@ header .brand {
193
291
  background: var(--surface);
194
292
  color: var(--fg-2);
195
293
  border-radius: var(--radius);
196
- padding: 5px 10px;
294
+ padding: 6px 12px;
197
295
  cursor: pointer;
198
- font-family: var(--font-mono);
199
- font-size: 11px;
200
- transition: all 0.1s ease;
296
+ font-family: var(--font-sans);
297
+ font-size: 12px;
298
+ transition: background-color 0.12s var(--ease-out), border-color 0.12s var(--ease-out), color 0.12s var(--ease-out);
201
299
  }
202
300
 
203
- .btn:hover {
301
+ .btn:not(:disabled):hover {
204
302
  background: var(--surface-2);
205
303
  border-color: var(--border-hover);
206
304
  color: var(--fg);
@@ -224,7 +322,7 @@ header .brand {
224
322
  }
225
323
 
226
324
  #stats {
227
- font-family: var(--font-mono);
325
+ font-family: var(--font-sans);
228
326
  color: var(--muted);
229
327
  font-size: 11px;
230
328
  }
@@ -235,6 +333,21 @@ header .brand {
235
333
  gap: 12px;
236
334
  }
237
335
 
336
+ .pause-btn {
337
+ display: inline-flex;
338
+ align-items: center;
339
+ justify-content: center;
340
+ min-width: 74px;
341
+ }
342
+
343
+ .pause-btn.live {
344
+ color: var(--green);
345
+ }
346
+
347
+ .pause-btn.paused {
348
+ color: var(--yellow);
349
+ }
350
+
238
351
  /* main layout */
239
352
  main {
240
353
  display: flex;
@@ -294,8 +407,8 @@ main {
294
407
  gap: 6px;
295
408
  align-items: center;
296
409
  padding: 4px 8px;
297
- font-family: var(--font-mono);
298
- font-size: 10px;
410
+ font-family: var(--font-sans);
411
+ font-size: 11px;
299
412
  text-transform: uppercase;
300
413
  letter-spacing: 0.5px;
301
414
  color: var(--muted);
@@ -342,6 +455,7 @@ main {
342
455
  border-bottom: 1px solid var(--border);
343
456
  cursor: pointer;
344
457
  min-width: 0;
458
+ font-size: var(--text-xs);
345
459
  transition: background 0.05s ease;
346
460
  }
347
461
 
@@ -392,7 +506,7 @@ main {
392
506
 
393
507
  .pill {
394
508
  padding: 1px 6px;
395
- border-radius: 3px;
509
+ border-radius: var(--radius-sm);
396
510
  font-family: var(--font-mono);
397
511
  font-weight: 600;
398
512
  font-size: 10px;
@@ -405,7 +519,7 @@ main {
405
519
 
406
520
  .status {
407
521
  padding: 1px 6px;
408
- border-radius: 3px;
522
+ border-radius: var(--radius-sm);
409
523
  font-family: var(--font-mono);
410
524
  font-weight: 600;
411
525
  font-size: 10px;
@@ -414,38 +528,20 @@ main {
414
528
  }
415
529
 
416
530
  .s-2 {
417
- background: rgba(52, 211, 153, 0.2);
418
- color: #6ee7b7;
531
+ background: var(--status-2xx-bg);
532
+ color: var(--status-2xx-fg);
419
533
  }
420
534
  .s-3 {
421
- background: rgba(251, 191, 36, 0.2);
422
- color: #fcd34d;
535
+ background: var(--status-3xx-bg);
536
+ color: var(--status-3xx-fg);
423
537
  }
424
538
  .s-4 {
425
- background: rgba(251, 146, 60, 0.2);
426
- color: #fdba74;
539
+ background: var(--status-4xx-bg);
540
+ color: var(--status-4xx-fg);
427
541
  }
428
542
  .s-5 {
429
- background: rgba(248, 113, 113, 0.2);
430
- color: #fca5a5;
431
- }
432
-
433
- /* light theme status badges */
434
- [data-theme="light"] .s-2 {
435
- background: rgba(22, 163, 74, 0.15);
436
- color: #15803d;
437
- }
438
- [data-theme="light"] .s-3 {
439
- background: rgba(202, 138, 4, 0.15);
440
- color: #a16207;
441
- }
442
- [data-theme="light"] .s-4 {
443
- background: rgba(234, 88, 12, 0.15);
444
- color: #c2410c;
445
- }
446
- [data-theme="light"] .s-5 {
447
- background: rgba(220, 38, 38, 0.15);
448
- color: #b91c1c;
543
+ background: var(--status-5xx-bg);
544
+ color: var(--status-5xx-fg);
449
545
  }
450
546
 
451
547
  .muted {
@@ -512,8 +608,8 @@ main {
512
608
  display: flex;
513
609
  gap: 12px;
514
610
  font-family: var(--font-mono);
515
- color: var(--muted);
516
- font-size: 10px;
611
+ color: var(--fg-3);
612
+ font-size: var(--text-2xs);
517
613
  }
518
614
 
519
615
  /* tabs */
@@ -536,7 +632,7 @@ main {
536
632
  background: transparent;
537
633
  cursor: pointer;
538
634
  color: var(--muted);
539
- font-family: var(--font-mono);
635
+ font-family: var(--font-sans);
540
636
  font-size: 11px;
541
637
  font-weight: 500;
542
638
  text-transform: uppercase;
@@ -614,12 +710,12 @@ main {
614
710
  .panel .title {
615
711
  flex: 0 0 auto;
616
712
  padding: 6px 10px;
617
- font-family: var(--font-mono);
618
- font-size: 10px;
619
- font-weight: 500;
713
+ font-family: var(--font-sans);
714
+ font-size: var(--text-2xs);
715
+ font-weight: 600;
620
716
  text-transform: uppercase;
621
717
  letter-spacing: 0.5px;
622
- color: var(--muted);
718
+ color: var(--fg-2);
623
719
  background: var(--surface-2);
624
720
  border-bottom: 1px solid var(--border);
625
721
  display: flex;
@@ -685,7 +781,7 @@ pre.code {
685
781
  }
686
782
 
687
783
  .kv .v {
688
- color: var(--fg-2);
784
+ color: var(--fg);
689
785
  word-break: break-all;
690
786
  }
691
787
 
@@ -697,15 +793,13 @@ pre.code {
697
793
  }
698
794
 
699
795
  .section-label {
700
- padding: 6px 10px;
701
- font-family: var(--font-mono);
702
- font-size: 9px;
796
+ padding: var(--sp-3) 10px var(--sp-1);
797
+ font-family: var(--font-sans);
798
+ font-size: var(--text-2xs);
703
799
  font-weight: 500;
704
800
  text-transform: uppercase;
705
801
  letter-spacing: 0.5px;
706
802
  color: var(--muted);
707
- background: var(--surface-2);
708
- border-bottom: 1px solid var(--border);
709
803
  }
710
804
 
711
805
  /* code and preview */
@@ -725,6 +819,13 @@ pre.code {
725
819
  color: var(--fg-2);
726
820
  }
727
821
 
822
+ /* react-json-view: tighten the library's per-row padding to match code density */
823
+ .react-json-view .variable-row {
824
+ padding-top: 1px !important;
825
+ padding-bottom: 1px !important;
826
+ line-height: 1.4 !important;
827
+ }
828
+
728
829
  .controls {
729
830
  display: flex;
730
831
  gap: 6px;
@@ -747,6 +848,16 @@ pre.code {
747
848
  font-size: 10px;
748
849
  }
749
850
 
851
+ .controls .btn.copied {
852
+ color: var(--green);
853
+ border-color: var(--green);
854
+ }
855
+
856
+ .controls .btn.error {
857
+ color: var(--red);
858
+ border-color: var(--red);
859
+ }
860
+
750
861
  iframe.preview {
751
862
  width: 100%;
752
863
  height: 100%;
@@ -775,9 +886,9 @@ footer {
775
886
  padding: 0 12px;
776
887
  border-top: 1px solid var(--border);
777
888
  background: var(--bg);
778
- color: var(--muted);
889
+ color: var(--fg-3);
779
890
  font-family: var(--font-mono);
780
- font-size: 10px;
891
+ font-size: var(--text-2xs);
781
892
  display: flex;
782
893
  align-items: center;
783
894
  justify-content: space-between;
@@ -799,7 +910,7 @@ footer {
799
910
  gap: 6px;
800
911
  padding: 4px 10px;
801
912
  border: none;
802
- border-radius: 4px;
913
+ border-radius: var(--radius);
803
914
  background: transparent;
804
915
  color: var(--muted);
805
916
  cursor: pointer;
@@ -852,33 +963,37 @@ footer {
852
963
  flex-shrink: 0;
853
964
  }
854
965
 
966
+ .status-icon path {
967
+ stroke: var(--icon-mark);
968
+ }
969
+
855
970
  /* copy as cURL button */
856
971
  .copy-curl-btn {
857
972
  border: 1px solid var(--border);
858
973
  background: var(--surface);
859
974
  color: var(--fg-2);
860
- border-radius: 4px;
975
+ border-radius: var(--radius);
861
976
  padding: 3px 8px;
862
977
  cursor: pointer;
863
- font-family: var(--font-mono);
864
- font-size: 10px;
865
- transition: all 0.1s ease;
978
+ font-family: var(--font-sans);
979
+ font-size: 11px;
980
+ transition: background-color 0.12s var(--ease-out), border-color 0.12s var(--ease-out), color 0.12s var(--ease-out);
866
981
  margin-left: 8px;
867
982
  }
868
983
 
869
- .copy-curl-btn:hover {
984
+ .copy-curl-btn:not(:disabled):hover {
870
985
  background: var(--surface-2);
871
986
  border-color: var(--border-hover);
872
987
  }
873
988
 
874
989
  .copy-curl-btn.copied {
875
- background: rgba(52, 211, 153, 0.2);
990
+ background: var(--green-dim);
876
991
  border-color: var(--green);
877
992
  color: var(--green);
878
993
  }
879
994
 
880
995
  .copy-curl-btn.error {
881
- background: rgba(248, 113, 113, 0.2);
996
+ background: var(--red-dim);
882
997
  border-color: var(--red);
883
998
  color: var(--red);
884
999
  }
@@ -951,7 +1066,7 @@ footer {
951
1066
  border: 1px solid var(--border);
952
1067
  background: var(--surface);
953
1068
  color: var(--fg-2);
954
- border-radius: 4px;
1069
+ border-radius: var(--radius);
955
1070
  padding: 6px 12px;
956
1071
  cursor: pointer;
957
1072
  font-size: 12px;
@@ -999,9 +1114,9 @@ footer {
999
1114
 
1000
1115
  .error-boundary-retry {
1001
1116
  border: 1px solid var(--red);
1002
- background: rgba(248, 113, 113, 0.1);
1117
+ background: var(--red-dim);
1003
1118
  color: var(--red);
1004
- border-radius: 4px;
1119
+ border-radius: var(--radius);
1005
1120
  padding: 8px 16px;
1006
1121
  cursor: pointer;
1007
1122
  font-size: 12px;
@@ -1053,7 +1168,7 @@ footer {
1053
1168
  }
1054
1169
 
1055
1170
  .waterfall-time-marker {
1056
- font-size: 9px;
1171
+ font-size: var(--text-2xs);
1057
1172
  }
1058
1173
 
1059
1174
  .waterfall-body {
@@ -1120,32 +1235,35 @@ footer {
1120
1235
  flex-direction: column;
1121
1236
  height: 100%;
1122
1237
  width: 100%;
1238
+ max-width: 1200px;
1239
+ margin-inline: auto;
1123
1240
  overflow: auto;
1124
- padding: 16px;
1125
- gap: 16px;
1241
+ padding: var(--sp-4);
1242
+ gap: var(--sp-4);
1126
1243
  background: var(--bg);
1127
1244
  }
1128
1245
 
1129
1246
  .analytics-stats {
1130
1247
  display: grid;
1131
1248
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
1132
- gap: 12px;
1249
+ gap: var(--sp-3);
1133
1250
  }
1134
1251
 
1135
1252
  .stat-card {
1136
1253
  background: var(--surface);
1137
1254
  border: 1px solid var(--border);
1138
- border-radius: 8px;
1139
- padding: 16px;
1255
+ border-radius: var(--radius-lg);
1256
+ padding: var(--sp-4);
1140
1257
  text-align: center;
1141
1258
  }
1142
1259
 
1143
1260
  .stat-value {
1144
1261
  font-family: var(--font-mono);
1145
- font-size: 24px;
1262
+ font-size: var(--text-display);
1146
1263
  font-weight: 600;
1147
1264
  color: var(--fg);
1148
1265
  margin-bottom: 4px;
1266
+ font-variant-numeric: tabular-nums;
1149
1267
  }
1150
1268
 
1151
1269
  .stat-label {
@@ -1164,15 +1282,15 @@ footer {
1164
1282
  .analytics-section {
1165
1283
  background: var(--surface);
1166
1284
  border: 1px solid var(--border);
1167
- border-radius: 8px;
1168
- padding: 16px;
1285
+ border-radius: var(--radius-lg);
1286
+ padding: var(--sp-4);
1169
1287
  }
1170
1288
 
1171
1289
  .analytics-section h3 {
1172
1290
  margin: 0 0 12px;
1173
- font-size: 12px;
1291
+ font-size: var(--text-xs);
1174
1292
  font-weight: 600;
1175
- color: var(--fg);
1293
+ color: var(--fg-2);
1176
1294
  text-transform: uppercase;
1177
1295
  letter-spacing: 0.5px;
1178
1296
  }
@@ -1263,7 +1381,7 @@ footer {
1263
1381
 
1264
1382
  #sumUrl .method {
1265
1383
  padding: 2px 6px;
1266
- border-radius: 3px;
1384
+ border-radius: var(--radius-sm);
1267
1385
  font-size: 10px;
1268
1386
  font-weight: 600;
1269
1387
  color: #fff;
@@ -1281,13 +1399,93 @@ footer {
1281
1399
  align-items: center;
1282
1400
  gap: 12px;
1283
1401
  font-family: var(--font-mono);
1284
- font-size: 11px;
1285
- color: var(--muted);
1402
+ font-size: var(--text-xs);
1403
+ color: var(--fg-3);
1286
1404
  }
1287
1405
 
1288
1406
  #sumStatus {
1289
1407
  padding: 4px 10px;
1290
- border-radius: 4px;
1291
- font-size: 12px;
1408
+ border-radius: var(--radius);
1409
+ font-size: var(--text-sm);
1292
1410
  font-weight: 600;
1293
1411
  }
1412
+
1413
+ /* interaction & accessibility states */
1414
+
1415
+ .btn:focus-visible,
1416
+ .input:focus-visible,
1417
+ .select:focus-visible,
1418
+ .tab-btn:focus-visible,
1419
+ .view-btn:focus-visible,
1420
+ .copy-curl-btn:focus-visible,
1421
+ .empty-state-action:focus-visible,
1422
+ .error-boundary-retry:focus-visible,
1423
+ .row:focus-visible,
1424
+ .sortable:focus-visible,
1425
+ .analytics-table tr.clickable:focus-visible {
1426
+ outline: 2px solid var(--focus);
1427
+ outline-offset: 2px;
1428
+ }
1429
+
1430
+ .tab-btn:focus-visible,
1431
+ .view-btn:focus-visible,
1432
+ .sortable:focus-visible {
1433
+ outline-offset: -2px;
1434
+ }
1435
+
1436
+ .btn:disabled,
1437
+ .copy-curl-btn:disabled,
1438
+ .empty-state-action:disabled,
1439
+ .input:disabled,
1440
+ .select:disabled {
1441
+ opacity: 0.45;
1442
+ cursor: not-allowed;
1443
+ }
1444
+
1445
+ .sortable.active {
1446
+ font-weight: 600;
1447
+ }
1448
+
1449
+ @media (pointer: coarse) {
1450
+ .btn,
1451
+ .input,
1452
+ .select,
1453
+ .tab-btn,
1454
+ .view-btn,
1455
+ .copy-curl-btn,
1456
+ .empty-state-action {
1457
+ min-height: 40px;
1458
+ }
1459
+ .controls .btn {
1460
+ min-height: 36px;
1461
+ }
1462
+ }
1463
+
1464
+ @media (prefers-reduced-motion: reduce) {
1465
+ *,
1466
+ *::before,
1467
+ *::after {
1468
+ animation-duration: 0.01ms !important;
1469
+ animation-iteration-count: 1 !important;
1470
+ transition-duration: 0.01ms !important;
1471
+ }
1472
+ .skeleton {
1473
+ animation: none;
1474
+ background: var(--surface-2);
1475
+ }
1476
+ }
1477
+
1478
+ @media (max-width: 520px) {
1479
+ header {
1480
+ padding: 0 var(--sp-2);
1481
+ }
1482
+ .header-right {
1483
+ gap: var(--sp-2);
1484
+ }
1485
+ #stats {
1486
+ display: none;
1487
+ }
1488
+ #filterBar {
1489
+ gap: var(--sp-1);
1490
+ }
1491
+ }