@troyio/vite-file-router 0.4.0 → 0.5.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,231 +1,1490 @@
1
- :root {
2
- color-scheme: light dark;
3
- font-family: Inter, ui-sans-serif, system-ui, sans-serif;
4
- font-size: 13px;
5
- color: #24292f;
6
- background: #fff;
7
- font-synthesis: none;
8
- text-rendering: optimizeLegibility;
9
- }
10
-
11
- * {
12
- box-sizing: border-box;
13
- }
14
-
15
- body {
16
- margin: 0;
17
- min-width: 320px;
18
- }
19
-
20
- main {
21
- max-width: 1100px;
22
- margin: 0 auto;
23
- padding: 24px;
24
- }
25
-
26
- header,
27
- .toolbar {
28
- display: flex;
29
- align-items: center;
30
- justify-content: space-between;
31
- gap: 16px;
32
- }
33
-
34
- header {
35
- margin-bottom: 20px;
36
- }
37
-
38
- .eyebrow {
39
- margin: 0 0 5px;
40
- color: #6e7781;
41
- font-size: 10px;
42
- font-weight: 700;
43
- letter-spacing: 0.1em;
44
- }
45
-
46
- h1 {
47
- margin: 0;
48
- font-size: 22px;
49
- }
50
-
51
- #status {
52
- margin: 6px 0 0;
53
- color: #6e7781;
54
- }
55
-
56
- button,
57
- input {
58
- min-height: 34px;
59
- border: 1px solid #d0d7de;
60
- border-radius: 6px;
61
- background: #fff;
62
- color: inherit;
63
- font: inherit;
64
- }
65
-
66
- button {
67
- padding: 0 12px;
68
- cursor: pointer;
69
- }
70
-
71
- button:hover {
72
- background: #f6f8fa;
73
- }
74
-
75
- .toolbar {
76
- justify-content: flex-start;
77
- margin-bottom: 16px;
78
- }
79
-
80
- .search {
81
- flex: 1;
82
- }
83
-
84
- input {
85
- width: 100%;
86
- padding: 0 10px;
87
- }
88
-
89
- #error {
90
- padding: 10px;
91
- border: 1px solid #cf222e;
92
- border-radius: 6px;
93
- color: #cf222e;
94
- }
95
-
96
- .route-list,
97
- .file-list {
98
- margin: 0;
99
- padding-left: 20px;
100
- list-style: none;
101
- }
102
-
103
- .root-list {
104
- padding: 0;
105
- }
106
-
107
- .route-node {
108
- position: relative;
109
- padding: 3px 0;
110
- }
111
-
112
- .route-details {
113
- min-width: 0;
114
- }
115
-
116
- .route-summary {
117
- display: flex;
118
- align-items: center;
119
- flex-wrap: wrap;
120
- gap: 7px;
121
- min-height: 28px;
122
- cursor: pointer;
123
- }
124
-
125
- .route-path,
126
- .file-path {
127
- overflow-wrap: anywhere;
128
- font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
129
- }
130
-
131
- .route-path {
132
- color: #0969da;
133
- font-weight: 600;
134
- }
135
-
136
- .badge {
137
- padding: 2px 6px;
138
- border-radius: 10px;
139
- background: #ddf4ff;
140
- color: #0550ae;
141
- font-size: 11px;
142
- }
143
-
144
- .group-badge {
145
- background: #fbefff;
146
- color: #8250df;
147
- }
148
-
149
- .optional-badge {
150
- background: #fff8c5;
151
- color: #7d4e00;
152
- }
153
-
154
- .file-list {
155
- padding-top: 3px;
156
- padding-bottom: 5px;
157
- }
158
-
159
- .file-row {
160
- display: flex;
161
- flex-wrap: wrap;
162
- gap: 10px;
163
- padding: 3px 0;
164
- color: #57606a;
165
- }
166
-
167
- .file-kind {
168
- min-width: 90px;
169
- font-weight: 600;
170
- }
171
-
172
- .empty {
173
- padding: 20px 0;
174
- color: #6e7781;
175
- }
176
-
177
- .visually-hidden {
178
- position: absolute;
179
- width: 1px;
180
- height: 1px;
181
- overflow: hidden;
182
- clip: rect(0, 0, 0, 0);
183
- white-space: nowrap;
184
- }
185
-
186
- @media (prefers-color-scheme: dark) {
187
- :root {
188
- color: #e6edf3;
189
- background: #0d1117;
190
- }
191
-
192
- button,
193
- input {
194
- border-color: #30363d;
195
- background: #161b22;
196
- }
197
-
198
- button:hover {
199
- background: #21262d;
200
- }
201
-
202
- #error {
203
- color: #ff7b72;
204
- }
205
-
206
- .route-path {
207
- color: #79c0ff;
208
- }
209
-
210
- .badge {
211
- background: #0c2d6b;
212
- color: #a5d6ff;
213
- }
214
-
215
- .group-badge {
216
- background: #2d1f4d;
217
- color: #d2a8ff;
218
- }
219
-
220
- .optional-badge {
221
- background: #3d2e00;
222
- color: #eac54f;
223
- }
224
-
225
- .file-row,
226
- .empty,
227
- #status,
228
- .eyebrow {
229
- color: #8b949e;
230
- }
231
- }
1
+ :root {
2
+ color-scheme: light;
3
+ --bg: #f5f5f5;
4
+ --surface: #ffffff;
5
+ --surface-2: #f0f0f0;
6
+ --border: #e3e3e3;
7
+ --border-strong: #c8c8c8;
8
+ --text: #171717;
9
+ --text-2: #4a4a4a;
10
+ --text-3: #737373;
11
+ --accent: #171717;
12
+ --accent-contrast: #ffffff;
13
+ --accent-soft: #ebebeb;
14
+ --accent-text: #171717;
15
+ --success: #3f9a62;
16
+ --success-soft: #f0f0f0;
17
+ --success-text: #4a4a4a;
18
+ --warning: #b7791f;
19
+ --warning-soft: #f0f0f0;
20
+ --warning-text: #8a5a14;
21
+ --danger: #c2413a;
22
+ --danger-soft: #f0f0f0;
23
+ --danger-text: #a3342e;
24
+ --info-soft: #f0f0f0;
25
+ --info-text: #4a4a4a;
26
+ --match: #f0f0f0;
27
+ --shadow: none;
28
+ --ring: 0 0 0 2px #a3a3a3;
29
+ --radius: 0;
30
+ --mono: ui-monospace, "JetBrains Mono", SFMono-Regular, Menlo, Consolas, monospace;
31
+
32
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
33
+ font-size: 13px;
34
+ line-height: 1.45;
35
+ color: var(--text);
36
+ background: var(--bg);
37
+ font-synthesis: none;
38
+ text-rendering: optimizeLegibility;
39
+ -webkit-font-smoothing: antialiased;
40
+ }
41
+
42
+ @media (prefers-color-scheme: dark) {
43
+ :root {
44
+ color-scheme: dark;
45
+ --bg: #111111;
46
+ --surface: #171717;
47
+ --surface-2: #212121;
48
+ --border: #2a2a2a;
49
+ --border-strong: #3d3d3d;
50
+ --text: #ededed;
51
+ --text-2: #b5b5b5;
52
+ --text-3: #8a8a8a;
53
+ --accent: #ededed;
54
+ --accent-contrast: #111111;
55
+ --accent-soft: #2a2a2a;
56
+ --accent-text: #ededed;
57
+ --success: #5cb87e;
58
+ --success-soft: #212121;
59
+ --success-text: #b5b5b5;
60
+ --warning: #d9a441;
61
+ --warning-soft: #212121;
62
+ --warning-text: #d9a441;
63
+ --danger: #e0716a;
64
+ --danger-soft: #212121;
65
+ --danger-text: #e0857f;
66
+ --info-soft: #212121;
67
+ --info-text: #b5b5b5;
68
+ --match: #212121;
69
+ --shadow: none;
70
+ --ring: 0 0 0 2px #6b6b6b;
71
+ }
72
+ }
73
+
74
+ * {
75
+ box-sizing: border-box;
76
+ }
77
+
78
+ [hidden] {
79
+ display: none !important;
80
+ }
81
+
82
+ body {
83
+ margin: 0;
84
+ min-width: 320px;
85
+ background: var(--bg);
86
+ }
87
+
88
+ svg {
89
+ width: 16px;
90
+ height: 16px;
91
+ flex: none;
92
+ }
93
+
94
+ h1,
95
+ h2,
96
+ p {
97
+ margin: 0;
98
+ }
99
+
100
+ button,
101
+ input {
102
+ font: inherit;
103
+ color: inherit;
104
+ }
105
+
106
+ :focus-visible {
107
+ outline: none;
108
+ box-shadow: var(--ring);
109
+ }
110
+
111
+ /* Top bar */
112
+
113
+ .topbar {
114
+ position: sticky;
115
+ top: 0;
116
+ z-index: 2;
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 20px;
120
+ padding: 12px 20px;
121
+ border-bottom: 1px solid var(--border);
122
+ background: color-mix(in srgb, var(--surface) 88%, transparent);
123
+ backdrop-filter: blur(10px);
124
+ }
125
+
126
+ .brand {
127
+ display: flex;
128
+ align-items: center;
129
+ gap: 10px;
130
+ }
131
+
132
+ .brand-mark {
133
+ display: grid;
134
+ place-items: center;
135
+ width: 30px;
136
+ height: 30px;
137
+ border-radius: 0;
138
+ background: var(--accent);
139
+ color: var(--accent-contrast);
140
+ }
141
+
142
+ h1 {
143
+ font-size: 14px;
144
+ font-weight: 650;
145
+ letter-spacing: -0.01em;
146
+ }
147
+
148
+ .subtitle {
149
+ color: var(--text-3);
150
+ font-family: var(--mono);
151
+ font-size: 11px;
152
+ }
153
+
154
+ .stats {
155
+ display: flex;
156
+ gap: 6px;
157
+ margin: 0;
158
+ flex-wrap: wrap;
159
+ }
160
+
161
+ .stat {
162
+ display: flex;
163
+ align-items: baseline;
164
+ gap: 5px;
165
+ padding: 4px 9px;
166
+ border: 1px solid var(--border);
167
+ border-radius: 0;
168
+ background: var(--surface);
169
+ }
170
+
171
+ .stat dt {
172
+ order: 2;
173
+ color: var(--text-3);
174
+ font-size: 11.5px;
175
+ }
176
+
177
+ .stat dd {
178
+ margin: 0;
179
+ font-weight: 650;
180
+ font-variant-numeric: tabular-nums;
181
+ }
182
+
183
+ .topbar-actions {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 8px;
187
+ margin-left: auto;
188
+ }
189
+
190
+ .live {
191
+ display: inline-flex;
192
+ align-items: center;
193
+ gap: 7px;
194
+ padding: 4px 10px;
195
+ border-radius: 0;
196
+ background: var(--surface-2);
197
+ color: var(--text-2);
198
+ font-size: 12px;
199
+ font-weight: 550;
200
+ }
201
+
202
+ .live-dot {
203
+ position: relative;
204
+ width: 7px;
205
+ height: 7px;
206
+ border-radius: 50%;
207
+ background: var(--text-3);
208
+ }
209
+
210
+ .live[data-state="live"] {
211
+ background: var(--success-soft);
212
+ color: var(--success-text);
213
+ }
214
+
215
+ .live[data-state="live"] .live-dot {
216
+ background: var(--success);
217
+ }
218
+
219
+ .live[data-state="live"] .live-dot::after {
220
+ content: "";
221
+ position: absolute;
222
+ inset: -3px;
223
+ border-radius: 50%;
224
+ background: var(--success);
225
+ opacity: 0.35;
226
+ animation: pulse 2s ease-out infinite;
227
+ }
228
+
229
+ .live[data-state="reconnecting"] {
230
+ background: var(--warning-soft);
231
+ color: var(--warning-text);
232
+ }
233
+
234
+ .live[data-state="reconnecting"] .live-dot {
235
+ background: var(--warning);
236
+ }
237
+
238
+ @keyframes pulse {
239
+ from {
240
+ transform: scale(0.6);
241
+ opacity: 0.45;
242
+ }
243
+ to {
244
+ transform: scale(2);
245
+ opacity: 0;
246
+ }
247
+ }
248
+
249
+ @media (prefers-reduced-motion: reduce) {
250
+ .live-dot::after {
251
+ animation: none !important;
252
+ }
253
+ }
254
+
255
+ /* Controls */
256
+
257
+ .icon-button,
258
+ .button {
259
+ display: inline-flex;
260
+ align-items: center;
261
+ justify-content: center;
262
+ gap: 6px;
263
+ height: 32px;
264
+ border: 1px solid var(--border);
265
+ border-radius: 0;
266
+ background: var(--surface);
267
+ color: var(--text-2);
268
+ cursor: pointer;
269
+ transition: background 120ms, border-color 120ms, color 120ms;
270
+ }
271
+
272
+ .icon-button {
273
+ width: 32px;
274
+ padding: 0;
275
+ }
276
+
277
+ .icon-button:hover {
278
+ border-color: var(--border-strong);
279
+ background: var(--surface-2);
280
+ color: var(--text);
281
+ }
282
+
283
+ .icon-button.spinning svg {
284
+ animation: spin 600ms ease;
285
+ }
286
+
287
+ @keyframes spin {
288
+ to {
289
+ transform: rotate(360deg);
290
+ }
291
+ }
292
+
293
+ .button {
294
+ padding: 0 14px;
295
+ border-color: transparent;
296
+ background: var(--accent);
297
+ color: var(--accent-contrast);
298
+ font-weight: 600;
299
+ }
300
+
301
+ .button:hover {
302
+ filter: brightness(1.08);
303
+ }
304
+
305
+ .field {
306
+ position: relative;
307
+ display: flex;
308
+ flex: 1;
309
+ align-items: center;
310
+ min-width: 0;
311
+ }
312
+
313
+ .field input {
314
+ width: 100%;
315
+ height: 32px;
316
+ padding: 0 10px;
317
+ border: 1px solid var(--border);
318
+ border-radius: 0;
319
+ background: var(--surface);
320
+ transition: border-color 120ms, box-shadow 120ms;
321
+ }
322
+
323
+ .field input::placeholder {
324
+ color: var(--text-3);
325
+ }
326
+
327
+ .field input:focus {
328
+ border-color: var(--border-strong);
329
+ outline: none;
330
+ box-shadow: var(--ring);
331
+ }
332
+
333
+ .field-icon {
334
+ position: absolute;
335
+ left: 10px;
336
+ color: var(--text-3);
337
+ pointer-events: none;
338
+ }
339
+
340
+ .field-icon + .visually-hidden + input {
341
+ padding-left: 32px;
342
+ }
343
+
344
+ .field-mono input {
345
+ font-family: var(--mono);
346
+ font-size: 12.5px;
347
+ }
348
+
349
+ /* Alerts */
350
+
351
+ .alert,
352
+ .conflicts {
353
+ margin: 16px 20px 0;
354
+ padding: 12px 14px;
355
+ border: 1px solid var(--border);
356
+ border-radius: 0;
357
+ background: var(--surface);
358
+ color: var(--text);
359
+ }
360
+
361
+ .alert,
362
+ .conflicts h2 {
363
+ color: var(--danger-text);
364
+ }
365
+
366
+ .conflicts h2 {
367
+ margin-bottom: 6px;
368
+ font-size: 13px;
369
+ }
370
+
371
+ .conflicts p {
372
+ color: var(--text-2);
373
+ margin-bottom: 8px;
374
+ }
375
+
376
+ .conflict + .conflict {
377
+ margin-top: 8px;
378
+ }
379
+
380
+ .conflict code {
381
+ font-family: var(--mono);
382
+ font-weight: 600;
383
+ }
384
+
385
+ /* Layout */
386
+
387
+ .layout {
388
+ display: grid;
389
+ grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
390
+ gap: 16px;
391
+ align-items: start;
392
+ padding: 16px 20px 24px;
393
+ }
394
+
395
+ @media (max-width: 860px) {
396
+ .layout {
397
+ grid-template-columns: minmax(0, 1fr);
398
+ }
399
+
400
+ .topbar {
401
+ flex-wrap: wrap;
402
+ gap: 10px 16px;
403
+ }
404
+ }
405
+
406
+ .side {
407
+ display: grid;
408
+ gap: 16px;
409
+ }
410
+
411
+ @media (min-width: 861px) {
412
+ .side {
413
+ position: sticky;
414
+ top: 72px;
415
+ }
416
+ }
417
+
418
+ .panel {
419
+ min-width: 0;
420
+ border: 1px solid var(--border);
421
+ border-radius: 0;
422
+ background: var(--surface);
423
+ box-shadow: var(--shadow);
424
+ }
425
+
426
+ .panel-header {
427
+ padding: 14px 16px 0;
428
+ }
429
+
430
+ .panel-header h2 {
431
+ font-size: 13px;
432
+ font-weight: 650;
433
+ }
434
+
435
+ .panel-header p {
436
+ margin-top: 2px;
437
+ color: var(--text-3);
438
+ font-size: 12px;
439
+ }
440
+
441
+ .panel-toolbar {
442
+ display: flex;
443
+ gap: 8px;
444
+ padding: 10px;
445
+ border-bottom: 1px solid var(--border);
446
+ }
447
+
448
+ /* Tree */
449
+
450
+ .tree {
451
+ padding: 6px;
452
+ }
453
+
454
+ .tree ul {
455
+ margin: 0;
456
+ padding: 0;
457
+ list-style: none;
458
+ }
459
+
460
+ .tree ul ul {
461
+ position: relative;
462
+ margin-left: 15px;
463
+ padding-left: 9px;
464
+ }
465
+
466
+ .tree ul ul::before {
467
+ content: "";
468
+ position: absolute;
469
+ top: 0;
470
+ bottom: 6px;
471
+ left: 0;
472
+ border-left: 1px solid var(--border);
473
+ }
474
+
475
+ .row {
476
+ display: flex;
477
+ align-items: center;
478
+ gap: 6px;
479
+ min-height: 30px;
480
+ padding: 3px 8px 3px 4px;
481
+ border-radius: 0;
482
+ cursor: pointer;
483
+ user-select: none;
484
+ }
485
+
486
+ .row:hover {
487
+ background: var(--surface-2);
488
+ }
489
+
490
+ .row[aria-selected="true"] {
491
+ background: var(--accent-soft);
492
+ }
493
+
494
+ .row.matched {
495
+ background: var(--match);
496
+ }
497
+
498
+ .row.matched[aria-selected="true"] {
499
+ background: var(--accent-soft);
500
+ }
501
+
502
+ .twisty {
503
+ display: grid;
504
+ place-items: center;
505
+ width: 18px;
506
+ height: 18px;
507
+ padding: 0;
508
+ border: 0;
509
+ border-radius: 0;
510
+ background: none;
511
+ color: var(--text-3);
512
+ cursor: pointer;
513
+ }
514
+
515
+ .twisty svg {
516
+ width: 13px;
517
+ height: 13px;
518
+ transition: transform 120ms;
519
+ }
520
+
521
+ .twisty[aria-expanded="true"] svg {
522
+ transform: rotate(90deg);
523
+ }
524
+
525
+ .twisty:hover {
526
+ background: var(--border);
527
+ color: var(--text);
528
+ }
529
+
530
+ .twisty-spacer {
531
+ width: 18px;
532
+ flex: none;
533
+ }
534
+
535
+ .segment {
536
+ overflow: hidden;
537
+ font-family: var(--mono);
538
+ font-size: 12.5px;
539
+ font-weight: 550;
540
+ text-overflow: ellipsis;
541
+ white-space: nowrap;
542
+ }
543
+
544
+ .segment .slash {
545
+ color: var(--text-3);
546
+ font-weight: 400;
547
+ }
548
+
549
+ .segment .param {
550
+ color: var(--text);
551
+ font-weight: 650;
552
+ }
553
+
554
+ .segment .optional {
555
+ color: var(--text-2);
556
+ font-style: italic;
557
+ }
558
+
559
+ .segment .group {
560
+ color: var(--text-3);
561
+ font-style: italic;
562
+ }
563
+
564
+ .full-path {
565
+ overflow: hidden;
566
+ color: var(--text-3);
567
+ font-family: var(--mono);
568
+ font-size: 11.5px;
569
+ text-overflow: ellipsis;
570
+ white-space: nowrap;
571
+ }
572
+
573
+ .row-files {
574
+ display: flex;
575
+ gap: 3px;
576
+ margin-left: auto;
577
+ padding-left: 8px;
578
+ }
579
+
580
+ .chip {
581
+ display: inline-flex;
582
+ align-items: center;
583
+ height: 20px;
584
+ padding: 0 7px;
585
+ border-radius: 0;
586
+ background: var(--surface-2);
587
+ color: var(--text-2);
588
+ font-size: 11px;
589
+ font-weight: 550;
590
+ white-space: nowrap;
591
+ }
592
+
593
+ .chip-page { background: var(--surface-2); color: var(--text); }
594
+ .chip-layout { background: var(--info-soft); color: var(--info-text); }
595
+ .chip-loader,
596
+ .chip-action,
597
+ .chip-middleware { background: var(--success-soft); color: var(--success-text); }
598
+ .chip-loading { background: var(--warning-soft); color: var(--warning-text); }
599
+ .chip-error,
600
+ .chip-notFound { background: var(--danger-soft); color: var(--danger-text); }
601
+ .chip-group { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-3); }
602
+
603
+ .empty {
604
+ padding: 28px 16px;
605
+ color: var(--text-3);
606
+ text-align: center;
607
+ }
608
+
609
+ mark {
610
+ border-radius: 0;
611
+ background: var(--accent-soft);
612
+ color: inherit;
613
+ }
614
+
615
+ /* Tester */
616
+
617
+ .tester {
618
+ display: flex;
619
+ gap: 8px;
620
+ padding: 12px 16px;
621
+ }
622
+
623
+ #tester-result:not(:empty) {
624
+ padding: 0 16px 16px;
625
+ }
626
+
627
+ .result-status {
628
+ display: flex;
629
+ align-items: center;
630
+ gap: 8px;
631
+ margin-bottom: 12px;
632
+ font-weight: 600;
633
+ }
634
+
635
+ .result-status .chip {
636
+ height: 22px;
637
+ font-size: 11.5px;
638
+ }
639
+
640
+ .result-pathname {
641
+ overflow: hidden;
642
+ color: var(--text-3);
643
+ font-family: var(--mono);
644
+ font-size: 12px;
645
+ font-weight: 400;
646
+ text-overflow: ellipsis;
647
+ white-space: nowrap;
648
+ }
649
+
650
+ .crumbs {
651
+ display: flex;
652
+ flex-wrap: wrap;
653
+ align-items: center;
654
+ gap: 4px;
655
+ margin-bottom: 12px;
656
+ font-family: var(--mono);
657
+ font-size: 12px;
658
+ }
659
+
660
+ .crumb {
661
+ padding: 2px 7px;
662
+ border: 1px solid var(--border);
663
+ border-radius: 0;
664
+ background: var(--surface-2);
665
+ cursor: pointer;
666
+ }
667
+
668
+ .crumb:hover {
669
+ border-color: var(--border-strong);
670
+ }
671
+
672
+ .crumb-sep {
673
+ color: var(--text-3);
674
+ }
675
+
676
+ /* Definition lists in tester and details */
677
+
678
+ .facts {
679
+ display: grid;
680
+ gap: 10px;
681
+ margin: 0;
682
+ }
683
+
684
+ .facts > div {
685
+ display: grid;
686
+ gap: 4px;
687
+ }
688
+
689
+ .facts dt {
690
+ color: var(--text-3);
691
+ font-size: 11px;
692
+ font-weight: 600;
693
+ letter-spacing: 0.04em;
694
+ text-transform: uppercase;
695
+ }
696
+
697
+ .facts dd {
698
+ display: grid;
699
+ gap: 4px;
700
+ margin: 0;
701
+ min-width: 0;
702
+ }
703
+
704
+ .params {
705
+ display: flex;
706
+ flex-wrap: wrap;
707
+ gap: 6px;
708
+ }
709
+
710
+ .param-pill {
711
+ display: inline-flex;
712
+ overflow: hidden;
713
+ border: 1px solid var(--border);
714
+ border-radius: 0;
715
+ font-family: var(--mono);
716
+ font-size: 12px;
717
+ }
718
+
719
+ .param-pill span {
720
+ padding: 2px 7px;
721
+ }
722
+
723
+ .param-pill span:first-child {
724
+ background: var(--surface-2);
725
+ color: var(--text-2);
726
+ }
727
+
728
+ .param-pill .missing {
729
+ color: var(--text-3);
730
+ font-style: italic;
731
+ }
732
+
733
+ .file-link {
734
+ display: flex;
735
+ align-items: center;
736
+ gap: 8px;
737
+ width: 100%;
738
+ min-width: 0;
739
+ padding: 6px 8px;
740
+ border: 1px solid var(--border);
741
+ border-radius: 0;
742
+ background: var(--surface);
743
+ color: var(--text);
744
+ font-family: var(--mono);
745
+ font-size: 12px;
746
+ text-align: left;
747
+ cursor: pointer;
748
+ transition: border-color 120ms, background 120ms;
749
+ }
750
+
751
+ .file-link span {
752
+ overflow: hidden;
753
+ text-overflow: ellipsis;
754
+ white-space: nowrap;
755
+ direction: rtl;
756
+ text-align: left;
757
+ }
758
+
759
+ .file-link svg {
760
+ width: 14px;
761
+ height: 14px;
762
+ margin-left: auto;
763
+ color: var(--text-3);
764
+ opacity: 0;
765
+ transition: opacity 120ms;
766
+ }
767
+
768
+ .file-link:hover {
769
+ border-color: var(--border-strong);
770
+ background: var(--surface-2);
771
+ }
772
+
773
+ .file-link:hover svg,
774
+ .file-link:focus-visible svg {
775
+ opacity: 1;
776
+ }
777
+
778
+ .file-link.opened {
779
+ background: var(--surface-2);
780
+ }
781
+
782
+ .muted {
783
+ color: var(--text-3);
784
+ }
785
+
786
+ .details-body {
787
+ padding: 12px 16px 16px;
788
+ }
789
+
790
+ .details-path {
791
+ margin-bottom: 12px;
792
+ font-family: var(--mono);
793
+ font-size: 14px;
794
+ font-weight: 600;
795
+ overflow-wrap: anywhere;
796
+ }
797
+
798
+ .link-button {
799
+ justify-self: start;
800
+ padding: 0;
801
+ border: 0;
802
+ background: none;
803
+ color: var(--accent-text);
804
+ font-weight: 550;
805
+ cursor: pointer;
806
+ }
807
+
808
+ .link-button:hover {
809
+ text-decoration: underline;
810
+ }
811
+
812
+ .toast {
813
+ position: fixed;
814
+ bottom: 16px;
815
+ left: 50%;
816
+ z-index: 3;
817
+ padding: 8px 14px;
818
+ border-radius: 0;
819
+ background: var(--text);
820
+ color: var(--bg);
821
+ font-size: 12px;
822
+ transform: translateX(-50%);
823
+ animation: toast-in 160ms ease;
824
+ }
825
+
826
+ @keyframes toast-in {
827
+ from {
828
+ opacity: 0;
829
+ transform: translate(-50%, 6px);
830
+ }
831
+ }
832
+
833
+ .visually-hidden {
834
+ position: absolute;
835
+ width: 1px;
836
+ height: 1px;
837
+ overflow: hidden;
838
+ clip: rect(0, 0, 0, 0);
839
+ white-space: nowrap;
840
+ }
841
+
842
+ /* Current page */
843
+
844
+ .panel-header-row {
845
+ display: flex;
846
+ align-items: flex-start;
847
+ justify-content: space-between;
848
+ gap: 12px;
849
+ }
850
+
851
+ #current:not(:empty) {
852
+ padding: 12px 16px 16px;
853
+ }
854
+
855
+ .current-url {
856
+ display: flex;
857
+ align-items: center;
858
+ gap: 8px;
859
+ margin-bottom: 10px;
860
+ min-width: 0;
861
+ }
862
+
863
+ .current-url code {
864
+ overflow: hidden;
865
+ font-family: var(--mono);
866
+ font-size: 13px;
867
+ font-weight: 600;
868
+ text-overflow: ellipsis;
869
+ white-space: nowrap;
870
+ }
871
+
872
+ .current-dot {
873
+ width: 8px;
874
+ height: 8px;
875
+ flex: none;
876
+ border-radius: 50%;
877
+ background: var(--success);
878
+ }
879
+
880
+ .current-empty {
881
+ padding: 12px 16px 16px;
882
+ color: var(--text-3);
883
+ }
884
+
885
+ .tab-picker {
886
+ display: flex;
887
+ flex-wrap: wrap;
888
+ justify-content: flex-end;
889
+ gap: 4px;
890
+ }
891
+
892
+ .tab-picker button {
893
+ height: 24px;
894
+ padding: 0 8px;
895
+ border: 1px solid var(--border);
896
+ border-radius: 0;
897
+ background: var(--surface);
898
+ color: var(--text-2);
899
+ font-size: 11.5px;
900
+ cursor: pointer;
901
+ }
902
+
903
+ .tab-picker button[aria-pressed="true"] {
904
+ border-color: var(--border-strong);
905
+ background: var(--success-soft);
906
+ color: var(--success-text);
907
+ }
908
+
909
+ .row.current .segment::after {
910
+ content: "";
911
+ display: inline-block;
912
+ width: 6px;
913
+ height: 6px;
914
+ margin-left: 7px;
915
+ border-radius: 50%;
916
+ background: var(--success);
917
+ vertical-align: middle;
918
+ }
919
+
920
+
921
+ /* Tabs */
922
+
923
+ .tabs {
924
+ display: flex;
925
+ gap: 4px;
926
+ padding: 4px;
927
+ border: 1px solid var(--border);
928
+ border-radius: 0;
929
+ background: var(--surface);
930
+ }
931
+
932
+ .tab {
933
+ display: inline-flex;
934
+ flex: 1;
935
+ align-items: center;
936
+ justify-content: center;
937
+ gap: 6px;
938
+ height: 30px;
939
+ border: 0;
940
+ border-radius: 0;
941
+ background: none;
942
+ color: var(--text-2);
943
+ font-weight: 600;
944
+ cursor: pointer;
945
+ }
946
+
947
+ .tab:hover {
948
+ color: var(--text);
949
+ }
950
+
951
+ .tab[aria-selected="true"] {
952
+ background: var(--accent-soft);
953
+ color: var(--accent-text);
954
+ }
955
+
956
+ .tab-count {
957
+ min-width: 18px;
958
+ height: 18px;
959
+ padding: 0 5px;
960
+ border-radius: 0;
961
+ background: var(--accent);
962
+ color: var(--accent-contrast);
963
+ font-size: 10.5px;
964
+ line-height: 18px;
965
+ font-variant-numeric: tabular-nums;
966
+ }
967
+
968
+ .view {
969
+ display: grid;
970
+ gap: 16px;
971
+ }
972
+
973
+ .view[hidden] {
974
+ display: none;
975
+ }
976
+
977
+ .text-button {
978
+ width: auto;
979
+ padding: 0 10px;
980
+ font-size: 12px;
981
+ }
982
+
983
+ /* Timeline */
984
+
985
+ .timeline-toolbar {
986
+ display: grid;
987
+ gap: 8px;
988
+ padding: 12px 16px;
989
+ border-bottom: 1px solid var(--border);
990
+ }
991
+
992
+ .segmented {
993
+ display: flex;
994
+ gap: 2px;
995
+ padding: 2px;
996
+ border-radius: 0;
997
+ background: var(--surface-2);
998
+ }
999
+
1000
+ .segmented button {
1001
+ flex: 1;
1002
+ height: 26px;
1003
+ border: 0;
1004
+ border-radius: 0;
1005
+ background: none;
1006
+ color: var(--text-2);
1007
+ font-size: 12px;
1008
+ font-weight: 550;
1009
+ cursor: pointer;
1010
+ }
1011
+
1012
+ .segmented button[aria-pressed="true"] {
1013
+ background: var(--surface);
1014
+ color: var(--text);
1015
+ }
1016
+
1017
+ .timeline {
1018
+ max-height: 560px;
1019
+ margin: 0;
1020
+ padding: 6px;
1021
+ overflow-y: auto;
1022
+ list-style: none;
1023
+ }
1024
+
1025
+ .timeline:empty::before {
1026
+ content: attr(data-empty);
1027
+ display: block;
1028
+ padding: 24px 12px;
1029
+ color: var(--text-3);
1030
+ text-align: center;
1031
+ }
1032
+
1033
+ .call {
1034
+ border-radius: 0;
1035
+ }
1036
+
1037
+ .call + .call {
1038
+ margin-top: 2px;
1039
+ }
1040
+
1041
+ .call-summary {
1042
+ display: grid;
1043
+ grid-template-columns: auto minmax(0, 1fr) auto;
1044
+ gap: 4px 8px;
1045
+ align-items: center;
1046
+ width: 100%;
1047
+ padding: 8px 10px;
1048
+ border: 0;
1049
+ border-radius: 0;
1050
+ background: none;
1051
+ color: inherit;
1052
+ text-align: left;
1053
+ cursor: pointer;
1054
+ }
1055
+
1056
+ .call-summary:hover,
1057
+ .call[open] .call-summary {
1058
+ background: var(--surface-2);
1059
+ }
1060
+
1061
+ .call-route {
1062
+ overflow: hidden;
1063
+ font-family: var(--mono);
1064
+ font-size: 12px;
1065
+ font-weight: 600;
1066
+ text-overflow: ellipsis;
1067
+ white-space: nowrap;
1068
+ }
1069
+
1070
+ .call-meta {
1071
+ grid-column: 2 / 4;
1072
+ display: flex;
1073
+ gap: 8px;
1074
+ min-width: 0;
1075
+ color: var(--text-3);
1076
+ font-size: 11.5px;
1077
+ }
1078
+
1079
+ .call-meta span:first-child {
1080
+ overflow: hidden;
1081
+ font-family: var(--mono);
1082
+ text-overflow: ellipsis;
1083
+ white-space: nowrap;
1084
+ }
1085
+
1086
+ .call-meta time {
1087
+ margin-left: auto;
1088
+ white-space: nowrap;
1089
+ }
1090
+
1091
+ .call-duration {
1092
+ color: var(--text-2);
1093
+ font-size: 11.5px;
1094
+ font-variant-numeric: tabular-nums;
1095
+ white-space: nowrap;
1096
+ }
1097
+
1098
+ .call-duration.slow {
1099
+ color: var(--warning-text);
1100
+ font-weight: 600;
1101
+ }
1102
+
1103
+ .call-body {
1104
+ display: grid;
1105
+ gap: 10px;
1106
+ padding: 4px 10px 12px;
1107
+ }
1108
+
1109
+ .call-preview {
1110
+ max-height: 160px;
1111
+ margin: 0;
1112
+ padding: 8px 10px;
1113
+ overflow: auto;
1114
+ border: 1px solid var(--border);
1115
+ border-radius: 0;
1116
+ background: var(--surface-2);
1117
+ font-family: var(--mono);
1118
+ font-size: 11.5px;
1119
+ white-space: pre-wrap;
1120
+ word-break: break-all;
1121
+ }
1122
+
1123
+ .chip-skipped {
1124
+ background: var(--surface-2);
1125
+ color: var(--text-3);
1126
+ border: 1px dashed var(--border-strong);
1127
+ }
1128
+
1129
+ .call-summary {
1130
+ list-style: none;
1131
+ }
1132
+
1133
+ .call-summary::-webkit-details-marker {
1134
+ display: none;
1135
+ }
1136
+
1137
+ /* Missing-file warnings */
1138
+
1139
+ .warnings {
1140
+ margin: 16px 20px 0;
1141
+ border: 1px solid var(--border);
1142
+ background: var(--surface);
1143
+ }
1144
+
1145
+ .warnings > details > summary {
1146
+ display: flex;
1147
+ align-items: baseline;
1148
+ gap: 10px;
1149
+ padding: 10px 14px;
1150
+ cursor: pointer;
1151
+ list-style: none;
1152
+ }
1153
+
1154
+ .warnings > details > summary::-webkit-details-marker {
1155
+ display: none;
1156
+ }
1157
+
1158
+ .warnings > details > summary::before {
1159
+ content: "▸";
1160
+ color: var(--text-3);
1161
+ }
1162
+
1163
+ .warnings > details[open] > summary::before {
1164
+ content: "▾";
1165
+ }
1166
+
1167
+ .warnings h2 {
1168
+ font-size: 13px;
1169
+ }
1170
+
1171
+ .warnings .warning-list {
1172
+ padding: 0 14px 12px;
1173
+ }
1174
+
1175
+ .warning-list {
1176
+ display: grid;
1177
+ gap: 8px;
1178
+ margin: 0 0 12px;
1179
+ padding: 0;
1180
+ list-style: none;
1181
+ }
1182
+
1183
+ .warning {
1184
+ display: grid;
1185
+ gap: 6px;
1186
+ padding: 10px 12px;
1187
+ background: var(--surface-2);
1188
+ }
1189
+
1190
+ .warning p {
1191
+ color: var(--text-2);
1192
+ }
1193
+
1194
+ .warning-head {
1195
+ display: flex;
1196
+ align-items: center;
1197
+ gap: 8px;
1198
+ }
1199
+
1200
+ .warning-route {
1201
+ font-family: var(--mono);
1202
+ font-size: 12px;
1203
+ }
1204
+
1205
+ .chip-warn {
1206
+ background: var(--surface-2);
1207
+ color: var(--warning-text);
1208
+ font-weight: 650;
1209
+ }
1210
+
1211
+ .chip-hint {
1212
+ color: var(--text-3);
1213
+ }
1214
+
1215
+ .warning .chip-warn {
1216
+ background: var(--surface);
1217
+ }
1218
+
1219
+ /* Per-route call stats */
1220
+
1221
+ .data-stats {
1222
+ display: grid;
1223
+ gap: 6px;
1224
+ margin-top: 14px;
1225
+ padding-top: 12px;
1226
+ border-top: 1px solid var(--border);
1227
+ }
1228
+
1229
+ .data-stats h3 {
1230
+ margin: 0;
1231
+ color: var(--text-3);
1232
+ font-size: 11px;
1233
+ font-weight: 600;
1234
+ letter-spacing: 0.04em;
1235
+ text-transform: uppercase;
1236
+ }
1237
+
1238
+ .stat-row {
1239
+ display: flex;
1240
+ flex-wrap: wrap;
1241
+ align-items: center;
1242
+ gap: 4px 10px;
1243
+ font-size: 12px;
1244
+ font-variant-numeric: tabular-nums;
1245
+ }
1246
+
1247
+ .stat-type {
1248
+ min-width: 76px;
1249
+ font-weight: 600;
1250
+ }
1251
+
1252
+ .stat-row .slow {
1253
+ color: var(--warning-text);
1254
+ font-weight: 600;
1255
+ }
1256
+
1257
+ .error-text {
1258
+ color: var(--danger-text);
1259
+ }
1260
+
1261
+ /* Timeline route filter */
1262
+
1263
+ .route-pill {
1264
+ display: flex;
1265
+ align-items: center;
1266
+ justify-content: space-between;
1267
+ gap: 8px;
1268
+ padding: 4px 4px 4px 10px;
1269
+ background: var(--surface-2);
1270
+ font-size: 12px;
1271
+ }
1272
+
1273
+ .route-pill strong {
1274
+ font-family: var(--mono);
1275
+ font-weight: 600;
1276
+ }
1277
+
1278
+ .route-pill button {
1279
+ width: 24px;
1280
+ height: 24px;
1281
+ border: 0;
1282
+ background: none;
1283
+ color: var(--text-3);
1284
+ cursor: pointer;
1285
+ }
1286
+
1287
+ .route-pill button:hover {
1288
+ color: var(--text);
1289
+ }
1290
+
1291
+ /* Call inspector */
1292
+
1293
+ .call-data {
1294
+ display: grid;
1295
+ gap: 6px;
1296
+ }
1297
+
1298
+ .call-data-actions {
1299
+ display: flex;
1300
+ align-items: center;
1301
+ justify-content: flex-end;
1302
+ gap: 10px;
1303
+ font-size: 11.5px;
1304
+ }
1305
+
1306
+ .json {
1307
+ max-height: 320px;
1308
+ padding: 8px 10px;
1309
+ overflow: auto;
1310
+ border: 1px solid var(--border);
1311
+ background: var(--surface-2);
1312
+ font-family: var(--mono);
1313
+ font-size: 11.5px;
1314
+ line-height: 1.6;
1315
+ }
1316
+
1317
+ .json-node > summary {
1318
+ cursor: pointer;
1319
+ list-style: none;
1320
+ }
1321
+
1322
+ .json-node > summary::-webkit-details-marker {
1323
+ display: none;
1324
+ }
1325
+
1326
+ .json-node > summary::before {
1327
+ content: "▸ ";
1328
+ color: var(--text-3);
1329
+ }
1330
+
1331
+ .json-node[open] > summary::before {
1332
+ content: "▾ ";
1333
+ }
1334
+
1335
+ .json-children {
1336
+ padding-left: 14px;
1337
+ }
1338
+
1339
+ .json-row {
1340
+ padding-left: 12px;
1341
+ overflow-wrap: anywhere;
1342
+ }
1343
+
1344
+ .json-key {
1345
+ color: var(--text-2);
1346
+ }
1347
+
1348
+ .json-string {
1349
+ color: var(--text);
1350
+ }
1351
+
1352
+ .json-number,
1353
+ .json-boolean,
1354
+ .json-null {
1355
+ color: var(--text-2);
1356
+ font-weight: 600;
1357
+ }
1358
+
1359
+ .json-preview {
1360
+ color: var(--text-3);
1361
+ }
1362
+
1363
+ .pairs {
1364
+ width: 100%;
1365
+ border-collapse: collapse;
1366
+ font-family: var(--mono);
1367
+ font-size: 11.5px;
1368
+ }
1369
+
1370
+ .pairs th,
1371
+ .pairs td {
1372
+ padding: 4px 8px;
1373
+ border: 1px solid var(--border);
1374
+ text-align: left;
1375
+ vertical-align: top;
1376
+ overflow-wrap: anywhere;
1377
+ }
1378
+
1379
+ .pairs th {
1380
+ width: 35%;
1381
+ background: var(--surface-2);
1382
+ color: var(--text-2);
1383
+ font-weight: 500;
1384
+ }
1385
+
1386
+ .call-headers > summary {
1387
+ color: var(--text-2);
1388
+ cursor: pointer;
1389
+ font-size: 12px;
1390
+ }
1391
+
1392
+ .call-headers[open] > summary {
1393
+ margin-bottom: 6px;
1394
+ }
1395
+
1396
+ .call-error {
1397
+ display: grid;
1398
+ gap: 6px;
1399
+ color: var(--danger-text);
1400
+ }
1401
+
1402
+ .call-stack {
1403
+ color: var(--text-2);
1404
+ }
1405
+
1406
+ /* Open in app */
1407
+
1408
+ .button-quiet {
1409
+ justify-self: start;
1410
+ height: 30px;
1411
+ padding: 0 12px;
1412
+ border: 1px solid var(--border-strong);
1413
+ background: var(--surface);
1414
+ color: var(--text);
1415
+ font-size: 12px;
1416
+ }
1417
+
1418
+ .button-quiet:hover {
1419
+ filter: none;
1420
+ background: var(--surface-2);
1421
+ }
1422
+
1423
+ .button-quiet svg {
1424
+ width: 14px;
1425
+ height: 14px;
1426
+ }
1427
+
1428
+ .open-form {
1429
+ display: grid;
1430
+ gap: 8px;
1431
+ }
1432
+
1433
+ .param-field {
1434
+ display: grid;
1435
+ gap: 3px;
1436
+ font-family: var(--mono);
1437
+ font-size: 12px;
1438
+ }
1439
+
1440
+ .param-field input {
1441
+ height: 30px;
1442
+ padding: 0 8px;
1443
+ border: 1px solid var(--border);
1444
+ background: var(--surface);
1445
+ font-family: var(--mono);
1446
+ font-size: 12px;
1447
+ }
1448
+
1449
+ .param-field input:focus {
1450
+ border-color: var(--border-strong);
1451
+ outline: none;
1452
+ }
1453
+
1454
+ .form-error {
1455
+ color: var(--danger-text);
1456
+ font-size: 12px;
1457
+ }
1458
+
1459
+ .row-open {
1460
+ display: grid;
1461
+ place-items: center;
1462
+ width: 22px;
1463
+ height: 20px;
1464
+ padding: 0;
1465
+ border: 1px solid var(--border);
1466
+ background: var(--surface);
1467
+ color: var(--text-2);
1468
+ cursor: pointer;
1469
+ visibility: hidden;
1470
+ }
1471
+
1472
+ .row:hover .row-open,
1473
+ .row[aria-selected="true"] .row-open,
1474
+ .row-open:focus-visible {
1475
+ visibility: visible;
1476
+ }
1477
+
1478
+ .row-open:hover {
1479
+ color: var(--text);
1480
+ border-color: var(--border-strong);
1481
+ }
1482
+
1483
+ .row-open svg {
1484
+ width: 13px;
1485
+ height: 13px;
1486
+ }
1487
+
1488
+ .result-open {
1489
+ margin-left: auto;
1490
+ }