claude-code-memory-explorer 0.11.0 → 0.12.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.
- package/README.md +9 -18
- package/package.json +1 -1
- package/public/app.js +598 -72
- package/public/index.html +5 -18
- package/public/style.css +429 -24
- package/server.js +291 -113
package/public/index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>
|
|
6
|
+
<title>Memory Diagnoser</title>
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Playfair+Display:wght@400;500;600&display=swap" rel="stylesheet">
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
<div class="topbar">
|
|
26
26
|
<div class="topbar-logo">
|
|
27
27
|
<div class="logo-mark"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v4c0 1.66 4.03 3 9 3s9-1.34 9-3V5"/><path d="M3 9v4c0 1.66 4.03 3 9 3s9-1.34 9-3V9"/><path d="M3 13v4c0 1.66 4.03 3 9 3s9-1.34 9-3v-4"/></svg></div>
|
|
28
|
-
<span class="logo-text">Memory</span>
|
|
28
|
+
<span class="logo-text">Memory Diagnoser</span>
|
|
29
29
|
</div>
|
|
30
30
|
<div class="spacer"></div>
|
|
31
31
|
<div class="topbar-project" id="projectBtn" onclick="changeProject()">
|
|
32
32
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/></svg>
|
|
33
33
|
<span id="projectName">Loading...</span>
|
|
34
34
|
</div>
|
|
35
|
-
<button class="topbar-btn" id="analyzeBtn" title="
|
|
35
|
+
<button class="topbar-btn" id="analyzeBtn" title="Memory health — Claude analysis" onclick="openHealthView()">
|
|
36
36
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l1.9 5.7L19.6 10l-5.7 1.9L12 17.6l-1.9-5.7L4.4 10l5.7-1.9z"/><path d="M19 15l.8 2.2L22 18l-2.2.8L19 21l-.8-2.2L16 18l2.2-.8z"/></svg>
|
|
37
37
|
<span>Analyze</span>
|
|
38
38
|
</button>
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
</div>
|
|
57
57
|
|
|
58
58
|
<!-- Size bar -->
|
|
59
|
-
<div class="budget-bar" id="budgetBar">
|
|
59
|
+
<div class="budget-bar" id="budgetBar" onclick="_toggleFootprint()" title="Click to highlight the files that count toward the memory footprint">
|
|
60
60
|
<div class="budget-label">
|
|
61
61
|
<span>Memory sources</span>
|
|
62
62
|
<span class="mono" id="budgetText">0 chars</span>
|
|
@@ -150,24 +150,11 @@
|
|
|
150
150
|
</div>
|
|
151
151
|
</div>
|
|
152
152
|
|
|
153
|
-
<!-- Analysis modal -->
|
|
154
|
-
<div class="modal-overlay" id="analysisModal" onclick="if(event.target===this)closeModal('analysisModal')">
|
|
155
|
-
<div class="modal modal-wide">
|
|
156
|
-
<div class="modal-header">
|
|
157
|
-
<h3>Claude analysis</h3>
|
|
158
|
-
<button class="modal-close" onclick="closeModal('analysisModal')">✕</button>
|
|
159
|
-
</div>
|
|
160
|
-
<div class="modal-body">
|
|
161
|
-
<div id="analysisSection"></div>
|
|
162
|
-
</div>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
|
|
166
153
|
<!-- Help modal -->
|
|
167
154
|
<div class="modal-overlay" id="helpModal" onclick="if(event.target===this)toggleHelpModal()">
|
|
168
155
|
<div class="modal">
|
|
169
156
|
<div class="modal-header">
|
|
170
|
-
<h3>Memory
|
|
157
|
+
<h3>Memory Diagnoser</h3>
|
|
171
158
|
<button class="modal-close" onclick="toggleHelpModal()">✕</button>
|
|
172
159
|
</div>
|
|
173
160
|
<div class="modal-body">
|
package/public/style.css
CHANGED
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
--font-mono: 'IBM Plex Mono', monospace;
|
|
31
31
|
--font-serif: 'Playfair Display', serif;
|
|
32
32
|
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
33
|
+
/* elevation: shadow-1 for resting cards, shadow-2 for floating layers (popovers, modals, toasts) */
|
|
34
|
+
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.15);
|
|
35
|
+
--shadow-2: 0 8px 24px rgba(0, 0, 0, 0.35);
|
|
36
|
+
--shadow-inset: inset 0 1px 3px rgba(0, 0, 0, 0.35);
|
|
33
37
|
}
|
|
34
38
|
/* #endregion VARIABLES */
|
|
35
39
|
|
|
@@ -179,7 +183,7 @@ body {
|
|
|
179
183
|
background: var(--bg-elevated);
|
|
180
184
|
border: 1px solid var(--border);
|
|
181
185
|
border-radius: 8px;
|
|
182
|
-
box-shadow:
|
|
186
|
+
box-shadow: var(--shadow-2);
|
|
183
187
|
}
|
|
184
188
|
.theme-menu.open {
|
|
185
189
|
display: block;
|
|
@@ -241,6 +245,20 @@ body {
|
|
|
241
245
|
border-bottom: 1px solid var(--border);
|
|
242
246
|
padding: 4px 16px 6px;
|
|
243
247
|
flex-shrink: 0;
|
|
248
|
+
cursor: pointer;
|
|
249
|
+
}
|
|
250
|
+
.budget-bar:hover .budget-label {
|
|
251
|
+
color: var(--text-secondary);
|
|
252
|
+
}
|
|
253
|
+
body.fp-mode .budget-bar {
|
|
254
|
+
border-bottom-color: var(--accent);
|
|
255
|
+
}
|
|
256
|
+
/* Footprint highlight: fade everything that costs nothing, mark what loads */
|
|
257
|
+
body.fp-mode .tree-item:not(.fp-hit) {
|
|
258
|
+
opacity: 0.35;
|
|
259
|
+
}
|
|
260
|
+
body.fp-mode .tree-item.fp-hit {
|
|
261
|
+
box-shadow: inset 2px 0 0 var(--accent);
|
|
244
262
|
}
|
|
245
263
|
.budget-label {
|
|
246
264
|
display: flex;
|
|
@@ -256,6 +274,7 @@ body {
|
|
|
256
274
|
background: var(--bg-elevated);
|
|
257
275
|
border-radius: 3px;
|
|
258
276
|
overflow: hidden;
|
|
277
|
+
box-shadow: var(--shadow-inset);
|
|
259
278
|
}
|
|
260
279
|
.budget-segments {
|
|
261
280
|
display: flex;
|
|
@@ -263,8 +282,17 @@ body {
|
|
|
263
282
|
}
|
|
264
283
|
.budget-segment {
|
|
265
284
|
height: 100%;
|
|
266
|
-
transition:
|
|
285
|
+
transition:
|
|
286
|
+
width 0.3s,
|
|
287
|
+
opacity 0.15s;
|
|
267
288
|
position: relative;
|
|
289
|
+
cursor: pointer;
|
|
290
|
+
}
|
|
291
|
+
.budget-segment:hover {
|
|
292
|
+
filter: brightness(1.2);
|
|
293
|
+
}
|
|
294
|
+
.budget-segment.seg-dim {
|
|
295
|
+
opacity: 0.3;
|
|
268
296
|
}
|
|
269
297
|
.budget-segment:first-child {
|
|
270
298
|
border-radius: 3px 0 0 3px;
|
|
@@ -324,16 +352,28 @@ body {
|
|
|
324
352
|
/* #endregion MAIN_LAYOUT */
|
|
325
353
|
|
|
326
354
|
/* #region TREE */
|
|
355
|
+
/* filled sticky section bars — same depth language as the marketplace tree headers */
|
|
327
356
|
.tree-group-header {
|
|
328
|
-
padding:
|
|
357
|
+
padding: 7px 12px;
|
|
329
358
|
font-size: 10px;
|
|
330
359
|
font-weight: 600;
|
|
331
360
|
text-transform: uppercase;
|
|
332
361
|
letter-spacing: 0.5px;
|
|
333
|
-
color: var(--text-
|
|
362
|
+
color: var(--text-tertiary);
|
|
334
363
|
display: flex;
|
|
335
364
|
align-items: center;
|
|
336
365
|
gap: 6px;
|
|
366
|
+
background: var(--bg-elevated);
|
|
367
|
+
border-top: 1px solid var(--border);
|
|
368
|
+
border-bottom: 1px solid var(--border);
|
|
369
|
+
position: sticky;
|
|
370
|
+
top: 0;
|
|
371
|
+
z-index: 2;
|
|
372
|
+
margin-top: -1px;
|
|
373
|
+
}
|
|
374
|
+
.tree-content > .tree-group-header:first-child {
|
|
375
|
+
border-top: none;
|
|
376
|
+
margin-top: 0;
|
|
337
377
|
}
|
|
338
378
|
.tree-subgroup-header {
|
|
339
379
|
padding: 6px 12px 2px 20px;
|
|
@@ -759,6 +799,7 @@ body.light .tree-conditional .file-name {
|
|
|
759
799
|
background: var(--bg-surface);
|
|
760
800
|
border: 1px solid var(--border);
|
|
761
801
|
border-radius: 8px;
|
|
802
|
+
box-shadow: var(--shadow-2);
|
|
762
803
|
width: 440px;
|
|
763
804
|
max-width: 90vw;
|
|
764
805
|
max-height: 80vh;
|
|
@@ -767,16 +808,6 @@ body.light .tree-conditional .file-name {
|
|
|
767
808
|
.modal.modal-wide {
|
|
768
809
|
width: 1140px;
|
|
769
810
|
}
|
|
770
|
-
/* the analysis box loses its standalone framing inside the modal; the modal header carries the title */
|
|
771
|
-
#analysisModal .analysis-box {
|
|
772
|
-
margin: 0;
|
|
773
|
-
border: none;
|
|
774
|
-
padding: 0;
|
|
775
|
-
background: transparent;
|
|
776
|
-
}
|
|
777
|
-
#analysisModal .analysis-title {
|
|
778
|
-
display: none;
|
|
779
|
-
}
|
|
780
811
|
.modal-header {
|
|
781
812
|
display: flex;
|
|
782
813
|
align-items: center;
|
|
@@ -910,6 +941,7 @@ body.light .tree-conditional .file-name {
|
|
|
910
941
|
padding: 6px 8px;
|
|
911
942
|
margin: 8px 0 12px;
|
|
912
943
|
word-break: break-all;
|
|
944
|
+
box-shadow: var(--shadow-inset);
|
|
913
945
|
}
|
|
914
946
|
.preview-actions {
|
|
915
947
|
margin-left: auto;
|
|
@@ -1031,6 +1063,7 @@ kbd {
|
|
|
1031
1063
|
background: var(--bg-elevated);
|
|
1032
1064
|
border: 1px solid var(--border);
|
|
1033
1065
|
border-radius: 6px;
|
|
1066
|
+
box-shadow: var(--shadow-2);
|
|
1034
1067
|
padding: 8px 14px;
|
|
1035
1068
|
font-size: 12px;
|
|
1036
1069
|
color: var(--text-secondary);
|
|
@@ -1073,6 +1106,9 @@ body.light {
|
|
|
1073
1106
|
--accent-dim: rgba(232, 111, 51, 0.18);
|
|
1074
1107
|
--accent-glow: rgba(232, 111, 51, 0.5);
|
|
1075
1108
|
--success: #1a8a5a;
|
|
1109
|
+
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.05);
|
|
1110
|
+
--shadow-2: 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
1111
|
+
--shadow-inset: inset 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
1076
1112
|
}
|
|
1077
1113
|
/* #endregion LIGHT_THEME */
|
|
1078
1114
|
|
|
@@ -1109,6 +1145,7 @@ body.light {
|
|
|
1109
1145
|
background: var(--bg-surface);
|
|
1110
1146
|
padding: 12px 14px;
|
|
1111
1147
|
font-family: var(--font-mono);
|
|
1148
|
+
box-shadow: var(--shadow-1);
|
|
1112
1149
|
}
|
|
1113
1150
|
.analysis-head {
|
|
1114
1151
|
display: flex;
|
|
@@ -1146,6 +1183,10 @@ body.light {
|
|
|
1146
1183
|
.analysis-status-error {
|
|
1147
1184
|
color: var(--error);
|
|
1148
1185
|
}
|
|
1186
|
+
.analysis-stalled {
|
|
1187
|
+
color: var(--text-muted);
|
|
1188
|
+
font-style: italic;
|
|
1189
|
+
}
|
|
1149
1190
|
.analysis-spinner {
|
|
1150
1191
|
width: 12px;
|
|
1151
1192
|
height: 12px;
|
|
@@ -1159,16 +1200,20 @@ body.light {
|
|
|
1159
1200
|
margin-top: 10px;
|
|
1160
1201
|
padding: 10px 12px;
|
|
1161
1202
|
border: 1px solid var(--border);
|
|
1162
|
-
border-left-width: 3px;
|
|
1163
1203
|
border-radius: 6px;
|
|
1164
1204
|
background: var(--bg-elevated);
|
|
1205
|
+
box-shadow: var(--shadow-1);
|
|
1165
1206
|
overflow: hidden;
|
|
1166
1207
|
transition:
|
|
1167
1208
|
opacity 0.25s,
|
|
1168
1209
|
transform 0.25s,
|
|
1169
1210
|
max-height 0.3s,
|
|
1170
1211
|
margin 0.3s,
|
|
1171
|
-
padding 0.3s
|
|
1212
|
+
padding 0.3s,
|
|
1213
|
+
border-color 0.15s;
|
|
1214
|
+
}
|
|
1215
|
+
.analysis-card:hover {
|
|
1216
|
+
border-color: var(--accent-dim);
|
|
1172
1217
|
}
|
|
1173
1218
|
.analysis-card.leaving {
|
|
1174
1219
|
opacity: 0;
|
|
@@ -1179,14 +1224,20 @@ body.light {
|
|
|
1179
1224
|
padding-bottom: 0;
|
|
1180
1225
|
border-width: 0;
|
|
1181
1226
|
}
|
|
1182
|
-
|
|
1183
|
-
|
|
1227
|
+
/* severity marker: same dot language as the filter pills and dashboard tiles */
|
|
1228
|
+
.analysis-card-head::before {
|
|
1229
|
+
content: '';
|
|
1230
|
+
width: 8px;
|
|
1231
|
+
height: 8px;
|
|
1232
|
+
border-radius: 50%;
|
|
1233
|
+
flex-shrink: 0;
|
|
1234
|
+
background: var(--text-tertiary);
|
|
1184
1235
|
}
|
|
1185
|
-
.analysis-card.sev-
|
|
1186
|
-
|
|
1236
|
+
.analysis-card.sev-high .analysis-card-head::before {
|
|
1237
|
+
background: var(--error);
|
|
1187
1238
|
}
|
|
1188
|
-
.analysis-card.sev-
|
|
1189
|
-
|
|
1239
|
+
.analysis-card.sev-med .analysis-card-head::before {
|
|
1240
|
+
background: var(--warning);
|
|
1190
1241
|
}
|
|
1191
1242
|
.analysis-card-head {
|
|
1192
1243
|
display: flex;
|
|
@@ -1370,7 +1421,7 @@ a.file-chip:hover {
|
|
|
1370
1421
|
border: 1px solid var(--border);
|
|
1371
1422
|
color: var(--text-tertiary);
|
|
1372
1423
|
cursor: pointer;
|
|
1373
|
-
background:
|
|
1424
|
+
background: var(--bg-elevated);
|
|
1374
1425
|
user-select: none;
|
|
1375
1426
|
}
|
|
1376
1427
|
.run-chip:hover {
|
|
@@ -1395,6 +1446,15 @@ a.file-chip:hover {
|
|
|
1395
1446
|
color: var(--accent-text);
|
|
1396
1447
|
background: var(--accent-dim);
|
|
1397
1448
|
}
|
|
1449
|
+
/* user-scope runs are shared across projects — tint the chip to set them apart */
|
|
1450
|
+
.run-chip-user {
|
|
1451
|
+
border-color: rgba(192, 128, 80, 0.45);
|
|
1452
|
+
}
|
|
1453
|
+
.run-chip-user.active {
|
|
1454
|
+
border-color: var(--scope-user);
|
|
1455
|
+
color: var(--scope-user);
|
|
1456
|
+
background: rgba(192, 128, 80, 0.12);
|
|
1457
|
+
}
|
|
1398
1458
|
.sev-strip {
|
|
1399
1459
|
display: flex;
|
|
1400
1460
|
gap: 8px;
|
|
@@ -1410,7 +1470,7 @@ a.file-chip:hover {
|
|
|
1410
1470
|
border: 1px solid var(--border);
|
|
1411
1471
|
color: var(--text-tertiary);
|
|
1412
1472
|
cursor: pointer;
|
|
1413
|
-
background:
|
|
1473
|
+
background: var(--bg-elevated);
|
|
1414
1474
|
display: inline-flex;
|
|
1415
1475
|
align-items: center;
|
|
1416
1476
|
gap: 6px;
|
|
@@ -1458,6 +1518,7 @@ a.file-chip:hover {
|
|
|
1458
1518
|
border-radius: 8px;
|
|
1459
1519
|
padding: 12px 14px;
|
|
1460
1520
|
margin-top: 10px;
|
|
1521
|
+
box-shadow: var(--shadow-1);
|
|
1461
1522
|
}
|
|
1462
1523
|
.scope-panel-title {
|
|
1463
1524
|
font-size: 11px;
|
|
@@ -1513,6 +1574,14 @@ a.file-chip:hover {
|
|
|
1513
1574
|
background: rgba(122, 181, 160, 0.18);
|
|
1514
1575
|
color: var(--scope-project);
|
|
1515
1576
|
}
|
|
1577
|
+
.scope-tag.t-user {
|
|
1578
|
+
background: rgba(192, 128, 80, 0.18);
|
|
1579
|
+
color: var(--scope-user);
|
|
1580
|
+
}
|
|
1581
|
+
.scope-tag.t-cross {
|
|
1582
|
+
background: rgba(155, 130, 190, 0.18);
|
|
1583
|
+
color: var(--scope-rule);
|
|
1584
|
+
}
|
|
1516
1585
|
.scope-meta {
|
|
1517
1586
|
color: var(--text-muted);
|
|
1518
1587
|
font-size: 10px;
|
|
@@ -1582,3 +1651,339 @@ a.file-chip:hover {
|
|
|
1582
1651
|
color: var(--accent);
|
|
1583
1652
|
}
|
|
1584
1653
|
/* #endregion ANALYZER */
|
|
1654
|
+
|
|
1655
|
+
/* #region HEALTH */
|
|
1656
|
+
.topbar-btn.active {
|
|
1657
|
+
border-color: var(--accent);
|
|
1658
|
+
color: var(--accent-text);
|
|
1659
|
+
background: var(--accent-dim);
|
|
1660
|
+
}
|
|
1661
|
+
.health-view {
|
|
1662
|
+
padding: 4px 0 24px;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
/* tree annotations — counts from the latest run */
|
|
1666
|
+
.tree-health {
|
|
1667
|
+
flex-shrink: 0;
|
|
1668
|
+
font-size: 10px;
|
|
1669
|
+
font-weight: 600;
|
|
1670
|
+
font-family: var(--font-mono);
|
|
1671
|
+
line-height: 1;
|
|
1672
|
+
min-width: 16px;
|
|
1673
|
+
padding: 2px 5px;
|
|
1674
|
+
border-radius: 9px;
|
|
1675
|
+
text-align: center;
|
|
1676
|
+
}
|
|
1677
|
+
.tree-health.th-high {
|
|
1678
|
+
background: var(--error-dim);
|
|
1679
|
+
color: var(--error);
|
|
1680
|
+
}
|
|
1681
|
+
.tree-health.th-med {
|
|
1682
|
+
background: var(--warning-dim);
|
|
1683
|
+
color: var(--warning);
|
|
1684
|
+
}
|
|
1685
|
+
.tree-health.th-low {
|
|
1686
|
+
background: var(--bg-hover);
|
|
1687
|
+
color: var(--text-tertiary);
|
|
1688
|
+
}
|
|
1689
|
+
.tree-health.th-clean {
|
|
1690
|
+
min-width: 0;
|
|
1691
|
+
width: 7px;
|
|
1692
|
+
height: 7px;
|
|
1693
|
+
padding: 0;
|
|
1694
|
+
border-radius: 50%;
|
|
1695
|
+
border: 1px solid var(--success);
|
|
1696
|
+
opacity: 0.7;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
/* dashboard tiles */
|
|
1700
|
+
.hv-tiles {
|
|
1701
|
+
display: grid;
|
|
1702
|
+
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
1703
|
+
gap: 10px;
|
|
1704
|
+
margin-top: 14px;
|
|
1705
|
+
}
|
|
1706
|
+
.hv-tile {
|
|
1707
|
+
border: 1px solid var(--border);
|
|
1708
|
+
border-radius: 8px;
|
|
1709
|
+
background: var(--bg-elevated);
|
|
1710
|
+
box-shadow: var(--shadow-1);
|
|
1711
|
+
padding: 12px 14px;
|
|
1712
|
+
display: flex;
|
|
1713
|
+
flex-direction: column;
|
|
1714
|
+
gap: 6px;
|
|
1715
|
+
min-width: 0;
|
|
1716
|
+
}
|
|
1717
|
+
.hv-tile.hv-ring-tile {
|
|
1718
|
+
flex-direction: row;
|
|
1719
|
+
align-items: center;
|
|
1720
|
+
gap: 12px;
|
|
1721
|
+
}
|
|
1722
|
+
.hv-ring {
|
|
1723
|
+
position: relative;
|
|
1724
|
+
width: 68px;
|
|
1725
|
+
height: 68px;
|
|
1726
|
+
flex-shrink: 0;
|
|
1727
|
+
}
|
|
1728
|
+
.hv-ring svg {
|
|
1729
|
+
width: 100%;
|
|
1730
|
+
height: 100%;
|
|
1731
|
+
}
|
|
1732
|
+
.hv-ring-val {
|
|
1733
|
+
position: absolute;
|
|
1734
|
+
inset: 0;
|
|
1735
|
+
display: flex;
|
|
1736
|
+
align-items: center;
|
|
1737
|
+
justify-content: center;
|
|
1738
|
+
font-size: 19px;
|
|
1739
|
+
font-weight: 600;
|
|
1740
|
+
font-family: var(--font-mono);
|
|
1741
|
+
}
|
|
1742
|
+
.hv-tile-txt {
|
|
1743
|
+
display: flex;
|
|
1744
|
+
flex-direction: column;
|
|
1745
|
+
gap: 4px;
|
|
1746
|
+
min-width: 0;
|
|
1747
|
+
}
|
|
1748
|
+
.hv-lbl {
|
|
1749
|
+
display: flex;
|
|
1750
|
+
align-items: center;
|
|
1751
|
+
gap: 6px;
|
|
1752
|
+
font-size: 11px;
|
|
1753
|
+
text-transform: uppercase;
|
|
1754
|
+
letter-spacing: 0.7px;
|
|
1755
|
+
color: var(--text-tertiary);
|
|
1756
|
+
}
|
|
1757
|
+
.hv-lbl .dot {
|
|
1758
|
+
width: 8px;
|
|
1759
|
+
height: 8px;
|
|
1760
|
+
border-radius: 50%;
|
|
1761
|
+
flex-shrink: 0;
|
|
1762
|
+
}
|
|
1763
|
+
.dot.sev-dot-high {
|
|
1764
|
+
background: var(--error);
|
|
1765
|
+
}
|
|
1766
|
+
.dot.sev-dot-med {
|
|
1767
|
+
background: var(--warning);
|
|
1768
|
+
}
|
|
1769
|
+
.dot.sev-dot-low {
|
|
1770
|
+
background: var(--text-muted);
|
|
1771
|
+
}
|
|
1772
|
+
.hv-sub {
|
|
1773
|
+
font-size: 11px;
|
|
1774
|
+
color: var(--text-tertiary);
|
|
1775
|
+
white-space: nowrap;
|
|
1776
|
+
overflow: hidden;
|
|
1777
|
+
text-overflow: ellipsis;
|
|
1778
|
+
}
|
|
1779
|
+
.hv-num {
|
|
1780
|
+
font-size: 26px;
|
|
1781
|
+
font-weight: 600;
|
|
1782
|
+
font-family: var(--font-mono);
|
|
1783
|
+
color: var(--text-primary);
|
|
1784
|
+
line-height: 1.1;
|
|
1785
|
+
}
|
|
1786
|
+
.hv-num i {
|
|
1787
|
+
font-style: normal;
|
|
1788
|
+
font-size: 13px;
|
|
1789
|
+
color: var(--text-tertiary);
|
|
1790
|
+
}
|
|
1791
|
+
.hv-num-high {
|
|
1792
|
+
color: var(--error);
|
|
1793
|
+
}
|
|
1794
|
+
.hv-num-med {
|
|
1795
|
+
color: var(--warning);
|
|
1796
|
+
}
|
|
1797
|
+
.hv-num-low {
|
|
1798
|
+
color: var(--text-tertiary);
|
|
1799
|
+
}
|
|
1800
|
+
.hv-num-clean {
|
|
1801
|
+
color: var(--success);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/* run trend — stacked mini-columns, oldest → newest */
|
|
1805
|
+
.hv-trend-tile {
|
|
1806
|
+
min-width: 120px;
|
|
1807
|
+
}
|
|
1808
|
+
.hv-trend {
|
|
1809
|
+
display: flex;
|
|
1810
|
+
align-items: flex-end;
|
|
1811
|
+
gap: 5px;
|
|
1812
|
+
height: 44px;
|
|
1813
|
+
margin-top: auto;
|
|
1814
|
+
}
|
|
1815
|
+
.hv-trun {
|
|
1816
|
+
display: flex;
|
|
1817
|
+
flex-direction: column-reverse;
|
|
1818
|
+
width: 16px;
|
|
1819
|
+
cursor: pointer;
|
|
1820
|
+
border-radius: 3px 3px 0 0;
|
|
1821
|
+
overflow: hidden;
|
|
1822
|
+
opacity: 0.75;
|
|
1823
|
+
}
|
|
1824
|
+
.hv-trun:hover,
|
|
1825
|
+
.hv-trun.cur {
|
|
1826
|
+
opacity: 1;
|
|
1827
|
+
}
|
|
1828
|
+
.hv-trun.cur {
|
|
1829
|
+
outline: 1px solid var(--accent);
|
|
1830
|
+
outline-offset: 1px;
|
|
1831
|
+
}
|
|
1832
|
+
.hv-trun i {
|
|
1833
|
+
display: block;
|
|
1834
|
+
}
|
|
1835
|
+
.hv-trun .th {
|
|
1836
|
+
background: var(--error);
|
|
1837
|
+
}
|
|
1838
|
+
.hv-trun .tm {
|
|
1839
|
+
background: var(--warning);
|
|
1840
|
+
}
|
|
1841
|
+
.hv-trun .tl {
|
|
1842
|
+
background: var(--text-muted);
|
|
1843
|
+
}
|
|
1844
|
+
.hv-trun .tz {
|
|
1845
|
+
height: 3px;
|
|
1846
|
+
background: var(--success);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
/* memory map — audited files sized by lines, colored by worst finding */
|
|
1850
|
+
/* filled section bar — mirrors the marketplace detail-panel component headers */
|
|
1851
|
+
.hv-map-label {
|
|
1852
|
+
margin-top: 18px;
|
|
1853
|
+
display: flex;
|
|
1854
|
+
align-items: center;
|
|
1855
|
+
gap: 10px;
|
|
1856
|
+
font-size: 11px;
|
|
1857
|
+
text-transform: uppercase;
|
|
1858
|
+
letter-spacing: 0.7px;
|
|
1859
|
+
color: var(--text-tertiary);
|
|
1860
|
+
background: var(--bg-surface);
|
|
1861
|
+
border: 1px solid var(--border);
|
|
1862
|
+
border-radius: 6px;
|
|
1863
|
+
padding: 6px 10px;
|
|
1864
|
+
}
|
|
1865
|
+
.hv-map {
|
|
1866
|
+
display: grid;
|
|
1867
|
+
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
1868
|
+
gap: 6px;
|
|
1869
|
+
margin-top: 10px;
|
|
1870
|
+
}
|
|
1871
|
+
.hv-cell {
|
|
1872
|
+
position: relative;
|
|
1873
|
+
min-height: 56px;
|
|
1874
|
+
border-radius: 6px;
|
|
1875
|
+
border: 1px solid var(--border);
|
|
1876
|
+
box-shadow: var(--shadow-1);
|
|
1877
|
+
padding: 8px 30px 8px 10px;
|
|
1878
|
+
cursor: pointer;
|
|
1879
|
+
display: flex;
|
|
1880
|
+
flex-direction: column;
|
|
1881
|
+
justify-content: space-between;
|
|
1882
|
+
gap: 4px;
|
|
1883
|
+
min-width: 0;
|
|
1884
|
+
overflow: hidden;
|
|
1885
|
+
transition: filter 0.15s;
|
|
1886
|
+
}
|
|
1887
|
+
.hv-cell:hover {
|
|
1888
|
+
filter: brightness(1.25);
|
|
1889
|
+
}
|
|
1890
|
+
.hv-cell.active {
|
|
1891
|
+
outline: 1px solid var(--accent);
|
|
1892
|
+
outline-offset: 1px;
|
|
1893
|
+
}
|
|
1894
|
+
.hv-cell.hv-clean {
|
|
1895
|
+
background: var(--bg-elevated);
|
|
1896
|
+
}
|
|
1897
|
+
.hv-cell.hv-low {
|
|
1898
|
+
background: var(--bg-hover);
|
|
1899
|
+
}
|
|
1900
|
+
.hv-cell.hv-med {
|
|
1901
|
+
background: var(--warning-dim);
|
|
1902
|
+
border-color: var(--warning);
|
|
1903
|
+
}
|
|
1904
|
+
.hv-cell.hv-high {
|
|
1905
|
+
background: var(--error-dim);
|
|
1906
|
+
border-color: var(--error);
|
|
1907
|
+
}
|
|
1908
|
+
.hv-cell-name {
|
|
1909
|
+
font-size: 12px;
|
|
1910
|
+
color: var(--text-primary);
|
|
1911
|
+
white-space: nowrap;
|
|
1912
|
+
overflow: hidden;
|
|
1913
|
+
text-overflow: ellipsis;
|
|
1914
|
+
}
|
|
1915
|
+
.hv-cell-meta {
|
|
1916
|
+
font-size: 10px;
|
|
1917
|
+
font-family: var(--font-mono);
|
|
1918
|
+
color: var(--text-tertiary);
|
|
1919
|
+
}
|
|
1920
|
+
.hv-cell-n {
|
|
1921
|
+
position: absolute;
|
|
1922
|
+
top: 6px;
|
|
1923
|
+
right: 6px;
|
|
1924
|
+
font-size: 10px;
|
|
1925
|
+
font-weight: 600;
|
|
1926
|
+
font-family: var(--font-mono);
|
|
1927
|
+
min-width: 16px;
|
|
1928
|
+
text-align: center;
|
|
1929
|
+
padding: 2px 4px;
|
|
1930
|
+
border-radius: 8px;
|
|
1931
|
+
background: var(--bg-deep);
|
|
1932
|
+
}
|
|
1933
|
+
.hv-cn-high {
|
|
1934
|
+
color: var(--error);
|
|
1935
|
+
}
|
|
1936
|
+
.hv-cn-med {
|
|
1937
|
+
color: var(--warning);
|
|
1938
|
+
}
|
|
1939
|
+
.hv-cn-low {
|
|
1940
|
+
color: var(--text-tertiary);
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
/* per-file findings inside the file preview — compact rows, click to expand */
|
|
1944
|
+
.preview-findings {
|
|
1945
|
+
margin: 12px 16px 0;
|
|
1946
|
+
max-width: 50%;
|
|
1947
|
+
min-width: 420px;
|
|
1948
|
+
}
|
|
1949
|
+
.pf-card {
|
|
1950
|
+
margin-top: 6px;
|
|
1951
|
+
padding: 6px 10px;
|
|
1952
|
+
}
|
|
1953
|
+
.pf-card .analysis-card-head {
|
|
1954
|
+
cursor: pointer;
|
|
1955
|
+
}
|
|
1956
|
+
.pf-card:not(.expanded) .analysis-card-detail,
|
|
1957
|
+
.pf-card:not(.expanded) .analysis-card-suggestion {
|
|
1958
|
+
display: none;
|
|
1959
|
+
}
|
|
1960
|
+
.pf-label {
|
|
1961
|
+
display: flex;
|
|
1962
|
+
align-items: center;
|
|
1963
|
+
gap: 10px;
|
|
1964
|
+
font-size: 11px;
|
|
1965
|
+
text-transform: uppercase;
|
|
1966
|
+
letter-spacing: 0.7px;
|
|
1967
|
+
color: var(--text-tertiary);
|
|
1968
|
+
font-family: var(--font-mono);
|
|
1969
|
+
background: var(--bg-surface);
|
|
1970
|
+
border: 1px solid var(--border);
|
|
1971
|
+
border-radius: 6px;
|
|
1972
|
+
padding: 6px 10px;
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
/* fix queue */
|
|
1976
|
+
.fix-check {
|
|
1977
|
+
accent-color: var(--accent);
|
|
1978
|
+
width: 13px;
|
|
1979
|
+
height: 13px;
|
|
1980
|
+
flex-shrink: 0;
|
|
1981
|
+
cursor: pointer;
|
|
1982
|
+
margin: 0;
|
|
1983
|
+
}
|
|
1984
|
+
.fix-plan-btn {
|
|
1985
|
+
border-color: var(--accent);
|
|
1986
|
+
color: var(--accent-text);
|
|
1987
|
+
background: var(--accent-dim);
|
|
1988
|
+
}
|
|
1989
|
+
/* #endregion HEALTH */
|