token-larper 1.0.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.
Files changed (42) hide show
  1. package/README.md +334 -0
  2. package/Start-TokenLarper.vbs +5 -0
  3. package/bin/cli.js +34 -0
  4. package/llms.txt +59 -0
  5. package/package.json +61 -0
  6. package/scripts/docs-demo-server.ts +141 -0
  7. package/scripts/launch-on-default-desktop.ps1 +42 -0
  8. package/scripts/launch-silent.vbs +6 -0
  9. package/scripts/run-server.ps1 +59 -0
  10. package/scripts/tray-host.ps1 +181 -0
  11. package/src/ccusage.ts +1075 -0
  12. package/src/client/App.tsx +560 -0
  13. package/src/client/charts.tsx +341 -0
  14. package/src/client/components/Calendar.tsx +207 -0
  15. package/src/client/components/DateRangePicker.tsx +131 -0
  16. package/src/client/components/KpiCards.tsx +122 -0
  17. package/src/client/components/RankChip.tsx +22 -0
  18. package/src/client/components/SelectMenu.tsx +116 -0
  19. package/src/client/components/SettingsDialog.tsx +207 -0
  20. package/src/client/components/ThemeSettings.tsx +131 -0
  21. package/src/client/context.tsx +60 -0
  22. package/src/client/index.html +54 -0
  23. package/src/client/lib/aggregate.ts +266 -0
  24. package/src/client/lib/range.ts +87 -0
  25. package/src/client/lib/rank.ts +323 -0
  26. package/src/client/lib/shareCard.ts +139 -0
  27. package/src/client/logo.svg +8 -0
  28. package/src/client/main.tsx +12 -0
  29. package/src/client/styles.css +1113 -0
  30. package/src/client/themes.ts +268 -0
  31. package/src/client/utils.ts +61 -0
  32. package/src/client/views/Models.tsx +71 -0
  33. package/src/client/views/Overview.tsx +280 -0
  34. package/src/client/views/Projects.tsx +88 -0
  35. package/src/client/views/Rank.tsx +255 -0
  36. package/src/client/views/Sessions.tsx +108 -0
  37. package/src/client/views/Tools.tsx +114 -0
  38. package/src/projects.ts +214 -0
  39. package/src/server.ts +173 -0
  40. package/src/startup.ts +110 -0
  41. package/src/tray.ts +293 -0
  42. package/src/types.ts +155 -0
