llm_cost_tracker 0.10.0 → 0.11.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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/README.md +4 -1
  4. data/app/assets/llm_cost_tracker/application.css +782 -801
  5. data/app/controllers/llm_cost_tracker/application_controller.rb +14 -2
  6. data/app/controllers/llm_cost_tracker/calls_controller.rb +23 -16
  7. data/app/controllers/llm_cost_tracker/dashboard_controller.rb +0 -3
  8. data/app/controllers/llm_cost_tracker/models_controller.rb +3 -1
  9. data/app/controllers/llm_cost_tracker/pricing_controller.rb +16 -0
  10. data/app/controllers/llm_cost_tracker/reconciliation_controller.rb +13 -19
  11. data/app/controllers/llm_cost_tracker/tags_controller.rb +3 -1
  12. data/app/helpers/llm_cost_tracker/application_helper.rb +15 -3
  13. data/app/helpers/llm_cost_tracker/chart_helper.rb +22 -6
  14. data/app/helpers/llm_cost_tracker/sortable_table_helper.rb +41 -0
  15. data/app/services/llm_cost_tracker/dashboard/pricing_overview.rb +95 -0
  16. data/app/services/llm_cost_tracker/dashboard/setup_state.rb +27 -33
  17. data/app/services/llm_cost_tracker/dashboard/sort.rb +9 -0
  18. data/app/services/llm_cost_tracker/dashboard/tag_breakdown.rb +19 -5
  19. data/app/services/llm_cost_tracker/dashboard/top_models.rb +34 -19
  20. data/app/views/layouts/llm_cost_tracker/application.html.erb +80 -17
  21. data/app/views/llm_cost_tracker/calls/index.html.erb +69 -90
  22. data/app/views/llm_cost_tracker/calls/show.html.erb +118 -119
  23. data/app/views/llm_cost_tracker/dashboard/index.html.erb +119 -158
  24. data/app/views/llm_cost_tracker/data_quality/index.html.erb +109 -108
  25. data/app/views/llm_cost_tracker/errors/database.html.erb +2 -2
  26. data/app/views/llm_cost_tracker/models/index.html.erb +39 -59
  27. data/app/views/llm_cost_tracker/pricing/index.html.erb +93 -0
  28. data/app/views/llm_cost_tracker/reconciliation/index.html.erb +49 -58
  29. data/app/views/llm_cost_tracker/shared/_filter_pill_date.html.erb +19 -0
  30. data/app/views/llm_cost_tracker/shared/_filter_pill_model.html.erb +22 -0
  31. data/app/views/llm_cost_tracker/shared/_filter_pill_provider.html.erb +22 -0
  32. data/app/views/llm_cost_tracker/shared/_filter_pill_stream.html.erb +23 -0
  33. data/app/views/llm_cost_tracker/shared/_spend_chart.html.erb +3 -13
  34. data/app/views/llm_cost_tracker/shared/_tag_chips.html.erb +1 -1
  35. data/app/views/llm_cost_tracker/shared/setup_required.html.erb +16 -15
  36. data/app/views/llm_cost_tracker/tags/index.html.erb +27 -32
  37. data/app/views/llm_cost_tracker/tags/show.html.erb +83 -102
  38. data/config/routes.rb +1 -0
  39. data/lib/llm_cost_tracker/budget.rb +1 -2
  40. data/lib/llm_cost_tracker/{parsers → capture}/sse.rb +1 -1
  41. data/lib/llm_cost_tracker/capture/stream_collector.rb +2 -16
  42. data/lib/llm_cost_tracker/capture/stream_tracker.rb +1 -5
  43. data/lib/llm_cost_tracker/configuration.rb +3 -20
  44. data/lib/llm_cost_tracker/doctor.rb +74 -8
  45. data/lib/llm_cost_tracker/event.rb +2 -2
  46. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_call_rollups_provider.rb.erb +4 -0
  47. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_provider_invoice_imports_provider.rb.erb +4 -0
  48. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_provider_invoices_metadata_index.rb.erb +2 -0
  49. data/lib/llm_cost_tracker/ingestion/inbox.rb +1 -1
  50. data/lib/llm_cost_tracker/integrations/anthropic.rb +24 -32
  51. data/lib/llm_cost_tracker/integrations/openai.rb +39 -93
  52. data/lib/llm_cost_tracker/integrations/ruby_llm.rb +19 -63
  53. data/lib/llm_cost_tracker/ledger.rb +13 -0
  54. data/lib/llm_cost_tracker/middleware/faraday.rb +2 -1
  55. data/lib/llm_cost_tracker/parsers/anthropic.rb +14 -31
  56. data/lib/llm_cost_tracker/parsers/gemini.rb +3 -5
  57. data/lib/llm_cost_tracker/parsers/openai_compatible.rb +1 -7
  58. data/lib/llm_cost_tracker/parsers/openai_usage.rb +3 -3
  59. data/lib/llm_cost_tracker/parsers.rb +0 -2
  60. data/lib/llm_cost_tracker/pricing/explainer.rb +1 -1
  61. data/lib/llm_cost_tracker/pricing/mode.rb +34 -4
  62. data/lib/llm_cost_tracker/pricing/service_charges.rb +1 -1
  63. data/lib/llm_cost_tracker/pricing.rb +1 -18
  64. data/lib/llm_cost_tracker/providers/anthropic/server_tools.rb +15 -0
  65. data/lib/llm_cost_tracker/providers/openai/service_charges.rb +157 -0
  66. data/lib/llm_cost_tracker/railtie.rb +0 -4
  67. data/lib/llm_cost_tracker/reconcile_tasks.rb +18 -21
  68. data/lib/llm_cost_tracker/reconciliation/importer.rb +2 -7
  69. data/lib/llm_cost_tracker/reconciliation/sources/anthropic_usage.rb +6 -30
  70. data/lib/llm_cost_tracker/reconciliation/sources/coercion.rb +40 -0
  71. data/lib/llm_cost_tracker/reconciliation/sources/openai_usage.rb +7 -31
  72. data/lib/llm_cost_tracker/report/formatter.rb +32 -19
  73. data/lib/llm_cost_tracker/tracker.rb +1 -1
  74. data/lib/llm_cost_tracker/version.rb +1 -1
  75. metadata +14 -6
  76. data/app/views/llm_cost_tracker/shared/_active_filters.html.erb +0 -16
  77. data/app/views/llm_cost_tracker/shared/_filters.html.erb +0 -66
  78. data/app/views/llm_cost_tracker/shared/_sort.html.erb +0 -13
  79. data/lib/llm_cost_tracker/parsers/openai_service_charges.rb +0 -155
@@ -1,107 +1,162 @@
1
1
  :root {
2
- --lct-bg: #f6f9fc;
2
+ --lct-bg: #f7f9fc;
3
+ --lct-surface: #ffffff;
4
+ --lct-surface-2: #f1f4f9;
5
+ --lct-surface-hover: #eef2f7;
3
6
  --lct-panel: #ffffff;
4
- --lct-surface: #eef2f7;
5
- --lct-border: #e3e8ee;
6
- --lct-text: #0a2540;
7
- --lct-muted: #697386;
8
- --lct-accent: #635bff;
9
- --lct-accent-hover: #5048e5;
10
- --lct-accent-soft: #f0edff;
11
- --lct-success: #0f766e;
12
- --lct-success-soft: #ccfbf1;
13
- --lct-warning: #d97706;
14
- --lct-warning-soft: #ffedd5;
15
- --lct-warning-border: #fdba74;
16
- --lct-danger: #dc2626;
17
- --lct-danger-soft: #fee2e2;
18
- --lct-danger-border: #fca5a5;
19
- --lct-warning-copy: #9a3412;
7
+ --lct-border: #e3e8ef;
8
+ --lct-border-strong: #cbd2dc;
9
+ --lct-text: #0d1b2a;
10
+ --lct-muted: #5a6573;
11
+ --lct-subtle: #8b95a4;
12
+ --lct-accent: #5b54d8;
13
+ --lct-accent-strong: #4540c4;
14
+ --lct-accent-hover: #4540c4;
15
+ --lct-accent-soft: #ecebff;
16
+ --lct-success: #047857;
17
+ --lct-success-soft: #d1fae5;
18
+ --lct-success-border: rgba(4, 120, 87, 0.25);
19
+ --lct-warning: #b45309;
20
+ --lct-warning-soft: #fef3c7;
21
+ --lct-warning-border: rgba(180, 83, 9, 0.30);
22
+ --lct-warning-copy: #b45309;
20
23
  --lct-warning-strong: #7c2d12;
24
+ --lct-danger: #b91c1c;
25
+ --lct-danger-soft: #fde8e8;
26
+ --lct-danger-border: rgba(185, 28, 28, 0.30);
21
27
  --lct-danger-copy: #b91c1c;
22
28
  --lct-danger-strong: #991b1b;
23
29
  --lct-row-hover: #f8fafc;
24
- --lct-th-bg: #fbfcfe;
25
- --lct-toolbar-bg: rgba(255, 255, 255, 0.72);
26
- --lct-toolbar-border: #e7ecf3;
27
- --lct-border-strong: #d4dae2;
28
- --lct-chart-secondary: rgba(10, 37, 64, 0.42);
29
- --lct-chart-marker: rgba(10, 37, 64, 0.45);
30
- --lct-chip-remove: rgba(10, 37, 64, 0.58);
31
- --lct-shadow: 0 1px 2px rgba(10, 37, 64, 0.05), 0 1px 1px rgba(10, 37, 64, 0.03);
32
- --lct-shadow-sm: 0 1px 2px rgba(10, 37, 64, 0.06);
33
- --lct-shadow-md: 0 4px 12px rgba(10, 37, 64, 0.08), 0 1px 2px rgba(10, 37, 64, 0.04);
34
- --lct-shadow-lg: 0 12px 32px rgba(10, 37, 64, 0.12), 0 2px 6px rgba(10, 37, 64, 0.05);
35
- --lct-focus-ring: 0 0 0 3px rgba(99, 91, 255, 0.25);
30
+ --lct-th-bg: #f1f4f9;
31
+ --lct-toolbar-bg: rgba(255, 255, 255, 0.92);
32
+ --lct-toolbar-border: #e3e8ef;
33
+ --lct-chart-secondary: rgba(13, 27, 42, 0.42);
34
+ --lct-chart-marker: rgba(13, 27, 42, 0.45);
35
+ --lct-chip-remove: rgba(13, 27, 42, 0.58);
36
+
37
+ --lct-provider-anthropic: #d97757;
38
+ --lct-provider-openai: #10a37f;
39
+ --lct-provider-gemini: #4285f4;
40
+ --lct-provider-ruby_llm: #a91401;
41
+
42
+ --lct-shadow: 0 1px 2px rgba(13, 27, 42, 0.04);
43
+ --lct-shadow-sm: 0 1px 2px rgba(13, 27, 42, 0.04);
44
+ --lct-shadow-md: 0 2px 6px rgba(13, 27, 42, 0.06), 0 1px 2px rgba(13, 27, 42, 0.04);
45
+ --lct-shadow-lg: 0 12px 32px rgba(13, 27, 42, 0.12), 0 2px 6px rgba(13, 27, 42, 0.05);
46
+ --lct-focus-ring: 0 0 0 3px rgba(91, 84, 216, 0.22);
36
47
 
37
48
  --sp-1: 4px;
38
49
  --sp-2: 8px;
39
50
  --sp-3: 12px;
40
51
  --sp-4: 16px;
41
- --sp-5: 24px;
42
- --sp-6: 32px;
43
-
44
- --fs-2xs: 10px;
45
- --fs-xs: 11px;
46
- --fs-sm: 13px;
47
- --fs-md: 14px;
48
- --fs-lg: 18px;
52
+ --sp-5: 20px;
53
+ --sp-6: 24px;
54
+
55
+ --fs-2xs: 10.5px;
56
+ --fs-xs: 11.5px;
57
+ --fs-sm: 12.5px;
58
+ --fs-md: 13.5px;
59
+ --fs-lg: 17px;
49
60
  --fs-xl: 22px;
50
61
  --fs-xxl: 28px;
62
+ --fs-stat: 26px;
51
63
  --fs-display: 30px;
52
64
  --fs-hero: 44px;
53
- --lct-control-height: 40px;
54
65
 
55
- --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
66
+ --radius-sm: 5px;
67
+ --radius-md: 7px;
68
+ --radius-lg: 10px;
69
+ --radius-pill: 999px;
70
+
71
+ --lct-control-height: 34px;
72
+
73
+ --mono: ui-monospace, "JetBrains Mono", "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace;
56
74
  }
