superlocalmemory 3.4.1 → 3.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +9 -12
  2. package/package.json +1 -1
  3. package/pyproject.toml +11 -2
  4. package/scripts/postinstall.js +26 -7
  5. package/src/superlocalmemory/cli/commands.py +71 -60
  6. package/src/superlocalmemory/cli/daemon.py +184 -64
  7. package/src/superlocalmemory/cli/main.py +25 -2
  8. package/src/superlocalmemory/cli/service_installer.py +367 -0
  9. package/src/superlocalmemory/cli/setup_wizard.py +150 -9
  10. package/src/superlocalmemory/core/config.py +28 -0
  11. package/src/superlocalmemory/core/consolidation_engine.py +38 -1
  12. package/src/superlocalmemory/core/engine.py +9 -0
  13. package/src/superlocalmemory/core/health_monitor.py +313 -0
  14. package/src/superlocalmemory/core/reranker_worker.py +19 -5
  15. package/src/superlocalmemory/ingestion/__init__.py +13 -0
  16. package/src/superlocalmemory/ingestion/adapter_manager.py +234 -0
  17. package/src/superlocalmemory/ingestion/base_adapter.py +177 -0
  18. package/src/superlocalmemory/ingestion/calendar_adapter.py +340 -0
  19. package/src/superlocalmemory/ingestion/credentials.py +118 -0
  20. package/src/superlocalmemory/ingestion/gmail_adapter.py +369 -0
  21. package/src/superlocalmemory/ingestion/parsers.py +100 -0
  22. package/src/superlocalmemory/ingestion/transcript_adapter.py +156 -0
  23. package/src/superlocalmemory/learning/consolidation_worker.py +47 -1
  24. package/src/superlocalmemory/learning/entity_compiler.py +377 -0
  25. package/src/superlocalmemory/mcp/server.py +32 -3
  26. package/src/superlocalmemory/mcp/tools_mesh.py +249 -0
  27. package/src/superlocalmemory/mesh/__init__.py +12 -0
  28. package/src/superlocalmemory/mesh/broker.py +344 -0
  29. package/src/superlocalmemory/retrieval/entity_channel.py +12 -6
  30. package/src/superlocalmemory/server/api.py +6 -7
  31. package/src/superlocalmemory/server/routes/adapters.py +63 -0
  32. package/src/superlocalmemory/server/routes/entity.py +151 -0
  33. package/src/superlocalmemory/server/routes/ingest.py +110 -0
  34. package/src/superlocalmemory/server/routes/mesh.py +186 -0
  35. package/src/superlocalmemory/server/unified_daemon.py +693 -0
  36. package/src/superlocalmemory/storage/schema_v343.py +229 -0
  37. package/src/superlocalmemory/ui/css/neural-glass.css +1588 -0
  38. package/src/superlocalmemory/ui/index.html +134 -4
  39. package/src/superlocalmemory/ui/js/memory-chat.js +28 -1
  40. package/src/superlocalmemory/ui/js/ng-entities.js +272 -0
  41. package/src/superlocalmemory/ui/js/ng-health.js +208 -0
  42. package/src/superlocalmemory/ui/js/ng-ingestion.js +203 -0
  43. package/src/superlocalmemory/ui/js/ng-mesh.js +311 -0
  44. package/src/superlocalmemory/ui/js/ng-shell.js +471 -0
  45. package/src/superlocalmemory.egg-info/PKG-INFO +18 -14
  46. package/src/superlocalmemory.egg-info/SOURCES.txt +26 -0
  47. package/src/superlocalmemory.egg-info/requires.txt +9 -1