@@ -0,0 +1,1113 @@
1
+ /* Token Larper: one theme, defined by tokens. Light is the default; dark swaps the
2
+ tokens on html[data-theme="dark"] (set before first paint by index.html). */
3
+
4
+ :root {
5
+ color-scheme: light;
6
+ --bg: #f7f8f6;
7
+ --surface: #ffffff;
8
+ --surface-2: #f2f5f1;
9
+ --surface-3: #e8eee7;
10
+ --border: #e1e6de;
11
+ --border-strong: #c7d1c5;
12
+ --text: #1f2a23;
13
+ --text-2: #4b5950;
14
+ --text-3: #5f6d64;
15
+ --accent: #2f5a43;
16
+ --accent-ink: #ffffff;
17
+ --accent-soft: #e5eee6;
18
+ --gold: #a5761c;
19
+ --focus: #2f5a43;
20
+ --shadow-pop: 0 12px 36px rgb(20 34 26 / 16%);
21
+ --warning-bg: #fff5e2;
22
+ --warning-border: #ebc47a;
23
+ --warning-text: #6f4600;
24
+ --error-bg: #fff1ef;
25
+ --error-border: #e6b8ae;
26
+ --error-text: #8d3227;
27
+
28
+ /* Validated categorical slots (color-blind separation checked in this order). */
29
+ --series-1: #2a78d6;
30
+ --series-2: #eb6834;
31
+ --series-3: #1baf7a;
32
+ --series-4: #eda100;
33
+ --series-5: #e87ba4;
34
+ --series-6: #008300;
35
+ --series-7: #4a3aa7;
36
+ --series-other: #a3a29a;
37
+ /* One-hue ramp for the activity calendar. */
38
+ --heat-0: #edf1eb;
39
+ --heat-1: #c6dcc9;
40
+ --heat-2: #8dbb97;
41
+ --heat-3: #4d8a5e;
42
+ --heat-4: #24563a;
43
+
44
+ --font: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, sans-serif;
45
+ --mono: "Cascadia Code", "Cascadia Mono", Consolas, ui-monospace, monospace;
46
+ --radius: 10px;
47
+ --radius-sm: 6px;
48
+ }
49
+
50
+ html[data-theme="dark"] {
51
+ color-scheme: dark;
52
+ --bg: #141916;
53
+ --surface: #1b221e;
54
+ --surface-2: #222b25;
55
+ --surface-3: #2b362f;
56
+ --border: #2e3932;
57
+ --border-strong: #45524a;
58
+ --text: #e8eee7;
59
+ --text-2: #b5c1b7;
60
+ --text-3: #98a59b;
61
+ --accent: #9fcaa8;
62
+ --accent-ink: #11261a;
63
+ --accent-soft: #24392b;
64
+ --gold: #e1b75c;
65
+ --focus: #b5dcbd;
66
+ --shadow-pop: 0 14px 40px rgb(0 0 0 / 45%);
67
+ --warning-bg: #3a2f1b;
68
+ --warning-border: #7a5d25;
69
+ --warning-text: #f4d08e;
70
+ --error-bg: #3c2926;
71
+ --error-border: #915c53;
72
+ --error-text: #ffc4b8;
73
+
74
+ --series-1: #3987e5;
75
+ --series-2: #d95926;
76
+ --series-3: #199e70;
77
+ --series-4: #c98500;
78
+ --series-5: #d55181;
79
+ --series-6: #008300;
80
+ --series-7: #9085e9;
81
+ --series-other: #72716b;
82
+ --heat-0: #252e28;
83
+ --heat-1: #2d4a35;
84
+ --heat-2: #3f714d;
85
+ --heat-3: #62a172;
86
+ --heat-4: #a6d8b0;
87
+ }
88
+
89
+ html[data-palette] {
90
+ --heat-0: color-mix(in srgb, var(--bg) 97%, var(--accent));
91
+ --heat-1: color-mix(in srgb, var(--bg) 84%, var(--accent));
92
+ --heat-2: color-mix(in srgb, var(--bg) 65%, var(--accent));
93
+ --heat-3: color-mix(in srgb, var(--bg) 42%, var(--accent));
94
+ --heat-4: color-mix(in srgb, var(--bg) 18%, var(--accent));
95
+ }
96
+
97
+ html[data-palette="slate"] {
98
+ color-scheme: light;
99
+ --bg: #f5f6f8; --surface: #fff; --surface-2: #eef1f4; --surface-3: #e5e9ee;
100
+ --border: #dce1e7; --border-strong: #c1cad5; --text: #202833; --text-2: #4c5967; --text-3: #667381;
101
+ --accent: #495d75; --accent-ink: #fff; --accent-soft: #e6edf4; --focus: #536b89;
102
+ }
103
+ html[data-palette="slate"][data-theme="dark"] {
104
+ color-scheme: dark;
105
+ --bg: #14181d; --surface: #1b2128; --surface-2: #232b34; --surface-3: #2c3641;
106
+ --border: #303a45; --border-strong: #46525f; --text: #e8edf3; --text-2: #bbc5d0; --text-3: #9da8b4;
107
+ --accent: #9bb4d2; --accent-ink: #111a24; --accent-soft: #2a3747; --focus: #bfd4eb;
108
+ }
109
+
110
+ html[data-palette="ocean"] {
111
+ color-scheme: light;
112
+ --bg: #f3f8fb; --surface: #fff; --surface-2: #eaf2f6; --surface-3: #dce9ef;
113
+ --border: #d4e1e8; --border-strong: #b5cbd6; --text: #18303a; --text-2: #41616e; --text-3: #5d7782;
114
+ --accent: #17627a; --accent-ink: #fff; --accent-soft: #deedf2; --focus: #19718d;
115
+ }
116
+ html[data-palette="ocean"][data-theme="dark"] {
117
+ color-scheme: dark;
118
+ --bg: #111a20; --surface: #17232a; --surface-2: #202f37; --surface-3: #293b44;
119
+ --border: #2a3a43; --border-strong: #405761; --text: #e5f0f3; --text-2: #b0c8d0; --text-3: #91adb7;
120
+ --accent: #78c5d8; --accent-ink: #10232a; --accent-soft: #203d47; --focus: #a5ddeb;
121
+ }
122
+
123
+ html[data-palette="iris"] {
124
+ color-scheme: light;
125
+ --bg: #f7f5fb; --surface: #fff; --surface-2: #f0edf6; --surface-3: #e7e1f0;
126
+ --border: #e0d9eb; --border-strong: #c9bddb; --text: #2c2438; --text-2: #5d526d; --text-3: #756a85;
127
+ --accent: #68518f; --accent-ink: #fff; --accent-soft: #ebe5f4; --focus: #765ba2;
128
+ }
129
+ html[data-palette="iris"][data-theme="dark"] {
130
+ color-scheme: dark;
131
+ --bg: #171420; --surface: #201b2b; --surface-2: #2a2437; --surface-3: #352d44;
132
+ --border: #393148; --border-strong: #53476a; --text: #f0eaf8; --text-2: #c7bad8; --text-3: #aa9bbf;
133
+ --accent: #c0a4ec; --accent-ink: #21172f; --accent-soft: #352845; --focus: #d4c2f2;
134
+ }
135
+
136
+ html[data-palette="clay"] {
137
+ color-scheme: light;
138
+ --bg: #faf5f0; --surface: #fff; --surface-2: #f4ece4; --surface-3: #ebdfd3;
139
+ --border: #e7d9ca; --border-strong: #ceb9a5; --text: #34271f; --text-2: #665246; --text-3: #806a5d;
140
+ --accent: #995431; --accent-ink: #fff; --accent-soft: #f2e4d8; --focus: #a55e37;
141
+ }
142
+ html[data-palette="clay"][data-theme="dark"] {
143
+ color-scheme: dark;
144
+ --bg: #1c1713; --surface: #261e19; --surface-2: #312720; --surface-3: #3b3027;
145
+ --border: #403329; --border-strong: #5a4739; --text: #f2e9e1; --text-2: #cdb9a8; --text-3: #b09a87;
146
+ --accent: #e1a177; --accent-ink: #2d1b11; --accent-soft: #3b2a20; --focus: #efbd9b;
147
+ }
148
+
149
+ html[data-palette="rose"] {
150
+ color-scheme: light;
151
+ --bg: #fbf5f7; --surface: #fff; --surface-2: #f5edf0; --surface-3: #eddee5;
152
+ --border: #e8d8e0; --border-strong: #d1b9c4; --text: #35242c; --text-2: #664d58; --text-3: #816976;
153
+ --accent: #934f67; --accent-ink: #fff; --accent-soft: #f3e5eb; --focus: #a65875;
154
+ }
155
+ html[data-palette="rose"][data-theme="dark"] {
156
+ color-scheme: dark;
157
+ --bg: #1e151a; --surface: #281c22; --surface-2: #35252d; --surface-3: #402d37;
158
+ --border: #45303a; --border-strong: #604450; --text: #f4e9ee; --text-2: #d0b8c2; --text-3: #b499a5;
159
+ --accent: #dfa1b4; --accent-ink: #301a22; --accent-soft: #402a34; --focus: #efbdcc;
160
+ }
161
+
162
+ /* ---------- Base ---------- */
163
+
164
+ *,
165
+ *::before,
166
+ *::after { box-sizing: border-box; }
167
+
168
+ * { margin: 0; padding: 0; }
169
+
170
+ html { background: var(--bg); }
171
+
172
+ body {
173
+ min-height: 100vh;
174
+ background: var(--bg);
175
+ color: var(--text);
176
+ font: 14px/1.45 var(--font);
177
+ -webkit-font-smoothing: antialiased;
178
+ }
179
+
180
+ button, input, select { font: inherit; color: inherit; }
181
+ button { cursor: pointer; background: none; border: 0; }
182
+ button:disabled { cursor: default; opacity: 0.55; }
183
+ code { font-family: var(--mono); font-size: 0.92em; }
184
+ img { display: block; }
185
+ :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
186
+
187
+ .sr-only {
188
+ position: absolute;
189
+ width: 1px;
190
+ height: 1px;
191
+ overflow: hidden;
192
+ clip: rect(0 0 0 0);
193
+ white-space: nowrap;
194
+ }
195
+
196
+ .muted { color: var(--text-3); }
197
+ .nowrap { white-space: nowrap; }
198
+ .strong { font-weight: 650; }
199
+ .spin { animation: spin 1s linear infinite; }
200
+ @keyframes spin { to { transform: rotate(360deg); } }
201
+
202
+ /* ---------- Shell ---------- */
203
+
204
+ .app {
205
+ max-width: 1240px;
206
+ margin: 0 auto;
207
+ padding: 0 32px 72px;
208
+ }
209
+
210
+ .topbar {
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: space-between;
214
+ gap: 16px;
215
+ margin: 0 -32px;
216
+ padding: 14px 32px;
217
+ border-bottom: 1px solid var(--border);
218
+ }
219
+
220
+ .brand { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
221
+ .brand-logo { width: 32px; height: 32px; }
222
+ .brand h1 { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
223
+
224
+ .topbar-actions { display: flex; align-items: center; gap: 8px; }
225
+ .updated { color: var(--text-3); font-size: 12px; margin-right: 4px; white-space: nowrap; }
226
+
227
+ .pill {
228
+ display: inline-flex;
229
+ align-items: center;
230
+ gap: 6px;
231
+ padding: 2px 10px;
232
+ border-radius: 999px;
233
+ background: var(--accent-soft);
234
+ color: var(--text-2);
235
+ font-size: 11.5px;
236
+ font-weight: 600;
237
+ }
238
+ .pill-warning { background: var(--warning-bg); color: var(--warning-text); border: 1px solid var(--warning-border); }
239
+
240
+ .btn {
241
+ display: inline-flex;
242
+ align-items: center;
243
+ justify-content: center;
244
+ gap: 7px;
245
+ min-height: 34px;
246
+ padding: 0 12px;
247
+ border: 1px solid var(--border-strong);
248
+ border-radius: var(--radius-sm);
249
+ background: var(--surface);
250
+ color: var(--text);
251
+ font-size: 13px;
252
+ font-weight: 600;
253
+ white-space: nowrap;
254
+ }
255
+ .btn:hover:not(:disabled) { background: var(--surface-2); }
256
+ .btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
257
+ .btn-primary:hover:not(:disabled) { background: var(--accent); filter: brightness(1.08); }
258
+
259
+ .icon-btn {
260
+ display: inline-grid;
261
+ place-items: center;
262
+ width: 34px;
263
+ height: 34px;
264
+ border: 1px solid var(--border-strong);
265
+ border-radius: var(--radius-sm);
266
+ background: var(--surface);
267
+ color: var(--text-2);
268
+ }
269
+ .icon-btn:hover { background: var(--surface-2); color: var(--text); }
270
+
271
+ .tabs {
272
+ display: flex;
273
+ gap: 24px;
274
+ border-bottom: 1px solid var(--border);
275
+ overflow-x: auto;
276
+ scrollbar-width: none;
277
+ }
278
+ .tabs::-webkit-scrollbar { display: none; }
279
+ .tab {
280
+ flex: 0 0 auto;
281
+ min-height: 42px;
282
+ color: var(--text-3);
283
+ font-size: 13px;
284
+ font-weight: 600;
285
+ box-shadow: inset 0 -2px transparent;
286
+ }
287
+ .tab:hover { color: var(--text); }
288
+ .tab[aria-current="page"] { color: var(--text); box-shadow: inset 0 -2px var(--accent); }
289
+
290
+ .intro {
291
+ display: flex;
292
+ align-items: flex-end;
293
+ justify-content: space-between;
294
+ gap: 24px;
295
+ padding: 28px 0 20px;
296
+ }
297
+ .eyebrow { color: var(--accent); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
298
+ .intro h2 { margin: 6px 0 4px; font-size: clamp(26px, 3vw, 32px); font-weight: 700; letter-spacing: -0.03em; line-height: 1.15; }
299
+ .intro p { color: var(--text-2); }
300
+
301
+ .inline-error {
302
+ margin-bottom: 14px;
303
+ padding: 10px 12px;
304
+ border: 1px solid var(--error-border);
305
+ border-radius: var(--radius-sm);
306
+ background: var(--error-bg);
307
+ color: var(--error-text);
308
+ font-size: 13px;
309
+ }
310
+
311
+ /* ---------- Filters ---------- */
312
+
313
+ .filters {
314
+ position: sticky;
315
+ top: 0;
316
+ z-index: 20;
317
+ display: flex;
318
+ align-items: flex-end;
319
+ flex-wrap: wrap;
320
+ gap: 10px;
321
+ margin: 0 -32px 20px;
322
+ padding: 10px 32px 12px;
323
+ background: color-mix(in srgb, var(--bg) 92%, transparent);
324
+ backdrop-filter: blur(8px);
325
+ border-bottom: 1px solid var(--border);
326
+ }
327
+
328
+ .field { display: flex; flex-direction: column; gap: 5px; }
329
+ .field-label { color: var(--text-2); font-size: 11.5px; font-weight: 600; }
330
+ .select-menu-trigger,
331
+ .cost-segmented,
332
+ .range-trigger,
333
+ .search {
334
+ height: 38px;
335
+ border: 1px solid var(--border-strong);
336
+ border-radius: var(--radius-sm);
337
+ background: var(--surface);
338
+ color: var(--text);
339
+ font-size: 13px;
340
+ }
341
+ .select-menu { position: relative; display: flex; flex-direction: column; gap: 5px; min-width: 150px; }
342
+ .select-menu-trigger { display: flex; align-items: center; gap: 9px; min-width: 150px; padding: 0 10px; text-align: left; }
343
+ .select-menu-trigger:hover, .range-trigger:hover { border-color: var(--text-3); }
344
+ .select-menu-copy { display: flex; flex: 1; flex-direction: column; min-width: 0; }
345
+ .select-menu-copy strong { overflow: hidden; font-size: 12.5px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
346
+ .select-menu-copy small { overflow: hidden; color: var(--text-3); font-size: 11.5px; text-overflow: ellipsis; white-space: nowrap; }
347
+ .select-menu-chevron { flex: 0 0 auto; color: var(--text-2); transition: transform 0.18s ease; }
348
+ .select-menu-trigger[aria-expanded="true"] .select-menu-chevron { transform: rotate(180deg); }
349
+ .select-menu-list {
350
+ position: absolute;
351
+ top: calc(100% + 5px);
352
+ left: 0;
353
+ z-index: 50;
354
+ width: max(100%, 220px);
355
+ max-height: min(360px, calc(100dvh - 200px));
356
+ padding: 5px;
357
+ overflow-y: auto;
358
+ border: 1px solid var(--border-strong);
359
+ border-radius: var(--radius-sm);
360
+ background: var(--surface);
361
+ box-shadow: var(--shadow-pop);
362
+ }
363
+ .select-menu-option { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 38px; padding: 7px 9px; border-radius: 4px; text-align: left; }
364
+ .select-menu-option:hover, .select-menu-option:focus-visible { background: var(--surface-2); }
365
+ .select-menu-option[aria-selected="true"] { background: var(--accent-soft); }
366
+ .select-menu-check { flex: 0 0 auto; margin-left: auto; color: var(--accent); }
367
+ .tool-filter-dot { width: 10px; height: 10px; flex: 0 0 10px; border-radius: 3px; background: var(--accent); }
368
+ .tool-filter-dot.is-all { background: linear-gradient(135deg, var(--series-1) 0 33%, var(--series-2) 33% 66%, var(--series-3) 66%); }
369
+ .cost-segmented { display: flex; align-items: center; gap: 2px; padding: 2px; }
370
+ .cost-segmented button { height: 32px; padding: 0 10px; border-radius: 4px; color: var(--text-2); font-size: 12px; font-weight: 600; white-space: nowrap; }
371
+ .cost-segmented button:hover { color: var(--text); }
372
+ .cost-segmented button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }
373
+ .field-search { margin-left: auto; }
374
+ .search { display: flex; align-items: center; gap: 8px; min-width: 240px; padding: 0 10px; color: var(--text-3); }
375
+ .search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text); }
376
+ .search:focus-within { outline: 2px solid var(--focus); outline-offset: 1px; }
377
+
378
+ .range-picker { position: relative; display: flex; flex-direction: column; gap: 5px; }
379
+ .range-trigger {
380
+ display: flex;
381
+ align-items: center;
382
+ gap: 9px;
383
+ min-width: 230px;
384
+ padding: 0 10px 0 11px;
385
+ text-align: left;
386
+ color: var(--text-2);
387
+ }
388
+ .range-value {
389
+ display: flex;
390
+ align-items: baseline;
391
+ gap: 8px;
392
+ white-space: nowrap;
393
+ color: var(--text);
394
+ flex: 1;
395
+ min-width: 0;
396
+ }
397
+ .range-value strong { font-weight: 650; }
398
+ .range-subspan { color: var(--text-3); font-size: 12.5px; }
399
+ .range-chevron {
400
+ flex: 0 0 auto;
401
+ margin-left: auto;
402
+ color: var(--text-2);
403
+ transition: transform 0.18s ease;
404
+ }
405
+ .range-trigger[aria-expanded="true"] .range-chevron {
406
+ transform: rotate(180deg);
407
+ }
408
+
409
+ .range-popover {
410
+ position: absolute;
411
+ top: calc(100% + 6px);
412
+ left: 0;
413
+ z-index: 40;
414
+ display: grid;
415
+ grid-template-columns: 150px 285px;
416
+ border: 1px solid var(--border-strong);
417
+ border-radius: var(--radius);
418
+ background: var(--surface);
419
+ box-shadow: var(--shadow-pop);
420
+ overflow: hidden;
421
+ }
422
+ .range-presets-title {
423
+ padding: 6px 10px 4px;
424
+ font-size: 11px;
425
+ font-weight: 700;
426
+ text-transform: uppercase;
427
+ letter-spacing: 0.05em;
428
+ color: var(--text-3);
429
+ }
430
+ .range-options {
431
+ display: flex;
432
+ flex-direction: column;
433
+ padding: 6px;
434
+ border-right: 1px solid var(--border);
435
+ background: var(--surface);
436
+ }
437
+ .range-option {
438
+ display: flex;
439
+ align-items: center;
440
+ gap: 6px;
441
+ min-height: 32px;
442
+ padding: 0 10px 0 6px;
443
+ border-radius: var(--radius-sm);
444
+ text-align: left;
445
+ font-size: 12.5px;
446
+ }
447
+ .range-option:hover { background: var(--surface-2); }
448
+ .range-option[aria-pressed="true"] { font-weight: 650; }
449
+ .range-check { display: inline-grid; place-items: center; width: 16px; color: var(--accent); }
450
+
451
+ .range-custom {
452
+ display: flex;
453
+ flex-direction: column;
454
+ padding: 12px 14px;
455
+ background: var(--surface);
456
+ gap: 10px;
457
+ }
458
+
459
+ /* ---------- Shadcn-style Calendar ---------- */
460
+ .cal-container {
461
+ display: flex;
462
+ flex-direction: column;
463
+ gap: 8px;
464
+ user-select: none;
465
+ }
466
+ .cal-header {
467
+ display: flex;
468
+ align-items: center;
469
+ justify-content: space-between;
470
+ padding: 0 4px;
471
+ }
472
+ .cal-title {
473
+ font-size: 13px;
474
+ font-weight: 650;
475
+ color: var(--text);
476
+ }
477
+ .cal-nav {
478
+ display: flex;
479
+ align-items: center;
480
+ gap: 3px;
481
+ }
482
+ .cal-nav-btn {
483
+ display: inline-grid;
484
+ place-items: center;
485
+ width: 24px;
486
+ height: 24px;
487
+ border-radius: var(--radius-sm);
488
+ border: 1px solid var(--border);
489
+ background: var(--surface);
490
+ color: var(--text-2);
491
+ cursor: pointer;
492
+ transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
493
+ }
494
+ .cal-nav-btn:hover:not(:disabled) {
495
+ background: var(--surface-2);
496
+ color: var(--text);
497
+ border-color: var(--border-strong);
498
+ }
499
+ .cal-nav-btn:disabled {
500
+ opacity: 0.3;
501
+ cursor: not-allowed;
502
+ }
503
+
504
+ .cal-weekdays {
505
+ display: grid;
506
+ grid-template-columns: repeat(7, 1fr);
507
+ text-align: center;
508
+ color: var(--text-3);
509
+ font-size: 11px;
510
+ font-weight: 600;
511
+ padding: 2px 0;
512
+ }
513
+ .cal-grid {
514
+ display: grid;
515
+ grid-template-columns: repeat(7, 1fr);
516
+ row-gap: 2px;
517
+ }
518
+ .cal-day {
519
+ position: relative;
520
+ height: 30px;
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: center;
524
+ border: 0;
525
+ background: transparent;
526
+ color: var(--text);
527
+ font-size: 12px;
528
+ font-weight: 500;
529
+ cursor: pointer;
530
+ padding: 0;
531
+ transition: background 0.12s ease, color 0.12s ease;
532
+ }
533
+ .cal-day > span {
534
+ display: inline-grid;
535
+ place-items: center;
536
+ width: 26px;
537
+ height: 26px;
538
+ border-radius: var(--radius-sm);
539
+ z-index: 1;
540
+ }
541
+ .cal-day:hover:not(.is-disabled) > span {
542
+ background: var(--surface-2);
543
+ }
544
+ .cal-day.is-other-month {
545
+ opacity: 0.28;
546
+ }
547
+ .cal-day.is-disabled {
548
+ opacity: 0.25;
549
+ cursor: not-allowed;
550
+ pointer-events: none;
551
+ }
552
+ .cal-day.is-today > span {
553
+ font-weight: 750;
554
+ border: 1px solid var(--border-strong);
555
+ }
556
+
557
+ /* Continuous range selection band (shadcn style) */
558
+ .cal-day.is-in-range {
559
+ background: var(--accent-soft);
560
+ color: var(--text);
561
+ }
562
+ .cal-day.is-range-start {
563
+ border-top-left-radius: var(--radius-sm);
564
+ border-bottom-left-radius: var(--radius-sm);
565
+ }
566
+ .cal-day.is-range-end {
567
+ border-top-right-radius: var(--radius-sm);
568
+ border-bottom-right-radius: var(--radius-sm);
569
+ }
570
+ .cal-day.is-single {
571
+ background: transparent !important;
572
+ }
573
+ .cal-day.is-range-start > span,
574
+ .cal-day.is-range-end > span {
575
+ background: var(--accent) !important;
576
+ color: var(--accent-ink) !important;
577
+ font-weight: 700;
578
+ }
579
+
580
+ /* Calendar footer & actions */
581
+ .range-custom-footer {
582
+ display: flex;
583
+ align-items: center;
584
+ justify-content: space-between;
585
+ padding-top: 8px;
586
+ border-top: 1px solid var(--border);
587
+ gap: 8px;
588
+ }
589
+ .range-custom-span-text {
590
+ font-size: 11.5px;
591
+ color: var(--text-2);
592
+ font-weight: 600;
593
+ }
594
+ .range-apply-btn {
595
+ height: 28px;
596
+ padding: 0 12px;
597
+ font-size: 11.5px;
598
+ font-weight: 650;
599
+ border-radius: var(--radius-sm);
600
+ }
601
+
602
+ /* ---------- Layout ---------- */
603
+
604
+ .content { display: grid; gap: 20px; }
605
+ .split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
606
+ .overview-split { align-items: stretch; }
607
+
608
+ .panel {
609
+ min-width: 0;
610
+ padding: 20px 22px;
611
+ border: 1px solid var(--border);
612
+ border-radius: var(--radius);
613
+ background: var(--surface);
614
+ }
615
+ .panel-head { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: 12px 20px; margin-bottom: 16px; }
616
+ .panel-head h2 { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
617
+ .panel-head p { margin-top: 3px; color: var(--text-2); font-size: 12.5px; max-width: 70ch; }
618
+ .panel-controls { display: flex; flex-wrap: wrap; gap: 8px; }
619
+ .subsection { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
620
+ .subhead { margin-bottom: 10px; color: var(--text-2); font-size: 12px; font-weight: 650; }
621
+ .empty-state, .table-empty { padding: 28px 0; text-align: center; }
622
+
623
+ .segmented { display: inline-flex; padding: 2px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); }
624
+ .segmented button { padding: 5px 10px; border-radius: 4px; color: var(--text-2); font-size: 12px; font-weight: 600; white-space: nowrap; }
625
+ .segmented button:hover { color: var(--text); }
626
+ .segmented button[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgb(0 0 0 / 12%); }
627
+
628
+ /* ---------- Rank: header chip ---------- */
629
+
630
+ .rank-chip {
631
+ display: inline-flex;
632
+ align-items: center;
633
+ gap: 7px;
634
+ height: 34px;
635
+ padding: 0 10px;
636
+ border: 1px solid var(--border-strong);
637
+ border-radius: 999px;
638
+ background: var(--surface);
639
+ color: var(--text);
640
+ font-size: 12.5px;
641
+ font-weight: 600;
642
+ }
643
+ .rank-chip svg { color: var(--gold); }
644
+ .rank-chip:hover, .rank-chip.is-active { border-color: var(--gold); }
645
+ .rank-chip-level { color: var(--gold); font-weight: 700; }
646
+ .rank-chip-title { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
647
+ .rank-chip-bar { width: 36px; height: 4px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
648
+ .rank-chip-bar span { display: block; height: 100%; background: var(--gold); }
649
+
650
+ /* ---------- Rank: minimal sheet ----------
651
+ Rank, four numbers, the next rival, and a row of badges. Details live behind a click.
652
+ Gold marks only experience and earned badges. */
653
+
654
+ .sheet {
655
+ --sheet-serif: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
656
+ max-width: 860px;
657
+ margin: 44px auto 0;
658
+ }
659
+
660
+ .sheet-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 20px; align-items: center; }
661
+ .sheet-level { display: grid; justify-items: center; min-width: 56px; font-family: var(--sheet-serif); }
662
+ .sheet-level span { color: var(--text-3); font-size: 14px; font-variant: small-caps; line-height: 1; }
663
+ .sheet-level strong { font-size: 52px; font-weight: 700; line-height: 1; }
664
+ .sheet-identity { display: grid; min-width: 0; }
665
+ .sheet-identity h2 { font-family: var(--sheet-serif); font-size: clamp(24px, 3.2vw, 32px); font-weight: 700; line-height: 1.15; }
666
+ .xp-bar { display: block; max-width: 460px; height: 8px; margin-top: 10px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
667
+ .xp-bar span { display: block; height: 100%; background: var(--gold); }
668
+ .xp-label { margin-top: 6px; color: var(--text-3); font-size: 12.5px; }
669
+ .sheet-share { align-self: start; border-color: transparent; background: transparent; }
670
+ .sheet-share:hover { background: var(--surface-2); }
671
+
672
+ .sheet-numbers { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-top: 28px; padding: 20px 0; border-block: 1px solid var(--border); }
673
+ .sheet-numbers dt { color: var(--text-3); font-size: 12px; }
674
+ .sheet-numbers dd { font-family: var(--sheet-serif); font-size: 26px; font-weight: 700; line-height: 1.2; font-variant-numeric: lining-nums; }
675
+
676
+ .sheet-row { display: grid; grid-template-columns: 110px minmax(0, 1fr) auto; gap: 16px; align-items: center; padding: 18px 0; border-bottom: 1px solid var(--border); }
677
+ .sheet-row:last-of-type { border-bottom: 0; }
678
+ .sheet-row-label { color: var(--text-3); font-size: 12.5px; font-weight: 600; }
679
+ .sheet-row-label span { font-weight: 500; }
680
+ .sheet-row-value { color: var(--text-2); font-size: 13px; white-space: nowrap; font-variant-numeric: tabular-nums; }
681
+ .sheet-rival { min-width: 0; }
682
+ .sheet-rival strong { display: block; overflow: hidden; font-size: 14px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
683
+ .rival-bar { display: block; height: 4px; margin-top: 8px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
684
+ .rival-bar span { display: block; height: 100%; background: var(--text-2); }
685
+
686
+ .sheet-badges { grid-template-columns: 110px minmax(0, 1fr); align-items: start; }
687
+ .sheet-badges .sheet-row-label { padding-top: 9px; }
688
+ .seals { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
689
+ .seal {
690
+ display: grid;
691
+ place-items: center;
692
+ width: 36px;
693
+ height: 36px;
694
+ border: 1.5px dashed var(--border-strong);
695
+ border-radius: 50%;
696
+ color: var(--text-3);
697
+ }
698
+ .seal.is-earned { border-style: solid; border-color: var(--gold); background: color-mix(in srgb, var(--gold) 14%, transparent); color: var(--gold); }
699
+ .seal:hover { border-color: var(--text-3); }
700
+ .seal.is-earned:hover { border-color: var(--gold); }
701
+ .seal[aria-pressed="true"] { outline: 2px solid var(--text); outline-offset: 2px; }
702
+ .seal-detail { margin-top: 12px; color: var(--text-2); font-size: 13px; }
703
+ .seal-detail strong { color: var(--text); font-weight: 650; }
704
+ .seal-detail span { color: var(--text-3); }
705
+
706
+ .share-dialog { width: min(780px, 100%); }
707
+ .share-body { padding: 18px 22px 6px; }
708
+ .share-preview { display: block; width: 100%; height: auto; border-radius: 12px; }
709
+ .share-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 12px 22px 18px; }
710
+ .share-status { flex: 1; min-width: 120px; color: var(--text-2); font-size: 12.5px; }
711
+ .check { display: inline-flex; align-items: center; gap: 7px; color: var(--text-2); font-size: 12.5px; font-weight: 600; cursor: pointer; }
712
+ .check input { width: 15px; height: 15px; accent-color: var(--accent); }
713
+
714
+ /* ---------- KPI cards ---------- */
715
+
716
+ .kpi-grid {
717
+ display: grid;
718
+ grid-template-columns: repeat(4, minmax(0, 1fr));
719
+ border: 1px solid var(--border);
720
+ border-radius: var(--radius);
721
+ background: var(--surface);
722
+ overflow: hidden;
723
+ }
724
+ .kpi { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 18px 20px 16px; }
725
+ .kpi + .kpi { border-left: 1px solid var(--border); }
726
+ .kpi-label { color: var(--text-2); font-size: 12px; font-weight: 650; }
727
+ .kpi-value { margin-top: 4px; font-size: clamp(24px, 2.6vw, 30px); font-weight: 700; letter-spacing: -0.03em; line-height: 1.15; }
728
+ .kpi-of { color: var(--text-3); font-size: 0.55em; font-weight: 600; letter-spacing: 0; }
729
+ .kpi-sub { color: var(--text-3); font-size: 12px; overflow-wrap: anywhere; }
730
+ .kpi-delta { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; color: var(--text-2); font-size: 12px; font-weight: 550; }
731
+ .spark { width: 100%; height: 28px; margin-top: auto; padding-top: 8px; overflow: visible; }
732
+ .spark-empty { height: 28px; margin-top: auto; }
733
+ .spark-line { fill: none; stroke: var(--accent); stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; }
734
+ .spark-area { fill: var(--accent); opacity: 0.1; }
735
+ .spark-dot { fill: var(--accent); }
736
+ .kpi-meter { height: 6px; margin-top: auto; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
737
+ .kpi-meter span { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
738
+
739
+ /* ---------- Tables ---------- */
740
+
741
+ /* position: relative keeps absolutely positioned children (e.g. .sr-only) inside the scroller. */
742
+ .table-scroll { position: relative; overflow-x: auto; margin: 0 -22px; padding: 0 22px; }
743
+ .table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
744
+ .table th {
745
+ padding: 8px 10px;
746
+ border-bottom: 1px solid var(--border-strong);
747
+ color: var(--text-2);
748
+ font-size: 11.5px;
749
+ font-weight: 650;
750
+ text-align: left;
751
+ white-space: nowrap;
752
+ }
753
+ .table td { padding: 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
754
+ .table tbody tr:last-child td { border-bottom: 0; }
755
+ .table th:first-child, .table td:first-child { padding-left: 0; }
756
+ .table th:last-child, .table td:last-child { padding-right: 0; }
757
+ .table .num { text-align: right; white-space: nowrap; }
758
+ .table-compact td { padding-top: 8px; padding-bottom: 8px; }
759
+ .bar-col { width: 22%; min-width: 80px; }
760
+ .row-button { cursor: pointer; }
761
+ .row-button:hover td { background: var(--surface-2); }
762
+ .row-button.is-selected td, .row-button.is-open td { background: var(--accent-soft); }
763
+ .cell-button { display: inline-flex; align-items: center; gap: 6px; text-align: left; font-size: inherit; }
764
+ .cell-button:focus-visible { outline-offset: 3px; }
765
+ .cell-note { display: block; margin-top: 2px; color: var(--text-3); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 36ch; }
766
+ .table-more { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 14px; font-size: 12.5px; }
767
+
768
+ .detail-row > td { padding: 14px 0 18px; background: var(--surface-2); }
769
+ .detail-row .table-scroll { margin: 0; padding: 0 14px; }
770
+ .detail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; padding: 0 14px; }
771
+ .detail-card { padding: 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
772
+ .detail-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; font-size: 12.5px; }
773
+ .detail-head span:not(.tool-tag) { color: var(--text-2); }
774
+ .detail-head span:last-child { margin-left: auto; }
775
+ .detail-card ul { list-style: none; display: grid; gap: 5px; }
776
+ .detail-card li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 12px; font-size: 12px; }
777
+ .detail-card li code { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
778
+ .detail-card li span { color: var(--text-2); text-align: right; }
779
+
780
+ .tool-tag { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; white-space: nowrap; }
781
+ .tool-tag i { width: 8px; height: 8px; flex: 0 0 8px; border-radius: 2px; }
782
+ .tag-row { display: flex; flex-wrap: wrap; gap: 4px 12px; }
783
+ .model-name { color: var(--text); font-size: 12px; }
784
+ .tag-row .model-name { padding: 1px 6px; border-radius: 4px; background: var(--surface-2); }
785
+ .tag {
786
+ display: inline-block;
787
+ margin-left: 8px;
788
+ padding: 1px 6px;
789
+ border: 1px solid var(--border-strong);
790
+ border-radius: 4px;
791
+ color: var(--text-2);
792
+ font-size: 10.5px;
793
+ font-weight: 650;
794
+ vertical-align: 1px;
795
+ }
796
+ .project-cell strong { font-weight: 650; }
797
+
798
+ .share-bar { display: block; height: 6px; border-radius: 99px; background: var(--surface-2); overflow: hidden; }
799
+ .share-bar span { display: block; height: 100%; border-radius: inherit; background: var(--text-3); }
800
+
801
+ .idle-list { list-style: none; display: grid; }
802
+ .idle-list li {
803
+ display: grid;
804
+ grid-template-columns: minmax(160px, 1fr) minmax(0, 1fr) auto;
805
+ align-items: center;
806
+ gap: 16px;
807
+ padding: 10px 0;
808
+ border-top: 1px solid var(--border);
809
+ font-size: 13px;
810
+ }
811
+ .idle-list li:first-child { border-top: 0; }
812
+ .idle-list li > div { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
813
+ .idle-list code { color: var(--text-3); font-size: 12px; }
814
+ .status { color: var(--text-2); font-size: 12px; white-space: nowrap; }
815
+ .status-missing { color: var(--text-3); }
816
+
817
+ /* ---------- Token mix ---------- */
818
+
819
+ .mix-bar { display: flex; gap: 2px; height: 10px; border-radius: 3px; overflow: hidden; background: var(--surface-2); }
820
+ .mix-bar span { min-width: 2px; }
821
+ .mix-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; margin-top: 14px; }
822
+ .mix-list > div { display: grid; gap: 2px; }
823
+ .mix-list dt { display: flex; align-items: center; gap: 7px; color: var(--text-2); font-size: 12px; }
824
+ .mix-list dt i { width: 9px; height: 9px; border-radius: 2px; }
825
+ .mix-list .swatch-none { border: 1px dashed var(--border-strong); }
826
+ .mix-list dd { display: flex; align-items: baseline; gap: 8px; padding-left: 16px; font-variant-numeric: tabular-nums; }
827
+ .mix-list dd strong { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
828
+ .mix-list dd span { color: var(--text-3); font-size: 12px; }
829
+
830
+ /* ---------- Usage chart ---------- */
831
+
832
+ .uchart { --axis-w: 44px; display: flex; flex-direction: column; gap: 8px; }
833
+ .uchart-plot { position: relative; height: 230px; margin-top: 6px; }
834
+ .uchart-grid { position: absolute; inset: 0; pointer-events: none; }
835
+ .uchart-gridline { position: absolute; left: var(--axis-w); right: 0; border-top: 1px solid var(--border); }
836
+ .uchart-gridline:first-child { border-top-color: var(--border-strong); }
837
+ .uchart-gridline span {
838
+ position: absolute;
839
+ right: calc(100% + 8px);
840
+ top: 0;
841
+ transform: translateY(-50%);
842
+ color: var(--text-3);
843
+ font-size: 10.5px;
844
+ font-variant-numeric: tabular-nums;
845
+ white-space: nowrap;
846
+ }
847
+ .uchart-bars { position: absolute; inset: 0 0 0 var(--axis-w); display: flex; align-items: flex-end; cursor: pointer; }
848
+ .uchart-col { flex: 1 1 0; min-width: 0; height: 100%; display: flex; align-items: flex-end; justify-content: center; border-radius: 3px 3px 0 0; }
849
+ .uchart-col.is-active { background: var(--surface-2); }
850
+ .uchart-stack { width: min(24px, 72%); display: flex; flex-direction: column-reverse; gap: 2px; border-radius: 4px 4px 0 0; overflow: hidden; }
851
+ .uchart-seg { flex: 1 1 0; min-height: 1px; }
852
+ .uchart-tip {
853
+ position: absolute;
854
+ top: 2px;
855
+ z-index: 5;
856
+ min-width: 190px;
857
+ max-width: 260px;
858
+ padding: 10px 12px;
859
+ border: 1px solid var(--border-strong);
860
+ border-radius: 8px;
861
+ background: var(--surface);
862
+ box-shadow: var(--shadow-pop);
863
+ color: var(--text);
864
+ font-size: 12px;
865
+ pointer-events: none;
866
+ }
867
+ .uchart-tip.side-right { transform: translateX(16px); }
868
+ .uchart-tip.side-left { transform: translateX(calc(-100% - 16px)); }
869
+ .uchart-tip-head { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; margin-bottom: 8px; }
870
+ .uchart-tip-head strong { font-weight: 650; }
871
+ .uchart-tip-head span { color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
872
+ .uchart-tip ul { list-style: none; display: grid; gap: 5px; }
873
+ .uchart-tip li { display: grid; grid-template-columns: 8px minmax(0, 1fr) auto; align-items: center; gap: 8px; }
874
+ .uchart-tip li i { width: 8px; height: 8px; border-radius: 2px; }
875
+ .uchart-tip li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-2); }
876
+ .uchart-tip li b { font-weight: 600; font-variant-numeric: tabular-nums; }
877
+ .uchart-tip-foot { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border); color: var(--text-2); }
878
+ .uchart-tip-empty { color: var(--text-2); }
879
+ .uchart-xaxis { display: flex; height: 14px; margin-left: var(--axis-w); color: var(--text-3); font-size: 10.5px; }
880
+ .uchart-xaxis span { flex: 1 1 0; min-width: 0; display: flex; justify-content: center; }
881
+ .uchart-xaxis em { font-style: normal; white-space: nowrap; font-variant-numeric: tabular-nums; }
882
+ .uchart-empty { display: grid; place-items: center; height: 230px; color: var(--text-3); }
883
+
884
+ .legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); color: var(--text-2); font-size: 12px; }
885
+ .legend-item { display: inline-flex; align-items: center; gap: 6px; }
886
+ .legend-item i { width: 10px; height: 10px; border-radius: 3px; }
887
+
888
+ /* ---------- Activity calendar ---------- */
889
+
890
+ .cal { display: grid; gap: 6px; width: 100%; min-width: 0; }
891
+ .cal-months, .cal-grid { display: grid; column-gap: 3px; }
892
+ .cal-months { height: 13px; color: var(--text-3); font-size: 10.5px; }
893
+ .cal-months span { white-space: nowrap; }
894
+ .cal-grid { grid-template-rows: repeat(7, auto); row-gap: 3px; }
895
+ .cal-cell { aspect-ratio: 1; border-radius: 2px; background: var(--heat-0); }
896
+ .cal-cell.lvl-1 { background: var(--heat-1); }
897
+ .cal-cell.lvl-2 { background: var(--heat-2); }
898
+ .cal-cell.lvl-3 { background: var(--heat-3); }
899
+ .cal-cell.lvl-4 { background: var(--heat-4); }
900
+ .cal-cell.is-outside { opacity: 0.35; }
901
+ .cal-cell.is-future { background: transparent; }
902
+ .cal-cell.is-hovered { outline: 1.5px solid var(--text); outline-offset: 1px; opacity: 1; }
903
+ .cal-foot { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px 14px; color: var(--text-3); font-size: 11.5px; }
904
+ .cal-readout strong { color: var(--text); font-weight: 650; }
905
+ .cal-scale { display: inline-flex; align-items: center; gap: 3px; }
906
+ .cal-scale .cal-cell { display: inline-block; width: 10px; height: 10px; }
907
+
908
+ /* ---------- Settings dialog ---------- */
909
+
910
+ .modal-backdrop {
911
+ position: fixed;
912
+ inset: 0;
913
+ z-index: 100;
914
+ display: grid;
915
+ place-items: center;
916
+ padding: 16px;
917
+ background: rgb(15 25 19 / 55%);
918
+ }
919
+ .modal {
920
+ width: min(540px, 100%);
921
+ max-height: min(680px, calc(100dvh - 32px));
922
+ overflow-y: auto;
923
+ border: 1px solid var(--border-strong);
924
+ border-radius: var(--radius);
925
+ background: var(--surface);
926
+ box-shadow: var(--shadow-pop);
927
+ }
928
+ .modal-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 20px 22px 16px; border-bottom: 1px solid var(--border); }
929
+ .modal-header h3 { font-size: 19px; letter-spacing: -0.02em; }
930
+ .modal-header p { margin-top: 3px; color: var(--text-2); font-size: 12.5px; }
931
+ .modal-body { padding: 6px 22px 0; }
932
+ .settings-section { padding: 12px 0 4px; }
933
+ .settings-section + .settings-section { border-top: 1px solid var(--border); }
934
+ .settings-section-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
935
+ .settings-section-heading h4 { font-size: 12.5px; }
936
+ .settings-section-heading span { color: var(--text-3); font-size: 12px; }
937
+ .theme-mode-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0 10px; color: var(--text-2); font-size: 12.5px; }
938
+ .palette-picker { margin-bottom: 5px; }
939
+ .palette-picker .select-menu-trigger { height: 50px; padding: 5px 10px; }
940
+ .palette-picker .select-menu-list { width: 100%; }
941
+ .palette-picker .select-menu-option { min-height: 46px; }
942
+ .palette-color { display: block; width: 24px; height: 24px; flex: 0 0 24px; border-radius: 5px; }
943
+ .theme-import { margin-top: 14px; border-top: 1px solid var(--border); }
944
+ .theme-import > summary {
945
+ display: flex;
946
+ align-items: center;
947
+ justify-content: space-between;
948
+ min-height: 44px;
949
+ color: var(--text-2);
950
+ font-size: 12.5px;
951
+ font-weight: 600;
952
+ cursor: pointer;
953
+ list-style: none;
954
+ }
955
+ .theme-import > summary::-webkit-details-marker { display: none; }
956
+ .theme-import > summary svg { transition: transform 0.18s ease; }
957
+ .theme-import[open] > summary svg { transform: rotate(180deg); }
958
+ .theme-import-body { display: grid; gap: 10px; padding-bottom: 14px; }
959
+ .theme-import-body > p { color: var(--text-2); font-size: 12px; line-height: 1.5; }
960
+ .theme-import-body > label { color: var(--text-2); font-size: 11.5px; font-weight: 600; }
961
+ .theme-import-body textarea {
962
+ width: 100%;
963
+ min-height: 132px;
964
+ padding: 10px;
965
+ border: 1px solid var(--text-3);
966
+ border-radius: var(--radius-sm);
967
+ background: var(--surface-2);
968
+ color: var(--text);
969
+ font: 11px/1.5 var(--mono);
970
+ resize: vertical;
971
+ }
972
+ .theme-import-body textarea::placeholder { color: var(--text-3); }
973
+ .theme-import-feedback { color: var(--accent); font-size: 12px; }
974
+ .theme-import-feedback.is-error { color: var(--error-text); }
975
+ .theme-import-actions { display: flex; align-items: center; }
976
+ .theme-format { min-width: 0; border: 1px solid var(--border); border-radius: var(--radius-sm); }
977
+ .theme-format > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 38px; padding: 0 11px; color: var(--text-2); font-size: 12px; font-weight: 600; cursor: pointer; list-style: none; }
978
+ .theme-format > summary::-webkit-details-marker { display: none; }
979
+ .theme-format > summary svg { transition: transform 0.18s ease; }
980
+ .theme-format[open] > summary svg { transform: rotate(180deg); }
981
+ .theme-format-body { display: grid; gap: 9px; padding: 0 11px 11px; }
982
+ .theme-format-body p { color: var(--text-3); font-size: 11.5px; }
983
+ .theme-format-body pre { width: 100%; padding: 12px; overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text-2); font: 11px/1.5 var(--mono); white-space: pre; }
984
+ .setting-row { display: flex; align-items: center; gap: 18px; min-height: 66px; padding: 10px 0; }
985
+ .setting-row + .setting-row { border-top: 1px solid var(--border); }
986
+ .setting-copy { flex: 1; min-width: 0; }
987
+ .setting-copy strong { display: block; font-size: 13.5px; font-weight: 650; }
988
+ .setting-copy p { margin-top: 2px; color: var(--text-2); font-size: 12.5px; }
989
+
990
+ .toggle { position: relative; flex: 0 0 auto; width: 46px; height: 40px; }
991
+ .toggle::before {
992
+ content: "";
993
+ position: absolute;
994
+ inset: 8px 0;
995
+ border-radius: 12px;
996
+ background: var(--border-strong);
997
+ transition: background 0.18s ease;
998
+ }
999
+ .toggle.on::before { background: var(--accent); }
1000
+ .toggle-knob {
1001
+ position: absolute;
1002
+ top: 11px;
1003
+ left: 3px;
1004
+ width: 18px;
1005
+ height: 18px;
1006
+ border-radius: 50%;
1007
+ background: #fff;
1008
+ box-shadow: 0 1px 2px rgb(0 0 0 / 25%);
1009
+ transition: transform 0.18s ease;
1010
+ }
1011
+ .toggle.on .toggle-knob { transform: translateX(22px); }
1012
+ html[data-theme="dark"] .toggle.on .toggle-knob { background: var(--accent-ink); }
1013
+
1014
+ .settings-details { border-top: 1px solid var(--border); }
1015
+ .settings-details summary {
1016
+ display: flex;
1017
+ align-items: center;
1018
+ justify-content: space-between;
1019
+ min-height: 46px;
1020
+ color: var(--text-2);
1021
+ font-size: 12.5px;
1022
+ font-weight: 600;
1023
+ cursor: pointer;
1024
+ list-style: none;
1025
+ }
1026
+ .settings-details summary::-webkit-details-marker { display: none; }
1027
+ .settings-details summary svg { transition: transform 0.18s ease; }
1028
+ .settings-details[open] summary svg { transform: rotate(180deg); }
1029
+ .settings-details dl { display: grid; gap: 10px; padding-bottom: 14px; }
1030
+ .settings-details dl > div { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 8px; font-size: 12px; }
1031
+ .settings-details dt { color: var(--text-3); }
1032
+ .settings-details code { overflow-wrap: anywhere; }
1033
+ .settings-empty { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 24px 0; color: var(--text-2); }
1034
+ .settings-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 22px; border-top: 1px solid var(--border); }
1035
+ .settings-footer > span { color: var(--text-3); font-size: 12px; }
1036
+ .settings-quit { display: inline-flex; align-items: center; gap: 7px; min-height: 34px; padding: 0 8px; border-radius: var(--radius-sm); color: var(--text-2); font-size: 13px; font-weight: 600; }
1037
+ .settings-quit:hover { background: var(--surface-2); color: var(--error-text); }
1038
+
1039
+ /* ---------- Splash screens ---------- */
1040
+
1041
+ .splash { display: grid; place-items: center; min-height: 100vh; padding: 24px; }
1042
+ .splash-card {
1043
+ display: grid;
1044
+ justify-items: center;
1045
+ gap: 12px;
1046
+ width: min(420px, 100%);
1047
+ padding: 32px 28px;
1048
+ border: 1px solid var(--border);
1049
+ border-radius: var(--radius);
1050
+ background: var(--surface);
1051
+ color: var(--text-2);
1052
+ text-align: center;
1053
+ }
1054
+ .splash-card h2 { color: var(--text); font-size: 19px; }
1055
+ .splash-logo { width: 64px; height: 64px; }
1056
+
1057
+ /* ---------- Responsive ---------- */
1058
+
1059
+ @media (max-width: 1020px) {
1060
+ .split { grid-template-columns: 1fr; }
1061
+ .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1062
+ .kpi:nth-child(3) { border-left: 0; }
1063
+ .kpi:nth-child(n + 3) { border-top: 1px solid var(--border); }
1064
+ }
1065
+
1066
+ @media (max-width: 700px) {
1067
+ .app { padding: 0 16px 48px; }
1068
+ .topbar { margin: 0 -16px; padding: 12px 16px; }
1069
+ .updated { display: none; }
1070
+ .filters { margin: 0 -16px 16px; padding: 8px 16px 10px; }
1071
+ .filters > * { flex: 1 1 140px; }
1072
+ .select-menu, .select-menu-trigger, .cost-field { min-width: 0; width: 100%; }
1073
+ .cost-segmented button { flex: 1; }
1074
+ .range-picker { flex-basis: 100%; }
1075
+ .range-trigger > span > span { display: none; }
1076
+ .range-popover { grid-template-columns: 1fr; width: min(340px, calc(100vw - 32px)); }
1077
+ .range-options { border-right: 0; border-bottom: 1px solid var(--border); }
1078
+ .field-search { margin-left: 0; flex-basis: 100%; }
1079
+ .search { min-width: 0; }
1080
+ .intro { padding: 22px 0 16px; }
1081
+ .panel { padding: 16px; }
1082
+ .table-scroll { margin: 0 -16px; padding: 0 16px; }
1083
+ .kpi { padding: 14px 14px 12px; }
1084
+ .kpi-value { font-size: 23px; }
1085
+ .uchart { --axis-w: 38px; }
1086
+ .uchart-plot, .uchart-empty { height: 190px; }
1087
+ .uchart-tip { min-width: 160px; }
1088
+ .idle-list li { grid-template-columns: 1fr; gap: 4px; }
1089
+ .table-compact .bar-col { display: none; }
1090
+ .rank-chip-title, .rank-chip-bar { display: none; }
1091
+ .sheet { margin-top: 24px; }
1092
+ .sheet-head { gap: 14px; }
1093
+ .sheet-level { min-width: 44px; }
1094
+ .sheet-level strong { font-size: 40px; }
1095
+ .sheet-numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1096
+ .sheet-row, .sheet-badges { grid-template-columns: 1fr; gap: 8px; }
1097
+ .sheet-badges .sheet-row-label { padding-top: 0; }
1098
+ }
1099
+
1100
+ @media (max-width: 420px) {
1101
+ .kpi-value { font-size: 21px; }
1102
+ .mix-list { grid-template-columns: 1fr; }
1103
+ .topbar-actions .btn span { display: none; }
1104
+ }
1105
+
1106
+ @media (prefers-reduced-motion: reduce) {
1107
+ .spin { animation: none; }
1108
+ *, *::before, *::after { transition-duration: 0s !important; scroll-behavior: auto !important; }
1109
+ }
1110
+
1111
+ @media (forced-colors: active) {
1112
+ .uchart-seg, .share-bar span, .mix-bar span, .cal-cell, .tool-tag i, .legend-item i { forced-color-adjust: none; }
1113
+ }