codesynapt 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +686 -0
  3. package/LICENSES.md +141 -0
  4. package/README.md +331 -0
  5. package/electron/main.cjs +2849 -0
  6. package/electron/plugin-loader.cjs +184 -0
  7. package/electron/preload.cjs +108 -0
  8. package/package.json +216 -0
  9. package/packages/core/bin/codesynapt-mcp.cjs +611 -0
  10. package/packages/core/bin/codesynapt.cjs +1933 -0
  11. package/packages/core/legacy.js +300 -0
  12. package/packages/core/lib/control-server.cjs +1539 -0
  13. package/packages/core/lib/embedding.cjs +89 -0
  14. package/packages/core/lib/logger.cjs +63 -0
  15. package/packages/core/lib/search-cache.cjs +140 -0
  16. package/packages/core/lib/search-worker.cjs +255 -0
  17. package/packages/core/lib/search.cjs +211 -0
  18. package/packages/core/lib/symbol-graph.cjs +402 -0
  19. package/packages/core/lib/symbol-parser-js.cjs +542 -0
  20. package/packages/core/lib/symbol-parser-misc.cjs +394 -0
  21. package/packages/core/lib/symbol-parser-py.cjs +215 -0
  22. package/packages/core/lib/symbol-parser-treesitter.cjs +658 -0
  23. package/packages/core/lib/symbol-parser-tsc.cjs +332 -0
  24. package/packages/core/monorepo.js +310 -0
  25. package/packages/core/parser.js +2234 -0
  26. package/packages/core/scanner.js +623 -0
  27. package/plugin-api/LICENSE +21 -0
  28. package/plugin-api/README.md +114 -0
  29. package/plugin-api/docs/01-getting-started.md +197 -0
  30. package/plugin-api/docs/02-concepts.md +269 -0
  31. package/plugin-api/docs/api-reference.md +463 -0
  32. package/plugin-api/docs/troubleshooting.md +332 -0
  33. package/plugin-api/docs/types/exporter.md +377 -0
  34. package/plugin-api/docs/types/theme.md +312 -0
  35. package/plugin-api/examples/hello-world-plugin/README.md +70 -0
  36. package/plugin-api/examples/hello-world-plugin/main.js +36 -0
  37. package/plugin-api/examples/hello-world-plugin/manifest.json +12 -0
  38. package/plugin-api/examples/mermaid-exporter/README.md +125 -0
  39. package/plugin-api/examples/mermaid-exporter/main.js +58 -0
  40. package/plugin-api/examples/mermaid-exporter/manifest.json +12 -0
  41. package/plugin-api/examples/rust-parser/README.md +71 -0
  42. package/plugin-api/examples/rust-parser/main.js +123 -0
  43. package/plugin-api/examples/rust-parser/manifest.json +12 -0
  44. package/plugin-api/examples/sunset-theme/README.md +95 -0
  45. package/plugin-api/examples/sunset-theme/manifest.json +12 -0
  46. package/plugin-api/examples/sunset-theme/theme.css +31 -0
  47. package/plugin-api/package.json +20 -0
  48. package/plugin-api/types.d.ts +395 -0
  49. package/public/app.js +6837 -0
  50. package/public/backend.js +285 -0
  51. package/public/index.html +647 -0
  52. package/public/plugin-host.js +321 -0
  53. package/public/style.css +4359 -0
  54. package/public/vendor/three.module.js +53044 -0
  55. package/scripts/competitor-watch.mjs +144 -0
  56. package/scripts/copy-vendor.js +21 -0
  57. package/scripts/download-bundled-node.cjs +53 -0
  58. package/scripts/fuses-after-pack.cjs +34 -0
  59. package/scripts/license-check.js +119 -0
  60. package/scripts/perf-test.js +200 -0
  61. package/server.js +132 -0