@@ -0,0 +1,1588 @@
1
+ /* ============================================
2
+ Neural Glass Design System v1.0
3
+ SuperLocalMemory Dashboard V2 "Neural Glass"
4
+ Linear darkness + Raycast glass + Claude warmth
5
+ Brand accent: Qualixar Cyan #00D4AA
6
+ ============================================ */
7
+
8
+ /* ============================================
9
+ 1. CUSTOM PROPERTIES (Design Tokens)
10
+ ============================================ */
11
+
12
+ :root {
13
+ /* --- Background Surfaces (Linear luminance stacking) --- */
14
+ --ng-bg-void: #0a0a0c;
15
+ --ng-bg-base: #0f1012;
16
+ --ng-bg-surface: #161719;
17
+ --ng-bg-elevated: #1c1d20;
18
+ --ng-bg-hover: #222326;
19
+
20
+ /* --- Glass Surfaces (Raycast macOS glass) --- */
21
+ --ng-bg-glass: rgba(255, 255, 255, 0.03);
22
+ --ng-bg-glass-hover: rgba(255, 255, 255, 0.06);
23
+ --ng-bg-glass-active: rgba(255, 255, 255, 0.08);
24
+ --ng-bg-glass-strong: rgba(255, 255, 255, 0.10);
25
+
26
+ /* --- Text (Claude warm neutrals — no cold blue-grays) --- */
27
+ --ng-text-primary: #f0eeeb;
28
+ --ng-text-secondary: #b8b5af;
29
+ --ng-text-tertiary: #7d7a74;
30
+ --ng-text-quaternary: #545250;
31
+ --ng-text-on-accent: #ffffff;
32
+
33
+ /* --- SLM Purple Accent (original #667eea → #764ba2 gradient) --- */
34
+ --ng-accent: #7C6AEF;
35
+ --ng-accent-hover: #9182F3;
36
+ --ng-accent-muted: rgba(124, 106, 239, 0.10);
37
+ --ng-accent-glow: rgba(124, 106, 239, 0.18);
38
+ --ng-accent-strong: rgba(124, 106, 239, 0.28);
39
+ --ng-accent-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
40
+
41
+ /* --- Status Colors --- */
42
+ --ng-status-success: #10b981;
43
+ --ng-status-success-bg: rgba(16, 185, 129, 0.10);
44
+ --ng-status-warning: #f59e0b;
45
+ --ng-status-warning-bg: rgba(245, 158, 11, 0.10);
46
+ --ng-status-error: #ef4444;
47
+ --ng-status-error-bg: rgba(239, 68, 68, 0.10);
48
+ --ng-status-info: #3b82f6;
49
+ --ng-status-info-bg: rgba(59, 130, 246, 0.10);
50
+
51
+ /* --- Borders (Linear semi-transparent white) --- */
52
+ --ng-border-subtle: rgba(255, 255, 255, 0.06);
53
+ --ng-border-default: rgba(255, 255, 255, 0.10);
54
+ --ng-border-prominent: rgba(255, 255, 255, 0.15);
55
+ --ng-border-accent: rgba(0, 212, 170, 0.30);
56
+
57
+ /* --- Shadows (Raycast macOS glass depth) --- */
58
+ --ng-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
59
+ --ng-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.25);
60
+ --ng-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.3);
61
+ --ng-shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.4);
62
+ --ng-shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.5);
63
+
64
+ /* Glass panel shadow (Raycast inset + outer) */
65
+ --ng-shadow-glass:
66
+ inset 0 1px 0 0 rgba(255, 255, 255, 0.06),
67
+ 0 1px 3px rgba(0, 0, 0, 0.3),
68
+ 0 4px 12px rgba(0, 0, 0, 0.2);
69
+
70
+ /* Elevated glass shadow */
71
+ --ng-shadow-glass-elevated:
72
+ inset 0 1px 0 0 rgba(255, 255, 255, 0.08),
73
+ 0 4px 16px rgba(0, 0, 0, 0.3),
74
+ 0 12px 40px rgba(0, 0, 0, 0.25);
75
+
76
+ /* Accent glow */
77
+ --ng-shadow-glow: 0 0 20px var(--ng-accent-glow), 0 0 40px rgba(124, 106, 239, 0.06);
78
+
79
+ /* --- Typography (Linear: Inter Variable + cv01/ss03) --- */
80
+ --ng-font-sans: 'Inter Variable', 'Inter', -apple-system, system-ui, 'Segoe UI', sans-serif;
81
+ --ng-font-mono: 'GeistMono', 'Berkeley Mono', ui-monospace, 'SF Mono', 'Menlo', monospace;
82
+ --ng-font-feature: "cv01", "ss03";
83
+
84
+ /* Weight scale (Linear: 400=read, 510=emphasis, 590=strong) */
85
+ --ng-weight-normal: 400;
86
+ --ng-weight-medium: 510;
87
+ --ng-weight-semibold: 590;
88
+
89
+ /* --- Spacing (8px grid) --- */
90
+ --ng-space-1: 4px;
91
+ --ng-space-2: 8px;
92
+ --ng-space-3: 12px;
93
+ --ng-space-4: 16px;
94
+ --ng-space-5: 20px;
95
+ --ng-space-6: 24px;
96
+ --ng-space-8: 32px;
97
+ --ng-space-10: 40px;
98
+ --ng-space-12: 48px;
99
+
100
+ /* --- Border Radius --- */
101
+ --ng-radius-sm: 4px;
102
+ --ng-radius-md: 8px;
103
+ --ng-radius-lg: 12px;
104
+ --ng-radius-xl: 16px;
105
+ --ng-radius-2xl: 20px;
106
+ --ng-radius-pill: 9999px;
107
+
108
+ /* --- Sidebar --- */
109
+ --ng-sidebar-width: 240px;
110
+ --ng-sidebar-collapsed: 56px;
111
+
112
+ /* --- Transitions --- */
113
+ --ng-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
114
+ --ng-transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1);
115
+ --ng-transition-slow: 400ms cubic-bezier(0.4, 0, 0.2, 1);
116
+ --ng-transition-spring: 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
117
+
118
+ /* --- Z-Index Scale --- */
119
+ --ng-z-sidebar: 100;
120
+ --ng-z-header: 90;
121
+ --ng-z-overlay: 200;
122
+ --ng-z-modal: 300;
123
+ --ng-z-tooltip: 400;
124
+ }
125
+
126
+
127
+ /* ============================================
128
+ 2. RESET & BASE
129
+ ============================================ */
130
+
131
+ .ng-dark {
132
+ background: var(--ng-bg-void);
133
+ color: var(--ng-text-primary);
134
+ font-family: var(--ng-font-sans);
135
+ font-feature-settings: var(--ng-font-feature);
136
+ font-weight: var(--ng-weight-normal);
137
+ -webkit-font-smoothing: antialiased;
138
+ -moz-osx-font-smoothing: grayscale;
139
+ text-rendering: optimizeLegibility;
140
+ line-height: 1.5;
141
+ }
142
+
143
+ .ng-dark *,
144
+ .ng-dark *::before,
145
+ .ng-dark *::after {
146
+ border-color: var(--ng-border-subtle);
147
+ }
148
+
149
+ .ng-dark ::selection {
150
+ background: var(--ng-accent-strong);
151
+ color: var(--ng-text-primary);
152
+ }
153
+
154
+ .ng-dark ::-webkit-scrollbar {
155
+ width: 6px;
156
+ height: 6px;
157
+ }
158
+
159
+ .ng-dark ::-webkit-scrollbar-track {
160
+ background: transparent;
161
+ }
162
+
163
+ .ng-dark ::-webkit-scrollbar-thumb {
164
+ background: rgba(255, 255, 255, 0.12);
165
+ border-radius: var(--ng-radius-pill);
166
+ }
167
+
168
+ .ng-dark ::-webkit-scrollbar-thumb:hover {
169
+ background: rgba(255, 255, 255, 0.20);
170
+ }
171
+
172
+
173
+ /* ============================================
174
+ 3. TYPOGRAPHY
175
+ ============================================ */
176
+
177
+ .ng-dark h1, .ng-dark h2, .ng-dark h3,
178
+ .ng-dark h4, .ng-dark h5, .ng-dark h6 {
179
+ color: var(--ng-text-primary);
180
+ font-weight: var(--ng-weight-medium);
181
+ letter-spacing: -0.02em;
182
+ line-height: 1.2;
183
+ }
184
+
185
+ .ng-dark h1 { font-size: 2rem; letter-spacing: -0.04em; }
186
+ .ng-dark h2 { font-size: 1.5rem; letter-spacing: -0.03em; }
187
+ .ng-dark h3 { font-size: 1.25rem; }
188
+ .ng-dark h4 { font-size: 1.125rem; }
189
+ .ng-dark h5 { font-size: 1rem; }
190
+ .ng-dark h6 { font-size: 0.875rem; font-weight: var(--ng-weight-semibold); text-transform: uppercase; letter-spacing: 0.04em; }
191
+
192
+ .ng-dark p { color: var(--ng-text-secondary); }
193
+ .ng-dark small, .ng-dark .text-muted { color: var(--ng-text-tertiary) !important; }
194
+ .ng-dark code, .ng-dark pre { font-family: var(--ng-font-mono); }
195
+
196
+ .ng-dark code {
197
+ background: var(--ng-bg-glass-active);
198
+ padding: 2px 6px;
199
+ border-radius: var(--ng-radius-sm);
200
+ font-size: 0.875em;
201
+ color: var(--ng-accent);
202
+ }
203
+
204
+ .ng-dark a {
205
+ color: var(--ng-accent);
206
+ text-decoration: none;
207
+ transition: color var(--ng-transition-fast);
208
+ }
209
+
210
+ .ng-dark a:hover {
211
+ color: var(--ng-accent-hover);
212
+ }
213
+
214
+ /* Stat value — Linear-style glow */
215
+ .ng-stat-value {
216
+ font-size: 2rem;
217
+ font-weight: var(--ng-weight-semibold);
218
+ letter-spacing: -0.04em;
219
+ color: var(--ng-text-primary);
220
+ line-height: 1;
221
+ }
222
+
223
+ .ng-stat-label {
224
+ font-size: 0.75rem;
225
+ font-weight: var(--ng-weight-medium);
226
+ color: var(--ng-text-tertiary);
227
+ text-transform: uppercase;
228
+ letter-spacing: 0.06em;
229
+ }
230
+
231
+
232
+ /* ============================================
233
+ 4. GLASS EFFECTS
234
+ ============================================ */
235
+
236
+ .ng-glass {
237
+ background: var(--ng-bg-glass);
238
+ border: 1px solid var(--ng-border-subtle);
239
+ border-radius: var(--ng-radius-lg);
240
+ box-shadow: var(--ng-shadow-glass);
241
+ backdrop-filter: blur(12px);
242
+ -webkit-backdrop-filter: blur(12px);
243
+ }
244
+
245
+ .ng-glass-elevated {
246
+ background: var(--ng-bg-glass-hover);
247
+ border: 1px solid var(--ng-border-default);
248
+ border-radius: var(--ng-radius-lg);
249
+ box-shadow: var(--ng-shadow-glass-elevated);
250
+ backdrop-filter: blur(16px);
251
+ -webkit-backdrop-filter: blur(16px);
252
+ }
253
+
254
+ .ng-glass-surface {
255
+ background: var(--ng-bg-surface);
256
+ border: 1px solid var(--ng-border-subtle);
257
+ border-radius: var(--ng-radius-lg);
258
+ box-shadow: var(--ng-shadow-sm);
259
+ }
260
+
261
+ .ng-glass-accent {
262
+ background: var(--ng-accent-muted);
263
+ border: 1px solid var(--ng-border-accent);
264
+ border-radius: var(--ng-radius-lg);
265
+ box-shadow: var(--ng-shadow-glow);
266
+ }
267
+
268
+ /* Inset glass (Raycast sunken panels) */
269
+ .ng-glass-inset {
270
+ background: rgba(0, 0, 0, 0.2);
271
+ border: 1px solid rgba(255, 255, 255, 0.04);
272
+ border-radius: var(--ng-radius-md);
273
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
274
+ }
275
+
276
+
277
+ /* ============================================
278
+ 5. LAYOUT: APP SHELL + SIDEBAR
279
+ ============================================ */
280
+
281
+ .ng-shell {
282
+ display: flex;
283
+ min-height: 100vh;
284
+ overflow: hidden;
285
+ }
286
+
287
+ /* Sidebar */
288
+ .ng-sidebar {
289
+ width: var(--ng-sidebar-width);
290
+ min-width: var(--ng-sidebar-width);
291
+ height: 100vh;
292
+ position: fixed;
293
+ top: 0;
294
+ left: 0;
295
+ z-index: var(--ng-z-sidebar);
296
+ display: flex;
297
+ flex-direction: column;
298
+ background: var(--ng-bg-base);
299
+ border-right: 1px solid var(--ng-border-subtle);
300
+ overflow-y: auto;
301
+ overflow-x: hidden;
302
+ transition: width var(--ng-transition-normal), min-width var(--ng-transition-normal);
303
+ }
304
+
305
+ .ng-sidebar-header {
306
+ padding: var(--ng-space-4) var(--ng-space-4) var(--ng-space-3);
307
+ border-bottom: 1px solid var(--ng-border-subtle);
308
+ flex-shrink: 0;
309
+ }
310
+
311
+ .ng-sidebar-brand {
312
+ display: flex;
313
+ align-items: center;
314
+ gap: var(--ng-space-3);
315
+ text-decoration: none;
316
+ }
317
+
318
+ .ng-sidebar-brand-icon {
319
+ width: 32px;
320
+ height: 32px;
321
+ border-radius: var(--ng-radius-md);
322
+ background: var(--ng-accent-gradient);
323
+ display: flex;
324
+ align-items: center;
325
+ justify-content: center;
326
+ font-size: 1rem;
327
+ color: var(--ng-text-on-accent);
328
+ flex-shrink: 0;
329
+ box-shadow: var(--ng-shadow-glow);
330
+ }
331
+
332
+ .ng-sidebar-brand-text {
333
+ font-size: 0.9375rem;
334
+ font-weight: var(--ng-weight-semibold);
335
+ color: var(--ng-text-primary);
336
+ letter-spacing: -0.02em;
337
+ line-height: 1.2;
338
+ }
339
+
340
+ .ng-sidebar-brand-version {
341
+ font-size: 0.6875rem;
342
+ color: var(--ng-text-quaternary);
343
+ font-weight: var(--ng-weight-normal);
344
+ }
345
+
346
+ /* Sidebar nav sections */
347
+ .ng-sidebar-nav {
348
+ flex: 1;
349
+ padding: var(--ng-space-2) var(--ng-space-2);
350
+ overflow-y: auto;
351
+ }
352
+
353
+ .ng-sidebar-section {
354
+ margin-bottom: var(--ng-space-2);
355
+ }
356
+
357
+ .ng-sidebar-section-label {
358
+ font-size: 0.6875rem;
359
+ font-weight: var(--ng-weight-semibold);
360
+ color: var(--ng-text-quaternary);
361
+ text-transform: uppercase;
362
+ letter-spacing: 0.08em;
363
+ padding: var(--ng-space-3) var(--ng-space-3) var(--ng-space-1);
364
+ }
365
+
366
+ .ng-sidebar-item {
367
+ display: flex;
368
+ align-items: center;
369
+ gap: var(--ng-space-3);
370
+ padding: 7px var(--ng-space-3);
371
+ border-radius: var(--ng-radius-md);
372
+ color: var(--ng-text-secondary);
373
+ font-size: 0.8125rem;
374
+ font-weight: var(--ng-weight-medium);
375
+ cursor: pointer;
376
+ transition:
377
+ background var(--ng-transition-fast),
378
+ color var(--ng-transition-fast);
379
+ text-decoration: none;
380
+ border: 1px solid transparent;
381
+ user-select: none;
382
+ }
383
+
384
+ .ng-sidebar-item:hover {
385
+ background: var(--ng-bg-glass-hover);
386
+ color: var(--ng-text-primary);
387
+ }
388
+
389
+ .ng-sidebar-item.active {
390
+ background: var(--ng-accent-muted);
391
+ color: var(--ng-accent);
392
+ border-color: var(--ng-border-accent);
393
+ box-shadow: var(--ng-shadow-glow);
394
+ }
395
+
396
+ .ng-sidebar-item.active .ng-sidebar-icon {
397
+ color: var(--ng-accent);
398
+ }
399
+
400
+ .ng-sidebar-icon {
401
+ font-size: 1rem;
402
+ width: 20px;
403
+ text-align: center;
404
+ flex-shrink: 0;
405
+ color: var(--ng-text-tertiary);
406
+ transition: color var(--ng-transition-fast);
407
+ }
408
+
409
+ .ng-sidebar-item:hover .ng-sidebar-icon {
410
+ color: var(--ng-text-secondary);
411
+ }
412
+
413
+ .ng-sidebar-badge {
414
+ margin-left: auto;
415
+ font-size: 0.625rem;
416
+ font-weight: var(--ng-weight-semibold);
417
+ padding: 1px 6px;
418
+ border-radius: var(--ng-radius-pill);
419
+ background: var(--ng-accent-muted);
420
+ color: var(--ng-accent);
421
+ }
422
+
423
+ /* Sidebar footer */
424
+ .ng-sidebar-footer {
425
+ padding: var(--ng-space-3) var(--ng-space-4);
426
+ border-top: 1px solid var(--ng-border-subtle);
427
+ flex-shrink: 0;
428
+ }
429
+
430
+ /* Main content area */
431
+ .ng-content {
432
+ flex: 1;
433
+ margin-left: var(--ng-sidebar-width);
434
+ min-height: 100vh;
435
+ background: var(--ng-bg-void);
436
+ overflow-x: hidden;
437
+ }
438
+
439
+ .ng-content-inner {
440
+ max-width: 1400px;
441
+ margin: 0 auto;
442
+ padding: var(--ng-space-6);
443
+ }
444
+
445
+ /* Content header */
446
+ .ng-content-header {
447
+ display: flex;
448
+ align-items: center;
449
+ justify-content: space-between;
450
+ margin-bottom: var(--ng-space-6);
451
+ padding-bottom: var(--ng-space-4);
452
+ border-bottom: 1px solid var(--ng-border-subtle);
453
+ }
454
+
455
+ .ng-content-title {
456
+ font-size: 1.375rem;
457
+ font-weight: var(--ng-weight-medium);
458
+ letter-spacing: -0.03em;
459
+ color: var(--ng-text-primary);
460
+ }
461
+
462
+ .ng-content-subtitle {
463
+ font-size: 0.8125rem;
464
+ color: var(--ng-text-tertiary);
465
+ margin-top: 2px;
466
+ }
467
+
468
+
469
+ /* ============================================
470
+ 6. CARDS & PANELS
471
+ ============================================ */
472
+
473
+ .ng-dark .card,
474
+ .ng-card {
475
+ background: var(--ng-bg-glass);
476
+ border: 1px solid var(--ng-border-subtle);
477
+ border-radius: var(--ng-radius-lg);
478
+ box-shadow: var(--ng-shadow-glass);
479
+ color: var(--ng-text-primary);
480
+ transition: border-color var(--ng-transition-fast), box-shadow var(--ng-transition-fast);
481
+ }
482
+
483
+ .ng-dark .card:hover,
484
+ .ng-card:hover {
485
+ border-color: var(--ng-border-default);
486
+ }
487
+
488
+ .ng-dark .card-header {
489
+ background: var(--ng-bg-glass-hover) !important;
490
+ border-bottom: 1px solid var(--ng-border-subtle);
491
+ color: var(--ng-text-primary) !important;
492
+ }
493
+
494
+ .ng-dark .card-body {
495
+ color: var(--ng-text-primary);
496
+ }
497
+
498
+ /* Stat cards */
499
+ .ng-dark .stat-card {
500
+ background: var(--ng-bg-glass);
501
+ border: 1px solid var(--ng-border-subtle);
502
+ box-shadow: var(--ng-shadow-glass);
503
+ }
504
+
505
+ .ng-dark .stat-card:hover {
506
+ border-color: var(--ng-border-default);
507
+ box-shadow: var(--ng-shadow-glass-elevated);
508
+ transform: translateY(-2px);
509
+ }
510
+
511
+ .ng-dark .stat-card .stat-bg {
512
+ display: none; /* Remove old gradient backgrounds */
513
+ }
514
+
515
+ .ng-dark .stat-card .stat-icon {
516
+ color: var(--ng-accent) !important;
517
+ opacity: 0.7;
518
+ }
519
+
520
+ .ng-dark .stat-card .stat-value {
521
+ color: var(--ng-text-primary);
522
+ font-weight: var(--ng-weight-semibold);
523
+ letter-spacing: -0.03em;
524
+ }
525
+
526
+
527
+ /* ============================================
528
+ 7. BUTTONS
529
+ ============================================ */
530
+
531
+ /* Ghost button (Linear default) */
532
+ .ng-btn {
533
+ display: inline-flex;
534
+ align-items: center;
535
+ gap: var(--ng-space-2);
536
+ padding: 6px 12px;
537
+ border-radius: var(--ng-radius-md);
538
+ font-size: 0.8125rem;
539
+ font-weight: var(--ng-weight-medium);
540
+ font-family: inherit;
541
+ font-feature-settings: var(--ng-font-feature);
542
+ cursor: pointer;
543
+ transition:
544
+ background var(--ng-transition-fast),
545
+ border-color var(--ng-transition-fast),
546
+ opacity var(--ng-transition-fast);
547
+ border: 1px solid var(--ng-border-default);
548
+ background: var(--ng-bg-glass);
549
+ color: var(--ng-text-secondary);
550
+ }
551
+
552
+ .ng-btn:hover {
553
+ background: var(--ng-bg-glass-hover);
554
+ color: var(--ng-text-primary);
555
+ border-color: var(--ng-border-prominent);
556
+ }
557
+
558
+ /* Primary accent button */
559
+ .ng-btn-accent {
560
+ background: var(--ng-accent);
561
+ color: var(--ng-text-on-accent);
562
+ border-color: transparent;
563
+ font-weight: var(--ng-weight-semibold);
564
+ }
565
+
566
+ .ng-btn-accent:hover {
567
+ background: var(--ng-accent-hover);
568
+ color: var(--ng-text-on-accent);
569
+ border-color: transparent;
570
+ box-shadow: var(--ng-shadow-glow);
571
+ }
572
+
573
+ /* Bootstrap button overrides */
574
+ .ng-dark .btn-primary {
575
+ background: var(--ng-accent) !important;
576
+ border-color: var(--ng-accent) !important;
577
+ color: var(--ng-text-on-accent) !important;
578
+ }
579
+
580
+ .ng-dark .btn-primary:hover {
581
+ background: var(--ng-accent-hover) !important;
582
+ border-color: var(--ng-accent-hover) !important;
583
+ box-shadow: var(--ng-shadow-glow);
584
+ }
585
+
586
+ .ng-dark .btn-outline-primary {
587
+ color: var(--ng-accent) !important;
588
+ border-color: var(--ng-accent) !important;
589
+ }
590
+
591
+ .ng-dark .btn-outline-primary:hover {
592
+ background: var(--ng-accent-muted) !important;
593
+ color: var(--ng-accent) !important;
594
+ border-color: var(--ng-accent) !important;
595
+ }
596
+
597
+ .ng-dark .btn-success { background: var(--ng-status-success) !important; border-color: var(--ng-status-success) !important; }
598
+ .ng-dark .btn-outline-success { color: var(--ng-status-success) !important; border-color: var(--ng-status-success) !important; }
599
+ .ng-dark .btn-outline-secondary {
600
+ color: var(--ng-text-secondary) !important;
601
+ border-color: var(--ng-border-default) !important;
602
+ background: var(--ng-bg-glass) !important;
603
+ }
604
+ .ng-dark .btn-outline-secondary:hover {
605
+ background: var(--ng-bg-glass-hover) !important;
606
+ color: var(--ng-text-primary) !important;
607
+ }
608
+ .ng-dark .btn-outline-light {
609
+ color: var(--ng-text-secondary) !important;
610
+ border-color: var(--ng-border-default) !important;
611
+ }
612
+ .ng-dark .btn-outline-light:hover {
613
+ background: var(--ng-bg-glass-hover) !important;
614
+ color: var(--ng-text-primary) !important;
615
+ }
616
+ .ng-dark .btn-outline-danger {
617
+ color: var(--ng-status-error) !important;
618
+ border-color: var(--ng-status-error) !important;
619
+ }
620
+ .ng-dark .btn-outline-info {
621
+ color: var(--ng-status-info) !important;
622
+ border-color: var(--ng-status-info) !important;
623
+ }
624
+
625
+
626
+ /* ============================================
627
+ 8. INPUTS & FORMS
628
+ ============================================ */
629
+
630
+ .ng-dark .form-control,
631
+ .ng-dark .form-select {
632
+ background: var(--ng-bg-glass) !important;
633
+ border: 1px solid var(--ng-border-default) !important;
634
+ color: var(--ng-text-primary) !important;
635
+ border-radius: var(--ng-radius-md);
636
+ font-feature-settings: var(--ng-font-feature);
637
+ transition: border-color var(--ng-transition-fast), box-shadow var(--ng-transition-fast);
638
+ }
639
+
640
+ .ng-dark .form-control:focus,
641
+ .ng-dark .form-select:focus {
642
+ border-color: var(--ng-accent) !important;
643
+ box-shadow: 0 0 0 2px var(--ng-accent-glow) !important;
644
+ outline: none;
645
+ }
646
+
647
+ .ng-dark .form-control::placeholder {
648
+ color: var(--ng-text-quaternary) !important;
649
+ }
650
+
651
+ .ng-dark .input-group-text {
652
+ background: var(--ng-bg-glass-hover) !important;
653
+ border: 1px solid var(--ng-border-default) !important;
654
+ color: var(--ng-text-tertiary) !important;
655
+ }
656
+
657
+ .ng-dark .form-check-input {
658
+ background-color: var(--ng-bg-glass-strong) !important;
659
+ border-color: var(--ng-border-default) !important;
660
+ }
661
+
662
+ .ng-dark .form-check-input:checked {
663
+ background-color: var(--ng-accent) !important;
664
+ border-color: var(--ng-accent) !important;
665
+ }
666
+
667
+ .ng-dark .form-label {
668
+ color: var(--ng-text-secondary);
669
+ font-weight: var(--ng-weight-medium);
670
+ font-size: 0.8125rem;
671
+ }
672
+
673
+ .ng-dark .form-range::-webkit-slider-thumb {
674
+ background: var(--ng-accent);
675
+ }
676
+
677
+
678
+ /* ============================================
679
+ 9. TABLES
680
+ ============================================ */
681
+
682
+ .ng-dark .table {
683
+ color: var(--ng-text-primary);
684
+ --bs-table-bg: transparent;
685
+ --bs-table-hover-bg: var(--ng-bg-glass-hover);
686
+ --bs-table-striped-bg: var(--ng-bg-glass);
687
+ border-color: var(--ng-border-subtle);
688
+ }
689
+
690
+ .ng-dark .table thead th {
691
+ color: var(--ng-text-tertiary);
692
+ font-weight: var(--ng-weight-semibold);
693
+ font-size: 0.75rem;
694
+ text-transform: uppercase;
695
+ letter-spacing: 0.06em;
696
+ border-bottom: 1px solid var(--ng-border-default);
697
+ padding: var(--ng-space-3) var(--ng-space-3);
698
+ }
699
+
700
+ .ng-dark .table tbody td {
701
+ border-bottom: 1px solid var(--ng-border-subtle);
702
+ padding: var(--ng-space-3) var(--ng-space-3);
703
+ font-size: 0.8125rem;
704
+ }
705
+
706
+ .ng-dark .table tbody tr:hover {
707
+ background: var(--ng-bg-glass-hover) !important;
708
+ }
709
+
710
+ .ng-dark .table-responsive {
711
+ border-radius: var(--ng-radius-lg);
712
+ border: 1px solid var(--ng-border-subtle);
713
+ }
714
+
715
+ /* Sortable headers */
716
+ .ng-dark .sortable:hover {
717
+ background: var(--ng-bg-glass-hover);
718
+ }
719
+
720
+
721
+ /* ============================================
722
+ 10. STATUS & BADGES
723
+ ============================================ */
724
+
725
+ .ng-badge {
726
+ display: inline-flex;
727
+ align-items: center;
728
+ gap: 4px;
729
+ padding: 2px 8px;
730
+ border-radius: var(--ng-radius-pill);
731
+ font-size: 0.6875rem;
732
+ font-weight: var(--ng-weight-semibold);
733
+ letter-spacing: 0.02em;
734
+ }
735
+
736
+ .ng-badge-success { background: var(--ng-status-success-bg); color: var(--ng-status-success); }
737
+ .ng-badge-warning { background: var(--ng-status-warning-bg); color: var(--ng-status-warning); }
738
+ .ng-badge-error { background: var(--ng-status-error-bg); color: var(--ng-status-error); }
739
+ .ng-badge-info { background: var(--ng-status-info-bg); color: var(--ng-status-info); }
740
+ .ng-badge-accent { background: var(--ng-accent-muted); color: var(--ng-accent); }
741
+ .ng-badge-neutral { background: var(--ng-bg-glass-active); color: var(--ng-text-secondary); }
742
+
743
+ /* Status dot */
744
+ .ng-status-dot {
745
+ width: 8px;
746
+ height: 8px;
747
+ border-radius: 50%;
748
+ flex-shrink: 0;
749
+ }
750
+
751
+ .ng-status-dot-success { background: var(--ng-status-success); box-shadow: 0 0 6px var(--ng-status-success); }
752
+ .ng-status-dot-warning { background: var(--ng-status-warning); box-shadow: 0 0 6px var(--ng-status-warning); }
753
+ .ng-status-dot-error { background: var(--ng-status-error); box-shadow: 0 0 6px var(--ng-status-error); }
754
+ .ng-status-dot-info { background: var(--ng-status-info); box-shadow: 0 0 6px var(--ng-status-info); }
755
+
756
+ /* Pulse animation for status */
757
+ .ng-pulse {
758
+ animation: ng-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
759
+ }
760
+
761
+ /* Bootstrap badge overrides */
762
+ .ng-dark .badge.bg-primary { background: var(--ng-accent-muted) !important; color: var(--ng-accent) !important; }
763
+ .ng-dark .badge.bg-success { background: var(--ng-status-success-bg) !important; color: var(--ng-status-success) !important; }
764
+ .ng-dark .badge.bg-warning { background: var(--ng-status-warning-bg) !important; color: var(--ng-status-warning) !important; }
765
+ .ng-dark .badge.bg-danger { background: var(--ng-status-error-bg) !important; color: var(--ng-status-error) !important; }
766
+ .ng-dark .badge.bg-info { background: var(--ng-status-info-bg) !important; color: var(--ng-status-info) !important; }
767
+ .ng-dark .badge.bg-light { background: var(--ng-bg-glass-active) !important; color: var(--ng-text-primary) !important; }
768
+ .ng-dark .badge.bg-dark { background: var(--ng-bg-glass) !important; color: var(--ng-text-secondary) !important; }
769
+
770
+
771
+ /* ============================================
772
+ 11. PROGRESS & GAUGES
773
+ ============================================ */
774
+
775
+ .ng-progress-bar {
776
+ height: 6px;
777
+ border-radius: var(--ng-radius-pill);
778
+ background: var(--ng-bg-glass-active);
779
+ overflow: hidden;
780
+ }
781
+
782
+ .ng-progress-fill {
783
+ height: 100%;
784
+ border-radius: var(--ng-radius-pill);
785
+ background: var(--ng-accent);
786
+ transition: width var(--ng-transition-slow);
787
+ }
788
+
789
+ .ng-progress-fill-success { background: var(--ng-status-success); }
790
+ .ng-progress-fill-warning { background: var(--ng-status-warning); }
791
+ .ng-progress-fill-error { background: var(--ng-status-error); }
792
+
793
+ /* Score/confidence bars */
794
+ .ng-dark .score-bar { background: var(--ng-bg-glass-active); }
795
+ .ng-dark .confidence-bar { background: var(--ng-bg-glass-active); }
796
+
797
+
798
+ /* ============================================
799
+ 12. MODALS & OVERLAYS
800
+ ============================================ */
801
+
802
+ .ng-dark .modal-content {
803
+ background: var(--ng-bg-surface) !important;
804
+ border: 1px solid var(--ng-border-default) !important;
805
+ border-radius: var(--ng-radius-xl) !important;
806
+ box-shadow: var(--ng-shadow-xl) !important;
807
+ color: var(--ng-text-primary);
808
+ }
809
+
810
+ .ng-dark .modal-header {
811
+ border-bottom-color: var(--ng-border-subtle) !important;
812
+ }
813
+
814
+ .ng-dark .modal-footer {
815
+ border-top-color: var(--ng-border-subtle) !important;
816
+ }
817
+
818
+ .ng-dark .modal-backdrop {
819
+ background: rgba(0, 0, 0, 0.75) !important;
820
+ backdrop-filter: blur(4px);
821
+ }
822
+
823
+ .ng-dark .btn-close {
824
+ filter: invert(1) grayscale(100%) brightness(0.8);
825
+ }
826
+
827
+
828
+ /* ============================================
829
+ 13. ALERTS & NOTICES
830
+ ============================================ */
831
+
832
+ .ng-dark .alert {
833
+ border-radius: var(--ng-radius-md);
834
+ }
835
+
836
+ .ng-dark .alert-info {
837
+ background: var(--ng-status-info-bg) !important;
838
+ border-color: rgba(59, 130, 246, 0.2) !important;
839
+ color: var(--ng-text-primary) !important;
840
+ }
841
+
842
+ .ng-dark .alert-success {
843
+ background: var(--ng-status-success-bg) !important;
844
+ border-color: rgba(16, 185, 129, 0.2) !important;
845
+ color: var(--ng-text-primary) !important;
846
+ }
847
+
848
+ .ng-dark .alert-warning {
849
+ background: var(--ng-status-warning-bg) !important;
850
+ border-color: rgba(245, 158, 11, 0.2) !important;
851
+ color: var(--ng-text-primary) !important;
852
+ }
853
+
854
+ .ng-dark .alert-danger {
855
+ background: var(--ng-status-error-bg) !important;
856
+ border-color: rgba(239, 68, 68, 0.2) !important;
857
+ color: var(--ng-text-primary) !important;
858
+ }
859
+
860
+
861
+ /* ============================================
862
+ 14. ANIMATIONS
863
+ ============================================ */
864
+
865
+ @keyframes ng-pulse {
866
+ 0%, 100% { opacity: 1; }
867
+ 50% { opacity: 0.5; }
868
+ }
869
+
870
+ @keyframes ng-fade-in {
871
+ from { opacity: 0; transform: translateY(8px); }
872
+ to { opacity: 1; transform: translateY(0); }
873
+ }
874
+
875
+ @keyframes ng-slide-in-left {
876
+ from { opacity: 0; transform: translateX(-12px); }
877
+ to { opacity: 1; transform: translateX(0); }
878
+ }
879
+
880
+ @keyframes ng-glow-pulse {
881
+ 0%, 100% { box-shadow: 0 0 8px var(--ng-accent-glow); }
882
+ 50% { box-shadow: 0 0 20px var(--ng-accent-glow), 0 0 40px rgba(0, 212, 170, 0.05); }
883
+ }
884
+
885
+ /* Tab pane entrance */
886
+ .ng-dark .tab-pane.active {
887
+ animation: ng-fade-in 300ms ease-out;
888
+ }
889
+
890
+
891
+ /* ============================================
892
+ 15. ACCESSIBILITY
893
+ ============================================ */
894
+
895
+ @media (prefers-reduced-motion: reduce) {
896
+ .ng-dark *,
897
+ .ng-dark *::before,
898
+ .ng-dark *::after {
899
+ animation-duration: 0.01ms !important;
900
+ animation-iteration-count: 1 !important;
901
+ transition-duration: 0.01ms !important;
902
+ }
903
+
904
+ .ng-pulse { animation: none; }
905
+ .ng-dark .tab-pane.active { animation: none; }
906
+ .ng-dark .stat-card:hover { transform: none; }
907
+ }
908
+
909
+ @media (prefers-reduced-transparency) {
910
+ .ng-glass,
911
+ .ng-glass-elevated {
912
+ backdrop-filter: none;
913
+ -webkit-backdrop-filter: none;
914
+ background: var(--ng-bg-surface);
915
+ }
916
+ }
917
+
918
+ /* Focus visible for keyboard navigation */
919
+ .ng-dark :focus-visible {
920
+ outline: 2px solid var(--ng-accent);
921
+ outline-offset: 2px;
922
+ }
923
+
924
+ .ng-sidebar-item:focus-visible {
925
+ outline: 2px solid var(--ng-accent);
926
+ outline-offset: -2px;
927
+ }
928
+
929
+
930
+ /* ============================================
931
+ 16. BOOTSTRAP DARK OVERRIDES
932
+ ============================================ */
933
+
934
+ /* Ensure Bootstrap dark theme uses our colors */
935
+ .ng-dark,
936
+ .ng-dark [data-bs-theme="dark"] {
937
+ --bs-body-bg: var(--ng-bg-void);
938
+ --bs-body-color: var(--ng-text-primary);
939
+ --bs-border-color: var(--ng-border-subtle);
940
+ --bs-secondary-color: var(--ng-text-tertiary);
941
+ --bs-tertiary-bg: var(--ng-bg-glass);
942
+ --bs-emphasis-color: var(--ng-text-primary);
943
+ --bs-primary: var(--ng-accent);
944
+ --bs-primary-rgb: 124, 106, 239;
945
+ }
946
+
947
+ /* Override navbar — we use sidebar now, but keep it in light mode for now */
948
+ .ng-dark .navbar { display: none !important; }
949
+ [data-bs-theme="light"] .navbar { display: none !important; }
950
+
951
+ /* Override Bootstrap nav tabs — hidden, sidebar drives navigation */
952
+ .ng-dark #mainTabs { display: none !important; }
953
+ [data-bs-theme="light"] #mainTabs { display: none !important; }
954
+
955
+ /* Override stats container — only show on dashboard */
956
+ .ng-dark #stats-container {
957
+ margin-bottom: var(--ng-space-6);
958
+ }
959
+
960
+ /* Dashboard-only elements — hidden via JS data attribute */
961
+ .ng-dark [data-ng-hide="true"] {
962
+ display: none !important;
963
+ }
964
+
965
+ /* Override footer */
966
+ .ng-dark footer {
967
+ border-top-color: var(--ng-border-subtle);
968
+ color: var(--ng-text-quaternary);
969
+ padding: var(--ng-space-6);
970
+ margin-top: var(--ng-space-8);
971
+ }
972
+
973
+ .ng-dark footer a {
974
+ color: var(--ng-accent);
975
+ }
976
+
977
+ /* Memory detail content */
978
+ .ng-dark .memory-detail-content {
979
+ background: var(--ng-bg-glass);
980
+ border: 1px solid var(--ng-border-subtle);
981
+ color: var(--ng-text-secondary);
982
+ }
983
+
984
+ /* Loading spinner */
985
+ .ng-dark .loading { color: var(--ng-text-tertiary); }
986
+ .ng-dark .spinner-border { color: var(--ng-accent) !important; }
987
+ .ng-dark .empty-state { color: var(--ng-text-tertiary); }
988
+
989
+ /* Graph container — override inline style with !important + specificity boost */
990
+ .ng-dark #graph-pane #graph-container,
991
+ body.ng-dark #graph-container {
992
+ background: #0f1012 !important;
993
+ background-color: #0f1012 !important;
994
+ border: 1px solid rgba(255, 255, 255, 0.06) !important;
995
+ border-radius: var(--ng-radius-lg);
996
+ box-shadow: var(--ng-shadow-glass);
997
+ }
998
+
999
+ /* Timeline chart in dark mode */
1000
+ .ng-dark #memory-timeline-chart,
1001
+ body.ng-dark #memory-timeline-chart {
1002
+ background: #0f1012 !important;
1003
+ background-color: #0f1012 !important;
1004
+ border-color: rgba(255, 255, 255, 0.06) !important;
1005
+ }
1006
+
1007
+ /* Left/right panels in graph view */
1008
+ .ng-dark #graph-left-panel .card,
1009
+ .ng-dark #graph-right-panel .card,
1010
+ .ng-dark #sigma-detail-panel {
1011
+ background: var(--ng-bg-surface) !important;
1012
+ border-color: var(--ng-border-subtle) !important;
1013
+ color: var(--ng-text-primary);
1014
+ }
1015
+
1016
+ /* Tab content area */
1017
+ .ng-dark .tab-content {
1018
+ min-height: auto;
1019
+ }
1020
+
1021
+ /* Mode buttons */
1022
+ .ng-dark .mode-btn {
1023
+ color: var(--ng-text-secondary) !important;
1024
+ border-color: var(--ng-border-default) !important;
1025
+ }
1026
+
1027
+ .ng-dark .mode-btn.active,
1028
+ .ng-dark .mode-btn:hover {
1029
+ background: var(--ng-accent-muted) !important;
1030
+ color: var(--ng-accent) !important;
1031
+ border-color: var(--ng-accent) !important;
1032
+ }
1033
+
1034
+ /* Tooltip */
1035
+ .ng-dark .tooltip-custom {
1036
+ background: var(--ng-bg-elevated);
1037
+ border: 1px solid var(--ng-border-default);
1038
+ border-radius: var(--ng-radius-md);
1039
+ box-shadow: var(--ng-shadow-lg);
1040
+ color: var(--ng-text-primary);
1041
+ }
1042
+
1043
+ /* Profile select in sidebar footer */
1044
+ .ng-dark .profile-select {
1045
+ background: var(--ng-bg-glass);
1046
+ border-color: var(--ng-border-default);
1047
+ color: var(--ng-text-primary);
1048
+ border-radius: var(--ng-radius-md);
1049
+ font-size: 0.8125rem;
1050
+ }
1051
+
1052
+ .ng-dark .profile-select option {
1053
+ background: var(--ng-bg-surface);
1054
+ color: var(--ng-text-primary);
1055
+ }
1056
+
1057
+ /* Cluster cards */
1058
+ .ng-dark .cluster-card {
1059
+ background: var(--ng-bg-glass);
1060
+ border: 1px solid var(--ng-border-subtle);
1061
+ border-radius: var(--ng-radius-md);
1062
+ }
1063
+
1064
+ /* Dropdown menus */
1065
+ .ng-dark .dropdown-menu {
1066
+ background: var(--ng-bg-elevated) !important;
1067
+ border: 1px solid var(--ng-border-default) !important;
1068
+ border-radius: var(--ng-radius-lg) !important;
1069
+ box-shadow: var(--ng-shadow-lg) !important;
1070
+ }
1071
+
1072
+ .ng-dark .dropdown-item {
1073
+ color: var(--ng-text-secondary) !important;
1074
+ border-radius: var(--ng-radius-sm);
1075
+ }
1076
+
1077
+ .ng-dark .dropdown-item:hover {
1078
+ background: var(--ng-bg-glass-hover) !important;
1079
+ color: var(--ng-text-primary) !important;
1080
+ }
1081
+
1082
+
1083
+ /* ============================================
1084
+ 17. LIGHT MODE OVERRIDES
1085
+ ============================================ */
1086
+
1087
+ [data-bs-theme="light"] .ng-sidebar {
1088
+ background: #f7f8fa;
1089
+ border-right-color: #e5e7eb;
1090
+ }
1091
+
1092
+ [data-bs-theme="light"] .ng-sidebar-brand-text { color: #1a1a2e; }
1093
+ [data-bs-theme="light"] .ng-sidebar-section-label { color: #9ca3af; }
1094
+
1095
+ [data-bs-theme="light"] .ng-sidebar-item {
1096
+ color: #4b5563;
1097
+ }
1098
+
1099
+ [data-bs-theme="light"] .ng-sidebar-item:hover {
1100
+ background: rgba(124, 106, 239, 0.06);
1101
+ color: #1a1a2e;
1102
+ }
1103
+
1104
+ [data-bs-theme="light"] .ng-sidebar-item.active {
1105
+ background: rgba(124, 106, 239, 0.10);
1106
+ color: #667eea;
1107
+ border-color: rgba(124, 106, 239, 0.25);
1108
+ }
1109
+
1110
+ [data-bs-theme="light"] .ng-sidebar-item.active .ng-sidebar-icon { color: #667eea; }
1111
+ [data-bs-theme="light"] .ng-sidebar-icon { color: #9ca3af; }
1112
+ [data-bs-theme="light"] .ng-sidebar-footer { border-top-color: #e5e7eb; }
1113
+
1114
+ [data-bs-theme="light"] .ng-content {
1115
+ background: #f8f9fa;
1116
+ }
1117
+
1118
+ [data-bs-theme="light"] .ng-glass {
1119
+ background: rgba(255, 255, 255, 0.8);
1120
+ border-color: #e5e7eb;
1121
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
1122
+ backdrop-filter: blur(8px);
1123
+ }
1124
+
1125
+ [data-bs-theme="light"] .ng-content-title { color: #111827; }
1126
+ [data-bs-theme="light"] .ng-content-subtitle { color: #4b5563; }
1127
+ [data-bs-theme="light"] .ng-stat-value { color: #111827; }
1128
+ [data-bs-theme="light"] .ng-stat-label { color: #6b7280; }
1129
+
1130
+ /* Light mode: ensure ALL text is readable (dark text on light bg) */
1131
+ [data-bs-theme="light"] h1,
1132
+ [data-bs-theme="light"] h2,
1133
+ [data-bs-theme="light"] h3,
1134
+ [data-bs-theme="light"] h4,
1135
+ [data-bs-theme="light"] h5,
1136
+ [data-bs-theme="light"] h6 {
1137
+ color: #111827 !important;
1138
+ }
1139
+
1140
+ [data-bs-theme="light"] p,
1141
+ [data-bs-theme="light"] span,
1142
+ [data-bs-theme="light"] div,
1143
+ [data-bs-theme="light"] label,
1144
+ [data-bs-theme="light"] td,
1145
+ [data-bs-theme="light"] th {
1146
+ color: inherit;
1147
+ }
1148
+
1149
+ [data-bs-theme="light"] .text-muted {
1150
+ color: #6b7280 !important;
1151
+ }
1152
+
1153
+ [data-bs-theme="light"] small {
1154
+ color: #6b7280;
1155
+ }
1156
+
1157
+ [data-bs-theme="light"] .card {
1158
+ background: #fff;
1159
+ border-color: #e5e7eb;
1160
+ color: #111827;
1161
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06);
1162
+ }
1163
+
1164
+ [data-bs-theme="light"] .card-body {
1165
+ color: #111827;
1166
+ }
1167
+
1168
+ [data-bs-theme="light"] .card-subtitle,
1169
+ [data-bs-theme="light"] .card h6 {
1170
+ color: #374151 !important;
1171
+ }
1172
+
1173
+ [data-bs-theme="light"] .stat-card .stat-value {
1174
+ color: #111827 !important;
1175
+ }
1176
+
1177
+ [data-bs-theme="light"] .stat-card .stat-icon {
1178
+ color: #667eea !important;
1179
+ }
1180
+
1181
+ [data-bs-theme="light"] .table {
1182
+ color: #111827;
1183
+ }
1184
+
1185
+ [data-bs-theme="light"] .table thead th {
1186
+ color: #374151;
1187
+ }
1188
+
1189
+ [data-bs-theme="light"] .form-control,
1190
+ [data-bs-theme="light"] .form-select {
1191
+ color: #111827 !important;
1192
+ background: #fff !important;
1193
+ border-color: #d1d5db !important;
1194
+ }
1195
+
1196
+ [data-bs-theme="light"] .form-control::placeholder {
1197
+ color: #9ca3af !important;
1198
+ }
1199
+
1200
+ [data-bs-theme="light"] .form-control:focus,
1201
+ [data-bs-theme="light"] .form-select:focus {
1202
+ border-color: #667eea !important;
1203
+ box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.15) !important;
1204
+ }
1205
+
1206
+ [data-bs-theme="light"] .input-group-text {
1207
+ background: #f3f4f6 !important;
1208
+ border-color: #d1d5db !important;
1209
+ color: #6b7280 !important;
1210
+ }
1211
+
1212
+ [data-bs-theme="light"] .alert {
1213
+ color: #111827 !important;
1214
+ }
1215
+
1216
+ [data-bs-theme="light"] .btn-primary {
1217
+ background: #667eea !important;
1218
+ border-color: #667eea !important;
1219
+ color: #fff !important;
1220
+ }
1221
+
1222
+ [data-bs-theme="light"] .btn-success {
1223
+ background: #10b981 !important;
1224
+ border-color: #10b981 !important;
1225
+ }
1226
+
1227
+ [data-bs-theme="light"] .btn-outline-primary {
1228
+ color: #667eea !important;
1229
+ border-color: #667eea !important;
1230
+ }
1231
+
1232
+ [data-bs-theme="light"] .btn-outline-secondary {
1233
+ color: #374151 !important;
1234
+ border-color: #d1d5db !important;
1235
+ }
1236
+
1237
+ [data-bs-theme="light"] .modal-content {
1238
+ background: #fff !important;
1239
+ color: #111827;
1240
+ }
1241
+
1242
+ [data-bs-theme="light"] .dropdown-menu {
1243
+ background: #fff !important;
1244
+ border-color: #e5e7eb !important;
1245
+ }
1246
+
1247
+ [data-bs-theme="light"] .dropdown-item {
1248
+ color: #374151 !important;
1249
+ }
1250
+
1251
+ [data-bs-theme="light"] .badge.bg-light {
1252
+ background: #f3f4f6 !important;
1253
+ color: #111827 !important;
1254
+ }
1255
+
1256
+ [data-bs-theme="light"] .score-bar { background: #e5e7eb; }
1257
+ [data-bs-theme="light"] .confidence-bar { background: #e5e7eb; }
1258
+
1259
+ [data-bs-theme="light"] .memory-detail-content {
1260
+ background: #f9fafb;
1261
+ color: #111827;
1262
+ }
1263
+
1264
+ [data-bs-theme="light"] #graph-container {
1265
+ background: #fff;
1266
+ border-color: #e5e7eb;
1267
+ }
1268
+
1269
+ [data-bs-theme="light"] #event-stream {
1270
+ background: #f9fafb !important;
1271
+ border-color: #e5e7eb !important;
1272
+ color: #111827;
1273
+ }
1274
+
1275
+ [data-bs-theme="light"] footer {
1276
+ color: #6b7280;
1277
+ border-top-color: #e5e7eb;
1278
+ }
1279
+
1280
+ [data-bs-theme="light"] footer a { color: #667eea; }
1281
+
1282
+ /* Light mode: sidebar profile select */
1283
+ [data-bs-theme="light"] .profile-select {
1284
+ background: #fff;
1285
+ border-color: #d1d5db;
1286
+ color: #111827;
1287
+ }
1288
+
1289
+ [data-bs-theme="light"] .ng-btn {
1290
+ background: #fff;
1291
+ border-color: #d1d5db;
1292
+ color: #374151;
1293
+ }
1294
+
1295
+ [data-bs-theme="light"] .ng-btn:hover {
1296
+ background: #f9fafb;
1297
+ border-color: #9ca3af;
1298
+ color: #111827;
1299
+ }
1300
+
1301
+ [data-bs-theme="light"] .ng-sidebar-badge {
1302
+ background: rgba(102, 126, 234, 0.12);
1303
+ color: #667eea;
1304
+ }
1305
+
1306
+ [data-bs-theme="light"] .ng-badge-accent {
1307
+ background: rgba(102, 126, 234, 0.10);
1308
+ color: #667eea;
1309
+ }
1310
+
1311
+ [data-bs-theme="light"] .ng-progress-bar {
1312
+ background: #e5e7eb;
1313
+ }
1314
+
1315
+ [data-bs-theme="light"] .ng-glass {
1316
+ background: #fff;
1317
+ border-color: #e5e7eb;
1318
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
1319
+ backdrop-filter: none;
1320
+ }
1321
+
1322
+ /* Light mode scrollbar */
1323
+ [data-bs-theme="light"] ::-webkit-scrollbar-thumb {
1324
+ background: rgba(0, 0, 0, 0.12);
1325
+ }
1326
+ [data-bs-theme="light"] ::-webkit-scrollbar-thumb:hover {
1327
+ background: rgba(0, 0, 0, 0.22);
1328
+ }
1329
+
1330
+ /* Light mode text visibility fixes */
1331
+ [data-bs-theme="light"] .stat-value,
1332
+ [data-bs-theme="light"] .ng-stat-value,
1333
+ [data-bs-theme="light"] h3,
1334
+ [data-bs-theme="light"] .card-body h3,
1335
+ [data-bs-theme="light"] .card-body .stat-value {
1336
+ color: #1a1a2e !important;
1337
+ }
1338
+
1339
+ [data-bs-theme="light"] .card-body h6,
1340
+ [data-bs-theme="light"] .card-subtitle {
1341
+ color: #4b5563 !important;
1342
+ }
1343
+
1344
+ [data-bs-theme="light"] .card-body p,
1345
+ [data-bs-theme="light"] .card-body .text-muted,
1346
+ [data-bs-theme="light"] .card-body small {
1347
+ color: #6b7280 !important;
1348
+ }
1349
+
1350
+ [data-bs-theme="light"] .card,
1351
+ [data-bs-theme="light"] .stat-card {
1352
+ color: #1a1a2e;
1353
+ }
1354
+
1355
+ [data-bs-theme="light"] .stat-icon {
1356
+ color: #667eea !important;
1357
+ }
1358
+
1359
+ [data-bs-theme="light"] .form-control,
1360
+ [data-bs-theme="light"] .form-select {
1361
+ background: #fff !important;
1362
+ border-color: #d1d5db !important;
1363
+ color: #1a1a2e !important;
1364
+ }
1365
+
1366
+ [data-bs-theme="light"] .form-control::placeholder {
1367
+ color: #9ca3af !important;
1368
+ }
1369
+
1370
+ [data-bs-theme="light"] .alert-info {
1371
+ background: rgba(124, 106, 239, 0.06) !important;
1372
+ border-color: rgba(124, 106, 239, 0.15) !important;
1373
+ color: #1a1a2e !important;
1374
+ }
1375
+
1376
+ [data-bs-theme="light"] .btn-primary {
1377
+ background: #667eea !important;
1378
+ border-color: #667eea !important;
1379
+ color: #fff !important;
1380
+ }
1381
+
1382
+ [data-bs-theme="light"] .btn-success {
1383
+ background: #10b981 !important;
1384
+ border-color: #10b981 !important;
1385
+ color: #fff !important;
1386
+ }
1387
+
1388
+ [data-bs-theme="light"] .badge.bg-light {
1389
+ background: rgba(124, 106, 239, 0.10) !important;
1390
+ color: #667eea !important;
1391
+ }
1392
+
1393
+ [data-bs-theme="light"] footer {
1394
+ color: #6b7280;
1395
+ border-top-color: #e5e7eb;
1396
+ }
1397
+
1398
+ [data-bs-theme="light"] footer a {
1399
+ color: #667eea;
1400
+ }
1401
+
1402
+
1403
+ /* ============================================
1404
+ 18. PRIVACY BLUR MODE (Screen Recording)
1405
+ Blurs memory text content while keeping UI structure visible.
1406
+ Toggle via: Privacy button in sidebar footer or URL ?blur=1
1407
+ ============================================ */
1408
+
1409
+ body.ng-privacy-blur .memory-content,
1410
+ body.ng-privacy-blur .memory-detail-content,
1411
+ body.ng-privacy-blur #chat-messages,
1412
+ body.ng-privacy-blur #quick-recall-results,
1413
+ body.ng-privacy-blur #sigma-detail-content,
1414
+ body.ng-privacy-blur #recall-lab-results,
1415
+ body.ng-privacy-blur #insight-results,
1416
+ body.ng-privacy-blur .cluster-card p,
1417
+ body.ng-privacy-blur .cluster-card .badge,
1418
+ body.ng-privacy-blur #event-stream,
1419
+ body.ng-privacy-blur #compliance-audit-content,
1420
+ body.ng-privacy-blur #behavioral-outcomes-content,
1421
+ body.ng-privacy-blur #behavioral-patterns-content,
1422
+ body.ng-privacy-blur #what-we-learned-content,
1423
+ body.ng-privacy-blur #lifecycle-transitions-content,
1424
+ body.ng-privacy-blur #ingestion-log,
1425
+ body.ng-privacy-blur .ng-glass .summary-preview {
1426
+ filter: blur(5px);
1427
+ user-select: none;
1428
+ transition: filter 0.3s ease;
1429
+ }
1430
+
1431
+ /* Blur table cell text (memory content columns) */
1432
+ body.ng-privacy-blur .memory-table td:nth-child(2),
1433
+ body.ng-privacy-blur .memory-table td:nth-child(3),
1434
+ body.ng-privacy-blur .table tbody td:first-child,
1435
+ body.ng-privacy-blur .table tbody td:nth-child(4) {
1436
+ filter: blur(4px);
1437
+ user-select: none;
1438
+ }
1439
+
1440
+ /* Blur entity cards content but keep names visible */
1441
+ body.ng-privacy-blur .ng-glass > div:nth-child(2) {
1442
+ filter: blur(4px);
1443
+ }
1444
+
1445
+ /* Blur graph node labels */
1446
+ body.ng-privacy-blur #graph-container canvas + div,
1447
+ body.ng-privacy-blur .sigma-label {
1448
+ filter: blur(6px);
1449
+ }
1450
+
1451
+ /* Keep UI chrome sharp — headings, stats, buttons, nav */
1452
+ body.ng-privacy-blur h1,
1453
+ body.ng-privacy-blur h2,
1454
+ body.ng-privacy-blur h3,
1455
+ body.ng-privacy-blur h4,
1456
+ body.ng-privacy-blur h5,
1457
+ body.ng-privacy-blur h6,
1458
+ body.ng-privacy-blur .ng-stat-value,
1459
+ body.ng-privacy-blur .ng-stat-label,
1460
+ body.ng-privacy-blur .ng-sidebar,
1461
+ body.ng-privacy-blur .ng-content-header,
1462
+ body.ng-privacy-blur .ng-btn,
1463
+ body.ng-privacy-blur .btn,
1464
+ body.ng-privacy-blur .badge,
1465
+ body.ng-privacy-blur .nav-link,
1466
+ body.ng-privacy-blur footer,
1467
+ body.ng-privacy-blur .form-control,
1468
+ body.ng-privacy-blur .form-select {
1469
+ filter: none !important;
1470
+ }
1471
+
1472
+ /* Privacy blur indicator bar */
1473
+ body.ng-privacy-blur::before {
1474
+ content: "PRIVACY BLUR ON — Memory content hidden for recording";
1475
+ display: block;
1476
+ position: fixed;
1477
+ top: 0;
1478
+ left: 240px;
1479
+ right: 0;
1480
+ z-index: 9999;
1481
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
1482
+ color: #fff;
1483
+ text-align: center;
1484
+ padding: 4px 16px;
1485
+ font-size: 0.75rem;
1486
+ font-weight: 600;
1487
+ letter-spacing: 0.05em;
1488
+ }
1489
+
1490
+ @media (max-width: 768px) {
1491
+ body.ng-privacy-blur::before {
1492
+ left: 0;
1493
+ }
1494
+ }
1495
+
1496
+
1497
+ /* ============================================
1498
+ 19. RESPONSIVE
1499
+ ============================================ */
1500
+
1501
+ /* Mobile: sidebar collapses to bottom bar */
1502
+ @media (max-width: 768px) {
1503
+ .ng-sidebar {
1504
+ position: fixed;
1505
+ top: auto;
1506
+ bottom: 0;
1507
+ left: 0;
1508
+ right: 0;
1509
+ width: 100%;
1510
+ min-width: 100%;
1511
+ height: auto;
1512
+ max-height: 60px;
1513
+ flex-direction: row;
1514
+ border-right: none;
1515
+ border-top: 1px solid var(--ng-border-subtle);
1516
+ overflow-x: auto;
1517
+ overflow-y: hidden;
1518
+ z-index: var(--ng-z-sidebar);
1519
+ }
1520
+
1521
+ .ng-sidebar-header,
1522
+ .ng-sidebar-section-label,
1523
+ .ng-sidebar-footer {
1524
+ display: none;
1525
+ }
1526
+
1527
+ .ng-sidebar-nav {
1528
+ display: flex;
1529
+ flex-direction: row;
1530
+ padding: var(--ng-space-1);
1531
+ gap: 2px;
1532
+ overflow-x: auto;
1533
+ -webkit-overflow-scrolling: touch;
1534
+ }
1535
+
1536
+ .ng-sidebar-section {
1537
+ display: contents;
1538
+ margin: 0;
1539
+ }
1540
+
1541
+ .ng-sidebar-item {
1542
+ flex-direction: column;
1543
+ padding: 6px 10px;
1544
+ font-size: 0.625rem;
1545
+ gap: 2px;
1546
+ min-width: 56px;
1547
+ text-align: center;
1548
+ white-space: nowrap;
1549
+ }
1550
+
1551
+ .ng-sidebar-icon {
1552
+ font-size: 1.125rem;
1553
+ }
1554
+
1555
+ .ng-sidebar-badge { display: none; }
1556
+
1557
+ .ng-content {
1558
+ margin-left: 0;
1559
+ padding-bottom: 68px;
1560
+ }
1561
+
1562
+ .ng-content-inner {
1563
+ padding: var(--ng-space-4);
1564
+ }
1565
+ }
1566
+
1567
+ /* Tablet: narrower sidebar */
1568
+ @media (min-width: 769px) and (max-width: 1024px) {
1569
+ :root {
1570
+ --ng-sidebar-width: 200px;
1571
+ }
1572
+
1573
+ .ng-sidebar-item {
1574
+ font-size: 0.75rem;
1575
+ padding: 6px var(--ng-space-2);
1576
+ }
1577
+
1578
+ .ng-content-inner {
1579
+ padding: var(--ng-space-4);
1580
+ }
1581
+ }
1582
+
1583
+ /* Large desktop */
1584
+ @media (min-width: 1600px) {
1585
+ .ng-content-inner {
1586
+ max-width: 1600px;
1587
+ }
1588
+ }