57
75
 
58
76
  @media (prefers-color-scheme: dark) {
59
- :root {
60
- --lct-bg: #0b1220;
61
- --lct-panel: #111a2e;
62
- --lct-surface: #1a253c;
63
- --lct-border: #233149;
64
- --lct-text: #e6ecf5;
65
- --lct-muted: #8a98b3;
66
- --lct-accent: #8a82ff;
67
- --lct-accent-hover: #a39cff;
68
- --lct-accent-soft: rgba(138, 130, 255, 0.16);
69
- --lct-success: #34d399;
70
- --lct-success-soft: rgba(52, 211, 153, 0.16);
71
- --lct-warning: #fbbf24;
72
- --lct-warning-soft: rgba(251, 191, 36, 0.16);
73
- --lct-warning-border: rgba(251, 191, 36, 0.4);
74
- --lct-danger: #f87171;
75
- --lct-danger-soft: rgba(248, 113, 113, 0.16);
76
- --lct-danger-border: rgba(248, 113, 113, 0.4);
77
- --lct-row-hover: #182238;
78
- --lct-th-bg: #142036;
79
- --lct-toolbar-bg: rgba(17, 26, 46, 0.78);
80
- --lct-toolbar-border: #233149;
81
- --lct-border-strong: #2f3f5c;
82
- --lct-warning-copy: #fcd34d;
77
+ :root:not([data-theme="light"]) {
78
+ --lct-bg: #0f1419;
79
+ --lct-surface: #161b22;
80
+ --lct-surface-2: #1c2229;
81
+ --lct-surface-hover: #232a35;
82
+ --lct-panel: #161b22;
83
+ --lct-border: #2a313c;
84
+ --lct-border-strong: #3d4654;
85
+ --lct-text: #e6edf3;
86
+ --lct-muted: #8b949e;
87
+ --lct-subtle: #6e7681;
88
+ --lct-accent: #7c83ff;
89
+ --lct-accent-strong: #a4abff;
90
+ --lct-accent-hover: #a4abff;
91
+ --lct-accent-soft: rgba(124, 131, 255, 0.16);
92
+ --lct-success: #56d364;
93
+ --lct-success-soft: rgba(86, 211, 100, 0.14);
94
+ --lct-success-border: rgba(86, 211, 100, 0.35);
95
+ --lct-warning: #d29922;
96
+ --lct-warning-soft: rgba(210, 153, 34, 0.14);
97
+ --lct-warning-border: rgba(210, 153, 34, 0.35);
98
+ --lct-warning-copy: #d29922;
83
99
  --lct-warning-strong: #fde68a;
84
- --lct-danger-copy: #fca5a5;
100
+ --lct-danger: #f85149;
101
+ --lct-danger-soft: rgba(248, 81, 73, 0.14);
102
+ --lct-danger-border: rgba(248, 81, 73, 0.40);
103
+ --lct-danger-copy: #f85149;
85
104
  --lct-danger-strong: #fecaca;
86
- --lct-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 1px rgba(0, 0, 0, 0.25);
87
- --lct-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
88
- --lct-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.25);
105
+ --lct-row-hover: #1c2229;
106
+ --lct-th-bg: #1c2229;
107
+ --lct-toolbar-bg: rgba(22, 27, 34, 0.92);
108
+ --lct-toolbar-border: #2a313c;
109
+ --lct-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
110
+ --lct-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
111
+ --lct-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.25);
89
112
  --lct-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
90
- --lct-focus-ring: 0 0 0 3px rgba(138, 130, 255, 0.35);
113
+ --lct-focus-ring: 0 0 0 3px rgba(124, 131, 255, 0.30);
91
114
  --lct-chart-secondary: rgba(230, 236, 245, 0.32);
92
115
  --lct-chart-marker: rgba(230, 236, 245, 0.45);
93
116
  --lct-chip-remove: rgba(230, 236, 245, 0.58);
94
117
  }
95
-
96
- .lct-field select {
97
- background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%238a98b3' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 4.5l3.5 3.5 3.5-3.5'/></svg>");
98
- }
99
-
100
- .lct-field input[type="date"]::-webkit-calendar-picker-indicator {
101
- filter: invert(70%) sepia(8%) saturate(437%) hue-rotate(176deg) brightness(95%) contrast(86%);
102
- }
103
118
  }
104
119
 
120
+ :root[data-theme="dark"] {
121
+ --lct-bg: #0f1419;
122
+ --lct-surface: #161b22;
123
+ --lct-surface-2: #1c2229;
124
+ --lct-surface-hover: #232a35;
125
+ --lct-panel: #161b22;
126
+ --lct-border: #2a313c;
127
+ --lct-border-strong: #3d4654;
128
+ --lct-text: #e6edf3;
129
+ --lct-muted: #8b949e;
130
+ --lct-subtle: #6e7681;
131
+ --lct-accent: #7c83ff;
132
+ --lct-accent-strong: #a4abff;
133
+ --lct-accent-hover: #a4abff;
134
+ --lct-accent-soft: rgba(124, 131, 255, 0.16);
135
+ --lct-success: #56d364;
136
+ --lct-success-soft: rgba(86, 211, 100, 0.14);
137
+ --lct-success-border: rgba(86, 211, 100, 0.35);
138
+ --lct-warning: #d29922;
139
+ --lct-warning-soft: rgba(210, 153, 34, 0.14);
140
+ --lct-warning-border: rgba(210, 153, 34, 0.35);
141
+ --lct-warning-copy: #d29922;
142
+ --lct-warning-strong: #fde68a;
143
+ --lct-danger: #f85149;
144
+ --lct-danger-soft: rgba(248, 81, 73, 0.14);
145
+ --lct-danger-border: rgba(248, 81, 73, 0.40);
146
+ --lct-danger-copy: #f85149;
147
+ --lct-danger-strong: #fecaca;
148
+ --lct-row-hover: #1c2229;
149
+ --lct-th-bg: #1c2229;
150
+ --lct-toolbar-bg: rgba(22, 27, 34, 0.92);
151
+ --lct-toolbar-border: #2a313c;
152
+ --lct-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
153
+ --lct-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
154
+ --lct-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.25);
155
+ --lct-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
156
+ --lct-focus-ring: 0 0 0 3px rgba(124, 131, 255, 0.30);
157
+ }
158
+
159
+ * { box-sizing: border-box; }
105
160
  .lct-body { margin: 0; }
106
161
 
107
162
  .lct-app {
@@ -113,885 +168,811 @@
113
168
  min-height: 100vh;
114
169
  }
115
170
 
