protocol-proxy 2.8.0 → 2.8.2

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/public/style.css CHANGED
@@ -1,1906 +1,1786 @@
1
- :root {
2
- --bg-body: #030712;
3
- --bg-card: rgba(15, 23, 42, 0.5);
4
- --bg-surface: rgba(6, 8, 15, 0.6);
5
- --bg-surface-alt: rgba(15, 23, 42, 0.4);
6
- --bg-elevated: rgba(15, 23, 42, 0.7);
7
- --bg-dropdown: rgba(15, 23, 42, 0.95);
8
- --text-primary: #f1f5f9;
9
- --text-secondary: #e2e8f0;
10
- --text-muted: #94a3b8;
11
- --text-dim: #64748b;
12
- --text-faint: #475569;
13
- --border-main: rgba(51, 65, 85, 0.4);
14
- --border-light: rgba(51, 65, 85, 0.35);
15
- --border-input: rgba(51, 65, 85, 0.5);
16
- --grid-opacity: 0.03;
17
- --card-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
18
- --accent: #60a5fa;
19
- --accent-dim: #3b82f6;
20
- }
21
-
22
- [data-theme="light"] {
23
- --bg-body: #f1f5f9;
24
- --bg-card: rgba(255, 255, 255, 0.85);
25
- --bg-surface: rgba(241, 245, 249, 0.8);
26
- --bg-surface-alt: rgba(241, 245, 249, 0.6);
27
- --bg-elevated: rgba(255, 255, 255, 0.92);
28
- --bg-dropdown: rgba(255, 255, 255, 0.97);
29
- --text-primary: #0f172a;
30
- --text-secondary: #1e293b;
31
- --text-muted: #475569;
32
- --text-dim: #64748b;
33
- --text-faint: #94a3b8;
34
- --border-main: rgba(203, 213, 225, 0.6);
35
- --border-light: rgba(203, 213, 225, 0.5);
36
- --border-input: rgba(203, 213, 225, 0.7);
37
- --grid-opacity: 0.4;
38
- --card-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
39
- --accent: #2563eb;
40
- --accent-dim: #1d4ed8;
41
- }
42
-
43
- [data-theme="pure-black"] {
44
- --bg-body: #000000;
45
- --bg-card: rgba(10, 10, 10, 0.7);
46
- --bg-surface: rgba(5, 5, 5, 0.8);
47
- --bg-surface-alt: rgba(10, 10, 10, 0.5);
48
- --bg-elevated: rgba(10, 10, 10, 0.85);
49
- --bg-dropdown: rgba(10, 10, 10, 0.97);
50
- --text-primary: #e5e5e5;
51
- --text-secondary: #d4d4d4;
52
- --text-muted: #a3a3a3;
53
- --text-dim: #737373;
54
- --text-faint: #525252;
55
- --border-main: rgba(64, 64, 64, 0.4);
56
- --border-light: rgba(64, 64, 64, 0.3);
57
- --border-input: rgba(64, 64, 64, 0.5);
58
- --grid-opacity: 0.02;
59
- --card-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
60
- --accent: #a3a3a3;
61
- --accent-dim: #737373;
62
- }
63
-
64
- [data-theme="neon"] {
65
- --bg-body: #0a0a1a;
66
- --bg-card: rgba(10, 10, 30, 0.6);
67
- --bg-surface: rgba(10, 10, 30, 0.7);
68
- --bg-surface-alt: rgba(15, 15, 40, 0.4);
69
- --bg-elevated: rgba(10, 10, 30, 0.8);
70
- --bg-dropdown: rgba(10, 10, 30, 0.95);
71
- --text-primary: #e0f7ff;
72
- --text-secondary: #c5e8f5;
73
- --text-muted: #7ec8e8;
74
- --text-dim: #4a9ab5;
75
- --text-faint: #2d6a80;
76
- --border-main: rgba(0, 200, 255, 0.2);
77
- --border-light: rgba(0, 200, 255, 0.15);
78
- --border-input: rgba(0, 200, 255, 0.25);
79
- --grid-opacity: 0.06;
80
- --card-shadow: 0 4px 24px rgba(0, 200, 255, 0.08);
81
- --accent: #00d4ff;
82
- --accent-dim: #0099cc;
83
- }
84
-
85
- [data-theme="amber"] {
86
- --bg-body: #0f0a05;
87
- --bg-card: rgba(20, 15, 8, 0.6);
88
- --bg-surface: rgba(15, 10, 5, 0.7);
89
- --bg-surface-alt: rgba(20, 15, 8, 0.45);
90
- --bg-elevated: rgba(20, 15, 8, 0.8);
91
- --bg-dropdown: rgba(20, 15, 8, 0.95);
92
- --text-primary: #fef3c7;
93
- --text-secondary: #fde68a;
94
- --text-muted: #c8a55a;
95
- --text-dim: #92703a;
96
- --text-faint: #6b5025;
97
- --border-main: rgba(180, 130, 50, 0.25);
98
- --border-light: rgba(180, 130, 50, 0.18);
99
- --border-input: rgba(180, 130, 50, 0.3);
100
- --grid-opacity: 0.04;
101
- --card-shadow: 0 4px 24px rgba(180, 130, 50, 0.06);
102
- --accent: #f59e0b;
103
- --accent-dim: #d97706;
104
- }
105
-
106
- * { box-sizing: border-box; margin: 0; padding: 0; }
107
-
108
- body {
109
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
110
- background: var(--bg-body);
111
- color: var(--text-secondary);
112
- line-height: 1.6;
113
- min-height: 100vh;
114
- }
115
-
116
- /* 科技网格背景 */
117
- body::before {
118
- content: '';
119
- position: fixed;
120
- top: 0; left: 0; right: 0; bottom: 0;
121
- background-image:
122
- linear-gradient(rgba(59, 130, 246, var(--grid-opacity)) 1px, transparent 1px),
123
- linear-gradient(90deg, rgba(59, 130, 246, var(--grid-opacity)) 1px, transparent 1px);
124
- background-size: 60px 60px;
125
- pointer-events: none;
126
- z-index: 0;
127
- }
128
-
129
- .container {
130
- position: relative;
131
- z-index: 1;
132
- max-width: 1200px;
133
- margin: 0 auto;
134
- padding: 40px 20px;
135
- }
136
-
137
- /* Theme toggle */
138
- .theme-toggle {
139
- position: fixed;
140
- top: 20px;
141
- right: 20px;
142
- z-index: 100;
143
- height: 36px;
144
- padding: 0 14px 0 10px;
145
- border-radius: 10px;
146
- border: 1px solid var(--border-input);
147
- background: var(--bg-card);
148
- backdrop-filter: blur(12px);
149
- color: var(--text-muted);
150
- font-size: 1rem;
151
- cursor: pointer;
152
- display: flex;
153
- align-items: center;
154
- gap: 6px;
155
- transition: all 0.25s;
156
- white-space: nowrap;
157
- }
158
-
159
- .theme-label {
160
- font-size: 0.78rem;
161
- font-weight: 500;
162
- }
163
-
164
- .theme-toggle:hover {
165
- border-color: var(--accent);
166
- color: var(--accent);
167
- box-shadow: 0 0 12px rgba(59, 130, 246, 0.15);
168
- }
169
-
170
- /* Header */
171
- header {
172
- text-align: center;
173
- margin-bottom: 40px;
174
- }
175
-
176
- header h1 {
177
- font-size: 2.8rem;
178
- font-weight: 800;
179
- letter-spacing: -0.02em;
180
- background: linear-gradient(135deg, #60a5fa 0%, #a78bfa 50%, #22d3ee 100%);
181
- -webkit-background-clip: text;
182
- -webkit-text-fill-color: transparent;
183
- background-clip: text;
184
- margin-bottom: 10px;
185
- text-shadow: 0 0 40px rgba(96, 165, 250, 0.15);
186
- }
187
-
188
- header p {
189
- color: #64748b;
190
- font-size: 1.05rem;
191
- letter-spacing: 0.02em;
192
- }
193
-
194
- /* Stats */
195
- .stats {
196
- display: flex;
197
- gap: 20px;
198
- justify-content: center;
199
- margin-bottom: 40px;
200
- }
201
-
202
- .stat-item {
203
- background: var(--bg-surface);
204
- backdrop-filter: blur(12px);
205
- border: 1px solid var(--border-input);
206
- border-radius: 16px;
207
- padding: 24px 48px;
208
- text-align: center;
209
- min-width: 160px;
210
- position: relative;
211
- overflow: hidden;
212
- transition: all 0.3s ease;
213
- }
214
-
215
- .stat-item::before {
216
- content: '';
217
- position: absolute;
218
- top: 0; left: 0; right: 0;
219
- height: 2px;
220
- background: linear-gradient(90deg, transparent, #3b82f6, transparent);
221
- opacity: 0.5;
222
- }
223
-
224
- .stat-item:hover {
225
- border-color: rgba(59, 130, 246, 0.3);
226
- box-shadow: 0 0 30px rgba(59, 130, 246, 0.08);
227
- transform: translateY(-2px);
228
- }
229
-
230
- .stat-value {
231
- display: block;
232
- font-size: 2.2rem;
233
- font-weight: 700;
234
- color: var(--accent);
235
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
236
- }
237
-
238
- .stat-label {
239
- color: #64748b;
240
- font-size: 0.85rem;
241
- text-transform: uppercase;
242
- letter-spacing: 0.08em;
243
- margin-top: 4px;
244
- }
245
-
246
- /* Card */
247
- .card {
248
- background: var(--bg-card);
249
- backdrop-filter: blur(16px);
250
- border: 1px solid var(--border-main);
251
- border-radius: 20px;
252
- overflow: hidden;
253
- box-shadow: var(--card-shadow);
254
- }
255
-
256
- .card-header {
257
- display: flex;
258
- justify-content: space-between;
259
- align-items: center;
260
- padding: 24px 28px;
261
- border-bottom: 1px solid var(--border-main);
262
- }
263
-
264
- .card-header h2 {
265
- font-size: 1.15rem;
266
- font-weight: 600;
267
- color: #f1f5f9;
268
- letter-spacing: -0.01em;
269
- }
270
-
271
- /* Buttons */
272
- .btn {
273
- padding: 9px 18px;
274
- border-radius: 10px;
275
- border: 1px solid rgba(71, 85, 105, 0.6);
276
- background: rgba(51, 65, 85, 0.4);
277
- color: #cbd5e1;
278
- cursor: pointer;
279
- font-size: 0.9rem;
280
- font-weight: 500;
281
- transition: all 0.25s ease;
282
- backdrop-filter: blur(8px);
283
- }
284
-
285
- .btn:hover {
286
- background: rgba(71, 85, 105, 0.5);
287
- border-color: rgba(100, 116, 139, 0.8);
288
- transform: translateY(-1px);
289
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
290
- }
291
-
292
- .btn-primary {
293
- background: linear-gradient(135deg, var(--accent), var(--accent-dim));
294
- border-color: transparent;
295
- color: white;
296
- box-shadow: 0 2px 8px rgba(59, 130, 246, 0.25);
297
- }
298
-
299
- .btn-primary:hover {
300
- box-shadow: 0 4px 16px rgba(59, 130, 246, 0.4);
301
- transform: translateY(-1px);
302
- }
303
-
304
- .btn-sm {
305
- padding: 5px 14px;
306
- font-size: 0.85rem;
307
- }
308
-
309
- .btn-danger {
310
- background: linear-gradient(135deg, #ef4444, #dc2626);
311
- border-color: transparent;
312
- color: white;
313
- box-shadow: 0 2px 8px rgba(239, 68, 68, 0.2);
314
- }
315
-
316
- .btn-danger:hover {
317
- background: linear-gradient(135deg, #ff5555, #ec3636);
318
- box-shadow: 0 4px 16px rgba(239, 68, 68, 0.35);
319
- }
320
-
321
- .btn-success {
322
- background: linear-gradient(135deg, #22c55e, #16a34a);
323
- border-color: transparent;
324
- color: white;
325
- box-shadow: 0 2px 8px rgba(34, 197, 94, 0.2);
326
- }
327
-
328
- .btn-success:hover {
329
- background: linear-gradient(135deg, #32d56e, #26b34a);
330
- box-shadow: 0 4px 16px rgba(34, 197, 94, 0.35);
331
- }
332
-
333
- /* Proxy toolbar */
334
- .proxy-toolbar {
335
- display: flex;
336
- align-items: center;
337
- gap: 12px;
338
- padding: 14px 28px;
339
- border-bottom: 1px solid var(--border-light);
340
- background: var(--bg-surface-alt);
341
- }
342
-
343
- .proxy-search {
344
- flex: 1;
345
- }
346
-
347
- .proxy-search input {
348
- width: 100%;
349
- padding: 8px 14px;
350
- background: var(--bg-surface);
351
- border: 1px solid var(--border-input);
352
- border-radius: 8px;
353
- color: var(--text-secondary);
354
- font-size: 0.85rem;
355
- transition: all 0.2s;
356
- }
357
-
358
- .proxy-search input::placeholder {
359
- color: #475569;
360
- }
361
-
362
- .proxy-search input:focus {
363
- outline: none;
364
- border-color: rgba(59, 130, 246, 0.5);
365
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
366
- }
367
-
368
- .proxy-toolbar-actions {
369
- display: flex;
370
- gap: 6px;
371
- flex-shrink: 0;
372
- }
373
-
374
- /* Proxy list */
375
- .proxy-list {
376
- padding: 20px;
377
- }
378
-
379
- .empty {
380
- text-align: center;
381
- padding: 80px 20px;
382
- color: var(--text-faint);
383
- font-size: 0.95rem;
384
- }
385
-
386
- .empty::before {
387
- content: '◈';
388
- display: block;
389
- font-size: 3rem;
390
- color: var(--text-faint);
391
- margin-bottom: 16px;
392
- }
393
-
394
- /* Proxy Item */
395
- .proxy-item {
396
- background: var(--bg-surface);
397
- backdrop-filter: blur(12px);
398
- border: 1px solid var(--border-light);
399
- border-radius: 16px;
400
- padding: 24px;
401
- margin-bottom: 16px;
402
- position: relative;
403
- overflow: hidden;
404
- transition: all 0.3s ease;
405
- }
406
-
407
- .proxy-item::before {
408
- content: '';
409
- position: absolute;
410
- left: 0; top: 0; bottom: 0;
411
- width: 3px;
412
- background: #475569;
413
- transition: background 0.3s ease;
414
- }
415
-
416
- .proxy-item:hover {
417
- border-color: rgba(71, 85, 105, 0.6);
418
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
419
- transform: translateY(-2px);
420
- }
421
-
422
- .proxy-item:hover::before {
423
- background: #3b82f6;
424
- box-shadow: 0 0 12px rgba(59, 130, 246, 0.5);
425
- }
426
-
427
- .proxy-header {
428
- display: flex;
429
- justify-content: space-between;
430
- align-items: center;
431
- margin-bottom: 14px;
432
- }
433
-
434
- .proxy-title {
435
- display: flex;
436
- align-items: center;
437
- gap: 12px;
438
- }
439
-
440
- .proxy-title h3 {
441
- font-size: 1.15rem;
442
- font-weight: 600;
443
- color: #f8fafc;
444
- }
445
-
446
- /* Badge */
447
- .badge {
448
- padding: 3px 12px;
449
- border-radius: 20px;
450
- font-size: 0.75rem;
451
- font-weight: 600;
452
- letter-spacing: 0.03em;
453
- backdrop-filter: blur(8px);
454
- }
455
-
456
- .badge-running {
457
- background: rgba(6, 78, 59, 0.4);
458
- color: #34d399;
459
- border: 1px solid rgba(52, 211, 153, 0.2);
460
- box-shadow: 0 0 8px rgba(52, 211, 153, 0.1);
461
- }
462
-
463
- .badge-stopped {
464
- background: rgba(69, 26, 3, 0.4);
465
- color: #fbbf24;
466
- border: 1px solid rgba(251, 191, 36, 0.2);
467
- }
468
-
469
- .proxy-meta {
470
- display: flex;
471
- gap: 24px;
472
- color: #64748b;
473
- font-size: 0.9rem;
474
- margin-bottom: 16px;
475
- }
476
-
477
- .proxy-meta span {
478
- display: flex;
479
- align-items: center;
480
- gap: 6px;
481
- }
482
-
483
- /* Target Table */
484
- .target-table {
485
- width: 100%;
486
- border-collapse: separate;
487
- border-spacing: 0;
488
- font-size: 0.85rem;
489
- table-layout: fixed;
490
- border-radius: 10px;
491
- overflow: hidden;
492
- }
493
-
494
- .target-table th:nth-child(1),
495
- .target-table td:nth-child(1) { width: 25%; }
496
-
497
- .target-table th:nth-child(2),
498
- .target-table td:nth-child(2) { width: 25%; }
499
-
500
- .target-table th:nth-child(3),
501
- .target-table td:nth-child(3) { width: 25%; }
502
-
503
- .target-table th:nth-child(4),
504
- .target-table td:nth-child(4) { width: 25%; text-align: center; }
505
-
506
- .target-table th,
507
- .target-table td {
508
- text-align: left;
509
- padding: 10px 14px;
510
- border-bottom: 1px solid rgba(30, 41, 59, 0.6);
511
- }
512
-
513
- .target-table th {
514
- color: #475569;
515
- font-weight: 600;
516
- text-transform: uppercase;
517
- font-size: 0.7rem;
518
- letter-spacing: 0.08em;
519
- background: rgba(15, 23, 42, 0.4);
520
- }
521
-
522
- .target-table td {
523
- color: #94a3b8;
524
- word-break: break-all;
525
- }
526
-
527
- .target-table tbody tr:last-child td {
528
- border-bottom: none;
529
- }
530
-
531
- .proxy-actions {
532
- display: flex;
533
- gap: 10px;
534
- margin-top: 18px;
535
- padding-top: 18px;
536
- border-top: 1px solid var(--border-light);
537
- }
538
-
539
- /* Modal */
540
- .modal {
541
- display: none;
542
- position: fixed;
543
- top: 0;
544
- left: 0;
545
- width: 100%;
546
- height: 100%;
547
- background: rgba(3, 7, 18, 0.85);
548
- backdrop-filter: blur(8px);
549
- z-index: 1000;
550
- justify-content: center;
551
- align-items: flex-start;
552
- padding: 20px;
553
- overflow-y: auto;
554
- }
555
-
556
- .modal.active {
557
- display: flex;
558
- }
559
-
560
- .modal-content {
561
- background: var(--bg-elevated);
562
- backdrop-filter: blur(24px);
563
- border: 1px solid var(--border-main);
564
- border-radius: 20px;
565
- width: 100%;
566
- max-width: 700px;
567
- margin: auto;
568
- box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(59, 130, 246, 0.05);
569
- animation: modal-in 0.3s ease;
570
- }
571
-
572
- @keyframes modal-in {
573
- from { opacity: 0; transform: translateY(20px) scale(0.97); }
574
- to { opacity: 1; transform: translateY(0) scale(1); }
575
- }
576
-
577
- .modal-header {
578
- display: flex;
579
- justify-content: space-between;
580
- align-items: center;
581
- padding: 22px 28px;
582
- border-bottom: 1px solid var(--border-main);
583
- }
584
-
585
- .modal-header h3 {
586
- font-size: 1.2rem;
587
- font-weight: 600;
588
- color: #f8fafc;
589
- }
590
-
591
- .btn-close {
592
- background: none;
593
- border: none;
594
- color: #64748b;
595
- font-size: 1.5rem;
596
- cursor: pointer;
597
- line-height: 1;
598
- width: 36px;
599
- height: 36px;
600
- border-radius: 10px;
601
- display: flex;
602
- align-items: center;
603
- justify-content: center;
604
- transition: all 0.2s;
605
- }
606
-
607
- .btn-close:hover {
608
- color: #e2e8f0;
609
- background: rgba(71, 85, 105, 0.3);
610
- }
611
-
612
- /* Form */
613
- form {
614
- padding: 24px 28px;
615
- }
616
-
617
- .form-group {
618
- margin-bottom: 18px;
619
- }
620
-
621
- .form-group label {
622
- display: block;
623
- margin-bottom: 8px;
624
- color: #94a3b8;
625
- font-size: 0.85rem;
626
- font-weight: 500;
627
- letter-spacing: 0.02em;
628
- }
629
-
630
- .form-group input,
631
- .form-group select,
632
- .form-group textarea {
633
- width: 100%;
634
- padding: 11px 16px;
635
- background: var(--bg-surface);
636
- border: 1px solid var(--border-input);
637
- border-radius: 10px;
638
- color: var(--text-primary);
639
- font-size: 0.95rem;
640
- transition: all 0.25s ease;
641
- appearance: none;
642
- -webkit-appearance: none;
643
- }
644
-
645
- .form-group input::placeholder,
646
- .form-group select::placeholder {
647
- color: #475569;
648
- }
649
-
650
- .form-group input:focus,
651
- .form-group select:focus {
652
- outline: none;
653
- border-color: rgba(59, 130, 246, 0.5);
654
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), 0 0 20px rgba(59, 130, 246, 0.08);
655
- background: rgba(6, 8, 15, 0.8);
656
- }
657
-
658
- /* Select 下拉框 - 科技感 */
659
- .form-group select {
660
- cursor: pointer;
661
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
662
- background-repeat: no-repeat;
663
- background-position: right 14px center;
664
- padding-right: 42px;
665
- }
666
-
667
- .form-group select:hover {
668
- border-color: rgba(100, 116, 139, 0.7);
669
- }
670
-
671
- .form-group select option {
672
- background: #0f172a;
673
- color: #e2e8f0;
674
- padding: 10px;
675
- }
676
-
677
- /* Form row */
678
- .form-row {
679
- display: grid;
680
- grid-template-columns: 1fr 1fr;
681
- gap: 18px;
682
- }
683
-
684
- /* Target section */
685
- .target-section {
686
- margin-top: 24px;
687
- padding-top: 24px;
688
- border-top: 1px solid var(--border-main);
689
- }
690
-
691
- .target-section h4 {
692
- font-size: 0.9rem;
693
- font-weight: 600;
694
- color: #64748b;
695
- text-transform: uppercase;
696
- letter-spacing: 0.08em;
697
- margin-bottom: 16px;
698
- }
699
-
700
- .target-item {
701
- background: var(--bg-surface-alt);
702
- border: 1px solid var(--border-light);
703
- border-radius: 14px;
704
- padding: 20px;
705
- margin-bottom: 12px;
706
- transition: border-color 0.25s;
707
- }
708
-
709
- .target-item:hover {
710
- border-color: rgba(71, 85, 105, 0.5);
711
- }
712
-
713
- .target-item .form-row {
714
- margin-bottom: 14px;
715
- }
716
-
717
- .target-item .form-row:last-child {
718
- margin-bottom: 0;
719
- }
720
-
721
- .target-remove {
722
- text-align: right;
723
- margin-top: 8px;
724
- }
725
-
726
- .modal-footer {
727
- display: flex;
728
- justify-content: flex-end;
729
- gap: 12px;
730
- padding-top: 20px;
731
- margin-top: 20px;
732
- border-top: 1px solid var(--border-main);
733
- }
734
-
735
- /* Proxy address */
736
- .proxy-address {
737
- display: flex;
738
- align-items: center;
739
- gap: 10px;
740
- margin-top: 14px;
741
- padding: 12px 16px;
742
- background: var(--bg-surface-alt);
743
- border: 1px solid var(--border-light);
744
- border-radius: 12px;
745
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
746
- transition: all 0.25s;
747
- }
748
-
749
- .proxy-address:hover {
750
- border-color: rgba(59, 130, 246, 0.3);
751
- box-shadow: 0 0 16px rgba(59, 130, 246, 0.06);
752
- }
753
-
754
- .proxy-address code {
755
- flex: 1;
756
- font-size: 0.85rem;
757
- color: var(--accent);
758
- word-break: break-all;
759
- }
760
-
761
- .copy-btn {
762
- flex-shrink: 0;
763
- display: flex;
764
- align-items: center;
765
- gap: 6px;
766
- padding: 6px 12px;
767
- background: rgba(51, 65, 85, 0.4);
768
- border: 1px solid rgba(71, 85, 105, 0.5);
769
- border-radius: 8px;
770
- color: #94a3b8;
771
- font-size: 0.8rem;
772
- cursor: pointer;
773
- transition: all 0.25s;
774
- backdrop-filter: blur(8px);
775
- }
776
-
777
- .copy-btn:hover {
778
- background: rgba(59, 130, 246, 0.15);
779
- border-color: rgba(59, 130, 246, 0.4);
780
- color: #60a5fa;
781
- box-shadow: 0 0 12px rgba(59, 130, 246, 0.15);
782
- }
783
-
784
- .copy-btn svg {
785
- width: 14px;
786
- height: 14px;
787
- }
788
-
789
- /* Toast */
790
- .toast {
791
- position: fixed;
792
- top: 50%;
793
- left: 50%;
794
- transform: translate(-50%, -50%);
795
- padding: 12px 24px;
796
- background: linear-gradient(135deg, #22c55e, #16a34a);
797
- color: white;
798
- border-radius: 12px;
799
- font-size: 0.9rem;
800
- font-weight: 500;
801
- z-index: 9999;
802
- animation: toast-in 0.35s ease, toast-out 0.35s ease 2.3s forwards;
803
- box-shadow: 0 8px 24px rgba(34, 197, 94, 0.3);
804
- backdrop-filter: blur(12px);
805
- }
806
-
807
- @keyframes toast-in {
808
- from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
809
- to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
810
- }
811
-
812
- @keyframes toast-out {
813
- from { opacity: 1; }
814
- to { opacity: 0; }
815
- }
816
-
817
- /* Custom model dropdown */
818
- .model-dropdown {
819
- position: relative;
820
- width: 100%;
821
- }
822
-
823
- .model-dropdown-trigger {
824
- display: flex;
825
- align-items: center;
826
- justify-content: space-between;
827
- width: 100%;
828
- padding: 11px 16px;
829
- background: var(--bg-surface);
830
- border: 1px solid var(--border-input);
831
- border-radius: 10px;
832
- color: var(--text-primary);
833
- font-size: 0.95rem;
834
- cursor: pointer;
835
- transition: all 0.25s ease;
836
- user-select: none;
837
- }
838
-
839
- .model-dropdown-trigger:hover {
840
- border-color: rgba(100, 116, 139, 0.6);
841
- }
842
-
843
- .model-dropdown.open .model-dropdown-trigger {
844
- border-color: rgba(59, 130, 246, 0.5);
845
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), 0 0 20px rgba(59, 130, 246, 0.08);
846
- }
847
-
848
- .model-dropdown-arrow {
849
- font-size: 0.7rem;
850
- color: #64748b;
851
- transition: transform 0.25s ease;
852
- }
853
-
854
- .model-dropdown.open .model-dropdown-arrow {
855
- transform: rotate(180deg);
856
- }
857
-
858
- .model-dropdown-menu {
859
- display: none;
860
- position: absolute;
861
- top: calc(100% + 6px);
862
- left: 0;
863
- right: 0;
864
- background: var(--bg-dropdown);
865
- backdrop-filter: blur(24px);
866
- border: 1px solid var(--border-input);
867
- border-radius: 12px;
868
- z-index: 100;
869
- overflow: hidden;
870
- box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(59, 130, 246, 0.05);
871
- animation: dropdown-in 0.2s ease;
872
- }
873
-
874
- @keyframes dropdown-in {
875
- from { opacity: 0; transform: translateY(-6px); }
876
- to { opacity: 1; transform: translateY(0); }
877
- }
878
-
879
- .model-dropdown.open .model-dropdown-menu {
880
- display: block;
881
- }
882
-
883
- .model-dropdown-options {
884
- max-height: 220px;
885
- overflow-y: auto;
886
- }
887
-
888
- .model-dropdown-options::-webkit-scrollbar {
889
- width: 6px;
890
- }
891
-
892
- .model-dropdown-options::-webkit-scrollbar-track {
893
- background: transparent;
894
- }
895
-
896
- .model-dropdown-options::-webkit-scrollbar-thumb {
897
- background: rgba(71, 85, 105, 0.5);
898
- border-radius: 3px;
899
- }
900
-
901
- .model-option {
902
- display: flex;
903
- align-items: center;
904
- justify-content: space-between;
905
- padding: 10px 16px;
906
- cursor: pointer;
907
- transition: all 0.15s ease;
908
- border-left: 2px solid transparent;
909
- }
910
-
911
- .model-option:hover {
912
- background: rgba(59, 130, 246, 0.08);
913
- border-left-color: rgba(59, 130, 246, 0.4);
914
- }
915
-
916
- .model-option.selected {
917
- background: rgba(59, 130, 246, 0.12);
918
- color: #7dd3fc;
919
- border-left-color: #3b82f6;
920
- }
921
-
922
- .model-option-name {
923
- flex: 1;
924
- font-size: 0.9rem;
925
- }
926
-
927
- .model-option-delete {
928
- display: flex;
929
- align-items: center;
930
- justify-content: center;
931
- width: 24px;
932
- height: 24px;
933
- border-radius: 6px;
934
- border: none;
935
- background: transparent;
936
- color: #64748b;
937
- font-size: 1rem;
938
- cursor: pointer;
939
- transition: all 0.15s;
940
- line-height: 1;
941
- padding: 0;
942
- }
943
-
944
- .model-option-delete:hover {
945
- background: rgba(239, 68, 68, 0.15);
946
- color: #ef4444;
947
- }
948
-
949
- .model-add-section {
950
- display: flex;
951
- gap: 8px;
952
- padding: 10px 16px;
953
- border-top: 1px solid var(--border-main);
954
- background: var(--bg-surface-alt);
955
- }
956
-
957
- .model-add-input {
958
- flex: 1;
959
- padding: 7px 12px;
960
- background: var(--bg-surface);
961
- border: 1px solid var(--border-input);
962
- border-radius: 8px;
963
- color: var(--text-secondary);
964
- font-size: 0.85rem;
965
- transition: all 0.2s;
966
- }
967
-
968
- .model-add-input:focus {
969
- outline: none;
970
- border-color: rgba(59, 130, 246, 0.4);
971
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.08);
972
- }
973
-
974
- /* Confirm modal */
975
- .confirm-modal {
976
- align-items: center;
977
- }
978
-
979
- .confirm-modal .confirm-box {
980
- background: var(--bg-elevated);
981
- backdrop-filter: blur(24px);
982
- border: 1px solid var(--border-main);
983
- border-radius: 20px;
984
- padding: 32px 36px;
985
- max-width: 380px;
986
- width: 90%;
987
- text-align: center;
988
- box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(239, 68, 68, 0.05);
989
- animation: confirm-pop 0.25s ease;
990
- }
991
-
992
- @keyframes confirm-pop {
993
- from { opacity: 0; transform: scale(0.92) translateY(10px); }
994
- to { opacity: 1; transform: scale(1) translateY(0); }
995
- }
996
-
997
- .confirm-icon {
998
- display: inline-flex;
999
- align-items: center;
1000
- justify-content: center;
1001
- width: 56px;
1002
- height: 56px;
1003
- border-radius: 16px;
1004
- background: rgba(69, 26, 3, 0.4);
1005
- color: #fbbf24;
1006
- font-size: 1.6rem;
1007
- font-weight: 700;
1008
- margin-bottom: 20px;
1009
- border: 1px solid rgba(251, 191, 36, 0.15);
1010
- }
1011
-
1012
- .confirm-text {
1013
- color: #94a3b8;
1014
- font-size: 0.95rem;
1015
- line-height: 1.6;
1016
- margin-bottom: 28px;
1017
- }
1018
-
1019
- .confirm-text strong {
1020
- color: #f1f5f9;
1021
- }
1022
-
1023
- .confirm-actions {
1024
- display: flex;
1025
- gap: 12px;
1026
- justify-content: center;
1027
- }
1028
-
1029
- .confirm-actions .btn {
1030
- min-width: 90px;
1031
- }
1032
-
1033
- /* Card header actions */
1034
- .card-header-actions {
1035
- display: flex;
1036
- gap: 8px;
1037
- align-items: center;
1038
- }
1039
-
1040
- /* Import modal */
1041
- .import-preview {
1042
- padding: 24px 28px;
1043
- }
1044
-
1045
- .import-stats {
1046
- display: flex;
1047
- gap: 16px;
1048
- margin-bottom: 24px;
1049
- }
1050
-
1051
- .import-stat {
1052
- flex: 1;
1053
- background: var(--bg-surface-alt);
1054
- border: 1px solid var(--border-light);
1055
- border-radius: 12px;
1056
- padding: 16px;
1057
- text-align: center;
1058
- }
1059
-
1060
- .import-stat-value {
1061
- display: block;
1062
- font-size: 1.8rem;
1063
- font-weight: 700;
1064
- color: var(--accent);
1065
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
1066
- }
1067
-
1068
- .import-stat-label {
1069
- color: #64748b;
1070
- font-size: 0.8rem;
1071
- text-transform: uppercase;
1072
- letter-spacing: 0.06em;
1073
- }
1074
-
1075
- .import-mode label {
1076
- display: block;
1077
- margin-bottom: 10px;
1078
- color: #94a3b8;
1079
- font-size: 0.85rem;
1080
- font-weight: 500;
1081
- }
1082
-
1083
- .import-mode-options {
1084
- display: flex;
1085
- flex-direction: column;
1086
- gap: 10px;
1087
- }
1088
-
1089
- .import-mode-option {
1090
- display: flex;
1091
- align-items: flex-start;
1092
- gap: 12px;
1093
- padding: 14px 16px;
1094
- background: var(--bg-surface-alt);
1095
- border: 1px solid var(--border-light);
1096
- border-radius: 10px;
1097
- cursor: pointer;
1098
- transition: all 0.2s;
1099
- }
1100
-
1101
- .import-mode-option:hover {
1102
- border-color: rgba(59, 130, 246, 0.3);
1103
- }
1104
-
1105
- .import-mode-option input[type="radio"] {
1106
- margin-top: 3px;
1107
- accent-color: #3b82f6;
1108
- }
1109
-
1110
- .import-mode-option strong {
1111
- display: block;
1112
- color: #e2e8f0;
1113
- font-size: 0.9rem;
1114
- margin-bottom: 2px;
1115
- }
1116
-
1117
- .import-mode-option small {
1118
- color: #64748b;
1119
- font-size: 0.8rem;
1120
- }
1121
-
1122
- /* Stats Panel */
1123
- .stats-panel .card-header {
1124
- flex-wrap: wrap;
1125
- gap: 12px;
1126
- }
1127
-
1128
- .stats-estimated-badge {
1129
- display: inline-block;
1130
- padding: 2px 10px;
1131
- border-radius: 12px;
1132
- font-size: 0.7rem;
1133
- font-weight: 500;
1134
- background: rgba(251, 191, 36, 0.15);
1135
- color: #fbbf24;
1136
- border: 1px solid rgba(251, 191, 36, 0.2);
1137
- vertical-align: middle;
1138
- letter-spacing: 0.02em;
1139
- }
1140
-
1141
- .stats-controls {
1142
- display: flex;
1143
- gap: 12px;
1144
- flex-wrap: wrap;
1145
- justify-content: flex-end; align-items: center;
1146
- }
1147
-
1148
- .stats-controls .model-dropdown {
1149
- width: 180px;
1150
- }
1151
-
1152
- .stats-filter-trigger {
1153
- padding: 7px 14px !important;
1154
- font-size: 0.85rem !important;
1155
- background: var(--bg-surface-alt) !important;
1156
- }
1157
-
1158
- .stats-range-btns {
1159
- display: flex;
1160
- gap: 4px;
1161
- align-items: center;
1162
- background: var(--bg-surface-alt);
1163
- border-radius: 10px;
1164
- padding: 3px;
1165
- border: 1px solid var(--border-light);
1166
- }
1167
-
1168
- .stats-range-btn {
1169
- border: none !important;
1170
- background: transparent !important;
1171
- box-shadow: none !important;
1172
- padding: 6px 16px !important;
1173
- border-radius: 8px !important;
1174
- color: #64748b !important;
1175
- font-size: 0.82rem !important;
1176
- transition: all 0.2s !important;
1177
- }
1178
-
1179
- .stats-range-btn:hover {
1180
- color: #94a3b8 !important;
1181
- background: rgba(51, 65, 85, 0.3) !important;
1182
- }
1183
-
1184
- .stats-range-btn.active {
1185
- background: rgba(59, 130, 246, 0.2) !important;
1186
- color: #60a5fa !important;
1187
- }
1188
-
1189
- .stats-date-range {
1190
- display: flex;
1191
- align-items: center;
1192
- gap: 4px;
1193
- }
1194
-
1195
- .stats-date-input {
1196
- background: var(--bg-surface);
1197
- border: 1px solid var(--border-input);
1198
- border-radius: 6px;
1199
- color: #e2e8f0;
1200
- padding: 6px 8px;
1201
- font-size: 0.78rem;
1202
- outline: none;
1203
- transition: border-color 0.2s;
1204
- width: 125px;
1205
- }
1206
-
1207
- .stats-date-input:focus {
1208
- border-color: #3b82f6;
1209
- }
1210
-
1211
- .stats-date-input::-webkit-calendar-picker-indicator {
1212
- filter: invert(0.7);
1213
- cursor: pointer;
1214
- }
1215
-
1216
- .stats-date-sep {
1217
- color: #475569;
1218
- font-size: 0.85rem;
1219
- }
1220
-
1221
- .stats-summary {
1222
- display: grid;
1223
- grid-template-columns: repeat(4, 1fr);
1224
- gap: 16px;
1225
- padding: 0 28px;
1226
- margin-top: 8px;
1227
- }
1228
-
1229
- .stats-summary-item {
1230
- background: var(--bg-surface-alt);
1231
- border: 1px solid var(--border-light);
1232
- border-radius: 12px;
1233
- padding: 18px 16px;
1234
- text-align: center;
1235
- transition: all 0.25s;
1236
- }
1237
-
1238
- .stats-summary-item:hover {
1239
- border-color: rgba(59, 130, 246, 0.25);
1240
- box-shadow: 0 0 16px rgba(59, 130, 246, 0.06);
1241
- }
1242
-
1243
- .stats-summary-value {
1244
- display: block;
1245
- font-size: 1.5rem;
1246
- font-weight: 700;
1247
- color: var(--accent);
1248
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
1249
- margin-bottom: 4px;
1250
- }
1251
-
1252
- .stats-summary-label {
1253
- color: #64748b;
1254
- font-size: 0.78rem;
1255
- text-transform: uppercase;
1256
- letter-spacing: 0.06em;
1257
- }
1258
-
1259
- .stats-breakdown {
1260
- padding: 20px 28px 28px;
1261
- }
1262
-
1263
- .stats-table {
1264
- width: 100%;
1265
- border-collapse: separate;
1266
- border-spacing: 0;
1267
- font-size: 0.85rem;
1268
- border-radius: 10px;
1269
- overflow: hidden;
1270
- }
1271
-
1272
- .stats-table th,
1273
- .stats-table td {
1274
- text-align: left;
1275
- padding: 10px 14px;
1276
- border-bottom: 1px solid rgba(30, 41, 59, 0.6);
1277
- }
1278
-
1279
- .stats-table th {
1280
- color: #475569;
1281
- font-weight: 600;
1282
- text-transform: uppercase;
1283
- font-size: 0.7rem;
1284
- letter-spacing: 0.08em;
1285
- background: rgba(15, 23, 42, 0.4);
1286
- }
1287
-
1288
- .stats-table td {
1289
- color: #94a3b8;
1290
- word-break: break-all;
1291
- }
1292
-
1293
- .stats-table tbody tr {
1294
- transition: background 0.15s;
1295
- }
1296
-
1297
- .stats-table tbody tr:hover {
1298
- background: rgba(59, 130, 246, 0.04);
1299
- }
1300
-
1301
- .stats-table tbody tr:last-child td {
1302
- border-bottom: none;
1303
- }
1304
-
1305
- .stats-table td.num {
1306
- text-align: right;
1307
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
1308
- font-size: 0.82rem;
1309
- color: var(--accent);
1310
- }
1311
-
1312
- .stats-table tfoot td {
1313
- font-weight: 600;
1314
- color: #e2e8f0;
1315
- background: rgba(15, 23, 42, 0.3);
1316
- }
1317
-
1318
- .stats-table .provider-cell {
1319
- color: #a78bfa;
1320
- }
1321
-
1322
- .stats-table .model-cell {
1323
- color: #94a3b8;
1324
- }
1325
-
1326
- .num-estimated {
1327
- color: #fbbf24;
1328
- font-size: 0.75rem;
1329
- margin-right: 2px;
1330
- cursor: help;
1331
- }
1332
-
1333
- @media (max-width: 640px) {
1334
- .stats-summary {
1335
- grid-template-columns: repeat(2, 1fr);
1336
- }
1337
-
1338
- .stats-controls {
1339
- flex-direction: column;
1340
- align-items: stretch;
1341
- }
1342
-
1343
- .stats-controls .model-dropdown {
1344
- width: 100%;
1345
- }
1346
-
1347
- .stats-date-range {
1348
- width: 100%;
1349
- }
1350
-
1351
- .stats-date-input {
1352
- flex: 1;
1353
- min-width: 0;
1354
- }
1355
- }
1356
-
1357
- /* Responsive */
1358
- @media (max-width: 640px) {
1359
- .form-row {
1360
- grid-template-columns: 1fr;
1361
- }
1362
-
1363
- .stats {
1364
- flex-direction: column;
1365
- align-items: center;
1366
- }
1367
-
1368
- .proxy-meta {
1369
- flex-direction: column;
1370
- gap: 8px;
1371
- }
1372
-
1373
- header h1 {
1374
- font-size: 2rem;
1375
- }
1376
- }
1377
-
1378
- .api-keys-header {
1379
- display: flex;
1380
- justify-content: space-between;
1381
- align-items: center;
1382
- margin-bottom: 10px;
1383
- }
1384
-
1385
- .api-keys-header span {
1386
- font-size: 0.85rem;
1387
- color: #94a3b8;
1388
- font-weight: 500;
1389
- }
1390
-
1391
- .api-keys-row {
1392
- grid-template-columns: 1fr;
1393
- }
1394
-
1395
- .api-key-entry {
1396
- display: grid;
1397
- grid-template-columns: 1fr 1fr auto auto;
1398
- align-items: start;
1399
- gap: 18px;
1400
- margin-bottom: 10px;
1401
- }
1402
-
1403
- /* Toggle switch */
1404
- .toggle-switch {
1405
- position: relative;
1406
- display: inline-block;
1407
- width: 36px;
1408
- height: 20px;
1409
- margin-top: 40px;
1410
- cursor: pointer;
1411
- }
1412
-
1413
- .toggle-switch input {
1414
- opacity: 0;
1415
- width: 0;
1416
- height: 0;
1417
- }
1418
-
1419
- .toggle-slider {
1420
- position: absolute;
1421
- inset: 0;
1422
- background: rgba(51, 65, 85, 0.6);
1423
- border-radius: 20px;
1424
- border: 1px solid rgba(71, 85, 105, 0.5);
1425
- transition: all 0.25s;
1426
- }
1427
-
1428
- .toggle-slider::before {
1429
- content: '';
1430
- position: absolute;
1431
- width: 14px;
1432
- height: 14px;
1433
- left: 2px;
1434
- top: 2px;
1435
- background: #94a3b8;
1436
- border-radius: 50%;
1437
- transition: all 0.25s;
1438
- }
1439
-
1440
- .toggle-switch input:checked + .toggle-slider {
1441
- background: rgba(59, 130, 246, 0.3);
1442
- border-color: rgba(59, 130, 246, 0.5);
1443
- }
1444
-
1445
- .toggle-switch input:checked + .toggle-slider::before {
1446
- transform: translateX(16px);
1447
- background: #60a5fa;
1448
- }
1449
-
1450
- .api-key-remove {
1451
- margin-top: 35px;
1452
- }
1453
-
1454
- .api-key-display {
1455
- display: block;
1456
- padding: 11px 16px;
1457
- background: var(--bg-surface);
1458
- border: 1px solid var(--border-input);
1459
- border-radius: 10px;
1460
- color: var(--text-dim);
1461
- font-size: 0.9rem;
1462
- letter-spacing: 2px;
1463
- cursor: pointer;
1464
- transition: border-color 0.2s, color 0.2s;
1465
- }
1466
-
1467
- .api-key-display:hover {
1468
- border-color: rgba(99, 102, 241, 0.5);
1469
- color: #94a3b8;
1470
- }
1471
-
1472
- .api-key-remove {
1473
- padding: 11px 14px;
1474
- border-radius: 10px;
1475
- border: 1px solid rgba(127, 29, 29, 0.5);
1476
- background: rgba(127, 29, 29, 0.15);
1477
- color: #fca5a5;
1478
- cursor: pointer;
1479
- font-size: 14px;
1480
- line-height: 1;
1481
- }
1482
-
1483
- .api-key-remove:hover {
1484
- background: rgba(127, 29, 29, 0.3);
1485
- border-color: rgba(248, 113, 113, 0.7);
1486
- }
1487
-
1488
- .proxy-routing-badge {
1489
- font-size: 0.75rem;
1490
- padding: 3px 10px;
1491
- border-radius: 6px;
1492
- background: rgba(51, 65, 85, 0.5);
1493
- color: #94a3b8;
1494
- font-weight: 500;
1495
- white-space: nowrap;
1496
- }
1497
-
1498
- .provider-tag {
1499
- font-size: 0.7rem;
1500
- padding: 1px 6px;
1501
- border-radius: 4px;
1502
- background: rgba(148, 163, 184, 0.15);
1503
- color: #94a3b8;
1504
- margin-left: 6px;
1505
- vertical-align: middle;
1506
- }
1507
-
1508
- .provider-pool-group {
1509
- grid-column: 1 / -1;
1510
- }
1511
-
1512
- .provider-pool-picker {
1513
- margin-bottom: 12px;
1514
- }
1515
-
1516
- .provider-pool-list {
1517
- display: flex;
1518
- flex-direction: column;
1519
- gap: 10px;
1520
- }
1521
-
1522
- .provider-pool-empty {
1523
- padding: 12px 14px;
1524
- border: 1px dashed var(--border-input);
1525
- border-radius: 10px;
1526
- color: var(--text-dim);
1527
- font-size: 0.9rem;
1528
- background: var(--bg-surface-alt);
1529
- }
1530
-
1531
- .provider-pool-item {
1532
- display: grid;
1533
- grid-template-columns: minmax(0, 1fr) 140px 120px auto;
1534
- gap: 12px;
1535
- align-items: center;
1536
- padding: 12px 14px;
1537
- border: 1px solid var(--border-input);
1538
- border-radius: 12px;
1539
- background: var(--bg-surface);
1540
- }
1541
-
1542
- .provider-pool-main {
1543
- min-width: 0;
1544
- }
1545
-
1546
- .provider-pool-name {
1547
- color: #e2e8f0;
1548
- font-weight: 600;
1549
- overflow: hidden;
1550
- text-overflow: ellipsis;
1551
- white-space: nowrap;
1552
- }
1553
-
1554
- .provider-pool-meta {
1555
- color: #64748b;
1556
- font-size: 0.82rem;
1557
- overflow: hidden;
1558
- text-overflow: ellipsis;
1559
- white-space: nowrap;
1560
- }
1561
-
1562
- .provider-pool-model label {
1563
- display: block;
1564
- margin-bottom: 4px;
1565
- font-size: 0.75rem;
1566
- color: #94a3b8;
1567
- }
1568
-
1569
- .provider-pool-model-value {
1570
- color: #e2e8f0;
1571
- font-size: 0.85rem;
1572
- overflow: hidden;
1573
- text-overflow: ellipsis;
1574
- white-space: nowrap;
1575
- display: block;
1576
- }
1577
-
1578
- .pool-provider-group {
1579
- position: relative;
1580
- }
1581
-
1582
- .pool-provider-trigger {
1583
- display: flex;
1584
- align-items: center;
1585
- gap: 4px;
1586
- }
1587
-
1588
- .pool-provider-arrow {
1589
- margin-left: auto;
1590
- font-size: 12px;
1591
- color: #64748b;
1592
- transition: transform 0.15s;
1593
- }
1594
-
1595
- .pool-provider-group.open > .pool-provider-trigger .pool-provider-arrow {
1596
- transform: rotate(90deg);
1597
- }
1598
-
1599
- .pool-model-sublist {
1600
- display: none;
1601
- padding-left: 16px;
1602
- border-left: 2px solid rgba(71, 85, 105, 0.3);
1603
- margin-left: 8px;
1604
- }
1605
-
1606
- .pool-provider-group.open > .pool-model-sublist {
1607
- display: block;
1608
- }
1609
-
1610
- .pool-model-sublist .model-option {
1611
- font-size: 13px;
1612
- padding: 6px 12px;
1613
- }
1614
-
1615
- .provider-pool-weight label {
1616
- display: block;
1617
- margin-bottom: 4px;
1618
- font-size: 0.75rem;
1619
- color: #94a3b8;
1620
- }
1621
-
1622
- .provider-pool-weight input {
1623
- width: 100%;
1624
- }
1625
-
1626
- .provider-pool-remove {
1627
- padding: 8px 12px;
1628
- border-radius: 10px;
1629
- border: 1px solid rgba(127, 29, 29, 0.6);
1630
- background: rgba(127, 29, 29, 0.2);
1631
- color: #fca5a5;
1632
- cursor: pointer;
1633
- }
1634
-
1635
- .provider-pool-remove:hover {
1636
- background: rgba(127, 29, 29, 0.35);
1637
- border-color: rgba(248, 113, 113, 0.8);
1638
- }
1639
-
1640
- /* Inline API Key error */
1641
- .api-key-error {
1642
- margin-top: 6px;
1643
- padding: 6px 10px;
1644
- background: rgba(127, 29, 29, 0.15);
1645
- border: 1px solid rgba(248, 113, 113, 0.2);
1646
- border-radius: 6px;
1647
- color: #fca5a5;
1648
- font-size: 0.78rem;
1649
- line-height: 1.4;
1650
- }
1651
-
1652
- /* Test result modal items */
1653
- .test-result-box {
1654
- max-width: 460px !important;
1655
- }
1656
-
1657
- .test-result-list {
1658
- display: flex;
1659
- flex-direction: column;
1660
- gap: 8px;
1661
- margin-bottom: 20px;
1662
- max-height: 300px;
1663
- overflow-y: auto;
1664
- }
1665
-
1666
- .test-result-item {
1667
- padding: 10px 14px;
1668
- border-radius: 10px;
1669
- background: rgba(6, 8, 15, 0.4);
1670
- border: 1px solid rgba(51, 65, 85, 0.3);
1671
- }
1672
-
1673
- .test-result-item.test-ok {
1674
- border-color: rgba(52, 211, 153, 0.2);
1675
- }
1676
-
1677
- .test-result-item.test-fail {
1678
- border-color: rgba(248, 113, 113, 0.3);
1679
- background: rgba(127, 29, 29, 0.1);
1680
- }
1681
-
1682
- .test-result-row {
1683
- display: flex;
1684
- align-items: center;
1685
- gap: 10px;
1686
- }
1687
-
1688
- .test-result-status {
1689
- font-size: 1rem;
1690
- font-weight: 700;
1691
- width: 20px;
1692
- text-align: center;
1693
- }
1694
-
1695
- .test-ok .test-result-status {
1696
- color: #34d399;
1697
- }
1698
-
1699
- .test-fail .test-result-status {
1700
- color: #f87171;
1701
- }
1702
-
1703
- .test-result-alias {
1704
- flex: 1;
1705
- color: #e2e8f0;
1706
- font-size: 0.9rem;
1707
- font-weight: 500;
1708
- }
1709
-
1710
- .test-result-latency {
1711
- color: #60a5fa;
1712
- font-size: 0.82rem;
1713
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
1714
- }
1715
-
1716
- .test-result-error {
1717
- margin-top: 6px;
1718
- padding: 5px 10px;
1719
- color: #fca5a5;
1720
- font-size: 0.78rem;
1721
- background: rgba(127, 29, 29, 0.15);
1722
- border-radius: 6px;
1723
- border: 1px solid rgba(248, 113, 113, 0.1);
1724
- }
1725
-
1726
- /* test-result-list scrollbar */
1727
- .test-result-list::-webkit-scrollbar {
1728
- width: 6px;
1729
- }
1730
-
1731
- .test-result-list::-webkit-scrollbar-track {
1732
- background: transparent;
1733
- }
1734
-
1735
- .test-result-list::-webkit-scrollbar-thumb {
1736
- background: rgba(71, 85, 105, 0.5);
1737
- border-radius: 3px;
1738
- }
1739
-
1740
- /* Log viewer */
1741
- .log-toolbar {
1742
- display: flex;
1743
- gap: 10px;
1744
- align-items: center;
1745
- padding: 14px 28px;
1746
- border-bottom: 1px solid var(--border-light);
1747
- background: var(--bg-surface-alt);
1748
- }
1749
-
1750
- .log-toolbar select {
1751
- padding: 6px 10px;
1752
- background: var(--bg-surface);
1753
- border: 1px solid var(--border-input);
1754
- border-radius: 8px;
1755
- color: #e2e8f0;
1756
- font-size: 0.85rem;
1757
- cursor: pointer;
1758
- appearance: auto;
1759
- }
1760
-
1761
- .log-toolbar select option {
1762
- background: #0f172a;
1763
- color: #e2e8f0;
1764
- }
1765
-
1766
- .log-content {
1767
- padding: 16px 28px 28px;
1768
- max-height: 500px;
1769
- overflow-y: auto;
1770
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
1771
- font-size: 0.78rem;
1772
- line-height: 1.7;
1773
- color: var(--text-muted);
1774
- background: var(--bg-surface-alt);
1775
- }
1776
-
1777
- .log-content::-webkit-scrollbar {
1778
- width: 6px;
1779
- }
1780
-
1781
- .log-content::-webkit-scrollbar-track {
1782
- background: transparent;
1783
- }
1784
-
1785
- .log-content::-webkit-scrollbar-thumb {
1786
- background: rgba(71, 85, 105, 0.5);
1787
- border-radius: 3px;
1788
- }
1789
-
1790
- .log-line {
1791
- padding: 1px 0;
1792
- white-space: pre-wrap;
1793
- word-break: break-all;
1794
- }
1795
-
1796
- .log-line.log-error {
1797
- color: #fca5a5;
1798
- }
1799
-
1800
- .log-line.log-warn {
1801
- color: #fbbf24;
1802
- }
1803
-
1804
- /* History viewer */
1805
- .history-content {
1806
- padding: 20px 28px 28px;
1807
- max-height: 500px;
1808
- overflow-y: auto;
1809
- }
1810
-
1811
- .history-content::-webkit-scrollbar {
1812
- width: 6px;
1813
- }
1814
-
1815
- .history-content::-webkit-scrollbar-track {
1816
- background: transparent;
1817
- }
1818
-
1819
- .history-content::-webkit-scrollbar-thumb {
1820
- background: rgba(71, 85, 105, 0.5);
1821
- border-radius: 3px;
1822
- }
1823
-
1824
- .history-list {
1825
- display: flex;
1826
- flex-direction: column;
1827
- gap: 8px;
1828
- }
1829
-
1830
- .history-item {
1831
- display: flex;
1832
- align-items: center;
1833
- justify-content: space-between;
1834
- padding: 12px 16px;
1835
- background: var(--bg-surface-alt);
1836
- border: 1px solid var(--border-light);
1837
- border-radius: 10px;
1838
- transition: border-color 0.2s;
1839
- }
1840
-
1841
- .history-item:hover {
1842
- border-color: rgba(59, 130, 246, 0.3);
1843
- }
1844
-
1845
- .history-info {
1846
- display: flex;
1847
- align-items: center;
1848
- gap: 14px;
1849
- flex: 1;
1850
- min-width: 0;
1851
- }
1852
-
1853
- .history-time {
1854
- color: #e2e8f0;
1855
- font-size: 0.85rem;
1856
- font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
1857
- white-space: nowrap;
1858
- }
1859
-
1860
- .history-reason {
1861
- color: #94a3b8;
1862
- font-size: 0.82rem;
1863
- padding: 2px 8px;
1864
- background: rgba(51, 65, 85, 0.3);
1865
- border-radius: 6px;
1866
- white-space: nowrap;
1867
- }
1868
-
1869
- .history-size {
1870
- color: #64748b;
1871
- font-size: 0.78rem;
1872
- white-space: nowrap;
1873
- }
1874
-
1875
- /* Health dots */
1876
- .health-dot {
1877
- display: inline-block;
1878
- width: 8px;
1879
- height: 8px;
1880
- border-radius: 50%;
1881
- vertical-align: middle;
1882
- margin-right: 4px;
1883
- }
1884
-
1885
- .health-ok { background: #22c55e; box-shadow: 0 0 6px rgba(34, 197, 94, 0.4); }
1886
- .health-warn { background: #f59e0b; box-shadow: 0 0 6px rgba(245, 158, 11, 0.4); }
1887
- .health-error { background: #ef4444; box-shadow: 0 0 6px rgba(239, 68, 68, 0.4); }
1888
- .health-unknown { background: #64748b; }
1889
-
1890
- /* Provider health summary */
1891
- .provider-health-summary {
1892
- display: flex;
1893
- align-items: center;
1894
- gap: 18px;
1895
- padding: 12px 28px;
1896
- border-bottom: 1px solid var(--border-light);
1897
- background: var(--bg-surface-alt);
1898
- font-size: 0.82rem;
1899
- color: var(--text-muted);
1900
- }
1901
-
1902
- .health-stat {
1903
- display: flex;
1904
- align-items: center;
1905
- gap: 5px;
1906
- }
1
+ /* ================================================
2
+ Protocol Proxy — Design System
3
+ ================================================ */
4
+
5
+ /* ---------- CSS Variables ---------- */
6
+ :root {
7
+ --font-display: 'Plus Jakarta Sans', system-ui, sans-serif;
8
+ --font-body: 'DM Sans', system-ui, sans-serif;
9
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
10
+
11
+ --bg-base: #FFFFFF;
12
+ --bg-elevated: #F4F4F5;
13
+ --bg-surface: #E4E4E7;
14
+ --bg-surface-hover: #D4D4D8;
15
+ --border-default: #E4E4E7;
16
+ --border-subtle: #F4F4F5;
17
+ --text-primary: #18181B;
18
+ --text-secondary: #52525B;
19
+ --text-muted: #71717A;
20
+ --text-faint: #A1A1AA;
21
+ --text-inverse: #FAFAFA;
22
+
23
+ --accent: #0EA5E9;
24
+ --accent-hover: #0284C7;
25
+ --accent-subtle: rgba(14, 165, 233, 0.08);
26
+ --accent-border: rgba(14, 165, 233, 0.25);
27
+
28
+ --success: #22C55E;
29
+ --success-bg: rgba(34, 197, 94, 0.08);
30
+ --warning: #F59E0B;
31
+ --warning-bg: rgba(245, 158, 11, 0.08);
32
+ --error: #EF4444;
33
+ --error-bg: rgba(239, 68, 68, 0.08);
34
+
35
+ --sidebar-width: 240px;
36
+ --topbar-height: 60px;
37
+ --radius-sm: 6px;
38
+ --radius-md: 8px;
39
+ --radius-lg: 12px;
40
+ --radius-full: 9999px;
41
+
42
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
43
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.06);
44
+ --shadow-lg: 0 12px 40px rgba(0,0,0,0.1);
45
+
46
+ --transition-micro: 100ms cubic-bezier(0,0,0.2,1);
47
+ --transition-short: 200ms cubic-bezier(0,0,0.2,1);
48
+ --transition-medium: 300ms cubic-bezier(0.4,0,0.2,1);
49
+ }
50
+
51
+ [data-theme="dark"] {
52
+ --bg-base: #09090B;
53
+ --bg-elevated: #18181B;
54
+ --bg-surface: #27272A;
55
+ --bg-surface-hover: #3F3F46;
56
+ --border-default: #3F3F46;
57
+ --border-subtle: #27272A;
58
+ --text-primary: #FAFAFA;
59
+ --text-secondary: #A1A1AA;
60
+ --text-muted: #71717A;
61
+ --text-faint: #52525B;
62
+ --text-inverse: #18181B;
63
+
64
+ --accent-subtle: rgba(14, 165, 233, 0.12);
65
+ --accent-border: rgba(14, 165, 233, 0.3);
66
+
67
+ --success-bg: rgba(34, 197, 94, 0.12);
68
+ --warning-bg: rgba(245, 158, 11, 0.12);
69
+ --error-bg: rgba(239, 68, 68, 0.12);
70
+
71
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
72
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.4);
73
+ --shadow-lg: 0 12px 40px rgba(0,0,0,0.5);
74
+ }
75
+
76
+ /* ---------- Midnight Theme ---------- */
77
+ [data-theme="midnight"] {
78
+ --bg-base: #0f0f1a;
79
+ --bg-elevated: #16162a;
80
+ --bg-surface: #222240;
81
+ --bg-surface-hover: #2e2e58;
82
+ --border-default: #2a2a50;
83
+ --border-subtle: #1e1e3a;
84
+ --text-primary: #f0f0ff;
85
+ --text-secondary: #a0a0c8;
86
+ --text-muted: #7a7aa8;
87
+ --text-faint: #55558a;
88
+ --text-inverse: #0f0f1a;
89
+
90
+ --accent: #8b5cf6;
91
+ --accent-hover: #7c3aed;
92
+ --accent-subtle: rgba(139, 92, 246, 0.12);
93
+ --accent-border: rgba(139, 92, 246, 0.3);
94
+
95
+ --success: #34d399;
96
+ --success-bg: rgba(52, 211, 153, 0.12);
97
+ --warning: #fbbf24;
98
+ --warning-bg: rgba(251, 191, 36, 0.12);
99
+ --error: #f87171;
100
+ --error-bg: rgba(248, 113, 113, 0.12);
101
+
102
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
103
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.5);
104
+ --shadow-lg: 0 12px 40px rgba(0,0,0,0.6);
105
+ }
106
+
107
+ /* ---------- Forest Theme ---------- */
108
+ [data-theme="forest"] {
109
+ --bg-base: #0a1a12;
110
+ --bg-elevated: #122b1e;
111
+ --bg-surface: #1b3f2d;
112
+ --bg-surface-hover: #24523b;
113
+ --border-default: #264f3a;
114
+ --border-subtle: #1a3628;
115
+ --text-primary: #e8f5e9;
116
+ --text-secondary: #90bfa0;
117
+ --text-muted: #6b9e80;
118
+ --text-faint: #4a7a5e;
119
+ --text-inverse: #0a1a12;
120
+
121
+ --accent: #34d399;
122
+ --accent-hover: #10b981;
123
+ --accent-subtle: rgba(52, 211, 153, 0.12);
124
+ --accent-border: rgba(52, 211, 153, 0.3);
125
+
126
+ --success: #4ade80;
127
+ --success-bg: rgba(74, 222, 128, 0.12);
128
+ --warning: #facc15;
129
+ --warning-bg: rgba(250, 204, 21, 0.12);
130
+ --error: #f87171;
131
+ --error-bg: rgba(248, 113, 113, 0.12);
132
+
133
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
134
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.5);
135
+ --shadow-lg: 0 12px 40px rgba(0,0,0,0.6);
136
+ }
137
+
138
+ /* ---------- Sunset Theme ---------- */
139
+ [data-theme="sunset"] {
140
+ --bg-base: #1c1410;
141
+ --bg-elevated: #2d1f18;
142
+ --bg-surface: #3e2b20;
143
+ --bg-surface-hover: #503828;
144
+ --border-default: #4a3428;
145
+ --border-subtle: #2d2018;
146
+ --text-primary: #fff5eb;
147
+ --text-secondary: #c4a890;
148
+ --text-muted: #a08068;
149
+ --text-faint: #786050;
150
+ --text-inverse: #1c1410;
151
+
152
+ --accent: #fb923c;
153
+ --accent-hover: #f97316;
154
+ --accent-subtle: rgba(251, 146, 60, 0.12);
155
+ --accent-border: rgba(251, 146, 60, 0.3);
156
+
157
+ --success: #86efac;
158
+ --success-bg: rgba(134, 239, 172, 0.12);
159
+ --warning: #fcd34d;
160
+ --warning-bg: rgba(252, 211, 77, 0.12);
161
+ --error: #fca5a5;
162
+ --error-bg: rgba(252, 165, 165, 0.12);
163
+
164
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
165
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.5);
166
+ --shadow-lg: 0 12px 40px rgba(0,0,0,0.6);
167
+ }
168
+
169
+ /* ---------- Ocean Theme ---------- */
170
+ [data-theme="ocean"] {
171
+ --bg-base: #0a1628;
172
+ --bg-elevated: #0f2744;
173
+ --bg-surface: #1a3a5c;
174
+ --bg-surface-hover: #234a70;
175
+ --border-default: #1e4568;
176
+ --border-subtle: #132840;
177
+ --text-primary: #e0f2fe;
178
+ --text-secondary: #7fb8d9;
179
+ --text-muted: #5a96b8;
180
+ --text-faint: #3f7496;
181
+ --text-inverse: #0a1628;
182
+
183
+ --accent: #22d3ee;
184
+ --accent-hover: #06b6d4;
185
+ --accent-subtle: rgba(34, 211, 238, 0.12);
186
+ --accent-border: rgba(34, 211, 238, 0.3);
187
+
188
+ --success: #4ade80;
189
+ --success-bg: rgba(74, 222, 128, 0.12);
190
+ --warning: #facc15;
191
+ --warning-bg: rgba(250, 204, 21, 0.12);
192
+ --error: #f87171;
193
+ --error-bg: rgba(248, 113, 113, 0.12);
194
+
195
+ --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
196
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.5);
197
+ --shadow-lg: 0 12px 40px rgba(0,0,0,0.6);
198
+ }
199
+
200
+ /* ---------- Sakura Theme ---------- */
201
+ [data-theme="sakura"] {
202
+ --bg-base: #fff5f7;
203
+ --bg-elevated: #ffe8ed;
204
+ --bg-surface: #ffd9e4;
205
+ --bg-surface-hover: #fcc9d8;
206
+ --border-default: #f2c2d0;
207
+ --border-subtle: #ffe8ed;
208
+ --text-primary: #4a1022;
209
+ --text-secondary: #8a4060;
210
+ --text-muted: #a86080;
211
+ --text-faint: #c490a8;
212
+ --text-inverse: #fff5f7;
213
+
214
+ --accent: #ec4899;
215
+ --accent-hover: #db2777;
216
+ --accent-subtle: rgba(236, 72, 153, 0.08);
217
+ --accent-border: rgba(236, 72, 153, 0.25);
218
+
219
+ --success: #22c55e;
220
+ --success-bg: rgba(34, 197, 94, 0.08);
221
+ --warning: #f59e0b;
222
+ --warning-bg: rgba(245, 158, 11, 0.08);
223
+ --error: #ef4444;
224
+ --error-bg: rgba(239, 68, 68, 0.08);
225
+
226
+ --shadow-sm: 0 1px 2px rgba(74, 16, 34, 0.06);
227
+ --shadow-md: 0 4px 12px rgba(74, 16, 34, 0.08);
228
+ --shadow-lg: 0 12px 40px rgba(74, 16, 34, 0.12);
229
+ }
230
+
231
+ /* ---------- Reset & Base ---------- */
232
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
233
+
234
+ html { font-size: 14px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
235
+
236
+ body {
237
+ font-family: var(--font-body);
238
+ background: var(--bg-base);
239
+ color: var(--text-secondary);
240
+ line-height: 1.6;
241
+ min-height: 100vh;
242
+ overflow: hidden;
243
+ }
244
+
245
+ /* ---------- App Layout ---------- */
246
+ .app {
247
+ display: flex;
248
+ height: 100vh;
249
+ width: 100vw;
250
+ overflow: hidden;
251
+ }
252
+
253
+ /* ---------- Sidebar ---------- */
254
+ .sidebar {
255
+ width: var(--sidebar-width);
256
+ flex-shrink: 0;
257
+ background: var(--bg-elevated);
258
+ border-right: 1px solid var(--border-default);
259
+ display: flex;
260
+ flex-direction: column;
261
+ height: 100%;
262
+ transition: width var(--transition-medium);
263
+ }
264
+
265
+ .sidebar-brand {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 10px;
269
+ padding: 0 20px;
270
+ height: var(--topbar-height);
271
+ border-bottom: 1px solid var(--border-default);
272
+ flex-shrink: 0;
273
+ }
274
+
275
+ .brand-icon {
276
+ width: 32px;
277
+ height: 32px;
278
+ border-radius: var(--radius-md);
279
+ background: var(--accent-subtle);
280
+ color: var(--accent);
281
+ display: flex;
282
+ align-items: center;
283
+ justify-content: center;
284
+ flex-shrink: 0;
285
+ }
286
+
287
+ .brand-text {
288
+ font-family: var(--font-display);
289
+ font-size: 15px;
290
+ font-weight: 700;
291
+ color: var(--text-primary);
292
+ letter-spacing: -0.01em;
293
+ }
294
+
295
+ .sidebar-nav {
296
+ flex: 1;
297
+ padding: 12px 10px;
298
+ overflow-y: auto;
299
+ }
300
+
301
+ .nav-item {
302
+ display: flex;
303
+ align-items: center;
304
+ gap: 10px;
305
+ padding: 9px 12px;
306
+ border-radius: var(--radius-md);
307
+ color: var(--text-secondary);
308
+ text-decoration: none;
309
+ font-size: 13px;
310
+ font-weight: 500;
311
+ transition: all var(--transition-micro);
312
+ margin-bottom: 2px;
313
+ cursor: pointer;
314
+ user-select: none;
315
+ }
316
+
317
+ .nav-item:hover {
318
+ background: var(--bg-surface);
319
+ color: var(--text-primary);
320
+ }
321
+
322
+ .nav-item.active {
323
+ background: var(--accent-subtle);
324
+ color: var(--accent);
325
+ }
326
+
327
+ .nav-item svg {
328
+ flex-shrink: 0;
329
+ opacity: 0.7;
330
+ }
331
+
332
+ .nav-item.active svg { opacity: 1; }
333
+
334
+ .nav-badge {
335
+ margin-left: auto;
336
+ padding: 1px 7px;
337
+ border-radius: var(--radius-full);
338
+ background: var(--bg-surface);
339
+ color: var(--text-muted);
340
+ font-size: 11px;
341
+ font-weight: 600;
342
+ font-family: var(--font-mono);
343
+ }
344
+
345
+ .nav-item.active .nav-badge {
346
+ background: var(--accent);
347
+ color: #fff;
348
+ }
349
+
350
+ .sidebar-footer {
351
+ padding: 12px 16px;
352
+ border-top: 1px solid var(--border-default);
353
+ flex-shrink: 0;
354
+ }
355
+
356
+ .theme-toggle-btn {
357
+ display: flex;
358
+ align-items: center;
359
+ gap: 8px;
360
+ width: 100%;
361
+ padding: 8px 12px;
362
+ border-radius: var(--radius-md);
363
+ border: 1px solid var(--border-default);
364
+ background: var(--bg-base);
365
+ color: var(--text-secondary);
366
+ font-size: 13px;
367
+ font-family: var(--font-body);
368
+ cursor: pointer;
369
+ transition: all var(--transition-micro);
370
+ }
371
+
372
+ .theme-toggle-btn:hover {
373
+ border-color: var(--accent);
374
+ color: var(--accent);
375
+ }
376
+
377
+ .version {
378
+ text-align: center;
379
+ margin-top: 8px;
380
+ font-size: 11px;
381
+ color: var(--text-faint);
382
+ font-family: var(--font-mono);
383
+ }
384
+
385
+ /* ---------- Main Area ---------- */
386
+ .main {
387
+ flex: 1;
388
+ display: flex;
389
+ flex-direction: column;
390
+ min-width: 0;
391
+ background: var(--bg-base);
392
+ }
393
+
394
+ /* ---------- Topbar ---------- */
395
+ .topbar {
396
+ display: flex;
397
+ align-items: center;
398
+ justify-content: space-between;
399
+ height: var(--topbar-height);
400
+ padding: 0 28px;
401
+ border-bottom: 1px solid var(--border-default);
402
+ flex-shrink: 0;
403
+ background: var(--bg-base);
404
+ }
405
+
406
+ .page-title {
407
+ font-family: var(--font-display);
408
+ font-size: 20px;
409
+ font-weight: 700;
410
+ color: var(--text-primary);
411
+ letter-spacing: -0.01em;
412
+ }
413
+
414
+ .topbar-right {
415
+ display: flex;
416
+ align-items: center;
417
+ gap: 12px;
418
+ }
419
+
420
+ .health-summary {
421
+ display: flex;
422
+ align-items: center;
423
+ gap: 8px;
424
+ font-size: 12px;
425
+ color: var(--text-muted);
426
+ }
427
+
428
+ .health-dot {
429
+ width: 8px;
430
+ height: 8px;
431
+ border-radius: var(--radius-full);
432
+ background: var(--text-faint);
433
+ }
434
+
435
+ .health-dot.ok { background: var(--success); }
436
+ .health-dot.warn { background: var(--warning); }
437
+ .health-dot.error { background: var(--error); }
438
+
439
+ /* ---------- Page ---------- */
440
+ .page {
441
+ display: none;
442
+ flex: 1;
443
+ overflow-y: auto;
444
+ padding: 24px 28px 48px;
445
+ }
446
+
447
+ .page.active { display: block; }
448
+
449
+ /* ---------- Page Toolbar ---------- */
450
+ .page-toolbar {
451
+ display: flex;
452
+ align-items: center;
453
+ justify-content: space-between;
454
+ gap: 16px;
455
+ margin-bottom: 24px;
456
+ flex-wrap: wrap;
457
+ }
458
+
459
+ .search-box {
460
+ display: flex;
461
+ align-items: center;
462
+ gap: 8px;
463
+ flex: 1;
464
+ max-width: 360px;
465
+ padding: 0 12px;
466
+ height: 36px;
467
+ background: var(--bg-elevated);
468
+ border: 1px solid var(--border-default);
469
+ border-radius: var(--radius-md);
470
+ transition: all var(--transition-micro);
471
+ }
472
+
473
+ .search-box:focus-within {
474
+ border-color: var(--accent);
475
+ box-shadow: 0 0 0 3px var(--accent-subtle);
476
+ }
477
+
478
+ .search-box svg {
479
+ color: var(--text-faint);
480
+ flex-shrink: 0;
481
+ }
482
+
483
+ .search-box input {
484
+ flex: 1;
485
+ border: none;
486
+ background: transparent;
487
+ color: var(--text-primary);
488
+ font-family: var(--font-body);
489
+ font-size: 13px;
490
+ outline: none;
491
+ }
492
+
493
+ .search-box input::placeholder { color: var(--text-faint); }
494
+
495
+ .filter-group {
496
+ display: flex;
497
+ align-items: center;
498
+ gap: 8px;
499
+ flex-wrap: wrap;
500
+ }
501
+
502
+ .filter-group select,
503
+ .filter-group input[type="date"],
504
+ .filter-group input[type="text"] {
505
+ height: 36px;
506
+ padding: 0 10px;
507
+ background: var(--bg-elevated);
508
+ border: 1px solid var(--border-default);
509
+ border-radius: var(--radius-md);
510
+ color: var(--text-primary);
511
+ font-family: var(--font-body);
512
+ font-size: 13px;
513
+ outline: none;
514
+ transition: all var(--transition-micro);
515
+ }
516
+
517
+ .filter-group select:focus,
518
+ .filter-group input:focus {
519
+ border-color: var(--accent);
520
+ box-shadow: 0 0 0 3px var(--accent-subtle);
521
+ }
522
+
523
+ .filter-sep {
524
+ color: var(--text-faint);
525
+ font-size: 12px;
526
+ }
527
+
528
+ .toolbar-actions {
529
+ display: flex;
530
+ align-items: center;
531
+ gap: 8px;
532
+ }
533
+
534
+ /* ---------- Buttons ---------- */
535
+ .btn {
536
+ display: inline-flex;
537
+ align-items: center;
538
+ justify-content: center;
539
+ gap: 6px;
540
+ height: 36px;
541
+ padding: 0 14px;
542
+ border-radius: var(--radius-md);
543
+ border: 1px solid var(--border-default);
544
+ background: var(--bg-elevated);
545
+ color: var(--text-secondary);
546
+ font-family: var(--font-body);
547
+ font-size: 13px;
548
+ font-weight: 500;
549
+ cursor: pointer;
550
+ transition: all var(--transition-micro);
551
+ white-space: nowrap;
552
+ }
553
+
554
+ .btn:hover {
555
+ background: var(--bg-surface);
556
+ color: var(--text-primary);
557
+ border-color: var(--text-faint);
558
+ }
559
+
560
+ .btn:disabled {
561
+ opacity: 0.5;
562
+ cursor: not-allowed;
563
+ }
564
+
565
+ .btn-primary {
566
+ background: var(--accent);
567
+ border-color: var(--accent);
568
+ color: #fff;
569
+ }
570
+
571
+ .btn-primary:hover {
572
+ background: var(--accent-hover);
573
+ border-color: var(--accent-hover);
574
+ }
575
+
576
+ .btn-danger {
577
+ background: var(--error);
578
+ border-color: var(--error);
579
+ color: #fff;
580
+ }
581
+
582
+ .btn-danger:hover {
583
+ background: #DC2626;
584
+ border-color: #DC2626;
585
+ }
586
+
587
+ .btn-sm {
588
+ height: 30px;
589
+ padding: 0 10px;
590
+ font-size: 12px;
591
+ }
592
+
593
+ /* ---------- Panel / Card ---------- */
594
+ .panel {
595
+ background: var(--bg-elevated);
596
+ border: 1px solid var(--border-default);
597
+ border-radius: var(--radius-lg);
598
+ overflow: hidden;
599
+ }
600
+
601
+ .panel-header {
602
+ display: flex;
603
+ align-items: center;
604
+ justify-content: space-between;
605
+ padding: 16px 20px;
606
+ border-bottom: 1px solid var(--border-subtle);
607
+ }
608
+
609
+ .panel-header h3 {
610
+ font-family: var(--font-display);
611
+ font-size: 15px;
612
+ font-weight: 600;
613
+ color: var(--text-primary);
614
+ }
615
+
616
+ .panel-sub {
617
+ font-size: 12px;
618
+ color: var(--text-muted);
619
+ font-weight: 500;
620
+ }
621
+
622
+ /* ---------- Dashboard ---------- */
623
+ .dashboard-grid {
624
+ display: grid;
625
+ grid-template-columns: repeat(4, 1fr);
626
+ gap: 16px;
627
+ margin-bottom: 24px;
628
+ }
629
+
630
+ .metric-card {
631
+ background: var(--bg-elevated);
632
+ border: 1px solid var(--border-default);
633
+ border-radius: var(--radius-lg);
634
+ padding: 20px;
635
+ transition: all var(--transition-short);
636
+ }
637
+
638
+ .metric-card:hover {
639
+ border-color: var(--accent-border);
640
+ box-shadow: var(--shadow-sm);
641
+ }
642
+
643
+ .metric-label {
644
+ font-size: 12px;
645
+ font-weight: 500;
646
+ color: var(--text-muted);
647
+ text-transform: uppercase;
648
+ letter-spacing: 0.04em;
649
+ margin-bottom: 8px;
650
+ }
651
+
652
+ .metric-value {
653
+ font-family: var(--font-mono);
654
+ font-size: 28px;
655
+ font-weight: 500;
656
+ color: var(--text-primary);
657
+ line-height: 1.2;
658
+ }
659
+
660
+ .metric-sub {
661
+ font-size: 12px;
662
+ color: var(--text-faint);
663
+ margin-top: 4px;
664
+ font-family: var(--font-mono);
665
+ }
666
+
667
+ .dashboard-row {
668
+ display: flex;
669
+ gap: 16px;
670
+ margin-bottom: 24px;
671
+ }
672
+
673
+ .dashboard-row .flex-2 { flex: 2; }
674
+ .dashboard-row .flex-1 { flex: 1; }
675
+
676
+ /* ---------- Proxy Mini List (Dashboard) ---------- */
677
+ .proxy-mini-list {
678
+ padding: 8px 0;
679
+ }
680
+
681
+ .proxy-mini-item {
682
+ display: flex;
683
+ align-items: center;
684
+ gap: 12px;
685
+ padding: 10px 20px;
686
+ transition: background var(--transition-micro);
687
+ cursor: pointer;
688
+ }
689
+
690
+ .proxy-mini-item:hover {
691
+ background: var(--bg-surface-hover);
692
+ }
693
+
694
+ .proxy-mini-status {
695
+ width: 8px;
696
+ height: 8px;
697
+ border-radius: var(--radius-full);
698
+ flex-shrink: 0;
699
+ }
700
+
701
+ .proxy-mini-status.running { background: var(--success); }
702
+ .proxy-mini-status.stopped { background: var(--warning); }
703
+
704
+ .proxy-mini-info {
705
+ flex: 1;
706
+ min-width: 0;
707
+ }
708
+
709
+ .proxy-mini-name {
710
+ font-size: 13px;
711
+ font-weight: 600;
712
+ color: var(--text-primary);
713
+ }
714
+
715
+ .proxy-mini-meta {
716
+ font-size: 12px;
717
+ color: var(--text-muted);
718
+ font-family: var(--font-mono);
719
+ }
720
+
721
+ .proxy-mini-port {
722
+ font-size: 12px;
723
+ color: var(--accent);
724
+ font-family: var(--font-mono);
725
+ font-weight: 500;
726
+ }
727
+
728
+ /* ---------- Provider Health List ---------- */
729
+ .provider-health-list {
730
+ padding: 8px 0;
731
+ }
732
+
733
+ .provider-health-item {
734
+ display: flex;
735
+ align-items: center;
736
+ gap: 10px;
737
+ padding: 8px 20px;
738
+ }
739
+
740
+ .provider-health-name {
741
+ flex: 1;
742
+ font-size: 13px;
743
+ color: var(--text-primary);
744
+ }
745
+
746
+ .provider-health-status {
747
+ font-size: 11px;
748
+ font-weight: 600;
749
+ padding: 2px 8px;
750
+ border-radius: var(--radius-full);
751
+ }
752
+
753
+ .provider-health-status.healthy {
754
+ background: var(--success-bg);
755
+ color: var(--success);
756
+ }
757
+
758
+ .provider-health-status.partial {
759
+ background: var(--warning-bg);
760
+ color: var(--warning);
761
+ }
762
+
763
+ .provider-health-status.unhealthy {
764
+ background: var(--error-bg);
765
+ color: var(--error);
766
+ }
767
+
768
+ /* ---------- Proxy Grid ---------- */
769
+ .proxy-grid {
770
+ display: grid;
771
+ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
772
+ gap: 16px;
773
+ }
774
+
775
+ .proxy-card {
776
+ background: var(--bg-elevated);
777
+ border: 1px solid var(--border-default);
778
+ border-radius: var(--radius-lg);
779
+ padding: 20px;
780
+ transition: all var(--transition-short);
781
+ position: relative;
782
+ overflow: hidden;
783
+ }
784
+
785
+ .proxy-card:hover {
786
+ border-color: var(--accent-border);
787
+ box-shadow: var(--shadow-md);
788
+ transform: translateY(-1px);
789
+ }
790
+
791
+ .proxy-card::before {
792
+ content: '';
793
+ position: absolute;
794
+ top: 0;
795
+ left: 0;
796
+ width: 3px;
797
+ height: 100%;
798
+ background: var(--text-faint);
799
+ transition: background var(--transition-short);
800
+ }
801
+
802
+ .proxy-card:hover::before {
803
+ background: var(--accent);
804
+ }
805
+
806
+ .proxy-card.running::before { background: var(--success); }
807
+ .proxy-card.stopped::before { background: var(--warning); }
808
+
809
+ .proxy-card-header {
810
+ display: flex;
811
+ align-items: center;
812
+ justify-content: space-between;
813
+ margin-bottom: 12px;
814
+ }
815
+
816
+ .proxy-card-title {
817
+ font-size: 15px;
818
+ font-weight: 600;
819
+ color: var(--text-primary);
820
+ }
821
+
822
+ .proxy-card-badge {
823
+ font-size: 11px;
824
+ font-weight: 600;
825
+ padding: 2px 8px;
826
+ border-radius: var(--radius-full);
827
+ }
828
+
829
+ .proxy-card-badge.running {
830
+ background: var(--success-bg);
831
+ color: var(--success);
832
+ }
833
+
834
+ .proxy-card-badge.stopped {
835
+ background: var(--warning-bg);
836
+ color: var(--warning);
837
+ }
838
+
839
+ .proxy-card-meta {
840
+ display: grid;
841
+ grid-template-columns: 1fr 1fr;
842
+ gap: 8px 16px;
843
+ margin-bottom: 16px;
844
+ }
845
+
846
+ .proxy-card-meta-item {
847
+ display: flex;
848
+ flex-direction: column;
849
+ gap: 2px;
850
+ }
851
+
852
+ .proxy-card-meta-label {
853
+ font-size: 11px;
854
+ color: var(--text-faint);
855
+ text-transform: uppercase;
856
+ letter-spacing: 0.04em;
857
+ }
858
+
859
+ .proxy-card-meta-value {
860
+ font-size: 13px;
861
+ color: var(--text-secondary);
862
+ font-family: var(--font-mono);
863
+ }
864
+
865
+ .proxy-pool-preview {
866
+ margin-bottom: 12px;
867
+ padding: 6px 10px;
868
+ font-size: 12px;
869
+ color: var(--text-muted);
870
+ background: var(--bg-elevated);
871
+ border-radius: var(--radius-sm);
872
+ border: 1px solid var(--border-subtle);
873
+ font-family: var(--font-mono);
874
+ }
875
+
876
+ .proxy-card-actions {
877
+ display: flex;
878
+ gap: 8px;
879
+ padding-top: 12px;
880
+ border-top: 1px solid var(--border-subtle);
881
+ }
882
+
883
+ /* ---------- Provider Grid ---------- */
884
+ .provider-grid {
885
+ display: grid;
886
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
887
+ gap: 16px;
888
+ }
889
+
890
+ .provider-card {
891
+ background: var(--bg-elevated);
892
+ border: 1px solid var(--border-default);
893
+ border-radius: var(--radius-lg);
894
+ padding: 20px;
895
+ transition: all var(--transition-short);
896
+ }
897
+
898
+ .provider-card:hover {
899
+ border-color: var(--accent-border);
900
+ box-shadow: var(--shadow-md);
901
+ }
902
+
903
+ .provider-card-header {
904
+ display: flex;
905
+ align-items: center;
906
+ justify-content: space-between;
907
+ margin-bottom: 12px;
908
+ }
909
+
910
+ .provider-card-name {
911
+ font-size: 15px;
912
+ font-weight: 600;
913
+ color: var(--text-primary);
914
+ }
915
+
916
+ .provider-card-protocol {
917
+ font-size: 11px;
918
+ font-weight: 600;
919
+ padding: 2px 8px;
920
+ border-radius: var(--radius-full);
921
+ background: var(--accent-subtle);
922
+ color: var(--accent);
923
+ text-transform: uppercase;
924
+ }
925
+
926
+ .provider-card-url {
927
+ font-size: 12px;
928
+ color: var(--text-muted);
929
+ font-family: var(--font-mono);
930
+ margin-bottom: 12px;
931
+ word-break: break-all;
932
+ }
933
+
934
+ .provider-card-models {
935
+ display: flex;
936
+ flex-wrap: wrap;
937
+ gap: 4px;
938
+ margin-bottom: 12px;
939
+ }
940
+
941
+ .provider-card-model {
942
+ font-size: 11px;
943
+ padding: 2px 8px;
944
+ border-radius: var(--radius-full);
945
+ background: var(--bg-surface);
946
+ color: var(--text-muted);
947
+ font-family: var(--font-mono);
948
+ }
949
+
950
+ .provider-card-keys {
951
+ font-size: 12px;
952
+ color: var(--text-faint);
953
+ margin-bottom: 12px;
954
+ }
955
+
956
+ .provider-card-actions {
957
+ display: flex;
958
+ gap: 8px;
959
+ padding-top: 12px;
960
+ border-top: 1px solid var(--border-subtle);
961
+ }
962
+
963
+ /* ---------- Data Table ---------- */
964
+ .data-table-wrap {
965
+ overflow-x: auto;
966
+ }
967
+
968
+ .data-table {
969
+ width: 100%;
970
+ border-collapse: collapse;
971
+ font-size: 13px;
972
+ }
973
+
974
+ .data-table th {
975
+ text-align: left;
976
+ padding: 10px 16px;
977
+ font-size: 11px;
978
+ font-weight: 600;
979
+ color: var(--text-faint);
980
+ text-transform: uppercase;
981
+ letter-spacing: 0.04em;
982
+ border-bottom: 1px solid var(--border-default);
983
+ white-space: nowrap;
984
+ }
985
+
986
+ .data-table td {
987
+ padding: 12px 16px;
988
+ border-bottom: 1px solid var(--border-subtle);
989
+ color: var(--text-secondary);
990
+ vertical-align: middle;
991
+ }
992
+
993
+ .data-table tbody tr:hover {
994
+ background: var(--bg-surface-hover);
995
+ }
996
+
997
+ .data-table tbody tr:last-child td {
998
+ border-bottom: none;
999
+ }
1000
+
1001
+ .data-table .num {
1002
+ text-align: right;
1003
+ font-family: var(--font-mono);
1004
+ font-variant-numeric: tabular-nums;
1005
+ }
1006
+
1007
+ .data-table code {
1008
+ font-family: var(--font-mono);
1009
+ font-size: 12px;
1010
+ padding: 2px 6px;
1011
+ border-radius: var(--radius-sm);
1012
+ background: var(--bg-surface);
1013
+ color: var(--text-secondary);
1014
+ }
1015
+
1016
+ .empty-cell {
1017
+ text-align: center;
1018
+ color: var(--text-faint);
1019
+ padding: 48px 16px !important;
1020
+ }
1021
+
1022
+ /* ---------- Stats ---------- */
1023
+ .stats-summary-bar {
1024
+ display: grid;
1025
+ grid-template-columns: repeat(4, 1fr);
1026
+ gap: 16px;
1027
+ margin-bottom: 24px;
1028
+ }
1029
+
1030
+ .stats-summary-item {
1031
+ background: var(--bg-elevated);
1032
+ border: 1px solid var(--border-default);
1033
+ border-radius: var(--radius-lg);
1034
+ padding: 16px 20px;
1035
+ }
1036
+
1037
+ .stats-summary-label {
1038
+ display: block;
1039
+ font-size: 12px;
1040
+ color: var(--text-muted);
1041
+ margin-bottom: 4px;
1042
+ }
1043
+
1044
+ .stats-summary-value {
1045
+ display: block;
1046
+ font-family: var(--font-mono);
1047
+ font-size: 22px;
1048
+ font-weight: 500;
1049
+ color: var(--text-primary);
1050
+ }
1051
+
1052
+ /* ---------- Request Log ---------- */
1053
+ .request-log-summary-bar {
1054
+ display: flex;
1055
+ gap: 16px;
1056
+ margin-bottom: 16px;
1057
+ flex-wrap: wrap;
1058
+ }
1059
+
1060
+ .request-log-summary-item {
1061
+ font-size: 12px;
1062
+ color: var(--text-muted);
1063
+ }
1064
+
1065
+ .request-log-summary-item strong {
1066
+ color: var(--text-primary);
1067
+ font-family: var(--font-mono);
1068
+ }
1069
+
1070
+ #rq-tbody tr.clickable {
1071
+ cursor: pointer;
1072
+ }
1073
+
1074
+ #rq-tbody tr.clickable:hover {
1075
+ background: var(--bg-hover, rgba(255,255,255,0.03));
1076
+ }
1077
+
1078
+ .request-log-detail-row td {
1079
+ padding: 0 !important;
1080
+ border-bottom: 1px solid var(--border-light);
1081
+ }
1082
+
1083
+ .request-log-detail {
1084
+ padding: 10px 16px;
1085
+ background: var(--bg-surface);
1086
+ border-top: 1px solid var(--border-light);
1087
+ }
1088
+
1089
+ .request-log-detail-grid {
1090
+ display: grid;
1091
+ grid-template-columns: auto 1fr;
1092
+ gap: 3px 12px;
1093
+ font-size: 12px;
1094
+ }
1095
+
1096
+ .detail-label {
1097
+ color: var(--text-muted);
1098
+ font-weight: 500;
1099
+ white-space: nowrap;
1100
+ }
1101
+
1102
+ .request-log-detail-error {
1103
+ color: #ef4444;
1104
+ word-break: break-all;
1105
+ }
1106
+
1107
+ /* ---------- Log Panel ---------- */
1108
+ .log-panel {
1109
+ background: var(--bg-elevated);
1110
+ border: 1px solid var(--border-default);
1111
+ border-radius: var(--radius-lg);
1112
+ padding: 16px 20px;
1113
+ font-family: var(--font-mono);
1114
+ font-size: 12px;
1115
+ line-height: 1.8;
1116
+ max-height: calc(100vh - 200px);
1117
+ overflow-y: auto;
1118
+ color: var(--text-secondary);
1119
+ }
1120
+
1121
+ .log-line {
1122
+ padding: 1px 0;
1123
+ border-bottom: 1px solid transparent;
1124
+ }
1125
+
1126
+ .log-line:hover {
1127
+ background: var(--bg-surface-hover);
1128
+ }
1129
+
1130
+ .log-time { color: var(--text-faint); }
1131
+ .log-level-info { color: var(--accent); }
1132
+ .log-level-error { color: var(--error); }
1133
+ .log-level-warn { color: var(--warning); }
1134
+
1135
+ /* ---------- Settings ---------- */
1136
+ .settings-grid {
1137
+ display: grid;
1138
+ grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
1139
+ gap: 16px;
1140
+ }
1141
+
1142
+ .settings-body {
1143
+ padding: 8px 0;
1144
+ }
1145
+
1146
+ .setting-item {
1147
+ display: flex;
1148
+ align-items: center;
1149
+ gap: 16px;
1150
+ padding: 14px 20px;
1151
+ border-bottom: 1px solid var(--border-subtle);
1152
+ }
1153
+
1154
+ .setting-item:last-child {
1155
+ border-bottom: none;
1156
+ }
1157
+
1158
+ .setting-info {
1159
+ flex: 1;
1160
+ min-width: 0;
1161
+ }
1162
+
1163
+ .setting-name {
1164
+ font-size: 14px;
1165
+ font-weight: 500;
1166
+ color: var(--text-primary);
1167
+ margin-bottom: 2px;
1168
+ }
1169
+
1170
+ .setting-desc {
1171
+ font-size: 12px;
1172
+ color: var(--text-muted);
1173
+ }
1174
+
1175
+ /* ---------- Modal ---------- */
1176
+ .modal-overlay {
1177
+ display: none;
1178
+ position: fixed;
1179
+ inset: 0;
1180
+ background: rgba(0,0,0,0.6);
1181
+ backdrop-filter: blur(4px);
1182
+ z-index: 1000;
1183
+ align-items: flex-start;
1184
+ justify-content: center;
1185
+ padding: 40px 20px;
1186
+ overflow-y: auto;
1187
+ }
1188
+
1189
+ .modal-overlay.active {
1190
+ display: flex;
1191
+ }
1192
+
1193
+ .modal {
1194
+ background: var(--bg-elevated);
1195
+ border: 1px solid var(--border-default);
1196
+ border-radius: var(--radius-lg);
1197
+ width: 100%;
1198
+ max-width: 600px;
1199
+ box-shadow: var(--shadow-lg);
1200
+ animation: modal-in 250ms cubic-bezier(0,0,0.2,1);
1201
+ }
1202
+
1203
+ .modal-sm { max-width: 400px; }
1204
+
1205
+ @keyframes modal-in {
1206
+ from { opacity: 0; transform: translateY(12px) scale(0.98); }
1207
+ to { opacity: 1; transform: translateY(0) scale(1); }
1208
+ }
1209
+
1210
+ .modal-header {
1211
+ display: flex;
1212
+ align-items: center;
1213
+ justify-content: space-between;
1214
+ padding: 16px 20px;
1215
+ border-bottom: 1px solid var(--border-default);
1216
+ }
1217
+
1218
+ .modal-header h3 {
1219
+ font-family: var(--font-display);
1220
+ font-size: 16px;
1221
+ font-weight: 600;
1222
+ color: var(--text-primary);
1223
+ }
1224
+
1225
+ .modal-close {
1226
+ width: 28px;
1227
+ height: 28px;
1228
+ display: flex;
1229
+ align-items: center;
1230
+ justify-content: center;
1231
+ border-radius: var(--radius-md);
1232
+ border: none;
1233
+ background: transparent;
1234
+ color: var(--text-muted);
1235
+ font-size: 20px;
1236
+ cursor: pointer;
1237
+ transition: all var(--transition-micro);
1238
+ }
1239
+
1240
+ .modal-close:hover {
1241
+ background: var(--bg-surface);
1242
+ color: var(--text-primary);
1243
+ }
1244
+
1245
+ .modal-body {
1246
+ padding: 20px;
1247
+ }
1248
+
1249
+ .modal-footer {
1250
+ display: flex;
1251
+ justify-content: flex-end;
1252
+ gap: 8px;
1253
+ padding-top: 16px;
1254
+ margin-top: 16px;
1255
+ border-top: 1px solid var(--border-subtle);
1256
+ }
1257
+
1258
+ /* ---------- Forms ---------- */
1259
+ .form-group {
1260
+ margin-bottom: 16px;
1261
+ }
1262
+
1263
+ .form-group label {
1264
+ display: block;
1265
+ margin-bottom: 6px;
1266
+ font-size: 12px;
1267
+ font-weight: 600;
1268
+ color: var(--text-secondary);
1269
+ text-transform: uppercase;
1270
+ letter-spacing: 0.04em;
1271
+ }
1272
+
1273
+ .form-group input[type="text"],
1274
+ .form-group input[type="number"],
1275
+ .form-group input[type="url"],
1276
+ .form-group input[type="password"],
1277
+ .form-group select,
1278
+ .form-group textarea {
1279
+ width: 100%;
1280
+ height: 38px;
1281
+ padding: 0 12px;
1282
+ background: var(--bg-base);
1283
+ border: 1px solid var(--border-default);
1284
+ border-radius: var(--radius-md);
1285
+ color: var(--text-primary);
1286
+ font-family: var(--font-body);
1287
+ font-size: 13px;
1288
+ outline: none;
1289
+ transition: all var(--transition-micro);
1290
+ }
1291
+
1292
+ .form-group input:focus,
1293
+ .form-group select:focus,
1294
+ .form-group textarea:focus {
1295
+ border-color: var(--accent);
1296
+ box-shadow: 0 0 0 3px var(--accent-subtle);
1297
+ }
1298
+
1299
+ .form-group input::placeholder {
1300
+ color: var(--text-faint);
1301
+ }
1302
+
1303
+ .form-group select {
1304
+ cursor: pointer;
1305
+ appearance: none;
1306
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2371717A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
1307
+ background-repeat: no-repeat;
1308
+ background-position: right 10px center;
1309
+ padding-right: 32px;
1310
+ }
1311
+
1312
+ .form-row {
1313
+ display: grid;
1314
+ grid-template-columns: 1fr 1fr;
1315
+ gap: 16px;
1316
+ }
1317
+
1318
+ .form-row .form-group {
1319
+ margin-bottom: 0;
1320
+ }
1321
+
1322
+ .form-divider {
1323
+ height: 1px;
1324
+ background: var(--border-default);
1325
+ margin: 20px 0;
1326
+ }
1327
+
1328
+ .form-section-title {
1329
+ font-size: 13px;
1330
+ font-weight: 600;
1331
+ color: var(--text-primary);
1332
+ margin-bottom: 12px;
1333
+ }
1334
+
1335
+ /* ---------- Tag Input ---------- */
1336
+ .tag-input {
1337
+ display: flex;
1338
+ flex-wrap: wrap;
1339
+ gap: 6px;
1340
+ padding: 6px 10px;
1341
+ background: var(--bg-base);
1342
+ border: 1px solid var(--border-default);
1343
+ border-radius: var(--radius-md);
1344
+ min-height: 38px;
1345
+ align-items: center;
1346
+ transition: all var(--transition-micro);
1347
+ }
1348
+
1349
+ .tag-input:focus-within {
1350
+ border-color: var(--accent);
1351
+ box-shadow: 0 0 0 3px var(--accent-subtle);
1352
+ }
1353
+
1354
+ .tag-list {
1355
+ display: flex;
1356
+ flex-wrap: wrap;
1357
+ gap: 6px;
1358
+ }
1359
+
1360
+ .tag {
1361
+ display: inline-flex;
1362
+ align-items: center;
1363
+ gap: 4px;
1364
+ padding: 3px 8px;
1365
+ border-radius: var(--radius-sm);
1366
+ background: var(--bg-surface);
1367
+ color: var(--text-secondary);
1368
+ font-size: 12px;
1369
+ font-family: var(--font-mono);
1370
+ }
1371
+
1372
+ .tag-remove {
1373
+ width: 14px;
1374
+ height: 14px;
1375
+ display: inline-flex;
1376
+ align-items: center;
1377
+ justify-content: center;
1378
+ border: none;
1379
+ background: transparent;
1380
+ color: var(--text-faint);
1381
+ cursor: pointer;
1382
+ font-size: 14px;
1383
+ line-height: 1;
1384
+ padding: 0;
1385
+ }
1386
+
1387
+ .tag-remove:hover {
1388
+ color: var(--error);
1389
+ }
1390
+
1391
+ .tag-input input {
1392
+ flex: 1;
1393
+ min-width: 80px;
1394
+ border: none;
1395
+ background: transparent;
1396
+ color: var(--text-primary);
1397
+ font-family: var(--font-body);
1398
+ font-size: 13px;
1399
+ outline: none;
1400
+ height: 24px;
1401
+ }
1402
+
1403
+ /* ---------- Pool Editor ---------- */
1404
+ .pool-editor {
1405
+ display: flex;
1406
+ flex-direction: column;
1407
+ gap: 8px;
1408
+ }
1409
+
1410
+ .pool-empty {
1411
+ padding: 12px;
1412
+ text-align: center;
1413
+ color: var(--text-faint);
1414
+ font-size: 13px;
1415
+ background: var(--bg-base);
1416
+ border: 1px dashed var(--border-default);
1417
+ border-radius: var(--radius-md);
1418
+ }
1419
+
1420
+ .pool-item {
1421
+ display: flex;
1422
+ align-items: center;
1423
+ gap: 8px;
1424
+ padding: 8px 12px;
1425
+ background: var(--bg-base);
1426
+ border: 1px solid var(--border-default);
1427
+ border-radius: var(--radius-md);
1428
+ }
1429
+
1430
+ .pool-item-name {
1431
+ flex: 1;
1432
+ font-size: 13px;
1433
+ color: var(--text-primary);
1434
+ }
1435
+
1436
+ .pool-item-model {
1437
+ font-size: 11px;
1438
+ color: var(--text-muted);
1439
+ font-family: var(--font-mono);
1440
+ }
1441
+
1442
+ .pool-item-select {
1443
+ flex: 1;
1444
+ height: 32px;
1445
+ padding: 0 8px;
1446
+ background: var(--bg-elevated);
1447
+ border: 1px solid var(--border-default);
1448
+ border-radius: var(--radius-sm);
1449
+ color: var(--text-primary);
1450
+ font-family: var(--font-body);
1451
+ font-size: 12px;
1452
+ cursor: pointer;
1453
+ outline: none;
1454
+ }
1455
+
1456
+ .pool-item-weight {
1457
+ width: 60px;
1458
+ }
1459
+
1460
+ .pool-item-weight input {
1461
+ width: 100%;
1462
+ height: 28px;
1463
+ padding: 0 6px;
1464
+ background: var(--bg-elevated);
1465
+ border: 1px solid var(--border-default);
1466
+ border-radius: var(--radius-sm);
1467
+ color: var(--text-primary);
1468
+ font-family: var(--font-mono);
1469
+ font-size: 12px;
1470
+ text-align: center;
1471
+ }
1472
+
1473
+ .pool-item-remove {
1474
+ width: 24px;
1475
+ height: 24px;
1476
+ display: flex;
1477
+ align-items: center;
1478
+ justify-content: center;
1479
+ border: none;
1480
+ background: transparent;
1481
+ color: var(--text-faint);
1482
+ cursor: pointer;
1483
+ font-size: 16px;
1484
+ border-radius: var(--radius-sm);
1485
+ }
1486
+
1487
+ .pool-item-remove:hover {
1488
+ background: var(--error-bg);
1489
+ color: var(--error);
1490
+ }
1491
+
1492
+ /* ---------- API Key Row ---------- */
1493
+ .key-row {
1494
+ display: flex;
1495
+ align-items: center;
1496
+ gap: 8px;
1497
+ margin-bottom: 8px;
1498
+ }
1499
+
1500
+ .key-row input {
1501
+ flex: 1;
1502
+ height: 32px;
1503
+ padding: 0 10px;
1504
+ background: var(--bg-base);
1505
+ border: 1px solid var(--border-default);
1506
+ border-radius: var(--radius-md);
1507
+ color: var(--text-primary);
1508
+ font-family: var(--font-mono);
1509
+ font-size: 12px;
1510
+ }
1511
+
1512
+ .key-row input::placeholder {
1513
+ font-family: var(--font-body);
1514
+ }
1515
+
1516
+ .key-row .btn {
1517
+ height: 32px;
1518
+ }
1519
+
1520
+ .key-row .toggle-switch {
1521
+ position: relative;
1522
+ display: inline-flex;
1523
+ align-items: center;
1524
+ width: 36px;
1525
+ height: 20px;
1526
+ flex-shrink: 0;
1527
+ cursor: pointer;
1528
+ }
1529
+
1530
+ .key-row .toggle-switch input {
1531
+ opacity: 0;
1532
+ width: 0;
1533
+ height: 0;
1534
+ }
1535
+
1536
+ .key-row .toggle-slider {
1537
+ position: absolute;
1538
+ inset: 0;
1539
+ background: rgba(51, 65, 85, 0.6);
1540
+ border-radius: 20px;
1541
+ border: 1px solid rgba(71, 85, 105, 0.5);
1542
+ transition: all 0.25s;
1543
+ }
1544
+
1545
+ .key-row .toggle-slider::before {
1546
+ content: '';
1547
+ position: absolute;
1548
+ width: 14px;
1549
+ height: 14px;
1550
+ left: 2px;
1551
+ top: 2px;
1552
+ background: #94a3b8;
1553
+ border-radius: 50%;
1554
+ transition: all 0.25s;
1555
+ }
1556
+
1557
+ .key-row .toggle-switch input:checked + .toggle-slider {
1558
+ background: rgba(59, 130, 246, 0.3);
1559
+ border-color: rgba(59, 130, 246, 0.5);
1560
+ }
1561
+
1562
+ .key-row .toggle-switch input:checked + .toggle-slider::before {
1563
+ transform: translateX(16px);
1564
+ background: #60a5fa;
1565
+ }
1566
+
1567
+ .key-row .api-key-masked {
1568
+ flex: 1;
1569
+ display: flex;
1570
+ align-items: center;
1571
+ min-width: 160px;
1572
+ height: 32px;
1573
+ padding: 0 10px;
1574
+ background: var(--bg-base);
1575
+ border: 1px solid var(--border-default);
1576
+ border-radius: var(--radius-md);
1577
+ color: var(--text-muted);
1578
+ font-family: var(--font-mono);
1579
+ font-size: 12px;
1580
+ cursor: pointer;
1581
+ user-select: none;
1582
+ letter-spacing: 0.2em;
1583
+ }
1584
+
1585
+ /* ---------- Radio ---------- */
1586
+ .radio-label {
1587
+ display: flex;
1588
+ align-items: flex-start;
1589
+ gap: 10px;
1590
+ padding: 10px 12px;
1591
+ border-radius: var(--radius-md);
1592
+ cursor: pointer;
1593
+ transition: background var(--transition-micro);
1594
+ margin-bottom: 4px;
1595
+ }
1596
+
1597
+ .radio-label:hover {
1598
+ background: var(--bg-surface-hover);
1599
+ }
1600
+
1601
+ .radio-label input {
1602
+ margin-top: 2px;
1603
+ }
1604
+
1605
+ .radio-label span {
1606
+ font-size: 13px;
1607
+ color: var(--text-secondary);
1608
+ line-height: 1.5;
1609
+ }
1610
+
1611
+ .radio-label strong {
1612
+ color: var(--text-primary);
1613
+ }
1614
+
1615
+ /* ---------- Confirm ---------- */
1616
+ .confirm-icon {
1617
+ width: 48px;
1618
+ height: 48px;
1619
+ border-radius: var(--radius-full);
1620
+ background: var(--warning-bg);
1621
+ color: var(--warning);
1622
+ display: inline-flex;
1623
+ align-items: center;
1624
+ justify-content: center;
1625
+ font-size: 24px;
1626
+ font-weight: 700;
1627
+ margin-bottom: 16px;
1628
+ }
1629
+
1630
+ .confirm-text {
1631
+ font-size: 14px;
1632
+ color: var(--text-secondary);
1633
+ line-height: 1.6;
1634
+ }
1635
+
1636
+ /* ---------- Import ---------- */
1637
+ .import-stats-row {
1638
+ display: flex;
1639
+ gap: 16px;
1640
+ margin-bottom: 20px;
1641
+ }
1642
+
1643
+ .import-stat {
1644
+ flex: 1;
1645
+ text-align: center;
1646
+ padding: 16px;
1647
+ background: var(--bg-base);
1648
+ border: 1px solid var(--border-default);
1649
+ border-radius: var(--radius-md);
1650
+ }
1651
+
1652
+ .import-stat-value {
1653
+ display: block;
1654
+ font-family: var(--font-mono);
1655
+ font-size: 24px;
1656
+ font-weight: 500;
1657
+ color: var(--text-primary);
1658
+ }
1659
+
1660
+ .import-stat-label {
1661
+ font-size: 12px;
1662
+ color: var(--text-muted);
1663
+ }
1664
+
1665
+ /* ---------- Empty State ---------- */
1666
+ .empty-state {
1667
+ grid-column: 1 / -1;
1668
+ text-align: center;
1669
+ padding: 80px 20px;
1670
+ color: var(--text-faint);
1671
+ }
1672
+
1673
+ .empty-icon {
1674
+ margin-bottom: 16px;
1675
+ color: var(--text-faint);
1676
+ }
1677
+
1678
+ .empty-state p {
1679
+ font-size: 14px;
1680
+ margin-bottom: 16px;
1681
+ }
1682
+
1683
+ .empty-sm {
1684
+ text-align: center;
1685
+ padding: 32px 20px;
1686
+ color: var(--text-faint);
1687
+ font-size: 13px;
1688
+ }
1689
+
1690
+ /* ---------- Toast ---------- */
1691
+ .toast {
1692
+ position: fixed;
1693
+ bottom: 24px;
1694
+ right: 24px;
1695
+ padding: 12px 20px;
1696
+ border-radius: var(--radius-md);
1697
+ background: var(--text-primary);
1698
+ color: var(--bg-base);
1699
+ font-size: 13px;
1700
+ font-weight: 500;
1701
+ z-index: 9999;
1702
+ box-shadow: var(--shadow-lg);
1703
+ animation: toast-in 250ms ease, toast-out 250ms ease 2.5s forwards;
1704
+ }
1705
+
1706
+ .toast.error {
1707
+ background: var(--error);
1708
+ color: #fff;
1709
+ }
1710
+
1711
+ @keyframes toast-in {
1712
+ from { opacity: 0; transform: translateY(8px); }
1713
+ to { opacity: 1; transform: translateY(0); }
1714
+ }
1715
+
1716
+ @keyframes toast-out {
1717
+ from { opacity: 1; }
1718
+ to { opacity: 0; }
1719
+ }
1720
+
1721
+ /* ---------- History List ---------- */
1722
+ .history-item {
1723
+ display: flex;
1724
+ align-items: center;
1725
+ gap: 12px;
1726
+ padding: 10px 0;
1727
+ border-bottom: 1px solid var(--border-subtle);
1728
+ }
1729
+
1730
+ .history-item:last-child {
1731
+ border-bottom: none;
1732
+ }
1733
+
1734
+ .history-meta {
1735
+ flex: 1;
1736
+ min-width: 0;
1737
+ }
1738
+
1739
+ .history-name {
1740
+ font-size: 13px;
1741
+ color: var(--text-primary);
1742
+ font-family: var(--font-mono);
1743
+ }
1744
+
1745
+ .history-reason {
1746
+ font-size: 11px;
1747
+ color: var(--text-muted);
1748
+ }
1749
+
1750
+ .history-actions {
1751
+ display: flex;
1752
+ gap: 8px;
1753
+ }
1754
+
1755
+ /* ---------- Responsive ---------- */
1756
+ @media (max-width: 1024px) {
1757
+ .dashboard-grid { grid-template-columns: repeat(2, 1fr); }
1758
+ .stats-summary-bar { grid-template-columns: repeat(2, 1fr); }
1759
+ .dashboard-row { flex-direction: column; }
1760
+ }
1761
+
1762
+ @media (max-width: 768px) {
1763
+ .sidebar { display: none; }
1764
+ .dashboard-grid { grid-template-columns: 1fr; }
1765
+ .stats-summary-bar { grid-template-columns: 1fr 1fr; }
1766
+ .proxy-grid { grid-template-columns: 1fr; }
1767
+ .provider-grid { grid-template-columns: 1fr; }
1768
+ .settings-grid { grid-template-columns: 1fr; }
1769
+ .form-row { grid-template-columns: 1fr; }
1770
+ .page-toolbar { flex-direction: column; align-items: stretch; }
1771
+ .search-box { max-width: none; }
1772
+ .topbar { padding: 0 16px; }
1773
+ .page { padding: 16px; }
1774
+ }
1775
+
1776
+ /* ---------- Scrollbar ---------- */
1777
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
1778
+ ::-webkit-scrollbar-track { background: transparent; }
1779
+ ::-webkit-scrollbar-thumb { background: var(--text-faint); border-radius: 3px; }
1780
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
1781
+
1782
+ /* ---------- Selection ---------- */
1783
+ ::selection {
1784
+ background: var(--accent-subtle);
1785
+ color: var(--accent);
1786
+ }