token-studio 4.8.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 (139) hide show
  1. package/.nvmrc +1 -0
  2. package/CHANGELOG.md +89 -0
  3. package/Dockerfile +17 -0
  4. package/LICENSE +22 -0
  5. package/NOTICE.md +21 -0
  6. package/PRIVACY.md +68 -0
  7. package/README.en.md +220 -0
  8. package/README.md +220 -0
  9. package/config/collectors.json +54 -0
  10. package/data/.gitkeep +1 -0
  11. package/docker-compose.yml +17 -0
  12. package/docs/assets/.gitkeep +1 -0
  13. package/docs/assets/token-studio-v44-dashboard.png +0 -0
  14. package/docs/assets/token-studio-v44-live.png +0 -0
  15. package/docs/assets/token-studio-v44-review-mobile.png +0 -0
  16. package/docs/assets/token-studio-v44-review.png +0 -0
  17. package/docs/assets/token-studio-v45-dashboard.png +0 -0
  18. package/docs/assets/token-studio-v45-live.png +0 -0
  19. package/docs/assets/token-studio-v45-review-mobile.png +0 -0
  20. package/docs/assets/token-studio-v45-review.png +0 -0
  21. package/docs/blog-case-study.md +34 -0
  22. package/docs/collector-support-matrix.md +65 -0
  23. package/docs/competitive-notes.md +87 -0
  24. package/docs/demo-data/README.md +12 -0
  25. package/docs/demo-data/token-studio-v2-demo.json +146 -0
  26. package/docs/demo-flow.md +39 -0
  27. package/docs/first-run.md +95 -0
  28. package/docs/local-collectors.md +49 -0
  29. package/docs/public-launch-checklist.md +45 -0
  30. package/docs/resume-bullets.md +7 -0
  31. package/docs/statusline.md +52 -0
  32. package/index.html +16 -0
  33. package/package.json +36 -0
  34. package/render.yaml +17 -0
  35. package/src/auto-attribution.mjs +396 -0
  36. package/src/ccusage-bridge.mjs +74 -0
  37. package/src/ccusage-import.mjs +415 -0
  38. package/src/cli.mjs +643 -0
  39. package/src/client/dashboard/App.jsx +1734 -0
  40. package/src/client/dashboard/annotation-presets.js +138 -0
  41. package/src/client/dashboard/attribution.js +328 -0
  42. package/src/client/dashboard/components-charts.jsx +622 -0
  43. package/src/client/dashboard/components-tables.jsx +1531 -0
  44. package/src/client/dashboard/components-top.jsx +307 -0
  45. package/src/client/dashboard/import-budget.js +41 -0
  46. package/src/client/dashboard/model-usage.js +108 -0
  47. package/src/client/dashboard/onboarding.js +80 -0
  48. package/src/client/dashboard/styles.css +2606 -0
  49. package/src/client/live/LiveApp.jsx +226 -0
  50. package/src/client/live/styles.css +446 -0
  51. package/src/client/main.jsx +20 -0
  52. package/src/client/review/ReviewApp.jsx +507 -0
  53. package/src/client/review/closure-progress.js +165 -0
  54. package/src/client/review/markdown-report.js +401 -0
  55. package/src/client/review/model-strategy.js +273 -0
  56. package/src/client/review/roi-advisor.js +255 -0
  57. package/src/client/review/roi-evidence.js +78 -0
  58. package/src/client/review/savings-simulator.js +252 -0
  59. package/src/client/review/sections-1.jsx +277 -0
  60. package/src/client/review/sections-2.jsx +927 -0
  61. package/src/client/review/styles.css +2321 -0
  62. package/src/client/review/utils.js +345 -0
  63. package/src/client/shared/utils.js +236 -0
  64. package/src/closure-check.mjs +537 -0
  65. package/src/closure-import.mjs +646 -0
  66. package/src/collect.mjs +247 -0
  67. package/src/collector-config.mjs +82 -0
  68. package/src/collector-registry.mjs +333 -0
  69. package/src/collectors/claude-code.mjs +355 -0
  70. package/src/collectors/codex.mjs +418 -0
  71. package/src/collectors/copilot.mjs +19 -0
  72. package/src/collectors/cursor.mjs +23 -0
  73. package/src/collectors/gemini.mjs +530 -0
  74. package/src/collectors/goose.mjs +15 -0
  75. package/src/collectors/hermes.mjs +206 -0
  76. package/src/collectors/kimi.mjs +15 -0
  77. package/src/collectors/openclaw.mjs +400 -0
  78. package/src/collectors/opencode.mjs +349 -0
  79. package/src/collectors/qwen.mjs +15 -0
  80. package/src/collectors/structured-usage.mjs +437 -0
  81. package/src/collectors/utils.mjs +93 -0
  82. package/src/db.mjs +1397 -0
  83. package/src/demo-seed.mjs +39 -0
  84. package/src/dev.mjs +43 -0
  85. package/src/live.mjs +428 -0
  86. package/src/model-policy.mjs +147 -0
  87. package/src/pricing.mjs +434 -0
  88. package/src/privacy-check.mjs +126 -0
  89. package/src/server.mjs +1240 -0
  90. package/src/source-health.mjs +195 -0
  91. package/src/statusline.mjs +156 -0
  92. package/src/terminal-report.mjs +245 -0
  93. package/src/update-pricing.mjs +8 -0
  94. package/test/annotation-presets.test.mjs +137 -0
  95. package/test/api-annotations.test.mjs +202 -0
  96. package/test/api-auto-attribution.test.mjs +169 -0
  97. package/test/api-source-health.test.mjs +109 -0
  98. package/test/api-v2.test.mjs +278 -0
  99. package/test/api-v43.test.mjs +151 -0
  100. package/test/api-v44.test.mjs +128 -0
  101. package/test/attribution-summary.test.mjs +164 -0
  102. package/test/auto-attribution.test.mjs +116 -0
  103. package/test/ccusage-bridge.test.mjs +36 -0
  104. package/test/ccusage-import.test.mjs +93 -0
  105. package/test/cli-v43.test.mjs +64 -0
  106. package/test/cli-v45.test.mjs +34 -0
  107. package/test/cli-v46.test.mjs +129 -0
  108. package/test/cli-v47.test.mjs +98 -0
  109. package/test/closure-check.test.mjs +202 -0
  110. package/test/closure-import.test.mjs +263 -0
  111. package/test/collector-config.test.mjs +25 -0
  112. package/test/collector-registry.test.mjs +56 -0
  113. package/test/csv.test.mjs +19 -0
  114. package/test/db-annotations.test.mjs +186 -0
  115. package/test/db-v2.test.mjs +200 -0
  116. package/test/db-v4.test.mjs +178 -0
  117. package/test/experimental-collectors.test.mjs +103 -0
  118. package/test/fixtures/collectors/copilot/usage.jsonl +2 -0
  119. package/test/fixtures/collectors/cursor/usage.jsonl +2 -0
  120. package/test/fixtures/collectors/goose/usage.jsonl +2 -0
  121. package/test/fixtures/collectors/kimi/usage.jsonl +2 -0
  122. package/test/fixtures/collectors/qwen/usage.jsonl +2 -0
  123. package/test/import-budget.test.mjs +40 -0
  124. package/test/live.test.mjs +256 -0
  125. package/test/markdown-report.test.mjs +193 -0
  126. package/test/model-policy.test.mjs +34 -0
  127. package/test/model-strategy.test.mjs +116 -0
  128. package/test/model-usage.test.mjs +99 -0
  129. package/test/official-pricing.test.mjs +70 -0
  130. package/test/onboarding.test.mjs +55 -0
  131. package/test/privacy-check.test.mjs +33 -0
  132. package/test/review-closure-progress.test.mjs +99 -0
  133. package/test/roi-advisor.test.mjs +188 -0
  134. package/test/roi-evidence.test.mjs +48 -0
  135. package/test/roi-summary.test.mjs +101 -0
  136. package/test/savings-simulator.test.mjs +141 -0
  137. package/test/source-health.test.mjs +62 -0
  138. package/test/statusline.test.mjs +148 -0
  139. package/vite.config.js +23 -0