116
- .lct-shell {
117
- max-width: 1180px;
118
- margin: 0 auto;
119
- padding: 24px;
120
- }
121
-
122
- .lct-header {
171
+ .lct-toolbar {
123
172
  display: flex;
124
- align-items: flex-start;
125
- justify-content: space-between;
126
- gap: 24px;
127
- margin-bottom: 20px;
128
- }
129
-
130
- .lct-header-copy { display: grid; gap: 6px; }
131
-
132
- .lct-title {
133
- margin: 0;
134
- font-size: var(--fs-display);
135
- font-weight: 700;
136
- letter-spacing: -0.01em;
137
- line-height: 1.2;
173
+ align-items: center;
174
+ height: 48px;
175
+ padding: 0 var(--sp-5);
176
+ background: var(--lct-toolbar-bg);
177
+ border-bottom: 1px solid var(--lct-toolbar-border);
178
+ position: sticky;
179
+ top: 0;
180
+ z-index: 100;
181
+ backdrop-filter: blur(10px);
138
182
  }
139
-
140
- .lct-nav { display: flex; gap: 4px; flex-wrap: wrap; }
141
-
142
- .lct-nav a {
143
- color: var(--lct-muted);
144
- text-decoration: none;
183
+ .lct-toolbar-brand {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: var(--sp-2);
187
+ font-weight: 600;
145
188
  font-size: var(--fs-md);
146
- font-weight: 500;
147
- padding: 8px 12px;
148
- border-radius: 6px;
189
+ color: var(--lct-text);
190
+ text-decoration: none;
149
191
  }
150
-
151
- .lct-nav a:hover { color: var(--lct-accent); background: rgba(99, 91, 255, 0.06); }
152
- .lct-nav .lct-active { background: var(--lct-accent-soft); color: var(--lct-accent); font-weight: 700; }
153
-
154
- .lct-panel {
155
- background: var(--lct-panel);
192
+ .lct-toolbar-brand .lct-brandmark {
193
+ width: 22px;
194
+ height: 22px;
195
+ border-radius: var(--radius-sm);
196
+ background: linear-gradient(135deg, var(--lct-accent), color-mix(in oklab, var(--lct-accent) 75%, white));
197
+ display: grid;
198
+ place-items: center;
199
+ color: white;
200
+ box-shadow: 0 2px 6px rgba(91, 84, 216, 0.25);
201
+ }
202
+ .lct-toolbar-brand .lct-brandmark svg { width: 13px; height: 13px; }
203
+ .lct-toolbar-right { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }
204
+
205
+ .lct-theme-toggle {
206
+ display: inline-grid;
207
+ place-items: center;
208
+ width: 30px;
209
+ height: 30px;
210
+ padding: 0;
211
+ background: transparent;
156
212
  border: 1px solid var(--lct-border);
157
- border-radius: 8px;
158
- padding: 20px;
159
- box-shadow: var(--lct-shadow);
213
+ border-radius: var(--radius-sm);
214
+ color: var(--lct-muted);
215
+ cursor: pointer;
160
216
  }
217
+ .lct-theme-toggle:hover { background: var(--lct-surface-2); color: var(--lct-text); border-color: var(--lct-border-strong); }
218
+ .lct-theme-toggle svg { width: 15px; height: 15px; }
219
+ .lct-theme-toggle .lct-icon-sun { display: none; }
220
+ .lct-theme-toggle .lct-icon-moon { display: block; }
221
+ @media (prefers-color-scheme: dark) {
222
+ :root:not([data-theme="light"]) .lct-theme-toggle .lct-icon-sun { display: block; }
223
+ :root:not([data-theme="light"]) .lct-theme-toggle .lct-icon-moon { display: none; }
224
+ }
225
+ :root[data-theme="dark"] .lct-theme-toggle .lct-icon-sun { display: block; }
226
+ :root[data-theme="dark"] .lct-theme-toggle .lct-icon-moon { display: none; }
161
227
 
162
- .lct-panel-tight { padding: 16px 18px; }
163
-
164
- .lct-panel + .lct-panel,
165
- .lct-stat-grid + .lct-panel { margin-top: 16px; }
166
- .lct-grid > .lct-panel + .lct-panel,
167
- .lct-grid > .lct-stat-grid + .lct-panel { margin-top: 0; }
168
-
169
- .lct-breadcrumb {
228
+ .lct-shell {
229
+ display: grid;
230
+ grid-template-columns: 200px 1fr;
231
+ min-height: calc(100vh - 48px);
232
+ }
233
+ .lct-sidebar {
234
+ border-right: 1px solid var(--lct-border);
235
+ background: var(--lct-surface);
236
+ }
237
+ .lct-sidebar-inner {
238
+ position: sticky;
239
+ top: 48px;
240
+ max-height: calc(100vh - 48px);
241
+ overflow-y: auto;
242
+ padding: var(--sp-3) var(--sp-2);
243
+ }
244
+ .lct-sidebar-section {
245
+ font-size: var(--fs-2xs);
246
+ text-transform: uppercase;
247
+ letter-spacing: 0.10em;
248
+ color: var(--lct-subtle);
249
+ font-weight: 700;
250
+ padding: var(--sp-3) var(--sp-3) var(--sp-1);
251
+ }
252
+ .lct-sidebar-section + .lct-sidebar-link,
253
+ .lct-sidebar-link + .lct-sidebar-section { margin-top: var(--sp-2); }
254
+ .lct-sidebar-link {
255
+ display: flex;
170
256
  align-items: center;
257
+ gap: var(--sp-2);
258
+ padding: 7px var(--sp-3);
259
+ border-radius: var(--radius-sm);
171
260
  color: var(--lct-muted);
172
- display: flex;
173
261
  font-size: var(--fs-sm);
174
- gap: 8px;
175
- margin-bottom: 14px;
176
- }
177
- .lct-breadcrumb-link {
178
- color: var(--lct-muted);
262
+ font-weight: 500;
179
263
  text-decoration: none;
180
- transition: color 0.15s ease;
264
+ cursor: pointer;
181
265
  }
182
- .lct-breadcrumb-link:hover { color: var(--lct-text); }
183
- .lct-breadcrumb-link:focus-visible {
184
- color: var(--lct-text);
185
- outline: 2px solid var(--lct-accent-soft);
186
- outline-offset: 2px;
187
- border-radius: 2px;
266
+ .lct-sidebar-link:hover { color: var(--lct-text); background: var(--lct-surface-2); }
267
+ .lct-sidebar-link.lct-active {
268
+ color: var(--lct-accent-strong);
269
+ background: var(--lct-accent-soft);
270
+ font-weight: 600;
271
+ box-shadow: inset 2px 0 0 var(--lct-accent);
188
272
  }
189
- .lct-breadcrumb-sep { color: var(--lct-border-strong); }
190
- .lct-breadcrumb-current { color: var(--lct-text); font-weight: 500; }
273
+ .lct-sidebar-link svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--lct-subtle); }
274
+ .lct-sidebar-link.lct-active svg { color: var(--lct-accent); }
191
275
 
192
- .lct-banner {
276
+ .lct-content { padding: var(--sp-4) var(--sp-5) var(--sp-6); max-width: none; }
277
+
278
+ .lct-alert {
279
+ display: flex;
193
280
  align-items: center;
194
- border-radius: 8px;
281
+ gap: var(--sp-3);
282
+ padding: 10px var(--sp-4);
283
+ border-radius: var(--radius-md);
195
284
  border: 1px solid;
196
- display: flex;
197
- gap: 20px;
198
- justify-content: space-between;
199
- margin-bottom: 16px;
200
- padding: 12px 16px;
201
- }
202
-
203
- .lct-banner-body { flex: 1; min-width: 0; }
204
- .lct-banner-title { font-size: var(--fs-md); font-weight: 600; margin: 0; }
205
- .lct-banner-muted { color: var(--lct-muted); font-weight: 400; }
206
-
207
- .lct-banner-warning { background: var(--lct-warning-soft); border-color: var(--lct-warning-border); color: var(--lct-warning-strong); }
208
- .lct-banner-warning .lct-banner-muted,
209
- .lct-banner-warning .lct-banner-copy { color: var(--lct-warning-copy); }
210
-
211
- .lct-banner-danger { background: var(--lct-danger-soft); border-color: var(--lct-danger-border); color: var(--lct-danger-strong); }
212
- .lct-banner-danger .lct-banner-muted,
213
- .lct-banner-danger .lct-banner-copy { color: var(--lct-danger-copy); }
214
-
215
- .lct-muted { color: var(--lct-muted); }
216
-
217
- .lct-code {
218
- background: var(--lct-surface);
219
- border-radius: 4px;
220
- padding: 2px 6px;
285
+ font-size: var(--fs-sm);
286
+ margin-bottom: var(--sp-3);
287
+ }
288
+ .lct-alert-warn { background: var(--lct-warning-soft); border-color: var(--lct-warning-border); color: var(--lct-warning); }
289
+ .lct-alert-danger { background: var(--lct-danger-soft); border-color: var(--lct-danger-border); color: var(--lct-danger); }
290
+ .lct-alert-info { background: var(--lct-accent-soft); border-color: color-mix(in oklab, var(--lct-accent) 22%, transparent); color: var(--lct-accent-strong); }
291
+ .lct-alert svg { flex-shrink: 0; }
292
+ .lct-alert strong { font-weight: 600; }
293
+ .lct-alert code {
221
294
  font-family: var(--mono);
222
- font-size: 0.92em;
223
- }
224
-
225
- .lct-grid { display: grid; gap: 16px; margin-bottom: 16px; }
226
-
227
- .lct-hero {
228
- align-items: stretch;
229
- display: grid;
230
- gap: 14px;
231
- grid-template-columns: minmax(0, 0.65fr) minmax(320px, 1fr);
232
- margin-bottom: 16px;
295
+ font-size: var(--fs-xs);
296
+ background: color-mix(in oklab, currentColor 10%, transparent);
297
+ padding: 1px 5px;
298
+ border-radius: 3px;
299
+ color: inherit;
233
300
  }
234
-
235
- .lct-hero-primary { align-content: space-between; display: grid; gap: 14px; }
236
-
237
- .lct-hero-value {
238
- font-size: var(--fs-hero);
239
- font-variant-numeric: tabular-nums;
240
- font-weight: 750;
241
- letter-spacing: -0.02em;
242
- line-height: 1.05;
243
- margin: 0;
301
+ .lct-alert-action {
302
+ margin-left: auto;
303
+ padding: 5px 11px;
304
+ background: var(--lct-surface);
305
+ border: 1px solid currentColor;
306
+ border-radius: var(--radius-sm);
307
+ font-weight: 600;
308
+ font-size: var(--fs-xs);
309
+ color: inherit;
310
+ cursor: pointer;
311
+ text-decoration: none;
244
312
  }
245
313
 
246
- .lct-hero-side { display: grid; gap: 14px; }
247
-
248
314
  .lct-stat-grid {
249
315
  display: grid;
250
- gap: 14px;
251
- grid-auto-rows: 1fr;
252
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
316
+ grid-template-columns: repeat(4, minmax(0, 1fr));
317
+ gap: var(--sp-2);
318
+ margin-bottom: var(--sp-3);
253
319
  }
254
-
255
- .lct-hero-side .lct-stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
256
- .lct-stat-grid-spaced { margin-bottom: 16px; }
257
- .lct-two-col { align-items: start; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
320
+ @media (max-width: 1024px) { .lct-stat-grid { grid-template-columns: repeat(2, 1fr); } }
321
+ @media (max-width: 640px) { .lct-stat-grid { grid-template-columns: 1fr; } }
258
322
 
259
323
  .lct-stat {
260
- align-items: flex-start;
261
- background: var(--lct-panel);
324
+ background: var(--lct-surface);
262
325
  border: 1px solid var(--lct-border);
263
- border-radius: 8px;
326
+ border-radius: var(--radius-md);
327
+ padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
328
+ position: relative;
329
+ overflow: hidden;
330
+ box-shadow: var(--lct-shadow-sm);
264
331
  display: flex;
265
332
  flex-direction: column;
266
- padding: 16px;
333
+ align-items: flex-start;
334
+ }
335
+ .lct-stat::before {
336
+ content: "";
337
+ position: absolute;
338
+ left: 0; top: 0; bottom: 0;
339
+ width: 3px;
340
+ background: var(--lct-accent);
341
+ }
342
+ .lct-stat-ok::before { background: var(--lct-success); }
343
+ .lct-stat-warn::before { background: var(--lct-warning); }
344
+ .lct-stat-danger::before { background: var(--lct-danger); }
345
+ .lct-stat-head {
346
+ display: flex;
347
+ align-items: center;
348
+ justify-content: space-between;
349
+ margin-bottom: var(--sp-2);
350
+ width: 100%;
351
+ }
352
+ .lct-stat-label {
353
+ font-size: var(--fs-2xs);
354
+ color: var(--lct-muted);
355
+ font-weight: 700;
356
+ text-transform: uppercase;
357
+ letter-spacing: 0.08em;
358
+ margin: 0;
267
359
  }
268
- .lct-stat .lct-stat-value { order: 1; }
269
- .lct-stat .lct-stat-label { order: 2; margin: 6px 0 0; }
270
- .lct-stat .lct-delta-badge { order: 3; }
271
-
272
360
  .lct-stat-value {
273
- font-size: var(--fs-xxl);
274
- font-variant-numeric: tabular-nums;
361
+ font-size: var(--fs-stat);
275
362
  font-weight: 700;
363
+ line-height: 1.1;
364
+ font-variant-numeric: tabular-nums;
276
365
  letter-spacing: -0.01em;
366
+ color: var(--lct-text);
277
367
  margin: 0;
278
368
  }
279
-
280
- .lct-stat-sub { color: var(--lct-muted); font-size: var(--fs-xs); margin: 4px 0 0; }
281
-
282
- .lct-stat-label,
283
- .lct-field label,
284
- .lct-call-summary-label,
285
- .lct-call-breakdown-title,
286
- .lct-chip-label {
369
+ .lct-stat-unit {
370
+ font-size: var(--fs-sm);
371
+ font-weight: 500;
287
372
  color: var(--lct-muted);
373
+ margin-left: 3px;
374
+ }
375
+ .lct-stat-foot {
288
376
  font-size: var(--fs-xs);
289
- font-weight: 600;
290
- letter-spacing: 0;
291
- text-transform: none;
292
- }
293
- .lct-stat-label { margin: 0 0 6px; }
294
- .lct-call-breakdown-title { color: var(--lct-text); font-size: var(--fs-md); margin: 0 0 10px; }
295
- .lct-chip-label { color: var(--lct-accent); font-weight: 700; }
296
- .lct-field label { color: var(--lct-text); font-size: var(--fs-md); font-weight: 500; }
297
-
298
- .lct-section-copy,
299
- .lct-stat-copy,
300
- .lct-banner-copy,
301
- .lct-call-breakdown-empty {
302
377
  color: var(--lct-muted);
303
- margin: 0;
378
+ margin-top: 6px;
379
+ font-variant-numeric: tabular-nums;
304
380
  }
305
- .lct-section-copy { font-size: var(--fs-md); margin-top: 4px; }
306
- .lct-stat-copy { font-size: var(--fs-sm); margin-top: 6px; }
307
- .lct-banner-copy { font-size: var(--fs-sm); margin-top: 4px; }
308
- .lct-call-breakdown-empty { font-size: var(--fs-sm); }
309
-
310
- .lct-section-title { margin: 0 0 8px; font-size: var(--fs-lg); font-weight: 600; letter-spacing: -0.01em; }
381
+ .lct-stat-section-label {
382
+ font-size: var(--fs-2xs);
383
+ font-weight: 700;
384
+ text-transform: uppercase;
385
+ letter-spacing: 0.08em;
386
+ color: var(--lct-muted);
387
+ margin: var(--sp-3) 0 var(--sp-2);
388
+ }
389
+ .lct-stat-section-label:first-child { margin-top: 0; }
311
390
 
312
- .lct-section-head {
313
- align-items: flex-start;
391
+ .lct-tabs {
314
392
  display: flex;
315
- justify-content: space-between;
316
- gap: 16px;
317
- margin-bottom: 14px;
393
+ gap: var(--sp-1);
394
+ border-bottom: 1px solid var(--lct-border);
395
+ margin-bottom: var(--sp-3);
318
396
  }
319
-
320
- .lct-table { border-collapse: collapse; width: 100%; font-size: var(--fs-sm); }
321
-
322
- .lct-num { font-variant-numeric: tabular-nums; text-align: right !important; white-space: nowrap; }
323
- .lct-num-muted { color: var(--lct-muted); }
324
-
325
- .lct-table-compact th,
326
- .lct-table-compact td { padding: 10px 12px; }
327
-
328
- .lct-badge {
329
- align-items: center;
330
- border-radius: 999px;
331
- display: inline-flex;
332
- font-size: var(--fs-xs);
397
+ .lct-tab {
398
+ padding: 8px 14px 9px;
399
+ font-size: var(--fs-sm);
400
+ font-weight: 500;
401
+ color: var(--lct-muted);
402
+ text-decoration: none;
403
+ border-bottom: 2px solid transparent;
404
+ margin-bottom: -1px;
405
+ }
406
+ .lct-tab:hover { color: var(--lct-text); }
407
+ .lct-tab.lct-active {
408
+ color: var(--lct-accent-strong);
409
+ border-bottom-color: var(--lct-accent);
333
410
  font-weight: 600;
334
- letter-spacing: 0.02em;
335
- line-height: 1;
336
- padding: 4px 10px;
337
- text-transform: uppercase;
338
- vertical-align: middle;
339
411
  }
340
- .lct-badge-ok { background: var(--lct-success-soft); color: var(--lct-success); }
341
- .lct-badge-warn { background: var(--lct-warning-soft); color: var(--lct-warning-strong); }
412
+ .lct-tab-count {
413
+ margin-left: 6px;
414
+ font-size: var(--fs-2xs);
415
+ color: var(--lct-subtle);
416
+ font-variant-numeric: tabular-nums;
417
+ }
418
+ .lct-stat-spark { height: 28px; margin-top: 8px; display: block; width: 100%; color: var(--lct-accent); }
342
419
 
343
- .lct-delta-badge {
344
- align-items: center;
345
- border-radius: 999px;
420
+ .lct-delta-badge,
421
+ .lct-delta {
346
422
  display: inline-flex;
423
+ align-items: center;
424
+ gap: 2px;
347
425
  font-size: var(--fs-xs);
426
+ font-weight: 700;
348
427
  font-variant-numeric: tabular-nums;
349
- font-weight: 600;
350
- gap: 6px;
351
- letter-spacing: 0.01em;
352
- line-height: 1;
353
- margin: 10px 0 0;
354
- padding: 4px 10px 4px 8px;
355
- }
356
- .lct-delta-dot {
357
- border-radius: 999px;
358
- display: inline-block;
359
- height: 6px;
360
- width: 6px;
361
- background: currentColor;
362
- flex-shrink: 0;
363
428
  }
364
- .lct-delta-neutral { background: var(--lct-surface); color: var(--lct-muted); box-shadow: inset 0 0 0 1px rgba(105, 115, 134, 0.2); }
365
- .lct-delta-up { background: var(--lct-danger-soft); color: #991b1b; box-shadow: inset 0 0 0 1px rgba(220, 38, 38, 0.2); }
366
- .lct-delta-down { background: var(--lct-success-soft); color: #115e59; box-shadow: inset 0 0 0 1px rgba(15, 118, 110, 0.2); }
367
-
368
- .lct-table-wrap { overflow-x: auto; }
429
+ .lct-delta-up { color: var(--lct-danger); }
430
+ .lct-delta-down { color: var(--lct-success); }
431
+ .lct-delta-flat,
432
+ .lct-delta-neutral { color: var(--lct-muted); }
369
433
 
370
- .lct-table th,
371
- .lct-table td {
434
+ .lct-panel {
435
+ background: var(--lct-panel);
436
+ border: 1px solid var(--lct-border);
437
+ border-radius: var(--radius-md);
438
+ margin-bottom: var(--sp-3);
439
+ box-shadow: var(--lct-shadow-sm);
440
+ }
441
+ .lct-panel-head {
442
+ display: flex;
443
+ align-items: center;
444
+ gap: var(--sp-3);
445
+ padding: 9px var(--sp-4);
372
446
  border-bottom: 1px solid var(--lct-border);
373
- padding: 12px;
374
- text-align: left;
375
- vertical-align: middle;
376
447
  }
377
-
378
- .lct-table tbody tr:last-child td { border-bottom: 0; }
379
-
380
- .lct-table th {
381
- background: var(--lct-th-bg);
382
- color: var(--lct-muted);
448
+ .lct-panel-title {
449
+ font-size: var(--fs-md);
383
450
  font-weight: 600;
384
- font-size: var(--fs-xs);
385
- letter-spacing: 0;
386
- text-transform: none;
387
- position: sticky;
388
- top: 0;
389
- z-index: 1;
390
- }
391
-
392
- .lct-table tbody tr {
393
- transition: background-color 0.1s ease;
394
- }
395
- .lct-table tbody tr:hover { background: var(--lct-row-hover); }
396
-
397
- @media (prefers-reduced-motion: reduce) {
398
- .lct-table tbody tr { transition: none; }
399
- }
400
-
401
- .lct-table td:last-child,
402
- .lct-table th:last-child,
403
- .lct-calls-table td:last-child,
404
- .lct-calls-table th:last-child { text-align: right; }
405
-
406
- .lct-bar-track,
407
- .lct-budget-track,
408
- .lct-stack-track {
409
- background: var(--lct-surface);
410
- border-radius: 999px;
411
- overflow: hidden;
451
+ margin: 0;
452
+ letter-spacing: -0.005em;
412
453
  }
413
- .lct-bar-track { height: 8px; min-width: 96px; }
414
- .lct-budget-track { height: 10px; border: 1px solid var(--lct-border); position: relative; }
415
- .lct-stack-track { height: 12px; display: flex; }
416
-
417
- .lct-bar-fill,
418
- .lct-budget-fill,
419
- .lct-stack-fill { height: 100%; display: block; }
420
- .lct-bar-fill { background: var(--lct-accent); }
421
- .lct-budget-fill { background: linear-gradient(90deg, #635bff, #7a73ff); transition: width 0.2s ease; }
422
- .lct-budget-fill--warn { background: linear-gradient(90deg, #f59e0b, #d97706); }
423
- .lct-budget-fill--over { background: linear-gradient(90deg, #ef4444, #b91c1c); }
424
- .lct-stack-fill-input { background: var(--lct-accent); }
425
- .lct-stack-fill-cache-read { background: #22c55e; }
426
- .lct-stack-fill-cache-write { background: #f59e0b; }
427
- .lct-stack-fill-cache-write-extended { background: #a855f7; }
428
- .lct-stack-fill-audio-input { background: #ec4899; }
429
- .lct-stack-fill-image-input { background: #f97316; }
430
- .lct-stack-fill-output { background: #0ea5e9; }
431
- .lct-stack-fill-audio-output { background: #14b8a6; }
432
- .lct-stack-fill-image-output { background: #84cc16; }
433
-
434
- .lct-budget { display: grid; gap: 10px; }
435
- .lct-budget-head { align-items: baseline; display: flex; gap: 10px; justify-content: space-between; }
436
- .lct-budget-spent {
437
- font-size: var(--fs-xl);
438
- font-variant-numeric: tabular-nums;
439
- font-weight: 700;
454
+ .lct-page-title {
455
+ font-size: var(--fs-lg);
456
+ font-weight: 600;
457
+ margin: 0 0 var(--sp-3);
440
458
  letter-spacing: -0.01em;
459
+ color: var(--lct-text);
441
460
  }
442
- .lct-budget-of { color: var(--lct-muted); font-size: var(--fs-sm); font-weight: 500; }
443
- .lct-budget-percent { font-size: var(--fs-md); font-variant-numeric: tabular-nums; font-weight: 700; }
444
- .lct-budget-marker {
445
- border-left: 2px dashed var(--lct-chart-marker);
446
- bottom: 0;
447
- position: absolute;
448
- top: 0;
461
+ .lct-panel-intro {
462
+ margin: 0;
463
+ padding: var(--sp-3) var(--sp-4);
464
+ font-size: var(--fs-sm);
465
+ color: var(--lct-muted);
466
+ line-height: 1.5;
467
+ }
468
+ .lct-panel-intro code { font-family: var(--mono); font-size: 0.9em; color: var(--lct-text); background: var(--lct-surface-2); padding: 1px 4px; border-radius: 3px; }
469
+ .lct-breadcrumb-back {
470
+ font-size: var(--fs-xs);
471
+ color: var(--lct-muted);
472
+ margin: 0 0 4px;
449
473
  }
450
- .lct-budget-projection {
451
- align-items: baseline;
474
+ .lct-breadcrumb-back a { color: var(--lct-accent-strong); text-decoration: none; font-weight: 600; }
475
+ .lct-breadcrumb-back a:hover { text-decoration: underline; }
476
+ .lct-panel-meta {
477
+ margin-left: auto;
478
+ font-size: var(--fs-xs);
452
479
  color: var(--lct-muted);
480
+ font-variant-numeric: tabular-nums;
453
481
  display: flex;
454
- flex-wrap: wrap;
455
- font-size: var(--fs-sm);
456
- gap: 8px 12px;
457
- justify-content: space-between;
458
- margin: 0;
482
+ gap: var(--sp-3);
483
+ align-items: center;
459
484
  }
460
- .lct-budget-projection strong { color: var(--lct-text); }
461
- .lct-budget-projection-status { font-weight: 600; }
462
- .lct-budget-projection-status--over { color: var(--lct-warning-copy); }
463
- .lct-budget-projection-status--under { color: var(--lct-muted); }
464
- .lct-budget-meta { color: var(--lct-muted); font-size: var(--fs-xs); }
485
+ .lct-panel-meta a { color: var(--lct-accent-strong); font-weight: 600; text-decoration: none; }
486
+ .lct-panel-meta a:hover { text-decoration: underline; }
487
+ .lct-panel-body { padding: var(--sp-3) var(--sp-4); }
465
488
 
466
- .lct-chart { display: block; height: 180px; width: 100%; }
467
- .lct-chart-area { fill: rgba(99, 91, 255, 0.12); }
468
- .lct-chart-line-secondary {
469
- fill: none;
470
- opacity: 0.75;
471
- stroke: var(--lct-chart-secondary);
472
- stroke-dasharray: 5 4;
473
- stroke-linejoin: round;
474
- stroke-linecap: round;
475
- stroke-width: 1.5;
476
- }
477
- .lct-chart-line { fill: none; stroke: var(--lct-accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
478
- .lct-chart-dot { fill: var(--lct-accent); }
479
- .lct-chart-grid { stroke: var(--lct-border); stroke-dasharray: 2 3; }
480
- .lct-chart-axis { fill: var(--lct-muted); font-family: var(--mono); font-size: var(--fs-2xs); }
481
- .lct-chart-legend {
489
+ .lct-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
490
+ @media (max-width: 900px) { .lct-grid-2 { grid-template-columns: 1fr; } }
491
+
492
+ .lct-page-title-meta {
493
+ font-size: var(--fs-sm);
494
+ font-weight: 500;
482
495
  color: var(--lct-muted);
483
- display: flex;
484
- font-size: var(--fs-xs);
496
+ margin-left: 6px;
485
497
  font-variant-numeric: tabular-nums;
486
- justify-content: space-between;
487
- margin-top: 10px;
488
- }
489
- .lct-chart-legend-compare { align-items: center; display: inline-flex; gap: 12px; }
490
- .lct-chart-key { align-items: center; display: inline-flex; gap: 6px; }
491
- .lct-chart-key-line { background: var(--lct-accent); border-radius: 999px; display: inline-block; height: 2px; width: 16px; }
492
- .lct-chart-key-line-secondary { background: var(--lct-chart-secondary); position: relative; }
493
- .lct-chart-key-line-secondary::after {
494
- background: linear-gradient(90deg, transparent 40%, var(--lct-bg) 40%, var(--lct-bg) 60%, transparent 60%);
495
- content: "";
496
- inset: -1px 0;
497
- position: absolute;
498
498
  }
499
- .lct-chart-empty {
499
+ .lct-page-subtitle {
500
+ margin: -8px 0 var(--sp-3);
501
+ display: inline-flex;
500
502
  align-items: center;
503
+ gap: 8px;
501
504
  color: var(--lct-muted);
502
- display: flex;
503
505
  font-size: var(--fs-sm);
504
- height: 180px;
505
- justify-content: center;
506
506
  }
507
- .lct-tag-chips { display: flex; flex-wrap: wrap; gap: 4px; max-width: 380px; }
508
- .lct-tag-chip {
509
- align-items: center;
510
- background: var(--lct-surface);
511
- border: 1px solid var(--lct-border);
512
- border-radius: 4px;
507
+ .lct-page-subtitle-sep { color: var(--lct-subtle); }
508
+ .lct-stat-value-sm {
509
+ font-size: var(--fs-md);
510
+ font-weight: 600;
511
+ line-height: 1.2;
513
512
  color: var(--lct-text);
514
- display: inline-flex;
515
- font-family: var(--mono);
516
- font-size: var(--fs-xs);
517
- gap: 0;
518
- line-height: 1.4;
519
- padding: 2px 6px;
520
- text-decoration: none;
521
- white-space: nowrap;
513
+ margin: 0;
522
514
  }
523
- .lct-tag-chip-more { background: transparent; border: 1px dashed var(--lct-border); color: var(--lct-muted); }
524
- .lct-tag-empty { color: var(--lct-muted); font-size: var(--fs-sm); font-style: italic; }
525
515
 
526
- .lct-empty {
527
- padding: 56px 28px;
528
- text-align: center;
529
- background:
530
- radial-gradient(ellipse 60% 50% at 50% 0%, rgba(99, 91, 255, 0.04), transparent 70%),
531
- var(--lct-panel);
516
+ .lct-meta-strip {
517
+ display: grid;
518
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
519
+ gap: var(--sp-3) var(--sp-4);
520
+ padding: var(--sp-3) var(--sp-4);
521
+ margin: 0;
532
522
  }
533
- .lct-state-title { font-size: var(--fs-lg); font-weight: 600; margin: 0 0 6px; letter-spacing: -0.005em; }
534
- .lct-state-copy { color: var(--lct-muted); margin: 0 auto; max-width: 480px; font-size: var(--fs-sm); line-height: 1.55; }
535
- .lct-state-pre {
536
- background: var(--lct-bg);
537
- border: 1px solid var(--lct-border);
538
- border-radius: 6px;
539
- color: var(--lct-text);
540
- font-family: var(--mono);
523
+ .lct-meta-strip-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
524
+ .lct-meta-strip-item dt {
525
+ font-size: var(--fs-2xs);
526
+ font-weight: 700;
527
+ text-transform: uppercase;
528
+ letter-spacing: 0.06em;
529
+ color: var(--lct-muted);
530
+ margin: 0;
531
+ }
532
+ .lct-meta-strip-item dd {
541
533
  font-size: var(--fs-sm);
542
- line-height: 1.55;
543
- margin: 12px auto 0;
544
- max-width: 560px;
545
- overflow: auto;
546
- padding: 12px 14px;
547
- text-align: left;
534
+ color: var(--lct-text);
535
+ font-variant-numeric: tabular-nums;
536
+ margin: 0;
537
+ word-break: break-all;
548
538
  }
549
- .lct-state-actions { display: flex; gap: 8px; justify-content: center; margin-top: 20px; }
550
539
 
551
- .lct-toolbar {
552
- background: var(--lct-toolbar-bg);
553
- backdrop-filter: blur(10px);
554
- border-color: var(--lct-toolbar-border);
555
- box-shadow: none;
556
- padding: 16px;
557
- margin-bottom: 16px;
558
- position: sticky;
559
- top: 12px;
560
- z-index: 10;
540
+ .lct-disclose { padding: 0; }
541
+ .lct-disclose-summary {
542
+ cursor: pointer;
543
+ list-style: none;
544
+ user-select: none;
561
545
  }
562
-
563
- .lct-toolbar-head {
564
- align-items: flex-start;
565
- display: flex;
566
- gap: 16px;
567
- justify-content: space-between;
568
- margin-bottom: 12px;
546
+ .lct-disclose-summary::-webkit-details-marker { display: none; }
547
+ .lct-disclose-summary::after {
548
+ content: "▸";
549
+ margin-left: 6px;
550
+ color: var(--lct-subtle);
551
+ font-size: var(--fs-xs);
552
+ transition: transform 0.15s ease;
553
+ display: inline-block;
554
+ }
555
+ .lct-disclose[open] .lct-disclose-summary::after { transform: rotate(90deg); }
556
+ .lct-disclose-summary:hover { background: var(--lct-surface-2); }
557
+ .lct-disclose-hint {
558
+ margin-left: auto;
559
+ font-size: var(--fs-xs);
560
+ color: var(--lct-muted);
561
+ font-weight: 500;
569
562
  }
570
563
 
571
- .lct-toolbar-actions { align-items: center; display: flex; gap: 8px; flex-wrap: wrap; }
572
-
573
- .lct-toolbar-actions .lct-button,
574
- .lct-banner .lct-button { font-size: var(--fs-sm); height: 32px; padding: 0 12px; }
575
-
576
- .lct-filters { display: block; }
564
+ .lct-pre {
565
+ margin: 0;
566
+ padding: var(--sp-3) var(--sp-4);
567
+ font-family: var(--mono);
568
+ font-size: var(--fs-xs);
569
+ color: var(--lct-text);
570
+ background: var(--lct-surface-2);
571
+ border-top: 1px solid var(--lct-border);
572
+ overflow-x: auto;
573
+ white-space: pre-wrap;
574
+ word-break: break-word;
575
+ }
577
576
 
578
- .lct-filter-row {
579
- align-items: flex-end;
577
+ .lct-stack-track {
580
578
  display: flex;
581
- flex-wrap: wrap;
582
- gap: 12px;
579
+ width: 100%;
580
+ height: 10px;
581
+ border-radius: 999px;
582
+ overflow: hidden;
583
+ background: var(--lct-surface-2);
583
584
  }
584
-
585
- .lct-filter-actions {
586
- align-items: flex-end;
585
+ .lct-stack-fill { height: 100%; display: block; }
586
+ .lct-stack-fill-input { background: var(--lct-accent); }
587
+ .lct-stack-fill-output { background: color-mix(in oklab, var(--lct-accent) 55%, white); }
588
+ .lct-stack-fill-cache-read { background: color-mix(in oklab, var(--lct-accent) 80%, white); }
589
+ .lct-stack-fill-cache-write { background: color-mix(in oklab, var(--lct-accent) 70%, white); }
590
+ .lct-stack-fill-cache-write-extended { background: color-mix(in oklab, var(--lct-accent) 45%, white); }
591
+ .lct-stack-fill-audio-input { background: var(--lct-provider-anthropic); }
592
+ .lct-stack-fill-audio-output { background: color-mix(in oklab, var(--lct-provider-anthropic) 60%, white); }
593
+ .lct-stack-fill-image-input { background: var(--lct-provider-openai); }
594
+ .lct-stack-fill-image-output { background: color-mix(in oklab, var(--lct-provider-openai) 60%, white); }
595
+
596
+ .lct-stack-legend {
587
597
  display: flex;
588
598
  flex-wrap: wrap;
589
- gap: 8px;
590
- margin-left: auto;
599
+ gap: 8px 20px;
600
+ margin-top: 12px;
601
+ font-size: var(--fs-xs);
591
602
  }
592
-
593
- .lct-field {
603
+ .lct-stack-legend-item {
594
604
  display: flex;
595
- flex: 1 1 160px;
596
- flex-direction: column;
597
- gap: 6px;
598
- min-width: 140px;
605
+ align-items: center;
606
+ gap: 8px;
607
+ color: var(--lct-muted);
608
+ font-variant-numeric: tabular-nums;
599
609
  }
610
+ .lct-stack-key { display: inline-flex; align-items: center; gap: 6px; color: var(--lct-text); font-weight: 500; }
611
+ .lct-stack-swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
612
+ .lct-stack-meta { color: var(--lct-muted); }
613
+ .lct-stack-empty { color: var(--lct-muted); font-size: var(--fs-sm); margin: 0; }
600
614
 
601
- .lct-field input,
602
- .lct-field select {
603
- appearance: none;
604
- -webkit-appearance: none;
605
- -moz-appearance: none;
606
- background: var(--lct-panel);
607
- border: 1px solid var(--lct-border);
608
- border-radius: 8px;
609
- box-sizing: border-box;
610
- color: var(--lct-text);
611
- font-family: inherit;
612
- font-size: var(--fs-md);
613
- height: var(--lct-control-height);
614
- line-height: 1.2;
615
- padding: 0 12px;
616
- width: 100%;
617
- }
615
+ .lct-legend { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--lct-muted); }
616
+ .lct-legend-dot { width: 9px; height: 9px; border-radius: 2px; }
617
+ .lct-legend-dot-current { background: var(--lct-accent); }
618
+ .lct-legend-dot-prior { background: var(--lct-subtle); }
618
619
 
619
- .lct-field select {
620
- background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23697386' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 4.5l3.5 3.5 3.5-3.5'/></svg>");
621
- background-position: right 10px center;
622
- background-repeat: no-repeat;
623
- background-size: 12px 12px;
624
- padding-right: 32px;
620
+ .lct-tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
621
+ .lct-tbl th {
622
+ font-size: var(--fs-2xs);
623
+ font-weight: 700;
624
+ text-transform: uppercase;
625
+ letter-spacing: 0.08em;
626
+ color: var(--lct-muted);
627
+ text-align: left;
628
+ padding: 9px var(--sp-4);
629
+ border-bottom: 1px solid var(--lct-border);
630
+ background: var(--lct-th-bg);
631
+ white-space: nowrap;
625
632
  }
626
-
627
- .lct-field input[type="date"] {
633
+ .lct-tbl td {
634
+ padding: 9px var(--sp-4);
635
+ border-bottom: 1px solid var(--lct-border);
628
636
  font-variant-numeric: tabular-nums;
629
- padding-right: 8px;
637
+ vertical-align: middle;
638
+ color: var(--lct-text);
630
639
  }
640
+ .lct-tbl tr:last-child td { border-bottom: 0; }
641
+ .lct-tbl tr:hover td { background: var(--lct-row-hover); }
642
+ .lct-num { text-align: right !important; white-space: nowrap; font-variant-numeric: tabular-nums; }
643
+ .lct-num-muted { color: var(--lct-muted); }
644
+ .lct-tbl th.lct-num { text-align: right; }
631
645
 
632
- .lct-field input[type="date"]::-webkit-calendar-picker-indicator {
633
- cursor: pointer;
634
- filter: invert(45%) sepia(8%) saturate(437%) hue-rotate(176deg) brightness(95%) contrast(86%);
635
- opacity: 0.85;
646
+ .lct-tbl th.lct-sortable { cursor: pointer; user-select: none; }
647
+ .lct-tbl th.lct-sortable a { color: inherit; text-decoration: none; display: inline-block; }
648
+ .lct-tbl th.lct-sortable:hover { background: var(--lct-surface-hover); color: var(--lct-text); }
649
+ .lct-sort-ind {
650
+ display: inline-block;
651
+ margin-left: 4px;
652
+ opacity: 0;
653
+ font-size: 9px;
654
+ color: var(--lct-muted);
655
+ vertical-align: 1px;
636
656
  }
657
+ .lct-tbl th.lct-sortable:hover .lct-sort-ind { opacity: 0.6; }
658
+ .lct-tbl th.lct-sortable.lct-sorted { color: var(--lct-text); }
659
+ .lct-tbl th.lct-sortable.lct-sorted .lct-sort-ind { opacity: 1; color: var(--lct-accent); }
637
660
 
638
- .lct-field input::placeholder { color: var(--lct-muted); }
639
-
640
- .lct-field input:hover,
641
- .lct-field select:hover { border-color: var(--lct-border-strong); }
661
+ .lct-table-wrap { overflow-x: auto; }
642
662
 
643
- .lct-field input:focus,
644
- .lct-field select:focus {
645
- border-color: var(--lct-accent);
646
- box-shadow: var(--lct-focus-ring);
647
- outline: none;
663
+ .lct-model-cell { display: inline-flex; align-items: center; gap: var(--sp-2); }
664
+ .lct-provider-dot {
665
+ width: 8px;
666
+ height: 8px;
667
+ border-radius: var(--radius-pill);
668
+ flex-shrink: 0;
648
669
  }
670
+ .lct-provider-dot-anthropic { background: var(--lct-provider-anthropic); }
671
+ .lct-provider-dot-openai { background: var(--lct-provider-openai); }
672
+ .lct-provider-dot-gemini { background: var(--lct-provider-gemini); }
673
+ .lct-provider-dot-ruby_llm { background: var(--lct-provider-ruby_llm); }
649
674
 
650
- .lct-results-toolbar {
651
- align-items: center;
652
- display: flex;
653
- flex-wrap: wrap;
654
- gap: 12px;
655
- margin: -4px 0 8px;
675
+ .lct-code-id {
676
+ font-family: var(--mono);
677
+ font-size: var(--fs-xs);
678
+ color: var(--lct-accent-strong);
656
679
  }
657
-
658
- .lct-results-toolbar .lct-pagination-per { order: 0; margin-right: auto; }
659
- .lct-results-toolbar .lct-sort { order: 1; margin-left: auto; }
660
-
661
- .lct-sort {
680
+ .lct-tag-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; max-width: 380px; }
681
+ .lct-tag-chip {
662
682
  align-items: center;
663
- background: var(--lct-surface);
664
- border-radius: 6px;
683
+ background: var(--lct-accent-soft);
684
+ border: 0;
685
+ border-radius: var(--radius-pill);
686
+ color: var(--lct-text);
665
687
  display: inline-flex;
666
- flex-wrap: wrap;
667
- gap: 2px;
668
- padding: 2px;
669
- }
670
-
671
- .lct-sort-option {
672
- border-radius: 4px;
673
- color: var(--lct-muted);
674
- display: inline-block;
688
+ font-family: var(--mono);
675
689
  font-size: var(--fs-xs);
676
- font-weight: 500;
677
- padding: 4px 8px;
690
+ line-height: 1.5;
691
+ padding: 2px 9px 2px 8px;
678
692
  text-decoration: none;
693
+ white-space: nowrap;
679
694
  }
680
-
681
- .lct-sort-option:hover { background: var(--lct-panel); color: var(--lct-text); }
682
- .lct-sort-option.is-active {
683
- background: var(--lct-panel);
684
- box-shadow: var(--lct-shadow);
685
- color: var(--lct-text);
695
+ .lct-tag-chip-key { color: var(--lct-accent); font-weight: 700; margin-right: 3px; letter-spacing: 0.02em; }
696
+ .lct-tag-chip-more {
697
+ background: transparent;
698
+ border: 1px dashed var(--lct-border-strong);
699
+ color: var(--lct-muted);
700
+ font-family: var(--mono);
701
+ padding: 1px 8px;
686
702
  }
687
703
 
688
- .lct-button {
689
- align-items: center;
690
- background: var(--lct-accent);
691
- border: 1px solid var(--lct-accent);
692
- border-radius: 8px;
693
- box-shadow: var(--lct-shadow-sm);
694
- color: #ffffff;
695
- cursor: pointer;
696
- display: inline-flex;
697
- font-family: inherit;
698
- font-size: var(--fs-md);
699
- font-weight: 600;
700
- justify-content: center;
701
- line-height: 1.2;
702
- height: var(--lct-control-height);
703
- padding: 0 14px;
704
- text-decoration: none;
705
- transition: background-color 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease, transform 0.08s ease;
706
- white-space: nowrap;
707
- }
704
+ .lct-spark { display: inline-block; width: 80px; height: 22px; vertical-align: middle; color: var(--lct-accent); }
708
705
 
709
- .lct-button:hover {
710
- background: var(--lct-accent-hover);
711
- border-color: var(--lct-accent-hover);
712
- box-shadow: var(--lct-shadow-md);
713
- transform: translateY(-1px);
706
+ .lct-bar {
707
+ display: inline-block;
708
+ height: 4px;
709
+ background: var(--lct-accent);
710
+ border-radius: var(--radius-pill);
711
+ vertical-align: middle;
712
+ opacity: 0.75;
714
713
  }
715
714
 
716
- .lct-button:active {
717
- transform: translateY(0);
718
- box-shadow: var(--lct-shadow-sm);
715
+ .lct-status-pill {
716
+ display: inline-flex;
717
+ align-items: center;
718
+ gap: 4px;
719
+ padding: 2px 8px;
720
+ border-radius: var(--radius-pill);
721
+ font-size: var(--fs-xs);
722
+ font-weight: 600;
719
723
  }
724
+ .lct-status-pill-ok { background: var(--lct-success-soft); color: var(--lct-success); }
725
+ .lct-status-pill-warn { background: var(--lct-warning-soft); color: var(--lct-warning); }
726
+ .lct-status-pill-danger { background: var(--lct-danger-soft); color: var(--lct-danger); }
727
+ .lct-status-pill-neutral{ background: var(--lct-surface-2); color: var(--lct-muted); }
720
728
 
721
- .lct-button:focus-visible,
722
- .lct-chip-remove:focus-visible,
723
- .lct-clear-link:focus-visible,
724
- .lct-nav a:focus-visible {
725
- box-shadow: var(--lct-focus-ring);
726
- outline: none;
729
+ .lct-filter-row {
730
+ display: flex;
731
+ align-items: center;
732
+ gap: 6px;
733
+ margin-bottom: var(--sp-3);
734
+ flex-wrap: wrap;
727
735
  }
728
-
729
- .lct-button-secondary {
730
- background: var(--lct-panel);
731
- border-color: var(--lct-border);
736
+ .lct-filter-pill {
737
+ display: inline-flex;
738
+ align-items: center;
739
+ gap: 6px;
740
+ height: 30px;
741
+ padding: 0 10px;
742
+ background: var(--lct-surface);
743
+ border: 1px solid var(--lct-border-strong);
744
+ border-radius: var(--radius-sm);
745
+ font-size: var(--fs-sm);
732
746
  color: var(--lct-text);
747
+ cursor: pointer;
748
+ line-height: 1;
749
+ text-decoration: none;
750
+ list-style: none;
751
+ user-select: none;
733
752
  }
734
- .lct-button-secondary:hover {
735
- background: var(--lct-row-hover);
736
- border-color: var(--lct-border-strong);
753
+ .lct-filter-pill::-webkit-details-marker { display: none; }
754
+ .lct-filter-pill:hover { background: var(--lct-surface-2); }
755
+ .lct-filter-pop {
756
+ position: relative;
757
+ display: inline-block;
758
+ }
759
+ .lct-filter-pop[open] .lct-filter-pill {
760
+ border-color: var(--lct-accent);
761
+ box-shadow: var(--lct-focus-ring);
737
762
  }
738
- .lct-button-secondary:active {
763
+ .lct-filter-pop-body {
764
+ position: absolute;
765
+ top: calc(100% + 6px);
766
+ left: 0;
767
+ z-index: 50;
739
768
  background: var(--lct-surface);
769
+ border: 1px solid var(--lct-border);
770
+ border-radius: var(--radius-md);
771
+ box-shadow: var(--lct-shadow-md);
772
+ padding: var(--sp-3);
773
+ display: flex;
774
+ align-items: flex-end;
775
+ gap: var(--sp-2);
740
776
  }
741
-
742
- @media (prefers-reduced-motion: reduce) {
743
- .lct-button { transition: none; }
744
- .lct-button:hover { transform: none; }
777
+ .lct-filter-pop-field { display: flex; flex-direction: column; gap: 4px; }
778
+ .lct-filter-pop-field label {
779
+ font-size: var(--fs-2xs);
780
+ font-weight: 700;
781
+ color: var(--lct-muted);
782
+ text-transform: uppercase;
783
+ letter-spacing: 0.08em;
745
784
  }
746
-
747
- .lct-button-compact {
785
+ .lct-filter-pop-field input {
786
+ font: inherit;
748
787
  font-size: var(--fs-sm);
749
- height: 32px;
750
- min-height: 32px;
788
+ height: var(--lct-control-height);
751
789
  padding: 0 10px;
752
- }
753
-
754
- .lct-toolbar-note { color: var(--lct-muted); font-size: var(--fs-xs); margin: 10px 0 0; }
755
-
756
- .lct-chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
757
-
758
- .lct-chip {
759
- align-items: center;
760
- background: var(--lct-accent-soft);
761
- border: 1px solid rgba(99, 91, 255, 0.12);
762
- border-radius: 999px;
790
+ border: 1px solid var(--lct-border-strong);
791
+ border-radius: var(--radius-sm);
792
+ background: var(--lct-surface);
763
793
  color: var(--lct-text);
764
- display: inline-flex;
765
- font-size: var(--fs-sm);
766
- gap: 8px;
767
- min-height: 28px;
768
- padding: 0 10px;
769
- }
770
-
771
- .lct-chip-remove {
772
- color: var(--lct-chip-remove);
773
- font-size: var(--fs-lg);
774
794
  line-height: 1;
775
- text-decoration: none;
795
+ min-width: 140px;
776
796
  }
777
-
778
- .lct-chip-remove:hover,
779
- .lct-clear-link:hover { color: var(--lct-accent); }
780
-
781
- .lct-clear-link {
782
- color: var(--lct-accent);
797
+ .lct-filter-pop-field input:focus { outline: none; box-shadow: var(--lct-focus-ring); border-color: var(--lct-accent); }
798
+ .lct-filter-pop-field select {
799
+ font: inherit;
783
800
  font-size: var(--fs-sm);
784
- font-weight: 600;
785
- margin-left: 4px;
786
- text-decoration: none;
801
+ height: var(--lct-control-height);
802
+ padding: 0 28px 0 10px;
803
+ border: 1px solid var(--lct-border-strong);
804
+ border-radius: var(--radius-sm);
805
+ background: var(--lct-surface);
806
+ color: var(--lct-text);
807
+ line-height: 1;
808
+ min-width: 180px;
809
+ appearance: none;
810
+ -webkit-appearance: none;
811
+ background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
812
+ background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
813
+ background-size: 5px 5px, 5px 5px;
814
+ background-repeat: no-repeat;
787
815
  }
788
-
789
- .lct-summary-row {
790
- align-items: center;
816
+ .lct-filter-pop-field select:focus { outline: none; box-shadow: var(--lct-focus-ring); border-color: var(--lct-accent); }
817
+ .lct-filter-pill svg { color: var(--lct-subtle); flex-shrink: 0; }
818
+ .lct-filter-pill-key {
791
819
  color: var(--lct-muted);
792
- display: flex;
793
- flex-wrap: wrap;
794
- gap: 8px;
795
- font-size: var(--fs-sm);
796
- margin-top: 12px;
820
+ font-weight: 500;
797
821
  }
798
-
799
- .lct-pagination {
800
- align-items: center;
801
- display: flex;
802
- justify-content: space-between;
803
- gap: 12px 20px;
804
- margin-top: 18px;
805
- flex-wrap: wrap;
806
- padding-top: 16px;
807
- border-top: 1px solid var(--lct-border);
822
+ .lct-filter-pill-key::after { content: ":"; margin: 0 1px 0 0; }
823
+ .lct-filter-pill-value {
824
+ color: var(--lct-text);
825
+ font-weight: 600;
808
826
  }
809
-
810
- .lct-pagination-info {
811
- display: flex;
812
- align-items: center;
813
- gap: 12px 18px;
814
- color: var(--lct-muted);
815
- font-size: var(--fs-sm);
816
- font-variant-numeric: tabular-nums;
817
- flex-wrap: wrap;
827
+ .lct-filter-pill .lct-chev { color: var(--lct-subtle); }
828
+ .lct-filter-pill.lct-active {
829
+ border-color: color-mix(in oklab, var(--lct-accent) 50%, var(--lct-border-strong));
830
+ background: var(--lct-accent-soft);
818
831
  }
819
-
820
- .lct-pagination-info strong { color: var(--lct-text); font-weight: 600; }
821
-
822
- .lct-pagination-per { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
823
- .lct-pagination-per-label { color: var(--lct-muted); font-size: var(--fs-xs); font-weight: 500; }
824
-
825
- .lct-pagination-per-option {
832
+ .lct-filter-pill.lct-active .lct-filter-pill-key,
833
+ .lct-filter-pill.lct-active .lct-filter-pill-value { color: var(--lct-accent-strong); }
834
+ .lct-filter-row-meta {
835
+ margin-left: auto;
826
836
  color: var(--lct-muted);
827
- text-decoration: none;
828
- padding: 2px 8px;
829
- border-radius: 999px;
830
837
  font-size: var(--fs-xs);
831
838
  font-variant-numeric: tabular-nums;
832
839
  }
833
-
834
- .lct-pagination-per-option:hover { background: transparent; color: var(--lct-text); }
835
- .lct-pagination-per-option.is-active { color: var(--lct-text); font-weight: 600; background: var(--lct-surface); }
836
-
837
- .lct-pagination-nav {
838
- display: inline-flex;
839
- align-items: center;
840
- gap: 0;
841
- margin-left: auto;
842
- border: 1px solid var(--lct-border);
843
- border-radius: 8px;
844
- background: var(--lct-panel);
845
- overflow: hidden;
840
+ .lct-filter-clear {
841
+ color: var(--lct-accent-strong);
842
+ font-size: var(--fs-xs);
843
+ font-weight: 600;
844
+ cursor: pointer;
845
+ padding: 0 6px;
846
+ text-decoration: none;
846
847
  }
848
+ .lct-filter-clear:hover { text-decoration: underline; }
847
849
 
848
- .lct-page-link {
849
- min-width: 40px;
850
- height: 40px;
851
- padding: 0;
850
+ .lct-button {
851
+ font: inherit;
852
+ height: var(--lct-control-height);
853
+ padding: 0 var(--sp-4);
854
+ border: 1px solid transparent;
855
+ border-radius: var(--radius-sm);
856
+ font-weight: 600;
857
+ font-size: var(--fs-sm);
858
+ cursor: pointer;
859
+ line-height: 1;
860
+ text-decoration: none;
852
861
  display: inline-flex;
853
862
  align-items: center;
854
863
  justify-content: center;
855
- border-radius: 0;
856
- border: 0;
857
- border-right: 1px solid var(--lct-border);
858
- background: transparent;
864
+ }
865
+ .lct-button-primary {
866
+ background: var(--lct-accent);
867
+ color: white;
868
+ box-shadow: 0 1px 2px rgba(91, 84, 216, 0.35);
869
+ }
870
+ .lct-button-primary:hover { background: var(--lct-accent-strong); }
871
+ .lct-button-secondary {
872
+ background: var(--lct-surface);
873
+ border-color: var(--lct-border-strong);
859
874
  color: var(--lct-text);
860
- font-size: var(--fs-sm);
861
- font-variant-numeric: tabular-nums;
862
- font-weight: 500;
863
- text-decoration: none;
864
- transition: background-color 0.1s ease, border-color 0.1s ease, color 0.1s ease;
865
875
  }
876
+ .lct-button-secondary:hover { background: var(--lct-surface-2); }
866
877
 
867
- .lct-page-link:hover { background: var(--lct-row-hover); }
868
- .lct-page-link.is-current { background: var(--lct-accent); color: #fff; font-weight: 600; cursor: default; }
869
- .lct-page-link.is-disabled { color: var(--lct-muted); background: transparent; cursor: not-allowed; opacity: 0.55; }
870
-
871
- .lct-page-arrow { font-size: var(--fs-lg); line-height: 1; min-width: 40px; }
872
-
873
- .lct-page-gap {
874
- align-items: center;
875
- border-right: 1px solid var(--lct-border);
878
+ .lct-seg {
876
879
  display: inline-flex;
877
- height: 40px;
878
- justify-content: center;
879
- min-width: 40px;
880
- text-align: center;
881
- color: var(--lct-muted);
882
- font-variant-numeric: tabular-nums;
883
- user-select: none;
884
- }
885
-
886
- .lct-pagination-nav > *:last-child { border-right: 0; }
887
-
888
- .lct-nowrap { white-space: nowrap; }
889
-
890
- .lct-detail-grid { align-items: start; display: grid; gap: 16px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
891
-
892
- .lct-dl {
893
- display: grid;
894
- gap: 12px;
895
- grid-template-columns: minmax(120px, 0.45fr) minmax(0, 1fr);
896
- margin: 0;
880
+ background: var(--lct-surface-2);
881
+ border: 1px solid var(--lct-border);
882
+ border-radius: var(--radius-sm);
883
+ padding: 2px;
897
884
  }
898
-
899
- .lct-dl dt {
900
- color: var(--lct-muted);
901
- font-size: var(--fs-sm);
885
+ .lct-seg a {
886
+ padding: 4px 10px;
887
+ font-size: var(--fs-xs);
902
888
  font-weight: 500;
889
+ color: var(--lct-muted);
890
+ border-radius: 4px;
891
+ cursor: pointer;
892
+ text-decoration: none;
903
893
  }
904
- .lct-dl dd { color: var(--lct-text); font-size: var(--fs-sm); margin: 0; min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
905
-
906
- .lct-pre {
907
- background: #0f172a;
908
- border-radius: 8px;
909
- color: #e5e7eb;
910
- margin: 0;
911
- overflow: auto;
912
- padding: 16px;
894
+ .lct-seg a:hover { background: var(--lct-surface); color: var(--lct-text); }
895
+ .lct-seg a.lct-active {
896
+ background: var(--lct-surface);
897
+ color: var(--lct-text);
898
+ font-weight: 600;
899
+ box-shadow: 0 1px 2px rgba(13, 27, 42, 0.07), inset 0 0 0 1px var(--lct-border-strong);
913
900
  }
914
901
 
915
- .lct-call-hero {
916
- align-items: start;
902
+ .lct-pagination {
917
903
  display: flex;
918
- gap: 20px;
919
- justify-content: space-between;
920
- margin-bottom: 20px;
921
- }
922
-
923
- .lct-call-title { margin-bottom: 8px; }
924
-
925
- .lct-call-subtitle {
926
904
  align-items: center;
905
+ gap: var(--sp-3);
906
+ padding: 7px var(--sp-4);
907
+ border-top: 1px solid var(--lct-border);
908
+ font-size: var(--fs-xs);
927
909
  color: var(--lct-muted);
928
- display: flex;
929
- flex-wrap: wrap;
930
- gap: 8px;
931
- margin: 0;
932
- }
933
-
934
- .lct-call-summary {
935
- display: grid;
936
- gap: 10px;
937
- grid-template-columns: repeat(2, minmax(0, 1fr));
938
- min-width: min(420px, 100%);
939
910
  }
940
-
941
- .lct-call-summary-item {
942
- background: var(--lct-row-hover);
943
- border: 1px solid var(--lct-border);
944
- border-radius: 8px;
945
- display: grid;
946
- gap: 4px;
947
- padding: 10px 12px;
911
+ .lct-pagination-info { font-variant-numeric: tabular-nums; }
912
+ .lct-pagination-info strong { color: var(--lct-text); }
913
+ .lct-pagination-perpage { margin-left: auto; }
914
+ .lct-pagination .lct-seg { padding: 1px; }
915
+ .lct-pagination .lct-seg a { padding: 2px 8px; font-size: var(--fs-2xs); }
916
+ .lct-pagination-nav { display: flex; gap: 2px; align-items: center; }
917
+ .lct-pagination-nav::before {
918
+ content: "";
919
+ width: 1px;
920
+ height: 14px;
921
+ background: var(--lct-border);
922
+ margin: 0 4px;
948
923
  }
949
-
950
- .lct-call-breakdown-grid {
951
- display: grid;
952
- gap: 16px;
953
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
954
- margin-bottom: 16px;
924
+ .lct-page-link {
925
+ display: inline-grid;
926
+ place-items: center;
927
+ min-width: 22px;
928
+ height: 22px;
929
+ padding: 0 6px;
930
+ border-radius: var(--radius-sm);
931
+ font-size: var(--fs-2xs);
932
+ font-weight: 600;
933
+ color: var(--lct-muted);
934
+ background: transparent;
935
+ cursor: pointer;
936
+ text-decoration: none;
955
937
  }
956
-
957
- .lct-stack-legend { display: grid; gap: 8px; margin-top: 12px; }
958
-
959
- .lct-stack-legend-item {
960
- align-items: center;
938
+ .lct-page-link:hover { background: var(--lct-surface-2); color: var(--lct-text); }
939
+ .lct-page-link.lct-current { background: var(--lct-accent); color: white; box-shadow: 0 1px 2px rgba(91, 84, 216, 0.35); }
940
+ .lct-page-link.lct-disabled { color: var(--lct-subtle); cursor: default; }
941
+ .lct-page-link.lct-disabled:hover { background: transparent; color: var(--lct-subtle); }
942
+
943
+ .lct-heatmap { display: grid; grid-template-columns: repeat(30, 1fr); gap: 2px; }
944
+ .lct-heatmap .lct-cell { height: 18px; border-radius: 2px; background: var(--lct-surface-2); }
945
+ .lct-heatmap .lct-l1 { background: color-mix(in oklab, var(--lct-accent) 14%, transparent); }
946
+ .lct-heatmap .lct-l2 { background: color-mix(in oklab, var(--lct-accent) 30%, transparent); }
947
+ .lct-heatmap .lct-l3 { background: color-mix(in oklab, var(--lct-accent) 50%, transparent); }
948
+ .lct-heatmap .lct-l4 { background: color-mix(in oklab, var(--lct-accent) 75%, transparent); }
949
+ .lct-heatmap .lct-l5 { background: var(--lct-accent); }
950
+ .lct-heatmap-labels {
961
951
  display: flex;
962
- font-size: var(--fs-sm);
963
- gap: 12px;
964
952
  justify-content: space-between;
953
+ padding: 6px 0 0;
954
+ font-size: var(--fs-2xs);
955
+ color: var(--lct-muted);
956
+ font-variant-numeric: tabular-nums;
965
957
  }
966
958
 
967
- .lct-stack-key { align-items: center; display: inline-flex; gap: 8px; }
968
- .lct-stack-swatch { border-radius: 999px; display: inline-block; height: 8px; width: 8px; }
969
- .lct-stack-meta { color: var(--lct-muted); font-variant-numeric: tabular-nums; }
970
-
971
- @media (max-width: 800px) {
972
- .lct-header { flex-direction: column; }
973
-
974
- .lct-hero,
975
- .lct-stat-grid,
976
- .lct-two-col { grid-template-columns: 1fr; }
977
-
978
- .lct-filters { gap: 12px; }
979
-
980
- .lct-filter-row,
981
- .lct-filter-row-basic { align-items: stretch; grid-template-columns: 1fr; }
982
-
983
- .lct-filter-actions { justify-content: flex-start; width: 100%; }
984
-
985
- .lct-toolbar { padding: 16px; position: static; }
986
-
987
- .lct-pagination { align-items: flex-start; flex-direction: column; }
988
-
989
- .lct-pagination-nav { margin-left: 0; width: 100%; overflow-x: auto; }
990
-
991
- .lct-detail-grid { grid-template-columns: 1fr; }
992
-
993
- .lct-call-hero { flex-direction: column; }
959
+ .lct-chart { width: 100%; height: auto; display: block; }
960
+ .lct-chart-area { fill: url(#lct-chart-grad); }
961
+ .lct-chart-line { fill: none; stroke: var(--lct-accent); stroke-width: 2.25; stroke-linejoin: round; stroke-linecap: round; }
962
+ .lct-chart-line-secondary { fill: none; stroke: var(--lct-chart-secondary); stroke-width: 1.4; stroke-dasharray: 3 3; }
963
+ .lct-chart-dot { fill: var(--lct-accent); }
964
+ .lct-chart-peak { fill: var(--lct-accent); stroke: var(--lct-accent-soft); stroke-width: 4; }
965
+ .lct-chart-grid { stroke: var(--lct-border); stroke-dasharray: 2 4; }
966
+ .lct-chart-axis { fill: var(--lct-muted); font-family: var(--mono); font-size: var(--fs-2xs); }
994
967
 
995
- .lct-call-summary,
996
- .lct-call-breakdown-grid { grid-template-columns: 1fr; min-width: 0; }
968
+ .lct-empty {
969
+ padding: 56px 28px;
970
+ text-align: center;
971
+ background: var(--lct-panel);
997
972
  }
973
+ .lct-state-title { font-size: var(--fs-lg); font-weight: 600; margin: 0 0 6px; letter-spacing: -0.005em; }
974
+ .lct-state-copy { color: var(--lct-muted); margin: 0 auto; max-width: 480px; font-size: var(--fs-sm); line-height: 1.55; }
975
+
976
+ .lct-setup-card { max-width: 640px; margin: var(--sp-5) auto 0; }
977
+ .lct-setup-body p { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); color: var(--lct-text); line-height: 1.55; }
978
+ .lct-setup-body p:last-child { margin-bottom: 0; }