codexmate 0.0.31 → 0.0.33

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.
Files changed (37) hide show
  1. package/README.md +92 -308
  2. package/README.zh.md +94 -318
  3. package/cli/local-bridge.js +227 -0
  4. package/cli/update.js +162 -0
  5. package/cli.js +357 -112
  6. package/lib/cli-sessions.js +16 -6
  7. package/lib/win-tray.js +119 -0
  8. package/package.json +2 -2
  9. package/web-ui/app.js +4 -0
  10. package/web-ui/logic.sessions.mjs +17 -1
  11. package/web-ui/modules/app.computed.session.mjs +51 -315
  12. package/web-ui/modules/app.methods.agents.mjs +19 -0
  13. package/web-ui/modules/app.methods.claude-config.mjs +71 -2
  14. package/web-ui/modules/app.methods.codex-config.mjs +20 -0
  15. package/web-ui/modules/app.methods.providers.mjs +53 -7
  16. package/web-ui/modules/app.methods.session-actions.mjs +1 -1
  17. package/web-ui/modules/app.methods.session-browser.mjs +29 -1
  18. package/web-ui/modules/app.methods.startup-claude.mjs +4 -0
  19. package/web-ui/modules/i18n.dict.mjs +21 -3
  20. package/web-ui/partials/index/layout-header.html +1 -2
  21. package/web-ui/partials/index/modal-config-template-agents.html +12 -1
  22. package/web-ui/partials/index/modals-basic.html +14 -3
  23. package/web-ui/partials/index/panel-config-claude.html +57 -85
  24. package/web-ui/partials/index/panel-config-codex.html +60 -226
  25. package/web-ui/partials/index/panel-dashboard.html +0 -33
  26. package/web-ui/partials/index/panel-docs.html +21 -53
  27. package/web-ui/partials/index/panel-sessions.html +37 -20
  28. package/web-ui/partials/index/panel-trash.html +33 -38
  29. package/web-ui/partials/index/panel-usage.html +71 -304
  30. package/web-ui/styles/controls-forms.css +11 -0
  31. package/web-ui/styles/docs-panel.css +57 -83
  32. package/web-ui/styles/layout-shell.css +26 -24
  33. package/web-ui/styles/modals-core.css +33 -0
  34. package/web-ui/styles/responsive.css +5 -67
  35. package/web-ui/styles/sessions-list.css +274 -8
  36. package/web-ui/styles/sessions-toolbar-trash.css +185 -15
  37. package/web-ui/styles/sessions-usage.css +336 -788
@@ -1,949 +1,461 @@
1
- .sessions-subtabs {
2
- display: flex;
3
- gap: 10px;
4
- align-items: center;
5
- margin: 0 0 16px;
6
- }
7
-
8
- .sessions-subtab {
9
- border: 1px solid var(--color-border);
10
- background: var(--color-surface-alt);
11
- color: var(--color-text-secondary);
12
- padding: 8px 14px;
13
- border-radius: 999px;
14
- cursor: pointer;
15
- font-size: 13px;
16
- font-weight: 600;
17
- transition:
18
- background var(--transition-fast) var(--ease-smooth),
19
- color var(--transition-fast) var(--ease-smooth),
20
- border-color var(--transition-fast) var(--ease-smooth),
21
- box-shadow var(--transition-fast) var(--ease-smooth),
22
- transform var(--transition-fast) var(--ease-smooth);
23
- }
24
-
25
- .sessions-subtab:hover {
26
- background: var(--color-surface);
27
- border-color: var(--color-border-strong);
28
- color: var(--color-text-primary);
29
- }
30
-
31
- .sessions-subtab.active {
32
- background: var(--color-brand-light);
33
- color: var(--color-brand-dark);
34
- border-color: var(--color-brand);
35
- box-shadow: var(--shadow-subtle);
36
- }
1
+ /* ============================================
2
+ Usage Tab — Refined Design System
3
+ ============================================ */
37
4
 
5
+ /* ---- Toolbar ---- */
38
6
  .usage-toolbar {
39
7
  display: flex;
40
8
  justify-content: space-between;
41
9
  align-items: center;
42
10
  gap: 12px;
43
11
  flex-wrap: wrap;
44
- margin-bottom: 16px;
45
- }
46
-
47
- .usage-current-session-bar {
48
- display: flex;
49
- flex-wrap: wrap;
50
- align-items: center;
51
- gap: 12px;
52
- padding: 10px 12px;
53
- margin: 0 0 14px;
54
- border-radius: 12px;
55
- border: 1px solid var(--color-border-soft);
56
- background: var(--color-surface-alt);
57
- font-size: 12px;
58
- color: var(--color-text-secondary);
59
- }
60
-
61
- .usage-current-session-label {
62
- font-weight: 700;
63
- color: var(--color-text-primary);
12
+ margin-bottom: 18px;
64
13
  }
65
14
 