@@ -0,0 +1,2321 @@
1
+ /* =============================================================
2
+ AI Token 复盘报告 — editorial light theme
3
+ ============================================================= */
4
+
5
+ :root {
6
+ /* Warm cream paper background */
7
+ --paper: oklch(0.97 0.008 80);
8
+ --paper-2: oklch(0.95 0.008 80);
9
+ --paper-3: oklch(0.92 0.010 80);
10
+ --ink: oklch(0.16 0.010 60);
11
+ --ink-2: oklch(0.32 0.010 60);
12
+ --ink-3: oklch(0.50 0.008 60);
13
+ --ink-soft: oklch(0.68 0.006 60);
14
+
15
+ --rule: oklch(0.88 0.010 60);
16
+ --rule-2: oklch(0.93 0.010 60);
17
+
18
+ /* Accents — same palette as dashboard */
19
+ --indigo: oklch(0.55 0.16 265);
20
+ --violet: oklch(0.60 0.15 295);
21
+ --teal: oklch(0.55 0.13 200);
22
+ --amber: oklch(0.68 0.15 70);
23
+ --green: oklch(0.58 0.13 145);
24
+ --rose: oklch(0.58 0.18 25);
25
+
26
+ --good: oklch(0.55 0.14 145);
27
+ --bad: oklch(0.55 0.18 25);
28
+
29
+ --serif: 'Instrument Serif', 'Source Serif 4', Georgia, serif;
30
+ --sans: 'Inter', system-ui, -apple-system, sans-serif;
31
+ --mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
32
+ }
33
+
34
+ * { box-sizing: border-box; }
35
+
36
+ html, body {
37
+ margin: 0;
38
+ padding: 0;
39
+ background: var(--paper);
40
+ color: var(--ink);
41
+ font-family: var(--sans);
42
+ font-size: 15px;
43
+ line-height: 1.6;
44
+ -webkit-font-smoothing: antialiased;
45
+ -moz-osx-font-smoothing: grayscale;
46
+ }
47
+
48
+ html {
49
+ overflow-x: clip;
50
+ }
51
+
52
+ body {
53
+ overflow-x: hidden;
54
+ }
55
+
56
+ html {
57
+ scroll-behavior: smooth;
58
+ }
59
+
60
+ button, input { font-family: inherit; color: inherit; }
61
+
62
+ /* paper texture */
63
+ body::before {
64
+ content: '';
65
+ position: fixed;
66
+ inset: 0;
67
+ pointer-events: none;
68
+ background-image:
69
+ radial-gradient(oklch(0.55 0.02 60 / 0.025) 1px, transparent 1px);
70
+ background-size: 3px 3px;
71
+ z-index: 0;
72
+ opacity: 0.6;
73
+ }
74
+
75
+ /* ─── Page chrome ─────────────────────────────────────────── */
76
+
77
+ .review-nav {
78
+ position: sticky;
79
+ top: 0;
80
+ z-index: 30;
81
+ background: color-mix(in oklab, var(--paper), transparent 8%);
82
+ backdrop-filter: blur(12px);
83
+ -webkit-backdrop-filter: blur(12px);
84
+ border-bottom: 1px solid var(--rule-2);
85
+ }
86
+
87
+ .review-nav-inner {
88
+ max-width: 1080px;
89
+ margin: 0 auto;
90
+ padding: 12px 32px;
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: space-between;
94
+ gap: 16px;
95
+ }
96
+
97
+ .brand-line {
98
+ display: inline-flex;
99
+ align-items: center;
100
+ gap: 12px;
101
+ font-size: 12.5px;
102
+ font-weight: 500;
103
+ color: var(--ink-2);
104
+ }
105
+ .brand-dot {
106
+ width: 7px; height: 7px;
107
+ background: var(--ink);
108
+ border-radius: 50%;
109
+ }
110
+ .brand-name {
111
+ font-weight: 600;
112
+ color: var(--ink);
113
+ letter-spacing: -0.01em;
114
+ }
115
+
116
+ /* Page nav pill — matches main dashboard */
117
+ .page-switch {
118
+ display: inline-flex;
119
+ background: var(--paper-3);
120
+ border: 1px solid var(--rule-2);
121
+ border-radius: 999px;
122
+ padding: 3px;
123
+ gap: 2px;
124
+ }
125
+ .page-chip {
126
+ height: 26px;
127
+ padding: 0 14px;
128
+ font-size: 12.5px;
129
+ font-weight: 500;
130
+ color: var(--ink-3);
131
+ background: transparent;
132
+ border: 0;
133
+ border-radius: 999px;
134
+ cursor: pointer;
135
+ text-decoration: none;
136
+ display: inline-flex;
137
+ align-items: center;
138
+ transition: color 120ms ease;
139
+ letter-spacing: 0.01em;
140
+ white-space: nowrap;
141
+ }
142
+ .page-chip:hover { color: var(--ink); }
143
+ .page-chip.active {
144
+ background: var(--ink);
145
+ color: var(--paper);
146
+ pointer-events: none;
147
+ }
148
+
149
+ .period-switch {
150
+ display: inline-flex;
151
+ background: var(--paper-2);
152
+ border: 1px solid var(--rule-2);
153
+ border-radius: 999px;
154
+ padding: 3px;
155
+ gap: 2px;
156
+ }
157
+
158
+ .period-chip {
159
+ height: 28px;
160
+ padding: 0 14px;
161
+ font-size: 12.5px;
162
+ font-weight: 500;
163
+ color: var(--ink-3);
164
+ background: transparent;
165
+ border: 0;
166
+ border-radius: 999px;
167
+ cursor: pointer;
168
+ letter-spacing: 0.01em;
169
+ }
170
+ .period-chip:hover { color: var(--ink); }
171
+ .period-chip.active {
172
+ background: var(--ink);
173
+ color: var(--paper);
174
+ }
175
+
176
+ .nav-actions {
177
+ display: inline-flex; gap: 6px;
178
+ }
179
+
180
+ .nav-btn {
181
+ height: 32px;
182
+ padding: 0 12px;
183
+ font-size: 12.5px;
184
+ background: transparent;
185
+ border: 1px solid var(--rule);
186
+ border-radius: 8px;
187
+ color: var(--ink-2);
188
+ cursor: pointer;
189
+ display: inline-flex;
190
+ align-items: center;
191
+ gap: 6px;
192
+ }
193
+ .nav-btn:hover { background: var(--paper-2); color: var(--ink); }
194
+ .nav-btn.primary {
195
+ background: var(--ink);
196
+ color: var(--paper);
197
+ border-color: var(--ink);
198
+ }
199
+ .nav-btn.primary:hover {
200
+ background: oklch(0.25 0.010 60);
201
+ color: var(--paper);
202
+ }
203
+
204
+ /* ─── Page layout ────────────────────────────────────────── */
205
+
206
+ .page {
207
+ position: relative;
208
+ z-index: 1;
209
+ max-width: 780px;
210
+ margin: 0 auto;
211
+ padding: 80px 32px 180px;
212
+ }
213
+
214
+ .page-wide {
215
+ max-width: 920px;
216
+ margin: 0 auto;
217
+ padding: 0 32px;
218
+ }
219
+
220
+ .review-page {
221
+ scroll-margin-top: 78px;
222
+ opacity: 0.42;
223
+ transform: translateY(16px);
224
+ filter: saturate(0.82);
225
+ transition:
226
+ opacity 260ms ease,
227
+ transform 260ms ease,
228
+ filter 260ms ease;
229
+ }
230
+
231
+ .review-page.active {
232
+ opacity: 1;
233
+ transform: translateY(0);
234
+ filter: saturate(1);
235
+ animation: review-page-fade 420ms ease both;
236
+ }
237
+
238
+ .review-page-narrow {
239
+ max-width: 780px;
240
+ margin: 0 auto;
241
+ }
242
+
243
+ @keyframes review-page-fade {
244
+ from {
245
+ opacity: 0.24;
246
+ transform: translateY(20px);
247
+ }
248
+ to {
249
+ opacity: 1;
250
+ transform: translateY(0);
251
+ }
252
+ }
253
+
254
+ /* ─── Section spacing ────────────────────────────────────── */
255
+
256
+ section.story {
257
+ padding: 96px 0;
258
+ border-top: 1px solid var(--rule-2);
259
+ }
260
+ section.story:first-of-type { border-top: 0; padding-top: 24px; }
261
+ section.story:last-of-type { padding-bottom: 56px; }
262
+
263
+ .section-label {
264
+ font-family: var(--mono);
265
+ font-size: 10.5px;
266
+ letter-spacing: 0.18em;
267
+ text-transform: uppercase;
268
+ color: var(--ink-soft);
269
+ margin-bottom: 24px;
270
+ display: inline-flex;
271
+ align-items: center;
272
+ gap: 10px;
273
+ }
274
+ .section-label::before {
275
+ content: '';
276
+ display: inline-block;
277
+ width: 20px;
278
+ height: 1px;
279
+ background: var(--ink-soft);
280
+ }
281
+
282
+ .section-title {
283
+ font-family: var(--serif);
284
+ font-weight: 400;
285
+ font-size: 38px;
286
+ line-height: 1.15;
287
+ color: var(--ink);
288
+ margin: 0 0 12px;
289
+ letter-spacing: -0.01em;
290
+ text-wrap: balance;
291
+ }
292
+
293
+ .section-sub {
294
+ font-size: 16px;
295
+ color: var(--ink-3);
296
+ margin: 0 0 36px;
297
+ max-width: 620px;
298
+ text-wrap: pretty;
299
+ }
300
+
301
+ /* ─── Hero / opening ────────────────────────────────────── */
302
+
303
+ .hero {
304
+ padding: 48px 0 0;
305
+ }
306
+
307
+ .hero-eyebrow {
308
+ font-family: var(--mono);
309
+ font-size: 10.5px;
310
+ letter-spacing: 0.22em;
311
+ text-transform: uppercase;
312
+ color: var(--ink-soft);
313
+ margin-bottom: 28px;
314
+ display: flex;
315
+ align-items: center;
316
+ gap: 12px;
317
+ }
318
+ .hero-eyebrow span {
319
+ display: inline-flex;
320
+ align-items: center;
321
+ gap: 6px;
322
+ }
323
+ .hero-eyebrow .sep {
324
+ flex: 0 0 24px;
325
+ height: 1px;
326
+ background: var(--ink-soft);
327
+ }
328
+
329
+ .hero-headline {
330
+ font-family: var(--serif);
331
+ font-weight: 400;
332
+ font-size: 76px;
333
+ line-height: 1.02;
334
+ letter-spacing: -0.025em;
335
+ color: var(--ink);
336
+ margin: 0 0 22px;
337
+ text-wrap: balance;
338
+ }
339
+ .hero-headline .num {
340
+ font-feature-settings: 'lnum', 'ss01';
341
+ font-variant-numeric: lining-nums;
342
+ display: inline-block;
343
+ background: linear-gradient(180deg, var(--indigo) 30%, oklch(0.45 0.18 280) 100%);
344
+ -webkit-background-clip: text;
345
+ background-clip: text;
346
+ color: transparent;
347
+ }
348
+
349
+ .hero-headline .em {
350
+ font-style: italic;
351
+ color: var(--ink-2);
352
+ }
353
+
354
+ .hero-sub {
355
+ font-size: 18px;
356
+ line-height: 1.55;
357
+ color: var(--ink-2);
358
+ margin: 0 0 16px;
359
+ max-width: 600px;
360
+ font-weight: 400;
361
+ }
362
+
363
+ .hero-sub .delta {
364
+ display: inline-flex;
365
+ align-items: baseline;
366
+ gap: 2px;
367
+ font-variant-numeric: tabular-nums;
368
+ font-weight: 600;
369
+ padding: 1px 7px;
370
+ border-radius: 4px;
371
+ font-size: 14.5px;
372
+ }
373
+ .hero-sub .delta.up { color: var(--bad); background: color-mix(in oklab, var(--bad), transparent 92%); }
374
+ .hero-sub .delta.down { color: var(--good); background: color-mix(in oklab, var(--good), transparent 92%); }
375
+
376
+ .hero-meta {
377
+ font-size: 14.5px;
378
+ color: var(--ink-3);
379
+ display: inline-flex;
380
+ align-items: center;
381
+ gap: 8px;
382
+ margin-bottom: 56px;
383
+ }
384
+ .hero-meta b { color: var(--ink); font-weight: 600; font-feature-settings: 'tnum'; }
385
+
386
+ /* ─── Stat strip (4 small cards under hero) ──────────────── */
387
+
388
+ .stat-strip {
389
+ display: grid;
390
+ grid-template-columns: repeat(4, 1fr);
391
+ gap: 1px;
392
+ margin-top: 32px;
393
+ background: var(--rule-2);
394
+ border-radius: 12px;
395
+ overflow: hidden;
396
+ border: 1px solid var(--rule-2);
397
+ }
398
+ .stat-cell {
399
+ background: var(--paper);
400
+ padding: 18px 18px 20px;
401
+ }
402
+ .stat-cell .l {
403
+ font-family: var(--mono);
404
+ font-size: 10.5px;
405
+ text-transform: uppercase;
406
+ letter-spacing: 0.12em;
407
+ color: var(--ink-soft);
408
+ margin-bottom: 10px;
409
+ }
410
+ .stat-cell .v {
411
+ font-family: var(--serif);
412
+ font-size: 30px;
413
+ line-height: 1;
414
+ color: var(--ink);
415
+ font-variant-numeric: lining-nums;
416
+ letter-spacing: -0.01em;
417
+ }
418
+ .stat-cell .s {
419
+ font-size: 12px;
420
+ color: var(--ink-3);
421
+ margin-top: 8px;
422
+ font-variant-numeric: tabular-nums;
423
+ }
424
+
425
+ /* ─── Project bars ───────────────────────────────────────── */
426
+
427
+ .proj-list {
428
+ display: flex;
429
+ flex-direction: column;
430
+ gap: 14px;
431
+ margin-top: 8px;
432
+ }
433
+ .proj-row {
434
+ display: grid;
435
+ grid-template-columns: 28px 1fr auto;
436
+ align-items: center;
437
+ gap: 16px;
438
+ }
439
+ .proj-rank {
440
+ font-family: var(--serif);
441
+ font-size: 22px;
442
+ color: var(--ink-soft);
443
+ text-align: center;
444
+ font-variant-numeric: lining-nums;
445
+ }
446
+ .proj-body { min-width: 0; }
447
+ .proj-head {
448
+ display: flex;
449
+ align-items: baseline;
450
+ gap: 10px;
451
+ margin-bottom: 6px;
452
+ flex-wrap: wrap;
453
+ }
454
+ .proj-name {
455
+ font-family: var(--mono);
456
+ font-size: 13px;
457
+ font-weight: 500;
458
+ color: var(--ink);
459
+ white-space: nowrap;
460
+ overflow: hidden;
461
+ text-overflow: ellipsis;
462
+ flex: 1;
463
+ min-width: 0;
464
+ }
465
+ .proj-meta {
466
+ font-size: 11.5px;
467
+ color: var(--ink-soft);
468
+ font-variant-numeric: tabular-nums;
469
+ white-space: nowrap;
470
+ }
471
+ .proj-bar {
472
+ height: 8px;
473
+ background: var(--paper-2);
474
+ border-radius: 2px;
475
+ overflow: hidden;
476
+ position: relative;
477
+ }
478
+ .proj-bar-fill {
479
+ height: 100%;
480
+ border-radius: 2px;
481
+ transition: width 700ms cubic-bezier(0.22, 1, 0.36, 1);
482
+ }
483
+ .proj-val {
484
+ text-align: right;
485
+ font-feature-settings: 'lnum';
486
+ font-variant-numeric: lining-nums tabular-nums;
487
+ white-space: nowrap;
488
+ }
489
+ .proj-val .big {
490
+ font-family: var(--serif);
491
+ font-size: 20px;
492
+ color: var(--ink);
493
+ line-height: 1;
494
+ }
495
+ .proj-val .small {
496
+ font-size: 11px;
497
+ color: var(--amber);
498
+ margin-top: 4px;
499
+ font-variant-numeric: tabular-nums;
500
+ }
501
+
502
+ /* narrative pullquote */
503
+ .pullquote {
504
+ margin: 36px 0 0;
505
+ padding: 22px 28px;
506
+ background: var(--paper-2);
507
+ border-left: 3px solid var(--ink);
508
+ border-radius: 4px 12px 12px 4px;
509
+ font-size: 15px;
510
+ line-height: 1.65;
511
+ color: var(--ink-2);
512
+ text-wrap: pretty;
513
+ }
514
+ .pullquote b { color: var(--ink); font-weight: 600; }
515
+ .pullquote code {
516
+ font-family: var(--mono);
517
+ font-size: 13px;
518
+ background: var(--paper-3);
519
+ padding: 1px 6px;
520
+ border-radius: 4px;
521
+ color: var(--ink);
522
+ }
523
+
524
+ /* ─── Calendar heatmap ───────────────────────────────────── */
525
+
526
+ .calendar {
527
+ background: var(--paper);
528
+ border: 1px solid var(--rule-2);
529
+ border-radius: 14px;
530
+ padding: 24px 28px 28px;
531
+ }
532
+
533
+ .cal-months {
534
+ display: flex;
535
+ gap: 32px;
536
+ justify-content: center;
537
+ flex-wrap: wrap;
538
+ }
539
+
540
+ .cal-month {
541
+ display: flex;
542
+ flex-direction: column;
543
+ gap: 6px;
544
+ min-width: 0;
545
+ }
546
+ .cal-month-label {
547
+ font-family: var(--mono);
548
+ font-size: 11px;
549
+ text-transform: uppercase;
550
+ letter-spacing: 0.12em;
551
+ color: var(--ink-soft);
552
+ margin-bottom: 8px;
553
+ text-align: center;
554
+ }
555
+
556
+ .cal-weeks {
557
+ display: grid;
558
+ grid-template-columns: 16px repeat(7, 14px);
559
+ grid-auto-rows: 14px;
560
+ gap: 3px;
561
+ }
562
+ .cal-dow {
563
+ font-family: var(--mono);
564
+ font-size: 9px;
565
+ color: var(--ink-soft);
566
+ display: grid; place-items: center;
567
+ }
568
+ .cal-cell {
569
+ width: 14px; height: 14px;
570
+ border-radius: 3px;
571
+ cursor: pointer;
572
+ transition: outline 100ms ease, transform 100ms ease;
573
+ position: relative;
574
+ }
575
+ .cal-cell:hover {
576
+ outline: 2px solid var(--ink);
577
+ outline-offset: 1px;
578
+ z-index: 2;
579
+ }
580
+ .cal-tip {
581
+ position: fixed;
582
+ z-index: 50;
583
+ background: var(--ink);
584
+ color: var(--paper);
585
+ padding: 8px 12px;
586
+ border-radius: 8px;
587
+ font-size: 11.5px;
588
+ pointer-events: none;
589
+ white-space: nowrap;
590
+ font-variant-numeric: tabular-nums;
591
+ box-shadow: 0 8px 24px -8px rgb(0 0 0 / 0.4);
592
+ transform: translate(-50%, -120%);
593
+ }
594
+ .cal-tip b { color: oklch(0.85 0.05 70); }
595
+ .cal-tip .dim { color: oklch(0.65 0.005 80); font-weight: 400; margin-left: 8px; }
596
+
597
+ .cal-scale {
598
+ display: inline-flex; align-items: center; gap: 6px;
599
+ font-size: 10.5px;
600
+ color: var(--ink-soft);
601
+ font-family: var(--mono);
602
+ margin-top: 22px;
603
+ justify-content: flex-end;
604
+ width: 100%;
605
+ }
606
+ .cal-scale-cells { display: inline-flex; gap: 2px; }
607
+ .cal-scale-cells span { width: 11px; height: 11px; border-radius: 2px; }
608
+
609
+ /* peak day list */
610
+ .peaks {
611
+ display: flex;
612
+ flex-direction: column;
613
+ gap: 1px;
614
+ margin-top: 36px;
615
+ background: var(--rule-2);
616
+ border-radius: 12px;
617
+ overflow: hidden;
618
+ border: 1px solid var(--rule-2);
619
+ }
620
+ .peak-row {
621
+ background: var(--paper);
622
+ padding: 16px 22px;
623
+ display: grid;
624
+ grid-template-columns: 26px 95px 1fr auto;
625
+ align-items: center;
626
+ gap: 16px;
627
+ }
628
+ .peak-rank {
629
+ font-family: var(--serif);
630
+ font-size: 22px;
631
+ color: var(--ink-soft);
632
+ font-variant-numeric: lining-nums;
633
+ }
634
+ .peak-date {
635
+ font-family: var(--mono);
636
+ font-size: 13px;
637
+ color: var(--ink);
638
+ font-weight: 500;
639
+ font-variant-numeric: tabular-nums;
640
+ }
641
+ .peak-detail {
642
+ font-size: 13px;
643
+ color: var(--ink-3);
644
+ min-width: 0;
645
+ }
646
+ .peak-detail b { color: var(--ink); font-weight: 500; }
647
+ .peak-detail .arrow { color: var(--ink-soft); margin: 0 6px; }
648
+ .peak-total {
649
+ font-family: var(--serif);
650
+ font-size: 20px;
651
+ color: var(--ink);
652
+ font-variant-numeric: lining-nums tabular-nums;
653
+ white-space: nowrap;
654
+ }
655
+
656
+ /* ─── Closure progress ───────────────────────────────────── */
657
+
658
+ .closure-section {
659
+ padding-top: 48px;
660
+ }
661
+
662
+ .closure-hero {
663
+ display: grid;
664
+ grid-template-columns: minmax(0, 1fr) 190px;
665
+ gap: 18px;
666
+ align-items: center;
667
+ padding: 22px 24px;
668
+ border: 1px solid var(--rule-2);
669
+ border-radius: 14px;
670
+ background: var(--paper);
671
+ margin-bottom: 14px;
672
+ }
673
+
674
+ .closure-hero span,
675
+ .closure-card-head span,
676
+ .closure-gaps-head span,
677
+ .closure-actions h3 {
678
+ font-family: var(--mono);
679
+ font-size: 10.5px;
680
+ letter-spacing: 0.08em;
681
+ text-transform: uppercase;
682
+ color: var(--ink-soft);
683
+ }
684
+
685
+ .closure-hero strong {
686
+ display: block;
687
+ margin-top: 4px;
688
+ font-family: var(--serif);
689
+ font-size: 46px;
690
+ line-height: 1;
691
+ font-weight: 400;
692
+ color: var(--ink);
693
+ }
694
+
695
+ .closure-hero p {
696
+ margin: 8px 0 0;
697
+ color: var(--ink-3);
698
+ font-size: 13px;
699
+ }
700
+
701
+ .closure-meter {
702
+ height: 10px;
703
+ overflow: hidden;
704
+ border-radius: 999px;
705
+ background: var(--paper-2);
706
+ border: 1px solid var(--rule-2);
707
+ }
708
+
709
+ .closure-meter span {
710
+ display: block;
711
+ height: 100%;
712
+ min-width: 0;
713
+ border-radius: inherit;
714
+ background: linear-gradient(90deg, var(--indigo), var(--good));
715
+ }
716
+
717
+ .closure-grid {
718
+ display: grid;
719
+ grid-template-columns: repeat(3, minmax(0, 1fr));
720
+ gap: 12px;
721
+ }
722
+
723
+ .closure-card {
724
+ min-width: 0;
725
+ padding: 16px;
726
+ border: 1px solid var(--rule-2);
727
+ border-radius: 12px;
728
+ background: var(--paper);
729
+ }
730
+
731
+ .closure-card.todo {
732
+ background: color-mix(in oklab, var(--amber), var(--paper) 92%);
733
+ }
734
+
735
+ .closure-card.done {
736
+ background: color-mix(in oklab, var(--good), var(--paper) 94%);
737
+ }
738
+
739
+ .closure-card-head {
740
+ display: flex;
741
+ align-items: center;
742
+ justify-content: space-between;
743
+ gap: 10px;
744
+ }
745
+
746
+ .closure-card-head b {
747
+ color: var(--ink);
748
+ font-size: 12px;
749
+ font-variant-numeric: tabular-nums;
750
+ white-space: nowrap;
751
+ }
752
+
753
+ .closure-card h3 {
754
+ margin: 11px 0 7px;
755
+ font-size: 16px;
756
+ line-height: 1.35;
757
+ color: var(--ink);
758
+ }
759
+
760
+ .closure-card p,
761
+ .closure-card strong {
762
+ display: block;
763
+ margin: 0;
764
+ color: var(--ink-3);
765
+ font-size: 12.5px;
766
+ line-height: 1.55;
767
+ }
768
+
769
+ .closure-card strong {
770
+ margin-top: 9px;
771
+ color: var(--ink);
772
+ }
773
+
774
+ .closure-gaps,
775
+ .closure-actions {
776
+ margin-top: 14px;
777
+ padding: 16px;
778
+ border: 1px solid var(--rule-2);
779
+ border-radius: 12px;
780
+ background: color-mix(in oklab, var(--paper-2), transparent 35%);
781
+ }
782
+
783
+ .closure-gaps-head {
784
+ display: flex;
785
+ align-items: baseline;
786
+ justify-content: space-between;
787
+ gap: 14px;
788
+ margin-bottom: 10px;
789
+ }
790
+
791
+ .closure-gaps-head h3,
792
+ .closure-actions h3 {
793
+ margin: 0;
794
+ color: var(--ink);
795
+ }
796
+
797
+ .closure-gaps-head h3 {
798
+ font-size: 15px;
799
+ }
800
+
801
+ .closure-gap-list {
802
+ display: grid;
803
+ gap: 1px;
804
+ overflow: hidden;
805
+ border: 1px solid var(--rule-2);
806
+ border-radius: 10px;
807
+ background: var(--rule-2);
808
+ }
809
+
810
+ .closure-gap-row {
811
+ display: grid;
812
+ grid-template-columns: 34px minmax(0, 1fr) auto;
813
+ gap: 12px;
814
+ align-items: center;
815
+ padding: 12px;
816
+ background: var(--paper);
817
+ }
818
+
819
+ .closure-gap-rank {
820
+ width: 28px;
821
+ height: 28px;
822
+ display: grid;
823
+ place-items: center;
824
+ border-radius: 8px;
825
+ background: var(--paper-2);
826
+ color: var(--ink-3);
827
+ font-family: var(--mono);
828
+ font-size: 11px;
829
+ }
830
+
831
+ .closure-gap-row strong,
832
+ .closure-gap-row b {
833
+ display: block;
834
+ color: var(--ink);
835
+ font-size: 13px;
836
+ line-height: 1.35;
837
+ overflow-wrap: anywhere;
838
+ }
839
+
840
+ .closure-gap-row span {
841
+ display: block;
842
+ margin-top: 3px;
843
+ color: var(--ink-3);
844
+ font-size: 12px;
845
+ line-height: 1.45;
846
+ overflow-wrap: anywhere;
847
+ }
848
+
849
+ .closure-gap-row b {
850
+ text-align: right;
851
+ font-family: var(--serif);
852
+ font-size: 19px;
853
+ font-weight: 400;
854
+ white-space: nowrap;
855
+ }
856
+
857
+ .closure-gap-row > div:last-child span {
858
+ text-align: right;
859
+ white-space: nowrap;
860
+ }
861
+
862
+ .closure-actions {
863
+ display: grid;
864
+ gap: 8px;
865
+ }
866
+
867
+ .closure-actions p {
868
+ margin: 0;
869
+ color: var(--ink-2);
870
+ font-size: 13px;
871
+ line-height: 1.55;
872
+ }
873
+
874
+ /* ─── ROI evidence score ─────────────────────────────────── */
875
+
876
+ .evidence-section {
877
+ padding-top: 48px;
878
+ }
879
+
880
+ .evidence-hero {
881
+ display: grid;
882
+ grid-template-columns: minmax(0, 1fr) 190px;
883
+ gap: 18px;
884
+ align-items: center;
885
+ padding: 22px 24px;
886
+ border: 1px solid var(--rule-2);
887
+ border-radius: 14px;
888
+ background: var(--paper);
889
+ margin-bottom: 14px;
890
+ }
891
+
892
+ .evidence-hero span,
893
+ .evidence-stat span {
894
+ font-family: var(--mono);
895
+ font-size: 10.5px;
896
+ letter-spacing: 0.08em;
897
+ text-transform: uppercase;
898
+ color: var(--ink-soft);
899
+ }
900
+
901
+ .evidence-hero strong {
902
+ display: block;
903
+ margin-top: 4px;
904
+ font-family: var(--serif);
905
+ font-size: 52px;
906
+ line-height: 1;
907
+ font-weight: 400;
908
+ color: var(--ink);
909
+ }
910
+
911
+ .evidence-hero p,
912
+ .evidence-stat p,
913
+ .evidence-gap-row p {
914
+ margin: 6px 0 0;
915
+ color: var(--ink-3);
916
+ font-size: 12.5px;
917
+ line-height: 1.5;
918
+ }
919
+
920
+ .evidence-meter {
921
+ height: 10px;
922
+ overflow: hidden;
923
+ border-radius: 999px;
924
+ background: var(--paper-2);
925
+ border: 1px solid var(--rule-2);
926
+ }
927
+
928
+ .evidence-meter span {
929
+ display: block;
930
+ height: 100%;
931
+ border-radius: inherit;
932
+ background: linear-gradient(90deg, var(--teal), var(--indigo));
933
+ }
934
+
935
+ .evidence-grid {
936
+ display: grid;
937
+ grid-template-columns: repeat(3, minmax(0, 1fr));
938
+ gap: 12px;
939
+ margin-bottom: 14px;
940
+ }
941
+
942
+ .evidence-stat {
943
+ padding: 16px;
944
+ border: 1px solid var(--rule-2);
945
+ border-radius: 12px;
946
+ background: var(--paper);
947
+ }
948
+
949
+ .evidence-stat strong {
950
+ display: block;
951
+ margin-top: 8px;
952
+ font-family: var(--serif);
953
+ font-size: 30px;
954
+ line-height: 1;
955
+ font-weight: 400;
956
+ color: var(--ink);
957
+ }
958
+
959
+ .evidence-gaps {
960
+ display: grid;
961
+ gap: 1px;
962
+ overflow: hidden;
963
+ border: 1px solid var(--rule-2);
964
+ border-radius: 12px;
965
+ background: var(--rule-2);
966
+ }
967
+
968
+ .evidence-gap-row {
969
+ display: grid;
970
+ grid-template-columns: 42px minmax(0, 1fr) auto;
971
+ align-items: center;
972
+ gap: 12px;
973
+ padding: 13px 14px;
974
+ background: var(--paper);
975
+ }
976
+
977
+ .evidence-gap-row span {
978
+ width: 30px;
979
+ height: 30px;
980
+ display: grid;
981
+ place-items: center;
982
+ border-radius: 9px;
983
+ background: var(--paper-2);
984
+ color: var(--ink-3);
985
+ font-family: var(--mono);
986
+ font-size: 11px;
987
+ }
988
+
989
+ .evidence-gap-row strong {
990
+ display: block;
991
+ color: var(--ink);
992
+ font-size: 13px;
993
+ line-height: 1.35;
994
+ overflow-wrap: anywhere;
995
+ }
996
+
997
+ .evidence-gap-row b {
998
+ font-family: var(--serif);
999
+ font-size: 19px;
1000
+ line-height: 1.2;
1001
+ font-weight: 400;
1002
+ white-space: nowrap;
1003
+ }
1004
+
1005
+ /* ─── Tools section ──────────────────────────────────────── */
1006
+
1007
+ .tools-split {
1008
+ display: grid;
1009
+ grid-template-columns: 280px 1fr;
1010
+ gap: 48px;
1011
+ align-items: flex-start;
1012
+ margin-top: 8px;
1013
+ }
1014
+
1015
+ .donut-wrap {
1016
+ position: relative;
1017
+ width: 280px;
1018
+ height: 280px;
1019
+ }
1020
+ .donut-center {
1021
+ position: absolute;
1022
+ inset: 0;
1023
+ display: grid; place-items: center;
1024
+ pointer-events: none;
1025
+ text-align: center;
1026
+ }
1027
+ .donut-center .l {
1028
+ font-family: var(--mono);
1029
+ font-size: 10.5px;
1030
+ text-transform: uppercase;
1031
+ letter-spacing: 0.12em;
1032
+ color: var(--ink-soft);
1033
+ }
1034
+ .donut-center .v {
1035
+ font-family: var(--serif);
1036
+ font-size: 32px;
1037
+ line-height: 1.1;
1038
+ margin-top: 4px;
1039
+ font-variant-numeric: lining-nums;
1040
+ }
1041
+ .donut-center .s {
1042
+ font-size: 11px;
1043
+ color: var(--ink-3);
1044
+ margin-top: 2px;
1045
+ font-variant-numeric: tabular-nums;
1046
+ }
1047
+
1048
+ .tool-list {
1049
+ display: flex;
1050
+ flex-direction: column;
1051
+ gap: 14px;
1052
+ }
1053
+ .tool-card {
1054
+ display: grid;
1055
+ grid-template-columns: 14px 1fr auto;
1056
+ align-items: center;
1057
+ gap: 14px;
1058
+ padding: 14px 0;
1059
+ border-bottom: 1px solid var(--rule-2);
1060
+ }
1061
+ .tool-card:last-child { border-bottom: 0; }
1062
+ .tool-dot {
1063
+ width: 10px; height: 10px;
1064
+ border-radius: 50%;
1065
+ }
1066
+ .tool-info { min-width: 0; }
1067
+ .tool-name {
1068
+ font-size: 14.5px;
1069
+ font-weight: 500;
1070
+ color: var(--ink);
1071
+ margin: 0 0 4px;
1072
+ letter-spacing: -0.005em;
1073
+ }
1074
+ .tool-model {
1075
+ font-family: var(--mono);
1076
+ font-size: 11.5px;
1077
+ color: var(--ink-3);
1078
+ }
1079
+ .tool-stats {
1080
+ text-align: right;
1081
+ display: flex;
1082
+ align-items: center;
1083
+ gap: 14px;
1084
+ }
1085
+ .tool-stats .tokens {
1086
+ font-family: var(--serif);
1087
+ font-size: 19px;
1088
+ color: var(--ink);
1089
+ font-variant-numeric: lining-nums;
1090
+ }
1091
+ .tool-stats .cost {
1092
+ font-size: 11.5px;
1093
+ color: var(--amber);
1094
+ font-variant-numeric: tabular-nums;
1095
+ margin-top: 4px;
1096
+ }
1097
+ .tool-badge {
1098
+ display: inline-flex;
1099
+ align-items: center;
1100
+ gap: 4px;
1101
+ height: 22px;
1102
+ padding: 0 8px;
1103
+ background: var(--paper-2);
1104
+ border: 1px solid var(--rule-2);
1105
+ border-radius: 999px;
1106
+ font-size: 11px;
1107
+ color: var(--ink-2);
1108
+ font-variant-numeric: tabular-nums;
1109
+ white-space: nowrap;
1110
+ }
1111
+ .tool-badge svg { width: 11px; height: 11px; opacity: 0.7; }
1112
+
1113
+ /* ─── Efficiency cards ───────────────────────────────────── */
1114
+
1115
+ .eff-grid {
1116
+ display: grid;
1117
+ grid-template-columns: repeat(3, 1fr);
1118
+ gap: 16px;
1119
+ margin-top: 8px;
1120
+ }
1121
+ .eff-card {
1122
+ background: var(--paper);
1123
+ border: 1px solid var(--rule-2);
1124
+ border-radius: 14px;
1125
+ padding: 22px 22px 24px;
1126
+ position: relative;
1127
+ }
1128
+ .eff-label {
1129
+ font-family: var(--mono);
1130
+ font-size: 10.5px;
1131
+ text-transform: uppercase;
1132
+ letter-spacing: 0.12em;
1133
+ color: var(--ink-soft);
1134
+ }
1135
+ .eff-value {
1136
+ font-family: var(--serif);
1137
+ font-size: 50px;
1138
+ line-height: 1;
1139
+ margin: 14px 0 12px;
1140
+ color: var(--ink);
1141
+ font-variant-numeric: lining-nums;
1142
+ letter-spacing: -0.02em;
1143
+ }
1144
+ .eff-value .unit {
1145
+ font-size: 22px;
1146
+ color: var(--ink-3);
1147
+ font-family: var(--serif);
1148
+ margin-left: 1px;
1149
+ }
1150
+ .eff-note {
1151
+ font-size: 12.5px;
1152
+ line-height: 1.55;
1153
+ color: var(--ink-3);
1154
+ margin: 0;
1155
+ text-wrap: pretty;
1156
+ }
1157
+ .eff-spark {
1158
+ margin-top: 14px;
1159
+ height: 32px;
1160
+ }
1161
+
1162
+ /* ─── ROI Advisor ────────────────────────────────────────── */
1163
+
1164
+ .savings-hero {
1165
+ display: grid;
1166
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1167
+ gap: 12px;
1168
+ margin-bottom: 14px;
1169
+ }
1170
+
1171
+ .savings-hero > div,
1172
+ .savings-card,
1173
+ .savings-unpriced {
1174
+ border: 1px solid var(--rule-2);
1175
+ border-radius: 14px;
1176
+ background: var(--paper);
1177
+ }
1178
+
1179
+ .savings-hero > div {
1180
+ padding: 18px;
1181
+ }
1182
+
1183
+ .savings-hero span,
1184
+ .savings-head span,
1185
+ .savings-metrics span,
1186
+ .savings-detail span,
1187
+ .savings-unpriced h3 {
1188
+ font-family: var(--mono);
1189
+ font-size: 10.5px;
1190
+ letter-spacing: 0.08em;
1191
+ text-transform: uppercase;
1192
+ color: var(--ink-soft);
1193
+ }
1194
+
1195
+ .savings-hero strong {
1196
+ display: block;
1197
+ margin-top: 6px;
1198
+ font-family: var(--serif);
1199
+ font-size: 42px;
1200
+ line-height: 1;
1201
+ font-weight: 400;
1202
+ color: var(--ink);
1203
+ }
1204
+
1205
+ .savings-hero p,
1206
+ .savings-card p,
1207
+ .savings-unpriced p {
1208
+ margin: 7px 0 0;
1209
+ color: var(--ink-3);
1210
+ font-size: 13px;
1211
+ line-height: 1.55;
1212
+ }
1213
+
1214
+ .savings-list {
1215
+ display: grid;
1216
+ gap: 14px;
1217
+ }
1218
+
1219
+ .savings-card {
1220
+ display: grid;
1221
+ grid-template-columns: 44px minmax(0, 1fr);
1222
+ gap: 16px;
1223
+ padding: 20px;
1224
+ }
1225
+
1226
+ .savings-rank {
1227
+ width: 34px;
1228
+ height: 34px;
1229
+ display: grid;
1230
+ place-items: center;
1231
+ border-radius: 10px;
1232
+ background: color-mix(in oklab, var(--green), transparent 88%);
1233
+ color: var(--ink);
1234
+ font-family: var(--mono);
1235
+ font-size: 11px;
1236
+ }
1237
+
1238
+ .savings-body {
1239
+ min-width: 0;
1240
+ }
1241
+
1242
+ .savings-head {
1243
+ display: flex;
1244
+ align-items: flex-start;
1245
+ justify-content: space-between;
1246
+ gap: 14px;
1247
+ }
1248
+
1249
+ .savings-head h3 {
1250
+ margin: 5px 0 0;
1251
+ font-size: 18px;
1252
+ line-height: 1.35;
1253
+ color: var(--ink);
1254
+ }
1255
+
1256
+ .savings-head strong {
1257
+ flex-shrink: 0;
1258
+ font-family: var(--serif);
1259
+ font-size: 24px;
1260
+ font-weight: 400;
1261
+ color: var(--good);
1262
+ font-variant-numeric: tabular-nums;
1263
+ }
1264
+
1265
+ .savings-metrics {
1266
+ display: grid;
1267
+ grid-template-columns: repeat(4, minmax(0, 1fr));
1268
+ gap: 8px;
1269
+ margin-top: 14px;
1270
+ }
1271
+
1272
+ .savings-metrics > div,
1273
+ .savings-detail {
1274
+ border: 1px solid var(--rule-2);
1275
+ border-radius: 10px;
1276
+ background: color-mix(in oklab, var(--paper-2), transparent 35%);
1277
+ }
1278
+
1279
+ .savings-metrics > div {
1280
+ min-width: 0;
1281
+ padding: 10px;
1282
+ }
1283
+
1284
+ .savings-metrics strong {
1285
+ display: block;
1286
+ margin-top: 4px;
1287
+ color: var(--ink);
1288
+ font-size: 13px;
1289
+ line-height: 1.35;
1290
+ overflow-wrap: anywhere;
1291
+ }
1292
+
1293
+ .savings-detail {
1294
+ display: grid;
1295
+ gap: 5px;
1296
+ margin-top: 12px;
1297
+ padding: 12px 14px;
1298
+ }
1299
+
1300
+ .savings-detail p {
1301
+ margin: 0 0 7px;
1302
+ }
1303
+
1304
+ .savings-detail p:last-child {
1305
+ margin-bottom: 0;
1306
+ }
1307
+
1308
+ .savings-unpriced {
1309
+ margin-top: 14px;
1310
+ padding: 16px;
1311
+ background: color-mix(in oklab, var(--amber), var(--paper) 92%);
1312
+ }
1313
+
1314
+ .savings-unpriced h3 {
1315
+ margin: 0 0 6px;
1316
+ color: var(--ink-soft);
1317
+ }
1318
+
1319
+ .advisor-list {
1320
+ display: grid;
1321
+ gap: 14px;
1322
+ }
1323
+
1324
+ .advisor-card {
1325
+ display: grid;
1326
+ grid-template-columns: 44px minmax(0, 1fr);
1327
+ gap: 16px;
1328
+ padding: 20px;
1329
+ background: var(--paper);
1330
+ border: 1px solid var(--rule-2);
1331
+ border-radius: 14px;
1332
+ }
1333
+
1334
+ .advisor-rank {
1335
+ width: 34px;
1336
+ height: 34px;
1337
+ display: grid;
1338
+ place-items: center;
1339
+ border-radius: 10px;
1340
+ background: var(--paper-2);
1341
+ color: var(--ink-3);
1342
+ font-family: var(--mono);
1343
+ font-size: 11px;
1344
+ }
1345
+
1346
+ .advisor-body {
1347
+ min-width: 0;
1348
+ }
1349
+
1350
+ .advisor-head {
1351
+ display: flex;
1352
+ align-items: flex-start;
1353
+ justify-content: space-between;
1354
+ gap: 14px;
1355
+ }
1356
+
1357
+ .advisor-head h3 {
1358
+ margin: 5px 0 0;
1359
+ font-size: 18px;
1360
+ line-height: 1.35;
1361
+ color: var(--ink);
1362
+ letter-spacing: -0.01em;
1363
+ }
1364
+
1365
+ .advisor-meta {
1366
+ display: flex;
1367
+ flex-wrap: wrap;
1368
+ gap: 6px;
1369
+ align-items: center;
1370
+ }
1371
+
1372
+ .advisor-category {
1373
+ display: inline-flex;
1374
+ align-items: center;
1375
+ min-height: 20px;
1376
+ padding: 2px 7px;
1377
+ border-radius: 999px;
1378
+ background: color-mix(in oklab, var(--green), transparent 86%);
1379
+ color: var(--ink);
1380
+ }
1381
+
1382
+ .advisor-impact {
1383
+ display: inline-flex;
1384
+ align-items: center;
1385
+ min-height: 20px;
1386
+ }
1387
+
1388
+ .advisor-category,
1389
+ .advisor-impact,
1390
+ .advisor-tone,
1391
+ .advisor-grid span,
1392
+ .advisor-action span {
1393
+ font-family: var(--mono);
1394
+ font-size: 10.5px;
1395
+ letter-spacing: 0.08em;
1396
+ text-transform: uppercase;
1397
+ color: var(--ink-soft);
1398
+ }
1399
+
1400
+ .advisor-tone {
1401
+ flex-shrink: 0;
1402
+ padding: 4px 8px;
1403
+ border-radius: 999px;
1404
+ background: var(--paper-2);
1405
+ border: 1px solid var(--rule-2);
1406
+ }
1407
+
1408
+ .advisor-recommendation {
1409
+ margin: 12px 0 14px;
1410
+ color: var(--ink);
1411
+ font-size: 14px;
1412
+ line-height: 1.7;
1413
+ }
1414
+
1415
+ .advisor-grid {
1416
+ display: grid;
1417
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1418
+ gap: 12px;
1419
+ }
1420
+
1421
+ .advisor-grid > div,
1422
+ .advisor-action {
1423
+ padding: 12px 14px;
1424
+ border-radius: 10px;
1425
+ background: color-mix(in oklab, var(--paper-2), transparent 35%);
1426
+ border: 1px solid var(--rule-2);
1427
+ }
1428
+
1429
+ .advisor-grid p {
1430
+ margin: 5px 0 0;
1431
+ font-size: 12.5px;
1432
+ color: var(--ink-3);
1433
+ line-height: 1.6;
1434
+ }
1435
+
1436
+ .advisor-action {
1437
+ margin-top: 12px;
1438
+ display: grid;
1439
+ gap: 5px;
1440
+ }
1441
+
1442
+ .advisor-action strong {
1443
+ font-size: 13px;
1444
+ line-height: 1.55;
1445
+ color: var(--ink);
1446
+ }
1447
+
1448
+ .advisor-actions {
1449
+ display: flex;
1450
+ flex-wrap: wrap;
1451
+ gap: 8px;
1452
+ margin-top: 14px;
1453
+ }
1454
+
1455
+ .advisor-actions button {
1456
+ height: 30px;
1457
+ padding: 0 11px;
1458
+ border: 1px solid var(--rule);
1459
+ border-radius: 8px;
1460
+ background: var(--paper-2);
1461
+ color: var(--ink-2);
1462
+ font-size: 12px;
1463
+ cursor: pointer;
1464
+ }
1465
+
1466
+ .advisor-actions button:hover {
1467
+ background: var(--paper-3);
1468
+ color: var(--ink);
1469
+ }
1470
+
1471
+ .advisor-action-loop {
1472
+ display: flex;
1473
+ flex-wrap: wrap;
1474
+ align-items: center;
1475
+ gap: 8px;
1476
+ margin-top: 10px;
1477
+ padding-top: 10px;
1478
+ border-top: 1px solid var(--rule-2);
1479
+ }
1480
+
1481
+ .advisor-action-loop button {
1482
+ min-height: 30px;
1483
+ padding: 0 11px;
1484
+ border: 1px solid var(--rule);
1485
+ border-radius: 8px;
1486
+ background: var(--paper);
1487
+ color: var(--ink-2);
1488
+ font-size: 12px;
1489
+ cursor: pointer;
1490
+ }
1491
+
1492
+ .advisor-action-loop button:hover:not(:disabled) {
1493
+ background: var(--paper-3);
1494
+ color: var(--ink);
1495
+ }
1496
+
1497
+ .advisor-action-loop button:disabled {
1498
+ opacity: 0.55;
1499
+ cursor: wait;
1500
+ }
1501
+
1502
+ .advisor-action-status {
1503
+ display: inline-flex;
1504
+ align-items: center;
1505
+ min-height: 30px;
1506
+ padding: 0 10px;
1507
+ border-radius: 999px;
1508
+ background: var(--paper-2);
1509
+ color: var(--ink-3);
1510
+ font-size: 12px;
1511
+ font-weight: 700;
1512
+ }
1513
+
1514
+ .advisor-action-status.status-done {
1515
+ background: color-mix(in oklab, var(--good), transparent 86%);
1516
+ color: var(--ink);
1517
+ }
1518
+
1519
+ .advisor-action-status.status-dismissed {
1520
+ background: color-mix(in oklab, var(--ink-soft), transparent 88%);
1521
+ color: var(--ink-3);
1522
+ }
1523
+
1524
+ .advisor-action-summary-section {
1525
+ padding-top: 48px;
1526
+ }
1527
+
1528
+ .action-summary-hero {
1529
+ display: grid;
1530
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1531
+ gap: 12px;
1532
+ margin-bottom: 14px;
1533
+ }
1534
+
1535
+ .action-summary-hero > div {
1536
+ min-width: 0;
1537
+ padding: 18px;
1538
+ border: 1px solid var(--rule-2);
1539
+ border-radius: 14px;
1540
+ background: var(--paper);
1541
+ }
1542
+
1543
+ .action-summary-hero span,
1544
+ .action-summary-card-head span {
1545
+ font-family: var(--mono);
1546
+ font-size: 10.5px;
1547
+ letter-spacing: 0.08em;
1548
+ text-transform: uppercase;
1549
+ color: var(--ink-soft);
1550
+ }
1551
+
1552
+ .action-summary-hero strong {
1553
+ display: block;
1554
+ margin-top: 6px;
1555
+ font-family: var(--serif);
1556
+ font-size: 42px;
1557
+ line-height: 1;
1558
+ font-weight: 400;
1559
+ color: var(--ink);
1560
+ }
1561
+
1562
+ .action-summary-hero p {
1563
+ margin: 8px 0 0;
1564
+ color: var(--ink-3);
1565
+ font-size: 12.5px;
1566
+ line-height: 1.5;
1567
+ }
1568
+
1569
+ .action-summary-toolbar {
1570
+ display: flex;
1571
+ justify-content: flex-end;
1572
+ margin-bottom: 12px;
1573
+ }
1574
+
1575
+ .action-summary-toolbar button,
1576
+ .action-summary-card-actions button {
1577
+ height: 34px;
1578
+ padding: 0 12px;
1579
+ border: 1px solid var(--rule);
1580
+ border-radius: 8px;
1581
+ background: var(--paper);
1582
+ color: var(--ink-2);
1583
+ cursor: pointer;
1584
+ font-size: 12px;
1585
+ }
1586
+
1587
+ .action-summary-toolbar button:hover,
1588
+ .action-summary-card-actions button:hover {
1589
+ border-color: var(--ink-soft);
1590
+ color: var(--ink);
1591
+ }
1592
+
1593
+ .action-summary-toolbar button:disabled,
1594
+ .action-summary-card-actions button:disabled {
1595
+ cursor: not-allowed;
1596
+ opacity: 0.5;
1597
+ }
1598
+
1599
+ .action-summary-list {
1600
+ display: grid;
1601
+ gap: 10px;
1602
+ }
1603
+
1604
+ .action-summary-card {
1605
+ display: grid;
1606
+ gap: 10px;
1607
+ padding: 16px;
1608
+ border: 1px solid var(--rule-2);
1609
+ border-radius: 14px;
1610
+ background: var(--paper);
1611
+ }
1612
+
1613
+ .action-summary-card.status-open {
1614
+ border-color: color-mix(in oklab, var(--indigo), transparent 70%);
1615
+ }
1616
+
1617
+ .action-summary-card.status-done {
1618
+ border-color: color-mix(in oklab, var(--good), transparent 70%);
1619
+ background: color-mix(in oklab, var(--good), var(--paper) 94%);
1620
+ }
1621
+
1622
+ .action-summary-card.status-dismissed {
1623
+ opacity: 0.78;
1624
+ }
1625
+
1626
+ .action-summary-card-head {
1627
+ display: flex;
1628
+ justify-content: space-between;
1629
+ gap: 12px;
1630
+ align-items: center;
1631
+ }
1632
+
1633
+ .action-summary-card-head b {
1634
+ color: var(--ink-2);
1635
+ font-size: 12px;
1636
+ }
1637
+
1638
+ .action-summary-card h3 {
1639
+ margin: 0;
1640
+ color: var(--ink);
1641
+ font-size: 17px;
1642
+ line-height: 1.35;
1643
+ }
1644
+
1645
+ .action-summary-card p,
1646
+ .action-summary-card small {
1647
+ margin: 0;
1648
+ color: var(--ink-3);
1649
+ font-size: 12.5px;
1650
+ line-height: 1.55;
1651
+ overflow-wrap: anywhere;
1652
+ }
1653
+
1654
+ .action-summary-card small {
1655
+ color: var(--ink-soft);
1656
+ }
1657
+
1658
+ .action-summary-card-actions {
1659
+ display: flex;
1660
+ flex-wrap: wrap;
1661
+ gap: 8px;
1662
+ }
1663
+
1664
+ .advisor-risk .advisor-rank,
1665
+ .advisor-risk .advisor-tone {
1666
+ background: color-mix(in oklab, var(--amber), transparent 86%);
1667
+ color: var(--ink);
1668
+ }
1669
+ .advisor-optimize .advisor-rank,
1670
+ .advisor-optimize .advisor-tone {
1671
+ background: color-mix(in oklab, var(--indigo), transparent 88%);
1672
+ color: var(--ink);
1673
+ }
1674
+ .advisor-good .advisor-rank,
1675
+ .advisor-good .advisor-tone {
1676
+ background: color-mix(in oklab, var(--good), transparent 88%);
1677
+ color: var(--ink);
1678
+ }
1679
+
1680
+ /* ─── Model strategy ─────────────────────────────────────── */
1681
+
1682
+ .strategy-coverage {
1683
+ display: grid;
1684
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1685
+ border: 1px solid var(--rule-2);
1686
+ border-radius: 12px;
1687
+ overflow: hidden;
1688
+ background: var(--paper);
1689
+ margin-bottom: 18px;
1690
+ }
1691
+
1692
+ .strategy-coverage > div {
1693
+ padding: 18px;
1694
+ border-right: 1px solid var(--rule-2);
1695
+ }
1696
+ .strategy-coverage > div:last-child { border-right: 0; }
1697
+
1698
+ .strategy-coverage span,
1699
+ .strategy-panel h3,
1700
+ .strategy-risk h3 {
1701
+ font-family: var(--mono);
1702
+ font-size: 10.5px;
1703
+ letter-spacing: 0.08em;
1704
+ text-transform: uppercase;
1705
+ color: var(--ink-soft);
1706
+ }
1707
+
1708
+ .strategy-coverage strong {
1709
+ display: block;
1710
+ font-family: var(--serif);
1711
+ font-size: 38px;
1712
+ line-height: 1.1;
1713
+ font-weight: 400;
1714
+ margin-top: 5px;
1715
+ }
1716
+
1717
+ .strategy-coverage p {
1718
+ margin: 6px 0 0;
1719
+ color: var(--ink-3);
1720
+ font-size: 13px;
1721
+ }
1722
+
1723
+ .strategy-grid {
1724
+ display: grid;
1725
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1726
+ gap: 12px;
1727
+ }
1728
+
1729
+ .strategy-playbook {
1730
+ display: grid;
1731
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1732
+ gap: 12px;
1733
+ margin-bottom: 14px;
1734
+ }
1735
+
1736
+ .strategy-policy {
1737
+ padding: 16px;
1738
+ border: 1px solid var(--rule-2);
1739
+ border-radius: 12px;
1740
+ background: var(--paper);
1741
+ }
1742
+
1743
+ .strategy-policy-light {
1744
+ background: color-mix(in oklab, var(--good), var(--paper) 92%);
1745
+ }
1746
+
1747
+ .strategy-policy-mid {
1748
+ background: color-mix(in oklab, var(--indigo), var(--paper) 93%);
1749
+ }
1750
+
1751
+ .strategy-policy-heavy {
1752
+ background: color-mix(in oklab, var(--amber), var(--paper) 92%);
1753
+ }
1754
+
1755
+ .strategy-policy-head {
1756
+ display: flex;
1757
+ align-items: center;
1758
+ justify-content: space-between;
1759
+ gap: 10px;
1760
+ }
1761
+
1762
+ .strategy-policy-head span,
1763
+ .strategy-policy-head b,
1764
+ .strategy-policy-evidence span {
1765
+ font-family: var(--mono);
1766
+ font-size: 10.5px;
1767
+ letter-spacing: 0.08em;
1768
+ text-transform: uppercase;
1769
+ color: var(--ink-soft);
1770
+ }
1771
+
1772
+ .strategy-policy-head b {
1773
+ padding: 3px 7px;
1774
+ border-radius: 999px;
1775
+ background: color-mix(in oklab, var(--paper-2), transparent 18%);
1776
+ color: var(--ink-2);
1777
+ font-weight: 600;
1778
+ white-space: nowrap;
1779
+ }
1780
+
1781
+ .strategy-policy h3 {
1782
+ margin: 10px 0 7px;
1783
+ font-size: 16px;
1784
+ line-height: 1.35;
1785
+ color: var(--ink);
1786
+ }
1787
+
1788
+ .strategy-policy p {
1789
+ margin: 0;
1790
+ min-height: 44px;
1791
+ color: var(--ink-3);
1792
+ font-size: 12.5px;
1793
+ line-height: 1.55;
1794
+ }
1795
+
1796
+ .strategy-policy-evidence {
1797
+ display: grid;
1798
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1799
+ gap: 8px;
1800
+ margin-top: 14px;
1801
+ }
1802
+
1803
+ .strategy-policy-evidence > div {
1804
+ min-width: 0;
1805
+ padding: 9px 10px;
1806
+ border-radius: 10px;
1807
+ background: color-mix(in oklab, var(--paper), transparent 22%);
1808
+ border: 1px solid var(--rule-2);
1809
+ }
1810
+
1811
+ .strategy-policy-evidence strong {
1812
+ display: block;
1813
+ margin-top: 4px;
1814
+ font-size: 12.5px;
1815
+ line-height: 1.35;
1816
+ color: var(--ink);
1817
+ overflow-wrap: anywhere;
1818
+ }
1819
+
1820
+ .strategy-panel {
1821
+ border: 1px solid var(--rule-2);
1822
+ border-radius: 12px;
1823
+ background: var(--paper);
1824
+ padding: 16px;
1825
+ }
1826
+
1827
+ .strategy-panel h3,
1828
+ .strategy-risk h3 {
1829
+ margin: 0 0 12px;
1830
+ }
1831
+
1832
+ .strategy-row,
1833
+ .strategy-risk-row {
1834
+ display: grid;
1835
+ grid-template-columns: minmax(0, 1fr) auto;
1836
+ gap: 12px;
1837
+ align-items: start;
1838
+ padding: 12px 0;
1839
+ border-top: 1px solid var(--rule-2);
1840
+ }
1841
+ .strategy-row:first-of-type,
1842
+ .strategy-risk-row:first-of-type { border-top: 0; padding-top: 0; }
1843
+
1844
+ .strategy-row strong,
1845
+ .strategy-risk-row strong {
1846
+ display: block;
1847
+ color: var(--ink);
1848
+ font-size: 13px;
1849
+ line-height: 1.35;
1850
+ overflow-wrap: anywhere;
1851
+ }
1852
+
1853
+ .strategy-row span,
1854
+ .strategy-risk-row span,
1855
+ .strategy-empty {
1856
+ display: block;
1857
+ color: var(--ink-3);
1858
+ font-size: 12px;
1859
+ line-height: 1.45;
1860
+ margin-top: 3px;
1861
+ }
1862
+
1863
+ .strategy-row b,
1864
+ .strategy-risk-row b {
1865
+ display: block;
1866
+ font-family: var(--serif);
1867
+ font-size: 18px;
1868
+ line-height: 1.2;
1869
+ font-weight: 400;
1870
+ text-align: right;
1871
+ }
1872
+
1873
+ .strategy-empty {
1874
+ margin: 0;
1875
+ }
1876
+
1877
+ .strategy-risk {
1878
+ margin-top: 14px;
1879
+ padding: 16px;
1880
+ border: 1px solid var(--rule-2);
1881
+ border-radius: 12px;
1882
+ background: color-mix(in oklab, var(--paper-2), transparent 35%);
1883
+ }
1884
+
1885
+ .strategy-recommendations {
1886
+ display: grid;
1887
+ gap: 10px;
1888
+ margin-top: 14px;
1889
+ }
1890
+
1891
+ .strategy-recommendations article {
1892
+ padding: 14px 16px;
1893
+ border: 1px solid var(--rule-2);
1894
+ border-radius: 12px;
1895
+ background: var(--paper);
1896
+ }
1897
+
1898
+ .strategy-recommendations h3 {
1899
+ margin: 0 0 6px;
1900
+ font-size: 15px;
1901
+ }
1902
+
1903
+ .strategy-recommendations p,
1904
+ .strategy-recommendations strong {
1905
+ display: block;
1906
+ margin: 0;
1907
+ font-size: 13px;
1908
+ line-height: 1.55;
1909
+ }
1910
+
1911
+ .strategy-recommendations p { color: var(--ink-3); }
1912
+ .strategy-recommendations strong { color: var(--ink); margin-top: 6px; }
1913
+
1914
+ /* ─── Insight cards ──────────────────────────────────────── */
1915
+
1916
+ .insights {
1917
+ display: flex;
1918
+ flex-direction: column;
1919
+ gap: 12px;
1920
+ margin-top: 8px;
1921
+ }
1922
+ .insight {
1923
+ background: var(--paper);
1924
+ border: 1px solid var(--rule-2);
1925
+ border-radius: 12px;
1926
+ padding: 18px 22px;
1927
+ cursor: pointer;
1928
+ transition: background 140ms ease, border-color 140ms ease;
1929
+ position: relative;
1930
+ }
1931
+ .insight:hover {
1932
+ background: oklch(0.985 0.006 80);
1933
+ border-color: var(--rule);
1934
+ }
1935
+ .insight-head {
1936
+ display: grid;
1937
+ grid-template-columns: 28px 1fr 16px;
1938
+ align-items: flex-start;
1939
+ gap: 14px;
1940
+ }
1941
+ .insight-emoji {
1942
+ width: 28px; height: 28px;
1943
+ display: grid; place-items: center;
1944
+ border-radius: 8px;
1945
+ font-size: 14px;
1946
+ flex-shrink: 0;
1947
+ background: var(--paper-2);
1948
+ }
1949
+ .insight-emoji.red { background: color-mix(in oklab, var(--bad), transparent 88%); }
1950
+ .insight-emoji.yellow { background: color-mix(in oklab, var(--amber), transparent 86%); }
1951
+ .insight-emoji.green { background: color-mix(in oklab, var(--good), transparent 88%); }
1952
+ .insight-emoji.blue { background: color-mix(in oklab, var(--indigo), transparent 88%); }
1953
+
1954
+ .insight-text {
1955
+ font-size: 14.5px;
1956
+ line-height: 1.55;
1957
+ color: var(--ink);
1958
+ text-wrap: pretty;
1959
+ }
1960
+ .insight-text b { font-weight: 600; }
1961
+
1962
+ .insight-arrow {
1963
+ color: var(--ink-soft);
1964
+ transition: transform 220ms ease;
1965
+ margin-top: 6px;
1966
+ }
1967
+ .insight.open .insight-arrow { transform: rotate(180deg); color: var(--ink); }
1968
+
1969
+ .insight-body {
1970
+ max-height: 0;
1971
+ overflow: hidden;
1972
+ transition: max-height 320ms cubic-bezier(0.4, 0, 0.2, 1), padding 200ms ease, opacity 200ms ease;
1973
+ opacity: 0;
1974
+ }
1975
+ .insight.open .insight-body {
1976
+ max-height: 400px;
1977
+ padding-top: 18px;
1978
+ margin-top: 14px;
1979
+ border-top: 1px solid var(--rule-2);
1980
+ opacity: 1;
1981
+ }
1982
+ .insight-detail {
1983
+ display: grid;
1984
+ grid-template-columns: repeat(3, 1fr);
1985
+ gap: 18px;
1986
+ font-size: 12.5px;
1987
+ }
1988
+ .insight-detail .k {
1989
+ font-family: var(--mono);
1990
+ font-size: 10.5px;
1991
+ color: var(--ink-soft);
1992
+ text-transform: uppercase;
1993
+ letter-spacing: 0.08em;
1994
+ margin-bottom: 4px;
1995
+ }
1996
+ .insight-detail .v {
1997
+ font-family: var(--serif);
1998
+ font-size: 18px;
1999
+ color: var(--ink);
2000
+ font-variant-numeric: lining-nums;
2001
+ }
2002
+ .insight-narrative {
2003
+ font-size: 13px;
2004
+ color: var(--ink-3);
2005
+ margin-top: 14px;
2006
+ line-height: 1.6;
2007
+ text-wrap: pretty;
2008
+ }
2009
+
2010
+ /* ─── Footer ─────────────────────────────────────────────── */
2011
+
2012
+ .review-footer {
2013
+ border-top: 1px solid var(--rule-2);
2014
+ padding: 40px 32px 60px;
2015
+ background: var(--paper-2);
2016
+ position: relative; z-index: 1;
2017
+ }
2018
+ .review-footer-inner {
2019
+ max-width: 780px;
2020
+ margin: 0 auto;
2021
+ display: flex;
2022
+ align-items: center;
2023
+ justify-content: space-between;
2024
+ gap: 24px;
2025
+ flex-wrap: wrap;
2026
+ }
2027
+
2028
+ .period-jump {
2029
+ display: inline-flex;
2030
+ align-items: center;
2031
+ gap: 12px;
2032
+ }
2033
+ .period-jump button {
2034
+ display: inline-flex;
2035
+ align-items: center;
2036
+ gap: 8px;
2037
+ height: 36px;
2038
+ padding: 0 14px;
2039
+ background: var(--paper);
2040
+ border: 1px solid var(--rule);
2041
+ border-radius: 8px;
2042
+ cursor: pointer;
2043
+ color: var(--ink-2);
2044
+ font-size: 13px;
2045
+ }
2046
+ .period-jump button:hover { background: var(--paper); border-color: var(--ink-soft); color: var(--ink); }
2047
+ .period-jump button:disabled { opacity: 0.4; cursor: not-allowed; }
2048
+ .period-current {
2049
+ font-family: var(--serif);
2050
+ font-size: 20px;
2051
+ color: var(--ink);
2052
+ font-variant-numeric: lining-nums;
2053
+ min-width: 180px;
2054
+ text-align: center;
2055
+ }
2056
+
2057
+ .export-btn {
2058
+ display: inline-flex;
2059
+ align-items: center;
2060
+ gap: 8px;
2061
+ height: 36px;
2062
+ padding: 0 16px;
2063
+ background: var(--ink);
2064
+ color: var(--paper);
2065
+ border: 0;
2066
+ border-radius: 8px;
2067
+ cursor: pointer;
2068
+ font-size: 13px;
2069
+ font-weight: 500;
2070
+ }
2071
+ .export-btn:hover { background: oklch(0.25 0.010 60); }
2072
+
2073
+ .review-page-controls {
2074
+ position: fixed;
2075
+ right: 22px;
2076
+ top: 50%;
2077
+ bottom: auto;
2078
+ transform: translateY(-50%);
2079
+ z-index: 35;
2080
+ display: grid;
2081
+ grid-template-columns: 1fr;
2082
+ align-items: center;
2083
+ gap: 8px;
2084
+ width: 152px;
2085
+ padding: 9px;
2086
+ border: 1px solid var(--rule-2);
2087
+ border-radius: 12px;
2088
+ background: color-mix(in oklab, var(--paper), transparent 6%);
2089
+ box-shadow: 0 18px 50px -30px rgb(0 0 0 / 0.42);
2090
+ backdrop-filter: blur(12px);
2091
+ -webkit-backdrop-filter: blur(12px);
2092
+ }
2093
+
2094
+ .review-page-btn {
2095
+ height: 34px;
2096
+ padding: 0 12px;
2097
+ border: 1px solid var(--rule);
2098
+ border-radius: 8px;
2099
+ background: var(--paper);
2100
+ color: var(--ink-2);
2101
+ cursor: pointer;
2102
+ display: inline-flex;
2103
+ align-items: center;
2104
+ justify-content: center;
2105
+ gap: 6px;
2106
+ font-size: 12.5px;
2107
+ white-space: nowrap;
2108
+ }
2109
+
2110
+ .review-page-btn:hover {
2111
+ border-color: var(--ink-soft);
2112
+ color: var(--ink);
2113
+ }
2114
+
2115
+ .review-page-btn.primary {
2116
+ background: var(--ink);
2117
+ border-color: var(--ink);
2118
+ color: var(--paper);
2119
+ }
2120
+
2121
+ .review-page-btn.primary:hover {
2122
+ background: oklch(0.25 0.010 60);
2123
+ color: var(--paper);
2124
+ }
2125
+
2126
+ .review-page-btn:disabled {
2127
+ opacity: 0.42;
2128
+ cursor: not-allowed;
2129
+ }
2130
+
2131
+ .review-page-current {
2132
+ min-width: 92px;
2133
+ padding: 0 8px;
2134
+ display: grid;
2135
+ gap: 1px;
2136
+ justify-items: center;
2137
+ line-height: 1.2;
2138
+ }
2139
+
2140
+ .review-page-current strong {
2141
+ color: var(--ink);
2142
+ font-family: var(--mono);
2143
+ font-size: 11px;
2144
+ font-weight: 600;
2145
+ font-variant-numeric: tabular-nums;
2146
+ }
2147
+
2148
+ .review-page-current span {
2149
+ max-width: 92px;
2150
+ overflow: hidden;
2151
+ text-overflow: ellipsis;
2152
+ color: var(--ink-3);
2153
+ font-size: 11.5px;
2154
+ white-space: nowrap;
2155
+ }
2156
+
2157
+ .review-page-dots {
2158
+ display: inline-flex;
2159
+ flex-wrap: wrap;
2160
+ justify-content: center;
2161
+ align-items: center;
2162
+ gap: 5px;
2163
+ padding: 0 4px;
2164
+ }
2165
+
2166
+ .review-page-dot {
2167
+ width: 7px;
2168
+ height: 7px;
2169
+ padding: 0;
2170
+ border: 0;
2171
+ border-radius: 999px;
2172
+ background: var(--rule);
2173
+ cursor: pointer;
2174
+ transition:
2175
+ width 160ms ease,
2176
+ background 160ms ease,
2177
+ opacity 160ms ease;
2178
+ }
2179
+
2180
+ .review-page-dot:hover {
2181
+ background: var(--ink-soft);
2182
+ }
2183
+
2184
+ .review-page-dot.active {
2185
+ width: 18px;
2186
+ background: var(--ink);
2187
+ }
2188
+
2189
+ /* ─── Misc ───────────────────────────────────────────────── */
2190
+
2191
+ .divider-rule {
2192
+ margin: 60px 0;
2193
+ height: 1px;
2194
+ background: var(--rule-2);
2195
+ }
2196
+
2197
+ .no-data {
2198
+ padding: 32px;
2199
+ text-align: center;
2200
+ color: var(--ink-soft);
2201
+ font-size: 13.5px;
2202
+ font-style: italic;
2203
+ font-family: var(--serif);
2204
+ }
2205
+
2206
+ /* responsive */
2207
+ @media (max-width: 720px) {
2208
+ .review-nav-inner {
2209
+ align-items: flex-start;
2210
+ flex-wrap: wrap;
2211
+ padding: 10px 18px;
2212
+ }
2213
+ .brand-line,
2214
+ .period-switch,
2215
+ .nav-actions {
2216
+ max-width: 100%;
2217
+ overflow-x: auto;
2218
+ }
2219
+ .stat-strip { grid-template-columns: repeat(2, 1fr); }
2220
+ .eff-grid { grid-template-columns: 1fr; }
2221
+ .closure-hero { grid-template-columns: 1fr; }
2222
+ .closure-grid { grid-template-columns: 1fr; }
2223
+ .evidence-hero { grid-template-columns: 1fr; }
2224
+ .evidence-grid { grid-template-columns: 1fr; }
2225
+ .evidence-gap-row { grid-template-columns: 1fr; }
2226
+ .evidence-gap-row b { white-space: normal; }
2227
+ .closure-gaps-head { align-items: flex-start; flex-direction: column; gap: 4px; }
2228
+ .closure-gap-row { grid-template-columns: 1fr; }
2229
+ .closure-gap-rank { width: 100%; justify-content: start; padding-left: 9px; }
2230
+ .closure-gap-row b,
2231
+ .closure-gap-row > div:last-child span { text-align: left; }
2232
+ .savings-hero { grid-template-columns: 1fr; }
2233
+ .savings-card { grid-template-columns: 1fr; }
2234
+ .savings-head { flex-direction: column; }
2235
+ .savings-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
2236
+ .advisor-card { grid-template-columns: 1fr; }
2237
+ .advisor-head { flex-direction: column; }
2238
+ .advisor-grid { grid-template-columns: 1fr; }
2239
+ .action-summary-hero { grid-template-columns: 1fr; }
2240
+ .action-summary-toolbar { justify-content: stretch; }
2241
+ .action-summary-toolbar button { width: 100%; }
2242
+ .strategy-coverage { grid-template-columns: 1fr; }
2243
+ .strategy-coverage > div {
2244
+ border-right: 0;
2245
+ border-bottom: 1px solid var(--rule-2);
2246
+ }
2247
+ .strategy-coverage > div:last-child { border-bottom: 0; }
2248
+ .strategy-playbook { grid-template-columns: 1fr; }
2249
+ .strategy-grid { grid-template-columns: 1fr; }
2250
+ .tools-split { grid-template-columns: 1fr; gap: 32px; }
2251
+ .donut-wrap { margin: 0 auto; }
2252
+ .hero-headline { font-size: 56px; }
2253
+ .section-title { font-size: 30px; }
2254
+ .page { padding: 60px 22px 210px; }
2255
+ .review-page {
2256
+ scroll-margin-top: 120px;
2257
+ min-height: calc(100vh - 80px);
2258
+ }
2259
+ .review-page-controls {
2260
+ left: auto;
2261
+ right: auto;
2262
+ top: 104px;
2263
+ bottom: auto;
2264
+ position: sticky;
2265
+ transform: none;
2266
+ width: min(339px, calc(100vw - 36px));
2267
+ max-width: min(339px, calc(100vw - 36px));
2268
+ box-sizing: border-box;
2269
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
2270
+ margin: 12px 18px;
2271
+ }
2272
+ .review-page-btn {
2273
+ order: 1;
2274
+ width: 100%;
2275
+ min-width: 0;
2276
+ box-sizing: border-box;
2277
+ }
2278
+ .review-page-dots {
2279
+ grid-column: 1 / -1;
2280
+ justify-content: center;
2281
+ order: 3;
2282
+ padding: 2px 0 0;
2283
+ }
2284
+ .review-page-current {
2285
+ min-width: 0;
2286
+ grid-column: 1 / -1;
2287
+ order: 2;
2288
+ }
2289
+ .review-page-current span {
2290
+ max-width: 120px;
2291
+ }
2292
+ .review-page-btn {
2293
+ padding: 0 10px;
2294
+ }
2295
+ }
2296
+
2297
+ @media (prefers-reduced-motion: reduce) {
2298
+ html {
2299
+ scroll-behavior: auto;
2300
+ }
2301
+ .review-page,
2302
+ .review-page.active,
2303
+ .review-page-dot {
2304
+ animation: none;
2305
+ transition: none;
2306
+ transform: none;
2307
+ }
2308
+ }
2309
+
2310
+ @media print {
2311
+ .review-page-controls {
2312
+ display: none;
2313
+ }
2314
+ .review-page,
2315
+ .review-page.active {
2316
+ opacity: 1;
2317
+ transform: none;
2318
+ filter: none;
2319
+ animation: none;
2320
+ }
2321
+ }