@@ -0,0 +1,4359 @@
1
+ /* ═══════════════════════════════════════════════════════
2
+ Theme system — 4 themes selectable at runtime.
3
+ Default is "observatory". Toggle via body[data-theme].
4
+
5
+ Each theme controls:
6
+ - Color palette (bg, fg, accents)
7
+ - --decoration: 1 if corner brackets shown, 0 if hidden
8
+ - --grain: noise overlay opacity
9
+ - --motion-scale: 0..1 multiplier for ambient animations
10
+ ═══════════════════════════════════════════════════════ */
11
+
12
+ /* ─── Theme: Observatory (default) ─────────────────────
13
+ Brutalist + astronomical. Corner brackets, pulsing
14
+ accents, constellation in welcome screen. */
15
+ :root,
16
+ body[data-theme="observatory"] {
17
+ --bg: #03050C;
18
+ --bg-deep: #01030A;
19
+ --bg-elev: rgba(12, 16, 26, 0.78);
20
+ --bg-glass: rgba(7, 9, 15, 0.82);
21
+ --bg-solid: #0A0E18;
22
+
23
+ --border: rgba(126, 207, 207, 0.16);
24
+ --border-hot: rgba(126, 207, 207, 0.55);
25
+ --border-edge: rgba(126, 207, 207, 0.06);
26
+
27
+ --fg: #E2E8F0;
28
+ --fg-dim: #94A3B8;
29
+ --fg-mute: #64748B;
30
+ --fg-faint: #475569;
31
+
32
+ --accent: #7ECFCF;
33
+ --accent-warm: #FFC850;
34
+ --accent-pink: #E879A6;
35
+ --accent-cool: #8B9DEB;
36
+ --danger: #F87171;
37
+
38
+ --decoration: 1; /* corner brackets visible */
39
+ --grain: 0.025; /* subtle overlay */
40
+ --motion-scale: 1;
41
+
42
+ --font-mono: 'JetBrains Mono', 'IBM Plex Mono', 'SF Mono', ui-monospace,
43
+ Menlo, Consolas, 'Liberation Mono', monospace;
44
+ --font-display: 'JetBrains Mono', ui-monospace, monospace;
45
+
46
+ --space-1: 4px;
47
+ --space-2: 8px;
48
+ --space-3: 12px;
49
+ --space-4: 16px;
50
+ --space-5: 24px;
51
+ --space-6: 32px;
52
+
53
+ --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
54
+ --ease-snap: cubic-bezier(0.85, 0, 0.15, 1);
55
+
56
+ --radius: 0; /* sharp corners */
57
+ }
58
+
59
+ /* ─── Theme: Minimal (Obsidian-inspired) ──────────────
60
+ Soft, quiet, graph-first. UI nearly invisible. */
61
+ body[data-theme="minimal"] {
62
+ --bg: #1A1B1E;
63
+ --bg-deep: #131418;
64
+ --bg-elev: rgba(30, 32, 38, 0.92);
65
+ --bg-glass: rgba(26, 28, 33, 0.88);
66
+ --bg-solid: #20232A;
67
+
68
+ --border: rgba(255, 255, 255, 0.08);
69
+ --border-hot: rgba(255, 255, 255, 0.22);
70
+ --border-edge: rgba(255, 255, 255, 0.04);
71
+
72
+ --fg: #E8E8E8;
73
+ --fg-dim: #B0B0B0;
74
+ --fg-mute: #707070;
75
+ --fg-faint: #505050;
76
+
77
+ --accent: #8FB8E0; /* soft sky blue — Obsidian-ish */
78
+ --accent-warm: #E0B870; /* muted gold */
79
+ --accent-pink: #C088B0; /* muted rose */
80
+ --accent-cool: #A0A8C0;
81
+ --danger: #D67878;
82
+
83
+ --decoration: 0; /* no corner brackets */
84
+ --grain: 0;
85
+ --motion-scale: 0.3; /* mostly static */
86
+
87
+ --font-mono: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
88
+ --font-display: -apple-system, 'Inter', 'Segoe UI', system-ui, sans-serif;
89
+
90
+ --radius: 6px; /* soft rounded corners */
91
+ }
92
+
93
+ /* ─── Theme: Terminal (Linear/VS Code-inspired) ───────
94
+ Monochrome, single accent, professional. */
95
+ body[data-theme="terminal"] {
96
+ --bg: #0A0A0A;
97
+ --bg-deep: #050505;
98
+ --bg-elev: rgba(18, 18, 18, 0.92);
99
+ --bg-glass: rgba(12, 12, 12, 0.88);
100
+ --bg-solid: #161616;
101
+
102
+ --border: rgba(255, 255, 255, 0.1);
103
+ --border-hot: rgba(255, 255, 255, 0.3);
104
+ --border-edge: rgba(255, 255, 255, 0.05);
105
+
106
+ --fg: #F5F5F5;
107
+ --fg-dim: #A8A8A8;
108
+ --fg-mute: #707070;
109
+ --fg-faint: #4D4D4D;
110
+
111
+ --accent: #5B9DFF; /* Linear-style blue */
112
+ --accent-warm: #5B9DFF; /* same — single accent philosophy */
113
+ --accent-pink: #FF6464; /* danger only */
114
+ --accent-cool: #5B9DFF;
115
+ --danger: #FF6464;
116
+
117
+ --decoration: 0;
118
+ --grain: 0;
119
+ --motion-scale: 0.5;
120
+
121
+ --font-mono: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
122
+ --font-display: 'JetBrains Mono', ui-monospace, monospace;
123
+
124
+ --radius: 4px;
125
+ }
126
+
127
+ /* ─── Theme: Maximal (expressive) ─────────────────────
128
+ Bold colors, strong contrast, playful. */
129
+ body[data-theme="maximal"] {
130
+ --bg: #0F0518; /* deep purple-black */
131
+ --bg-deep: #080210;
132
+ --bg-elev: rgba(28, 12, 40, 0.85);
133
+ --bg-glass: rgba(20, 8, 32, 0.85);
134
+ --bg-solid: #1A0828;
135
+
136
+ --border: rgba(255, 100, 200, 0.22);
137
+ --border-hot: rgba(255, 100, 200, 0.7);
138
+ --border-edge: rgba(255, 100, 200, 0.08);
139
+
140
+ --fg: #FFEEFA;
141
+ --fg-dim: #D8B8D0;
142
+ --fg-mute: #A088A0;
143
+ --fg-faint: #604858;
144
+
145
+ --accent: #FF55BB; /* hot pink */
146
+ --accent-warm: #FFD700; /* electric gold */
147
+ --accent-pink: #FF4488;
148
+ --accent-cool: #66E5FF; /* cyan */
149
+ --danger: #FF3355;
150
+
151
+ --decoration: 1;
152
+ --grain: 0.04;
153
+ --motion-scale: 1.2; /* extra motion */
154
+
155
+ --font-mono: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
156
+ --font-display: 'JetBrains Mono', ui-monospace, monospace;
157
+
158
+ --radius: 0;
159
+ }
160
+
161
+ /* ─── Theme: Carbon (developer classic dark) ──────────
162
+ Pure black background, phosphor green like an old CRT
163
+ terminal. Vim / Dracula / classic-IDE vibes. */
164
+ body[data-theme="carbon"] {
165
+ --bg: #000000; /* true black */
166
+ --bg-deep: #000000;
167
+ --bg-elev: rgba(10, 10, 10, 0.92);
168
+ --bg-glass: rgba(6, 6, 6, 0.88);
169
+ --bg-solid: #0C0C0C;
170
+
171
+ --border: rgba(80, 220, 100, 0.15);
172
+ --border-hot: rgba(80, 220, 100, 0.55);
173
+ --border-edge: rgba(80, 220, 100, 0.06);
174
+
175
+ --fg: #C8E6C9; /* slight green tint to off-white */
176
+ --fg-dim: #8FA88F;
177
+ --fg-mute: #5C7060;
178
+ --fg-faint: #3D4D40;
179
+
180
+ --accent: #50DC64; /* phosphor green */
181
+ --accent-warm: #FFD24D; /* amber for CRT contrast */
182
+ --accent-pink: #FF5577; /* error red */
183
+ --accent-cool: #5DC9D9; /* cyan secondary */
184
+ --danger: #FF4444;
185
+
186
+ --decoration: 0;
187
+ --grain: 0.015;
188
+ --motion-scale: 0.4;
189
+
190
+ --font-mono: 'JetBrains Mono', 'IBM Plex Mono', 'SF Mono', ui-monospace,
191
+ 'Cascadia Code', Menlo, Consolas, monospace;
192
+ --font-display: 'JetBrains Mono', ui-monospace, monospace;
193
+
194
+ --radius: 2px;
195
+ }
196
+
197
+ /* ─── Theme: Mono (warm developer dark) ──────────────
198
+ Tokyo Night / Gruvbox-inspired. Warm dark backgrounds,
199
+ muted amber accents. Easy on eyes for long sessions. */
200
+ body[data-theme="mono"] {
201
+ --bg: #1A1B26; /* Tokyo Night base */
202
+ --bg-deep: #15161E;
203
+ --bg-elev: rgba(36, 40, 59, 0.92);
204
+ --bg-glass: rgba(26, 27, 38, 0.88);
205
+ --bg-solid: #24283B;
206
+
207
+ --border: rgba(192, 202, 245, 0.12);
208
+ --border-hot: rgba(192, 202, 245, 0.35);
209
+ --border-edge: rgba(192, 202, 245, 0.05);
210
+
211
+ --fg: #C0CAF5; /* Tokyo Night fg */
212
+ --fg-dim: #9AA5CE;
213
+ --fg-mute: #565F89;
214
+ --fg-faint: #414868;
215
+
216
+ --accent: #7AA2F7; /* Tokyo Night blue */
217
+ --accent-warm: #E0AF68; /* Tokyo Night yellow */
218
+ --accent-pink: #F7768E; /* Tokyo Night red */
219
+ --accent-cool: #BB9AF7; /* Tokyo Night magenta */
220
+ --danger: #F7768E;
221
+
222
+ --decoration: 0;
223
+ --grain: 0;
224
+ --motion-scale: 0.4;
225
+
226
+ --font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', ui-monospace, Menlo, monospace;
227
+ --font-display: 'JetBrains Mono', ui-monospace, monospace;
228
+
229
+ --radius: 5px;
230
+ }
231
+
232
+ /* ─── Theme: Daylight (light mode) ────────────────────
233
+ Clean white background, ink-on-paper. GitHub Light /
234
+ Xcode-ish. For when the dark mode is too much. */
235
+ body[data-theme="daylight"] {
236
+ --bg: #FAFAFA;
237
+ --bg-deep: #FFFFFF;
238
+ --bg-elev: rgba(255, 255, 255, 0.92);
239
+ --bg-glass: rgba(250, 250, 250, 0.88);
240
+ --bg-solid: #F0F0F2;
241
+
242
+ --border: rgba(0, 0, 0, 0.08);
243
+ --border-hot: rgba(0, 0, 0, 0.28);
244
+ --border-edge: rgba(0, 0, 0, 0.04);
245
+
246
+ --fg: #1A1A1A;
247
+ --fg-dim: #4A4A4A;
248
+ --fg-mute: #888888;
249
+ --fg-faint: #BBBBBB;
250
+
251
+ --accent: #0969DA; /* GitHub blue */
252
+ --accent-warm: #BF8700; /* warm orange */
253
+ --accent-pink: #CF222E; /* red */
254
+ --accent-cool: #8250DF; /* purple */
255
+ --danger: #CF222E;
256
+
257
+ --decoration: 0;
258
+ --grain: 0;
259
+ --motion-scale: 0.4;
260
+
261
+ --font-mono: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
262
+ --font-display: 'JetBrains Mono', ui-monospace, monospace;
263
+
264
+ --radius: 6px;
265
+ }
266
+
267
+ * { box-sizing: border-box; margin: 0; padding: 0; }
268
+
269
+ html, body {
270
+ width: 100%; height: 100%;
271
+ background: var(--bg);
272
+ color: var(--fg);
273
+ font: 12.5px/1.55 var(--font-mono);
274
+ overflow: hidden;
275
+ -webkit-font-smoothing: antialiased;
276
+ -moz-osx-font-smoothing: grayscale;
277
+ user-select: none;
278
+ font-feature-settings: 'ss01', 'cv01', 'cv02'; /* JetBrains Mono ligatures off, alt forms on */
279
+ }
280
+
281
+ /* Subtle grain overlay — adds atmospheric texture without distraction */
282
+ body::before {
283
+ content: '';
284
+ position: fixed;
285
+ inset: 0;
286
+ pointer-events: none;
287
+ z-index: 100;
288
+ opacity: 0.025;
289
+ background-image:
290
+ repeating-conic-gradient(from 0deg at 50% 50%,
291
+ transparent 0deg, rgba(255,255,255,0.5) 0.3deg, transparent 0.6deg);
292
+ mix-blend-mode: overlay;
293
+ }
294
+
295
+ /* ─── Three-column grid layout ──────────────────────────────
296
+ Body is a CSS Grid: topbar row / main row (3 columns) / statusbar row.
297
+ The three main columns are: leftRail | canvas | rightRail.
298
+ Everything else (welcome, dialogs, toasts, settings, inspector,
299
+ searchbar, hints) stays position:fixed as overlays on top. */
300
+ :root {
301
+ --rail-w: 280px;
302
+ --topbar-h: 48px;
303
+ --statusbar-h: 24px;
304
+ --grid-gap: 12px;
305
+ --grid-pad: 12px;
306
+ }
307
+ @media (max-width: 1280px) { :root { --rail-w: 240px; } }
308
+ @media (max-width: 1024px) { :root { --rail-w: 220px; } }
309
+ @media (max-width: 800px) { :root { --rail-w: 200px; } }
310
+
311
+ html, body { height: 100%; }
312
+ body {
313
+ display: grid;
314
+ grid-template-columns: var(--rail-w) 1fr var(--rail-w);
315
+ grid-template-rows: var(--topbar-h) 1fr var(--statusbar-h);
316
+ grid-template-areas:
317
+ "top top top"
318
+ "lft can rgt"
319
+ "bot bot bot";
320
+ column-gap: var(--grid-gap);
321
+ padding: 0 var(--grid-pad) var(--grid-pad);
322
+ margin: 0;
323
+ overflow: hidden;
324
+ }
325
+ body.rail-collapsed { grid-template-columns: var(--rail-w) 1fr 0; column-gap: var(--grid-gap); }
326
+ body.left-rail-collapsed { grid-template-columns: 0 1fr var(--rail-w); }
327
+ body.no-folder { grid-template-columns: 0 1fr 0; column-gap: 0; padding: 0; }
328
+
329
+ #topbar { grid-area: top; }
330
+ #leftRail { grid-area: lft; }
331
+ #canvas { grid-area: can; width: 100%; height: 100%; min-width: 0; min-height: 0; display: block; }
332
+ #rightRail { grid-area: rgt; }
333
+ #statusBar { grid-area: bot; }
334
+
335
+ .node-label {
336
+ position: absolute;
337
+ color: #cfd6e0;
338
+ font: 11px ui-monospace, monospace;
339
+ pointer-events: none;
340
+ text-shadow: 0 1px 4px rgba(0,0,0,0.8), 0 0 8px rgba(0,0,0,0.6);
341
+ white-space: nowrap;
342
+ transform: translate(-50%, -150%);
343
+ opacity: 0;
344
+ transition: opacity 0.15s;
345
+ letter-spacing: 0.02em;
346
+ }
347
+
348
+ /* ─── Top bar — IDE-style toolbar with grouped controls ─── */
349
+ #topbar {
350
+ margin: 0 calc(var(--grid-pad) * -1); /* extend topbar full-width over grid padding */
351
+ padding: 0 12px;
352
+ display: flex; align-items: center; gap: 4px;
353
+ background:
354
+ linear-gradient(180deg, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.55) 100%);
355
+ backdrop-filter: blur(14px) saturate(140%);
356
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
357
+ border-bottom: 1px solid var(--border-edge);
358
+ z-index: 10;
359
+ }
360
+ /* Reserve space for macOS traffic light buttons */
361
+ body.is-mac #topbar { padding-left: 88px; }
362
+
363
+ /* Faint horizontal measurement line under topbar */
364
+ #topbar::after {
365
+ content: '';
366
+ position: absolute;
367
+ left: 0; right: 0; bottom: -1px;
368
+ height: 1px;
369
+ background: linear-gradient(90deg,
370
+ transparent 0%,
371
+ rgba(126,207,207,0.18) 25%,
372
+ rgba(126,207,207,0.05) 50%,
373
+ rgba(126,207,207,0.18) 75%,
374
+ transparent 100%);
375
+ }
376
+
377
+ /* Drag region for frameless macOS title bar */
378
+ .drag-region {
379
+ position: absolute; inset: 0;
380
+ -webkit-app-region: drag;
381
+ pointer-events: none;
382
+ }
383
+ #topbar > *:not(.drag-region) {
384
+ -webkit-app-region: no-drag;
385
+ position: relative;
386
+ z-index: 1;
387
+ }
388
+
389
+ /* Brand — distinct display treatment */
390
+ .brand {
391
+ display: flex; align-items: center; gap: 10px;
392
+ position: relative;
393
+ padding-right: var(--space-4);
394
+ }
395
+ .brand::after {
396
+ /* Vertical divider after brand */
397
+ content: '';
398
+ position: absolute;
399
+ right: 0; top: 50%;
400
+ transform: translateY(-50%);
401
+ width: 1px; height: 18px;
402
+ background: var(--border-edge);
403
+ }
404
+ .brand .dot {
405
+ width: 6px; height: 6px; border-radius: var(--radius); /* square — brutalist */
406
+ background: var(--accent);
407
+ box-shadow:
408
+ 0 0 0 1px var(--bg),
409
+ 0 0 12px var(--accent),
410
+ 0 0 20px rgba(126,207,207,0.3);
411
+ animation: brandPulse 3.2s var(--ease-out) infinite;
412
+ }
413
+ @keyframes brandPulse {
414
+ 0%, 100% { opacity: 1; transform: scale(1); }
415
+ 50% { opacity: 0.6; transform: scale(0.92); }
416
+ }
417
+ .brand .label {
418
+ font-family: var(--font-display);
419
+ font-size: 11px;
420
+ font-weight: 700;
421
+ text-transform: uppercase;
422
+ letter-spacing: 0.32em;
423
+ color: var(--fg);
424
+ position: relative;
425
+ }
426
+ .brand .label::before,
427
+ .brand .label::after {
428
+ /* Corner brackets around brand text */
429
+ font-weight: 400;
430
+ color: var(--accent);
431
+ opacity: 0.7;
432
+ letter-spacing: normal;
433
+ margin: 0 6px;
434
+ }
435
+ .brand .label::before { content: '['; }
436
+ .brand .label::after { content: ']'; }
437
+ .brand .accent {
438
+ color: var(--accent);
439
+ font-weight: 400;
440
+ opacity: 0.85;
441
+ }
442
+
443
+ .folder-btn {
444
+ display: flex; align-items: center; gap: 10px;
445
+ padding: 6px 12px 6px 10px;
446
+ background: transparent;
447
+ border: 1px solid var(--border);
448
+ border-radius: var(--radius);
449
+ color: var(--fg);
450
+ font: inherit;
451
+ font-size: 11.5px;
452
+ cursor: pointer;
453
+ max-width: 480px;
454
+ overflow: hidden;
455
+ transition: all 0.18s var(--ease-out);
456
+ position: relative;
457
+ }
458
+ .folder-btn::before {
459
+ /* Tiny corner mark — top-left */
460
+ content: '';
461
+ position: absolute;
462
+ top: -1px; left: -1px;
463
+ width: 4px; height: 4px;
464
+ border-top: 1px solid var(--accent);
465
+ border-left: 1px solid var(--accent);
466
+ opacity: 0;
467
+ transition: opacity 0.2s;
468
+ }
469
+ .folder-btn::after {
470
+ /* Tiny corner mark — bottom-right */
471
+ content: '';
472
+ position: absolute;
473
+ bottom: -1px; right: -1px;
474
+ width: 4px; height: 4px;
475
+ border-bottom: 1px solid var(--accent);
476
+ border-right: 1px solid var(--accent);
477
+ opacity: 0;
478
+ transition: opacity 0.2s;
479
+ }
480
+ .folder-btn:hover {
481
+ border-color: var(--border-hot);
482
+ background: rgba(126, 207, 207, 0.05);
483
+ color: var(--accent);
484
+ }
485
+ .folder-btn.active {
486
+ border-color: var(--border-hot);
487
+ background: rgba(126, 207, 207, 0.1);
488
+ color: var(--accent);
489
+ }
490
+ .folder-btn.active::before,
491
+ .folder-btn.active::after { opacity: 1; }
492
+ .folder-btn:hover::before,
493
+ .folder-btn:hover::after { opacity: 1; }
494
+ .folder-btn .icon {
495
+ flex-shrink: 0;
496
+ font-size: 11px;
497
+ color: var(--accent);
498
+ opacity: 0.85;
499
+ }
500
+ .folder-btn:disabled {
501
+ opacity: 0.4;
502
+ cursor: not-allowed;
503
+ }
504
+ .folder-btn:disabled:hover {
505
+ border-color: var(--border);
506
+ background: transparent;
507
+ color: var(--fg);
508
+ }
509
+ @keyframes refreshSpin {
510
+ from { transform: rotate(0deg); }
511
+ to { transform: rotate(360deg); }
512
+ }
513
+ #refreshBtn.spinning .icon {
514
+ display: inline-block;
515
+ animation: refreshSpin 0.8s linear infinite;
516
+ }
517
+ .folder-btn #pathLabel {
518
+ overflow: hidden;
519
+ text-overflow: ellipsis;
520
+ white-space: nowrap;
521
+ font-family: var(--font-mono);
522
+ font-size: 11px;
523
+ color: var(--fg-dim);
524
+ direction: rtl;
525
+ text-align: left;
526
+ letter-spacing: 0.02em;
527
+ }
528
+
529
+ .meta {
530
+ margin-left: auto;
531
+ display: flex; align-items: center; gap: var(--space-3);
532
+ font-family: var(--font-mono);
533
+ font-size: 10.5px;
534
+ color: var(--fg-mute);
535
+ letter-spacing: 0.04em;
536
+ }
537
+ .meta .sep { opacity: 0.3; font-weight: 400; }
538
+ .meta > span:not(.sep) {
539
+ color: var(--fg-dim);
540
+ }
541
+
542
+ /* ─── Search bar ───────────────────────────────────────── */
543
+ /* Top-bar grouped buttons — each `.tb-group` is a small flex row.
544
+ Adjacent groups get a faint vertical divider between them so the
545
+ user can see which controls cluster (file / search / view / AI). */
546
+ .tb-group {
547
+ display: flex; align-items: center; gap: 4px;
548
+ padding: 0 8px;
549
+ height: 30px;
550
+ border-right: 1px solid var(--border-edge);
551
+ }
552
+ .tb-group:last-of-type { border-right: 0; }
553
+ .tb-spacer { flex: 1 1 auto; }
554
+
555
+ /* "More" popover — anchored under the ⋯ button. Sits above every other
556
+ panel (right rail is z-index 40), so we force it to z-index 100. */
557
+ #moreMenu {
558
+ position: fixed;
559
+ top: 60px;
560
+ right: 12px;
561
+ min-width: 200px;
562
+ background: #0b0f17;
563
+ border: 1px solid var(--border-hot);
564
+ border-radius: var(--radius);
565
+ box-shadow:
566
+ 0 0 0 1px rgba(0, 0, 0, 0.5),
567
+ 0 18px 48px rgba(0, 0, 0, 0.75);
568
+ padding: 6px;
569
+ display: flex;
570
+ flex-direction: column;
571
+ gap: 2px;
572
+ z-index: 100;
573
+ }
574
+ #moreMenu.hidden { display: none; }
575
+ .more-item {
576
+ display: flex; align-items: center; gap: 10px;
577
+ width: 100%;
578
+ padding: 8px 10px;
579
+ background: transparent;
580
+ border: 1px solid transparent;
581
+ color: var(--fg);
582
+ font: inherit;
583
+ font-size: 11.5px;
584
+ text-align: left;
585
+ border-radius: 6px;
586
+ cursor: pointer;
587
+ transition: background 0.12s var(--ease-out), border-color 0.12s, color 0.12s;
588
+ }
589
+ .more-item:hover {
590
+ background: rgba(126, 207, 207, 0.08);
591
+ border-color: rgba(126, 207, 207, 0.25);
592
+ color: var(--accent);
593
+ }
594
+ .more-item.active {
595
+ background: rgba(126, 207, 207, 0.12);
596
+ border-color: var(--accent);
597
+ color: var(--accent);
598
+ }
599
+ .more-icon {
600
+ width: 22px;
601
+ text-align: center;
602
+ font-size: 13px;
603
+ flex: 0 0 22px;
604
+ }
605
+ .more-label { flex: 1 1 auto; }
606
+
607
+ #search {
608
+ width: 240px;
609
+ padding: 7px 12px;
610
+ background: var(--bg-glass);
611
+ border: 1px solid var(--border);
612
+ border-radius: var(--radius);
613
+ color: var(--fg);
614
+ font: inherit;
615
+ font-size: 11.5px;
616
+ outline: none;
617
+ backdrop-filter: blur(10px);
618
+ -webkit-backdrop-filter: blur(10px);
619
+ transition: border-color 0.2s var(--ease-out), background 0.2s;
620
+ letter-spacing: 0.01em;
621
+ }
622
+ #search:focus {
623
+ border-color: var(--accent);
624
+ background: rgba(7, 9, 15, 0.95);
625
+ }
626
+ #search::placeholder {
627
+ color: var(--fg-mute);
628
+ opacity: 0.7;
629
+ }
630
+
631
+ /* Plain icon buttons inside top-bar groups (pause, recenter, AI tools, more).
632
+ `.folder-btn` keeps its own larger styling — these are the 30×30 squares. */
633
+ #topbar .tb-group > button:not(.folder-btn) {
634
+ width: 30px; height: 30px;
635
+ background: var(--bg-glass);
636
+ border: 1px solid var(--border);
637
+ color: var(--fg-mute);
638
+ border-radius: var(--radius);
639
+ cursor: pointer;
640
+ font-size: 10.5px;
641
+ font-family: var(--font-mono);
642
+ backdrop-filter: blur(10px);
643
+ -webkit-backdrop-filter: blur(10px);
644
+ transition: all 0.18s var(--ease-out);
645
+ letter-spacing: 0.02em;
646
+ }
647
+ #topbar .tb-group > button:not(.folder-btn):hover {
648
+ border-color: var(--border-hot);
649
+ color: var(--accent);
650
+ background: rgba(126, 207, 207, 0.04);
651
+ }
652
+ #topbar .tb-group > button:not(.folder-btn).active {
653
+ border-color: var(--accent);
654
+ color: var(--accent);
655
+ background: rgba(126, 207, 207, 0.08);
656
+ }
657
+
658
+ /* ─── Legend ───────────────────────────────────────────── */
659
+ #legend {
660
+ position: relative;
661
+ padding: 12px 14px;
662
+ background: var(--bg-elev);
663
+ border: 1px solid var(--border);
664
+ border-radius: 2px;
665
+ backdrop-filter: blur(8px);
666
+ flex: 0 0 auto;
667
+ max-height: 30vh;
668
+ overflow-y: auto;
669
+ }
670
+ body.no-folder #legend { display: none; }
671
+
672
+ .legend-title {
673
+ font-size: 9px;
674
+ text-transform: uppercase;
675
+ letter-spacing: 0.2em;
676
+ color: var(--fg-mute);
677
+ margin-bottom: 8px;
678
+ }
679
+
680
+ #legend-items {
681
+ display: grid;
682
+ grid-template-columns: 1fr 1fr;
683
+ column-gap: 14px;
684
+ row-gap: 4px;
685
+ }
686
+
687
+ .legend-item {
688
+ display: flex; align-items: center; gap: 8px;
689
+ font-size: 11px;
690
+ color: var(--fg-dim);
691
+ cursor: pointer;
692
+ transition: color 0.15s;
693
+ }
694
+ .legend-item:hover { color: var(--fg); }
695
+ .legend-item.dim { opacity: 0.3; }
696
+ .legend-item .swatch {
697
+ width: 8px; height: 8px;
698
+ border-radius: 50%;
699
+ flex-shrink: 0;
700
+ }
701
+ .legend-item .count {
702
+ margin-left: auto;
703
+ color: var(--fg-mute);
704
+ font-size: 10px;
705
+ }
706
+
707
+ /* ─── Inspector ────────────────────────────────────────── */
708
+ #inspector {
709
+ grid-area: can;
710
+ align-self: stretch;
711
+ justify-self: stretch;
712
+ margin: 60px 12px 12px 12px; /* leave space for searchbar above */
713
+ width: auto;
714
+ max-width: none;
715
+ background: var(--bg-glass);
716
+ border: 1px solid var(--border-hot);
717
+ border-radius: var(--radius);
718
+ backdrop-filter: blur(14px) saturate(140%);
719
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
720
+ z-index: 11;
721
+ max-height: none;
722
+ display: flex;
723
+ flex-direction: column;
724
+ box-shadow:
725
+ 0 0 0 1px rgba(0,0,0,0.4),
726
+ 0 16px 48px rgba(0, 0, 0, 0.5);
727
+ }
728
+ /* Corner brackets — top-left and bottom-right */
729
+ #inspector::before,
730
+ #inspector::after {
731
+ content: '';
732
+ position: absolute;
733
+ width: 10px; height: 10px;
734
+ pointer-events: none;
735
+ }
736
+ #inspector::before {
737
+ top: -1px; left: -1px;
738
+ border-top: 1px solid var(--accent);
739
+ border-left: 1px solid var(--accent);
740
+ }
741
+ #inspector::after {
742
+ bottom: -1px; right: -1px;
743
+ border-bottom: 1px solid var(--accent);
744
+ border-right: 1px solid var(--accent);
745
+ }
746
+ @media (max-width: 800px) {
747
+ #inspector { width: auto; justify-self: stretch; margin: 60px 4px 4px 4px; }
748
+ }
749
+ #inspector.hidden { display: none; }
750
+
751
+ .inspector-head {
752
+ display: flex; align-items: center; justify-content: space-between;
753
+ padding: 12px 16px;
754
+ border-bottom: 1px solid var(--border-edge);
755
+ position: relative;
756
+ }
757
+ .inspector-head::after {
758
+ content: '';
759
+ position: absolute;
760
+ bottom: -1px; left: 0;
761
+ width: 16px; height: 1px;
762
+ background: var(--accent);
763
+ }
764
+ .kicker {
765
+ font-family: var(--font-mono);
766
+ font-size: 9.5px;
767
+ text-transform: uppercase;
768
+ letter-spacing: 0.32em;
769
+ color: var(--accent);
770
+ font-weight: 500;
771
+ }
772
+ #closeInspector {
773
+ background: none; border: none;
774
+ color: var(--fg-mute);
775
+ cursor: pointer;
776
+ font-size: 14px;
777
+ font-family: var(--font-mono);
778
+ transition: color 0.18s;
779
+ }
780
+ #closeInspector:hover { color: var(--accent-pink); }
781
+
782
+ #inspector-body {
783
+ padding: 14px 16px;
784
+ overflow-y: auto;
785
+ flex: 1;
786
+ }
787
+
788
+ .ins-name {
789
+ font-family: var(--font-mono);
790
+ font-size: 12.5px;
791
+ color: var(--fg);
792
+ word-break: break-all;
793
+ margin-bottom: 4px;
794
+ letter-spacing: 0.01em;
795
+ user-select: text;
796
+ }
797
+ .ins-sub {
798
+ font-size: 10px;
799
+ color: var(--fg-mute);
800
+ margin-bottom: 10px;
801
+ letter-spacing: 0.05em;
802
+ }
803
+ .ins-actions {
804
+ display: flex; gap: 6px;
805
+ margin-bottom: 14px;
806
+ }
807
+ .ins-action {
808
+ flex: 1;
809
+ padding: 5px 8px;
810
+ background: rgba(126, 207, 207, 0.06);
811
+ border: 1px solid var(--border);
812
+ color: var(--fg-dim);
813
+ border-radius: 2px;
814
+ font: inherit;
815
+ font-size: 10px;
816
+ cursor: pointer;
817
+ transition: all 0.15s;
818
+ }
819
+ .ins-action:hover {
820
+ border-color: var(--border-hot);
821
+ color: var(--accent);
822
+ }
823
+ .ins-section {
824
+ font-size: 9px;
825
+ text-transform: uppercase;
826
+ letter-spacing: 0.2em;
827
+ color: var(--fg-mute);
828
+ margin: 14px 0 6px;
829
+ }
830
+ .ins-row {
831
+ display: flex; align-items: center; gap: 8px;
832
+ font-size: 11px;
833
+ color: var(--fg-dim);
834
+ padding: 4px 0;
835
+ cursor: pointer;
836
+ transition: color 0.15s;
837
+ }
838
+ .ins-row:hover { color: var(--fg); }
839
+ .ins-row .arrow { width: 14px; text-align: center; flex-shrink: 0; }
840
+ .ins-row .target {
841
+ flex: 1;
842
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
843
+ }
844
+ .ins-row .kind {
845
+ font-size: 9px;
846
+ color: var(--fg-mute);
847
+ text-transform: uppercase;
848
+ letter-spacing: 0.1em;
849
+ }
850
+
851
+ .ins-preview {
852
+ font-size: 10px;
853
+ color: var(--fg-mute);
854
+ background: rgba(0,0,0,0.4);
855
+ padding: 8px;
856
+ border-radius: 2px;
857
+ white-space: pre;
858
+ overflow-x: auto;
859
+ max-height: 220px;
860
+ overflow-y: auto;
861
+ font-family: ui-monospace, monospace;
862
+ line-height: 1.45;
863
+ user-select: text;
864
+ }
865
+ .ins-editor {
866
+ display: block;
867
+ width: 100%;
868
+ min-height: 50vh;
869
+ flex: 1;
870
+ font-size: 12px;
871
+ color: var(--fg);
872
+ background: rgba(0,0,0,0.4);
873
+ border: 1px solid var(--border-edge);
874
+ padding: 10px 12px;
875
+ border-radius: 2px;
876
+ font-family: ui-monospace, monospace;
877
+ line-height: 1.55;
878
+ resize: vertical;
879
+ white-space: pre;
880
+ tab-size: 2;
881
+ box-sizing: border-box;
882
+ outline: none;
883
+ }
884
+ .ins-editor:focus { border-color: var(--accent); }
885
+ .ins-save-status {
886
+ font-family: var(--font-mono);
887
+ font-size: 10px;
888
+ color: var(--fg-mute);
889
+ margin-top: 6px;
890
+ min-height: 14px;
891
+ letter-spacing: 0.04em;
892
+ }
893
+ .ins-save-status.ok { color: var(--accent); }
894
+ .ins-save-status.err { color: var(--accent-pink); }
895
+
896
+ .ins-badges {
897
+ margin: 6px 0 10px 0;
898
+ display: flex; flex-wrap: wrap; gap: 6px;
899
+ }
900
+ .ins-badge {
901
+ font-family: var(--font-mono);
902
+ font-size: 10px;
903
+ padding: 3px 8px;
904
+ border-radius: 10px;
905
+ border: 1px solid var(--border-edge);
906
+ background: rgba(255,255,255,0.04);
907
+ letter-spacing: 0.04em;
908
+ }
909
+ .ins-badge.connected { border-color: rgba(80, 200, 120, 0.5); color: #7ad79a; }
910
+ .ins-badge.leaf { border-color: rgba(220, 180, 60, 0.5); color: #e8c66a; }
911
+ .ins-badge.orphan { border-color: rgba(220, 130, 60, 0.55); color: #f0a070; }
912
+
913
+ .ins-hint {
914
+ font-family: var(--font-mono);
915
+ font-size: 9.5px;
916
+ color: var(--fg-mute);
917
+ letter-spacing: 0.06em;
918
+ margin-left: 6px;
919
+ text-transform: none;
920
+ }
921
+ .ins-history {
922
+ display: flex; flex-direction: column; gap: 4px;
923
+ margin-bottom: 6px;
924
+ }
925
+ .hist-row {
926
+ display: flex; align-items: center; gap: 8px;
927
+ font-family: var(--font-mono);
928
+ font-size: 11px;
929
+ padding: 4px 6px;
930
+ background: rgba(0,0,0,0.3);
931
+ border: 1px solid var(--border-edge);
932
+ border-radius: 2px;
933
+ }
934
+ .hist-stamp { color: var(--fg); min-width: 110px; }
935
+ .hist-size { color: var(--fg-mute); font-size: 10px; flex: 1; }
936
+ .hist-btn {
937
+ background: rgba(255,255,255,0.04);
938
+ border: 1px solid var(--border-edge);
939
+ color: var(--fg);
940
+ padding: 2px 8px;
941
+ border-radius: 2px;
942
+ font-family: var(--font-mono);
943
+ font-size: 10px;
944
+ cursor: pointer;
945
+ }
946
+ .hist-btn:hover { border-color: var(--accent); color: var(--accent); }
947
+
948
+ /* ─── AI trace panel (overlay in canvas grid area, bottom-right) ── */
949
+ #aiTracePanel {
950
+ grid-area: can;
951
+ align-self: end;
952
+ justify-self: end;
953
+ margin: 0 12px 50px 0;
954
+ width: 320px;
955
+ max-width: calc(100% - 24px);
956
+ background: var(--bg-glass);
957
+ border: 1px solid var(--border-edge);
958
+ border-radius: var(--radius);
959
+ backdrop-filter: blur(14px) saturate(140%);
960
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
961
+ z-index: 10;
962
+ font-family: var(--font-mono);
963
+ pointer-events: auto;
964
+ transition: border-color 0.3s, box-shadow 0.3s;
965
+ }
966
+ #aiTracePanel.active {
967
+ border-color: rgba(120, 200, 255, 0.6);
968
+ box-shadow: 0 0 0 1px rgba(120, 200, 255, 0.25), 0 8px 32px rgba(0,0,0,0.4);
969
+ }
970
+ .ai-trace-head {
971
+ display: flex; justify-content: space-between; align-items: center;
972
+ padding: 8px 12px;
973
+ border-bottom: 1px solid var(--border-edge);
974
+ }
975
+ .trace-dot {
976
+ width: 8px; height: 8px; border-radius: 50%;
977
+ background: rgba(120, 200, 255, 0.4);
978
+ }
979
+ #aiTracePanel.active .trace-dot {
980
+ background: rgb(120, 200, 255);
981
+ box-shadow: 0 0 8px rgba(120, 200, 255, 0.8);
982
+ animation: trace-pulse 1.5s ease-in-out infinite;
983
+ }
984
+ @keyframes trace-pulse {
985
+ 0%, 100% { opacity: 1; }
986
+ 50% { opacity: 0.4; }
987
+ }
988
+ #aiTraceBody { padding: 6px 10px 10px; max-height: 220px; overflow-y: auto; }
989
+ .trace-empty {
990
+ font-size: 10px; color: var(--fg-mute); padding: 6px 2px;
991
+ font-style: italic;
992
+ }
993
+ .trace-row {
994
+ display: flex; gap: 8px; align-items: baseline;
995
+ padding: 3px 0;
996
+ font-size: 10.5px;
997
+ border-bottom: 1px dashed rgba(255,255,255,0.04);
998
+ }
999
+ .trace-row:last-child { border-bottom: none; }
1000
+ .trace-stamp { color: var(--fg-mute); flex-shrink: 0; min-width: 56px; }
1001
+ .trace-tool { color: rgb(120, 200, 255); flex-shrink: 0; min-width: 56px; text-transform: uppercase; font-size: 9.5px; letter-spacing: 0.05em; }
1002
+ .trace-row[data-tool="write"] .trace-tool,
1003
+ .trace-row[data-tool="restore"] .trace-tool { color: rgb(255, 110, 110); }
1004
+ .trace-row[data-tool="focus"] .trace-tool,
1005
+ .trace-row[data-tool="open"] .trace-tool { color: rgb(255, 220, 100); }
1006
+ .trace-row[data-tool="history"] .trace-tool { color: rgb(220, 200, 100); }
1007
+ .trace-id { color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
1008
+
1009
+ /* ─── Time-lapse slider overlay ──────────────────────────────── */
1010
+ #timelapse {
1011
+ grid-area: can;
1012
+ align-self: end;
1013
+ justify-self: center;
1014
+ margin: 0 auto 50px;
1015
+ width: min(720px, 80%);
1016
+ padding: 10px 16px 12px;
1017
+ background: var(--bg-glass);
1018
+ border: 1px solid var(--border-edge);
1019
+ border-radius: var(--radius);
1020
+ backdrop-filter: blur(14px) saturate(140%);
1021
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
1022
+ z-index: 12;
1023
+ display: flex; flex-direction: column; gap: 6px;
1024
+ pointer-events: auto;
1025
+ }
1026
+ #timelapse.hidden { display: none; }
1027
+ .tl-head { display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 11px; }
1028
+ .tl-stamp { color: var(--accent); flex: 1; font-size: 12px; letter-spacing: 0.05em; }
1029
+ .tl-btn {
1030
+ background: rgba(255,255,255,0.04);
1031
+ border: 1px solid var(--border-edge);
1032
+ color: var(--fg);
1033
+ padding: 2px 8px;
1034
+ border-radius: 2px;
1035
+ font-family: var(--font-mono);
1036
+ font-size: 11px;
1037
+ cursor: pointer;
1038
+ }
1039
+ .tl-btn:hover { border-color: var(--accent); color: var(--accent); }
1040
+ #tlSlider { width: 100%; }
1041
+ .tl-meta { font-family: var(--font-mono); font-size: 10px; color: var(--fg-mute); }
1042
+
1043
+ /* ─── AI changes panel (sits in canvas grid, like inspector) ──── */
1044
+ #changes {
1045
+ grid-area: can;
1046
+ align-self: stretch;
1047
+ justify-self: stretch;
1048
+ margin: 60px 12px 12px 12px;
1049
+ background: var(--bg-glass);
1050
+ border: 1px solid var(--border-hot);
1051
+ border-radius: var(--radius);
1052
+ backdrop-filter: blur(14px) saturate(140%);
1053
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
1054
+ z-index: 11;
1055
+ display: flex; flex-direction: column;
1056
+ overflow: hidden;
1057
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 16px 48px rgba(0,0,0,0.5);
1058
+ }
1059
+ #changes.hidden { display: none; }
1060
+ .changes-head {
1061
+ display: flex; justify-content: space-between; align-items: center;
1062
+ padding: 12px 16px;
1063
+ border-bottom: 1px solid var(--border-edge);
1064
+ }
1065
+ .changes-head button {
1066
+ background: none; border: none; color: var(--fg-mute);
1067
+ cursor: pointer; font-size: 14px; font-family: var(--font-mono);
1068
+ }
1069
+ .changes-head button:hover { color: var(--accent-pink); }
1070
+ .changes-list { flex: 1; overflow-y: auto; padding: 8px 0; }
1071
+ .changes-empty {
1072
+ padding: 24px;
1073
+ color: var(--fg-mute);
1074
+ font-size: 12px;
1075
+ text-align: center;
1076
+ }
1077
+ .change-row {
1078
+ display: grid;
1079
+ grid-template-columns: 100px 1fr auto auto;
1080
+ align-items: center;
1081
+ gap: 10px;
1082
+ padding: 10px 16px;
1083
+ border-bottom: 1px solid rgba(255,255,255,0.04);
1084
+ font-family: var(--font-mono);
1085
+ font-size: 11px;
1086
+ cursor: default;
1087
+ }
1088
+ .change-row:hover { background: rgba(255,255,255,0.02); }
1089
+ .change-stamp { color: var(--fg-mute); }
1090
+ .change-id { color: var(--fg); overflow: hidden; text-overflow: ellipsis; }
1091
+ .change-meta { color: var(--accent); font-size: 10px; letter-spacing: 0.04em; }
1092
+ .change-meta.shrink { color: rgb(255,150,150); }
1093
+ .change-expand {
1094
+ background: rgba(255,255,255,0.04);
1095
+ border: 1px solid var(--border-edge);
1096
+ color: var(--fg);
1097
+ width: 26px; height: 22px;
1098
+ border-radius: 2px;
1099
+ cursor: pointer;
1100
+ font-family: var(--font-mono);
1101
+ font-size: 14px;
1102
+ line-height: 1;
1103
+ }
1104
+ .change-expand:hover { border-color: var(--accent); color: var(--accent); }
1105
+ .change-diff {
1106
+ padding: 8px 16px 14px 16px;
1107
+ background: rgba(0,0,0,0.4);
1108
+ font-family: ui-monospace, monospace;
1109
+ font-size: 10.5px;
1110
+ line-height: 1.5;
1111
+ max-height: 60vh;
1112
+ overflow: auto;
1113
+ white-space: pre;
1114
+ display: block;
1115
+ border-bottom: 1px solid rgba(255,255,255,0.06);
1116
+ }
1117
+ .diff-add { color: rgb(140, 220, 140); }
1118
+ .diff-del { color: rgb(255, 130, 130); }
1119
+ .diff-eq { color: rgba(255,255,255,0.4); }
1120
+ .diff-add::before { content: '+ '; }
1121
+ .diff-del::before { content: '- '; }
1122
+ .diff-eq::before { content: ' '; }
1123
+
1124
+ /* ─── Folder name labels (over 3D bubbles when grouping is on) ── */
1125
+ .folder-labels {
1126
+ position: fixed;
1127
+ inset: 0;
1128
+ pointer-events: none;
1129
+ z-index: 8;
1130
+ }
1131
+ .folder-label {
1132
+ position: absolute;
1133
+ transform: translate(-50%, -50%);
1134
+ font-family: var(--font-mono);
1135
+ font-size: 18px;
1136
+ font-weight: 600;
1137
+ letter-spacing: 0.08em;
1138
+ text-shadow:
1139
+ 0 0 8px rgba(0,0,0,0.85),
1140
+ 0 0 16px rgba(0,0,0,0.6);
1141
+ white-space: nowrap;
1142
+ opacity: 0.9;
1143
+ pointer-events: none;
1144
+ }
1145
+
1146
+ /* ─── Project switcher popover ───────────────────────────────── */
1147
+ #projectSwitcher {
1148
+ position: fixed;
1149
+ top: 48px;
1150
+ left: 180px; /* offset to sit under the ▾ button */
1151
+ width: 380px;
1152
+ max-height: 60vh;
1153
+ background: var(--bg-glass);
1154
+ border: 1px solid var(--border-hot);
1155
+ border-radius: var(--radius);
1156
+ backdrop-filter: blur(14px) saturate(140%);
1157
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
1158
+ z-index: 50;
1159
+ display: flex; flex-direction: column;
1160
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 12px 36px rgba(0,0,0,0.45);
1161
+ overflow: hidden;
1162
+ font-family: var(--font-mono);
1163
+ }
1164
+ #projectSwitcher.hidden { display: none; }
1165
+ .psw-head {
1166
+ display: flex; align-items: center; gap: 8px;
1167
+ padding: 8px 10px;
1168
+ border-bottom: 1px solid var(--border-edge);
1169
+ }
1170
+ .psw-head .kicker { flex: 1; }
1171
+ .psw-btn {
1172
+ background: rgba(255,255,255,0.05);
1173
+ border: 1px solid var(--border-edge);
1174
+ color: var(--fg);
1175
+ padding: 3px 9px;
1176
+ border-radius: 2px;
1177
+ font-family: var(--font-mono);
1178
+ font-size: 11px;
1179
+ cursor: pointer;
1180
+ }
1181
+ .psw-btn:hover { border-color: var(--accent); color: var(--accent); }
1182
+ .psw-section { padding: 4px 0; max-height: 200px; overflow-y: auto; }
1183
+ .psw-section-title {
1184
+ font-size: 9.5px;
1185
+ letter-spacing: 0.22em;
1186
+ text-transform: uppercase;
1187
+ color: var(--fg-mute);
1188
+ padding: 8px 12px 4px;
1189
+ border-top: 1px dashed rgba(255,255,255,0.06);
1190
+ }
1191
+ .psw-row {
1192
+ display: grid;
1193
+ grid-template-columns: 1fr auto auto;
1194
+ gap: 6px;
1195
+ align-items: center;
1196
+ padding: 8px 12px;
1197
+ font-size: 11px;
1198
+ border-bottom: 1px dashed rgba(255,255,255,0.04);
1199
+ cursor: pointer;
1200
+ transition: background 0.12s;
1201
+ }
1202
+ .psw-row:hover { background: rgba(255,255,255,0.04); }
1203
+ .psw-row.active {
1204
+ background: rgba(126, 207, 207, 0.08);
1205
+ border-left: 2px solid var(--accent);
1206
+ padding-left: 10px;
1207
+ }
1208
+ .psw-name {
1209
+ display: flex; flex-direction: column; gap: 2px;
1210
+ overflow: hidden;
1211
+ }
1212
+ .psw-name-row {
1213
+ display: flex; align-items: center; gap: 6px;
1214
+ color: var(--fg);
1215
+ font-weight: 600;
1216
+ }
1217
+ .psw-path {
1218
+ color: var(--fg-mute);
1219
+ font-size: 9.5px;
1220
+ overflow: hidden;
1221
+ text-overflow: ellipsis;
1222
+ white-space: nowrap;
1223
+ }
1224
+ .psw-icon {
1225
+ width: 16px; height: 16px;
1226
+ display: inline-flex; align-items: center; justify-content: center;
1227
+ font-size: 12px;
1228
+ color: var(--accent);
1229
+ }
1230
+ .psw-pin {
1231
+ background: none; border: none; color: var(--fg-mute);
1232
+ cursor: pointer; font-size: 14px;
1233
+ width: 24px; height: 24px;
1234
+ }
1235
+ .psw-pin:hover { color: var(--accent); }
1236
+ .psw-pin.pinned { color: var(--accent); }
1237
+ .psw-empty { padding: 24px; color: var(--fg-mute); font-size: 11px; text-align: center; }
1238
+ .psw-empty.hidden { display: none; }
1239
+
1240
+ /* ─── Hints ────────────────────────────────────────────── */
1241
+ #hints {
1242
+ grid-area: can;
1243
+ align-self: end;
1244
+ justify-self: end;
1245
+ margin: 12px;
1246
+ font-family: var(--font-mono);
1247
+ font-size: 10px;
1248
+ color: var(--fg-mute);
1249
+ text-align: right;
1250
+ letter-spacing: 0.04em;
1251
+ z-index: 5;
1252
+ display: flex;
1253
+ pointer-events: none;
1254
+ align-items: center;
1255
+ gap: 4px;
1256
+ }
1257
+ .hint-key {
1258
+ display: inline-block;
1259
+ padding: 2px 6px;
1260
+ background: rgba(126, 207, 207, 0.05);
1261
+ border: 1px solid var(--border-edge);
1262
+ color: var(--accent);
1263
+ font-size: 9.5px;
1264
+ text-transform: uppercase;
1265
+ letter-spacing: 0.08em;
1266
+ margin-right: 2px;
1267
+ }
1268
+ .hint-sep {
1269
+ opacity: 0.35;
1270
+ margin: 0 4px;
1271
+ }
1272
+ body.no-folder #hints { display: none; }
1273
+
1274
+ /* ─── Welcome ──────────────────────────────────────────── */
1275
+ #welcome {
1276
+ position: fixed; inset: 0;
1277
+ display: flex; align-items: center; justify-content: center;
1278
+ z-index: 20;
1279
+ background:
1280
+ radial-gradient(ellipse 80% 50% at center, rgba(126, 207, 207, 0.04), transparent 60%),
1281
+ radial-gradient(circle at 20% 80%, rgba(232, 121, 166, 0.03), transparent 40%),
1282
+ radial-gradient(circle at 80% 20%, rgba(255, 200, 80, 0.025), transparent 40%);
1283
+ }
1284
+ body:not(.no-folder) #welcome { display: none; }
1285
+
1286
+ .welcome-inner {
1287
+ text-align: center;
1288
+ width: 520px;
1289
+ max-width: 90vw;
1290
+ }
1291
+
1292
+ /* Framed plate with corner brackets — observatory readout */
1293
+ .welcome-frame {
1294
+ position: relative;
1295
+ padding: 56px 48px 40px;
1296
+ border: 1px solid var(--border-edge);
1297
+ background:
1298
+ linear-gradient(180deg, rgba(7,9,15,0.4) 0%, rgba(7,9,15,0.7) 100%);
1299
+ backdrop-filter: blur(6px);
1300
+ }
1301
+ /* Four corner brackets, like a printed instrument plate */
1302
+ .frame-corner {
1303
+ position: absolute;
1304
+ width: 18px;
1305
+ height: 18px;
1306
+ pointer-events: none;
1307
+ }
1308
+ .frame-corner.tl { top: -1px; left: -1px; border-top: 1px solid var(--accent); border-left: 1px solid var(--accent); }
1309
+ .frame-corner.tr { top: -1px; right: -1px; border-top: 1px solid var(--accent); border-right: 1px solid var(--accent); }
1310
+ .frame-corner.bl { bottom: -1px; left: -1px; border-bottom: 1px solid var(--accent); border-left: 1px solid var(--accent); }
1311
+ .frame-corner.br { bottom: -1px; right: -1px; border-bottom: 1px solid var(--accent); border-right: 1px solid var(--accent); }
1312
+
1313
+ /* Top meta line — measurement-like channel readout */
1314
+ .welcome-meta {
1315
+ display: flex;
1316
+ justify-content: center;
1317
+ gap: 10px;
1318
+ font-family: var(--font-mono);
1319
+ font-size: 9.5px;
1320
+ letter-spacing: 0.22em;
1321
+ text-transform: uppercase;
1322
+ color: var(--fg-mute);
1323
+ margin-bottom: 28px;
1324
+ }
1325
+ .welcome-coord { opacity: 0.85; }
1326
+ .welcome-coord:first-child { color: var(--accent); opacity: 1; }
1327
+ .welcome-sep { opacity: 0.3; }
1328
+
1329
+ /* Constellation SVG */
1330
+ .welcome-constellation {
1331
+ height: 90px;
1332
+ margin: 0 auto 24px;
1333
+ color: var(--accent);
1334
+ opacity: 0.7;
1335
+ animation: constellationFade 4s var(--ease-out) infinite;
1336
+ }
1337
+ .welcome-constellation svg {
1338
+ width: 220px;
1339
+ height: 90px;
1340
+ filter: drop-shadow(0 0 8px rgba(126, 207, 207, 0.4));
1341
+ }
1342
+ @keyframes constellationFade {
1343
+ 0%, 100% { opacity: 0.55; }
1344
+ 50% { opacity: 0.85; }
1345
+ }
1346
+
1347
+ .welcome-title {
1348
+ font-family: var(--font-display);
1349
+ font-size: 28px;
1350
+ font-weight: 700;
1351
+ letter-spacing: 0.18em;
1352
+ text-transform: lowercase;
1353
+ color: var(--fg);
1354
+ margin-bottom: 14px;
1355
+ line-height: 1;
1356
+ }
1357
+ .welcome-title .accent { color: var(--accent); font-weight: 700; }
1358
+ .welcome-bracket {
1359
+ color: var(--accent);
1360
+ opacity: 0.5;
1361
+ font-weight: 400;
1362
+ margin: 0 12px;
1363
+ display: inline-block;
1364
+ transform: translateY(-2px);
1365
+ }
1366
+
1367
+ .welcome-sub {
1368
+ font-size: 11.5px;
1369
+ color: var(--fg-mute);
1370
+ margin-bottom: 32px;
1371
+ line-height: 1.65;
1372
+ letter-spacing: 0.02em;
1373
+ }
1374
+
1375
+ /* Divider with brackets — "begin" callout */
1376
+ .welcome-divider {
1377
+ display: flex;
1378
+ align-items: center;
1379
+ justify-content: center;
1380
+ gap: 8px;
1381
+ font-family: var(--font-mono);
1382
+ font-size: 10px;
1383
+ color: var(--fg-mute);
1384
+ letter-spacing: 0.3em;
1385
+ text-transform: uppercase;
1386
+ margin-bottom: 20px;
1387
+ }
1388
+ .welcome-divider-tick {
1389
+ color: var(--accent);
1390
+ font-size: 8px;
1391
+ }
1392
+
1393
+ .primary-btn {
1394
+ display: inline-flex;
1395
+ align-items: center;
1396
+ gap: 14px;
1397
+ padding: 12px 22px 12px 18px;
1398
+ background: transparent;
1399
+ color: var(--accent);
1400
+ border: 1px solid var(--accent);
1401
+ border-radius: var(--radius);
1402
+ font: inherit;
1403
+ font-family: var(--font-display);
1404
+ font-size: 11.5px;
1405
+ font-weight: 600;
1406
+ letter-spacing: 0.16em;
1407
+ text-transform: uppercase;
1408
+ cursor: pointer;
1409
+ transition: all 0.22s var(--ease-out);
1410
+ position: relative;
1411
+ box-shadow:
1412
+ 0 0 0 1px transparent,
1413
+ 0 0 32px rgba(126, 207, 207, 0.0);
1414
+ }
1415
+ .primary-btn::before {
1416
+ content: '';
1417
+ position: absolute;
1418
+ inset: 3px;
1419
+ border: 1px solid transparent;
1420
+ transition: border-color 0.22s var(--ease-out);
1421
+ pointer-events: none;
1422
+ }
1423
+ .primary-btn:hover {
1424
+ background: var(--accent);
1425
+ color: var(--bg);
1426
+ box-shadow:
1427
+ 0 0 0 1px var(--accent),
1428
+ 0 0 32px rgba(126, 207, 207, 0.4);
1429
+ }
1430
+ .primary-btn:hover::before {
1431
+ border-color: var(--bg);
1432
+ }
1433
+ .primary-btn:active {
1434
+ transform: translateY(1px);
1435
+ }
1436
+ .btn-icon {
1437
+ font-family: var(--font-mono);
1438
+ font-size: 9px;
1439
+ letter-spacing: -0.1em;
1440
+ opacity: 0.7;
1441
+ }
1442
+ .btn-key {
1443
+ font-family: var(--font-mono);
1444
+ font-size: 9.5px;
1445
+ padding: 2px 6px;
1446
+ border: 1px solid currentColor;
1447
+ opacity: 0.6;
1448
+ letter-spacing: 0.05em;
1449
+ font-weight: 400;
1450
+ }
1451
+
1452
+ #recentList {
1453
+ margin: 32px 0 0;
1454
+ display: flex; flex-direction: column;
1455
+ gap: 2px;
1456
+ }
1457
+ #recentList:empty { display: none; }
1458
+
1459
+ .recent-label {
1460
+ font-family: var(--font-mono);
1461
+ font-size: 9.5px;
1462
+ text-transform: uppercase;
1463
+ letter-spacing: 0.28em;
1464
+ color: var(--fg-mute);
1465
+ margin-bottom: 10px;
1466
+ display: flex;
1467
+ align-items: center;
1468
+ gap: 8px;
1469
+ }
1470
+ .recent-label::before { content: '└─'; opacity: 0.5; }
1471
+ .recent-label::after { content: '──'; opacity: 0.3; flex: 1; }
1472
+
1473
+ .recent-item {
1474
+ padding: 7px 14px;
1475
+ background: transparent;
1476
+ border: 1px solid transparent;
1477
+ border-radius: var(--radius);
1478
+ color: var(--fg-dim);
1479
+ font-size: 11px;
1480
+ cursor: pointer;
1481
+ text-align: left;
1482
+ font-family: var(--font-mono);
1483
+ overflow: hidden;
1484
+ text-overflow: ellipsis;
1485
+ white-space: nowrap;
1486
+ direction: rtl;
1487
+ transition: all 0.18s var(--ease-out);
1488
+ position: relative;
1489
+ }
1490
+ .recent-item::before {
1491
+ content: '▸ ';
1492
+ color: var(--accent);
1493
+ opacity: 0;
1494
+ margin-right: -8px;
1495
+ transition: opacity 0.18s, margin 0.18s var(--ease-out);
1496
+ }
1497
+ .recent-item:hover {
1498
+ border-color: var(--border);
1499
+ background: rgba(126, 207, 207, 0.03);
1500
+ color: var(--fg);
1501
+ }
1502
+ .recent-item:hover::before {
1503
+ opacity: 0.8;
1504
+ margin-right: 0;
1505
+ }
1506
+
1507
+ .welcome-hint {
1508
+ margin-top: 24px;
1509
+ font-family: var(--font-mono);
1510
+ font-size: 10px;
1511
+ color: var(--fg-mute);
1512
+ letter-spacing: 0.08em;
1513
+ }
1514
+ .hint-dim {
1515
+ opacity: 0.5;
1516
+ margin-right: 4px;
1517
+ color: var(--accent);
1518
+ }
1519
+
1520
+ /* ─── Drop overlay ─────────────────────────────────────── */
1521
+ #dropOverlay {
1522
+ position: fixed; inset: 0;
1523
+ background: rgba(7, 9, 15, 0.85);
1524
+ display: flex; align-items: center; justify-content: center;
1525
+ z-index: 100;
1526
+ pointer-events: none;
1527
+ border: 3px dashed var(--accent);
1528
+ }
1529
+ #dropOverlay.hidden { display: none; }
1530
+ .drop-inner {
1531
+ font-size: 14px;
1532
+ letter-spacing: 0.2em;
1533
+ text-transform: uppercase;
1534
+ color: var(--accent);
1535
+ text-shadow: 0 0 20px var(--accent);
1536
+ }
1537
+
1538
+ /* Scrollbar */
1539
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
1540
+ ::-webkit-scrollbar-track { background: transparent; }
1541
+ ::-webkit-scrollbar-thumb { background: rgba(126, 207, 207, 0.2); border-radius: 3px; }
1542
+ ::-webkit-scrollbar-thumb:hover { background: rgba(126, 207, 207, 0.4); }
1543
+
1544
+ /* ─── Settings panel ───────────────────────────────────── */
1545
+ #settings {
1546
+ position: fixed;
1547
+ top: 70px;
1548
+ right: 16px;
1549
+ width: 360px;
1550
+ max-height: calc(100vh - 100px);
1551
+ overflow-y: auto;
1552
+ background: rgba(12, 16, 24, 0.92);
1553
+ backdrop-filter: blur(14px);
1554
+ -webkit-backdrop-filter: blur(14px);
1555
+ border: 1px solid rgba(126, 207, 207, 0.18);
1556
+ border-radius: 10px;
1557
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
1558
+ z-index: 50;
1559
+ font-size: 12px;
1560
+ }
1561
+ #settings.hidden { display: none; }
1562
+ .settings-head {
1563
+ display: flex; justify-content: space-between; align-items: center;
1564
+ padding: 12px 14px;
1565
+ border-bottom: 1px solid rgba(126, 207, 207, 0.1);
1566
+ }
1567
+ .settings-head .kicker {
1568
+ font-size: 9px;
1569
+ letter-spacing: 0.2em;
1570
+ text-transform: uppercase;
1571
+ color: var(--fg-mute);
1572
+ }
1573
+ #closeSettings {
1574
+ background: transparent;
1575
+ border: none;
1576
+ color: var(--fg-mute);
1577
+ font-size: 14px;
1578
+ cursor: pointer;
1579
+ padding: 4px 8px;
1580
+ }
1581
+ #closeSettings:hover { color: var(--fg); }
1582
+ .settings-body { padding: 12px 14px; }
1583
+ .settings-section {
1584
+ font-size: 11px;
1585
+ letter-spacing: 0.15em;
1586
+ text-transform: uppercase;
1587
+ color: var(--accent);
1588
+ margin-bottom: 8px;
1589
+ }
1590
+ .settings-help {
1591
+ font-size: 11px;
1592
+ color: var(--fg-mute);
1593
+ line-height: 1.5;
1594
+ margin: 0 0 12px;
1595
+ }
1596
+ .setting-row { display: flex; align-items: center; gap: 8px; margin: 4px 0; }
1597
+ .setting-toggle {
1598
+ display: inline-flex; align-items: center; gap: 8px;
1599
+ cursor: pointer;
1600
+ font-size: 12px;
1601
+ color: var(--fg);
1602
+ user-select: none;
1603
+ }
1604
+ .setting-toggle input[type=checkbox] { cursor: pointer; }
1605
+ .settings-help code {
1606
+ font-family: var(--font-mono);
1607
+ font-size: 10.5px;
1608
+ padding: 1px 5px;
1609
+ background: rgba(255,255,255,0.06);
1610
+ border-radius: 2px;
1611
+ color: var(--accent);
1612
+ }
1613
+ .radio-group { display: flex; flex-direction: column; gap: 4px; }
1614
+ .radio {
1615
+ display: flex;
1616
+ align-items: flex-start;
1617
+ gap: 10px;
1618
+ padding: 10px;
1619
+ border-radius: 6px;
1620
+ cursor: pointer;
1621
+ border: 1px solid transparent;
1622
+ transition: background 0.15s, border-color 0.15s;
1623
+ }
1624
+ .radio:hover { background: rgba(126, 207, 207, 0.06); }
1625
+ .radio.is-disabled {
1626
+ opacity: 0.5;
1627
+ cursor: not-allowed;
1628
+ pointer-events: auto; /* keep tooltip on hover */
1629
+ }
1630
+ .radio.is-disabled:hover { background: transparent; }
1631
+ .radio.is-disabled .radio-sub { font-style: italic; }
1632
+ .radio input[type="radio"] {
1633
+ margin-top: 2px;
1634
+ accent-color: var(--accent);
1635
+ }
1636
+ .radio input[type="radio"]:checked + .radio-label {
1637
+ color: var(--fg);
1638
+ }
1639
+ .radio:has(input:checked) {
1640
+ background: rgba(126, 207, 207, 0.08);
1641
+ border-color: rgba(126, 207, 207, 0.25);
1642
+ }
1643
+ .radio-label {
1644
+ display: flex;
1645
+ flex-direction: column;
1646
+ gap: 3px;
1647
+ flex: 1;
1648
+ }
1649
+ .radio-label strong {
1650
+ font-size: 12px;
1651
+ color: var(--fg);
1652
+ font-weight: 500;
1653
+ }
1654
+ .radio-label .radio-sub {
1655
+ font-size: 10.5px;
1656
+ color: var(--fg-mute);
1657
+ line-height: 1.45;
1658
+ }
1659
+ .status-block {
1660
+ margin-top: 14px;
1661
+ padding: 10px 12px;
1662
+ background: rgba(0, 0, 0, 0.25);
1663
+ border-radius: 6px;
1664
+ border: 1px solid rgba(255, 255, 255, 0.04);
1665
+ font-family: 'SF Mono', Menlo, monospace;
1666
+ }
1667
+ .status-row {
1668
+ display: flex;
1669
+ justify-content: space-between;
1670
+ padding: 3px 0;
1671
+ font-size: 11px;
1672
+ }
1673
+ .status-key {
1674
+ color: var(--fg-mute);
1675
+ letter-spacing: 0.05em;
1676
+ }
1677
+ .status-row span:last-child { color: var(--fg); }
1678
+ .status-row .reason {
1679
+ text-align: right;
1680
+ max-width: 220px;
1681
+ word-break: break-word;
1682
+ font-size: 10.5px;
1683
+ }
1684
+
1685
+ #settingsBtn {
1686
+ background: rgba(126, 207, 207, 0.08);
1687
+ border: 1px solid rgba(126, 207, 207, 0.2);
1688
+ color: var(--fg);
1689
+ border-radius: 6px;
1690
+ padding: 0 10px;
1691
+ font-size: 14px;
1692
+ cursor: pointer;
1693
+ transition: background 0.15s;
1694
+ }
1695
+ #settingsBtn:hover { background: rgba(126, 207, 207, 0.16); }
1696
+
1697
+ /* ─── Focus-depth controls ─────────────────────────────── */
1698
+ .depth-control {
1699
+ display: flex;
1700
+ flex-direction: column;
1701
+ gap: 10px;
1702
+ margin-bottom: 10px;
1703
+ }
1704
+ .slider-row {
1705
+ display: flex;
1706
+ flex-direction: column;
1707
+ gap: 6px;
1708
+ margin-top: 12px;
1709
+ }
1710
+ .slider-label {
1711
+ display: flex;
1712
+ justify-content: space-between;
1713
+ font-size: 11.5px;
1714
+ color: var(--fg);
1715
+ letter-spacing: 0.04em;
1716
+ }
1717
+ .slider-val {
1718
+ font-family: 'SF Mono', Menlo, monospace;
1719
+ font-size: 11px;
1720
+ color: var(--accent);
1721
+ }
1722
+ .slider-row input[type="range"] {
1723
+ width: 100%;
1724
+ accent-color: var(--accent);
1725
+ background: transparent;
1726
+ }
1727
+ .depth-input-label {
1728
+ display: flex;
1729
+ align-items: center;
1730
+ gap: 10px;
1731
+ font-size: 12px;
1732
+ color: var(--fg);
1733
+ font-weight: 500;
1734
+ }
1735
+ .depth-input-label > span:first-child {
1736
+ letter-spacing: 0.05em;
1737
+ min-width: 42px;
1738
+ }
1739
+ .depth-hint {
1740
+ font-size: 10.5px;
1741
+ color: var(--fg-mute);
1742
+ font-family: 'SF Mono', Menlo, monospace;
1743
+ letter-spacing: 0.05em;
1744
+ }
1745
+ #focusDepthInput {
1746
+ width: 64px;
1747
+ padding: 6px 10px;
1748
+ background: rgba(0, 0, 0, 0.3);
1749
+ border: 1px solid rgba(126, 207, 207, 0.2);
1750
+ border-radius: 5px;
1751
+ color: var(--fg);
1752
+ font-family: 'SF Mono', Menlo, monospace;
1753
+ font-size: 13px;
1754
+ font-weight: 500;
1755
+ text-align: center;
1756
+ outline: none;
1757
+ transition: border-color 0.15s, background 0.15s;
1758
+ }
1759
+ #focusDepthInput:focus {
1760
+ border-color: var(--accent);
1761
+ background: rgba(126, 207, 207, 0.06);
1762
+ box-shadow: 0 0 0 2px rgba(126, 207, 207, 0.12);
1763
+ }
1764
+ #focusDepthInput:disabled {
1765
+ opacity: 0.4;
1766
+ cursor: not-allowed;
1767
+ background: rgba(0, 0, 0, 0.15);
1768
+ }
1769
+ .depth-input-label:has(input:disabled) {
1770
+ opacity: 0.5;
1771
+ }
1772
+ /* Hide native number arrows */
1773
+ #focusDepthInput::-webkit-inner-spin-button,
1774
+ #focusDepthInput::-webkit-outer-spin-button {
1775
+ -webkit-appearance: none;
1776
+ margin: 0;
1777
+ }
1778
+ #focusDepthInput { -moz-appearance: textfield; }
1779
+
1780
+ .toggle-btn {
1781
+ display: flex;
1782
+ align-items: center;
1783
+ gap: 9px;
1784
+ padding: 9px 12px;
1785
+ background: transparent;
1786
+ border: 1px solid rgba(126, 207, 207, 0.2);
1787
+ border-radius: 6px;
1788
+ color: var(--fg-mute);
1789
+ font-size: 12px;
1790
+ letter-spacing: 0.02em;
1791
+ cursor: pointer;
1792
+ transition: background 0.15s, border-color 0.15s, color 0.15s;
1793
+ width: 100%;
1794
+ text-align: left;
1795
+ }
1796
+ .toggle-btn:hover {
1797
+ background: rgba(126, 207, 207, 0.06);
1798
+ color: var(--fg);
1799
+ }
1800
+ .toggle-btn.active {
1801
+ background: rgba(126, 207, 207, 0.12);
1802
+ border-color: var(--accent);
1803
+ color: var(--fg);
1804
+ }
1805
+ .toggle-dot {
1806
+ width: 10px; height: 10px;
1807
+ border-radius: 50%;
1808
+ background: rgba(255, 255, 255, 0.12);
1809
+ border: 1px solid rgba(255, 255, 255, 0.2);
1810
+ transition: background 0.15s, box-shadow 0.15s, border-color 0.15s;
1811
+ flex-shrink: 0;
1812
+ }
1813
+ .toggle-btn.active .toggle-dot {
1814
+ background: var(--accent);
1815
+ border-color: var(--accent);
1816
+ box-shadow: 0 0 8px var(--accent);
1817
+ }
1818
+
1819
+ .depth-legend {
1820
+ margin-top: 8px;
1821
+ padding: 10px 12px;
1822
+ background: rgba(0, 0, 0, 0.18);
1823
+ border-radius: 6px;
1824
+ display: flex;
1825
+ flex-direction: column;
1826
+ gap: 5px;
1827
+ }
1828
+ .depth-row {
1829
+ display: flex;
1830
+ align-items: center;
1831
+ gap: 10px;
1832
+ font-size: 11px;
1833
+ color: var(--fg-mute);
1834
+ }
1835
+ .depth-swatch {
1836
+ width: 10px; height: 10px;
1837
+ border-radius: 50%;
1838
+ background: var(--accent);
1839
+ box-shadow: 0 0 4px var(--accent);
1840
+ flex-shrink: 0;
1841
+ }
1842
+
1843
+ /* ─── Search bar enhancements ───────────────────────────── */
1844
+ .search-input-wrap {
1845
+ position: relative;
1846
+ flex: 1;
1847
+ display: flex;
1848
+ }
1849
+ .search-input-wrap input { flex: 1; }
1850
+ .search-count {
1851
+ position: absolute;
1852
+ right: 10px;
1853
+ top: 50%;
1854
+ transform: translateY(-50%);
1855
+ font-size: 10.5px;
1856
+ font-family: 'SF Mono', Menlo, monospace;
1857
+ color: var(--fg-mute);
1858
+ pointer-events: none;
1859
+ letter-spacing: 0.04em;
1860
+ }
1861
+ .search-count.has-result { color: var(--accent); }
1862
+ .search-count.no-result { color: #E879A6; }
1863
+
1864
+ .micro-btn {
1865
+ width: 30px; height: 30px;
1866
+ background: transparent;
1867
+ border: 1px solid rgba(126, 207, 207, 0.2);
1868
+ color: var(--fg-mute);
1869
+ border-radius: 6px;
1870
+ font-size: 11px;
1871
+ font-family: 'SF Mono', Menlo, monospace;
1872
+ cursor: pointer;
1873
+ transition: background 0.15s, color 0.15s, border-color 0.15s;
1874
+ display: flex; align-items: center; justify-content: center;
1875
+ }
1876
+ .micro-btn:hover { background: rgba(126, 207, 207, 0.08); color: var(--fg); }
1877
+ .micro-btn.active {
1878
+ background: rgba(126, 207, 207, 0.16);
1879
+ border-color: var(--accent);
1880
+ color: var(--accent);
1881
+ }
1882
+
1883
+ /* ─── Scan toast ────────────────────────────────────────── */
1884
+ #scanToast {
1885
+ position: fixed;
1886
+ bottom: 24px;
1887
+ left: 50%;
1888
+ transform: translateX(-50%);
1889
+ display: flex;
1890
+ align-items: center;
1891
+ gap: 10px;
1892
+ padding: 10px 16px;
1893
+ background: rgba(12, 16, 24, 0.92);
1894
+ backdrop-filter: blur(14px);
1895
+ border: 1px solid rgba(126, 207, 207, 0.3);
1896
+ border-radius: 24px;
1897
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6), 0 0 24px rgba(126, 207, 207, 0.15);
1898
+ z-index: 60;
1899
+ font-size: 12px;
1900
+ color: var(--fg);
1901
+ }
1902
+ #scanToast.hidden { display: none; }
1903
+ .spinner {
1904
+ width: 12px; height: 12px;
1905
+ border: 2px solid rgba(126, 207, 207, 0.2);
1906
+ border-top-color: var(--accent);
1907
+ border-radius: 50%;
1908
+ animation: spin 0.8s linear infinite;
1909
+ }
1910
+ @keyframes spin { to { transform: rotate(360deg); } }
1911
+ .scan-label { font-family: 'SF Mono', Menlo, monospace; letter-spacing: 0.04em; }
1912
+ .scan-label span { color: var(--accent); font-weight: 500; }
1913
+
1914
+ /* ─── Stats panel ───────────────────────────────────────── */
1915
+ #statsPanel {
1916
+ position: fixed;
1917
+ top: 70px;
1918
+ right: 16px;
1919
+ width: 320px;
1920
+ max-height: calc(100vh - 100px);
1921
+ overflow-y: auto;
1922
+ background: rgba(12, 16, 24, 0.92);
1923
+ backdrop-filter: blur(14px);
1924
+ border: 1px solid rgba(126, 207, 207, 0.18);
1925
+ border-radius: 10px;
1926
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
1927
+ z-index: 49;
1928
+ font-size: 12px;
1929
+ }
1930
+ #statsPanel.hidden { display: none; }
1931
+ .stats-head {
1932
+ display: flex; justify-content: space-between; align-items: center;
1933
+ padding: 12px 14px;
1934
+ border-bottom: 1px solid rgba(126, 207, 207, 0.1);
1935
+ }
1936
+ .stats-head .kicker {
1937
+ font-size: 9px;
1938
+ letter-spacing: 0.2em;
1939
+ text-transform: uppercase;
1940
+ color: var(--fg-mute);
1941
+ }
1942
+ #closeStats {
1943
+ background: transparent;
1944
+ border: none;
1945
+ color: var(--fg-mute);
1946
+ font-size: 14px;
1947
+ cursor: pointer;
1948
+ padding: 4px 8px;
1949
+ }
1950
+ .stats-body { padding: 12px 14px; }
1951
+ .stats-block { margin-bottom: 18px; }
1952
+ .stats-block:last-child { margin-bottom: 0; }
1953
+ .stats-block h4 {
1954
+ margin: 0 0 8px;
1955
+ font-size: 10.5px;
1956
+ letter-spacing: 0.18em;
1957
+ text-transform: uppercase;
1958
+ color: var(--accent);
1959
+ font-weight: 500;
1960
+ }
1961
+ .stats-block .stat-line {
1962
+ display: flex; justify-content: space-between;
1963
+ padding: 4px 0;
1964
+ font-size: 11.5px;
1965
+ color: var(--fg-mute);
1966
+ }
1967
+ .stats-block .stat-line strong { color: var(--fg); font-weight: 500; }
1968
+ .stats-block .stat-list {
1969
+ margin: 0; padding: 0; list-style: none;
1970
+ }
1971
+ .stats-block .stat-list li {
1972
+ display: flex;
1973
+ justify-content: space-between;
1974
+ align-items: center;
1975
+ padding: 5px 8px;
1976
+ border-radius: 4px;
1977
+ font-size: 11px;
1978
+ color: var(--fg-mute);
1979
+ cursor: pointer;
1980
+ transition: background 0.12s;
1981
+ }
1982
+ .stats-block .stat-list li:hover { background: rgba(126, 207, 207, 0.08); color: var(--fg); }
1983
+ .stats-block .stat-list .deg {
1984
+ font-family: 'SF Mono', Menlo, monospace;
1985
+ color: var(--accent);
1986
+ font-size: 10.5px;
1987
+ }
1988
+
1989
+ /* ─── Toast (generic) ───────────────────────────────────── */
1990
+ #toastHost {
1991
+ position: fixed;
1992
+ bottom: 24px;
1993
+ right: 24px;
1994
+ display: flex;
1995
+ flex-direction: column;
1996
+ gap: 8px;
1997
+ z-index: 70;
1998
+ pointer-events: none;
1999
+ }
2000
+ .toast {
2001
+ background: rgba(12, 16, 24, 0.95);
2002
+ backdrop-filter: blur(14px);
2003
+ border: 1px solid rgba(126, 207, 207, 0.25);
2004
+ border-radius: 8px;
2005
+ padding: 10px 14px;
2006
+ font-size: 12px;
2007
+ color: var(--fg);
2008
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
2009
+ animation: toastIn 0.2s ease, toastOut 0.3s ease 2.7s forwards;
2010
+ }
2011
+ @keyframes toastIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; } }
2012
+ @keyframes toastOut { to { opacity: 0; transform: translateY(-4px); } }
2013
+
2014
+ /* ─── Export + preset buttons ───────────────────────────── */
2015
+ .export-row, .preset-row {
2016
+ display: flex;
2017
+ flex-direction: column;
2018
+ gap: 6px;
2019
+ }
2020
+ .preset-row { flex-direction: row; }
2021
+ .export-btn, .preset-btn {
2022
+ padding: 8px 12px;
2023
+ background: rgba(126, 207, 207, 0.06);
2024
+ border: 1px solid rgba(126, 207, 207, 0.2);
2025
+ color: var(--fg);
2026
+ border-radius: 6px;
2027
+ font-size: 11.5px;
2028
+ cursor: pointer;
2029
+ text-align: left;
2030
+ transition: background 0.15s, border-color 0.15s;
2031
+ }
2032
+ .preset-btn {
2033
+ flex: 1;
2034
+ text-align: center;
2035
+ font-family: 'SF Mono', Menlo, monospace;
2036
+ font-size: 10.5px;
2037
+ letter-spacing: 0.05em;
2038
+ }
2039
+ .export-btn:hover, .preset-btn:hover {
2040
+ background: rgba(126, 207, 207, 0.14);
2041
+ border-color: var(--accent);
2042
+ }
2043
+
2044
+ /* ─── Right sidebar shell — fills grid area "rgt" ──────── */
2045
+ #rightRail {
2046
+ display: flex;
2047
+ flex-direction: column;
2048
+ gap: 0;
2049
+ z-index: 40;
2050
+ min-height: 0;
2051
+ min-width: 0;
2052
+ overflow-y: auto;
2053
+ background: var(--bg-elev);
2054
+ border-left: 1px solid var(--border-edge);
2055
+ margin: 0 calc(var(--grid-pad) * -1) 0 0;
2056
+ transition: opacity 0.22s ease;
2057
+ }
2058
+ /* Minimap can collapse to a header-only strip (− button next to it). */
2059
+ #rightRail #minimapWrap.collapsed {
2060
+ aspect-ratio: auto;
2061
+ height: 28px;
2062
+ max-height: 28px;
2063
+ }
2064
+ #rightRail #minimapWrap.collapsed > #minimapCanvas { display: none; }
2065
+ #rightRail #minimapWrap.collapsed > .minimap-corner.top-left {
2066
+ top: 50%;
2067
+ transform: translateY(-50%);
2068
+ }
2069
+ #rightRail #minimapWrap.collapsed > #minimapToggle {
2070
+ top: 50%;
2071
+ transform: translateY(-50%);
2072
+ }
2073
+
2074
+ /* Sections inside the right rail stack vertically with thin dividers. */
2075
+ .rs-section {
2076
+ border-bottom: 1px solid var(--border-edge);
2077
+ flex: 0 0 auto;
2078
+ }
2079
+ .rs-section:last-child { border-bottom: 0; flex: 1 1 auto; min-height: 0; }
2080
+ .rs-head {
2081
+ display: flex; align-items: center; justify-content: space-between;
2082
+ padding: 10px 14px;
2083
+ border-bottom: 1px solid var(--border-edge);
2084
+ }
2085
+ .rs-empty {
2086
+ padding: 14px 16px;
2087
+ color: var(--fg-mute);
2088
+ font-size: 10.5px;
2089
+ font-style: italic;
2090
+ text-align: center;
2091
+ opacity: 0.7;
2092
+ }
2093
+
2094
+ /* Override floating positioning when these panels live inside #rightRail. */
2095
+ #rightRail #inspector {
2096
+ grid-area: auto;
2097
+ align-self: auto;
2098
+ justify-self: auto;
2099
+ margin: 0;
2100
+ width: auto;
2101
+ max-width: none;
2102
+ background: transparent;
2103
+ border: 0;
2104
+ border-radius: 0;
2105
+ backdrop-filter: none;
2106
+ -webkit-backdrop-filter: none;
2107
+ box-shadow: none;
2108
+ z-index: auto;
2109
+ max-height: none;
2110
+ flex: 0 0 auto;
2111
+ }
2112
+ #rightRail #inspector::before,
2113
+ #rightRail #inspector::after { display: none; }
2114
+ #rightRail #aiTracePanel {
2115
+ grid-area: auto;
2116
+ align-self: auto;
2117
+ justify-self: auto;
2118
+ margin: 0;
2119
+ width: auto;
2120
+ max-width: none;
2121
+ background: transparent;
2122
+ border: 0;
2123
+ border-radius: 0;
2124
+ backdrop-filter: none;
2125
+ -webkit-backdrop-filter: none;
2126
+ z-index: auto;
2127
+ }
2128
+ #rightRail #minimapWrap {
2129
+ width: 100%;
2130
+ height: auto;
2131
+ aspect-ratio: 1 / 1;
2132
+ max-height: var(--rail-w);
2133
+ border-radius: 0;
2134
+ border: 0;
2135
+ box-shadow: none;
2136
+ }
2137
+ #rightRail #contextPanel {
2138
+ background: transparent;
2139
+ border: 0;
2140
+ padding: 0;
2141
+ margin: 0;
2142
+ }
2143
+ #rightRail #contextPanel > .ctx-body { padding: 10px 16px 14px; }
2144
+ #rightRail #inspector > #inspector-body {
2145
+ padding: 12px 16px;
2146
+ }
2147
+ /* Inside the right rail the inspector is permanent — `.hidden` from other
2148
+ code paths is ignored; an empty body just shows the placeholder text. */
2149
+ #rightRail #inspector.hidden { display: flex; }
2150
+
2151
+ #minimapWrap {
2152
+ position: relative;
2153
+ width: var(--rail-w);
2154
+ height: var(--rail-w);
2155
+ background: var(--bg-glass);
2156
+ backdrop-filter: blur(14px) saturate(140%);
2157
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
2158
+ border: 1px solid var(--border);
2159
+ border-radius: var(--radius);
2160
+ box-shadow:
2161
+ 0 0 0 1px rgba(0,0,0,0.4),
2162
+ 0 12px 40px rgba(0, 0, 0, 0.5);
2163
+ overflow: hidden;
2164
+ }
2165
+ /* Bracket markers on all 4 corners */
2166
+ #minimapWrap::before,
2167
+ #minimapWrap::after {
2168
+ content: '';
2169
+ position: absolute;
2170
+ width: 10px; height: 10px;
2171
+ pointer-events: none;
2172
+ z-index: 2;
2173
+ }
2174
+ #minimapWrap::before {
2175
+ top: 4px; left: 4px;
2176
+ border-top: 1px solid var(--accent);
2177
+ border-left: 1px solid var(--accent);
2178
+ }
2179
+ #minimapWrap::after {
2180
+ bottom: 4px; right: 4px;
2181
+ border-bottom: 1px solid var(--accent);
2182
+ border-right: 1px solid var(--accent);
2183
+ }
2184
+ #minimapCanvas {
2185
+ display: block;
2186
+ width: 100%;
2187
+ height: 100%;
2188
+ cursor: crosshair;
2189
+ }
2190
+ .minimap-corner {
2191
+ position: absolute;
2192
+ font-family: var(--font-mono);
2193
+ font-size: 9px;
2194
+ letter-spacing: 0.28em;
2195
+ text-transform: uppercase;
2196
+ color: var(--fg-mute);
2197
+ padding: 8px 12px;
2198
+ pointer-events: none;
2199
+ user-select: none;
2200
+ z-index: 3;
2201
+ }
2202
+ .minimap-corner.top-left {
2203
+ top: 0; left: 0;
2204
+ color: var(--accent);
2205
+ font-weight: 500;
2206
+ opacity: 0.85;
2207
+ }
2208
+ .minimap-corner.top-right {
2209
+ top: 4px; right: 4px;
2210
+ pointer-events: auto;
2211
+ background: transparent;
2212
+ border: 1px solid var(--border-edge);
2213
+ color: var(--fg-mute);
2214
+ cursor: pointer;
2215
+ font-size: 14px;
2216
+ font-family: var(--font-mono);
2217
+ padding: 0;
2218
+ width: 22px;
2219
+ height: 22px;
2220
+ line-height: 1;
2221
+ display: flex;
2222
+ align-items: center;
2223
+ justify-content: center;
2224
+ transition: all 0.18s var(--ease-out);
2225
+ }
2226
+ .minimap-corner.top-right:hover {
2227
+ color: var(--accent);
2228
+ border-color: var(--border-hot);
2229
+ background: rgba(126, 207, 207, 0.06);
2230
+ }
2231
+
2232
+ #contextPanel {
2233
+ background: var(--bg-glass);
2234
+ backdrop-filter: blur(14px) saturate(140%);
2235
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
2236
+ border: 1px solid var(--border);
2237
+ border-radius: var(--radius);
2238
+ padding: 14px 16px;
2239
+ font-size: 11.5px;
2240
+ color: var(--fg);
2241
+ max-height: calc(100vh - 380px);
2242
+ overflow-y: auto;
2243
+ box-shadow:
2244
+ 0 0 0 1px rgba(0,0,0,0.5),
2245
+ 0 12px 40px rgba(0, 0, 0, 0.55);
2246
+ position: relative;
2247
+ }
2248
+ /* Corner brackets on context panel */
2249
+ #contextPanel::before,
2250
+ #contextPanel::after {
2251
+ content: '';
2252
+ position: absolute;
2253
+ width: 8px; height: 8px;
2254
+ pointer-events: none;
2255
+ opacity: 0.6;
2256
+ }
2257
+ #contextPanel::before {
2258
+ top: -1px; left: -1px;
2259
+ border-top: 1px solid var(--accent);
2260
+ border-left: 1px solid var(--accent);
2261
+ }
2262
+ #contextPanel::after {
2263
+ bottom: -1px; right: -1px;
2264
+ border-bottom: 1px solid var(--accent);
2265
+ border-right: 1px solid var(--accent);
2266
+ }
2267
+ .ctx-head {
2268
+ display: flex;
2269
+ justify-content: space-between;
2270
+ align-items: center;
2271
+ margin-bottom: 12px;
2272
+ padding-bottom: 10px;
2273
+ border-bottom: 1px solid var(--border-edge);
2274
+ position: relative;
2275
+ }
2276
+ .ctx-head::after {
2277
+ /* Tiny tick on the divider */
2278
+ content: '';
2279
+ position: absolute;
2280
+ bottom: -1px; left: 0;
2281
+ width: 12px; height: 1px;
2282
+ background: var(--accent);
2283
+ }
2284
+ .ctx-head .kicker {
2285
+ font-family: var(--font-mono);
2286
+ font-size: 9.5px;
2287
+ letter-spacing: 0.28em;
2288
+ text-transform: uppercase;
2289
+ color: var(--fg-mute);
2290
+ }
2291
+ .ctx-head .micro-btn { width: 22px; height: 22px; font-size: 10px; }
2292
+
2293
+ .ctx-body { line-height: 1.6; word-wrap: break-word; }
2294
+
2295
+ /* Node info layout */
2296
+ .ctx-node-title {
2297
+ font-family: var(--font-mono);
2298
+ font-size: 12px;
2299
+ font-weight: 600;
2300
+ color: var(--accent);
2301
+ margin-bottom: 4px;
2302
+ word-break: break-all;
2303
+ letter-spacing: 0.01em;
2304
+ }
2305
+ .ctx-node-path {
2306
+ font-family: var(--font-mono);
2307
+ font-size: 10px;
2308
+ color: var(--fg-mute);
2309
+ margin-bottom: 14px;
2310
+ word-break: break-all;
2311
+ letter-spacing: 0.02em;
2312
+ opacity: 0.85;
2313
+ }
2314
+ .ctx-row {
2315
+ display: flex;
2316
+ justify-content: space-between;
2317
+ padding: 5px 0;
2318
+ font-size: 11px;
2319
+ font-family: var(--font-mono);
2320
+ border-bottom: 1px solid var(--border-edge);
2321
+ }
2322
+ .ctx-row:last-of-type { border-bottom: none; }
2323
+ .ctx-row span:first-child {
2324
+ color: var(--fg-mute);
2325
+ letter-spacing: 0.04em;
2326
+ }
2327
+ .ctx-row span:last-child {
2328
+ color: var(--fg);
2329
+ font-family: var(--font-mono);
2330
+ font-feature-settings: 'tnum';
2331
+ }
2332
+ .ctx-actions {
2333
+ display: flex;
2334
+ gap: 6px;
2335
+ margin-top: 14px;
2336
+ }
2337
+ .ctx-actions button {
2338
+ flex: 1;
2339
+ padding: 7px 10px;
2340
+ background: rgba(126, 207, 207, 0.08);
2341
+ border: 1px solid rgba(126, 207, 207, 0.2);
2342
+ color: var(--fg);
2343
+ border-radius: 5px;
2344
+ font-size: 11px;
2345
+ cursor: pointer;
2346
+ transition: background 0.15s;
2347
+ }
2348
+ .ctx-actions button:hover { background: rgba(126, 207, 207, 0.16); }
2349
+
2350
+ /* Project info layout */
2351
+ .ctx-project-name {
2352
+ font-size: 14px;
2353
+ font-weight: 500;
2354
+ color: var(--fg);
2355
+ margin-bottom: 2px;
2356
+ }
2357
+ .ctx-project-meta {
2358
+ font-size: 10.5px;
2359
+ color: var(--fg-mute);
2360
+ font-family: 'SF Mono', Menlo, monospace;
2361
+ margin-bottom: 12px;
2362
+ }
2363
+ .ctx-project-section {
2364
+ font-size: 9.5px;
2365
+ letter-spacing: 0.18em;
2366
+ text-transform: uppercase;
2367
+ color: var(--accent);
2368
+ margin: 12px 0 6px;
2369
+ font-weight: 500;
2370
+ }
2371
+ .ctx-project-text {
2372
+ font-size: 11.5px;
2373
+ color: var(--fg-mute);
2374
+ line-height: 1.6;
2375
+ white-space: pre-wrap;
2376
+ }
2377
+ .ctx-empty {
2378
+ color: var(--fg-mute);
2379
+ font-size: 11px;
2380
+ text-align: center;
2381
+ padding: 20px 0;
2382
+ line-height: 1.6;
2383
+ }
2384
+ .ctx-empty button {
2385
+ margin-top: 10px;
2386
+ padding: 6px 14px;
2387
+ background: rgba(126, 207, 207, 0.1);
2388
+ border: 1px solid var(--accent);
2389
+ color: var(--accent);
2390
+ border-radius: 5px;
2391
+ font-size: 11px;
2392
+ cursor: pointer;
2393
+ }
2394
+
2395
+ /* ─── Project dialog ───────────────────────────────────── */
2396
+ #projectDialog {
2397
+ position: fixed;
2398
+ inset: 0;
2399
+ z-index: 200;
2400
+ display: flex;
2401
+ align-items: center;
2402
+ justify-content: center;
2403
+ }
2404
+ #projectDialog.hidden { display: none; }
2405
+ .dialog-backdrop {
2406
+ position: absolute;
2407
+ inset: 0;
2408
+ background: rgba(0, 0, 0, 0.55);
2409
+ backdrop-filter: blur(4px);
2410
+ }
2411
+ .dialog-card {
2412
+ position: relative;
2413
+ width: 480px;
2414
+ max-width: calc(100vw - 40px);
2415
+ max-height: calc(100vh - 80px);
2416
+ overflow-y: auto;
2417
+ background: rgba(14, 18, 26, 0.98);
2418
+ border: 1px solid rgba(126, 207, 207, 0.25);
2419
+ border-radius: 12px;
2420
+ box-shadow: 0 30px 80px rgba(0, 0, 0, 0.7);
2421
+ }
2422
+ .dialog-head {
2423
+ display: flex;
2424
+ justify-content: space-between;
2425
+ align-items: center;
2426
+ padding: 14px 18px;
2427
+ border-bottom: 1px solid rgba(126, 207, 207, 0.1);
2428
+ }
2429
+ #dialogClose {
2430
+ background: transparent;
2431
+ border: none;
2432
+ color: var(--fg-mute);
2433
+ font-size: 14px;
2434
+ cursor: pointer;
2435
+ padding: 4px 8px;
2436
+ }
2437
+ #dialogClose:hover { color: var(--fg); }
2438
+ .dialog-help {
2439
+ margin: 14px 18px 0;
2440
+ font-size: 11.5px;
2441
+ color: var(--fg-mute);
2442
+ line-height: 1.55;
2443
+ }
2444
+ .dialog-form {
2445
+ padding: 14px 18px 0;
2446
+ display: flex;
2447
+ flex-direction: column;
2448
+ gap: 10px;
2449
+ }
2450
+ .form-row {
2451
+ display: flex;
2452
+ flex-direction: column;
2453
+ gap: 4px;
2454
+ }
2455
+ .form-label {
2456
+ font-size: 10px;
2457
+ letter-spacing: 0.15em;
2458
+ text-transform: uppercase;
2459
+ color: var(--fg-mute);
2460
+ }
2461
+ .form-row input,
2462
+ .form-row textarea {
2463
+ background: rgba(0, 0, 0, 0.3);
2464
+ border: 1px solid rgba(126, 207, 207, 0.2);
2465
+ border-radius: 5px;
2466
+ padding: 8px 10px;
2467
+ color: var(--fg);
2468
+ font-size: 12.5px;
2469
+ font-family: inherit;
2470
+ outline: none;
2471
+ resize: vertical;
2472
+ }
2473
+ .form-row input:focus,
2474
+ .form-row textarea:focus {
2475
+ border-color: var(--accent);
2476
+ background: rgba(126, 207, 207, 0.05);
2477
+ }
2478
+ .dialog-actions {
2479
+ display: flex;
2480
+ justify-content: flex-end;
2481
+ gap: 8px;
2482
+ padding: 18px;
2483
+ border-top: 1px solid rgba(126, 207, 207, 0.1);
2484
+ margin-top: 14px;
2485
+ }
2486
+ .secondary-btn, .primary-btn {
2487
+ padding: 8px 18px;
2488
+ border-radius: 6px;
2489
+ font-size: 12px;
2490
+ cursor: pointer;
2491
+ font-family: inherit;
2492
+ }
2493
+ .secondary-btn {
2494
+ background: transparent;
2495
+ border: 1px solid rgba(126, 207, 207, 0.2);
2496
+ color: var(--fg-mute);
2497
+ }
2498
+ .secondary-btn:hover { color: var(--fg); }
2499
+ /* primary-btn is already defined in original style.css */
2500
+
2501
+ /* Shift settings/stats panels left so they don't cover the minimap */
2502
+ #settings,
2503
+ #statsPanel {
2504
+ right: 312px; /* 280 minimap + 16 + 16 gap */
2505
+ }
2506
+
2507
+ /* When right rail is open, the toggle button shows active styling */
2508
+ #rightRailBtn.active {
2509
+ background: rgba(126, 207, 207, 0.16);
2510
+ border-color: var(--accent);
2511
+ color: var(--accent);
2512
+ }
2513
+
2514
+ /* When right rail is collapsed, settings/stats can use the normal right edge */
2515
+ body.rail-collapsed #settings,
2516
+ body.rail-collapsed #statsPanel {
2517
+ right: 16px;
2518
+ }
2519
+
2520
+ /* ─── Status bar (bottom strip) ────────────────────────── */
2521
+ #statusBar {
2522
+ margin: 0 calc(var(--grid-pad) * -1);
2523
+ display: flex;
2524
+ align-items: center;
2525
+ background: rgba(7, 9, 15, 0.92);
2526
+ backdrop-filter: blur(12px);
2527
+ -webkit-backdrop-filter: blur(12px);
2528
+ border-top: 1px solid rgba(126, 207, 207, 0.12);
2529
+ z-index: 30;
2530
+ padding: 0 12px;
2531
+ font-size: 10.5px;
2532
+ font-family: 'SF Mono', Menlo, monospace;
2533
+ color: var(--fg-mute);
2534
+ letter-spacing: 0.03em;
2535
+ user-select: none;
2536
+ }
2537
+ .status-section {
2538
+ display: flex;
2539
+ gap: 18px;
2540
+ align-items: center;
2541
+ }
2542
+ .status-left { flex: 1; }
2543
+ .status-center { flex: 1; justify-content: center; }
2544
+ .status-right { flex: 1; justify-content: flex-end; }
2545
+ .status-cell {
2546
+ white-space: nowrap;
2547
+ overflow: hidden;
2548
+ text-overflow: ellipsis;
2549
+ }
2550
+ .status-cell .v { color: var(--fg); }
2551
+ .status-cell .accent { color: var(--accent); }
2552
+ .status-cell.bad { color: #E879A6; }
2553
+ .status-cell.good { color: #6BCB77; }
2554
+ .status-cell.sb-clickable {
2555
+ cursor: pointer;
2556
+ transition: color .15s, background .15s;
2557
+ padding: 2px 6px;
2558
+ border-radius: 3px;
2559
+ }
2560
+ .status-cell.sb-clickable:hover {
2561
+ color: var(--accent);
2562
+ background: rgba(126,207,207,0.08);
2563
+ }
2564
+ .status-cell.sb-clickable.loading {
2565
+ color: var(--warn);
2566
+ animation: sb-pulse 1.2s ease-in-out infinite;
2567
+ }
2568
+ @keyframes sb-pulse {
2569
+ 0%, 100% { opacity: 1; }
2570
+ 50% { opacity: 0.55; }
2571
+ }
2572
+
2573
+ /* Bottom-anchored overlays need to lift above the status bar */
2574
+ #scanToast { bottom: 36px !important; }
2575
+ #toastHost { bottom: 36px !important; }
2576
+
2577
+ /* ─── Filter badges (topbar) ───────────────────────────── */
2578
+ .filter-badges {
2579
+ display: flex;
2580
+ gap: 6px;
2581
+ flex: 1;
2582
+ margin-left: 14px;
2583
+ overflow: hidden;
2584
+ align-items: center;
2585
+ }
2586
+ .filter-badge {
2587
+ display: inline-flex;
2588
+ align-items: center;
2589
+ gap: 6px;
2590
+ padding: 3px 8px 3px 10px;
2591
+ background: rgba(126, 207, 207, 0.1);
2592
+ border: 1px solid rgba(126, 207, 207, 0.25);
2593
+ color: var(--fg);
2594
+ border-radius: 999px;
2595
+ font-size: 10.5px;
2596
+ letter-spacing: 0.02em;
2597
+ white-space: nowrap;
2598
+ flex-shrink: 0;
2599
+ max-width: 200px;
2600
+ overflow: hidden;
2601
+ text-overflow: ellipsis;
2602
+ }
2603
+ .filter-badge .badge-key {
2604
+ font-size: 9px;
2605
+ letter-spacing: 0.15em;
2606
+ text-transform: uppercase;
2607
+ color: var(--accent);
2608
+ margin-right: 2px;
2609
+ }
2610
+ .filter-badge button {
2611
+ background: transparent;
2612
+ border: none;
2613
+ color: var(--fg-mute);
2614
+ cursor: pointer;
2615
+ padding: 0 0 0 4px;
2616
+ font-size: 12px;
2617
+ line-height: 1;
2618
+ }
2619
+ .filter-badge button:hover { color: var(--fg); }
2620
+ .filter-badge.warning {
2621
+ background: rgba(232, 121, 166, 0.08);
2622
+ border-color: rgba(232, 121, 166, 0.35);
2623
+ }
2624
+ .filter-badge.warning .badge-key { color: #E879A6; }
2625
+
2626
+ /* ─── Recent files panel ───────────────────────────────── */
2627
+ #recentFiles {
2628
+ position: relative;
2629
+ width: auto;
2630
+ background: rgba(7, 9, 15, 0.85);
2631
+ backdrop-filter: blur(12px);
2632
+ -webkit-backdrop-filter: blur(12px);
2633
+ border: 1px solid rgba(126, 207, 207, 0.18);
2634
+ border-radius: 8px;
2635
+ padding: 8px 10px 10px;
2636
+ font-size: 11px;
2637
+ flex: 0 0 auto;
2638
+ }
2639
+ #recentFiles.hidden { display: none; }
2640
+ .rf-head {
2641
+ display: flex; justify-content: space-between; align-items: center;
2642
+ margin-bottom: 6px;
2643
+ }
2644
+ .rf-list {
2645
+ display: flex; flex-direction: column; gap: 2px;
2646
+ max-height: 180px;
2647
+ overflow-y: auto;
2648
+ }
2649
+ .rf-item {
2650
+ display: flex;
2651
+ align-items: center;
2652
+ gap: 8px;
2653
+ padding: 5px 7px;
2654
+ border-radius: 4px;
2655
+ cursor: pointer;
2656
+ font-size: 11px;
2657
+ color: var(--fg-mute);
2658
+ transition: background 0.12s, color 0.12s;
2659
+ }
2660
+ .rf-item:hover { background: rgba(126, 207, 207, 0.08); color: var(--fg); }
2661
+ .rf-item .rf-dot {
2662
+ width: 6px; height: 6px;
2663
+ border-radius: 50%;
2664
+ flex-shrink: 0;
2665
+ box-shadow: 0 0 4px currentColor;
2666
+ }
2667
+ .rf-item .rf-name {
2668
+ overflow: hidden;
2669
+ text-overflow: ellipsis;
2670
+ white-space: nowrap;
2671
+ flex: 1;
2672
+ font-family: 'SF Mono', Menlo, monospace;
2673
+ font-size: 10.5px;
2674
+ }
2675
+ .rf-item.active { background: rgba(126, 207, 207, 0.16); color: var(--accent); }
2676
+ .rf-empty {
2677
+ padding: 16px 14px;
2678
+ color: var(--fg-mute);
2679
+ font-size: 10.5px;
2680
+ text-align: center;
2681
+ opacity: 0.7;
2682
+ }
2683
+
2684
+ /* ─── Left sidebar shell — fills grid area "lft" ──────── */
2685
+ #leftRail {
2686
+ display: flex;
2687
+ flex-direction: column;
2688
+ min-height: 0;
2689
+ min-width: 0;
2690
+ overflow: hidden;
2691
+ background: var(--bg-elev);
2692
+ border-right: 1px solid var(--border-edge);
2693
+ margin: 0 calc(var(--grid-pad) * -1) 0 calc(var(--grid-pad) * -1);
2694
+ /* extend full-width into grid gap so it visually anchors to viewport edge */
2695
+ }
2696
+
2697
+ /* ═══ Left sidebar: tabs + single visible pane ═══ */
2698
+ .left-tabs {
2699
+ display: flex;
2700
+ border-bottom: 1px solid var(--border-edge);
2701
+ background: rgba(0, 0, 0, 0.25);
2702
+ flex: 0 0 32px;
2703
+ }
2704
+ .left-tab {
2705
+ flex: 1;
2706
+ height: 32px;
2707
+ background: transparent;
2708
+ border: 0;
2709
+ color: var(--fg-mute);
2710
+ font: inherit;
2711
+ font-size: 10.5px;
2712
+ text-transform: lowercase;
2713
+ letter-spacing: 0.04em;
2714
+ cursor: pointer;
2715
+ border-bottom: 2px solid transparent;
2716
+ transition: color 0.12s, border-color 0.12s, background 0.12s;
2717
+ }
2718
+ .left-tab:hover { color: var(--fg); background: rgba(126, 207, 207, 0.04); }
2719
+ .left-tab.active {
2720
+ color: var(--accent);
2721
+ border-bottom-color: var(--accent);
2722
+ background: rgba(126, 207, 207, 0.06);
2723
+ }
2724
+ .left-tab-pane {
2725
+ flex: 1 1 auto;
2726
+ min-height: 0;
2727
+ overflow-y: auto;
2728
+ display: flex;
2729
+ flex-direction: column;
2730
+ }
2731
+ .left-tab-pane.hidden { display: none; }
2732
+ body.no-folder #leftRail { display: none; }
2733
+ /* Tree collapse hides only the file tree section — the other left-rail
2734
+ panels (pipelines, recent, legend) remain visible. */
2735
+ body.tree-collapsed #fileTreePanel { display: none; }
2736
+
2737
+ #fileTreePanel {
2738
+ position: relative;
2739
+ width: auto;
2740
+ flex: 1 1 auto;
2741
+ min-height: 140px;
2742
+ background: rgba(7, 9, 15, 0.85);
2743
+ backdrop-filter: blur(12px);
2744
+ -webkit-backdrop-filter: blur(12px);
2745
+ border: 1px solid rgba(126, 207, 207, 0.18);
2746
+ border-radius: 10px;
2747
+ display: flex;
2748
+ flex-direction: column;
2749
+ overflow: hidden;
2750
+ transition: opacity 0.22s ease;
2751
+ }
2752
+ #fileTreePanel.collapsed {
2753
+ transform: translateX(calc(-100% - 32px));
2754
+ opacity: 0;
2755
+ pointer-events: none;
2756
+ }
2757
+ .ft-head {
2758
+ display: flex;
2759
+ justify-content: space-between;
2760
+ align-items: center;
2761
+ padding: 10px 12px;
2762
+ border-bottom: 1px solid rgba(126, 207, 207, 0.1);
2763
+ flex-shrink: 0;
2764
+ }
2765
+ .ft-actions { display: flex; gap: 4px; }
2766
+ .ft-root {
2767
+ padding: 6px 12px 8px;
2768
+ font-family: var(--font-mono);
2769
+ font-size: 11px;
2770
+ color: var(--accent);
2771
+ border-bottom: 1px solid rgba(126, 207, 207, 0.08);
2772
+ word-break: break-all;
2773
+ line-height: 1.4;
2774
+ flex-shrink: 0;
2775
+ }
2776
+ .ft-root:empty { display: none; }
2777
+ .ft-root .ft-root-name { color: var(--fg); font-weight: 600; }
2778
+ .ft-root .ft-root-path { color: var(--fg-mute); font-size: 9.5px; display: block; margin-top: 2px; }
2779
+ #fileTreePanel.collapsed .ft-root { display: none; }
2780
+ .ft-body {
2781
+ padding: 8px 6px 8px 8px;
2782
+ overflow-y: auto;
2783
+ overflow-x: auto;
2784
+ flex: 1;
2785
+ font-family: 'SF Mono', Menlo, monospace;
2786
+ font-size: 11px;
2787
+ }
2788
+ .ft-row {
2789
+ display: flex;
2790
+ align-items: center;
2791
+ padding: 3px 6px;
2792
+ border-radius: 4px;
2793
+ cursor: pointer;
2794
+ color: var(--fg-mute);
2795
+ white-space: nowrap;
2796
+ user-select: none;
2797
+ transition: background 0.1s;
2798
+ }
2799
+ .ft-row:hover { background: rgba(126, 207, 207, 0.06); color: var(--fg); }
2800
+ .ft-row.active { background: rgba(126, 207, 207, 0.16); color: var(--accent); }
2801
+ .ft-row .ft-icon {
2802
+ width: 12px; height: 12px;
2803
+ display: inline-flex;
2804
+ align-items: center;
2805
+ justify-content: center;
2806
+ margin-right: 4px;
2807
+ font-size: 9px;
2808
+ color: var(--fg-mute);
2809
+ flex-shrink: 0;
2810
+ }
2811
+ .ft-row .ft-icon.expand { cursor: pointer; }
2812
+ .ft-row .ft-color {
2813
+ width: 6px; height: 6px;
2814
+ border-radius: 50%;
2815
+ margin-right: 6px;
2816
+ box-shadow: 0 0 4px currentColor;
2817
+ flex-shrink: 0;
2818
+ }
2819
+ .ft-row .ft-label {
2820
+ overflow: hidden;
2821
+ text-overflow: ellipsis;
2822
+ }
2823
+ .ft-row .ft-count {
2824
+ margin-left: auto;
2825
+ font-size: 9px;
2826
+ color: var(--fg-mute);
2827
+ padding-left: 6px;
2828
+ }
2829
+ .ft-folder .ft-label { color: var(--fg); }
2830
+ .ft-row.matched { background: rgba(126, 207, 207, 0.10); }
2831
+
2832
+ /* ─── Responsive: narrow screens ───────────────────────── */
2833
+ @media (max-width: 1280px) {
2834
+ #minimapWrap { width: var(--rail-w); height: var(--rail-w); }
2835
+ }
2836
+ @media (max-width: 800px) {
2837
+ /* On very narrow screens, hide the right rail entirely; user can
2838
+ bring it back with M shortcut. */
2839
+ #rightRail { transform: translateX(calc(100% + 32px)); opacity: 0; pointer-events: none; }
2840
+ }
2841
+
2842
+ /* ─── No-folder welcome state — hide all chrome panels ─── */
2843
+ body.no-folder #leftRail,
2844
+ body.no-folder #rightRail,
2845
+ body.no-folder #statusBar,
2846
+ body.no-folder #statsPanel,
2847
+ body.no-folder .filter-badges {
2848
+ display: none;
2849
+ }
2850
+
2851
+ /* ─── Dialog shake animation (for backdrop click feedback) ─ */
2852
+ @keyframes shakeDialog {
2853
+ 0%, 100% { transform: translateX(0); }
2854
+ 20% { transform: translateX(-6px); }
2855
+ 40% { transform: translateX(6px); }
2856
+ 60% { transform: translateX(-4px); }
2857
+ 80% { transform: translateX(4px); }
2858
+ }
2859
+ .dialog-card.shake {
2860
+ animation: shakeDialog 0.32s ease-out;
2861
+ }
2862
+
2863
+ /* ─── File tree active-set markings ────────────────────── */
2864
+ .ft-star {
2865
+ width: 14px;
2866
+ display: inline-flex;
2867
+ align-items: center;
2868
+ justify-content: center;
2869
+ margin-right: 4px;
2870
+ font-size: 11px;
2871
+ color: rgba(255, 255, 255, 0.18);
2872
+ cursor: pointer;
2873
+ user-select: none;
2874
+ transition: color 0.12s, transform 0.1s;
2875
+ flex-shrink: 0;
2876
+ }
2877
+ .ft-star:hover { color: rgba(255, 200, 80, 0.7); transform: scale(1.15); }
2878
+ .ft-star.on { color: #FFC850; text-shadow: 0 0 4px rgba(255, 200, 80, 0.5); }
2879
+ .ft-row.starred .ft-label { color: var(--fg); }
2880
+ .ft-row.starred .ft-color { box-shadow: 0 0 6px currentColor; }
2881
+ .ft-stars {
2882
+ font-size: 9px;
2883
+ color: #FFC850;
2884
+ margin-left: auto;
2885
+ padding-right: 4px;
2886
+ font-family: 'SF Mono', Menlo, monospace;
2887
+ }
2888
+ .ft-row.ft-folder .ft-count {
2889
+ margin-left: 0;
2890
+ }
2891
+ .ft-row.ft-folder .ft-stars + .ft-count {
2892
+ margin-left: 6px;
2893
+ }
2894
+
2895
+ /* ─── Pipelines panel ──────────────────────────────────── */
2896
+ #pipelinesPanel {
2897
+ position: relative;
2898
+ width: auto;
2899
+ background: var(--bg-glass);
2900
+ backdrop-filter: blur(14px) saturate(140%);
2901
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
2902
+ border: 1px solid var(--border);
2903
+ border-radius: var(--radius);
2904
+ padding: 12px 12px 14px;
2905
+ font-size: 11px;
2906
+ flex: 0 0 auto;
2907
+ max-height: 220px;
2908
+ overflow-y: auto;
2909
+ box-shadow:
2910
+ 0 0 0 1px rgba(0,0,0,0.4),
2911
+ 0 12px 40px rgba(0, 0, 0, 0.5);
2912
+ }
2913
+ #pipelinesPanel::before,
2914
+ #pipelinesPanel::after {
2915
+ content: '';
2916
+ position: absolute;
2917
+ width: 8px; height: 8px;
2918
+ pointer-events: none;
2919
+ opacity: 0.6;
2920
+ }
2921
+ #pipelinesPanel::before {
2922
+ top: -1px; left: -1px;
2923
+ border-top: 1px solid var(--accent-warm);
2924
+ border-left: 1px solid var(--accent-warm);
2925
+ }
2926
+ #pipelinesPanel::after {
2927
+ bottom: -1px; right: -1px;
2928
+ border-bottom: 1px solid var(--accent-warm);
2929
+ border-right: 1px solid var(--accent-warm);
2930
+ }
2931
+ #pipelinesPanel.hidden { display: none; }
2932
+
2933
+ .pp-head {
2934
+ display: flex; justify-content: space-between; align-items: center;
2935
+ margin-bottom: 10px;
2936
+ padding-bottom: 8px;
2937
+ border-bottom: 1px solid var(--border-edge);
2938
+ position: relative;
2939
+ }
2940
+ .pp-head::after {
2941
+ content: '';
2942
+ position: absolute;
2943
+ bottom: -1px; left: 0;
2944
+ width: 14px; height: 1px;
2945
+ background: var(--accent-warm);
2946
+ }
2947
+ .pp-head .kicker {
2948
+ font-family: var(--font-mono);
2949
+ font-size: 9.5px;
2950
+ letter-spacing: 0.28em;
2951
+ text-transform: uppercase;
2952
+ color: var(--accent-warm);
2953
+ opacity: 0.85;
2954
+ font-weight: 500;
2955
+ }
2956
+ .pp-actions { display: flex; gap: 4px; }
2957
+ .pp-list { display: flex; flex-direction: column; gap: 3px; }
2958
+
2959
+ .pp-item {
2960
+ display: flex;
2961
+ align-items: center;
2962
+ gap: 8px;
2963
+ padding: 6px 9px;
2964
+ border-radius: var(--radius);
2965
+ background: transparent;
2966
+ border: 1px solid var(--border-edge);
2967
+ transition: all 0.18s var(--ease-out);
2968
+ cursor: default;
2969
+ position: relative;
2970
+ }
2971
+ .pp-item:hover {
2972
+ border-color: var(--border);
2973
+ background: rgba(126, 207, 207, 0.02);
2974
+ }
2975
+ .pp-item.on {
2976
+ background: rgba(255, 200, 80, 0.06);
2977
+ border-color: rgba(255, 200, 80, 0.35);
2978
+ }
2979
+ .pp-item.on::before {
2980
+ content: '';
2981
+ position: absolute;
2982
+ left: -1px; top: 0; bottom: 0;
2983
+ width: 2px;
2984
+ background: var(--accent-warm);
2985
+ box-shadow: 0 0 8px var(--accent-warm);
2986
+ }
2987
+ .pp-item .pp-toggle {
2988
+ width: 12px; height: 12px;
2989
+ border-radius: var(--radius);
2990
+ border: 1px solid var(--fg-mute);
2991
+ display: inline-flex;
2992
+ align-items: center;
2993
+ justify-content: center;
2994
+ cursor: pointer;
2995
+ flex-shrink: 0;
2996
+ font-size: 8px;
2997
+ font-family: var(--font-mono);
2998
+ color: transparent;
2999
+ transition: all 0.18s var(--ease-out);
3000
+ }
3001
+ .pp-item.on .pp-toggle {
3002
+ background: var(--accent-warm);
3003
+ border-color: var(--accent-warm);
3004
+ color: var(--bg);
3005
+ }
3006
+ .pp-item .pp-name {
3007
+ flex: 1;
3008
+ overflow: hidden;
3009
+ text-overflow: ellipsis;
3010
+ white-space: nowrap;
3011
+ cursor: text;
3012
+ font-family: var(--font-mono);
3013
+ font-size: 11px;
3014
+ outline: none;
3015
+ }
3016
+ .pp-item.on .pp-name { color: var(--fg); }
3017
+ .pp-item .pp-count {
3018
+ font-size: 9px;
3019
+ color: var(--fg-mute);
3020
+ font-family: var(--font-mono);
3021
+ letter-spacing: 0.05em;
3022
+ font-feature-settings: 'tnum';
3023
+ }
3024
+ .pp-item.on .pp-count {
3025
+ color: var(--accent-warm);
3026
+ opacity: 0.85;
3027
+ }
3028
+ .pp-item .pp-del {
3029
+ background: transparent;
3030
+ border: none;
3031
+ color: var(--fg-mute);
3032
+ cursor: pointer;
3033
+ padding: 0 2px;
3034
+ font-size: 11px;
3035
+ opacity: 0.4;
3036
+ font-family: var(--font-mono);
3037
+ transition: opacity 0.15s, color 0.15s;
3038
+ }
3039
+ .pp-item .pp-del:hover { color: var(--accent-pink); opacity: 1; }
3040
+
3041
+ .pp-empty {
3042
+ font-family: var(--font-mono);
3043
+ font-size: 10px;
3044
+ color: var(--fg-mute);
3045
+ text-align: center;
3046
+ padding: 10px 4px;
3047
+ line-height: 1.7;
3048
+ letter-spacing: 0.02em;
3049
+ }
3050
+
3051
+ /* ─── Context panel active-set block ──────────────────── */
3052
+ .ctx-active-block {
3053
+ margin-top: 16px;
3054
+ padding-top: 14px;
3055
+ border-top: 1px solid var(--border-edge);
3056
+ position: relative;
3057
+ }
3058
+ .ctx-active-block::before {
3059
+ content: '';
3060
+ position: absolute;
3061
+ top: -1px; left: 0;
3062
+ width: 14px; height: 1px;
3063
+ background: var(--accent-warm);
3064
+ }
3065
+ .ctx-star-btn {
3066
+ width: 100%;
3067
+ padding: 8px 12px;
3068
+ background: transparent;
3069
+ border: 1px solid rgba(255, 200, 80, 0.3);
3070
+ color: rgba(255, 200, 80, 0.85);
3071
+ border-radius: var(--radius);
3072
+ font: inherit;
3073
+ font-family: var(--font-mono);
3074
+ font-size: 11px;
3075
+ cursor: pointer;
3076
+ letter-spacing: 0.05em;
3077
+ transition: all 0.2s var(--ease-out);
3078
+ text-transform: uppercase;
3079
+ }
3080
+ .ctx-star-btn:hover {
3081
+ background: rgba(255, 200, 80, 0.06);
3082
+ color: var(--accent-warm);
3083
+ border-color: var(--accent-warm);
3084
+ }
3085
+ .ctx-star-btn.on {
3086
+ background: rgba(255, 200, 80, 0.12);
3087
+ border-color: var(--accent-warm);
3088
+ color: var(--accent-warm);
3089
+ box-shadow: 0 0 16px rgba(255, 200, 80, 0.15);
3090
+ }
3091
+ .ctx-pipe-membership {
3092
+ margin-top: 10px;
3093
+ font-family: var(--font-mono);
3094
+ font-size: 10px;
3095
+ color: var(--fg-mute);
3096
+ letter-spacing: 0.04em;
3097
+ }
3098
+ .ctx-pipe-tag {
3099
+ display: inline-block;
3100
+ margin: 4px 4px 0 0;
3101
+ padding: 2px 8px;
3102
+ background: rgba(255, 200, 80, 0.08);
3103
+ border: 1px solid rgba(255, 200, 80, 0.2);
3104
+ border-radius: var(--radius);
3105
+ color: var(--accent-warm);
3106
+ font-size: 10px;
3107
+ letter-spacing: 0.04em;
3108
+ }
3109
+ .ctx-pipe-select {
3110
+ margin-top: 10px;
3111
+ width: 100%;
3112
+ background: rgba(0, 0, 0, 0.3);
3113
+ border: 1px solid var(--border);
3114
+ border-radius: var(--radius);
3115
+ padding: 6px 10px;
3116
+ color: var(--fg);
3117
+ font: inherit;
3118
+ font-family: var(--font-mono);
3119
+ font-size: 10.5px;
3120
+ cursor: pointer;
3121
+ letter-spacing: 0.02em;
3122
+ transition: border-color 0.18s;
3123
+ }
3124
+ .ctx-pipe-select:hover { border-color: var(--border-hot); }
3125
+
3126
+ /* (removed) tree-collapsed pipelines reposition — pipelines is now inside leftRail flex flow */
3127
+ body.no-folder #pipelinesPanel { display: none; }
3128
+
3129
+ /* ═══════════════════════════════════════════════════════
3130
+ Theme-driven global overrides
3131
+ These reach across all panels to enforce theme rules
3132
+ without rewriting every component.
3133
+ ═══════════════════════════════════════════════════════ */
3134
+
3135
+ /* Hide corner brackets when --decoration is 0 (minimal/terminal) */
3136
+ body[data-theme="minimal"] #contextPanel::before,
3137
+ body[data-theme="minimal"] #contextPanel::after,
3138
+ body[data-theme="minimal"] #inspector::before,
3139
+ body[data-theme="minimal"] #inspector::after,
3140
+ body[data-theme="minimal"] #minimapWrap::before,
3141
+ body[data-theme="minimal"] #minimapWrap::after,
3142
+ body[data-theme="minimal"] #pipelinesPanel::before,
3143
+ body[data-theme="minimal"] #pipelinesPanel::after,
3144
+ body[data-theme="minimal"] .folder-btn::before,
3145
+ body[data-theme="minimal"] .folder-btn::after,
3146
+ body[data-theme="minimal"] .frame-corner,
3147
+ body[data-theme="terminal"] #contextPanel::before,
3148
+ body[data-theme="terminal"] #contextPanel::after,
3149
+ body[data-theme="terminal"] #inspector::before,
3150
+ body[data-theme="terminal"] #inspector::after,
3151
+ body[data-theme="terminal"] #minimapWrap::before,
3152
+ body[data-theme="terminal"] #minimapWrap::after,
3153
+ body[data-theme="terminal"] #pipelinesPanel::before,
3154
+ body[data-theme="terminal"] #pipelinesPanel::after,
3155
+ body[data-theme="terminal"] .folder-btn::before,
3156
+ body[data-theme="terminal"] .folder-btn::after,
3157
+ body[data-theme="terminal"] .frame-corner {
3158
+ display: none;
3159
+ }
3160
+
3161
+ /* Hide bracket characters around brand label in minimal/terminal */
3162
+ body[data-theme="minimal"] .brand .label::before,
3163
+ body[data-theme="minimal"] .brand .label::after,
3164
+ body[data-theme="terminal"] .brand .label::before,
3165
+ body[data-theme="terminal"] .brand .label::after {
3166
+ content: none;
3167
+ }
3168
+ body[data-theme="minimal"] .welcome-bracket,
3169
+ body[data-theme="terminal"] .welcome-bracket {
3170
+ display: none;
3171
+ }
3172
+
3173
+ /* Hide ASCII divider in minimal/terminal welcome */
3174
+ body[data-theme="minimal"] .welcome-divider,
3175
+ body[data-theme="terminal"] .welcome-divider {
3176
+ display: none;
3177
+ }
3178
+ body[data-theme="minimal"] .welcome-meta,
3179
+ body[data-theme="terminal"] .welcome-meta {
3180
+ display: none;
3181
+ }
3182
+ body[data-theme="minimal"] .recent-label::before,
3183
+ body[data-theme="minimal"] .recent-label::after,
3184
+ body[data-theme="terminal"] .recent-label::before,
3185
+ body[data-theme="terminal"] .recent-label::after {
3186
+ content: none;
3187
+ }
3188
+ body[data-theme="minimal"] .hint-dim,
3189
+ body[data-theme="terminal"] .hint-dim {
3190
+ display: none;
3191
+ }
3192
+
3193
+ /* Theme: Minimal — soften everything */
3194
+ body[data-theme="minimal"] .welcome-frame {
3195
+ border: none;
3196
+ background: transparent;
3197
+ backdrop-filter: none;
3198
+ }
3199
+ body[data-theme="minimal"] .welcome-title {
3200
+ font-family: var(--font-display);
3201
+ font-weight: 300;
3202
+ letter-spacing: 0.02em;
3203
+ font-size: 32px;
3204
+ text-transform: none;
3205
+ }
3206
+ body[data-theme="minimal"] .welcome-title .accent {
3207
+ font-weight: 600;
3208
+ }
3209
+ body[data-theme="minimal"] .brand .label {
3210
+ font-weight: 500;
3211
+ letter-spacing: 0.08em;
3212
+ font-family: var(--font-display);
3213
+ text-transform: none;
3214
+ font-size: 13px;
3215
+ }
3216
+ body[data-theme="minimal"] .brand .dot {
3217
+ border-radius: 50%;
3218
+ animation: none;
3219
+ width: 8px; height: 8px;
3220
+ }
3221
+ body[data-theme="minimal"] .kicker,
3222
+ body[data-theme="minimal"] .ctx-kicker,
3223
+ body[data-theme="minimal"] .pp-head .kicker,
3224
+ body[data-theme="minimal"] .ctx-head .kicker,
3225
+ body[data-theme="minimal"] .inspector-kicker {
3226
+ letter-spacing: 0.1em;
3227
+ font-size: 10.5px;
3228
+ }
3229
+ body[data-theme="minimal"] .welcome-constellation {
3230
+ opacity: 0.25;
3231
+ animation: none;
3232
+ }
3233
+ body[data-theme="minimal"] .primary-btn {
3234
+ background: var(--accent);
3235
+ color: var(--bg);
3236
+ border-color: var(--accent);
3237
+ text-transform: none;
3238
+ letter-spacing: 0.04em;
3239
+ font-weight: 500;
3240
+ }
3241
+ body[data-theme="minimal"] .primary-btn:hover {
3242
+ filter: brightness(1.1);
3243
+ background: var(--accent);
3244
+ }
3245
+ body[data-theme="minimal"] .btn-icon { display: none; }
3246
+ body[data-theme="minimal"] .recent-item { direction: ltr; }
3247
+
3248
+ /* Theme: Terminal — strict monochrome */
3249
+ body[data-theme="terminal"] .welcome-frame {
3250
+ border: 1px solid var(--border);
3251
+ background: var(--bg-glass);
3252
+ }
3253
+ body[data-theme="terminal"] .welcome-title {
3254
+ font-family: var(--font-display);
3255
+ font-weight: 700;
3256
+ letter-spacing: 0.04em;
3257
+ text-transform: lowercase;
3258
+ font-size: 26px;
3259
+ }
3260
+ body[data-theme="terminal"] .brand .dot {
3261
+ border-radius: 50%;
3262
+ animation: none;
3263
+ }
3264
+ body[data-theme="terminal"] .welcome-constellation {
3265
+ opacity: 0.25;
3266
+ animation: none;
3267
+ }
3268
+ body[data-theme="terminal"] .primary-btn {
3269
+ background: var(--accent);
3270
+ color: var(--bg);
3271
+ text-transform: none;
3272
+ letter-spacing: 0.02em;
3273
+ font-weight: 500;
3274
+ }
3275
+ body[data-theme="terminal"] .primary-btn:hover {
3276
+ background: var(--accent);
3277
+ filter: brightness(1.15);
3278
+ }
3279
+ body[data-theme="terminal"] .btn-icon { display: none; }
3280
+
3281
+ /* Theme: Maximal — louder accents */
3282
+ body[data-theme="maximal"] .brand .dot {
3283
+ width: 8px; height: 8px;
3284
+ box-shadow:
3285
+ 0 0 0 1px var(--bg),
3286
+ 0 0 16px var(--accent),
3287
+ 0 0 32px var(--accent),
3288
+ 0 0 48px var(--accent-warm);
3289
+ }
3290
+ body[data-theme="maximal"] .welcome-title {
3291
+ background: linear-gradient(90deg, var(--accent) 0%, var(--accent-warm) 50%, var(--accent-cool) 100%);
3292
+ -webkit-background-clip: text;
3293
+ -webkit-text-fill-color: transparent;
3294
+ background-clip: text;
3295
+ font-size: 32px;
3296
+ }
3297
+ body[data-theme="maximal"] .welcome-title .accent,
3298
+ body[data-theme="maximal"] .welcome-bracket {
3299
+ -webkit-text-fill-color: initial;
3300
+ }
3301
+ body[data-theme="maximal"] .welcome-constellation {
3302
+ filter: drop-shadow(0 0 12px var(--accent)) drop-shadow(0 0 24px var(--accent-warm));
3303
+ }
3304
+ body[data-theme="maximal"] .primary-btn {
3305
+ background: linear-gradient(135deg, var(--accent), var(--accent-warm));
3306
+ color: var(--bg);
3307
+ border: none;
3308
+ font-weight: 700;
3309
+ box-shadow:
3310
+ 0 0 0 1px var(--accent),
3311
+ 0 0 32px rgba(255, 85, 187, 0.4);
3312
+ }
3313
+ body[data-theme="maximal"] .primary-btn:hover {
3314
+ background: linear-gradient(135deg, var(--accent-warm), var(--accent));
3315
+ box-shadow:
3316
+ 0 0 0 1px var(--accent-warm),
3317
+ 0 0 48px rgba(255, 215, 0, 0.5);
3318
+ }
3319
+
3320
+ /* Adjust grain overlay per theme */
3321
+ body::before { opacity: var(--grain); }
3322
+
3323
+ /* Disable ambient animations when motion-scale = 0 or low */
3324
+ body[data-theme="minimal"] .brand .dot,
3325
+ body[data-theme="minimal"] .welcome-constellation,
3326
+ body[data-theme="terminal"] .brand .dot,
3327
+ body[data-theme="terminal"] .welcome-constellation {
3328
+ animation: none;
3329
+ }
3330
+
3331
+ /* ─── Theme selection grid ─────────────────────────────── */
3332
+ .theme-grid {
3333
+ display: grid;
3334
+ grid-template-columns: 1fr 1fr;
3335
+ gap: 8px;
3336
+ }
3337
+ .theme-card {
3338
+ display: flex;
3339
+ flex-direction: column;
3340
+ align-items: flex-start;
3341
+ gap: 6px;
3342
+ padding: 10px 12px;
3343
+ background: transparent;
3344
+ border: 1px solid var(--border);
3345
+ border-radius: var(--radius);
3346
+ color: var(--fg);
3347
+ font: inherit;
3348
+ font-family: var(--font-mono);
3349
+ text-align: left;
3350
+ cursor: pointer;
3351
+ transition: all 0.18s var(--ease-out);
3352
+ position: relative;
3353
+ }
3354
+ .theme-card:hover {
3355
+ border-color: var(--border-hot);
3356
+ background: rgba(126, 207, 207, 0.04);
3357
+ }
3358
+ .theme-card.active {
3359
+ border-color: var(--accent);
3360
+ background: rgba(126, 207, 207, 0.08);
3361
+ }
3362
+ .theme-card.active::after {
3363
+ content: '✓';
3364
+ position: absolute;
3365
+ top: 8px; right: 10px;
3366
+ color: var(--accent);
3367
+ font-size: 11px;
3368
+ }
3369
+ .theme-swatches {
3370
+ display: flex;
3371
+ gap: 3px;
3372
+ }
3373
+ .theme-sw {
3374
+ width: 14px; height: 14px;
3375
+ border-radius: var(--radius);
3376
+ display: inline-block;
3377
+ box-shadow: 0 0 0 1px rgba(255,255,255,0.05);
3378
+ }
3379
+ .theme-name {
3380
+ font-size: 11.5px;
3381
+ font-weight: 600;
3382
+ letter-spacing: 0.02em;
3383
+ color: var(--fg);
3384
+ }
3385
+ .theme-desc {
3386
+ font-size: 9.5px;
3387
+ color: var(--fg-mute);
3388
+ letter-spacing: 0.04em;
3389
+ }
3390
+
3391
+ /* ═══════════════════════════════════════════════════════
3392
+ Decoration overrides for new themes (carbon/mono/daylight)
3393
+ ═══════════════════════════════════════════════════════ */
3394
+
3395
+ /* Carbon / Mono / Daylight: no corner brackets */
3396
+ body[data-theme="carbon"] #contextPanel::before,
3397
+ body[data-theme="carbon"] #contextPanel::after,
3398
+ body[data-theme="carbon"] #inspector::before,
3399
+ body[data-theme="carbon"] #inspector::after,
3400
+ body[data-theme="carbon"] #minimapWrap::before,
3401
+ body[data-theme="carbon"] #minimapWrap::after,
3402
+ body[data-theme="carbon"] #pipelinesPanel::before,
3403
+ body[data-theme="carbon"] #pipelinesPanel::after,
3404
+ body[data-theme="carbon"] .folder-btn::before,
3405
+ body[data-theme="carbon"] .folder-btn::after,
3406
+ body[data-theme="carbon"] .frame-corner,
3407
+ body[data-theme="mono"] #contextPanel::before,
3408
+ body[data-theme="mono"] #contextPanel::after,
3409
+ body[data-theme="mono"] #inspector::before,
3410
+ body[data-theme="mono"] #inspector::after,
3411
+ body[data-theme="mono"] #minimapWrap::before,
3412
+ body[data-theme="mono"] #minimapWrap::after,
3413
+ body[data-theme="mono"] #pipelinesPanel::before,
3414
+ body[data-theme="mono"] #pipelinesPanel::after,
3415
+ body[data-theme="mono"] .folder-btn::before,
3416
+ body[data-theme="mono"] .folder-btn::after,
3417
+ body[data-theme="mono"] .frame-corner,
3418
+ body[data-theme="daylight"] #contextPanel::before,
3419
+ body[data-theme="daylight"] #contextPanel::after,
3420
+ body[data-theme="daylight"] #inspector::before,
3421
+ body[data-theme="daylight"] #inspector::after,
3422
+ body[data-theme="daylight"] #minimapWrap::before,
3423
+ body[data-theme="daylight"] #minimapWrap::after,
3424
+ body[data-theme="daylight"] #pipelinesPanel::before,
3425
+ body[data-theme="daylight"] #pipelinesPanel::after,
3426
+ body[data-theme="daylight"] .folder-btn::before,
3427
+ body[data-theme="daylight"] .folder-btn::after,
3428
+ body[data-theme="daylight"] .frame-corner {
3429
+ display: none;
3430
+ }
3431
+
3432
+ body[data-theme="carbon"] .brand .label::before,
3433
+ body[data-theme="carbon"] .brand .label::after,
3434
+ body[data-theme="mono"] .brand .label::before,
3435
+ body[data-theme="mono"] .brand .label::after,
3436
+ body[data-theme="daylight"] .brand .label::before,
3437
+ body[data-theme="daylight"] .brand .label::after {
3438
+ content: none;
3439
+ }
3440
+ body[data-theme="carbon"] .welcome-bracket,
3441
+ body[data-theme="mono"] .welcome-bracket,
3442
+ body[data-theme="daylight"] .welcome-bracket {
3443
+ display: none;
3444
+ }
3445
+ body[data-theme="carbon"] .welcome-divider,
3446
+ body[data-theme="mono"] .welcome-divider,
3447
+ body[data-theme="daylight"] .welcome-divider,
3448
+ body[data-theme="mono"] .welcome-meta,
3449
+ body[data-theme="daylight"] .welcome-meta {
3450
+ display: none;
3451
+ }
3452
+ body[data-theme="carbon"] .recent-label::before,
3453
+ body[data-theme="carbon"] .recent-label::after,
3454
+ body[data-theme="mono"] .recent-label::before,
3455
+ body[data-theme="mono"] .recent-label::after,
3456
+ body[data-theme="daylight"] .recent-label::before,
3457
+ body[data-theme="daylight"] .recent-label::after {
3458
+ content: none;
3459
+ }
3460
+ body[data-theme="carbon"] .hint-dim,
3461
+ body[data-theme="mono"] .hint-dim,
3462
+ body[data-theme="daylight"] .hint-dim {
3463
+ display: none;
3464
+ }
3465
+
3466
+ /* ─── Theme: Carbon — classic terminal feel ───────────── */
3467
+ body[data-theme="carbon"] {
3468
+ /* Scan-line texture overlay subtly hints at CRT */
3469
+ background-image:
3470
+ repeating-linear-gradient(0deg, rgba(80, 220, 100, 0.012) 0px, rgba(80, 220, 100, 0.012) 1px, transparent 1px, transparent 3px);
3471
+ }
3472
+ body[data-theme="carbon"] .welcome-frame {
3473
+ border: 1px solid var(--accent);
3474
+ background: rgba(0, 0, 0, 0.6);
3475
+ backdrop-filter: none;
3476
+ }
3477
+ body[data-theme="carbon"] .welcome-frame::before {
3478
+ /* A prefix line like a terminal prompt */
3479
+ content: '$ cs init';
3480
+ position: absolute;
3481
+ top: 12px; left: 16px;
3482
+ font-family: var(--font-mono);
3483
+ font-size: 9.5px;
3484
+ color: var(--accent);
3485
+ opacity: 0.6;
3486
+ letter-spacing: 0.04em;
3487
+ }
3488
+ body[data-theme="carbon"] .welcome-title {
3489
+ font-family: var(--font-mono);
3490
+ font-weight: 700;
3491
+ letter-spacing: 0.04em;
3492
+ text-transform: lowercase;
3493
+ font-size: 26px;
3494
+ color: var(--accent);
3495
+ text-shadow: 0 0 12px rgba(80, 220, 100, 0.4);
3496
+ }
3497
+ body[data-theme="carbon"] .welcome-title .accent {
3498
+ color: var(--accent);
3499
+ opacity: 0.7;
3500
+ }
3501
+ body[data-theme="carbon"] .welcome-sub {
3502
+ color: var(--fg-dim);
3503
+ }
3504
+ body[data-theme="carbon"] .brand .dot {
3505
+ border-radius: 0;
3506
+ width: 6px; height: 6px;
3507
+ animation: phosphorPulse 1.6s steps(4) infinite;
3508
+ }
3509
+ @keyframes phosphorPulse {
3510
+ 0%, 50% { opacity: 1; box-shadow: 0 0 12px var(--accent); }
3511
+ 51%, 100% { opacity: 0.3; box-shadow: 0 0 4px var(--accent); }
3512
+ }
3513
+ body[data-theme="carbon"] .welcome-constellation {
3514
+ opacity: 0.5;
3515
+ color: var(--accent);
3516
+ filter: drop-shadow(0 0 6px var(--accent));
3517
+ }
3518
+ body[data-theme="carbon"] .primary-btn {
3519
+ background: var(--accent);
3520
+ color: #000;
3521
+ border-color: var(--accent);
3522
+ text-transform: lowercase;
3523
+ letter-spacing: 0.04em;
3524
+ font-weight: 700;
3525
+ text-shadow: none;
3526
+ }
3527
+ body[data-theme="carbon"] .primary-btn::before { content: '> '; opacity: 0.7; }
3528
+ body[data-theme="carbon"] .primary-btn:hover {
3529
+ background: #6FF080;
3530
+ box-shadow: 0 0 24px var(--accent);
3531
+ }
3532
+ body[data-theme="carbon"] .btn-icon { display: none; }
3533
+ body[data-theme="carbon"] .btn-key {
3534
+ background: rgba(0,0,0,0.4);
3535
+ border: 1px solid var(--accent);
3536
+ color: var(--accent);
3537
+ }
3538
+ body[data-theme="carbon"] .ctx-title,
3539
+ body[data-theme="carbon"] .kicker {
3540
+ color: var(--accent);
3541
+ text-shadow: 0 0 4px rgba(80, 220, 100, 0.3);
3542
+ }
3543
+
3544
+ /* ─── Theme: Mono — Tokyo Night warmth ────────────────── */
3545
+ body[data-theme="mono"] .welcome-frame {
3546
+ border: 1px solid var(--border);
3547
+ background: var(--bg-glass);
3548
+ }
3549
+ body[data-theme="mono"] .welcome-title {
3550
+ font-family: var(--font-display);
3551
+ font-weight: 600;
3552
+ letter-spacing: 0.04em;
3553
+ text-transform: lowercase;
3554
+ font-size: 28px;
3555
+ }
3556
+ body[data-theme="mono"] .brand .dot {
3557
+ border-radius: 50%;
3558
+ animation: none;
3559
+ }
3560
+ body[data-theme="mono"] .welcome-constellation {
3561
+ opacity: 0.4;
3562
+ animation: none;
3563
+ }
3564
+ body[data-theme="mono"] .primary-btn {
3565
+ background: var(--accent);
3566
+ color: var(--bg);
3567
+ border-color: var(--accent);
3568
+ text-transform: none;
3569
+ letter-spacing: 0.02em;
3570
+ font-weight: 500;
3571
+ }
3572
+ body[data-theme="mono"] .primary-btn:hover {
3573
+ filter: brightness(1.15);
3574
+ }
3575
+ body[data-theme="mono"] .btn-icon { display: none; }
3576
+
3577
+ /* ─── Theme: Daylight — light mode ────────────────────── */
3578
+ body[data-theme="daylight"] {
3579
+ background: var(--bg);
3580
+ color: var(--fg);
3581
+ }
3582
+ /* Override the grain overlay in light mode — it would be ugly */
3583
+ body[data-theme="daylight"]::before {
3584
+ opacity: 0 !important;
3585
+ }
3586
+ body[data-theme="daylight"] #topbar {
3587
+ background: linear-gradient(180deg, rgba(255,255,255,0.85), rgba(255,255,255,0.55));
3588
+ border-bottom: 1px solid var(--border);
3589
+ }
3590
+ body[data-theme="daylight"] #topbar::after {
3591
+ background: linear-gradient(90deg, transparent, rgba(9,105,218,0.18) 50%, transparent);
3592
+ }
3593
+ body[data-theme="daylight"] #welcome {
3594
+ background:
3595
+ radial-gradient(ellipse 80% 50% at center, rgba(9, 105, 218, 0.04), transparent 60%),
3596
+ linear-gradient(180deg, #FFFFFF 0%, #F5F5F7 100%);
3597
+ }
3598
+ body[data-theme="daylight"] .welcome-frame {
3599
+ border: 1px solid var(--border);
3600
+ background: rgba(255, 255, 255, 0.6);
3601
+ backdrop-filter: blur(10px);
3602
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.06);
3603
+ }
3604
+ body[data-theme="daylight"] .welcome-title {
3605
+ font-family: var(--font-display);
3606
+ font-weight: 700;
3607
+ letter-spacing: 0.02em;
3608
+ text-transform: lowercase;
3609
+ color: var(--fg);
3610
+ font-size: 30px;
3611
+ }
3612
+ body[data-theme="daylight"] .welcome-sub { color: var(--fg-mute); }
3613
+ body[data-theme="daylight"] .brand .dot {
3614
+ border-radius: 50%;
3615
+ animation: none;
3616
+ }
3617
+ body[data-theme="daylight"] .welcome-constellation {
3618
+ opacity: 0.5;
3619
+ animation: none;
3620
+ }
3621
+ body[data-theme="daylight"] .primary-btn {
3622
+ background: var(--accent);
3623
+ color: #FFFFFF;
3624
+ border-color: var(--accent);
3625
+ text-transform: none;
3626
+ letter-spacing: 0.02em;
3627
+ font-weight: 500;
3628
+ }
3629
+ body[data-theme="daylight"] .primary-btn:hover {
3630
+ background: #0860C7;
3631
+ }
3632
+ body[data-theme="daylight"] .btn-icon { display: none; }
3633
+
3634
+ body[data-theme="daylight"] #contextPanel,
3635
+ body[data-theme="daylight"] #inspector,
3636
+ body[data-theme="daylight"] #minimapWrap,
3637
+ body[data-theme="daylight"] #pipelinesPanel,
3638
+ body[data-theme="daylight"] #settings,
3639
+ body[data-theme="daylight"] #statsPanel {
3640
+ background: rgba(255, 255, 255, 0.92);
3641
+ backdrop-filter: blur(14px) saturate(160%);
3642
+ box-shadow:
3643
+ 0 1px 0 rgba(0,0,0,0.04),
3644
+ 0 12px 40px rgba(0, 0, 0, 0.08);
3645
+ }
3646
+
3647
+ body[data-theme="daylight"] .filter-badge {
3648
+ background: rgba(9, 105, 218, 0.06);
3649
+ color: var(--accent);
3650
+ }
3651
+
3652
+ body[data-theme="daylight"] #search,
3653
+ body[data-theme="daylight"] #searchbar button {
3654
+ background: rgba(255, 255, 255, 0.85);
3655
+ }
3656
+ body[data-theme="daylight"] #search:focus {
3657
+ background: #FFFFFF;
3658
+ }
3659
+
3660
+ body[data-theme="daylight"] .hint-key {
3661
+ background: rgba(9, 105, 218, 0.08);
3662
+ border-color: rgba(9, 105, 218, 0.15);
3663
+ }
3664
+
3665
+ body[data-theme="daylight"] .node-label {
3666
+ color: #1A1A1A;
3667
+ text-shadow:
3668
+ 0 1px 4px rgba(255, 255, 255, 0.8),
3669
+ 0 0 8px rgba(255, 255, 255, 0.6);
3670
+ }
3671
+
3672
+ /* Drop overlay in light mode — light over dark canvas */
3673
+ body[data-theme="daylight"] #dropOverlay {
3674
+ background: rgba(255, 255, 255, 0.92);
3675
+ }
3676
+ body[data-theme="daylight"] .drop-message {
3677
+ color: var(--accent);
3678
+ }
3679
+
3680
+ /* ─── Packages panel (monorepo) ─────────────────────────────── */
3681
+ #packages {
3682
+ grid-area: can;
3683
+ align-self: stretch;
3684
+ justify-self: stretch;
3685
+ margin: 60px 12px 12px 12px;
3686
+ background: var(--bg-glass);
3687
+ border: 1px solid var(--border-hot);
3688
+ border-radius: var(--radius);
3689
+ backdrop-filter: blur(14px) saturate(140%);
3690
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
3691
+ z-index: 11;
3692
+ display: flex; flex-direction: column;
3693
+ overflow: hidden;
3694
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 16px 48px rgba(0,0,0,0.5);
3695
+ }
3696
+ #packages.hidden { display: none; }
3697
+ .packages-head {
3698
+ display: flex; justify-content: space-between; align-items: center;
3699
+ padding: 12px 16px;
3700
+ border-bottom: 1px solid var(--border-edge);
3701
+ }
3702
+ .packages-head button {
3703
+ background: none; border: none; color: var(--fg-mute);
3704
+ cursor: pointer; font-size: 14px; font-family: var(--font-mono);
3705
+ }
3706
+ .packages-head button:hover { color: var(--accent-pink); }
3707
+ .packages-meta {
3708
+ padding: 8px 16px;
3709
+ font-family: var(--font-mono);
3710
+ font-size: 11px;
3711
+ color: var(--fg-mute);
3712
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3713
+ }
3714
+ .packages-actions {
3715
+ padding: 8px 16px;
3716
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3717
+ }
3718
+ #pkgGroupingToggle.active {
3719
+ background: var(--accent);
3720
+ color: #000;
3721
+ }
3722
+ .packages-list { flex: 1; overflow-y: auto; padding: 4px 0; }
3723
+ .packages-empty {
3724
+ padding: 24px;
3725
+ color: var(--fg-mute);
3726
+ font-size: 12px;
3727
+ text-align: center;
3728
+ }
3729
+ .pkg-row {
3730
+ display: grid;
3731
+ grid-template-columns: 1fr auto;
3732
+ grid-template-rows: auto auto;
3733
+ gap: 2px 12px;
3734
+ padding: 10px 16px;
3735
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3736
+ font-family: var(--font-mono);
3737
+ font-size: 11px;
3738
+ cursor: pointer;
3739
+ }
3740
+ .pkg-row:hover { background: rgba(255,255,255,0.04); }
3741
+ .pkg-row-main {
3742
+ grid-column: 1;
3743
+ display: flex;
3744
+ gap: 8px;
3745
+ align-items: center;
3746
+ }
3747
+ .pkg-icon { opacity: 0.7; }
3748
+ .pkg-name { color: var(--fg); font-weight: 600; }
3749
+ .pkg-lang {
3750
+ font-size: 9px;
3751
+ background: rgba(255,255,255,0.06);
3752
+ padding: 1px 6px;
3753
+ border-radius: 8px;
3754
+ color: var(--fg-mute);
3755
+ }
3756
+ .pkg-path {
3757
+ grid-column: 1;
3758
+ color: var(--fg-mute);
3759
+ font-size: 10px;
3760
+ overflow: hidden;
3761
+ text-overflow: ellipsis;
3762
+ white-space: nowrap;
3763
+ }
3764
+ .pkg-meta {
3765
+ grid-column: 2;
3766
+ grid-row: 1 / span 2;
3767
+ align-self: center;
3768
+ text-align: right;
3769
+ color: var(--accent);
3770
+ font-size: 10px;
3771
+ }
3772
+ .pkg-edges {
3773
+ display: block;
3774
+ color: var(--fg-mute);
3775
+ font-size: 9px;
3776
+ }
3777
+ .package-detail {
3778
+ position: absolute;
3779
+ inset: 0;
3780
+ background: var(--bg-glass);
3781
+ backdrop-filter: blur(14px);
3782
+ overflow-y: auto;
3783
+ padding: 0;
3784
+ z-index: 12;
3785
+ }
3786
+ .package-detail.hidden { display: none; }
3787
+ .pkg-detail-head {
3788
+ display: flex;
3789
+ align-items: center;
3790
+ gap: 12px;
3791
+ padding: 12px 16px;
3792
+ border-bottom: 1px solid var(--border-edge);
3793
+ }
3794
+ .pkg-detail-name { font-weight: 600; font-family: var(--font-mono); }
3795
+ .pkg-detail-lang {
3796
+ font-size: 10px;
3797
+ color: var(--fg-mute);
3798
+ flex: 1;
3799
+ }
3800
+ .pkg-section-title {
3801
+ padding: 12px 16px 6px;
3802
+ font-size: 10px;
3803
+ text-transform: uppercase;
3804
+ letter-spacing: 0.08em;
3805
+ color: var(--fg-mute);
3806
+ }
3807
+ .pkg-declared, .pkg-edges-list, .pkg-files {
3808
+ padding: 0 16px 8px;
3809
+ font-family: var(--font-mono);
3810
+ font-size: 10px;
3811
+ }
3812
+ .pkg-dep, .pkg-edge, .pkg-file {
3813
+ padding: 3px 6px;
3814
+ border-bottom: 1px solid rgba(255,255,255,0.03);
3815
+ cursor: pointer;
3816
+ }
3817
+ .pkg-dep:hover, .pkg-edge:hover, .pkg-file:hover { background: rgba(255,255,255,0.04); }
3818
+ .pkg-dep-kind {
3819
+ font-size: 9px;
3820
+ background: rgba(255,255,255,0.06);
3821
+ padding: 1px 4px;
3822
+ border-radius: 4px;
3823
+ margin-right: 6px;
3824
+ }
3825
+ .pkg-dep-spec { color: var(--fg-mute); }
3826
+ .pkg-edge-pkg { color: var(--accent); }
3827
+ .pkg-edge-from, .pkg-edge-to { color: var(--fg); }
3828
+ .pkg-file-mass {
3829
+ color: var(--accent);
3830
+ margin-right: 6px;
3831
+ }
3832
+
3833
+ /* ─── Legacy / migration audit panel ─────────────────────────── */
3834
+ #legacy {
3835
+ grid-area: can;
3836
+ align-self: stretch;
3837
+ justify-self: stretch;
3838
+ margin: 60px 12px 12px 12px;
3839
+ background: var(--bg-glass);
3840
+ border: 1px solid var(--border-hot);
3841
+ border-radius: var(--radius);
3842
+ backdrop-filter: blur(14px) saturate(140%);
3843
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
3844
+ z-index: 11;
3845
+ display: flex; flex-direction: column;
3846
+ overflow: hidden;
3847
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 16px 48px rgba(0,0,0,0.5);
3848
+ }
3849
+ #legacy.hidden { display: none; }
3850
+ .legacy-head {
3851
+ display: flex; justify-content: space-between; align-items: center;
3852
+ padding: 12px 16px;
3853
+ border-bottom: 1px solid var(--border-edge);
3854
+ }
3855
+ .legacy-head button {
3856
+ background: none; border: none; color: var(--fg-mute);
3857
+ cursor: pointer; font-size: 14px; font-family: var(--font-mono);
3858
+ }
3859
+ .legacy-head button:hover { color: var(--accent-pink); }
3860
+ .legacy-meta {
3861
+ padding: 8px 16px;
3862
+ font-family: var(--font-mono);
3863
+ font-size: 11px;
3864
+ color: var(--fg-mute);
3865
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3866
+ }
3867
+ .legacy-toolbar {
3868
+ display: flex;
3869
+ align-items: center;
3870
+ gap: 12px;
3871
+ padding: 8px 16px;
3872
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3873
+ }
3874
+ .legacy-conf {
3875
+ display: flex; align-items: center; gap: 8px;
3876
+ font-family: var(--font-mono);
3877
+ font-size: 10px;
3878
+ color: var(--fg-mute);
3879
+ }
3880
+ .legacy-conf input[type=range] { width: 120px; }
3881
+ #legacyHighlightBtn.active {
3882
+ background: rgb(220, 110, 30);
3883
+ color: #000;
3884
+ }
3885
+ .legacy-tabs {
3886
+ display: flex;
3887
+ border-bottom: 1px solid var(--border-edge);
3888
+ padding: 0 8px;
3889
+ }
3890
+ .legacy-tab {
3891
+ background: none;
3892
+ border: none;
3893
+ color: var(--fg-mute);
3894
+ font-family: var(--font-mono);
3895
+ font-size: 11px;
3896
+ padding: 10px 12px;
3897
+ cursor: pointer;
3898
+ border-bottom: 2px solid transparent;
3899
+ }
3900
+ .legacy-tab.active {
3901
+ color: var(--fg);
3902
+ border-bottom-color: rgb(220, 110, 30);
3903
+ }
3904
+ .legacy-tab:hover { color: var(--fg); }
3905
+ .legacy-list { flex: 1; overflow-y: auto; padding: 4px 0; }
3906
+ .legacy-empty {
3907
+ padding: 24px;
3908
+ color: var(--fg-mute);
3909
+ font-size: 12px;
3910
+ text-align: center;
3911
+ }
3912
+ .legacy-row {
3913
+ display: grid;
3914
+ grid-template-columns: auto auto 1fr auto;
3915
+ grid-template-rows: auto auto;
3916
+ gap: 2px 8px;
3917
+ padding: 8px 16px;
3918
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3919
+ font-family: var(--font-mono);
3920
+ font-size: 11px;
3921
+ cursor: pointer;
3922
+ align-items: center;
3923
+ }
3924
+ .legacy-row:hover { background: rgba(255,255,255,0.04); }
3925
+ .legacy-conf-pill {
3926
+ padding: 1px 6px;
3927
+ border-radius: 8px;
3928
+ font-size: 9px;
3929
+ font-weight: 600;
3930
+ }
3931
+ .legacy-conf-pill.conf-high { background: rgba(220, 110, 30, 0.4); color: rgb(255, 200, 130); }
3932
+ .legacy-conf-pill.conf-med { background: rgba(200, 180, 80, 0.3); color: rgb(230, 220, 130); }
3933
+ .legacy-conf-pill.conf-low { background: rgba(120, 120, 120, 0.25); color: rgb(200, 200, 200); }
3934
+ .legacy-tag {
3935
+ padding: 1px 6px;
3936
+ border-radius: 4px;
3937
+ font-size: 9px;
3938
+ background: rgba(255,255,255,0.05);
3939
+ color: var(--fg-mute);
3940
+ }
3941
+ .legacy-tag.dup-current { background: rgba(80, 200, 130, 0.2); color: rgb(150, 230, 180); }
3942
+ .legacy-tag.dup-legacy { background: rgba(220, 110, 30, 0.3); color: rgb(255, 200, 130); }
3943
+ .legacy-id {
3944
+ color: var(--fg);
3945
+ overflow: hidden;
3946
+ text-overflow: ellipsis;
3947
+ white-space: nowrap;
3948
+ }
3949
+ .legacy-meta-row { color: var(--fg-mute); font-size: 9px; }
3950
+ .legacy-reason {
3951
+ grid-column: 1 / -1;
3952
+ color: var(--fg-mute);
3953
+ font-size: 10px;
3954
+ padding-left: 12px;
3955
+ border-left: 2px solid rgba(220, 110, 30, 0.3);
3956
+ margin-top: 4px;
3957
+ }
3958
+ .legacy-dup-group {
3959
+ padding: 8px 16px;
3960
+ border-bottom: 1px solid rgba(255,255,255,0.04);
3961
+ }
3962
+ .legacy-dup-name {
3963
+ font-family: var(--font-mono);
3964
+ font-size: 11px;
3965
+ color: var(--accent);
3966
+ margin-bottom: 4px;
3967
+ }
3968
+ .legacy-dup-row {
3969
+ grid-template-columns: auto 1fr auto;
3970
+ padding: 4px 0;
3971
+ border-bottom: none;
3972
+ }
3973
+
3974
+ /* ─── Full AI trace panel ────────────────────────────────────── */
3975
+ .ai-trace-mini {
3976
+ background: none; border: none; color: var(--fg-mute);
3977
+ cursor: pointer; font-family: var(--font-mono); font-size: 11px;
3978
+ margin-left: 4px;
3979
+ }
3980
+ .ai-trace-mini:hover { color: var(--fg); }
3981
+ #traceFull {
3982
+ grid-area: can;
3983
+ align-self: stretch;
3984
+ justify-self: stretch;
3985
+ margin: 60px 12px 12px 12px;
3986
+ background: var(--bg-glass);
3987
+ border: 1px solid var(--border-hot);
3988
+ border-radius: var(--radius);
3989
+ backdrop-filter: blur(14px) saturate(140%);
3990
+ -webkit-backdrop-filter: blur(14px) saturate(140%);
3991
+ z-index: 11;
3992
+ display: flex; flex-direction: column;
3993
+ overflow: hidden;
3994
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 16px 48px rgba(0,0,0,0.5);
3995
+ }
3996
+ #traceFull.hidden { display: none; }
3997
+ .trace-full-head {
3998
+ display: flex; justify-content: space-between; align-items: center;
3999
+ padding: 12px 16px;
4000
+ border-bottom: 1px solid var(--border-edge);
4001
+ }
4002
+ .trace-full-head button {
4003
+ background: none; border: none; color: var(--fg-mute);
4004
+ cursor: pointer; font-family: var(--font-mono); font-size: 14px;
4005
+ }
4006
+ .trace-full-head button:hover { color: var(--accent-pink); }
4007
+ .trace-full-meta {
4008
+ padding: 8px 16px;
4009
+ font-family: var(--font-mono);
4010
+ font-size: 11px;
4011
+ color: var(--fg-mute);
4012
+ border-bottom: 1px solid rgba(255,255,255,0.04);
4013
+ }
4014
+ .trace-full-toolbar {
4015
+ display: flex;
4016
+ gap: 6px;
4017
+ padding: 8px 16px;
4018
+ border-bottom: 1px solid rgba(255,255,255,0.04);
4019
+ flex-wrap: wrap;
4020
+ }
4021
+ .trace-filter {
4022
+ background: rgba(255,255,255,0.04);
4023
+ border: 1px solid var(--border-edge);
4024
+ color: var(--fg);
4025
+ padding: 4px 8px;
4026
+ border-radius: 4px;
4027
+ font-family: var(--font-mono);
4028
+ font-size: 10px;
4029
+ }
4030
+ .trace-tabs {
4031
+ display: flex;
4032
+ border-bottom: 1px solid var(--border-edge);
4033
+ padding: 0 8px;
4034
+ }
4035
+ .trace-tab {
4036
+ background: none; border: none;
4037
+ color: var(--fg-mute);
4038
+ font-family: var(--font-mono);
4039
+ font-size: 11px;
4040
+ padding: 10px 12px;
4041
+ cursor: pointer;
4042
+ border-bottom: 2px solid transparent;
4043
+ }
4044
+ .trace-tab.active { color: var(--fg); border-bottom-color: var(--accent); }
4045
+ .trace-tab:hover { color: var(--fg); }
4046
+ .trace-full-body { flex: 1; overflow-y: auto; padding: 4px 0; }
4047
+ .trace-full-row {
4048
+ display: grid;
4049
+ grid-template-columns: 80px 100px 1fr;
4050
+ gap: 8px;
4051
+ padding: 4px 16px;
4052
+ font-family: var(--font-mono);
4053
+ font-size: 11px;
4054
+ cursor: pointer;
4055
+ border-bottom: 1px solid rgba(255,255,255,0.02);
4056
+ }
4057
+ .trace-full-row:hover { background: rgba(255,255,255,0.04); }
4058
+ .trace-stamp { color: var(--fg-mute); }
4059
+ .trace-tool {
4060
+ font-size: 10px;
4061
+ padding: 1px 6px;
4062
+ border-radius: 4px;
4063
+ background: rgba(255,255,255,0.06);
4064
+ align-self: center;
4065
+ text-align: center;
4066
+ }
4067
+ .trace-tool.tool-read { background: rgba(80, 160, 220, 0.3); }
4068
+ .trace-tool.tool-focus { background: rgba(220, 160, 80, 0.3); }
4069
+ .trace-tool.tool-open { background: rgba(220, 80, 160, 0.3); }
4070
+ .trace-tool.tool-blast { background: rgba(220, 100, 100, 0.4); }
4071
+ .trace-tool.tool-write { background: rgba(120, 220, 100, 0.3); }
4072
+ .trace-tool.tool-deps,
4073
+ .trace-tool.tool-users { background: rgba(160, 120, 220, 0.3); }
4074
+ .trace-tool.tool-package { background: rgba(120, 220, 200, 0.3); }
4075
+ .trace-section-title {
4076
+ padding: 14px 16px 6px;
4077
+ font-size: 10px;
4078
+ text-transform: uppercase;
4079
+ letter-spacing: 0.08em;
4080
+ color: var(--fg-mute);
4081
+ }
4082
+ .trace-stats-list { padding: 4px 16px 12px; }
4083
+ .trace-stat-row {
4084
+ display: grid;
4085
+ grid-template-columns: 100px 50px 1fr;
4086
+ gap: 8px;
4087
+ align-items: center;
4088
+ padding: 3px 0;
4089
+ font-family: var(--font-mono);
4090
+ font-size: 11px;
4091
+ }
4092
+ .trace-stat-label { color: var(--fg); }
4093
+ .trace-stat-count { color: var(--accent); text-align: right; }
4094
+ .trace-stat-bar {
4095
+ background: rgba(255,255,255,0.06);
4096
+ height: 8px;
4097
+ border-radius: 4px;
4098
+ overflow: hidden;
4099
+ }
4100
+ .trace-stat-fill {
4101
+ background: var(--accent);
4102
+ height: 100%;
4103
+ }
4104
+ .trace-timeline {
4105
+ display: flex;
4106
+ align-items: flex-end;
4107
+ gap: 2px;
4108
+ padding: 8px 16px;
4109
+ height: 60px;
4110
+ }
4111
+ .trace-tl-bar {
4112
+ flex: 1;
4113
+ background: linear-gradient(to top, var(--accent), rgba(255,255,255,0.2));
4114
+ border-radius: 2px 2px 0 0;
4115
+ min-height: 2px;
4116
+ }
4117
+ .trace-top-files { padding: 4px 16px; }
4118
+ .trace-top-file {
4119
+ display: grid;
4120
+ grid-template-columns: 50px 1fr;
4121
+ gap: 8px;
4122
+ padding: 4px 0;
4123
+ font-family: var(--font-mono);
4124
+ font-size: 11px;
4125
+ cursor: pointer;
4126
+ border-bottom: 1px solid rgba(255,255,255,0.02);
4127
+ }
4128
+ .trace-top-file:hover { background: rgba(255,255,255,0.04); }
4129
+ .trace-top-count { color: var(--accent); }
4130
+ .trace-session-row {
4131
+ display: grid;
4132
+ grid-template-columns: 160px 1fr auto;
4133
+ gap: 8px;
4134
+ padding: 8px 16px;
4135
+ font-family: var(--font-mono);
4136
+ font-size: 11px;
4137
+ cursor: pointer;
4138
+ border-bottom: 1px solid rgba(255,255,255,0.04);
4139
+ }
4140
+ .trace-session-row:hover { background: rgba(255,255,255,0.04); }
4141
+ .trace-session-meta { color: var(--fg-mute); }
4142
+ .trace-session-cur {
4143
+ background: var(--accent);
4144
+ color: #000;
4145
+ padding: 2px 8px;
4146
+ border-radius: 10px;
4147
+ font-size: 9px;
4148
+ font-weight: 600;
4149
+ }
4150
+
4151
+ /* ─── Inspector editor toolbar ──────────────────────────────── */
4152
+ .ins-editor-actions {
4153
+ display: inline-flex;
4154
+ gap: 8px;
4155
+ align-items: center;
4156
+ margin-left: 12px;
4157
+ font-family: var(--font-mono);
4158
+ font-size: 10px;
4159
+ }
4160
+ .ins-action-btn {
4161
+ background: rgba(255,255,255,0.04);
4162
+ border: 1px solid var(--border-edge);
4163
+ color: var(--fg);
4164
+ padding: 2px 8px;
4165
+ border-radius: 3px;
4166
+ font-family: var(--font-mono);
4167
+ font-size: 10px;
4168
+ cursor: pointer;
4169
+ }
4170
+ .ins-action-btn:hover { background: rgba(255,255,255,0.08); border-color: var(--accent); }
4171
+ .ins-autosave-label {
4172
+ display: inline-flex;
4173
+ align-items: center;
4174
+ gap: 4px;
4175
+ color: var(--fg-mute);
4176
+ cursor: pointer;
4177
+ user-select: none;
4178
+ }
4179
+ .ins-autosave-label input { margin: 0; }
4180
+ .ins-save-status.warn { color: rgb(220, 180, 80); }
4181
+
4182
+ /* ─── Diff modal ─────────────────────────────────────────────── */
4183
+ .diff-modal {
4184
+ position: fixed;
4185
+ inset: 0;
4186
+ z-index: 100;
4187
+ background: rgba(0,0,0,0.7);
4188
+ display: flex;
4189
+ align-items: center;
4190
+ justify-content: center;
4191
+ backdrop-filter: blur(6px);
4192
+ }
4193
+ .diff-modal.hidden { display: none; }
4194
+ .diff-modal-inner {
4195
+ width: 80%;
4196
+ max-width: 900px;
4197
+ height: 80vh;
4198
+ background: var(--bg);
4199
+ border: 1px solid var(--border-hot);
4200
+ border-radius: var(--radius);
4201
+ display: flex;
4202
+ flex-direction: column;
4203
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 24px 64px rgba(0,0,0,0.7);
4204
+ outline: none;
4205
+ }
4206
+ .diff-modal-head {
4207
+ display: flex;
4208
+ align-items: center;
4209
+ gap: 12px;
4210
+ padding: 12px 16px;
4211
+ border-bottom: 1px solid var(--border-edge);
4212
+ }
4213
+ .diff-modal-id {
4214
+ flex: 1;
4215
+ font-family: var(--font-mono);
4216
+ font-size: 11px;
4217
+ color: var(--fg);
4218
+ overflow: hidden;
4219
+ text-overflow: ellipsis;
4220
+ white-space: nowrap;
4221
+ }
4222
+ .diff-modal-stat {
4223
+ font-family: var(--font-mono);
4224
+ font-size: 11px;
4225
+ }
4226
+ .dm-add { color: rgb(120, 220, 100); }
4227
+ .dm-del { color: rgb(255, 120, 120); }
4228
+ .diff-close {
4229
+ background: none; border: none; color: var(--fg-mute);
4230
+ cursor: pointer; font-size: 14px; font-family: var(--font-mono);
4231
+ }
4232
+ .diff-close:hover { color: var(--accent-pink); }
4233
+ .diff-modal-body {
4234
+ flex: 1;
4235
+ overflow-y: auto;
4236
+ font-family: var(--font-mono);
4237
+ font-size: 11px;
4238
+ padding: 8px 0;
4239
+ background: rgba(0,0,0,0.3);
4240
+ }
4241
+ .diff-line {
4242
+ display: grid;
4243
+ grid-template-columns: 80px 18px 1fr;
4244
+ padding: 1px 16px;
4245
+ white-space: pre;
4246
+ }
4247
+ .diff-line.diff-add { background: rgba(80, 220, 100, 0.08); color: rgb(160, 240, 160); }
4248
+ .diff-line.diff-del { background: rgba(220, 80, 80, 0.08); color: rgb(240, 160, 160); }
4249
+ .diff-line.diff-eq { color: var(--fg-mute); }
4250
+ .diff-num {
4251
+ color: rgba(255,255,255,0.3);
4252
+ text-align: right;
4253
+ padding-right: 8px;
4254
+ font-size: 10px;
4255
+ }
4256
+ .diff-sign {
4257
+ text-align: center;
4258
+ font-weight: 600;
4259
+ }
4260
+ .diff-text { overflow-x: auto; }
4261
+ .diff-modal-foot {
4262
+ display: flex;
4263
+ align-items: center;
4264
+ gap: 12px;
4265
+ padding: 12px 16px;
4266
+ border-top: 1px solid var(--border-edge);
4267
+ }
4268
+ .diff-btn {
4269
+ background: rgba(255,255,255,0.06);
4270
+ border: 1px solid var(--border-edge);
4271
+ color: var(--fg);
4272
+ padding: 6px 16px;
4273
+ border-radius: 4px;
4274
+ font-family: var(--font-mono);
4275
+ font-size: 11px;
4276
+ cursor: pointer;
4277
+ }
4278
+ .diff-btn:hover { border-color: var(--accent); }
4279
+ .diff-btn.primary {
4280
+ background: var(--accent);
4281
+ color: #000;
4282
+ border-color: var(--accent);
4283
+ }
4284
+ .diff-btn.primary:hover { filter: brightness(1.1); }
4285
+ .diff-skip {
4286
+ margin-left: auto;
4287
+ font-family: var(--font-mono);
4288
+ font-size: 10px;
4289
+ color: var(--fg-mute);
4290
+ cursor: pointer;
4291
+ display: inline-flex;
4292
+ align-items: center;
4293
+ gap: 6px;
4294
+ }
4295
+
4296
+ /* ─── View cube (camera orientation widget) ──────────────────── */
4297
+ #viewCubeCanvas {
4298
+ position: fixed;
4299
+ /* Bottom-left of main canvas, clear of the left rail (--rail-w) */
4300
+ left: calc(var(--rail-w) + var(--grid-gap) + var(--grid-pad));
4301
+ bottom: calc(var(--statusbar-h) + 14px);
4302
+ width: 96px;
4303
+ height: 96px;
4304
+ z-index: 12;
4305
+ pointer-events: auto;
4306
+ cursor: grab;
4307
+ background: transparent;
4308
+ border: none;
4309
+ backdrop-filter: none;
4310
+ }
4311
+ #viewCubeCanvas:active { cursor: grabbing; }
4312
+ /* When left rail is hidden, snap to absolute bottom-left */
4313
+ body.no-folder #viewCubeCanvas { display: none; }
4314
+
4315
+ /* ─── Vertical zoom slider (left edge of canvas) ─────────────── */
4316
+ #zoomSliderWrap {
4317
+ position: fixed;
4318
+ left: calc(var(--rail-w) + var(--grid-gap) + 14px);
4319
+ top: 50%;
4320
+ transform: translateY(-50%);
4321
+ z-index: 12;
4322
+ display: flex;
4323
+ flex-direction: column;
4324
+ align-items: center;
4325
+ gap: 4px;
4326
+ background: rgba(0, 0, 0, 0.30);
4327
+ border: 1px solid var(--border-edge);
4328
+ border-radius: 8px;
4329
+ padding: 6px 4px;
4330
+ backdrop-filter: blur(8px);
4331
+ pointer-events: auto;
4332
+ }
4333
+ body.no-folder #zoomSliderWrap { display: none; }
4334
+ .zoom-slider-btn {
4335
+ width: 28px; height: 24px;
4336
+ background: rgba(255,255,255,0.05);
4337
+ border: 1px solid var(--border-edge);
4338
+ color: var(--fg);
4339
+ border-radius: 3px;
4340
+ cursor: pointer;
4341
+ font-family: var(--font-mono);
4342
+ font-size: 14px;
4343
+ line-height: 1;
4344
+ padding: 0;
4345
+ }
4346
+ .zoom-slider-btn:hover {
4347
+ background: rgba(255,255,255,0.10);
4348
+ border-color: var(--accent);
4349
+ }
4350
+ #zoomSlider {
4351
+ -webkit-appearance: slider-vertical;
4352
+ appearance: slider-vertical;
4353
+ writing-mode: vertical-lr;
4354
+ direction: rtl;
4355
+ width: 18px;
4356
+ height: 200px;
4357
+ margin: 4px 0;
4358
+ cursor: pointer;
4359
+ }