66
- .usage-current-session-item strong {
67
- font-weight: 700;
15
+ .usage-toolbar-title {
16
+ font-size: var(--font-size-title);
17
+ font-weight: var(--font-weight-title);
68
18
  color: var(--color-text-primary);
19
+ letter-spacing: -0.01em;
69
20
  }
70
21
 
71
22
  .usage-range-group {
72
23
  display: flex;
73
- gap: 8px;
74
- flex-wrap: wrap;
24
+ gap: 4px;
25
+ padding: 3px;
26
+ border-radius: var(--radius-md);
27
+ background: var(--color-surface-alt);
28
+ border: 1px solid var(--color-border-soft);
75
29
  }
76
30
 
77
31
  .usage-range-btn {
78
- border: 1px solid var(--color-border);
79
- background: var(--color-surface-alt);
80
- color: var(--color-text-secondary);
81
- padding: 6px 12px;
82
- border-radius: 999px;
32
+ border: none;
33
+ background: transparent;
34
+ color: var(--color-text-tertiary);
35
+ padding: 5px 11px;
36
+ border-radius: var(--radius-sm);
83
37
  cursor: pointer;
84
38
  font-size: 12px;
85
39
  font-weight: 600;
86
- transition:
87
- background var(--transition-fast) var(--ease-smooth),
88
- color var(--transition-fast) var(--ease-smooth),
89
- border-color var(--transition-fast) var(--ease-smooth),
90
- box-shadow var(--transition-fast) var(--ease-smooth);
91
- }
92
-
93
- .usage-range-btn:hover {
94
- background: var(--color-surface);
95
- border-color: var(--color-border-strong);
96
- color: var(--color-text-primary);
97
- }
98
-
99
- .usage-range-btn.active {
100
- background: var(--color-brand-light);
101
- color: var(--color-brand-dark);
102
- border-color: var(--color-brand);
103
- box-shadow: var(--shadow-subtle);
104
- }
105
-
106
- .usage-summary-grid {
107
- display: grid;
108
- grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
109
- gap: 12px;
110
- margin-bottom: 16px;
111
- }
112
-
113
- .usage-summary-card {
114
- display: flex;
115
- flex-direction: column;
116
- justify-content: flex-start;
117
- gap: 4px;
118
- min-height: 88px;
119
- padding: 12px 14px;
120
- border-radius: 12px;
121
- background: var(--color-surface);
122
- border: 1px solid var(--color-border);
123
- box-shadow: none;
124
- }
125
-
126
- .usage-content {
127
- position: relative;
128
- }
129
-
130
- .usage-content-loading {
131
- opacity: 0.82;
132
- }
133
-
134
- .usage-content-overlay {
135
- position: absolute;
136
- inset: 0;
137
- display: flex;
138
- align-items: flex-start;
139
- justify-content: flex-end;
140
- padding: 12px 10px;
141
- pointer-events: none;
142
- font-size: 12px;
143
- color: var(--color-text-secondary);
144
- }
145
-
146
- .usage-spinner {
147
- width: 14px;
148
- height: 14px;
149
- border-radius: 999px;
150
- border: 2px solid rgba(80, 90, 100, 0.22);
151
- border-top-color: rgba(80, 90, 100, 0.7);
152
- margin-right: 8px;
153
- animation: usage-spin 0.9s linear infinite;
154
- }
155
-
156
- @keyframes usage-spin {
157
- to {
158
- transform: rotate(360deg);
159
- }
160
- }
161
-
162
- .usage-copyable {
163
- cursor: pointer;
164
- user-select: none;
40
+ font-family: var(--font-family);
41
+ white-space: nowrap;
42
+ transition: all 120ms var(--ease-spring);
43
+ outline: none;
165
44
  -webkit-tap-highlight-color: transparent;
166
45
  }
167
46
 
168
- .usage-copyable:focus-visible {
169
- outline: 2px solid var(--color-brand);
170
- outline-offset: 2px;
171
- border-radius: 10px;
172
- }
173
-
174
- .usage-summary-card.usage-copyable:hover {
175
- border-color: var(--color-border-strong);
176
- background: var(--color-surface-alt);
177
- }
178
-
179
- .usage-loading-skeleton {
180
- display: flex;
181
- flex-direction: column;
182
- gap: 16px;
183
- }
184
-
185
- /* When showing the "正在加载" notice above the skeleton, keep comfortable spacing. */
186
- .session-empty + .usage-loading-skeleton {
187
- margin-top: 14px;
188
- }
189
-
190
- .usage-skeleton-card {
191
- position: relative;
192
- overflow: hidden;
193
- }
194
-
195
- .usage-skeleton-block {
196
- position: relative;
197
- min-height: 220px;
198
- overflow: hidden;
199
- }
200
-
201
- .usage-skeleton-line {
202
- height: 10px;
203
- border-radius: 999px;
204
- background: linear-gradient(90deg, rgba(150, 160, 170, 0.12), rgba(150, 160, 170, 0.22), rgba(150, 160, 170, 0.12));
205
- background-size: 200% 100%;
206
- animation: usage-skeleton 1.2s ease-in-out infinite;
207
- }
208
-
209
- .usage-skeleton-line.h-lg {
210
- height: 20px;
211
- margin-top: 6px;
212
- }
213
-
214
- .usage-skeleton-line.w-40 { width: 40%; }
215
- .usage-skeleton-line.w-55 { width: 55%; }
216
- .usage-skeleton-line.w-70 { width: 70%; }
217
-
218
- .usage-skeleton-card .usage-skeleton-line + .usage-skeleton-line {
219
- margin-top: 10px;
220
- }
221
-
222
- .usage-skeleton-block::before,
223
- .usage-skeleton-card::before {
224
- content: '';
225
- position: absolute;
226
- inset: 0;
227
- background: radial-gradient(circle at 25% 10%, rgba(255, 255, 255, 0.22), transparent 55%);
228
- pointer-events: none;
229
- }
230
-
231
- @keyframes usage-skeleton {
232
- 0% { background-position: 0% 0; }
233
- 100% { background-position: 200% 0; }
234
- }
235
-
236
- .usage-summary-label {
237
- min-height: 0;
238
- font-size: 12px;
239
- line-height: 1.4;
240
- color: var(--color-text-secondary);
241
- margin-bottom: 0;
242
- }
243
-
244
- .usage-summary-value {
245
- min-height: 0;
246
- display: flex;
247
- align-items: center;
248
- font-size: clamp(18px, 1.8vw, 22px);
249
- line-height: 1.15;
250
- font-weight: 700;
251
- color: var(--color-text-primary);
252
- word-break: break-word;
253
- }
254
-
255
- .usage-summary-note {
256
- margin-top: 2px;
257
- min-height: 0;
258
- font-size: 12px;
47
+ .usage-range-btn:hover:not(:disabled) {
259
48
  color: var(--color-text-secondary);
260
- line-height: 1.35;
261
- }
262
-
263
- .usage-chart-grid {
264
- display: grid;
265
- grid-template-columns: 1fr;
266
- gap: 16px;
267
- }
268
-
269
- .usage-card {
270
- padding: 16px;
271
- border-radius: 12px;
272
49
  background: var(--color-surface);
273
- border: 1px solid var(--color-border);
274
- box-shadow: none;
275
- min-width: 0;
276
- overflow: hidden;
277
50
  }
278
51
 
279
- .usage-card-head {
280
- display: flex;
281
- align-items: flex-start;
282
- justify-content: space-between;
283
- gap: 12px;
284
- margin-bottom: 12px;
52
+ .usage-range-btn:active:not(:disabled) {
53
+ transform: scale(0.97);
285
54
  }
286
55
 
287
- .usage-card-title {
288
- font-size: 14px;
289
- font-weight: 700;
290
- color: var(--color-text-primary);
291
- margin-bottom: 4px;
56
+ .usage-range-btn.active {
57
+ color: #fff;
58
+ background: var(--color-brand);
59
+ box-shadow: 0 1px 3px rgba(200, 121, 99, 0.35);
292
60
  }
293
61
 
294
- .usage-card-subtitle {
295
- font-size: 12px;
296
- line-height: 1.5;
297
- color: var(--color-text-secondary);
62
+ .usage-range-btn:disabled {
63
+ opacity: 0.4;
64
+ cursor: not-allowed;
298
65
  }
299
66
 
300
- .usage-card-kicker {
67
+ .usage-range-btn-icon {
68
+ padding: 5px 8px;
301
69
  display: inline-flex;
302
70
  align-items: center;
303
- min-height: 30px;
304
- padding: 0 10px;
305
- border-radius: 999px;
306
- border: 1px solid var(--color-border);
307
- background: transparent;
308
- color: var(--color-text-secondary);
309
- font-size: 12px;
310
- font-weight: 600;
311
- white-space: nowrap;
312
- }
313
-
314
- .usage-bars {
315
- display: flex;
316
- align-items: flex-end;
317
- gap: 8px;
318
- min-height: 180px;
319
- width: 100%;
320
- min-width: 0;
321
- overflow-x: auto;
322
- overflow-y: hidden;
323
- padding: 0 2px 10px;
324
- scrollbar-gutter: stable both-edges;
325
- scrollbar-width: thin;
326
- scrollbar-color: rgba(24, 24, 27, 0.26) rgba(24, 24, 27, 0.08);
327
- }
328
-
329
- .usage-bars::-webkit-scrollbar {
330
- height: 10px;
331
- }
332
-
333
- .usage-bars::-webkit-scrollbar-track {
334
- background: rgba(24, 24, 27, 0.06);
335
- border-radius: 999px;
336
- }
337
-
338
- .usage-bars::-webkit-scrollbar-thumb {
339
- background: rgba(24, 24, 27, 0.26);
340
- border-radius: 999px;
341
- border: 2px solid rgba(255, 255, 255, 0.92);
342
- }
343
-
344
- .usage-bars::-webkit-scrollbar-thumb:hover {
345
- background: rgba(24, 24, 27, 0.34);
71
+ justify-content: center;
346
72
  }
347
73
 
348
- .usage-bar-group {
349
- flex: 1 0 44px;
350
- min-width: 44px;
351
- display: flex;
352
- flex-direction: column;
353
- align-items: center;
354
- gap: 8px;
74
+ .usage-range-btn-icon svg {
75
+ width: 14px;
76
+ height: 14px;
355
77
  }
356
78
 
357
- .usage-bar-stack {
358
- width: 100%;
359
- max-width: 36px;
360
- height: 160px;
79
+ /* ---- Current session bar ---- */
80
+ .usage-current-session-bar {
361
81
  display: flex;
362
- align-items: flex-end;
363
- gap: 4px;
364
- }
365
-
366
- .usage-bar {
367
- flex: 1;
368
- border-radius: 10px 10px 4px 4px;
369
- min-height: 4px;
370
- }
371
-
372
- .usage-bar.codex {
373
- background: var(--color-brand);
374
- }
375
-
376
- /* =========================
377
- Daily usage (token + cost)
378
- ========================= */
379
-
380
- .usage-card-wide {
381
- grid-column: 1 / -1;
382
- }
383
-
384
- .usage-daydetail-controls {
385
- display: inline-flex;
82
+ flex-wrap: wrap;
386
83
  align-items: center;
387
- gap: 8px;
388
- }
389
-
390
- .usage-daydetail-select {
391
- min-height: 30px;
392
- padding: 0 30px 0 10px;
393
- border-radius: 999px;
394
- border: 1px solid var(--color-border);
395
- background-color: transparent;
396
- color: var(--color-text-secondary);
397
- font-size: 12px;
398
- font-weight: 600;
399
- cursor: pointer;
400
- appearance: none;
401
- -webkit-appearance: none;
402
- -moz-appearance: none;
403
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%23505A66' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M2 4l4 4 4-4'/%3E%3C/svg%3E");
404
- background-repeat: no-repeat;
405
- background-position: right 10px center;
406
- background-size: 12px;
407
- }
408
-
409
- .usage-daydetail-select:hover {
410
- background-color: var(--color-surface-alt);
411
- }
412
-
413
- .usage-daydetail-select:focus {
414
- outline: none;
415
- box-shadow: var(--shadow-input-focus);
416
- border-color: var(--color-brand);
417
- background-color: var(--color-surface-alt);
418
- }
419
-
420
- .usage-daydetail-empty {
421
- padding: 10px 0 2px;
84
+ gap: 10px;
85
+ padding: 8px 14px;
86
+ margin-bottom: 16px;
87
+ border-radius: var(--radius-md);
88
+ background: var(--color-surface-alt);
422
89
  font-size: 12px;
423
90
  color: var(--color-text-secondary);
424
91
  }
425
92
 
426
- .usage-daydetail-grid {
427
- display: grid;
428
- grid-template-columns: repeat(2, minmax(0, 1fr));
429
- gap: 10px;
430
- margin-top: 10px;
431
- }
432
-
433
- .usage-daydetail-metric {
434
- border: 1px solid var(--color-border);
435
- border-radius: 14px;
436
- padding: 10px 12px;
437
- background: var(--color-surface-alt);
93
+ .usage-current-session-dot {
94
+ width: 7px;
95
+ height: 7px;
96
+ border-radius: 50%;
97
+ background: var(--color-success);
98
+ flex-shrink: 0;
99
+ animation: usage-pulse 2s ease-in-out infinite;
438
100
  }
439
101
 
440
- .usage-daydetail-label {
441
- font-size: 12px;
442
- color: var(--color-text-tertiary);
102
+ @keyframes usage-pulse {
103
+ 0%, 100% { opacity: 1; }
104
+ 50% { opacity: 0.4; }
443
105
  }
444
106
 
445
- .usage-daydetail-value {
446
- margin-top: 4px;
447
- font-size: 18px;
448
- font-weight: 750;
107
+ .usage-current-session-label {
108
+ font-weight: 700;
449
109
  color: var(--color-text-primary);
450
110
  }
451
111
 
452
- .usage-daydetail-sub {
453
- margin-top: 6px;
454
- font-size: 11px;
112
+ .usage-current-session-stat {
455
113
  color: var(--color-text-tertiary);
456
- line-height: 1.25;
457
- }
458
-
459
- .usage-daydetail-section {
460
- margin-top: 12px;
461
114
  }
462
115
 
463
- .usage-daydetail-section-title {
464
- font-size: 12px;
465
- font-weight: 700;
466
- color: var(--color-text-secondary);
467
- margin-bottom: 8px;
116
+ .usage-current-session-stat::before {
117
+ content: '·';
118
+ margin-right: 10px;
119
+ color: var(--color-border-strong);
468
120
  }
469
121
 
470
- .usage-daydetail-list {
122
+ /* ---- Summary cards ---- */
123
+ .usage-summary-grid {
471
124
  display: grid;
472
- gap: 8px;
125
+ grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
126
+ gap: 10px;
127
+ margin-bottom: 18px;
473
128
  }
474
129
 
475
- .usage-daydetail-row {
130
+ .usage-summary-card {
476
131
  display: flex;
477
- align-items: center;
478
- justify-content: space-between;
479
- gap: 10px;
480
- padding: 8px 10px;
481
- border-radius: 12px;
482
- background: rgba(24, 24, 27, 0.02);
483
- border: 1px solid rgba(24, 24, 27, 0.08);
132
+ flex-direction: column;
133
+ justify-content: center;
134
+ gap: 2px;
135
+ padding: 14px 16px;
136
+ border-radius: var(--radius-md);
137
+ background: var(--color-surface);
138
+ border: 1px solid var(--color-border-soft);
139
+ transition: all 120ms var(--ease-spring);
140
+ min-height: 72px;
484
141
  }
485
142
 
486
- .usage-daydetail-row-title {
487
- flex: 1;
488
- min-width: 0;
489
- overflow: hidden;
490
- text-overflow: ellipsis;
491
- white-space: nowrap;
143
+ .usage-summary-card-value {
144
+ font-size: 26px;
145
+ font-weight: 700;
492
146
  color: var(--color-text-primary);
493
- font-size: 12px;
147
+ line-height: 1.1;
148
+ letter-spacing: -0.02em;
149
+ font-variant-numeric: tabular-nums;
494
150
  }
495
151
 
496
- .usage-daydetail-row-meta {
497
- flex-shrink: 0;
152
+ .usage-summary-card-label {
153
+ font-size: 11px;
154
+ font-weight: 500;
498
155
  color: var(--color-text-tertiary);
499
- font-size: 12px;
500
- }
501
-
502
- .usage-daydetail-models {
503
- display: flex;
504
- flex-wrap: wrap;
505
- gap: 6px;
156
+ text-transform: uppercase;
157
+ letter-spacing: 0.04em;
506
158
  }
507
159
 
508
- .usage-daydetail-model {
509
- font-size: 12px;
510
- padding: 4px 8px;
511
- border-radius: 999px;
512
- background: rgba(24, 24, 27, 0.06);
513
- color: var(--color-text-secondary);
160
+ .usage-copyable {
161
+ cursor: pointer;
162
+ -webkit-tap-highlight-color: transparent;
514
163
  }
515
164
 
516
- @media (max-width: 900px) {
517
- .usage-chart-grid {
518
- grid-template-columns: 1fr;
519
- }
165
+ .usage-copyable:hover {
166
+ border-color: var(--color-brand);
167
+ background: var(--color-surface-alt);
520
168
  }
521
169
 
522
- .usage-bar.claude {
523
- background: #8b6bd6;
170
+ .usage-copyable:active {
171
+ transform: scale(0.98);
524
172
  }
525
173
 
526
- .usage-bar-label {
527
- font-size: 11px;
528
- color: var(--color-text-secondary);
529
- width: 100%;
530
- text-align: center;
531
- white-space: nowrap;
532
- overflow: hidden;
533
- text-overflow: ellipsis;
174
+ .usage-copyable:focus-visible {
175
+ outline: 2px solid var(--color-brand-light);
176
+ outline-offset: 2px;
534
177
  }
535
178
 
536
- .usage-legend {
537
- display: flex;
538
- gap: 14px;
539
- flex-wrap: wrap;
540
- font-size: 12px;
541
- color: var(--color-text-secondary);
542
- margin-bottom: 10px;
179
+ /* ---- Content area ---- */
180
+ .usage-content {
181
+ position: relative;
543
182
  }
544
183
 
545
- .usage-legend-dot {
546
- width: 10px;
547
- height: 10px;
548
- border-radius: 999px;
549
- display: inline-block;
550
- margin-right: 6px;
184
+ .usage-content-loading {
185
+ opacity: 0.7;
186
+ pointer-events: none;
551
187
  }
552
188
 
553
- .usage-list {
189
+ .usage-content-overlay {
190
+ position: absolute;
191
+ inset: 0;
554
192
  display: flex;
555
- flex-direction: column;
556
- gap: 10px;
557
- min-width: 0;
558
- }
559
-
560
- .usage-list-scroll {
561
- max-height: 220px;
562
- overflow-y: auto;
563
- padding-right: 6px;
564
- scrollbar-gutter: stable;
565
- scrollbar-width: thin;
566
- scrollbar-color: rgba(199, 116, 98, 0.72) rgba(199, 116, 98, 0.08);
567
- }
568
-
569
- .usage-list-top-paths {
570
- max-height: 140px;
571
- gap: 6px;
572
- }
573
-
574
- .usage-card-top-paths {
575
- grid-column: 1 / -1;
576
- }
577
-
578
- .usage-list-scroll::-webkit-scrollbar {
579
- width: 10px;
580
- }
581
-
582
- .usage-list-scroll::-webkit-scrollbar-track {
583
- background: linear-gradient(180deg, rgba(199, 116, 98, 0.04), rgba(199, 116, 98, 0.1));
584
- border-radius: 999px;
585
- }
586
-
587
- .usage-list-scroll::-webkit-scrollbar-thumb {
588
- background: linear-gradient(180deg, rgba(199, 116, 98, 0.68), rgba(180, 94, 78, 0.92));
589
- border-radius: 999px;
590
- border: 2px solid rgba(248, 243, 238, 0.96);
591
- }
592
-
593
- .usage-list-scroll::-webkit-scrollbar-thumb:hover {
594
- background: linear-gradient(180deg, rgba(199, 116, 98, 0.82), rgba(180, 94, 78, 1));
193
+ align-items: flex-start;
194
+ justify-content: flex-end;
195
+ padding: 12px;
196
+ z-index: 1;
595
197
  }
596
198
 
597
- .usage-list-row {
598
- display: grid;
599
- grid-template-columns: minmax(56px, 72px) minmax(0, 1fr) minmax(48px, auto);
600
- gap: 10px;
601
- align-items: center;
602
- min-width: 0;
199
+ .usage-spinner {
200
+ width: 16px;
201
+ height: 16px;
202
+ border-radius: 50%;
203
+ border: 2px solid var(--color-border-soft);
204
+ border-top-color: var(--color-brand);
205
+ animation: usage-spin 0.8s linear infinite;
603
206
  }
604
207
 
605
- .usage-list-label,
606
- .usage-list-value {
607
- font-size: 12px;
608
- color: var(--color-text-secondary);
609
- min-width: 0;
208
+ @keyframes usage-spin {
209
+ to { transform: rotate(360deg); }
610
210
  }
611
211
 
612
- .usage-list-label {
613
- font-weight: 600;
614
- color: var(--color-text-primary);
212
+ /* ---- Cards ---- */
213
+ .usage-card {
214
+ padding: 18px;
215
+ border-radius: var(--radius-md);
216
+ background: var(--color-surface);
217
+ border: 1px solid var(--color-border-soft);
218
+ margin-bottom: 12px;
615
219
  }
616
220
 
617
- .usage-list-value {
618
- word-break: break-word;
619
- overflow-wrap: anywhere;
620
- text-align: right;
221
+ .usage-card-head {
222
+ margin-bottom: 14px;
621
223
  }
622
224
 
623
- .usage-list-subvalue {
624
- grid-column: 1 / -1;
625
- font-size: 11px;
626
- color: var(--color-text-tertiary, var(--color-text-secondary));
627
- line-height: 1.45;
225
+ .usage-card-title {
226
+ font-size: 14px;
227
+ font-weight: 700;
228
+ color: var(--color-text-primary);
229
+ margin-bottom: 2px;
628
230
  }
629
231
 
630
- .usage-list-row-compact {
631
- grid-template-columns: minmax(52px, 64px) minmax(0, 1fr) minmax(32px, auto);
232
+ .usage-card-subtitle {
233
+ font-size: 11px;
234
+ color: var(--color-text-muted);
632
235
  }
633
236
 
634
- .usage-progress {
635
- height: 8px;
636
- border-radius: 999px;
637
- background: rgba(71, 60, 52, 0.10);
638
- overflow: hidden;
237
+ /* ---- Chart grid ---- */
238
+ .usage-chart-grid {
239
+ display: grid;
240
+ grid-template-columns: repeat(2, 1fr);
241
+ gap: 12px;
639
242
  }
640
243
 
641
- .usage-progress-fill {
642
- height: 100%;
643
- border-radius: 999px;
644
- background: linear-gradient(90deg, var(--color-brand), #8b6bd6);
244
+ .usage-card-wide {
245
+ grid-column: 1 / -1;
645
246
  }
646
247
 
647
- .usage-mini-bars {
648
- display: grid;
649
- grid-template-columns: repeat(24, minmax(0, 1fr));
650
- gap: 10px 8px;
651
- align-items: end;
248
+ /* ---- Daily chart ---- */
249
+ .usage-daily-chart {
250
+ display: flex;
251
+ align-items: flex-end;
252
+ gap: 4px;
253
+ height: 140px;
254
+ padding: 0 2px;
652
255
  }
653
256
 
654
- .usage-mini-bar-group {
257
+ .usage-daily-bar-group {
258
+ flex: 1;
655
259
  display: flex;
656
260
  flex-direction: column;
657
261
  align-items: center;
658
262
  gap: 6px;
263
+ cursor: pointer;
659
264
  min-width: 0;
265
+ -webkit-tap-highlight-color: transparent;
660
266
  }
661
267
 
662
- .usage-mini-bar-track {
268
+ .usage-daily-bar-stack {
663
269
  width: 100%;
664
- min-width: 16px;
665
- max-width: 24px;
666
- height: 72px;
667
- border-radius: 10px;
668
- background: rgba(71, 60, 52, 0.08);
270
+ max-width: 32px;
271
+ height: 100px;
669
272
  display: flex;
670
- align-items: flex-end;
273
+ flex-direction: column;
274
+ justify-content: flex-end;
275
+ position: relative;
276
+ border-radius: 4px 4px 0 0;
671
277
  overflow: hidden;
278
+ background: var(--color-surface-alt);
672
279
  }
673
280
 
674
- .usage-mini-bar-fill {
281
+ .usage-daily-bar-fill {
675
282
  width: 100%;
676
- min-height: 6px;
677
- border-radius: 10px 10px 4px 4px;
678
- background: linear-gradient(180deg, #8b6bd6 0%, var(--color-brand) 100%);
679
- }
680
-
681
- .usage-mini-bar-label {
682
- font-size: 10px;
683
- color: var(--color-text-secondary);
283
+ border-radius: 4px 4px 0 0;
284
+ background: var(--color-brand);
285
+ transition: height 200ms var(--ease-spring);
286
+ min-height: 2px;
684
287
  }
685
288
 
686
- .usage-session-list {
687
- display: flex;
688
- flex-direction: column;
689
- gap: 10px;
289
+ .usage-daily-bar-prev {
290
+ width: 100%;
291
+ background: var(--color-text-muted);
292
+ opacity: 0.35;
293
+ border-radius: 4px 4px 0 0;
690
294
  }
691
295
 
692
- .usage-session-item {
693
- padding: 12px;
694
- border-radius: 12px;
695
- background: var(--color-surface-alt);
696
- border: 1px solid var(--color-border-soft);
697
- min-width: 0;
296
+ .usage-daily-bar-group.active .usage-daily-bar-fill {
297
+ background: var(--color-brand-dark);
298
+ box-shadow: 0 0 8px rgba(200, 121, 99, 0.3);
698
299
  }
699
300
 
700
- .usage-session-row {
701
- display: flex;
702
- justify-content: space-between;
703
- gap: 10px;
704
- align-items: flex-start;
705
- min-width: 0;
301
+ .usage-daily-bar-group:hover .usage-daily-bar-fill {
302
+ filter: brightness(1.1);
706
303
  }
707
304
 
708
- .usage-session-title {
709
- font-size: 13px;
710
- font-weight: 600;
711
- color: var(--color-text-primary);
712
- min-width: 0;
305
+ .usage-daily-bar-label {
306
+ font-size: 10px;
307
+ color: var(--color-text-muted);
308
+ text-align: center;
309
+ white-space: nowrap;
713
310
  overflow: hidden;
714
311
  text-overflow: ellipsis;
715
- white-space: nowrap;
312
+ max-width: 100%;
716
313
  }
717
314
 
718
- .usage-inline-stat {
719
- font-size: 11px;
315
+ .usage-daily-bar-group.active .usage-daily-bar-label {
720
316
  color: var(--color-brand-dark);
721
- background: var(--color-brand-light);
722
- border-radius: 999px;
723
- padding: 4px 8px;
724
- flex-shrink: 0;
725
317
  font-weight: 700;
726
318
  }
727
319
 
728
- .usage-session-meta {
320
+ /* ---- Daily legend ---- */
321
+ .usage-daily-legend {
729
322
  display: flex;
730
- gap: 10px;
731
- flex-wrap: wrap;
732
- font-size: 11px;
733
- color: var(--color-text-secondary);
734
- margin-top: 6px;
735
- }
736
-
737
- .usage-session-path {
738
- margin-top: 6px;
323
+ gap: 16px;
324
+ margin-top: 10px;
739
325
  font-size: 11px;
740
- color: var(--color-text-secondary);
741
- word-break: break-word;
742
- overflow-wrap: anywhere;
326
+ color: var(--color-text-muted);
743
327
  }
744
328
 
745
- .usage-card-models {
746
- display: flex;
747
- flex-direction: column;
748
- gap: 12px;
329
+ .usage-daily-legend-item {
330
+ display: inline-flex;
331
+ align-items: center;
332
+ gap: 5px;
749
333
  }
750
334
 
751
- .usage-model-coverage-strip {
752
- display: grid;
753
- grid-template-columns: repeat(3, minmax(0, 1fr));
754
- gap: 10px;
335
+ .usage-daily-legend-swatch {
336
+ width: 10px;
337
+ height: 10px;
338
+ border-radius: 2px;
755
339
  }
756
340
 
757
- .usage-model-coverage-item {
758
- padding: 12px;
759
- border-radius: 12px;
760
- border: 1px solid var(--color-border-soft);
761
- background: var(--color-surface-alt);
762
- display: flex;
763
- flex-direction: column;
764
- gap: 4px;
341
+ .usage-daily-legend-swatch.current {
342
+ background: var(--color-brand);
765
343
  }
766
344
 
767
- .usage-model-coverage-item strong {
768
- font-size: 20px;
769
- color: var(--color-text-primary);
345
+ .usage-daily-legend-swatch.prev {
346
+ background: var(--color-text-muted);
347
+ opacity: 0.35;
770
348
  }
771
349
 
772
- .usage-model-coverage-item span,
773
- .usage-inline-note,
774
- .usage-diagnostic-copy,
775
- .usage-diagnostic-meta {
776
- font-size: 12px;
777
- line-height: 1.5;
778
- color: var(--color-text-secondary);
350
+ /* ---- Day detail ---- */
351
+ .usage-daydetail {
352
+ margin-top: 12px;
353
+ padding: 10px 14px;
354
+ border-radius: var(--radius-sm);
355
+ background: var(--color-surface-alt);
779
356
  }
780
357
 
781
- .usage-diagnostic-empty {
782
- padding: 14px;
783
- border-radius: 14px;
784
- border: 1px dashed var(--color-border);
785
- background: var(--color-surface-alt);
358
+ .usage-daydetail-header {
359
+ display: flex;
360
+ justify-content: space-between;
361
+ align-items: center;
362
+ flex-wrap: wrap;
363
+ gap: 8px;
786
364
  }
787
365
 
788
- .usage-diagnostic-title {
789
- font-size: 13px;
366
+ .usage-daydetail-date {
790
367
  font-weight: 700;
368
+ font-size: 13px;
791
369
  color: var(--color-text-primary);
792
- margin-bottom: 6px;
793
370
  }
794
371
 
795
- .usage-inline-note {
796
- padding: 10px 12px;
797
- border-radius: 12px;
798
- background: rgba(255, 244, 220, 0.62);
799
- color: #7a5110;
372
+ .usage-daydetail-stats {
373
+ font-size: 12px;
374
+ color: var(--color-text-secondary);
800
375
  }
801
376
 
802
- .usage-inline-tag {
803
- display: inline-flex;
804
- align-items: center;
805
- margin: 0 6px 0 0;
806
- padding: 2px 8px;
807
- border-radius: 999px;
808
- background: rgba(122, 81, 16, 0.10);
809
- border: 1px solid rgba(122, 81, 16, 0.14);
810
- color: inherit;
811
- font-weight: 700;
377
+ .usage-daydetail-compare {
378
+ margin-top: 4px;
379
+ font-size: 11px;
380
+ color: var(--color-text-muted);
812
381
  }
813
382
 
814
- .usage-diagnostic-list {
383
+ /* ---- Lists ---- */
384
+ .usage-list {
815
385
  display: flex;
816
386
  flex-direction: column;
817
387
  gap: 8px;
818
388
  }
819
389
 
820
- .usage-diagnostic-list-title {
821
- font-size: 12px;
822
- font-weight: 700;
823
- color: var(--color-text-primary);
824
- }
825
-
826
- .usage-diagnostic-row {
827
- display: flex;
828
- justify-content: space-between;
829
- gap: 12px;
390
+ .usage-list-row {
391
+ display: grid;
392
+ grid-template-columns: 1fr auto;
830
393
  align-items: center;
831
- padding: 10px 12px;
832
- border-radius: 12px;
833
- border: 1px solid var(--color-border-soft);
394
+ gap: 8px 12px;
395
+ padding: 8px 10px;
396
+ border-radius: var(--radius-sm);
834
397
  background: var(--color-surface-alt);
398
+ transition: background 120ms var(--ease-spring);
835
399
  }
836
400
 
837
- .usage-diagnostic-row-main,
838
- .usage-diagnostic-row-side {
839
- min-width: 0;
401
+ .usage-list-row:hover {
402
+ background: var(--color-surface-elevated);
840
403
  }
841
404
 
842
- .usage-diagnostic-row-title {
405
+ .usage-list-title {
843
406
  font-size: 12px;
844
- font-weight: 700;
407
+ font-weight: 600;
845
408
  color: var(--color-text-primary);
846
- word-break: break-word;
847
- overflow-wrap: anywhere;
409
+ overflow: hidden;
410
+ text-overflow: ellipsis;
411
+ white-space: nowrap;
848
412
  }
849
413
 
850
- .usage-diagnostic-row-meta {
851
- display: flex;
852
- flex-wrap: wrap;
853
- gap: 8px;
854
- margin-top: 4px;
855
- font-size: 11px;
414
+ .usage-list-path {
415
+ font-size: 12px;
856
416
  color: var(--color-text-secondary);
417
+ overflow: hidden;
418
+ text-overflow: ellipsis;
419
+ white-space: nowrap;
420
+ font-family: var(--font-family-mono);
421
+ font-size: 11px;
857
422
  }
858
423
 
859
- .usage-diagnostic-row-side {
860
- display: flex;
861
- align-items: center;
862
- gap: 8px;
863
- flex-wrap: wrap;
864
- justify-content: flex-end;
865
- }
866
-
867
- .usage-model-list {
868
- display: flex;
869
- flex-wrap: wrap;
870
- gap: 10px;
871
- }
872
-
873
- .usage-model-chip {
874
- min-width: 0;
875
- max-width: 100%;
876
- padding: 10px 12px;
877
- border-radius: 12px;
878
- background: var(--color-surface-alt);
879
- border: 1px solid var(--color-border-soft);
880
- }
881
-
882
- .usage-model-name {
883
- font-size: 12px;
424
+ .usage-list-stat {
425
+ font-size: 13px;
884
426
  font-weight: 700;
885
427
  color: var(--color-text-primary);
886
- word-break: break-word;
887
- overflow-wrap: anywhere;
428
+ font-variant-numeric: tabular-nums;
429
+ text-align: right;
888
430
  }
889
431
 
890
- .usage-model-meta {
891
- margin-top: 4px;
432
+ .usage-list-meta {
433
+ grid-column: 1 / -1;
892
434
  font-size: 11px;
893
- color: var(--color-text-secondary);
894
- line-height: 1.4;
435
+ color: var(--color-text-muted);
895
436
  }
896
437
 
897
- .usage-empty {
898
- padding: 24px 16px;
899
- border-radius: 16px;
900
- background: var(--color-surface-alt);
901
- border: 1px dashed var(--color-border);
438
+ .usage-list-value {
439
+ font-size: 12px;
902
440
  color: var(--color-text-secondary);
441
+ padding: 8px 0;
903
442
  }
904
443
 
905
- @media (max-width: 960px) {
906
- .usage-chart-grid,
907
- .usage-model-coverage-strip {
908
- grid-template-columns: 1fr;
909
- }
444
+ .usage-progress {
445
+ height: 3px;
446
+ border-radius: 2px;
447
+ background: var(--color-surface-alt);
448
+ overflow: hidden;
910
449
  }
911
450
 
912
- @media (max-width: 640px) {
913
- .usage-list-row {
914
- grid-template-columns: 1fr;
915
- gap: 6px;
916
- }
917
-
918
- .usage-list-subvalue {
919
- grid-column: auto;
920
- }
921
-
922
- .usage-list-value {
923
- text-align: left;
924
- }
925
-
926
- .usage-mini-bars {
927
- grid-template-columns: repeat(12, minmax(0, 1fr));
928
- }
929
-
930
- .usage-bar-group {
931
- flex-basis: 36px;
932
- min-width: 36px;
933
- }
934
-
935
- .usage-bar-stack {
936
- max-width: 28px;
937
- }
938
-
939
- .usage-toolbar,
940
- .usage-card-head,
941
- .usage-session-row {
942
- flex-direction: column;
943
- align-items: stretch;
944
- }
451
+ .usage-progress-fill {
452
+ height: 100%;
453
+ border-radius: 2px;
454
+ background: var(--color-brand);
455
+ transition: width 300ms var(--ease-spring);
945
456
  }
946
457
 
458
+ /* ---- Hourly heatmap ---- */
947
459
  .usage-card-hourly-heatmap {
948
460
  overflow-x: auto;
949
461
  }
@@ -952,8 +464,8 @@
952
464
  display: flex;
953
465
  flex-direction: column;
954
466
  gap: 2px;
955
- margin-top: 8px;
956
- min-width: 580px;
467
+ margin-top: 10px;
468
+ min-width: 480px;
957
469
  }
958
470
 
959
471
  .hourly-heatmap-header {
@@ -963,14 +475,14 @@
963
475
  }
964
476
 
965
477
  .hourly-heatmap-corner {
966
- width: 36px;
478
+ width: 32px;
967
479
  flex-shrink: 0;
968
480
  }
969
481
 
970
482
  .hourly-heatmap-hour-label {
971
483
  flex: 1;
972
484
  min-width: 0;
973
- font-size: 10px;
485
+ font-size: 9px;
974
486
  color: var(--color-text-muted);
975
487
  text-align: center;
976
488
  line-height: 14px;
@@ -983,9 +495,9 @@
983
495
  }
984
496
 
985
497
  .hourly-heatmap-weekday-label {
986
- width: 36px;
498
+ width: 32px;
987
499
  flex-shrink: 0;
988
- font-size: 11px;
500
+ font-size: 10px;
989
501
  color: var(--color-text-secondary);
990
502
  text-align: right;
991
503
  padding-right: 4px;
@@ -996,45 +508,81 @@
996
508
  min-width: 0;
997
509
  aspect-ratio: 1;
998
510
  border-radius: 3px;
999
- cursor: default;
1000
- }
1001
-
1002
- .hourly-heatmap-cell.level-0 {
1003
- background: var(--color-surface-alt);
1004
511
  }
1005
512
 
1006
- .hourly-heatmap-cell.level-1 {
1007
- background: var(--color-heatmap-1);
1008
- }
1009
-
1010
- .hourly-heatmap-cell.level-2 {
1011
- background: var(--color-heatmap-2);
1012
- }
1013
-
1014
- .hourly-heatmap-cell.level-3 {
1015
- background: var(--color-heatmap-3);
1016
- }
1017
-
1018
- .hourly-heatmap-cell.level-4 {
1019
- background: var(--color-heatmap-4);
1020
- }
513
+ .hourly-heatmap-cell.level-0 { background: var(--color-surface-alt); }
514
+ .hourly-heatmap-cell.level-1 { background: var(--color-heatmap-1); }
515
+ .hourly-heatmap-cell.level-2 { background: var(--color-heatmap-2); }
516
+ .hourly-heatmap-cell.level-3 { background: var(--color-heatmap-3); }
517
+ .hourly-heatmap-cell.level-4 { background: var(--color-heatmap-4); }
1021
518
 
1022
519
  .hourly-heatmap-legend {
1023
520
  display: flex;
1024
521
  align-items: center;
1025
522
  gap: 3px;
1026
523
  justify-content: flex-end;
1027
- margin-top: 6px;
524
+ margin-top: 8px;
1028
525
  font-size: 10px;
1029
526
  color: var(--color-text-muted);
1030
527
  }
1031
528
 
1032
529
  .hourly-heatmap-legend .hourly-heatmap-cell {
1033
- width: 12px;
1034
- height: 12px;
530
+ width: 11px;
531
+ height: 11px;
1035
532
  aspect-ratio: auto;
1036
533
  }
1037
534
 
1038
535
  .hourly-heatmap-legend-label {
1039
536
  margin: 0 2px;
1040
537
  }
538
+
539
+ /* ---- Empty state ---- */
540
+ .usage-empty {
541
+ padding: 32px 16px;
542
+ border-radius: var(--radius-md);
543
+ background: var(--color-surface-alt);
544
+ border: 1px dashed var(--color-border);
545
+ color: var(--color-text-secondary);
546
+ text-align: center;
547
+ font-size: 13px;
548
+ }
549
+
550
+ /* ---- Responsive ---- */
551
+ @media (max-width: 960px) {
552
+ .usage-chart-grid {
553
+ grid-template-columns: 1fr;
554
+ }
555
+
556
+ .usage-summary-grid {
557
+ grid-template-columns: repeat(2, 1fr);
558
+ }
559
+ }
560
+
561
+ @media (max-width: 640px) {
562
+ .usage-toolbar {
563
+ flex-direction: column;
564
+ align-items: stretch;
565
+ }
566
+
567
+ .usage-range-group {
568
+ justify-content: center;
569
+ flex-wrap: wrap;
570
+ }
571
+
572
+ .usage-summary-grid {
573
+ grid-template-columns: repeat(2, 1fr);
574
+ }
575
+
576
+ .usage-summary-card-value {
577
+ font-size: 22px;
578
+ }
579
+
580
+ .usage-daily-chart {
581
+ height: 100px;
582
+ }
583
+
584
+ .usage-daily-bar-stack {
585
+ max-width: 24px;
586
+ height: 70px;
587
+ }
588
+ }