agent-tank 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1149 @@
1
+ :root {
2
+ /* Dark mode colors (default) - Industrial aesthetic */
3
+ --bg-primary: #0d1117;
4
+ --bg-card: #161b22;
5
+ --bg-secondary: #21262d;
6
+ --text-primary: #f0f6fc;
7
+ --text-secondary: #8b949e;
8
+ --text-tertiary: #6e7681;
9
+ --accent-primary: #161b22;
10
+ --accent-hover: #21262d;
11
+ --border-color: #30363d;
12
+ --disabled-bg: #484f58;
13
+ --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
14
+ --card-border: #30363d;
15
+ --progress-track: rgba(255, 255, 255, 0.06);
16
+ /* Industrial/tank specific */
17
+ --tank-glass: rgba(255, 255, 255, 0.08);
18
+ --tank-glow: rgba(72, 187, 120, 0.3);
19
+ --dot-grid-color: rgba(255, 255, 255, 0.03);
20
+ /* Monospace font for numbers */
21
+ --font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
22
+ }
23
+
24
+ body.light-mode {
25
+ /* Light mode colors - Industrial aesthetic */
26
+ --bg-primary: #f6f8fa;
27
+ --bg-card: #ffffff;
28
+ --bg-secondary: #f0f3f6;
29
+ --text-primary: #1f2328;
30
+ --text-secondary: #656d76;
31
+ --text-tertiary: #8b949e;
32
+ --accent-primary: #1f2328;
33
+ --accent-hover: #32383f;
34
+ --border-color: #d0d7de;
35
+ --disabled-bg: #afb8c1;
36
+ --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
37
+ --card-border: #d0d7de;
38
+ --progress-track: #e6e8eb;
39
+ /* Industrial/tank specific */
40
+ --tank-glass: rgba(0, 0, 0, 0.04);
41
+ --tank-glow: rgba(72, 187, 120, 0.2);
42
+ --dot-grid-color: rgba(0, 0, 0, 0.03);
43
+ }
44
+
45
+ * { box-sizing: border-box; }
46
+
47
+ body {
48
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
49
+ font-variant-numeric: tabular-nums;
50
+ background: var(--bg-primary);
51
+ color: var(--text-primary);
52
+ margin: 0;
53
+ padding: 0;
54
+ transition: background-color 0.3s ease, color 0.3s ease;
55
+ /* Holy Grail Flexbox layout for sticky footer */
56
+ min-height: 100vh;
57
+ display: flex;
58
+ flex-direction: column;
59
+ }
60
+
61
+ /* Top Navigation Bar */
62
+ .top-nav {
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: space-between;
66
+ padding: 16px 24px;
67
+ background: var(--bg-card);
68
+ border-bottom: 1px solid var(--border-color);
69
+ position: sticky;
70
+ top: 0;
71
+ z-index: 100;
72
+ }
73
+
74
+ .top-nav-left {
75
+ display: flex;
76
+ align-items: center;
77
+ gap: 12px;
78
+ }
79
+
80
+ /* Logo link - wraps tank icon and title */
81
+ .logo-link {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 12px;
85
+ text-decoration: none;
86
+ color: inherit;
87
+ transition: opacity 0.2s ease;
88
+ }
89
+
90
+ .logo-link:hover {
91
+ opacity: 0.8;
92
+ }
93
+
94
+ /* Tank logo styling */
95
+ .tank-logo {
96
+ width: 28px;
97
+ height: 28px;
98
+ color: var(--text-primary);
99
+ opacity: 0.9;
100
+ }
101
+
102
+ .top-nav-title {
103
+ font-size: 15px;
104
+ font-weight: 600;
105
+ color: var(--text-secondary);
106
+ margin: 0;
107
+ letter-spacing: 0.08em;
108
+ text-transform: uppercase;
109
+ }
110
+
111
+ .top-nav-title .brand-emphasis {
112
+ color: var(--text-primary);
113
+ font-weight: 700;
114
+ }
115
+
116
+ .top-nav-right {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 16px;
120
+ }
121
+
122
+ .top-nav .last-checked {
123
+ font-size: 13px;
124
+ color: var(--text-tertiary);
125
+ }
126
+
127
+ /* Unified header button base styles */
128
+ .top-nav .refresh-all-btn,
129
+ .top-nav .monitor-toggle-btn,
130
+ .top-nav .theme-toggle-btn {
131
+ height: 36px;
132
+ padding: 0 12px;
133
+ font-size: 13px;
134
+ font-weight: 500;
135
+ width: auto;
136
+ display: flex;
137
+ align-items: center;
138
+ gap: 6px;
139
+ background: transparent;
140
+ border: 1px solid var(--border-color);
141
+ color: var(--text-secondary);
142
+ border-radius: 6px;
143
+ transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.1s ease, box-shadow 0.2s ease;
144
+ }
145
+
146
+ /* Interactive click feedback - press effect */
147
+ .top-nav .refresh-all-btn:active:not(:disabled),
148
+ .top-nav .monitor-toggle-btn:active:not(:disabled),
149
+ .top-nav .theme-toggle-btn:active:not(:disabled) {
150
+ transform: scale(0.98);
151
+ background: var(--bg-secondary);
152
+ }
153
+
154
+ /* Refresh All button specific */
155
+ .top-nav .refresh-all-btn {
156
+ --accent-glow: rgba(20, 184, 166, 0.4);
157
+ }
158
+
159
+ .top-nav .refresh-all-btn:hover:not(:disabled) {
160
+ background: var(--bg-secondary);
161
+ color: var(--text-primary);
162
+ box-shadow: 0 0 12px var(--accent-glow);
163
+ border-color: #14b8a6;
164
+ }
165
+
166
+ .top-nav .refresh-all-btn .sync-icon {
167
+ width: 14px;
168
+ height: 14px;
169
+ flex-shrink: 0;
170
+ }
171
+
172
+ /* Syncing state for Refresh All */
173
+ .top-nav .refresh-all-btn.syncing {
174
+ pointer-events: none;
175
+ opacity: 0.8;
176
+ }
177
+
178
+ .top-nav .refresh-all-btn.syncing .sync-icon {
179
+ animation: spin 0.8s linear infinite;
180
+ }
181
+
182
+ body.light-mode .top-nav .refresh-all-btn {
183
+ background: transparent;
184
+ border: 1px solid var(--border-color);
185
+ color: var(--text-secondary);
186
+ }
187
+
188
+ body.light-mode .top-nav .refresh-all-btn:hover:not(:disabled) {
189
+ background: var(--bg-secondary);
190
+ box-shadow: 0 0 12px rgba(20, 184, 166, 0.3);
191
+ }
192
+
193
+ body.light-mode .top-nav .refresh-all-btn:active:not(:disabled) {
194
+ background: var(--bg-secondary);
195
+ }
196
+
197
+ /* Theme toggle button specific */
198
+ .top-nav .theme-toggle-btn {
199
+ --accent-glow: rgba(251, 191, 36, 0.4);
200
+ }
201
+
202
+ .top-nav .theme-toggle-btn:hover:not(:disabled) {
203
+ background: var(--bg-secondary);
204
+ color: var(--text-primary);
205
+ box-shadow: 0 0 12px var(--accent-glow);
206
+ border-color: #fbbf24;
207
+ }
208
+
209
+ body.light-mode .top-nav .theme-toggle-btn {
210
+ background: transparent;
211
+ border: 1px solid var(--border-color);
212
+ }
213
+
214
+ body.light-mode .top-nav .theme-toggle-btn:hover:not(:disabled) {
215
+ box-shadow: 0 0 12px rgba(251, 191, 36, 0.3);
216
+ }
217
+
218
+ body.light-mode .top-nav .theme-toggle-btn:active:not(:disabled) {
219
+ background: var(--bg-secondary);
220
+ }
221
+
222
+ .container {
223
+ max-width: 1200px;
224
+ margin: 0 auto;
225
+ padding: 24px;
226
+ /* Flex grow to fill available space and push footer to bottom */
227
+ flex-grow: 1;
228
+ display: flex;
229
+ flex-direction: column;
230
+ /* Ensure full width for grid children */
231
+ width: 100%;
232
+ }
233
+
234
+ .agents {
235
+ display: grid;
236
+ /* Default: single column on mobile */
237
+ grid-template-columns: 1fr;
238
+ gap: 20px;
239
+ /* Ensure grid fills container width for proper row layout */
240
+ width: 100%;
241
+ /* Top-align cards with generous spacing below the header */
242
+ margin-top: 48px;
243
+ /* Align to top, not center - scalable for multiple rows */
244
+ align-content: start;
245
+ }
246
+
247
+ /* Row layout for wider screens - 3 columns for 3 provider cards */
248
+ @media (min-width: 768px) {
249
+ .agents {
250
+ grid-template-columns: repeat(3, 1fr);
251
+ }
252
+ }
253
+
254
+ .agent-card {
255
+ background: var(--bg-card);
256
+ border-radius: 12px;
257
+ padding: 32px 24px 28px 24px;
258
+ border: 1px solid rgba(255, 255, 255, 0.08);
259
+ box-shadow: var(--card-shadow);
260
+ display: flex;
261
+ flex-direction: column;
262
+ transition: background-color 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
263
+ /* Dot-grid background for industrial panel look */
264
+ background-image: radial-gradient(var(--dot-grid-color) 1px, transparent 1px);
265
+ background-size: 16px 16px;
266
+ position: relative;
267
+ }
268
+
269
+ body.light-mode .agent-card {
270
+ border: 1px solid var(--card-border);
271
+ }
272
+
273
+ .agent-card:hover {
274
+ border-color: var(--text-tertiary);
275
+ }
276
+
277
+ .agent-card.error { border-color: #e53e3e; }
278
+ .agent-card.refreshing { border-color: #ecc94b; }
279
+
280
+ .agent-card h2 {
281
+ margin: 0 0 20px 0;
282
+ color: var(--text-primary);
283
+ font-size: 15px;
284
+ font-weight: 600;
285
+ }
286
+
287
+ .usage { margin-bottom: 15px; flex: 1; }
288
+
289
+ .usage-item {
290
+ display: flex;
291
+ justify-content: space-between;
292
+ align-items: center;
293
+ padding: 10px 0 4px 0;
294
+ min-height: 48px;
295
+ }
296
+
297
+ /* Trackable usage items - clickable entire row */
298
+ .usage-item.trackable {
299
+ cursor: pointer;
300
+ padding: 10px 8px 4px 8px;
301
+ margin: 0 -8px;
302
+ border-radius: 6px;
303
+ transition: background-color 0.15s ease;
304
+ }
305
+
306
+ .usage-item.trackable:hover {
307
+ background-color: var(--bg-secondary);
308
+ }
309
+
310
+ /* Active tracking state for the row - subtle highlight with vibrant LED */
311
+ .usage-item.trackable.tracking {
312
+ background-color: rgba(72, 187, 120, 0.08);
313
+ border: 1px solid rgba(72, 187, 120, 0.2);
314
+ margin: -1px -9px 0 -9px;
315
+ padding: 10px 8px 4px 8px;
316
+ }
317
+
318
+ body.light-mode .usage-item.trackable.tracking {
319
+ background-color: rgba(72, 187, 120, 0.06);
320
+ }
321
+
322
+ /* Enhanced LED glow when row is being tracked */
323
+ .usage-item.trackable.tracking .status-dot {
324
+ box-shadow: 0 0 8px currentColor, 0 0 12px currentColor;
325
+ }
326
+
327
+ .usage-item:last-child { border-bottom: none; }
328
+
329
+ .usage-item.reset-info {
330
+ padding: 0 0 0 12px;
331
+ font-size: 13px;
332
+ border-bottom: none;
333
+ min-height: auto;
334
+ }
335
+
336
+ /* Container for reset info + time progress bar */
337
+ .reset-info-wrapper {
338
+ position: relative;
339
+ margin-top: 8px;
340
+ margin-bottom: 12px;
341
+ }
342
+
343
+ .usage-item.reset-info .usage-label { font-size: 12px; text-transform: none; }
344
+ .usage-item.reset-info .usage-value { font-family: var(--font-mono); font-weight: 500; color: var(--text-secondary); }
345
+
346
+ .usage-label {
347
+ color: var(--text-tertiary);
348
+ font-size: 12px;
349
+ font-weight: 500;
350
+ letter-spacing: 0.02em;
351
+ /* Universal LED standard: all labels have status dots */
352
+ display: flex;
353
+ align-items: center;
354
+ gap: 8px;
355
+ }
356
+
357
+ /* Model name styling - dark grey (light mode) / light grey (dark mode), slightly bolder, lowercase */
358
+ .usage-label.model-name {
359
+ color: #d1d5db;
360
+ font-weight: 500;
361
+ text-transform: none;
362
+ }
363
+
364
+ body.light-mode .usage-label.model-name {
365
+ color: #374151;
366
+ }
367
+
368
+ /* Status dot indicator for model usage tier */
369
+ .status-dot {
370
+ width: 6px;
371
+ height: 6px;
372
+ border-radius: 50%;
373
+ flex-shrink: 0;
374
+ box-shadow: 0 0 6px currentColor;
375
+ }
376
+
377
+ .status-dot.status-green {
378
+ background-color: #48bb78;
379
+ color: #48bb78;
380
+ }
381
+
382
+ .status-dot.status-yellow {
383
+ background-color: #ecc94b;
384
+ color: #ecc94b;
385
+ }
386
+
387
+ .status-dot.status-red {
388
+ background-color: #e53e3e;
389
+ color: #e53e3e;
390
+ }
391
+
392
+ /* Pill background removed - plain text with status dots for uniform look */
393
+ .model-pill {
394
+ /* Background removed per design unification - just keep inline-flex for alignment */
395
+ display: inline-flex;
396
+ align-items: center;
397
+ gap: 8px;
398
+ }
399
+
400
+ .usage-value {
401
+ font-family: var(--font-mono);
402
+ font-weight: 600;
403
+ display: flex;
404
+ align-items: baseline;
405
+ gap: 2px;
406
+ font-variant-numeric: tabular-nums;
407
+ }
408
+
409
+ .usage-percent {
410
+ font-family: var(--font-mono);
411
+ font-size: 26px;
412
+ font-weight: 700;
413
+ line-height: 1.2;
414
+ font-variant-numeric: tabular-nums;
415
+ }
416
+
417
+ .usage-suffix {
418
+ font-family: var(--font-mono);
419
+ font-size: 12px;
420
+ font-weight: 500;
421
+ color: var(--text-tertiary);
422
+ }
423
+
424
+ .usage-value.high { color: #48bb78; }
425
+ .usage-value.high .usage-percent { color: #48bb78; }
426
+ .usage-value.medium { color: #ecc94b; }
427
+ .usage-value.medium .usage-percent { color: #ecc94b; }
428
+ .usage-value.low { color: #e53e3e; }
429
+ .usage-value.low .usage-percent { color: #e53e3e; }
430
+
431
+ .progress-bar {
432
+ height: 16px;
433
+ background: var(--tank-glass);
434
+ border-radius: 4px;
435
+ margin-top: 8px;
436
+ overflow: hidden;
437
+ position: relative;
438
+ /* Glass vial effect with inset shadow */
439
+ box-shadow:
440
+ inset 0 2px 4px rgba(0, 0, 0, 0.3),
441
+ inset 0 -1px 2px rgba(255, 255, 255, 0.05);
442
+ /* Measurement tick marks every 20% - dark on empty part */
443
+ background-image:
444
+ repeating-linear-gradient(
445
+ 90deg,
446
+ transparent,
447
+ transparent calc(20% - 1px),
448
+ rgba(255, 255, 255, 0.08) calc(20% - 1px),
449
+ rgba(255, 255, 255, 0.08) 20%
450
+ );
451
+ background-color: var(--tank-glass);
452
+ }
453
+
454
+ body.light-mode .progress-bar {
455
+ box-shadow:
456
+ inset 0 2px 4px rgba(0, 0, 0, 0.1),
457
+ inset 0 -1px 2px rgba(255, 255, 255, 0.5);
458
+ background-image:
459
+ repeating-linear-gradient(
460
+ 90deg,
461
+ transparent,
462
+ transparent calc(20% - 1px),
463
+ rgba(0, 0, 0, 0.1) calc(20% - 1px),
464
+ rgba(0, 0, 0, 0.1) 20%
465
+ );
466
+ }
467
+
468
+ .progress-fill {
469
+ height: 100%;
470
+ border-radius: 3px;
471
+ transition: width 0.3s ease;
472
+ position: relative;
473
+ /* Liquid effect with inner glow and gradient */
474
+ box-shadow:
475
+ inset 0 -2px 4px rgba(0, 0, 0, 0.2),
476
+ inset 0 2px 4px rgba(255, 255, 255, 0.15),
477
+ 0 0 8px var(--tank-glow);
478
+ /* Subtle gradient for liquid depth effect */
479
+ background-image:
480
+ /* Backlit tick marks - lighter/white on filled part */
481
+ repeating-linear-gradient(
482
+ 90deg,
483
+ transparent,
484
+ transparent calc(20% - 1px),
485
+ rgba(255, 255, 255, 0.25) calc(20% - 1px),
486
+ rgba(255, 255, 255, 0.25) 20%
487
+ ),
488
+ /* Original depth gradient */
489
+ linear-gradient(
490
+ 180deg,
491
+ rgba(255, 255, 255, 0.2) 0%,
492
+ transparent 40%,
493
+ rgba(0, 0, 0, 0.1) 100%
494
+ );
495
+ background-blend-mode: overlay;
496
+ }
497
+
498
+ .card-footer {
499
+ margin-top: auto;
500
+ padding-top: 15px;
501
+ border-top: 1px solid var(--border-color);
502
+ }
503
+
504
+ .card-footer .last-updated {
505
+ display: block;
506
+ font-size: 12px;
507
+ color: var(--text-tertiary);
508
+ margin-top: 10px;
509
+ text-align: center;
510
+ }
511
+
512
+ .error-msg {
513
+ display: block;
514
+ color: #e53e3e;
515
+ margin-bottom: 10px;
516
+ font-size: 13px;
517
+ }
518
+
519
+ /* Version update notice below agent cards */
520
+ .version-update-notice {
521
+ font-family: var(--font-mono);
522
+ font-size: 12px;
523
+ color: #ecc94b;
524
+ padding: 6px 10px;
525
+ background: rgba(236, 201, 75, 0.08);
526
+ border-radius: 4px;
527
+ border: 1px solid rgba(236, 201, 75, 0.2);
528
+ }
529
+
530
+ body.light-mode .version-update-notice {
531
+ color: #b7791f;
532
+ background: rgba(236, 201, 75, 0.1);
533
+ border-color: rgba(183, 121, 31, 0.2);
534
+ }
535
+
536
+ button {
537
+ width: 100%;
538
+ padding: 10px;
539
+ background: var(--accent-primary);
540
+ color: white;
541
+ border: none;
542
+ border-radius: 6px;
543
+ cursor: pointer;
544
+ font-size: 14px;
545
+ transition: background-color 0.2s ease;
546
+ }
547
+
548
+ button:hover:not(:disabled) { background: var(--accent-hover); }
549
+
550
+ button:disabled {
551
+ background: var(--disabled-bg);
552
+ cursor: not-allowed;
553
+ }
554
+
555
+ button .spinner {
556
+ display: inline-block;
557
+ width: 14px;
558
+ height: 14px;
559
+ border: 2px solid rgba(255,255,255,0.3);
560
+ border-top-color: white;
561
+ border-radius: 50%;
562
+ animation: spin 0.8s linear infinite;
563
+ margin-right: 6px;
564
+ vertical-align: middle;
565
+ }
566
+
567
+ @keyframes spin {
568
+ to { transform: rotate(360deg); }
569
+ }
570
+
571
+ /* Legacy classes removed - controls now in top-nav */
572
+
573
+ /* Agent heading with icon */
574
+ .agent-heading {
575
+ display: flex;
576
+ align-items: center;
577
+ gap: 10px;
578
+ }
579
+
580
+ /* Public API Status Badge */
581
+ .status-badge {
582
+ display: inline-flex;
583
+ align-items: center;
584
+ padding: 2px 8px;
585
+ font-size: 10px;
586
+ font-weight: 600;
587
+ text-transform: uppercase;
588
+ letter-spacing: 0.05em;
589
+ border-radius: 4px;
590
+ margin-left: 4px;
591
+ white-space: nowrap;
592
+ }
593
+
594
+ .status-badge-green {
595
+ background: rgba(72, 187, 120, 0.15);
596
+ color: #48bb78;
597
+ border: 1px solid rgba(72, 187, 120, 0.3);
598
+ }
599
+
600
+ .status-badge-yellow {
601
+ background: rgba(236, 201, 75, 0.15);
602
+ color: #ecc94b;
603
+ border: 1px solid rgba(236, 201, 75, 0.3);
604
+ }
605
+
606
+ .status-badge-red {
607
+ background: rgba(229, 62, 62, 0.15);
608
+ color: #e53e3e;
609
+ border: 1px solid rgba(229, 62, 62, 0.3);
610
+ }
611
+
612
+ .status-badge-grey {
613
+ background: rgba(113, 128, 150, 0.15);
614
+ color: #718096;
615
+ border: 1px solid rgba(113, 128, 150, 0.3);
616
+ }
617
+
618
+ /* Light mode badge adjustments */
619
+ body.light-mode .status-badge-green {
620
+ background: rgba(72, 187, 120, 0.12);
621
+ color: #38a169;
622
+ border-color: rgba(56, 161, 105, 0.3);
623
+ }
624
+
625
+ body.light-mode .status-badge-yellow {
626
+ background: rgba(236, 201, 75, 0.12);
627
+ color: #b7791f;
628
+ border-color: rgba(183, 121, 31, 0.3);
629
+ }
630
+
631
+ body.light-mode .status-badge-red {
632
+ background: rgba(229, 62, 62, 0.12);
633
+ color: #c53030;
634
+ border-color: rgba(197, 48, 48, 0.3);
635
+ }
636
+
637
+ body.light-mode .status-badge-grey {
638
+ background: rgba(113, 128, 150, 0.12);
639
+ color: #4a5568;
640
+ border-color: rgba(74, 85, 104, 0.3);
641
+ }
642
+
643
+ /* Agent icon styling */
644
+ .agent-icon {
645
+ width: 24px;
646
+ height: 24px;
647
+ flex-shrink: 0;
648
+ }
649
+
650
+ /* Agent icons - neutral low-opacity white/grey for industrial look
651
+ Status dots (LEDs) are now the primary color indicators */
652
+ .agent-claude,
653
+ .agent-gemini,
654
+ .agent-codex {
655
+ --agent-bg-subtle: rgba(255, 255, 255, 0.04);
656
+ }
657
+
658
+ .agent-claude .agent-icon,
659
+ .agent-gemini .agent-icon,
660
+ .agent-codex .agent-icon {
661
+ color: var(--text-tertiary);
662
+ opacity: 0.7;
663
+ }
664
+
665
+ body.light-mode .agent-claude .agent-icon,
666
+ body.light-mode .agent-gemini .agent-icon,
667
+ body.light-mode .agent-codex .agent-icon {
668
+ color: var(--text-secondary);
669
+ opacity: 0.6;
670
+ }
671
+
672
+ /* Agent cards have simple borders - brand colors only on icons */
673
+ .agent-claude,
674
+ .agent-gemini,
675
+ .agent-codex {
676
+ background: var(--bg-card);
677
+ }
678
+
679
+ /* Light mode adjustments for subtle backgrounds */
680
+ body.light-mode .agent-claude,
681
+ body.light-mode .agent-gemini,
682
+ body.light-mode .agent-codex {
683
+ --agent-bg-subtle: rgba(0, 0, 0, 0.02);
684
+ }
685
+
686
+ /* Agent headings use neutral color, only icons have brand colors */
687
+ .agent-claude h2,
688
+ .agent-gemini h2,
689
+ .agent-codex h2 {
690
+ color: var(--text-primary);
691
+ }
692
+
693
+ /* Time elapsed progress bar - subtle, thin bar positioned below reset info */
694
+ .time-progress-bar {
695
+ position: relative;
696
+ margin-top: 4px;
697
+ margin-left: 12px;
698
+ height: 3px;
699
+ background: rgba(113, 128, 150, 0.2);
700
+ border-radius: 2px;
701
+ overflow: hidden;
702
+ }
703
+
704
+ .time-progress-fill {
705
+ height: 100%;
706
+ background: rgba(113, 128, 150, 0.5);
707
+ border-radius: 2px;
708
+ transition: width 0.3s;
709
+ }
710
+
711
+ /* Light mode adjustments for time progress bar */
712
+ body.light-mode .time-progress-bar {
713
+ background: rgba(113, 128, 150, 0.15);
714
+ }
715
+
716
+ body.light-mode .time-progress-fill {
717
+ background: rgba(113, 128, 150, 0.4);
718
+ }
719
+
720
+ /* Refresh icon button - inline in card header */
721
+ .refresh-icon-btn {
722
+ background: none;
723
+ border: none;
724
+ padding: 4px;
725
+ margin-left: auto;
726
+ cursor: pointer;
727
+ color: var(--text-secondary);
728
+ width: 28px;
729
+ height: 28px;
730
+ display: flex;
731
+ align-items: center;
732
+ justify-content: center;
733
+ border-radius: 4px;
734
+ transition: color 0.2s ease, background-color 0.2s ease;
735
+ }
736
+
737
+ .refresh-icon-btn:hover:not(:disabled) {
738
+ color: var(--text-primary);
739
+ background: var(--bg-secondary);
740
+ }
741
+
742
+ .refresh-icon-btn:hover:not(:disabled) svg {
743
+ stroke-width: 2.5;
744
+ }
745
+
746
+ .refresh-icon-btn:disabled {
747
+ cursor: not-allowed;
748
+ opacity: 0.5;
749
+ }
750
+
751
+ .refresh-icon-btn svg {
752
+ width: 18px;
753
+ height: 18px;
754
+ }
755
+
756
+ .refresh-icon-btn.spinning svg {
757
+ animation: spin 0.8s linear infinite;
758
+ }
759
+
760
+ /* Global last-updated timestamp - now in nav bar, legacy class */
761
+ .last-updated-global {
762
+ display: none;
763
+ }
764
+
765
+ /* Model container wrapper - consistent vertical spacing */
766
+ .model-container {
767
+ margin-bottom: 24px;
768
+ /* Ensure minimum padding even when "Resets in" is hidden */
769
+ padding-bottom: 8px;
770
+ }
771
+
772
+ .model-container:last-child {
773
+ margin-bottom: 0;
774
+ padding-bottom: 0;
775
+ }
776
+
777
+ /* Zero usage - de-emphasized styling using color shift (not opacity for accessibility) */
778
+ /* Only apply grey color to the percentage text, not the model name */
779
+ .zero-usage .usage-value,
780
+ .zero-usage .usage-percent,
781
+ .zero-usage .usage-suffix {
782
+ color: #9ca3af !important;
783
+ }
784
+
785
+ /* Progress bar for zero usage: show track but no fill, but keep track visible */
786
+ .progress-bar.zero-usage {
787
+ background-color: var(--tank-glass);
788
+ background-image:
789
+ repeating-linear-gradient(
790
+ 90deg,
791
+ transparent,
792
+ transparent calc(20% - 1px),
793
+ rgba(255, 255, 255, 0.05) calc(20% - 1px),
794
+ rgba(255, 255, 255, 0.05) 20%
795
+ );
796
+ }
797
+
798
+ .progress-bar.zero-usage .progress-fill {
799
+ width: 0 !important;
800
+ background: transparent !important;
801
+ box-shadow: none !important;
802
+ }
803
+
804
+ /* Light mode: zero usage progress bars */
805
+ body.light-mode .progress-bar.zero-usage {
806
+ background-color: var(--tank-glass);
807
+ background-image:
808
+ repeating-linear-gradient(
809
+ 90deg,
810
+ transparent,
811
+ transparent calc(20% - 1px),
812
+ rgba(0, 0, 0, 0.04) calc(20% - 1px),
813
+ rgba(0, 0, 0, 0.04) 20%
814
+ );
815
+ }
816
+
817
+ /* Reset info for zero usage: grey text */
818
+ .reset-info-wrapper.zero-usage .usage-value,
819
+ .reset-info-wrapper.zero-usage .usage-label {
820
+ color: #9ca3af;
821
+ }
822
+
823
+ /* Time progress bar in zero state */
824
+ .time-progress-bar.zero-usage .time-progress-fill {
825
+ background: rgba(156, 163, 175, 0.4);
826
+ }
827
+
828
+ /* Interactive hover for zero-usage items - subtle highlight */
829
+ .usage-item.zero-usage:hover {
830
+ background-color: rgba(0, 0, 0, 0.02);
831
+ border-radius: 4px;
832
+ }
833
+
834
+ body.light-mode .usage-item.zero-usage:hover {
835
+ background-color: rgba(0, 0, 0, 0.03);
836
+ }
837
+
838
+ /* Model subheading - Codex visual grouping (keeps ALL CAPS as category dividers) */
839
+ .model-subheading {
840
+ margin-top: 2em;
841
+ padding-top: 1.25em;
842
+ border-top: 1px solid var(--border-color);
843
+ min-height: auto;
844
+ }
845
+
846
+ /* Add extra spacing between model groups for distinct "module" feel */
847
+ .model-subheading:not(:first-child) {
848
+ margin-top: calc(2em + 4px);
849
+ }
850
+
851
+ .model-subheading .usage-label {
852
+ font-weight: 600;
853
+ font-size: 11px;
854
+ text-transform: uppercase;
855
+ letter-spacing: 0.05em;
856
+ color: var(--text-secondary);
857
+ }
858
+
859
+ .model-subheading:first-child {
860
+ margin-top: 0;
861
+ padding-top: 0;
862
+ border-top: none;
863
+ }
864
+
865
+ /* Model container within Codex subheading - consistent spacing */
866
+ .model-subheading + .model-container {
867
+ margin-top: 12px;
868
+ }
869
+
870
+ /* Nested metrics under Codex model subheadings - indented 12px for visual grouping */
871
+ .nested-container {
872
+ padding-left: 12px;
873
+ }
874
+
875
+ .usage-item.nested-metric {
876
+ /* Adjust padding for nested items */
877
+ }
878
+
879
+ .progress-bar.nested-metric {
880
+ /* Keep progress bars aligned with their nested labels */
881
+ }
882
+
883
+ /* Footer - SaaS-style split layout, improved contrast */
884
+ .footer {
885
+ /* Push footer to bottom using auto margin */
886
+ margin-top: auto;
887
+ padding: 16px 24px;
888
+ font-size: 0.75rem;
889
+ color: #9ca3af;
890
+ opacity: 0.75;
891
+ display: flex;
892
+ justify-content: space-between;
893
+ align-items: center;
894
+ border-top: 1px solid var(--border-color);
895
+ transition: opacity 0.2s ease;
896
+ }
897
+
898
+ /* Reveal footer on hover */
899
+ .footer:hover {
900
+ opacity: 0.95;
901
+ }
902
+
903
+ body.light-mode .footer {
904
+ color: #6b7280;
905
+ opacity: 0.8;
906
+ }
907
+
908
+ body.light-mode .footer:hover {
909
+ opacity: 1;
910
+ }
911
+
912
+ .footer-left,
913
+ .footer-right {
914
+ display: flex;
915
+ align-items: center;
916
+ gap: 0.5em;
917
+ }
918
+
919
+ .footer-right {
920
+ gap: 1em;
921
+ }
922
+
923
+ .footer-separator {
924
+ color: inherit;
925
+ opacity: 0.5;
926
+ }
927
+
928
+ .footer a {
929
+ color: inherit;
930
+ text-decoration: none;
931
+ transition: color 0.2s ease;
932
+ }
933
+
934
+ .footer a:hover {
935
+ color: var(--text-primary);
936
+ }
937
+
938
+ .footer-version {
939
+ font-variant-numeric: tabular-nums;
940
+ }
941
+
942
+ /* API Endpoint link - developer-first monospace styling */
943
+ .api-link {
944
+ font-family: var(--font-mono);
945
+ font-size: 0.7rem;
946
+ padding: 2px 6px;
947
+ background: rgba(255, 255, 255, 0.03);
948
+ border-radius: 4px;
949
+ color: inherit;
950
+ text-decoration: none;
951
+ transition: all 0.2s;
952
+ cursor: pointer;
953
+ }
954
+
955
+ .api-link:hover {
956
+ background: rgba(255, 255, 255, 0.08);
957
+ color: #48bb78;
958
+ }
959
+
960
+ /* Copied state - green feedback */
961
+ .api-link.copied {
962
+ background: rgba(72, 187, 120, 0.15);
963
+ color: #48bb78;
964
+ }
965
+
966
+ /* Light mode adjustments for API link */
967
+ body.light-mode .api-link {
968
+ background: rgba(0, 0, 0, 0.03);
969
+ }
970
+
971
+ body.light-mode .api-link:hover {
972
+ background: rgba(0, 0, 0, 0.08);
973
+ color: #38a169;
974
+ }
975
+
976
+ body.light-mode .api-link.copied {
977
+ background: rgba(72, 187, 120, 0.12);
978
+ color: #38a169;
979
+ }
980
+
981
+ /* Copy API button - small icon button next to API link */
982
+ .copy-api-btn {
983
+ background: none;
984
+ border: none;
985
+ padding: 2px;
986
+ margin: 0;
987
+ cursor: pointer;
988
+ width: 18px;
989
+ height: 18px;
990
+ display: inline-flex;
991
+ align-items: center;
992
+ justify-content: center;
993
+ color: inherit;
994
+ opacity: 0.6;
995
+ transition: opacity 0.2s ease, color 0.2s ease;
996
+ vertical-align: middle;
997
+ }
998
+
999
+ .copy-api-btn:hover {
1000
+ opacity: 1;
1001
+ color: var(--text-primary);
1002
+ }
1003
+
1004
+ .copy-api-btn .copy-icon {
1005
+ width: 12px;
1006
+ height: 12px;
1007
+ }
1008
+
1009
+ /* Copied state - green checkmark effect */
1010
+ .copy-api-btn.copied {
1011
+ color: #48bb78;
1012
+ opacity: 1;
1013
+ }
1014
+
1015
+ body.light-mode .copy-api-btn.copied {
1016
+ color: #38a169;
1017
+ }
1018
+
1019
+ /* ===== Background Monitor Feature ===== */
1020
+
1021
+ /* Track button - inline target icon for pinning metrics */
1022
+ .track-btn {
1023
+ background: none;
1024
+ border: none;
1025
+ padding: 4px;
1026
+ margin-left: 8px;
1027
+ cursor: pointer;
1028
+ width: 24px;
1029
+ height: 24px;
1030
+ display: flex;
1031
+ align-items: center;
1032
+ justify-content: center;
1033
+ border-radius: 4px;
1034
+ opacity: 0;
1035
+ transition: opacity 0.2s ease, color 0.2s ease, background-color 0.2s ease;
1036
+ color: var(--text-tertiary);
1037
+ flex-shrink: 0;
1038
+ }
1039
+
1040
+ /* Show on hover of parent usage-item */
1041
+ .usage-item:hover .track-btn {
1042
+ opacity: 1;
1043
+ }
1044
+
1045
+ .track-btn:hover:not(:disabled) {
1046
+ color: var(--text-primary);
1047
+ background: var(--bg-secondary);
1048
+ }
1049
+
1050
+ /* Active/tracking state - always visible with accent color and glow */
1051
+ .track-btn.tracking {
1052
+ opacity: 1;
1053
+ color: #48bb78;
1054
+ animation: tracking-pulse 2s ease-in-out infinite;
1055
+ }
1056
+
1057
+ /* Subtle pulsing glow for tracking indicator */
1058
+ @keyframes tracking-pulse {
1059
+ 0%, 100% {
1060
+ filter: drop-shadow(0 0 2px rgba(72, 187, 120, 0.4));
1061
+ }
1062
+ 50% {
1063
+ filter: drop-shadow(0 0 6px rgba(72, 187, 120, 0.8));
1064
+ }
1065
+ }
1066
+
1067
+ .track-btn.tracking:hover {
1068
+ color: #38a169;
1069
+ background: rgba(72, 187, 120, 0.1);
1070
+ animation: none;
1071
+ filter: drop-shadow(0 0 6px rgba(72, 187, 120, 0.6));
1072
+ }
1073
+
1074
+ .track-btn svg {
1075
+ width: 16px;
1076
+ height: 16px;
1077
+ }
1078
+
1079
+ /* Monitor toggle button removed - monitoring is always on */
1080
+
1081
+ /* Hide default favicon when using canvas-generated one */
1082
+ .favicon-canvas {
1083
+ display: none;
1084
+ }
1085
+
1086
+ /* ===== Pace Warning Feature ===== */
1087
+
1088
+ /* Pace warning indicator - shows when usage is out-pacing time */
1089
+ .pace-warning {
1090
+ display: inline-flex;
1091
+ align-items: center;
1092
+ gap: 4px;
1093
+ margin-left: 8px;
1094
+ padding: 2px 6px;
1095
+ background: rgba(236, 201, 75, 0.12);
1096
+ border: 1px solid rgba(236, 201, 75, 0.25);
1097
+ border-radius: 4px;
1098
+ font-size: 11px;
1099
+ font-weight: 500;
1100
+ color: #ecc94b;
1101
+ cursor: help;
1102
+ }
1103
+
1104
+ .pace-warning .pace-icon {
1105
+ font-size: 10px;
1106
+ }
1107
+
1108
+ .pace-warning .pace-text {
1109
+ font-family: var(--font-mono);
1110
+ font-size: 10px;
1111
+ font-weight: 600;
1112
+ }
1113
+
1114
+ /* Light mode adjustments for pace warning */
1115
+ body.light-mode .pace-warning {
1116
+ background: rgba(236, 201, 75, 0.15);
1117
+ border-color: rgba(183, 121, 31, 0.25);
1118
+ color: #b7791f;
1119
+ }
1120
+
1121
+ /* Critical pace (2x or higher) - red warning */
1122
+ .pace-warning.pace-critical {
1123
+ background: rgba(229, 62, 62, 0.12);
1124
+ border-color: rgba(229, 62, 62, 0.25);
1125
+ color: #e53e3e;
1126
+ }
1127
+
1128
+ body.light-mode .pace-warning.pace-critical {
1129
+ background: rgba(229, 62, 62, 0.1);
1130
+ border-color: rgba(197, 48, 48, 0.25);
1131
+ color: #c53030;
1132
+ }
1133
+
1134
+ /* Pace ETA indicator - shows "runs out in X" */
1135
+ .pace-warning .pace-eta {
1136
+ font-family: var(--font-mono);
1137
+ font-size: 10px;
1138
+ font-weight: 500;
1139
+ margin-left: 4px;
1140
+ padding-left: 4px;
1141
+ border-left: 1px solid currentColor;
1142
+ opacity: 0.85;
1143
+ }
1144
+
1145
+ /* ETA emphasis for critical pace (2x+) */
1146
+ .pace-warning.pace-critical .pace-eta {
1147
+ font-weight: 600;
1148
+ opacity: 1;
1149
+ }