codexmate 0.0.34 → 0.0.37

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 (34) hide show
  1. package/README.md +14 -5
  2. package/README.zh.md +14 -5
  3. package/cli.js +74 -61
  4. package/package.json +2 -1
  5. package/web-ui/app.js +32 -2
  6. package/web-ui/index.html +1 -1
  7. package/web-ui/logic.sessions.mjs +6 -5
  8. package/web-ui/modules/app.computed.dashboard.mjs +4 -0
  9. package/web-ui/modules/app.computed.session.mjs +147 -6
  10. package/web-ui/modules/app.methods.claude-config.mjs +4 -0
  11. package/web-ui/modules/app.methods.navigation.mjs +32 -16
  12. package/web-ui/modules/app.methods.session-browser.mjs +7 -0
  13. package/web-ui/modules/app.methods.session-trash.mjs +30 -0
  14. package/web-ui/modules/i18n.dict.mjs +5 -0
  15. package/web-ui/modules/sessions-filters-url.mjs +65 -12
  16. package/web-ui/modules/skills.methods.mjs +31 -0
  17. package/web-ui/partials/index/layout-header.html +20 -11
  18. package/web-ui/partials/index/panel-config-claude.html +5 -3
  19. package/web-ui/partials/index/panel-config-codex.html +1 -1
  20. package/web-ui/partials/index/panel-market.html +76 -149
  21. package/web-ui/partials/index/panel-sessions.html +2 -2
  22. package/web-ui/partials/index/panel-settings.html +4 -2
  23. package/web-ui/partials/index/panel-usage.html +111 -68
  24. package/web-ui/res/vue.runtime.global.prod.js +7 -0
  25. package/web-ui/res/web-ui-render.precompiled.js +7269 -0
  26. package/web-ui/session-helpers.mjs +15 -4
  27. package/web-ui/source-bundle.cjs +73 -1
  28. package/web-ui/styles/base-theme.css +10 -0
  29. package/web-ui/styles/layout-shell.css +65 -27
  30. package/web-ui/styles/navigation-panels.css +8 -0
  31. package/web-ui/styles/responsive.css +50 -9
  32. package/web-ui/styles/sessions-usage.css +501 -336
  33. package/web-ui/styles/skills-market.css +294 -0
  34. package/web-ui/styles/titles-cards.css +14 -0
@@ -1,5 +1,5 @@
1
1
  /* ============================================
2
- Usage Tab — Refined Design System
2
+ Usage Tab — 流光设计 (Flow of Light)
3
3
  ============================================ */
4
4
 
5
5
  /* ---- Toolbar ---- */
@@ -7,554 +7,710 @@
7
7
  display: flex;
8
8
  justify-content: space-between;
9
9
  align-items: center;
10
- gap: 12px;
10
+ gap: 16px;
11
11
  flex-wrap: wrap;
12
- margin-bottom: 18px;
12
+ margin-bottom: 28px;
13
13
  }
14
14
 
15
15
  .usage-toolbar-title {
16
- font-size: var(--font-size-title);
17
- font-weight: var(--font-weight-title);
16
+ font-size: 20px;
17
+ font-weight: 600;
18
18
  color: var(--color-text-primary);
19
- letter-spacing: -0.01em;
19
+ letter-spacing: -0.03em;
20
20
  }
21
21
 
22
22
  .usage-range-group {
23
23
  display: flex;
24
- gap: 4px;
24
+ gap: 2px;
25
25
  padding: 3px;
26
- border-radius: var(--radius-md);
27
- background: var(--color-surface-alt);
28
- border: 1px solid var(--color-border-soft);
26
+ border-radius: 12px;
27
+ background: linear-gradient(135deg, rgba(255,255,255,0.9), rgba(247,239,232,0.7));
28
+ border: 1px solid rgba(137, 111, 94, 0.08);
29
+ box-shadow: 0 2px 12px rgba(92, 68, 52, 0.06);
30
+ backdrop-filter: blur(8px);
29
31
  }
30
32
 
31
33
  .usage-range-btn {
32
34
  border: none;
33
35
  background: transparent;
34
36
  color: var(--color-text-tertiary);
35
- padding: 5px 11px;
36
- border-radius: var(--radius-sm);
37
+ padding: 8px 16px;
38
+ border-radius: 9px;
37
39
  cursor: pointer;
38
- font-size: 12px;
39
- font-weight: 600;
40
+ font-size: 13px;
41
+ font-weight: 500;
40
42
  font-family: var(--font-family);
41
43
  white-space: nowrap;
42
- transition: all 120ms var(--ease-spring);
44
+ transition: all 180ms var(--ease-spring);
43
45
  outline: none;
44
46
  -webkit-tap-highlight-color: transparent;
45
47
  }
46
48
 
47
49
  .usage-range-btn:hover:not(:disabled) {
48
50
  color: var(--color-text-secondary);
49
- background: var(--color-surface);
51
+ background: rgba(200, 121, 99, 0.08);
50
52
  }
