@dollhousemcp/mcp-server 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/generated/version.d.ts +2 -2
  3. package/dist/generated/version.js +3 -3
  4. package/dist/seed-elements/memories/dollhousemcp-baseline-knowledge.yaml +149 -0
  5. package/dist/seed-elements/memories/how-to-create-custom-auto-load-memories.yaml +455 -0
  6. package/dist/seed-elements/memories/priority-best-practices-for-teams.yaml +542 -0
  7. package/dist/seed-elements/memories/token-estimation-guidelines.yaml +602 -0
  8. package/dist/web/public/fonts/ibmplexmono--F63fjptAgt5VM-kVkqdyU8n1i8q131nj-o.woff2 +0 -0
  9. package/dist/web/public/fonts/ibmplexmono--F63fjptAgt5VM-kVkqdyU8n1iAq131nj-otFQ.woff2 +0 -0
  10. package/dist/web/public/fonts/ibmplexmono--F63fjptAgt5VM-kVkqdyU8n1iEq131nj-otFQ.woff2 +0 -0
  11. package/dist/web/public/fonts/ibmplexmono--F63fjptAgt5VM-kVkqdyU8n1iIq131nj-otFQ.woff2 +0 -0
  12. package/dist/web/public/fonts/ibmplexmono--F63fjptAgt5VM-kVkqdyU8n1isq131nj-otFQ.woff2 +0 -0
  13. package/dist/web/public/fonts/ibmplexmono--F6qfjptAgt5VM-kVkqdyU8n3twJwl1FgsAXHNlYzg.woff2 +0 -0
  14. package/dist/web/public/fonts/ibmplexmono--F6qfjptAgt5VM-kVkqdyU8n3twJwl5FgsAXHNlYzg.woff2 +0 -0
  15. package/dist/web/public/fonts/ibmplexmono--F6qfjptAgt5VM-kVkqdyU8n3twJwl9FgsAXHNlYzg.woff2 +0 -0
  16. package/dist/web/public/fonts/ibmplexmono--F6qfjptAgt5VM-kVkqdyU8n3twJwlBFgsAXHNk.woff2 +0 -0
  17. package/dist/web/public/fonts/ibmplexmono--F6qfjptAgt5VM-kVkqdyU8n3twJwlRFgsAXHNlYzg.woff2 +0 -0
  18. package/dist/web/public/fonts/manrope-xn7gYHE41ni1AdIRggOxSvfedN62Zw.woff2 +0 -0
  19. package/dist/web/public/fonts/manrope-xn7gYHE41ni1AdIRggSxSvfedN62Zw.woff2 +0 -0
  20. package/dist/web/public/fonts/manrope-xn7gYHE41ni1AdIRggexSvfedN4.woff2 +0 -0
  21. package/dist/web/public/fonts/manrope-xn7gYHE41ni1AdIRggixSvfedN62Zw.woff2 +0 -0
  22. package/dist/web/public/fonts/manrope-xn7gYHE41ni1AdIRggmxSvfedN62Zw.woff2 +0 -0
  23. package/dist/web/public/fonts/manrope-xn7gYHE41ni1AdIRggqxSvfedN62Zw.woff2 +0 -0
  24. package/dist/web/public/fonts/plusjakartasans-LDIoaomQNQcsA88c7O9yZ4KMCoOg4Ko20yygg_vb.woff2 +0 -0
  25. package/dist/web/public/fonts/plusjakartasans-LDIoaomQNQcsA88c7O9yZ4KMCoOg4Ko40yygg_vbd-E.woff2 +0 -0
  26. package/dist/web/public/fonts/plusjakartasans-LDIoaomQNQcsA88c7O9yZ4KMCoOg4Ko50yygg_vbd-E.woff2 +0 -0
  27. package/dist/web/public/fonts/plusjakartasans-LDIoaomQNQcsA88c7O9yZ4KMCoOg4Ko70yygg_vbd-E.woff2 +0 -0
  28. package/dist/web/public/fonts.css +270 -0
  29. package/dist/web/public/index.html +365 -0
  30. package/dist/web/public/logs.css +472 -0
  31. package/dist/web/public/metrics.css +238 -0
  32. package/dist/web/public/permissions.css +364 -0
  33. package/dist/web/public/sessions.css +235 -0
  34. package/dist/web/public/setup.css +648 -0
  35. package/dist/web/public/styles.css +1717 -0
  36. package/package.json +3 -1
  37. package/server.json +2 -2