51
53
 
52
54
  .usage-range-btn:active:not(:disabled) {
53
- transform: scale(0.97);
55
+ transform: scale(0.95);
54
56
  }
55
57
 
56
58
  .usage-range-btn.active {
57
59
  color: #fff;
58
- background: var(--color-brand);
59
- box-shadow: 0 1px 3px rgba(200, 121, 99, 0.35);
60
+ background: linear-gradient(135deg, var(--color-brand), var(--color-brand-dark));
61
+ box-shadow: 0 4px 16px rgba(200, 121, 99, 0.35), 0 0 0 1px rgba(255,255,255,0.1) inset;
60
62
  }
61
63
 
62
64
  .usage-range-btn:disabled {
63
- opacity: 0.4;
65
+ opacity: 0.35;
64
66
  cursor: not-allowed;
65
67
  }
66
68
 
67
69
  .usage-range-btn-icon {
68
- padding: 5px 8px;
70
+ padding: 8px 12px;
69
71
  display: inline-flex;
70
72
  align-items: center;
71
73
  justify-content: center;
72
74
  }
73
75
 
74
76
  .usage-range-btn-icon svg {
75
- width: 14px;
76
- height: 14px;
77
+ width: 16px;
78
+ height: 16px;
79
+ }
80
+
81
+ .usage-range-btn-icon:active {
82
+ transform: rotate(180deg);
83
+ transition: transform 400ms var(--ease-spring);
84
+ }
85
+
86
+ /* ---- Empty State (插画风格) ---- */
87
+ .usage-empty-state {
88
+ display: flex;
89
+ flex-direction: column;
90
+ align-items: center;
91
+ justify-content: center;
92
+ padding: 64px 20px;
93
+ text-align: center;
94
+ }
95
+
96
+ .usage-empty-illustration {
97
+ width: 72px;
98
+ height: 72px;
99
+ color: var(--color-text-muted);
100
+ opacity: 0.5;
101
+ margin-bottom: 20px;
102
+ animation: usage-empty-breathe 4s ease-in-out infinite;
77
103
  }
78
104
 