@@ -0,0 +1,472 @@
1
+ /**
2
+ * Log Viewer Styles — Dark terminal aesthetic, theme-aware
3
+ */
4
+
5
+ /* ── Log viewer container ─────────────────────────────────────── */
6
+ .log-viewer {
7
+ display: flex;
8
+ flex-direction: column;
9
+ height: calc(100vh - 120px);
10
+ font-family: var(--font-mono);
11
+ font-size: 12.5px;
12
+ line-height: 1.5;
13
+ }
14
+
15
+ /* ── Controls bar ─────────────────────────────────────────────── */
16
+ .log-controls {
17
+ display: flex;
18
+ gap: 8px;
19
+ padding: 10px 12px;
20
+ background: var(--surface-1);
21
+ border-bottom: 1px solid var(--line);
22
+ align-items: center;
23
+ flex-wrap: wrap;
24
+ }
25
+
26
+ .log-controls label {
27
+ color: var(--ink-500);
28
+ font-size: 11px;
29
+ font-family: var(--font-mono);
30
+ text-transform: uppercase;
31
+ letter-spacing: 0.05em;
32
+ }
33
+
34
+ .log-controls select,
35
+ .log-controls input {
36
+ background: var(--paper-strong);
37
+ color: var(--ink-900);
38
+ border: 1px solid var(--line);
39
+ border-radius: var(--radius-sm);
40
+ padding: 4px 8px;
41
+ font-family: var(--font-mono);
42
+ font-size: 12px;
43
+ }
44
+
45
+ .log-controls select:focus,
46
+ .log-controls input:focus {
47
+ outline: 2px solid var(--signal-2);
48
+ outline-offset: -1px;
49
+ }
50
+
51
+ .log-filter-group {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 4px;
55
+ }
56
+
57
+ .log-search {
58
+ flex: 1;
59
+ min-width: 140px;
60
+ max-width: 280px;
61
+ }
62
+
63
+ /* ── Status & action buttons ──────────────────────────────────── */
64
+ .log-status-bar {
65
+ display: flex;
66
+ gap: 8px;
67
+ padding: 4px 12px;
68
+ background: var(--surface-2);
69
+ border-bottom: 1px solid var(--line);
70
+ align-items: center;
71
+ font-size: 11px;
72
+ color: var(--ink-500);
73
+ }
74
+
75
+ .log-status-indicator {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ gap: 4px;
79
+ }
80
+
81
+ .log-status-dot {
82
+ width: 7px;
83
+ height: 7px;
84
+ border-radius: 50%;
85
+ background: #888;
86
+ }
87
+
88
+ .log-status-dot.connected { background: #22c55e; }
89
+ .log-status-dot.disconnected { background: #ef4444; }
90
+ .log-status-dot.reconnecting { background: #f59e0b; animation: pulse-dot 1s infinite; }
91
+
92
+ @keyframes pulse-dot {
93
+ 0%, 100% { opacity: 1; }
94
+ 50% { opacity: 0.3; }
95
+ }
96
+
97
+ .log-action-btn {
98
+ background: var(--paper-strong);
99
+ color: var(--ink-700);
100
+ border: 1px solid var(--line);
101
+ border-radius: var(--radius-sm);
102
+ padding: 2px 10px;
103
+ font-family: var(--font-mono);
104
+ font-size: 11px;
105
+ cursor: pointer;
106
+ transition: background 0.15s, color 0.15s;
107
+ }
108
+
109
+ .log-action-btn:hover {
110
+ background: var(--signal-2);
111
+ color: #fff;
112
+ border-color: var(--signal-2);
113
+ }
114
+
115
+ .log-action-btn.active {
116
+ background: var(--signal);
117
+ color: #fff;
118
+ border-color: var(--signal);
119
+ }
120
+
121
+ .log-entry-count {
122
+ margin-left: auto;
123
+ font-variant-numeric: tabular-nums;
124
+ }
125
+
126
+ /* ── Virtual scroll viewport ──────────────────────────────────── */
127
+ .log-viewport {
128
+ flex: 1;
129
+ overflow-y: auto;
130
+ position: relative;
131
+ background: var(--paper);
132
+ }
133
+
134
+ .log-scroll-spacer {
135
+ width: 100%;
136
+ position: relative;
137
+ }
138
+
139
+ /* ── Log entries ──────────────────────────────────────────────── */
140
+ .log-entry {
141
+ position: absolute;
142
+ left: 0;
143
+ right: 0;
144
+ height: 22px;
145
+ display: flex;
146
+ align-items: center;
147
+ padding: 0 12px;
148
+ gap: 6px;
149
+ white-space: nowrap;
150
+ overflow: hidden;
151
+ cursor: pointer;
152
+ border-bottom: 1px solid transparent;
153
+ }
154
+
155
+ .log-entry:hover {
156
+ background: var(--surface-1);
157
+ }
158
+
159
+ .log-entry.selected {
160
+ background: color-mix(in srgb, var(--signal-2) 12%, transparent);
161
+ border-bottom-color: color-mix(in srgb, var(--signal-2) 20%, transparent);
162
+ }
163
+
164
+ .log-entry.selected:hover {
165
+ background: color-mix(in srgb, var(--signal-2) 18%, transparent);
166
+ }
167
+
168
+ /* ── Checkbox ─────────────────────────────────────────────────── */
169
+ .log-checkbox {
170
+ width: 14px;
171
+ height: 14px;
172
+ flex-shrink: 0;
173
+ border: 1.5px solid var(--line);
174
+ border-radius: 3px;
175
+ display: inline-flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ transition: background 0.1s, border-color 0.1s;
179
+ }
180
+
181
+ .log-checkbox:hover {
182
+ border-color: var(--signal-2);
183
+ }
184
+
185
+ .log-checkbox.checked {
186
+ background: var(--signal);
187
+ border-color: var(--signal);
188
+ }
189
+
190
+ .log-checkbox.checked::after {
191
+ content: '';
192
+ width: 5px;
193
+ height: 8px;
194
+ border: solid #fff;
195
+ border-width: 0 2px 2px 0;
196
+ transform: rotate(45deg) translate(-1px, -1px);
197
+ }
198
+
199
+ /* ── Entry fields ─────────────────────────────────────────────── */
200
+ .log-time {
201
+ color: var(--ink-500);
202
+ font-size: 11px;
203
+ flex-shrink: 0;
204
+ width: 85px;
205
+ }
206
+
207
+ .log-level {
208
+ font-size: 10px;
209
+ font-weight: 700;
210
+ text-transform: uppercase;
211
+ letter-spacing: 0.05em;
212
+ flex-shrink: 0;
213
+ width: 42px;
214
+ text-align: center;
215
+ padding: 1px 0;
216
+ border-radius: 3px;
217
+ }
218
+
219
+ .log-level.debug { color: var(--ink-500); background: transparent; }
220
+ .log-level.info { color: #2563eb; background: rgba(59, 130, 246, 0.1); } /* NOSONAR — contrast computed against page bg, not rgba tint */
221
+ .log-level.warn { color: #b45309; background: rgba(245, 158, 11, 0.1); } /* NOSONAR */
222
+ .log-level.error { color: #dc2626; background: rgba(239, 68, 68, 0.1); } /* NOSONAR */
223
+
224
+ .log-category {
225
+ color: var(--ink-500);
226
+ font-size: 10px;
227
+ flex-shrink: 0;
228
+ width: 70px;
229
+ }
230
+
231
+ .log-source {
232
+ color: var(--violet);
233
+ font-size: 11px;
234
+ flex-shrink: 0;
235
+ max-width: 150px;
236
+ overflow: hidden;
237
+ text-overflow: ellipsis;
238
+ }
239
+
240
+ .log-message {
241
+ color: var(--ink-900);
242
+ overflow: hidden;
243
+ text-overflow: ellipsis;
244
+ flex: 1;
245
+ }
246
+
247
+ .log-entry.level-error .log-message { color: #ef4444; }
248
+ .log-entry.level-warn .log-message { color: #f59e0b; }
249
+
250
+ /* ── Correlation ID badge (per-row) ───────────────────────────── */
251
+ .log-corr-badge {
252
+ flex-shrink: 0;
253
+ width: 60px;
254
+ text-align: center;
255
+ font-family: var(--font-mono, monospace);
256
+ font-size: 10px;
257
+ padding: 1px 5px;
258
+ border-radius: 3px;
259
+ background: color-mix(in srgb, var(--signal, #6366f1) 12%, transparent);
260
+ color: var(--signal, #6366f1);
261
+ cursor: pointer;
262
+ user-select: none;
263
+ white-space: nowrap;
264
+ }
265
+ .log-corr-badge:hover:not(.empty) {
266
+ background: color-mix(in srgb, var(--signal, #6366f1) 25%, transparent);
267
+ }
268
+ .log-corr-badge.empty {
269
+ background: none;
270
+ cursor: default;
271
+ }
272
+
273
+ /* ── Trace banner ────────────────────────────────────────────── */
274
+ .log-trace-banner {
275
+ display: flex;
276
+ align-items: center;
277
+ gap: 8px;
278
+ padding: 4px 12px;
279
+ background: color-mix(in srgb, var(--signal) 10%, var(--surface-0));
280
+ border-bottom: 1px solid color-mix(in srgb, var(--signal) 30%, transparent);
281
+ font-size: 12px;
282
+ color: var(--ink-700);
283
+ }
284
+ .log-trace-banner-icon { font-size: 13px; }
285
+ .log-trace-banner code {
286
+ font-family: var(--font-mono, monospace);
287
+ font-size: 11px;
288
+ background: color-mix(in srgb, var(--signal) 15%, transparent);
289
+ padding: 1px 6px;
290
+ border-radius: 3px;
291
+ }
292
+ .log-trace-clear {
293
+ margin-left: auto;
294
+ background: none;
295
+ border: 1px solid var(--line);
296
+ border-radius: 4px;
297
+ padding: 2px 8px;
298
+ font-size: 11px;
299
+ cursor: pointer;
300
+ color: var(--ink-500);
301
+ }
302
+ .log-trace-clear:hover {
303
+ background: var(--surface-1);
304
+ color: var(--ink-900);
305
+ }
306
+
307
+ /* ── Trace link in detail modal ──────────────────────────────── */
308
+ .log-trace-link {
309
+ color: var(--signal);
310
+ text-decoration: none;
311
+ cursor: pointer;
312
+ }
313
+ .log-trace-link:hover {
314
+ text-decoration: underline;
315
+ }
316
+
317
+ /* ── Detail modal card ────────────────────────────────────────── */
318
+ .log-detail-modal {
319
+ position: fixed;
320
+ inset: 0;
321
+ z-index: 100;
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ }
326
+
327
+ .log-detail-modal[hidden] {
328
+ display: none !important;
329
+ }
330
+
331
+ .log-detail-backdrop {
332
+ position: absolute;
333
+ inset: 0;
334
+ background: rgba(0, 0, 0, 0.4);
335
+ backdrop-filter: blur(2px);
336
+ }
337
+
338
+ .log-detail-card {
339
+ position: relative;
340
+ width: min(680px, 90vw);
341
+ max-height: 80vh;
342
+ background: var(--paper-strong);
343
+ border: 1px solid var(--line);
344
+ border-radius: var(--radius-lg);
345
+ box-shadow: var(--shadow-card);
346
+ display: flex;
347
+ flex-direction: column;
348
+ overflow: hidden;
349
+ }
350
+
351
+ .log-detail-card-header {
352
+ display: flex;
353
+ align-items: center;
354
+ justify-content: space-between;
355
+ padding: 14px 18px;
356
+ background: var(--surface-1);
357
+ border-bottom: 1px solid var(--line);
358
+ }
359
+
360
+ .log-detail-card-title {
361
+ font-family: var(--font-heading);
362
+ font-size: 14px;
363
+ font-weight: 700;
364
+ color: var(--ink-900);
365
+ }
366
+
367
+ .log-detail-card-actions {
368
+ display: flex;
369
+ gap: 6px;
370
+ align-items: center;
371
+ }
372
+
373
+ .log-detail-close {
374
+ background: none;
375
+ border: none;
376
+ color: var(--ink-500);
377
+ font-size: 18px;
378
+ cursor: pointer;
379
+ padding: 2px 6px;
380
+ border-radius: var(--radius-sm);
381
+ }
382
+
383
+ .log-detail-close:hover {
384
+ background: var(--surface-2);
385
+ color: var(--ink-900);
386
+ }
387
+
388
+ .log-detail-card-body {
389
+ padding: 16px 18px;
390
+ overflow-y: auto;
391
+ font-family: var(--font-mono);
392
+ font-size: 12px;
393
+ line-height: 1.6;
394
+ }
395
+
396
+ .log-detail-field {
397
+ display: flex;
398
+ gap: 10px;
399
+ padding: 4px 0;
400
+ border-bottom: 1px solid var(--surface-1);
401
+ }
402
+
403
+ .log-detail-field-label {
404
+ color: var(--ink-500);
405
+ min-width: 100px;
406
+ flex-shrink: 0;
407
+ font-size: 11px;
408
+ text-transform: uppercase;
409
+ letter-spacing: 0.04em;
410
+ padding-top: 1px;
411
+ }
412
+
413
+ .log-detail-field-value {
414
+ color: var(--ink-900);
415
+ word-break: break-all;
416
+ }
417
+
418
+ .log-detail-section {
419
+ margin-top: 12px;
420
+ padding-top: 8px;
421
+ border-top: 1px solid var(--line);
422
+ }
423
+
424
+ .log-detail-section-title {
425
+ font-size: 11px;
426
+ font-weight: 700;
427
+ text-transform: uppercase;
428
+ letter-spacing: 0.05em;
429
+ color: var(--ink-500);
430
+ margin-bottom: 6px;
431
+ }
432
+
433
+ .log-detail-pre {
434
+ background: var(--surface-1);
435
+ border: 1px solid var(--line);
436
+ border-radius: var(--radius-sm);
437
+ padding: 10px 12px;
438
+ margin: 6px 0;
439
+ overflow-x: auto;
440
+ font-size: 11px;
441
+ line-height: 1.5;
442
+ max-height: 300px;
443
+ white-space: pre-wrap;
444
+ word-break: break-all;
445
+ color: var(--ink-900);
446
+ }
447
+
448
+ /* ── Jump to bottom button ────────────────────────────────────── */
449
+ .log-jump-bottom {
450
+ position: absolute;
451
+ bottom: 16px;
452
+ right: 24px;
453
+ background: var(--signal);
454
+ color: #fff;
455
+ border: none;
456
+ border-radius: 20px;
457
+ padding: 6px 16px;
458
+ font-family: var(--font-mono);
459
+ font-size: 11px;
460
+ cursor: pointer;
461
+ box-shadow: var(--shadow-soft);
462
+ z-index: 10;
463
+ display: none;
464
+ }
465
+
466
+ .log-jump-bottom.visible {
467
+ display: block;
468
+ }
469
+
470
+ .log-jump-bottom:hover {
471
+ background: var(--signal-2);
472
+ }
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Metrics Dashboard Styles — Grid layout, card-based sections
3
+ */
4
+
5
+ /* ── Dashboard container ──────────────────────────────────────── */
6
+ .metrics-dashboard {
7
+ padding: 16px;
8
+ display: grid;
9
+ grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
10
+ gap: 16px;
11
+ font-family: var(--font-body);
12
+ }
13
+
14
+ @media (max-width: 900px) {
15
+ .metrics-dashboard {
16
+ grid-template-columns: 1fr;
17
+ }
18
+ }
19
+
20
+ /* ── Cards ────────────────────────────────────────────────────── */
21
+ .metrics-card {
22
+ background: var(--paper-strong);
23
+ border: 1px solid var(--line);
24
+ border-radius: var(--radius-md);
25
+ overflow: hidden;
26
+ }
27
+
28
+ .metrics-card-header {
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: space-between;
32
+ padding: 10px 14px;
33
+ background: var(--surface-1);
34
+ border-bottom: 1px solid var(--line);
35
+ cursor: pointer;
36
+ user-select: none;
37
+ }
38
+
39
+ .metrics-card-header:hover {
40
+ background: var(--surface-2);
41
+ }
42
+
43
+ .metrics-card-title {
44
+ font-family: var(--font-heading);
45
+ font-size: 13px;
46
+ font-weight: 700;
47
+ color: var(--ink-900);
48
+ letter-spacing: 0.02em;
49
+ }
50
+
51
+ .metrics-card-toggle {
52
+ font-size: 12px;
53
+ color: var(--ink-500);
54
+ transition: transform 0.2s;
55
+ }
56
+
57
+ .metrics-card.collapsed .metrics-card-toggle {
58
+ transform: rotate(-90deg);
59
+ }
60
+
61
+ .metrics-card.collapsed .metrics-card-body {
62
+ display: none;
63
+ }
64
+
65
+ .metrics-card-body {
66
+ padding: 14px;
67
+ overflow-x: auto;
68
+ }
69
+
70
+ /* ── Status bar ───────────────────────────────────────────────── */
71
+ .metrics-status-bar {
72
+ display: flex;
73
+ gap: 12px;
74
+ padding: 10px 16px;
75
+ background: var(--surface-1);
76
+ border-bottom: 1px solid var(--line);
77
+ align-items: center;
78
+ font-size: 12px;
79
+ color: var(--ink-500);
80
+ font-family: var(--font-mono);
81
+ }
82
+
83
+ .metrics-time-range {
84
+ display: flex;
85
+ gap: 4px;
86
+ margin-left: auto;
87
+ }
88
+
89
+ .metrics-time-btn {
90
+ background: var(--paper-strong);
91
+ color: var(--ink-700);
92
+ border: 1px solid var(--line);
93
+ border-radius: var(--radius-sm);
94
+ padding: 2px 10px;
95
+ font-family: var(--font-mono);
96
+ font-size: 11px;
97
+ cursor: pointer;
98
+ }
99
+
100
+ .metrics-time-btn.active {
101
+ background: var(--signal);
102
+ color: #fff;
103
+ border-color: var(--signal);
104
+ }
105
+
106
+ .metrics-time-btn:hover:not(.active) {
107
+ background: var(--surface-2);
108
+ }
109
+
110
+ /* ── Stat values ──────────────────────────────────────────────── */
111
+ .metrics-stat-grid {
112
+ display: grid;
113
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
114
+ gap: 10px;
115
+ }
116
+
117
+ .metrics-stat {
118
+ padding: 10px;
119
+ background: var(--surface-2);
120
+ border-radius: var(--radius-sm);
121
+ text-align: center;
122
+ }
123
+
124
+ .metrics-stat-value {
125
+ font-family: var(--font-mono);
126
+ font-size: 22px;
127
+ font-weight: 700;
128
+ color: var(--ink-950);
129
+ line-height: 1.2;
130
+ }
131
+
132
+ .metrics-stat-label {
133
+ font-size: 10.5px;
134
+ color: var(--ink-500);
135
+ text-transform: uppercase;
136
+ letter-spacing: 0.05em;
137
+ margin-top: 2px;
138
+ }
139
+
140
+ .metrics-stat-unit {
141
+ font-size: 11px;
142
+ color: var(--ink-500);
143
+ }
144
+
145
+ /* ── Tables ───────────────────────────────────────────────────── */
146
+ .metrics-table {
147
+ width: 100%;
148
+ min-width: 480px;
149
+ border-collapse: collapse;
150
+ font-family: var(--font-mono);
151
+ font-size: 11.5px;
152
+ }
153
+
154
+ .metrics-table th {
155
+ text-align: left;
156
+ padding: 5px 6px;
157
+ color: var(--ink-500);
158
+ font-weight: 600;
159
+ font-size: 10px;
160
+ text-transform: uppercase;
161
+ letter-spacing: 0.05em;
162
+ border-bottom: 1px solid var(--line);
163
+ }
164
+
165
+ .metrics-table td {
166
+ padding: 4px 6px;
167
+ color: var(--ink-900);
168
+ border-bottom: 1px solid var(--surface-1);
169
+ }
170
+
171
+ .metrics-table tr:hover td {
172
+ background: var(--surface-2);
173
+ }
174
+
175
+ .metrics-table tfoot td {
176
+ border-top: 2px solid var(--line);
177
+ padding-top: 6px;
178
+ color: var(--ink-950);
179
+ }
180
+
181
+ /* ── Charts ───────────────────────────────────────────────────── */
182
+ .metrics-chart-container {
183
+ width: 100%;
184
+ margin-top: 12px;
185
+ /* uPlot sets explicit pixel sizes on its wrapper — let it control height */
186
+ }
187
+
188
+ /* Prevent uPlot canvas from overflowing card width */
189
+ .metrics-chart-container .u-wrap {
190
+ max-width: 100%;
191
+ }
192
+
193
+ /* ── Alerts / warnings ────────────────────────────────────────── */
194
+ .metrics-alert {
195
+ padding: 6px 10px;
196
+ border-radius: var(--radius-sm);
197
+ font-size: 11.5px;
198
+ margin-bottom: 8px;
199
+ }
200
+
201
+ .metrics-alert.warn {
202
+ background: rgba(245, 158, 11, 0.1);
203
+ color: #b45309; /* NOSONAR — contrast computed against page bg, not rgba tint */
204
+ border: 1px solid rgba(245, 158, 11, 0.2);
205
+ }
206
+
207
+ .metrics-alert.error {
208
+ background: rgba(239, 68, 68, 0.1);
209
+ color: #dc2626; /* NOSONAR */
210
+ border: 1px solid rgba(239, 68, 68, 0.2);
211
+ }
212
+
213
+ /* ── Progress bars ────────────────────────────────────────────── */
214
+ .metrics-bar {
215
+ height: 8px;
216
+ background: var(--surface-1);
217
+ border-radius: 4px;
218
+ overflow: hidden;
219
+ margin-top: 4px;
220
+ }
221
+
222
+ .metrics-bar-fill {
223
+ height: 100%;
224
+ border-radius: 4px;
225
+ background: var(--signal-2);
226
+ transition: width 0.3s ease;
227
+ }
228
+
229
+ .metrics-bar-fill.high { background: #f59e0b; }
230
+ .metrics-bar-fill.critical { background: #ef4444; }
231
+
232
+ /* ── Loading state ────────────────────────────────────────────── */
233
+ .metrics-loading {
234
+ text-align: center;
235
+ padding: 40px;
236
+ color: var(--ink-500);
237
+ font-size: 13px;
238
+ }