79
- /* ---- Current session bar ---- */
80
- .usage-current-session-bar {
105
+ @keyframes usage-empty-breathe {
106
+ 0%, 100% { transform: scale(1) translateY(0); opacity: 0.5; }
107
+ 50% { transform: scale(1.08) translateY(-4px); opacity: 0.7; }
108
+ }
109
+
110
+ .usage-empty-text {
111
+ font-size: 14px;
112
+ color: var(--color-text-secondary);
113
+ max-width: 300px;
114
+ line-height: 1.6;
115
+ }
116
+
117
+ /* ---- Hero 区域 (全宽沉浸式) ---- */
118
+ .usage-hero {
119
+ padding: 32px 28px;
120
+ margin-bottom: 24px;
121
+ border-radius: 18px;
122
+ background: linear-gradient(135deg, rgba(255,255,255,0.95), rgba(252,248,241,0.9));
123
+ border: 1px solid rgba(137, 111, 94, 0.08);
124
+ min-height: 160px;
125
+ display: flex;
126
+ flex-direction: column;
127
+ justify-content: center;
128
+ gap: 20px;
129
+ box-shadow: 0 8px 32px rgba(92, 68, 52, 0.08), 0 0 0 1px rgba(255,255,255,0.5) inset;
130
+ backdrop-filter: blur(10px);
131
+ position: relative;
132
+ overflow: hidden;
133
+ }
134
+
135
+ .usage-hero::before {
136
+ content: '';
137
+ position: absolute;
138
+ top: -50%;
139
+ right: -20%;
140
+ width: 400px;
141
+ height: 400px;
142
+ background: radial-gradient(circle, rgba(200, 121, 99, 0.06) 0%, transparent 70%);
143
+ pointer-events: none;
144
+ }
145
+
146
+ .usage-hero-active {
81
147
  display: flex;
82
148
  flex-wrap: wrap;
83
149
  align-items: center;
84
- gap: 10px;
85
- padding: 8px 14px;
86
- margin-bottom: 16px;
87
- border-radius: var(--radius-md);
88
- background: var(--color-surface-alt);
150
+ gap: 10px 16px;
151
+ padding: 12px 18px;
152
+ border-radius: 12px;
153
+ background: linear-gradient(135deg, rgba(200, 121, 99, 0.08), rgba(200, 121, 99, 0.04));
154
+ border: 1px solid rgba(200, 121, 99, 0.12);
89
155
  font-size: 12px;
90
- color: var(--color-text-secondary);
156
+ position: relative;
157
+ z-index: 1;
91
158
  }
92
159
 
93
- .usage-current-session-dot {
160
+ .usage-hero-active-dot {
94
161
  width: 7px;
95
162
  height: 7px;
96
163
  border-radius: 50%;
97
164
  background: var(--color-success);
98
165
  flex-shrink: 0;
99
- animation: usage-pulse 2s ease-in-out infinite;
166
+ animation: usage-pulse 2.2s ease-in-out infinite;
167
+ box-shadow: 0 0 12px rgba(75, 139, 106, 0.4);
100
168
  }
101
169
 
102
170
  @keyframes usage-pulse {
103
- 0%, 100% { opacity: 1; }
104
- 50% { opacity: 0.4; }
171
+ 0%, 100% { opacity: 1; transform: scale(1); }
172
+ 50% { opacity: 0.5; transform: scale(0.85); }
105
173
  }
106
174
 
107
- .usage-current-session-label {
108
- font-weight: 700;
175
+ .usage-hero-active-label {
176
+ font-weight: 600;
109
177
  color: var(--color-text-primary);
110
178
  }
111
179
 
112
- .usage-current-session-stat {
180
+ .usage-hero-active-stat {
113
181
  color: var(--color-text-tertiary);
114
182
  }
115
183
 
116
- .usage-current-session-stat::before {
184
+ .usage-hero-active-stat::before {
117
185
  content: '·';
118
- margin-right: 10px;
186
+ margin-right: 12px;
119
187
  color: var(--color-border-strong);
120
188
  }
121
189
 
122
- /* ---- Summary cards ---- */
123
- .usage-summary-grid {
124
- display: grid;
125
- grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
126
- gap: 10px;
127
- margin-bottom: 18px;
128
- }
129
-
130
- .usage-summary-card {
131
- display: flex;
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;
190
+ .usage-hero-metrics {
191
+ text-align: center;
192
+ position: relative;
193
+ z-index: 1;
141
194
  }
142
195
 
143
- .usage-summary-card-value {
144
- font-size: 26px;
196
+ .usage-hero-main {
197
+ font-size: 52px;
145
198
  font-weight: 700;
146
199
  color: var(--color-text-primary);
147
- line-height: 1.1;
148
- letter-spacing: -0.02em;
200
+ line-height: 1;
201
+ letter-spacing: -0.04em;
149
202
  font-variant-numeric: tabular-nums;
203
+ animation: usage-hero-count 1s var(--ease-out-expo);
204
+ background: linear-gradient(135deg, var(--color-text-primary) 0%, var(--color-brand) 100%);
205
+ -webkit-background-clip: text;
206
+ -webkit-text-fill-color: transparent;
207
+ background-clip: text;
150
208
  }
151
209
 
152
- .usage-summary-card-label {
153
- font-size: 11px;
154
- font-weight: 500;
210
+ @keyframes usage-hero-count {
211
+ from { opacity: 0; transform: translateY(16px) scale(0.95); }
212
+ to { opacity: 1; transform: translateY(0) scale(1); }
213
+ }
214
+
215
+ .usage-hero-sub {
216
+ margin-top: 10px;
217
+ font-size: 14px;
155
218
  color: var(--color-text-tertiary);
156
- text-transform: uppercase;
157
- letter-spacing: 0.04em;
219
+ display: flex;
220
+ align-items: center;
221
+ justify-content: center;
222
+ gap: 14px;
223
+ flex-wrap: wrap;
158
224
  }
159
225
 
160
- .usage-copyable {
161
- cursor: pointer;
162
- -webkit-tap-highlight-color: transparent;
226
+ .usage-hero-delta {
227
+ font-size: 12px;
228
+ font-weight: 600;
229
+ padding: 3px 10px;
230
+ border-radius: 16px;
163
231
  }
164
232
 
165
- .usage-copyable:hover {
166
- border-color: var(--color-brand);
167
- background: var(--color-surface-alt);
233
+ .usage-hero-delta.delta-up {
234
+ color: var(--color-success);
235
+ background: linear-gradient(135deg, rgba(75, 139, 106, 0.15), rgba(75, 139, 106, 0.08));
168
236
  }
169
237
 
170
- .usage-copyable:active {
171
- transform: scale(0.98);
238
+ .usage-hero-delta.delta-down {
239
+ color: var(--color-error);
240
+ background: linear-gradient(135deg, rgba(196, 69, 54, 0.15), rgba(196, 69, 54, 0.08));
172
241
  }
173
242
 
174
- .usage-copyable:focus-visible {
175
- outline: 2px solid var(--color-brand-light);
176
- outline-offset: 2px;
243
+ /* ---- 波浪图 (流体动画) ---- */
244
+ .usage-wave-section {
245
+ overflow: hidden;
246
+ border: none;
247
+ background: transparent;
248
+ padding: 0;
249
+ margin-bottom: 24px;
177
250
  }
178
251
 
179
- /* ---- Content area ---- */
180
- .usage-content {
252
+ .usage-wave-container {
253
+ margin-top: 16px;
181
254
  position: relative;
255
+ padding: 20px;
256
+ border-radius: 18px;
257
+ background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
258
+ border: 1px solid rgba(137, 111, 94, 0.06);
259
+ box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
260
+ backdrop-filter: blur(8px);
182
261
  }
183
262
 
184
- .usage-content-loading {
185
- opacity: 0.7;
186
- pointer-events: none;
263
+ .usage-wave-chart {
264
+ width: 100%;
265
+ height: 150px;
266
+ display: block;
187
267
  }
188
268
 
189
- .usage-content-overlay {
190
- position: absolute;
191
- inset: 0;
192
- display: flex;
193
- align-items: flex-start;
194
- justify-content: flex-end;
195
- padding: 12px;
196
- z-index: 1;
269
+ .usage-wave-area {
270
+ transition: d 600ms var(--ease-spring);
271
+ animation: usage-wave-pulse 4s ease-in-out infinite;
197
272
  }
198
273
 
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;
274
+ @keyframes usage-wave-pulse {
275
+ 0%, 100% { opacity: 1; }
276
+ 50% { opacity: 0.85; }
206
277
  }
207
278
 
208
- @keyframes usage-spin {
209
- to { transform: rotate(360deg); }
279
+ .usage-wave-line {
280
+ transition: d 600ms var(--ease-spring);
281
+ filter: drop-shadow(0 4px 12px rgba(200, 121, 99, 0.25));
210
282
  }
211
283
 
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;
284
+ .usage-wave-hover-line {
285
+ transition: x1 200ms var(--ease-spring), x2 200ms var(--ease-spring),
286
+ y1 200ms var(--ease-spring), y2 200ms var(--ease-spring);
287
+ stroke-dasharray: 4 4;
288
+ animation: usage-hover-dash 20s linear infinite;
219
289
  }
220
290
 
221
- .usage-card-head {
222
- margin-bottom: 14px;
291
+ @keyframes usage-hover-dash {
292
+ to { stroke-dashoffset: -100; }
223
293
  }
224
294
 
225
- .usage-card-title {
226
- font-size: 14px;
227
- font-weight: 700;
228
- color: var(--color-text-primary);
229
- margin-bottom: 2px;
295
+ .usage-wave-hover-point {
296
+ transition: cx 200ms var(--ease-spring), cy 200ms var(--ease-spring);
297
+ filter: drop-shadow(0 0 8px rgba(200, 121, 99, 0.4));
298
+ animation: usage-point-pulse 2s ease-in-out infinite;
230
299
  }
231
300
 
232
- .usage-card-subtitle {
301
+ @keyframes usage-point-pulse {
302
+ 0%, 100% { r: 5; }
303
+ 50% { r: 6.5; }
304
+ }
305
+
306
+ .usage-wave-labels {
307
+ display: flex;
308
+ justify-content: space-between;
309
+ margin-top: 12px;
310
+ padding: 0 8px;
311
+ }
312
+
313
+ .usage-wave-label {
233
314
  font-size: 11px;
234
315
  color: var(--color-text-muted);
316
+ cursor: pointer;
317
+ padding: 4px 8px;
318
+ border-radius: 6px;
319
+ transition: all 180ms var(--ease-spring);
320
+ -webkit-tap-highlight-color: transparent;
321
+ font-weight: 500;
235
322
  }
236
323
 
237
- /* ---- Chart grid ---- */
238
- .usage-chart-grid {
239
- display: grid;
240
- grid-template-columns: repeat(2, 1fr);
241
- gap: 12px;
324
+ .usage-wave-label:hover {
325
+ color: var(--color-text-secondary);
326
+ background: rgba(200, 121, 99, 0.08);
242
327
  }
243
328
 
244
- .usage-card-wide {
245
- grid-column: 1 / -1;
329
+ .usage-wave-label.active {
330
+ color: var(--color-brand);
331
+ font-weight: 600;
332
+ background: linear-gradient(135deg, rgba(200, 121, 99, 0.12), rgba(200, 121, 99, 0.06));
246
333
  }
247
334
 
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;
335
+ /* ---- 日期详情 ---- */
336
+ .usage-daydetail {
337
+ margin-top: 16px;
338
+ padding: 14px 18px;
339
+ border-radius: 12px;
340
+ background: linear-gradient(135deg, rgba(247, 239, 232, 0.8), rgba(247, 239, 232, 0.4));
341
+ border: 1px solid rgba(137, 111, 94, 0.06);
255
342
  }
256
343
 
257
- .usage-daily-bar-group {
258
- flex: 1;
344
+ .usage-daydetail-header {
259
345
  display: flex;
260
- flex-direction: column;
346
+ justify-content: space-between;
261
347
  align-items: center;
262
- gap: 6px;
263
- cursor: pointer;
264
- min-width: 0;
265
- -webkit-tap-highlight-color: transparent;
348
+ flex-wrap: wrap;
349
+ gap: 8px;
266
350
  }
267
351
 
268
- .usage-daily-bar-stack {
269
- width: 100%;
270
- max-width: 32px;
271
- height: 100px;
272
- display: flex;
273
- flex-direction: column;
274
- justify-content: flex-end;
275
- position: relative;
276
- border-radius: 4px 4px 0 0;
277
- overflow: hidden;
278
- background: var(--color-surface-alt);
352
+ .usage-daydetail-date {
353
+ font-weight: 600;
354
+ font-size: 14px;
355
+ color: var(--color-text-primary);
279
356
  }
280
357
 
281
- .usage-daily-bar-fill {
282
- width: 100%;
283
- border-radius: 4px 4px 0 0;
284
- background: var(--color-brand);
285
- transition: height 200ms var(--ease-spring);
286
- min-height: 2px;
358
+ .usage-daydetail-stats {
359
+ font-size: 12px;
360
+ color: var(--color-text-secondary);
287
361
  }
288
362
 
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;
363
+ .usage-daydetail-compare {
364
+ margin-top: 6px;
365
+ font-size: 11px;
366
+ color: var(--color-text-muted);
294
367
  }
295
368
 
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);
369
+ /* ---- 热力图 (动态呼吸) ---- */
370
+ .usage-card-hourly-heatmap {
371
+ overflow-x: auto;
372
+ border: none;
373
+ background: transparent;
374
+ padding: 0;
299
375
  }
300
376
 
301
- .usage-daily-bar-group:hover .usage-daily-bar-fill {
302
- filter: brightness(1.1);
377
+ .hourly-heatmap-wrapper {
378
+ display: flex;
379
+ flex-direction: column;
380
+ gap: 3px;
381
+ margin-top: 14px;
382
+ min-width: 500px;
383
+ padding: 16px;
384
+ border-radius: 18px;
385
+ background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
386
+ border: 1px solid rgba(137, 111, 94, 0.06);
387
+ box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
388
+ backdrop-filter: blur(8px);
303
389
  }
304
390
 
305
- .usage-daily-bar-label {
306
- font-size: 10px;
307
- color: var(--color-text-muted);
308
- text-align: center;
309
- white-space: nowrap;
310
- overflow: hidden;
311
- text-overflow: ellipsis;
312
- max-width: 100%;
391
+ .hourly-heatmap-header {
392
+ display: flex;
393
+ gap: 3px;
394
+ align-items: flex-end;
313
395
  }
314
396
 
315
- .usage-daily-bar-group.active .usage-daily-bar-label {
316
- color: var(--color-brand-dark);
317
- font-weight: 700;
397
+ .hourly-heatmap-corner {
398
+ width: 36px;
399
+ flex-shrink: 0;
318
400
  }
319
401
 
320
- /* ---- Daily legend ---- */
321
- .usage-daily-legend {
322
- display: flex;
323
- gap: 16px;
324
- margin-top: 10px;
325
- font-size: 11px;
402
+ .hourly-heatmap-hour-label {
403
+ flex: 1;
404
+ min-width: 0;
405
+ font-size: 9px;
326
406
  color: var(--color-text-muted);
407
+ text-align: center;
408
+ line-height: 14px;
327
409
  }
328
410
 
329
- .usage-daily-legend-item {
330
- display: inline-flex;
411
+ .hourly-heatmap-row {
412
+ display: flex;
413
+ gap: 3px;
331
414
  align-items: center;
332
- gap: 5px;
333
415
  }
334
416
 
335
- .usage-daily-legend-swatch {
336
- width: 10px;
337
- height: 10px;
338
- border-radius: 2px;
417
+ .hourly-heatmap-weekday-label {
418
+ width: 36px;
419
+ flex-shrink: 0;
420
+ font-size: 11px;
421
+ color: var(--color-text-secondary);
422
+ text-align: right;
423
+ padding-right: 6px;
424
+ font-weight: 500;
339
425
  }
340
426
 
341
- .usage-daily-legend-swatch.current {
342
- background: var(--color-brand);
427
+ .hourly-heatmap-cell {
428
+ flex: 1;
429
+ min-width: 0;
430
+ height: 7px;
431
+ border-radius: 4px;
432
+ transition: all 200ms var(--ease-spring);
433
+ cursor: crosshair;
343
434
  }
344
435
 
345
- .usage-daily-legend-swatch.prev {
346
- background: var(--color-text-muted);
347
- opacity: 0.35;
436
+ .hourly-heatmap-cell:hover {
437
+ transform: scaleY(1.4);
438
+ filter: brightness(1.1);
348
439
  }
349
440
 
350
- /* ---- Day detail ---- */
351
- .usage-daydetail {
352
- margin-top: 12px;
353
- padding: 10px 14px;
354
- border-radius: var(--radius-sm);
441
+ .hourly-heatmap-cell.level-0 {
355
442
  background: var(--color-surface-alt);
356
443
  }
444
+ .hourly-heatmap-cell.level-1 {
445
+ background: var(--color-heatmap-1);
446
+ animation: heatmap-breath-1 3s ease-in-out infinite;
447
+ }
448
+ .hourly-heatmap-cell.level-2 {
449
+ background: var(--color-heatmap-2);
450
+ animation: heatmap-breath-2 3s ease-in-out infinite;
451
+ }
452
+ .hourly-heatmap-cell.level-3 {
453
+ background: var(--color-heatmap-3);
454
+ animation: heatmap-breath-3 3s ease-in-out infinite;
455
+ }
456
+ .hourly-heatmap-cell.level-4 {
457
+ background: var(--color-heatmap-4);
458
+ animation: heatmap-breath-4 3s ease-in-out infinite;
459
+ box-shadow: 0 0 8px rgba(200, 121, 99, 0.3);
460
+ }
357
461
 
358
- .usage-daydetail-header {
462
+ @keyframes heatmap-breath-1 {
463
+ 0%, 100% { opacity: 1; }
464
+ 50% { opacity: 0.85; }
465
+ }
466
+ @keyframes heatmap-breath-2 {
467
+ 0%, 100% { opacity: 1; }
468
+ 50% { opacity: 0.9; }
469
+ }
470
+ @keyframes heatmap-breath-3 {
471
+ 0%, 100% { opacity: 1; }
472
+ 50% { opacity: 0.95; }
473
+ }
474
+ @keyframes heatmap-breath-4 {
475
+ 0%, 100% { opacity: 1; box-shadow: 0 0 8px rgba(200, 121, 99, 0.3); }
476
+ 50% { opacity: 0.9; box-shadow: 0 0 14px rgba(200, 121, 99, 0.5); }
477
+ }
478
+
479
+ .hourly-heatmap-legend {
359
480
  display: flex;
360
- justify-content: space-between;
361
481
  align-items: center;
362
- flex-wrap: wrap;
363
- gap: 8px;
482
+ gap: 4px;
483
+ justify-content: flex-end;
484
+ margin-top: 12px;
485
+ font-size: 10px;
486
+ color: var(--color-text-muted);
364
487
  }
365
488
 
366
- .usage-daydetail-date {
367
- font-weight: 700;
368
- font-size: 13px;
369
- color: var(--color-text-primary);
489
+ .hourly-heatmap-legend .hourly-heatmap-cell {
490
+ width: 12px;
491
+ height: 12px;
492
+ border-radius: 3px;
370
493
  }
371
494
 
372
- .usage-daydetail-stats {
373
- font-size: 12px;
374
- color: var(--color-text-secondary);
495
+ .hourly-heatmap-legend-label {
496
+ margin: 0 4px;
375
497
  }
376
498
 
377
- .usage-daydetail-compare {
378
- margin-top: 4px;
379
- font-size: 11px;
380
- color: var(--color-text-muted);
499
+ /* ---- 列表样式 (加大间距) ---- */
500
+ .usage-list-compact {
501
+ display: flex;
502
+ flex-direction: column;
503
+ gap: 6px;
381
504
  }
382
505
 
383
- /* ---- Lists ---- */
384
- .usage-list {
506
+ .usage-list-compact-item {
385
507
  display: flex;
386
- flex-direction: column;
387
- gap: 8px;
508
+ align-items: flex-start;
509
+ gap: 10px;
510
+ padding: 10px 14px;
511
+ border-radius: 10px;
512
+ cursor: pointer;
513
+ transition: all 180ms var(--ease-spring);
514
+ -webkit-tap-highlight-color: transparent;
388
515
  }
389
516
 
390
- .usage-list-row {
391
- display: grid;
392
- grid-template-columns: 1fr auto;
393
- align-items: center;
394
- gap: 8px 12px;
395
- padding: 8px 10px;
396
- border-radius: var(--radius-sm);
397
- background: var(--color-surface-alt);
398
- transition: background 120ms var(--ease-spring);
517
+ .usage-list-compact-item:hover {
518
+ background: linear-gradient(135deg, rgba(255,255,255,0.9), rgba(252,248,241,0.7));
519
+ transform: translateX(4px);
520
+ box-shadow: 0 2px 8px rgba(92, 68, 52, 0.06);
399
521
  }
400
522
 
401
- .usage-list-row:hover {
402
- background: var(--color-surface-elevated);
523
+ .usage-list-compact-item:active {
524
+ transform: translateX(2px) scale(0.98);
403
525
  }
404
526
 
405
- .usage-list-title {
406
- font-size: 12px;
407
- font-weight: 600;
408
- color: var(--color-text-primary);
409
- overflow: hidden;
410
- text-overflow: ellipsis;
411
- white-space: nowrap;
527
+ .usage-list-bullet {
528
+ color: var(--color-brand);
529
+ font-size: 16px;
530
+ line-height: 1.4;
531
+ flex-shrink: 0;
532
+ opacity: 0.7;
412
533
  }
413
534
 
414
- .usage-list-path {
415
- font-size: 12px;
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;
535
+ .usage-list-compact-item:hover .usage-list-bullet {
536
+ opacity: 1;
537
+ }
538
+
539
+ .usage-list-compact-content {
540
+ flex: 1;
541
+ min-width: 0;
422
542
  }
423
543
 
424
- .usage-list-stat {
544
+ .usage-list-title {
425
545
  font-size: 13px;
426
- font-weight: 700;
546
+ font-weight: 500;
427
547
  color: var(--color-text-primary);
428
- font-variant-numeric: tabular-nums;
429
- text-align: right;
548
+ overflow: hidden;
549
+ text-overflow: ellipsis;
550
+ white-space: nowrap;
430
551
  }
431
552
 
432
553
  .usage-list-meta {
433
- grid-column: 1 / -1;
434
554
  font-size: 11px;
435
555
  color: var(--color-text-muted);
556
+ margin-top: 3px;
436
557
  }
437
558
 
438
559
  .usage-list-value {
439
- font-size: 12px;
560
+ font-size: 13px;
440
561
  color: var(--color-text-secondary);
441
- padding: 8px 0;
562
+ padding: 10px 0;
442
563
  }
443
564
 
444
- .usage-progress {
445
- height: 3px;
446
- border-radius: 2px;
447
- background: var(--color-surface-alt);
448
- overflow: hidden;
449
- }
450
-
451
- .usage-progress-fill {
452
- height: 100%;
453
- border-radius: 2px;
454
- background: var(--color-brand);
455
- transition: width 300ms var(--ease-spring);
456
- }
457
-
458
- /* ---- Hourly heatmap ---- */
459
- .usage-card-hourly-heatmap {
460
- overflow-x: auto;
565
+ /* ---- Path 列表 ---- */
566
+ .usage-paths-section {
567
+ grid-column: 1 / -1;
568
+ border: none;
569
+ background: transparent;
570
+ padding: 0;
461
571
  }
462
572
 
463
- .hourly-heatmap-wrapper {
573
+ .usage-list-paths {
464
574
  display: flex;
465
575
  flex-direction: column;
466
- gap: 2px;
467
- margin-top: 10px;
468
- min-width: 480px;
576
+ gap: 8px;
577
+ padding: 16px;
578
+ border-radius: 18px;
579
+ background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
580
+ border: 1px solid rgba(137, 111, 94, 0.06);
581
+ box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
582
+ backdrop-filter: blur(8px);
469
583
  }
470
584
 
471
- .hourly-heatmap-header {
585
+ .usage-list-path-row {
472
586
  display: flex;
473
- gap: 2px;
474
- align-items: flex-end;
587
+ align-items: center;
588
+ gap: 12px;
589
+ padding: 10px 12px;
590
+ border-radius: 10px;
591
+ transition: all 180ms var(--ease-spring);
475
592
  }
476
593
 
477
- .hourly-heatmap-corner {
478
- width: 32px;
594
+ .usage-list-path-row:hover {
595
+ background: rgba(255, 255, 255, 0.7);
596
+ transform: translateX(4px);
597
+ }
598
+
599
+ .usage-list-path-rank {
600
+ width: 22px;
601
+ height: 22px;
602
+ display: flex;
603
+ align-items: center;
604
+ justify-content: center;
605
+ font-size: 11px;
606
+ font-weight: 600;
607
+ color: var(--color-brand);
608
+ background: linear-gradient(135deg, rgba(200, 121, 99, 0.12), rgba(200, 121, 99, 0.06));
609
+ border-radius: 6px;
479
610
  flex-shrink: 0;
480
611
  }
481
612
 
482
- .hourly-heatmap-hour-label {
613
+ .usage-list-path-content {
483
614
  flex: 1;
615
+ display: flex;
616
+ justify-content: space-between;
617
+ align-items: center;
618
+ gap: 12px;
484
619
  min-width: 0;
485
- font-size: 9px;
486
- color: var(--color-text-muted);
487
- text-align: center;
488
- line-height: 14px;
489
620
  }
490
621
 
491
- .hourly-heatmap-row {
492
- display: flex;
493
- gap: 2px;
494
- align-items: center;
622
+ .usage-list-path {
623
+ font-size: 12px;
624
+ color: var(--color-text-secondary);
625
+ font-family: var(--font-family-mono);
626
+ overflow: hidden;
627
+ text-overflow: ellipsis;
628
+ white-space: nowrap;
495
629
  }
496
630
 
497
- .hourly-heatmap-weekday-label {
498
- width: 32px;
631
+ .usage-list-path-stat {
632
+ font-size: 14px;
633
+ font-weight: 600;
634
+ color: var(--color-text-primary);
635
+ font-variant-numeric: tabular-nums;
499
636
  flex-shrink: 0;
500
- font-size: 10px;
501
- color: var(--color-text-secondary);
502
- text-align: right;
503
- padding-right: 4px;
504
637
  }
505
638
 
506
- .hourly-heatmap-cell {
507
- flex: 1;
508
- min-width: 0;
509
- aspect-ratio: 1;
510
- border-radius: 3px;
639
+ /* ---- 卡片 (无边框浮动式) ---- */
640
+ .usage-card {
641
+ padding: 0;
642
+ border-radius: 0;
643
+ background: transparent;
644
+ border: none;
645
+ margin-bottom: 0;
511
646
  }
512
647
 
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); }
648
+ .usage-card-title {
649
+ font-size: 15px;
650
+ font-weight: 600;
651
+ color: var(--color-text-primary);
652
+ margin-bottom: 0;
653
+ letter-spacing: -0.02em;
654
+ }
518
655
 
519
- .hourly-heatmap-legend {
520
- display: flex;
521
- align-items: center;
522
- gap: 3px;
523
- justify-content: flex-end;
524
- margin-top: 8px;
525
- font-size: 10px;
526
- color: var(--color-text-muted);
656
+ /* ---- 图表网格 (加大间距) ---- */
657
+ .usage-chart-grid {
658
+ display: grid;
659
+ grid-template-columns: repeat(2, 1fr);
660
+ gap: 20px;
527
661
  }
528
662
 
529
- .hourly-heatmap-legend .hourly-heatmap-cell {
530
- width: 11px;
531
- height: 11px;
532
- aspect-ratio: auto;
663
+ /* 为非 paths 卡片添加容器 */
664
+ .usage-chart-grid > .usage-card:not(.usage-paths-section):not(.usage-wave-section):not(.usage-card-hourly-heatmap) {
665
+ padding: 16px;
666
+ border-radius: 18px;
667
+ background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(252,248,241,0.6));
668
+ border: 1px solid rgba(137, 111, 94, 0.06);
669
+ box-shadow: 0 4px 20px rgba(92, 68, 52, 0.05);
670
+ backdrop-filter: blur(8px);
533
671
  }
534
672
 
535
- .hourly-heatmap-legend-label {
536
- margin: 0 2px;
673
+ /* ---- 内容区域 ---- */
674
+ .usage-content {
675
+ position: relative;
537
676
  }
538
677
 
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;
678
+ .usage-content-loading {
679
+ opacity: 0.6;
680
+ pointer-events: none;
681
+ }
682
+
683
+ .usage-content-overlay {
684
+ position: absolute;
685
+ inset: 0;
686
+ display: flex;
687
+ align-items: flex-start;
688
+ justify-content: flex-end;
689
+ padding: 16px;
690
+ z-index: 10;
691
+ }
692
+
693
+ .usage-spinner {
694
+ width: 18px;
695
+ height: 18px;
696
+ border-radius: 50%;
697
+ border: 2px solid rgba(137, 111, 94, 0.15);
698
+ border-top-color: var(--color-brand);
699
+ animation: usage-spin 0.8s linear infinite;
700
+ }
701
+
702
+ @keyframes usage-spin {
703
+ to { transform: rotate(360deg); }
548
704
  }
549
705
 
550
- /* ---- Responsive ---- */
706
+ /* ---- 响应式 ---- */
551
707
  @media (max-width: 960px) {
552
708
  .usage-chart-grid {
553
709
  grid-template-columns: 1fr;
554
710
  }
555
711
 
556
- .usage-summary-grid {
557
- grid-template-columns: repeat(2, 1fr);
712
+ .usage-hero-main {
713
+ font-size: 44px;
558
714
  }
559
715
  }
560
716
 
@@ -569,20 +725,29 @@
569
725
  flex-wrap: wrap;
570
726
  }
571
727
 
572
- .usage-summary-grid {
573
- grid-template-columns: repeat(2, 1fr);
728
+ .usage-hero {
729
+ padding: 24px 20px;
730
+ min-height: 140px;
731
+ }
732
+
733
+ .usage-hero-main {
734
+ font-size: 38px;
574
735
  }
575
736
 
576
- .usage-summary-card-value {
577
- font-size: 22px;
737
+ .usage-wave-chart {
738
+ height: 110px;
578
739
  }
579
740
 
580
- .usage-daily-chart {
581
- height: 100px;
741
+ .usage-wave-labels {
742
+ font-size: 10px;
582
743
  }
583
744
 
584
- .usage-daily-bar-stack {
585
- max-width: 24px;
586
- height: 70px;
745
+ .hourly-heatmap-wrapper {
746
+ min-width: 100%;
747
+ overflow-x: auto;
748
+ }
749
+
750
+ .usage-chart-grid {
751
+ gap: 16px;
587
752
  }
588
753
  }