@co-engram/viewer 0.1.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 (54) hide show
  1. package/README.md +38 -0
  2. package/dist/brand-logos.d.ts +9 -0
  3. package/dist/brand-logos.d.ts.map +1 -0
  4. package/dist/brand-logos.js +10 -0
  5. package/dist/brand-logos.js.map +1 -0
  6. package/dist/html.d.ts +21 -0
  7. package/dist/html.d.ts.map +1 -0
  8. package/dist/html.js +299 -0
  9. package/dist/html.js.map +1 -0
  10. package/dist/index.d.ts +8 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +8 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/runtime/app.d.ts +11 -0
  15. package/dist/runtime/app.d.ts.map +1 -0
  16. package/dist/runtime/app.js +437 -0
  17. package/dist/runtime/app.js.map +1 -0
  18. package/dist/runtime/decay.d.ts +16 -0
  19. package/dist/runtime/decay.d.ts.map +1 -0
  20. package/dist/runtime/decay.js +108 -0
  21. package/dist/runtime/decay.js.map +1 -0
  22. package/dist/runtime/graph.d.ts +13 -0
  23. package/dist/runtime/graph.d.ts.map +1 -0
  24. package/dist/runtime/graph.js +313 -0
  25. package/dist/runtime/graph.js.map +1 -0
  26. package/dist/runtime/i18n.d.ts +16 -0
  27. package/dist/runtime/i18n.d.ts.map +1 -0
  28. package/dist/runtime/i18n.js +76 -0
  29. package/dist/runtime/i18n.js.map +1 -0
  30. package/dist/runtime/tabs.d.ts +8 -0
  31. package/dist/runtime/tabs.d.ts.map +1 -0
  32. package/dist/runtime/tabs.js +1783 -0
  33. package/dist/runtime/tabs.js.map +1 -0
  34. package/dist/server.d.ts +73 -0
  35. package/dist/server.d.ts.map +1 -0
  36. package/dist/server.js +985 -0
  37. package/dist/server.js.map +1 -0
  38. package/dist/styles.d.ts +13 -0
  39. package/dist/styles.d.ts.map +1 -0
  40. package/dist/styles.js +1632 -0
  41. package/dist/styles.js.map +1 -0
  42. package/dist/vendor/dompurify-source.d.ts +11 -0
  43. package/dist/vendor/dompurify-source.d.ts.map +1 -0
  44. package/dist/vendor/dompurify-source.js +15 -0
  45. package/dist/vendor/dompurify-source.js.map +1 -0
  46. package/dist/vendor/marked-source.d.ts +11 -0
  47. package/dist/vendor/marked-source.d.ts.map +1 -0
  48. package/dist/vendor/marked-source.js +18 -0
  49. package/dist/vendor/marked-source.js.map +1 -0
  50. package/dist/vendor/vis-network-source.d.ts +11 -0
  51. package/dist/vendor/vis-network-source.d.ts.map +1 -0
  52. package/dist/vendor/vis-network-source.js +46 -0
  53. package/dist/vendor/vis-network-source.js.map +1 -0
  54. package/package.json +61 -0
package/dist/styles.js ADDED
@@ -0,0 +1,1632 @@
1
+ /**
2
+ * Viewer v2 CSS — 科幻神经元风格。
3
+ *
4
+ * 设计理念:
5
+ * - 深邃的太空背景 + 神经元脉冲光晕
6
+ * - 玻璃态卡片(backdrop-filter blur + 半透明)
7
+ * - 青色主色 (#5eead4) + 紫色辅色 (#c084fc),代表 AI + 神经元
8
+ * - 信号感发光、流光边框
9
+ *
10
+ * @module @co-engram/claude-code/viewer
11
+ */
12
+ export const VIEWER_CSS = `
13
+ :root {
14
+ color-scheme: dark;
15
+ /* 基础色 */
16
+ --bg-deep: #050816;
17
+ --bg: #0a0e1f;
18
+ --bg-elev: #0f1530;
19
+ --fg: #e2e8f0;
20
+ --fg-bright: #f8fafc;
21
+ --fg-muted: #6b7693;
22
+ --fg-dim: #4a5378;
23
+ --border: rgba(94, 234, 212, 0.12);
24
+ --border-strong: rgba(94, 234, 212, 0.28);
25
+ --border-glow: rgba(94, 234, 212, 0.5);
26
+ --accent: #5eead4; /* 青绿 - 神经元电信号 */
27
+ --accent-2: #c084fc; /* 紫色 - AI 智慧感 */
28
+ --accent-warm: #fbbf24; /* 琥珀 - 能量、提醒 */
29
+ --accent-fg: #050816;
30
+ --panel-bg: rgba(15, 21, 48, 0.55);
31
+ --panel-bg-solid: #0f1530;
32
+ --panel-bg-alt: rgba(94, 234, 212, 0.04);
33
+ --chip-bg: rgba(94, 234, 212, 0.08);
34
+ --shadow: 0 0 0 1px rgba(94,234,212,.06), 0 2px 8px rgba(0,0,0,.3);
35
+ --shadow-lift: 0 0 0 1px rgba(94,234,212,.15), 0 12px 32px rgba(0,0,0,.5), 0 0 32px rgba(94,234,212,.05);
36
+ --glow-cyan: 0 0 16px rgba(94, 234, 212, 0.35);
37
+ --glow-purple: 0 0 20px rgba(192, 132, 252, 0.3);
38
+ --radius: 6px;
39
+ --radius-lg: 12px;
40
+
41
+ /* SynapseFamily 配色 */
42
+ --fam-structural: #60a5fa;
43
+ --fam-causal: #fb923c;
44
+ --fam-evidential: #34d399;
45
+ --fam-temporal: #a78bfa;
46
+ --fam-modulatory: #94a3b8;
47
+ --fam-contradicts: #f43f5e;
48
+
49
+ /* EngramKind 配色 */
50
+ --kind-fact: #34d399;
51
+ --kind-observation: #60a5fa;
52
+ --kind-pattern: #a78bfa;
53
+ --kind-procedure: #fb923c;
54
+ --kind-hypothesis: #f43f5e;
55
+
56
+ /* Audit action 类别配色 */
57
+ --audit-state: #60a5fa;
58
+ --audit-effective: #34d399;
59
+ --audit-contradicted: #f43f5e;
60
+ --audit-proposal: #a78bfa;
61
+ }
62
+
63
+ * { box-sizing: border-box; }
64
+ html, body { height: 100%; }
65
+ body {
66
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
67
+ margin: 0;
68
+ color: var(--fg);
69
+ line-height: 1.55;
70
+ font-size: 14px;
71
+ -webkit-font-smoothing: antialiased;
72
+ background:
73
+ radial-gradient(ellipse 80% 50% at 20% 0%, rgba(94, 234, 212, 0.08), transparent 60%),
74
+ radial-gradient(ellipse 60% 50% at 80% 100%, rgba(192, 132, 252, 0.08), transparent 60%),
75
+ radial-gradient(ellipse 100% 60% at 50% 50%, rgba(15, 21, 48, 0.4), transparent 70%),
76
+ var(--bg-deep);
77
+ background-attachment: fixed;
78
+ min-height: 100vh;
79
+ }
80
+
81
+ /* 神经元网格背景(微妙) */
82
+ body::before {
83
+ content: '';
84
+ position: fixed;
85
+ inset: 0;
86
+ background-image:
87
+ linear-gradient(rgba(94, 234, 212, 0.025) 1px, transparent 1px),
88
+ linear-gradient(90deg, rgba(94, 234, 212, 0.025) 1px, transparent 1px);
89
+ background-size: 40px 40px;
90
+ pointer-events: none;
91
+ z-index: 0;
92
+ mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
93
+ -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 80%);
94
+ }
95
+
96
+ /* === Layout === */
97
+ header.app-header {
98
+ position: sticky;
99
+ top: 0;
100
+ z-index: 10;
101
+ background: linear-gradient(180deg, rgba(10, 14, 31, 0.92) 0%, rgba(10, 14, 31, 0.78) 100%);
102
+ backdrop-filter: blur(20px) saturate(140%);
103
+ -webkit-backdrop-filter: blur(20px) saturate(140%);
104
+ border-bottom: 1px solid var(--border);
105
+ padding: 0.85rem 1.5rem;
106
+ }
107
+ header.app-header h1 {
108
+ margin: 0;
109
+ font-size: 1.5rem;
110
+ font-weight: 500;
111
+ display: inline-block;
112
+ background: linear-gradient(90deg, #bec7d2 0%, #b8941d 100%);
113
+ -webkit-background-clip: text;
114
+ background-clip: text;
115
+ -webkit-text-fill-color: transparent;
116
+ letter-spacing: 0.02em;
117
+ }
118
+ /* (h1::before 的 ◉ 装饰已由 .brand-logo 中的真实 logo 取代) */
119
+ .brand {
120
+ display: inline-flex;
121
+ align-items: center;
122
+ gap: 0.7rem;
123
+ }
124
+ .brand-text {
125
+ display: flex;
126
+ flex-direction: column;
127
+ gap: 0.55rem;
128
+ line-height: 1.15;
129
+ }
130
+ .brand-slogan {
131
+ font-size: 1.05rem;
132
+ font-weight: 400;
133
+ color: var(--fg-muted);
134
+ letter-spacing: 0.04em;
135
+ opacity: 0.85;
136
+ /* 不继承 h1 的渐变文字色 */
137
+ -webkit-text-fill-color: var(--fg-muted);
138
+ }
139
+ .brand-logo {
140
+ display: inline-flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ width: 94.5px;
144
+ height: 94.5px;
145
+ flex-shrink: 0;
146
+ }
147
+ .brand-logo svg {
148
+ width: 100%;
149
+ height: 100%;
150
+ display: block;
151
+ animation: brand-breathe 4s ease-in-out infinite;
152
+ }
153
+ /* 呼吸灯效果:opacity + 金色 drop-shadow 同步脉动,模拟"记忆印迹在呼吸" */
154
+ @keyframes brand-breathe {
155
+ 0%, 100% {
156
+ opacity: 0.82;
157
+ filter: drop-shadow(0 0 3px rgba(184, 148, 29, 0.25)) drop-shadow(0 0 6px rgba(190, 199, 210, 0.15));
158
+ }
159
+ 50% {
160
+ opacity: 1;
161
+ filter: drop-shadow(0 0 8px rgba(184, 148, 29, 0.55)) drop-shadow(0 0 16px rgba(212, 168, 56, 0.4));
162
+ }
163
+ }
164
+ @media (prefers-reduced-motion: reduce) {
165
+ .brand-logo svg { animation: none; }
166
+ }
167
+ /* 浅色系统主题:隐藏 dark 版 logo */
168
+ .brand-logo-dark { display: none; }
169
+ /* 深色系统主题:切换为 dark 版 logo */
170
+ @media (prefers-color-scheme: dark) {
171
+ .brand-logo-light { display: none; }
172
+ .brand-logo-dark { display: inline-flex; }
173
+ }
174
+ header.app-header nav {
175
+ display: inline-flex;
176
+ gap: 0.15rem;
177
+ margin-left: 1.5rem;
178
+ flex-wrap: wrap;
179
+ }
180
+ .tab {
181
+ background: transparent;
182
+ border: 1px solid transparent;
183
+ color: var(--fg-muted);
184
+ padding: 0.4rem 0.85rem;
185
+ border-radius: var(--radius);
186
+ cursor: pointer;
187
+ font-size: 0.82rem;
188
+ font-weight: 500;
189
+ transition: all .2s;
190
+ position: relative;
191
+ font-family: inherit;
192
+ }
193
+ .tab:hover {
194
+ background: var(--chip-bg);
195
+ color: var(--accent);
196
+ }
197
+ .tab.active {
198
+ background: linear-gradient(135deg, rgba(94, 234, 212, 0.12), rgba(192, 132, 252, 0.08));
199
+ color: var(--accent);
200
+ border-color: var(--border-strong);
201
+ box-shadow: inset 0 0 0 1px rgba(94, 234, 212, 0.15);
202
+ }
203
+ .tab.active::after {
204
+ content: '';
205
+ position: absolute;
206
+ left: 50%;
207
+ bottom: -1px;
208
+ transform: translateX(-50%);
209
+ width: 30%;
210
+ height: 1px;
211
+ background: var(--accent);
212
+ box-shadow: 0 0 8px var(--accent);
213
+ }
214
+ .auth-bar {
215
+ margin-top: 0.6rem;
216
+ font-size: 0.78rem;
217
+ display: flex;
218
+ align-items: center;
219
+ gap: 0.5rem;
220
+ color: var(--fg-muted);
221
+ }
222
+ .auth-bar input {
223
+ background: rgba(94, 234, 212, 0.05);
224
+ border: 1px solid var(--border);
225
+ color: var(--fg);
226
+ padding: 0.3rem 0.6rem;
227
+ border-radius: 4px;
228
+ font-size: 0.78rem;
229
+ font-family: inherit;
230
+ }
231
+ .auth-bar input:focus {
232
+ outline: none;
233
+ border-color: var(--accent);
234
+ box-shadow: 0 0 0 2px rgba(94, 234, 212, 0.15);
235
+ }
236
+
237
+ main {
238
+ max-width: 1400px;
239
+ margin: 0 auto;
240
+ padding: 1.5rem 1.5rem 3rem;
241
+ position: relative;
242
+ z-index: 1;
243
+ }
244
+ section.tab-panel { display: none; }
245
+ section.tab-panel.active { display: block; animation: fade-in .25s ease-out; }
246
+ @keyframes fade-in {
247
+ from { opacity: 0; transform: translateY(4px); }
248
+ to { opacity: 1; transform: translateY(0); }
249
+ }
250
+
251
+ /* === Search === */
252
+ .search-bar {
253
+ display: flex;
254
+ gap: 0.5rem;
255
+ margin-bottom: 1.25rem;
256
+ }
257
+ .search-bar input {
258
+ flex: 1;
259
+ background: var(--panel-bg);
260
+ backdrop-filter: blur(12px);
261
+ -webkit-backdrop-filter: blur(12px);
262
+ border: 1px solid var(--border);
263
+ color: var(--fg);
264
+ padding: 0.6rem 1rem;
265
+ border-radius: var(--radius);
266
+ font-size: 0.88rem;
267
+ font-family: inherit;
268
+ transition: all .2s;
269
+ }
270
+ .search-bar input::placeholder { color: var(--fg-dim); }
271
+ .search-bar input:focus {
272
+ outline: none;
273
+ border-color: var(--accent);
274
+ box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12), var(--glow-cyan);
275
+ }
276
+ .search-bar button {
277
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
278
+ color: var(--accent-fg);
279
+ border: none;
280
+ padding: 0.6rem 1.4rem;
281
+ border-radius: var(--radius);
282
+ cursor: pointer;
283
+ font-weight: 600;
284
+ font-family: inherit;
285
+ font-size: 0.85rem;
286
+ transition: all .2s;
287
+ }
288
+ .search-bar button:hover {
289
+ filter: brightness(1.15);
290
+ box-shadow: var(--glow-cyan);
291
+ }
292
+ .search-bar button[type=button] {
293
+ background: transparent;
294
+ color: var(--fg-dim);
295
+ border: 1px solid var(--border);
296
+ padding: 0.55rem 1.1rem;
297
+ font-weight: 500;
298
+ }
299
+ .search-bar button[type=button]:hover {
300
+ color: var(--fg);
301
+ border-color: var(--accent);
302
+ filter: none;
303
+ box-shadow: none;
304
+ }
305
+
306
+ /* === Cards & Grid === */
307
+ .grid {
308
+ display: grid;
309
+ gap: 0.85rem;
310
+ }
311
+ .grid.cols-3 { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
312
+ .grid.cols-4 { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
313
+
314
+ .card {
315
+ background: var(--panel-bg);
316
+ backdrop-filter: blur(12px) saturate(140%);
317
+ -webkit-backdrop-filter: blur(12px) saturate(140%);
318
+ border: 1px solid var(--border);
319
+ border-radius: var(--radius-lg);
320
+ padding: 1rem 1.1rem;
321
+ box-shadow: var(--shadow);
322
+ transition: all .2s;
323
+ position: relative;
324
+ overflow: hidden;
325
+ }
326
+ .card::before {
327
+ content: '';
328
+ position: absolute;
329
+ inset: 0;
330
+ background: linear-gradient(135deg, rgba(94, 234, 212, 0) 0%, rgba(94, 234, 212, 0.04) 100%);
331
+ pointer-events: none;
332
+ opacity: 0;
333
+ transition: opacity .25s;
334
+ }
335
+ .card:hover {
336
+ border-color: var(--border-strong);
337
+ box-shadow: var(--shadow-lift);
338
+ transform: translateY(-1px);
339
+ }
340
+ .card:hover::before { opacity: 1; }
341
+ .card-title {
342
+ font-weight: 600;
343
+ font-size: 0.95rem;
344
+ margin: 0 0 0.5rem;
345
+ cursor: pointer;
346
+ color: var(--fg-bright);
347
+ transition: color .15s;
348
+ }
349
+ .card-title:hover { color: var(--accent); text-shadow: 0 0 8px rgba(94, 234, 212, 0.4); }
350
+ .card-meta {
351
+ font-size: 0.75rem;
352
+ color: var(--fg-muted);
353
+ display: flex;
354
+ flex-wrap: wrap;
355
+ gap: 0.4rem 0.85rem;
356
+ margin-top: 0.6rem;
357
+ }
358
+
359
+ .chip {
360
+ display: inline-flex;
361
+ align-items: center;
362
+ gap: 0.25rem;
363
+ padding: 0.15rem 0.55rem;
364
+ border-radius: 999px;
365
+ font-size: 0.7rem;
366
+ font-weight: 500;
367
+ background: var(--chip-bg);
368
+ color: var(--fg);
369
+ border: 1px solid transparent;
370
+ font-family: inherit;
371
+ }
372
+ .chip.kind-fact { background: rgba(52, 211, 153, 0.12); color: var(--kind-fact); border-color: rgba(52, 211, 153, 0.25); }
373
+ .chip.kind-observation { background: rgba(96, 165, 250, 0.12); color: var(--kind-observation); border-color: rgba(96, 165, 250, 0.25); }
374
+ .chip.kind-pattern { background: rgba(167, 139, 250, 0.12); color: var(--kind-pattern); border-color: rgba(167, 139, 250, 0.25); }
375
+ .chip.kind-procedure { background: rgba(251, 146, 60, 0.12); color: var(--kind-procedure); border-color: rgba(251, 146, 60, 0.25); }
376
+ .chip.kind-hypothesis { background: rgba(244, 63, 94, 0.12); color: var(--kind-hypothesis); border-color: rgba(244, 63, 94, 0.25); }
377
+ .chip.dot::before {
378
+ content: '';
379
+ display: inline-block;
380
+ width: 6px;
381
+ height: 6px;
382
+ border-radius: 50%;
383
+ background: currentColor;
384
+ margin-right: 2px;
385
+ box-shadow: 0 0 4px currentColor;
386
+ }
387
+
388
+ /* === Filter bar === */
389
+ .filter-bar {
390
+ display: flex;
391
+ flex-wrap: wrap;
392
+ gap: 0.6rem;
393
+ align-items: center;
394
+ margin-bottom: 1rem;
395
+ padding: 0.75rem 1rem;
396
+ background: var(--panel-bg);
397
+ backdrop-filter: blur(12px);
398
+ -webkit-backdrop-filter: blur(12px);
399
+ border: 1px solid var(--border);
400
+ border-radius: var(--radius);
401
+ }
402
+ .filter-bar select, .filter-bar input[type=text], .filter-bar input[type=search] {
403
+ background: rgba(94, 234, 212, 0.04);
404
+ border: 1px solid var(--border);
405
+ color: var(--fg);
406
+ padding: 0.35rem 0.6rem;
407
+ border-radius: 4px;
408
+ font-size: 0.8rem;
409
+ min-width: 100px;
410
+ font-family: inherit;
411
+ }
412
+ .filter-bar select:focus, .filter-bar input:focus {
413
+ outline: none;
414
+ border-color: var(--accent);
415
+ }
416
+ .filter-bar label {
417
+ font-size: 0.75rem;
418
+ color: var(--fg-muted);
419
+ display: inline-flex;
420
+ align-items: center;
421
+ gap: 0.35rem;
422
+ }
423
+ .filter-bar .spacer { flex: 1; }
424
+
425
+ /* === KPI (stats) === */
426
+ .kpi-grid {
427
+ display: grid;
428
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
429
+ gap: 0.9rem;
430
+ margin-bottom: 1.75rem;
431
+ }
432
+ .kpi {
433
+ background: var(--panel-bg);
434
+ backdrop-filter: blur(12px) saturate(140%);
435
+ -webkit-backdrop-filter: blur(12px) saturate(140%);
436
+ border: 1px solid var(--border);
437
+ border-radius: var(--radius-lg);
438
+ padding: 1rem 1.15rem;
439
+ box-shadow: var(--shadow);
440
+ cursor: pointer;
441
+ transition: all .2s;
442
+ position: relative;
443
+ overflow: hidden;
444
+ }
445
+ .kpi::before {
446
+ content: '';
447
+ position: absolute;
448
+ top: 0;
449
+ left: 0;
450
+ right: 0;
451
+ height: 2px;
452
+ background: linear-gradient(90deg, var(--accent), var(--accent-2));
453
+ opacity: 0;
454
+ transition: opacity .25s;
455
+ }
456
+ .kpi::after {
457
+ content: '→';
458
+ position: absolute;
459
+ right: 1rem;
460
+ bottom: 0.85rem;
461
+ color: var(--fg-dim);
462
+ font-size: 1rem;
463
+ opacity: 0;
464
+ transition: all .2s;
465
+ }
466
+ .kpi:hover {
467
+ border-color: var(--border-strong);
468
+ box-shadow: var(--shadow-lift), var(--glow-cyan);
469
+ transform: translateY(-2px);
470
+ }
471
+ .kpi:hover::before { opacity: 1; }
472
+ .kpi:hover::after { opacity: 1; right: 0.85rem; color: var(--accent); }
473
+ .kpi-label {
474
+ font-size: 0.7rem;
475
+ text-transform: uppercase;
476
+ letter-spacing: 0.08em;
477
+ color: var(--fg-muted);
478
+ margin-bottom: 0.35rem;
479
+ font-weight: 500;
480
+ }
481
+ .kpi-value {
482
+ font-size: 1.85rem;
483
+ font-weight: 700;
484
+ color: var(--fg-bright);
485
+ font-variant-numeric: tabular-nums;
486
+ background: linear-gradient(135deg, var(--fg-bright) 0%, var(--accent) 100%);
487
+ -webkit-background-clip: text;
488
+ background-clip: text;
489
+ -webkit-text-fill-color: transparent;
490
+ }
491
+ .kpi-sub {
492
+ font-size: 0.7rem;
493
+ color: var(--fg-muted);
494
+ margin-top: 0.2rem;
495
+ }
496
+
497
+ /* === Bars (stats distribution) === */
498
+ .bar-row {
499
+ display: grid;
500
+ grid-template-columns: 110px 1fr 40px;
501
+ gap: 0.6rem;
502
+ align-items: center;
503
+ font-size: 0.8rem;
504
+ margin-bottom: 0.4rem;
505
+ }
506
+ .bar-row .bar-label { color: var(--fg-muted); }
507
+ .bar-row .bar-track {
508
+ background: rgba(94, 234, 212, 0.06);
509
+ border-radius: 4px;
510
+ height: 14px;
511
+ overflow: hidden;
512
+ position: relative;
513
+ }
514
+ .bar-row .bar-fill {
515
+ height: 100%;
516
+ border-radius: 4px;
517
+ transition: width .4s;
518
+ background: linear-gradient(90deg, var(--accent), var(--accent-2));
519
+ box-shadow: 0 0 8px rgba(94, 234, 212, 0.4);
520
+ }
521
+ .bar-row .bar-value { text-align: right; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
522
+
523
+ /* === Graph overlay === */
524
+ .graph-container {
525
+ position: relative;
526
+ background: var(--panel-bg);
527
+ backdrop-filter: blur(8px);
528
+ -webkit-backdrop-filter: blur(8px);
529
+ border: 1px solid var(--border);
530
+ border-radius: var(--radius-lg);
531
+ height: calc(100vh - 200px);
532
+ min-height: 480px;
533
+ overflow: hidden;
534
+ }
535
+ #graph-canvas { width: 100%; height: 100%; }
536
+ #graph-canvas .vis-network {
537
+ background: transparent !important;
538
+ }
539
+ .graph-toolbar {
540
+ position: absolute;
541
+ top: 0.85rem;
542
+ left: 0.85rem;
543
+ z-index: 5;
544
+ display: flex;
545
+ flex-direction: column;
546
+ gap: 0.4rem;
547
+ background: rgba(15, 21, 48, 0.82);
548
+ backdrop-filter: blur(16px) saturate(140%);
549
+ -webkit-backdrop-filter: blur(16px) saturate(140%);
550
+ border: 1px solid var(--border);
551
+ border-radius: var(--radius);
552
+ padding: 0.55rem 0.65rem;
553
+ font-size: 0.72rem;
554
+ box-shadow: var(--shadow);
555
+ width: 240px;
556
+ max-width: 260px;
557
+ max-height: calc(100% - 1.7rem);
558
+ overflow-y: auto;
559
+ overflow-x: hidden;
560
+ }
561
+ .graph-toolbar::-webkit-scrollbar { width: 6px; }
562
+ .graph-toolbar::-webkit-scrollbar-track { background: transparent; }
563
+ .graph-toolbar::-webkit-scrollbar-thumb {
564
+ background: rgba(94, 234, 212, 0.2);
565
+ border-radius: 3px;
566
+ }
567
+ .graph-toolbar::-webkit-scrollbar-thumb:hover { background: rgba(94, 234, 212, 0.4); }
568
+
569
+ /* 操作按钮行:横排 */
570
+ .graph-toolbar .toolbar-actions {
571
+ display: grid;
572
+ grid-template-columns: repeat(3, 1fr);
573
+ gap: 0.3rem;
574
+ }
575
+ .graph-toolbar .toolbar-actions button.mini {
576
+ padding: 0.3rem 0.2rem;
577
+ text-align: center;
578
+ font-size: 0.68rem;
579
+ }
580
+
581
+ .graph-toolbar .group { display: flex; flex-direction: column; gap: 0.2rem; }
582
+ .graph-toolbar .group.kind-grid {
583
+ display: grid;
584
+ grid-template-columns: repeat(2, minmax(0, 1fr));
585
+ gap: 0.2rem 0.4rem;
586
+ }
587
+ .graph-toolbar .group-title {
588
+ font-size: 0.65rem;
589
+ text-transform: uppercase;
590
+ letter-spacing: 0.08em;
591
+ color: var(--fg-muted);
592
+ margin-top: 0.4rem;
593
+ font-weight: 500;
594
+ padding-bottom: 0.2rem;
595
+ border-bottom: 1px dashed var(--border);
596
+ }
597
+ .graph-toolbar .group-title:first-child { margin-top: 0; }
598
+
599
+ /* 族分组(fieldset) */
600
+ .graph-toolbar .family-group {
601
+ border: none;
602
+ margin: 0;
603
+ padding: 0;
604
+ border-left: 2px solid var(--border);
605
+ padding-left: 0.4rem;
606
+ }
607
+ .graph-toolbar .family-group legend {
608
+ font-size: 0.66rem;
609
+ font-weight: 500;
610
+ color: var(--fg);
611
+ padding: 0;
612
+ margin-bottom: 0.2rem;
613
+ cursor: default;
614
+ display: flex;
615
+ align-items: center;
616
+ gap: 0.3rem;
617
+ }
618
+ .graph-toolbar .family-dot {
619
+ display: inline-block;
620
+ width: 8px;
621
+ height: 8px;
622
+ border-radius: 50%;
623
+ box-shadow: 0 0 4px currentColor;
624
+ }
625
+ .graph-toolbar .family-kinds {
626
+ display: grid;
627
+ grid-template-columns: repeat(2, minmax(0, 1fr));
628
+ gap: 0.18rem 0.35rem;
629
+ }
630
+ .graph-toolbar .family-kinds label {
631
+ font-size: 0.68rem;
632
+ }
633
+
634
+ .graph-toolbar label {
635
+ display: flex;
636
+ align-items: center;
637
+ gap: 0.3rem;
638
+ cursor: pointer;
639
+ user-select: none;
640
+ color: var(--fg);
641
+ overflow: hidden;
642
+ text-overflow: ellipsis;
643
+ white-space: nowrap;
644
+ }
645
+ .graph-toolbar label:hover { color: var(--accent); }
646
+ .graph-toolbar .swatch {
647
+ width: 9px;
648
+ height: 9px;
649
+ border-radius: 2px;
650
+ flex-shrink: 0;
651
+ box-shadow: 0 0 4px currentColor;
652
+ }
653
+ .graph-toolbar input[type=checkbox] {
654
+ accent-color: var(--accent);
655
+ flex-shrink: 0;
656
+ }
657
+ .graph-toolbar button.mini {
658
+ background: rgba(94, 234, 212, 0.08);
659
+ border: 1px solid var(--border);
660
+ color: var(--fg);
661
+ padding: 0.25rem 0.55rem;
662
+ border-radius: 4px;
663
+ cursor: pointer;
664
+ font-size: 0.7rem;
665
+ font-family: inherit;
666
+ transition: all .15s;
667
+ }
668
+ .graph-toolbar button.mini:hover {
669
+ border-color: var(--accent);
670
+ color: var(--accent);
671
+ box-shadow: 0 0 8px rgba(94, 234, 212, 0.2);
672
+ }
673
+
674
+ /* === Detail drawer (right side) === */
675
+ .drawer {
676
+ position: fixed;
677
+ top: 0;
678
+ right: 0;
679
+ width: 480px;
680
+ max-width: 92vw;
681
+ height: 100vh;
682
+ background: linear-gradient(180deg, rgba(15, 21, 48, 0.95), rgba(10, 14, 31, 0.95));
683
+ backdrop-filter: blur(24px) saturate(140%);
684
+ -webkit-backdrop-filter: blur(24px) saturate(140%);
685
+ border-left: 1px solid var(--border-strong);
686
+ box-shadow: -20px 0 60px rgba(0, 0, 0, 0.5), -1px 0 0 var(--accent);
687
+ transform: translateX(100%);
688
+ transition: transform .3s cubic-bezier(0.16, 1, 0.3, 1);
689
+ z-index: 100;
690
+ overflow-y: auto;
691
+ padding: 1.5rem 1.75rem;
692
+ }
693
+ .drawer.open { transform: translateX(0); }
694
+ .drawer-close {
695
+ position: absolute;
696
+ top: 0.85rem;
697
+ right: 0.85rem;
698
+ background: rgba(94, 234, 212, 0.08);
699
+ border: 1px solid var(--border);
700
+ border-radius: 4px;
701
+ cursor: pointer;
702
+ color: var(--fg-muted);
703
+ padding: 0.25rem 0.6rem;
704
+ font-size: 0.85rem;
705
+ transition: all .15s;
706
+ }
707
+ .drawer-close:hover {
708
+ color: var(--accent);
709
+ border-color: var(--accent);
710
+ box-shadow: 0 0 8px rgba(94, 234, 212, 0.2);
711
+ }
712
+ .drawer h2 {
713
+ margin: 0 0 0.6rem;
714
+ font-size: 1.2rem;
715
+ font-weight: 600;
716
+ color: var(--fg-bright);
717
+ }
718
+ .drawer h3 {
719
+ margin: 1.2rem 0 0.5rem;
720
+ font-size: 0.75rem;
721
+ color: var(--accent);
722
+ text-transform: uppercase;
723
+ letter-spacing: 0.1em;
724
+ font-weight: 600;
725
+ }
726
+ .drawer .field { margin-bottom: 0.6rem; font-size: 0.82rem; }
727
+ .drawer .field-label {
728
+ color: var(--fg-muted);
729
+ margin-right: 0.45rem;
730
+ font-size: 0.75rem;
731
+ text-transform: uppercase;
732
+ letter-spacing: 0.05em;
733
+ }
734
+ .drawer label.field-label {
735
+ display: block;
736
+ margin: 0 0 0.3rem;
737
+ color: var(--accent);
738
+ text-transform: none;
739
+ letter-spacing: 0.02em;
740
+ font-size: 0.78rem;
741
+ }
742
+ .section-title {
743
+ margin: 0 0 0.7rem;
744
+ font-size: 0.78rem;
745
+ color: var(--accent);
746
+ text-transform: uppercase;
747
+ letter-spacing: 0.1em;
748
+ font-weight: 600;
749
+ }
750
+ .drawer .field-value { color: var(--fg); }
751
+ .drawer .editable-input,
752
+ .drawer .editable-textarea,
753
+ .drawer input[type=text],
754
+ .drawer input[type=number],
755
+ .drawer textarea,
756
+ .drawer select {
757
+ background: rgba(94, 234, 212, 0.04);
758
+ border: 1px solid var(--border);
759
+ color: var(--fg);
760
+ padding: 0.45rem 0.65rem;
761
+ border-radius: 4px;
762
+ font-family: inherit;
763
+ font-size: 0.82rem;
764
+ width: 100%;
765
+ transition: all .15s;
766
+ }
767
+ .drawer textarea { resize: vertical; min-height: 80px; font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace; }
768
+ .drawer input:focus, .drawer textarea:focus, .drawer select:focus {
769
+ outline: none;
770
+ border-color: var(--accent);
771
+ box-shadow: 0 0 0 2px rgba(94, 234, 212, 0.15);
772
+ }
773
+
774
+ /* === Audit timeline === */
775
+ .timeline { display: flex; flex-direction: column; gap: 0.5rem; }
776
+ .timeline-row {
777
+ display: grid;
778
+ grid-template-columns: 110px 24px 160px 1fr auto;
779
+ gap: 0.7rem;
780
+ align-items: center;
781
+ padding: 0.6rem 0.9rem;
782
+ background: var(--panel-bg);
783
+ backdrop-filter: blur(8px);
784
+ -webkit-backdrop-filter: blur(8px);
785
+ border: 1px solid var(--border);
786
+ border-radius: var(--radius);
787
+ font-size: 0.8rem;
788
+ transition: all .15s;
789
+ }
790
+ .timeline-row:hover {
791
+ border-color: var(--border-strong);
792
+ box-shadow: var(--shadow);
793
+ }
794
+ .timeline-row .ts {
795
+ color: var(--fg-muted);
796
+ font-variant-numeric: tabular-nums;
797
+ font-size: 0.74rem;
798
+ cursor: help;
799
+ }
800
+ .timeline-row .actor-icon {
801
+ width: 22px;
802
+ height: 22px;
803
+ border-radius: 50%;
804
+ display: inline-flex;
805
+ align-items: center;
806
+ justify-content: center;
807
+ font-size: 0.68rem;
808
+ font-weight: 700;
809
+ color: white;
810
+ border: 1px solid rgba(255, 255, 255, 0.1);
811
+ }
812
+ .timeline-row .actor-icon.user { background: linear-gradient(135deg, #3b82f6, #60a5fa); }
813
+ .timeline-row .actor-icon.llm { background: linear-gradient(135deg, #8b5cf6, #c084fc); }
814
+ .timeline-row .actor-icon.system { background: linear-gradient(135deg, #475569, #94a3b8); }
815
+ .timeline-row .action {
816
+ font-weight: 600;
817
+ font-size: 0.72rem;
818
+ padding: 0.18rem 0.6rem;
819
+ border-radius: 999px;
820
+ display: inline-block;
821
+ text-align: center;
822
+ border: 1px solid transparent;
823
+ }
824
+ .timeline-row .action.audit-state { background: rgba(96, 165, 250, 0.12); color: var(--audit-state); border-color: rgba(96, 165, 250, 0.25); }
825
+ .timeline-row .action.audit-effective { background: rgba(52, 211, 153, 0.12); color: var(--audit-effective); border-color: rgba(52, 211, 153, 0.25); }
826
+ .timeline-row .action.audit-contradicted { background: rgba(244, 63, 94, 0.12); color: var(--audit-contradicted); border-color: rgba(244, 63, 94, 0.25); }
827
+ .timeline-row .action.audit-proposal { background: rgba(167, 139, 250, 0.12); color: var(--audit-proposal); border-color: rgba(167, 139, 250, 0.25); }
828
+ .timeline-row .engram-link {
829
+ color: var(--accent);
830
+ cursor: pointer;
831
+ font-size: 0.75rem;
832
+ text-decoration: underline;
833
+ text-decoration-style: dotted;
834
+ text-underline-offset: 2px;
835
+ }
836
+ .timeline-row .engram-link:hover { text-decoration-style: solid; text-shadow: 0 0 6px rgba(94, 234, 212, 0.5); }
837
+ .timeline-row .metadata {
838
+ font-size: 0.7rem;
839
+ color: var(--fg-muted);
840
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
841
+ max-width: 100%;
842
+ overflow: hidden;
843
+ text-overflow: ellipsis;
844
+ white-space: nowrap;
845
+ }
846
+
847
+ /* === Audit row v2 (structured target cell + metadata) === */
848
+ .timeline-row.audit-row {
849
+ grid-template-columns: 100px 22px 140px minmax(160px, 240px) 1fr;
850
+ align-items: start;
851
+ }
852
+ .timeline-row.audit-row .action {
853
+ /* action 列内容可能比 140px 长(如 update_lifecycle),允许 wrap */
854
+ white-space: normal;
855
+ word-break: break-word;
856
+ line-height: 1.2;
857
+ }
858
+ /* 可点击的 action 标签:点击后按 action 精确过滤 */
859
+ .timeline-row.audit-row .action.action-button {
860
+ cursor: pointer;
861
+ font-family: inherit;
862
+ transition: transform 0.08s ease, filter 0.08s ease;
863
+ }
864
+ .timeline-row.audit-row .action.action-button:hover {
865
+ filter: brightness(1.18);
866
+ transform: translateY(-1px);
867
+ }
868
+ .timeline-row.audit-row .action.action-button:active {
869
+ transform: translateY(0);
870
+ }
871
+ .timeline-row.audit-row .action.action-button.active {
872
+ outline: 2px solid var(--accent);
873
+ outline-offset: 1px;
874
+ }
875
+ /* 当前生效的 action 过滤 chip */
876
+ .audit-action-chip {
877
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
878
+ font-size: 0.72rem;
879
+ background: var(--accent);
880
+ color: var(--bg);
881
+ align-items: center;
882
+ gap: 0.25rem;
883
+ }
884
+ .audit-action-chip code {
885
+ background: rgba(0, 0, 0, 0.18);
886
+ padding: 0.05rem 0.3rem;
887
+ border-radius: 3px;
888
+ color: var(--bg);
889
+ }
890
+ .audit-meta-cell {
891
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
892
+ font-size: 0.72rem;
893
+ min-width: 0;
894
+ }
895
+ .audit-meta-empty { color: var(--fg-muted); opacity: 0.6; }
896
+
897
+ /* 目标 cell:可点按钮 / 灰色删除线 / 占位 */
898
+ .btn-link {
899
+ background: transparent;
900
+ border: 1px solid var(--border-strong);
901
+ color: var(--accent);
902
+ padding: 0.2rem 0.5rem;
903
+ border-radius: var(--radius);
904
+ font-size: 0.7rem;
905
+ cursor: pointer;
906
+ display: inline-flex;
907
+ align-items: center;
908
+ gap: 0.3rem;
909
+ font-family: inherit;
910
+ transition: all .15s;
911
+ }
912
+ .btn-link:hover {
913
+ background: rgba(94, 234, 212, 0.08);
914
+ border-color: var(--accent);
915
+ box-shadow: 0 0 0 2px rgba(94, 234, 212, 0.12);
916
+ }
917
+ .btn-link code {
918
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
919
+ font-size: 0.68rem;
920
+ color: var(--accent);
921
+ }
922
+ .audit-target-gone {
923
+ font-size: 0.7rem;
924
+ color: var(--fg-muted);
925
+ opacity: 0.7;
926
+ display: inline-flex;
927
+ align-items: center;
928
+ gap: 0.3rem;
929
+ }
930
+ .audit-target-gone code { font-family: 'SF Mono', monospace; }
931
+ .audit-target-gone em { font-style: italic; font-size: 0.66rem; opacity: 0.8; }
932
+ .audit-target-none { color: var(--fg-muted); opacity: 0.5; }
933
+
934
+ /* update 类:changed fields 列表 */
935
+ .audit-changes {
936
+ display: flex;
937
+ flex-direction: column;
938
+ gap: 0.18rem;
939
+ border-left: 2px solid var(--border-strong);
940
+ padding-left: 0.6rem;
941
+ }
942
+ .audit-change-row {
943
+ display: grid;
944
+ grid-template-columns: minmax(80px, 130px) 1fr auto 1fr;
945
+ gap: 0.4rem;
946
+ align-items: baseline;
947
+ font-size: 0.7rem;
948
+ }
949
+ .audit-field {
950
+ font-weight: 600;
951
+ color: var(--accent);
952
+ font-family: inherit;
953
+ }
954
+ .audit-from {
955
+ color: var(--fg-muted);
956
+ text-decoration: line-through;
957
+ text-decoration-color: rgba(244, 63, 94, 0.5);
958
+ word-break: break-word;
959
+ }
960
+ .audit-arrow {
961
+ color: var(--fg-muted);
962
+ font-weight: 700;
963
+ }
964
+ .audit-to {
965
+ color: var(--fg);
966
+ word-break: break-word;
967
+ }
968
+ .audit-meta-extra {
969
+ margin-top: 0.3rem;
970
+ font-size: 0.66rem;
971
+ opacity: 0.75;
972
+ display: flex;
973
+ flex-wrap: wrap;
974
+ gap: 0.3rem;
975
+ }
976
+
977
+ /* synapse 类 / 通用 chips */
978
+ .audit-chips {
979
+ display: flex;
980
+ flex-wrap: wrap;
981
+ gap: 0.3rem;
982
+ align-items: center;
983
+ }
984
+ .audit-chips .chip {
985
+ font-size: 0.66rem;
986
+ padding: 0.1rem 0.45rem;
987
+ border-radius: 999px;
988
+ background: rgba(94, 234, 212, 0.08);
989
+ border: 1px solid var(--border-strong);
990
+ color: var(--fg);
991
+ font-family: 'SF Mono', monospace;
992
+ }
993
+ .audit-chips .chip.synapse-chip {
994
+ background: rgba(167, 139, 250, 0.12);
995
+ border-color: rgba(167, 139, 250, 0.3);
996
+ color: #c4b5fd;
997
+ font-weight: 600;
998
+ }
999
+ .audit-chips .chip.kind-contradicts {
1000
+ background: rgba(244, 63, 94, 0.12);
1001
+ border-color: rgba(244, 63, 94, 0.3);
1002
+ color: #fca5a5;
1003
+ }
1004
+ .audit-kv {
1005
+ font-size: 0.68rem;
1006
+ font-family: 'SF Mono', monospace;
1007
+ color: var(--fg);
1008
+ }
1009
+ .audit-kv b { color: var(--accent); font-weight: 600; }
1010
+
1011
+ /* === Table (trash) === */
1012
+ table.data-table {
1013
+ width: 100%;
1014
+ border-collapse: collapse;
1015
+ font-size: 0.8rem;
1016
+ }
1017
+ table.data-table th, table.data-table td {
1018
+ text-align: left;
1019
+ padding: 0.6rem 0.9rem;
1020
+ border-bottom: 1px solid var(--border);
1021
+ }
1022
+ table.data-table th {
1023
+ font-weight: 600;
1024
+ color: var(--accent);
1025
+ font-size: 0.7rem;
1026
+ text-transform: uppercase;
1027
+ letter-spacing: 0.08em;
1028
+ background: rgba(94, 234, 212, 0.04);
1029
+ }
1030
+ table.data-table tr:hover td { background: rgba(94, 234, 212, 0.03); }
1031
+
1032
+ /* === Buttons === */
1033
+ .btn {
1034
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
1035
+ color: var(--accent-fg);
1036
+ border: none;
1037
+ padding: 0.4rem 0.95rem;
1038
+ border-radius: 4px;
1039
+ cursor: pointer;
1040
+ font-size: 0.76rem;
1041
+ font-weight: 600;
1042
+ font-family: inherit;
1043
+ transition: all .2s;
1044
+ }
1045
+ .btn:hover {
1046
+ filter: brightness(1.15);
1047
+ box-shadow: var(--glow-cyan);
1048
+ }
1049
+ .btn.secondary {
1050
+ background: rgba(94, 234, 212, 0.06);
1051
+ color: var(--fg);
1052
+ border: 1px solid var(--border);
1053
+ }
1054
+ .btn.secondary:hover {
1055
+ border-color: var(--accent);
1056
+ color: var(--accent);
1057
+ filter: none;
1058
+ box-shadow: 0 0 8px rgba(94, 234, 212, 0.15);
1059
+ }
1060
+ .btn.danger {
1061
+ background: transparent;
1062
+ color: var(--audit-contradicted);
1063
+ border: 1px solid var(--audit-contradicted);
1064
+ }
1065
+ .btn.danger:hover {
1066
+ background: rgba(244, 63, 94, 0.1);
1067
+ box-shadow: 0 0 8px rgba(244, 63, 94, 0.2);
1068
+ }
1069
+
1070
+ /* === Empty / Loading states === */
1071
+ .empty, .loading {
1072
+ text-align: center;
1073
+ padding: 3rem 1rem;
1074
+ color: var(--fg-muted);
1075
+ font-size: 0.88rem;
1076
+ }
1077
+ .empty .icon {
1078
+ font-size: 2rem;
1079
+ opacity: .5;
1080
+ margin-bottom: 0.75rem;
1081
+ display: block;
1082
+ }
1083
+ .loading {
1084
+ position: relative;
1085
+ }
1086
+ .loading::after {
1087
+ content: '';
1088
+ display: inline-block;
1089
+ width: 14px;
1090
+ height: 14px;
1091
+ margin-left: 0.5rem;
1092
+ border: 2px solid var(--border);
1093
+ border-top-color: var(--accent);
1094
+ border-radius: 50%;
1095
+ animation: spin 0.8s linear infinite;
1096
+ vertical-align: middle;
1097
+ }
1098
+ @keyframes spin {
1099
+ to { transform: rotate(360deg); }
1100
+ }
1101
+
1102
+ /* === Footer === */
1103
+ footer.app-footer {
1104
+ text-align: center;
1105
+ padding: 1.25rem;
1106
+ border-top: 1px solid var(--border);
1107
+ color: var(--fg-dim);
1108
+ font-size: 0.72rem;
1109
+ margin-top: 2.5rem;
1110
+ position: relative;
1111
+ z-index: 1;
1112
+ }
1113
+
1114
+ /* === Misc === */
1115
+ .pre-compact {
1116
+ background: rgba(94, 234, 212, 0.04);
1117
+ border: 1px solid var(--border);
1118
+ border-radius: 4px;
1119
+ padding: 0.6rem;
1120
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
1121
+ font-size: 0.74rem;
1122
+ white-space: pre-wrap;
1123
+ word-break: break-word;
1124
+ max-height: 280px;
1125
+ overflow-y: auto;
1126
+ color: var(--fg);
1127
+ }
1128
+
1129
+ /* === Markdown body (engram/synapse 内容渲染) ===
1130
+ * marked + DOMPurify 后的 HTML 在此容器内排版。
1131
+ * 限定常见 markdown 标签的样式,避免污染主 UI。
1132
+ */
1133
+ .markdown-body {
1134
+ color: var(--fg);
1135
+ font-size: 0.85rem;
1136
+ line-height: 1.65;
1137
+ word-break: break-word;
1138
+ }
1139
+ .markdown-body > :first-child { margin-top: 0; }
1140
+ .markdown-body > :last-child { margin-bottom: 0; }
1141
+ .markdown-body h1,
1142
+ .markdown-body h2,
1143
+ .markdown-body h3,
1144
+ .markdown-body h4,
1145
+ .markdown-body h5,
1146
+ .markdown-body h6 {
1147
+ margin: 1.2em 0 0.5em;
1148
+ line-height: 1.3;
1149
+ color: var(--fg);
1150
+ }
1151
+ .markdown-body h1 { font-size: 1.35em; border-bottom: 1px solid var(--border); padding-bottom: 0.2em; }
1152
+ .markdown-body h2 { font-size: 1.2em; }
1153
+ .markdown-body h3 { font-size: 1.05em; }
1154
+ .markdown-body h4,
1155
+ .markdown-body h5,
1156
+ .markdown-body h6 { font-size: 0.95em; color: var(--fg-muted, var(--fg)); }
1157
+ .markdown-body p { margin: 0.6em 0; }
1158
+ .markdown-body ul,
1159
+ .markdown-body ol { margin: 0.5em 0; padding-left: 1.5em; }
1160
+ .markdown-body li { margin: 0.2em 0; }
1161
+ .markdown-body li > ul,
1162
+ .markdown-body li > ol { margin: 0.2em 0; }
1163
+ .markdown-body a {
1164
+ color: var(--accent-cool, #60a5fa);
1165
+ text-decoration: underline;
1166
+ text-underline-offset: 2px;
1167
+ }
1168
+ .markdown-body a:hover { text-decoration-thickness: 2px; }
1169
+ .markdown-body strong { font-weight: 700; }
1170
+ .markdown-body em { font-style: italic; }
1171
+ .markdown-body del { opacity: 0.7; }
1172
+ .markdown-body hr {
1173
+ border: none;
1174
+ border-top: 1px solid var(--border);
1175
+ margin: 1em 0;
1176
+ }
1177
+ .markdown-body blockquote {
1178
+ margin: 0.6em 0;
1179
+ padding: 0.2em 0.8em;
1180
+ border-left: 3px solid var(--accent-cool, #60a5fa);
1181
+ color: var(--fg-muted, var(--fg));
1182
+ background: rgba(96, 165, 250, 0.06);
1183
+ border-radius: 0 4px 4px 0;
1184
+ }
1185
+ .markdown-body blockquote > :first-child { margin-top: 0; }
1186
+ .markdown-body blockquote > :last-child { margin-bottom: 0; }
1187
+ .markdown-body code {
1188
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
1189
+ font-size: 0.85em;
1190
+ background: rgba(94, 234, 212, 0.08);
1191
+ border: 1px solid var(--border);
1192
+ border-radius: 3px;
1193
+ padding: 0.1em 0.35em;
1194
+ }
1195
+ .markdown-body pre {
1196
+ background: rgba(94, 234, 212, 0.04);
1197
+ border: 1px solid var(--border);
1198
+ border-radius: 4px;
1199
+ padding: 0.6rem;
1200
+ overflow-x: auto;
1201
+ margin: 0.6em 0;
1202
+ }
1203
+ .markdown-body pre code {
1204
+ background: transparent;
1205
+ border: none;
1206
+ padding: 0;
1207
+ font-size: 0.8em;
1208
+ line-height: 1.5;
1209
+ }
1210
+ .markdown-body table {
1211
+ border-collapse: collapse;
1212
+ margin: 0.6em 0;
1213
+ font-size: 0.85em;
1214
+ display: block;
1215
+ overflow-x: auto;
1216
+ }
1217
+ .markdown-body th,
1218
+ .markdown-body td {
1219
+ border: 1px solid var(--border);
1220
+ padding: 0.35em 0.6em;
1221
+ text-align: left;
1222
+ }
1223
+ .markdown-body th { background: rgba(94, 234, 212, 0.08); font-weight: 700; }
1224
+ .markdown-body img { max-width: 100%; border-radius: 4px; }
1225
+ .importance-bar {
1226
+ display: inline-block;
1227
+ width: 60px;
1228
+ height: 5px;
1229
+ background: rgba(94, 234, 212, 0.1);
1230
+ border-radius: 3px;
1231
+ overflow: hidden;
1232
+ vertical-align: middle;
1233
+ }
1234
+ .importance-bar > span {
1235
+ display: block;
1236
+ height: 100%;
1237
+ background: linear-gradient(90deg, var(--accent), var(--accent-2));
1238
+ box-shadow: 0 0 6px rgba(94, 234, 212, 0.4);
1239
+ }
1240
+
1241
+ /* === Decay visualization (详情面板的衰退进度) === */
1242
+ .decay-block {
1243
+ display: inline-block;
1244
+ vertical-align: middle;
1245
+ min-width: 180px;
1246
+ margin-left: 0.5rem;
1247
+ }
1248
+ .decay-row {
1249
+ display: flex;
1250
+ align-items: baseline;
1251
+ justify-content: space-between;
1252
+ gap: 0.75rem;
1253
+ margin-bottom: 0.3rem;
1254
+ font-size: 12px;
1255
+ }
1256
+ .decay-level {
1257
+ font-weight: 600;
1258
+ letter-spacing: 0.02em;
1259
+ }
1260
+ .decay-level.freshness-fresh { color: var(--accent); }
1261
+ .decay-level.freshness-aging { color: var(--accent-warm); }
1262
+ .decay-level.freshness-stale { color: #fb923c; }
1263
+ .decay-level.freshness-forgotten { color: var(--fg-dim); }
1264
+ .decay-countdown {
1265
+ color: var(--fg-muted);
1266
+ font-size: 11px;
1267
+ }
1268
+ .decay-bar {
1269
+ width: 100%;
1270
+ height: 6px;
1271
+ background: rgba(94, 234, 212, 0.08);
1272
+ border: 1px solid var(--border);
1273
+ border-radius: 3px;
1274
+ overflow: hidden;
1275
+ }
1276
+ .decay-fill {
1277
+ height: 100%;
1278
+ transition: width .3s ease;
1279
+ }
1280
+ .decay-fill.freshness-fresh {
1281
+ background: linear-gradient(90deg, var(--accent), var(--accent-2));
1282
+ box-shadow: 0 0 6px rgba(94, 234, 212, 0.4);
1283
+ }
1284
+ .decay-fill.freshness-aging {
1285
+ background: var(--accent-warm);
1286
+ box-shadow: 0 0 4px rgba(251, 191, 36, 0.4);
1287
+ }
1288
+ .decay-fill.freshness-stale {
1289
+ background: #fb923c;
1290
+ box-shadow: 0 0 4px rgba(251, 146, 60, 0.35);
1291
+ }
1292
+ .decay-fill.freshness-forgotten {
1293
+ background: var(--fg-dim);
1294
+ }
1295
+ .decay-empty {
1296
+ font-size: 12px;
1297
+ color: var(--fg-muted);
1298
+ font-style: italic;
1299
+ }
1300
+
1301
+ /* === Config form === */
1302
+ .config-section {
1303
+ background: var(--panel-bg);
1304
+ backdrop-filter: blur(12px);
1305
+ -webkit-backdrop-filter: blur(12px);
1306
+ border: 1px solid var(--border);
1307
+ border-radius: var(--radius-lg);
1308
+ padding: 1.25rem 1.4rem;
1309
+ margin-bottom: 1rem;
1310
+ }
1311
+ .config-section h3 {
1312
+ margin: 0 0 0.85rem;
1313
+ font-size: 0.78rem;
1314
+ color: var(--accent);
1315
+ text-transform: uppercase;
1316
+ letter-spacing: 0.1em;
1317
+ font-weight: 600;
1318
+ }
1319
+ .config-row {
1320
+ display: grid;
1321
+ grid-template-columns: 200px 1fr;
1322
+ gap: 1rem;
1323
+ align-items: center;
1324
+ padding: 0.6rem 0;
1325
+ border-bottom: 1px dashed var(--border);
1326
+ }
1327
+ .config-row:last-child { border-bottom: none; }
1328
+ .config-row .config-label {
1329
+ color: var(--fg);
1330
+ font-size: 0.85rem;
1331
+ }
1332
+ .config-row .config-label .desc {
1333
+ display: block;
1334
+ color: var(--fg-muted);
1335
+ font-size: 0.72rem;
1336
+ margin-top: 0.15rem;
1337
+ }
1338
+ .config-row .config-control input[type=text],
1339
+ .config-row .config-control input[type=number],
1340
+ .config-row .config-control select {
1341
+ background: rgba(94, 234, 212, 0.04);
1342
+ border: 1px solid var(--border);
1343
+ color: var(--fg);
1344
+ padding: 0.4rem 0.65rem;
1345
+ border-radius: 4px;
1346
+ font-family: inherit;
1347
+ font-size: 0.82rem;
1348
+ width: 100%;
1349
+ max-width: 320px;
1350
+ }
1351
+ .config-row .config-control input:focus, .config-row .config-control select:focus {
1352
+ outline: none;
1353
+ border-color: var(--accent);
1354
+ box-shadow: 0 0 0 2px rgba(94, 234, 212, 0.15);
1355
+ }
1356
+ /* dark dropdown options (browser default is white) */
1357
+ .config-row select option,
1358
+ .drawer select option,
1359
+ .filter-bar select option {
1360
+ background: #0a0f1f;
1361
+ color: var(--fg);
1362
+ }
1363
+ .config-row select option:checked,
1364
+ .drawer select option:checked,
1365
+ .filter-bar select option:checked {
1366
+ background: rgba(94, 234, 212, 0.2);
1367
+ color: var(--accent);
1368
+ }
1369
+
1370
+ /* === Range slider (importance/weight/confidence editors) === */
1371
+ .config-row input[type=range],
1372
+ .drawer input[type=range],
1373
+ .field input[type=range] {
1374
+ -webkit-appearance: none;
1375
+ appearance: none;
1376
+ width: 200px;
1377
+ height: 6px;
1378
+ background: linear-gradient(90deg, var(--accent), var(--accent-2));
1379
+ border-radius: 3px;
1380
+ outline: none;
1381
+ vertical-align: middle;
1382
+ }
1383
+ .config-row input[type=range]::-webkit-slider-thumb,
1384
+ .drawer input[type=range]::-webkit-slider-thumb,
1385
+ .field input[type=range]::-webkit-slider-thumb {
1386
+ -webkit-appearance: none;
1387
+ appearance: none;
1388
+ width: 18px;
1389
+ height: 18px;
1390
+ border-radius: 50%;
1391
+ background: #fff;
1392
+ border: 2px solid var(--accent);
1393
+ cursor: pointer;
1394
+ box-shadow: 0 0 8px rgba(94, 234, 212, 0.5);
1395
+ }
1396
+ .config-row input[type=range]::-moz-range-thumb,
1397
+ .drawer input[type=range]::-moz-range-thumb,
1398
+ .field input[type=range]::-moz-range-thumb {
1399
+ width: 18px;
1400
+ height: 18px;
1401
+ border-radius: 50%;
1402
+ background: #fff;
1403
+ border: 2px solid var(--accent);
1404
+ cursor: pointer;
1405
+ }
1406
+
1407
+ /* === Toggle switch (runtime state editor) === */
1408
+ .toggle-switch {
1409
+ position: relative;
1410
+ display: inline-block;
1411
+ width: 40px;
1412
+ height: 22px;
1413
+ flex-shrink: 0;
1414
+ }
1415
+ .toggle-switch input {
1416
+ opacity: 0;
1417
+ width: 0;
1418
+ height: 0;
1419
+ }
1420
+ .toggle-slider {
1421
+ position: absolute;
1422
+ cursor: pointer;
1423
+ top: 0; left: 0; right: 0; bottom: 0;
1424
+ background: rgba(148, 163, 184, 0.25);
1425
+ border: 1px solid var(--border);
1426
+ border-radius: 22px;
1427
+ transition: all .2s;
1428
+ }
1429
+ .toggle-slider::before {
1430
+ position: absolute;
1431
+ content: "";
1432
+ height: 16px;
1433
+ width: 16px;
1434
+ left: 2px;
1435
+ bottom: 2px;
1436
+ background: var(--fg-muted);
1437
+ border-radius: 50%;
1438
+ transition: all .2s;
1439
+ }
1440
+ .toggle-switch input:checked + .toggle-slider {
1441
+ background: rgba(94, 234, 212, 0.3);
1442
+ border-color: var(--accent);
1443
+ box-shadow: 0 0 8px rgba(94, 234, 212, 0.3);
1444
+ }
1445
+ .toggle-switch input:checked + .toggle-slider::before {
1446
+ transform: translateX(18px);
1447
+ background: var(--accent);
1448
+ }
1449
+ .toggle-state {
1450
+ font-size: 0.78rem;
1451
+ font-weight: 500;
1452
+ }
1453
+ .toggle-state.on { color: var(--accent); }
1454
+ .toggle-state.off { color: var(--fg-muted); }
1455
+ .config-row.readonly .config-label::after {
1456
+ content: '只读';
1457
+ display: inline-block;
1458
+ margin-left: 0.5rem;
1459
+ padding: 0.05rem 0.4rem;
1460
+ font-size: 0.65rem;
1461
+ background: rgba(94, 234, 212, 0.08);
1462
+ color: var(--fg-muted);
1463
+ border-radius: 3px;
1464
+ text-transform: uppercase;
1465
+ letter-spacing: 0.05em;
1466
+ vertical-align: middle;
1467
+ }
1468
+ .config-row.readonly .config-control input,
1469
+ .config-row.readonly .config-control select {
1470
+ background: rgba(94, 234, 212, 0.02);
1471
+ color: var(--fg-muted);
1472
+ cursor: not-allowed;
1473
+ }
1474
+ .config-save-bar {
1475
+ position: sticky;
1476
+ bottom: 0;
1477
+ background: linear-gradient(180deg, transparent, rgba(5, 8, 22, 0.9) 30%);
1478
+ padding: 1rem 0;
1479
+ display: flex;
1480
+ justify-content: flex-end;
1481
+ gap: 0.5rem;
1482
+ }
1483
+
1484
+ /* === Editable indicator === */
1485
+ .edit-banner {
1486
+ background: rgba(251, 191, 36, 0.08);
1487
+ border: 1px solid rgba(251, 191, 36, 0.25);
1488
+ border-radius: 4px;
1489
+ padding: 0.5rem 0.75rem;
1490
+ font-size: 0.78rem;
1491
+ color: var(--accent-warm);
1492
+ margin-bottom: 1rem;
1493
+ }
1494
+ .edit-actions {
1495
+ display: flex;
1496
+ gap: 0.5rem;
1497
+ margin-top: 1rem;
1498
+ padding-top: 1rem;
1499
+ border-top: 1px solid var(--border);
1500
+ }
1501
+
1502
+ /* === Scrollbar === */
1503
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
1504
+ ::-webkit-scrollbar-track { background: transparent; }
1505
+ ::-webkit-scrollbar-thumb {
1506
+ background: rgba(94, 234, 212, 0.15);
1507
+ border-radius: 5px;
1508
+ }
1509
+ ::-webkit-scrollbar-thumb:hover { background: rgba(94, 234, 212, 0.3); }
1510
+
1511
+ /* === vis-network dark overrides === */
1512
+ div.vis-tooltip {
1513
+ background: rgba(15, 21, 48, 0.95) !important;
1514
+ color: var(--fg) !important;
1515
+ border: 1px solid var(--border-strong) !important;
1516
+ border-radius: 4px !important;
1517
+ padding: 0.5rem 0.7rem !important;
1518
+ font-size: 0.78rem !important;
1519
+ box-shadow: var(--shadow-lift) !important;
1520
+ }
1521
+
1522
+ /* === 视图切换按钮组(engrams 卡片/目录) === */
1523
+ .view-toggle {
1524
+ display: inline-flex;
1525
+ gap: 0.15rem;
1526
+ padding: 0.15rem;
1527
+ border: 1px solid var(--border);
1528
+ border-radius: 6px;
1529
+ background: rgba(148, 163, 184, 0.04);
1530
+ }
1531
+ .view-toggle button {
1532
+ padding: 0.25rem 0.7rem;
1533
+ font-size: 0.8rem;
1534
+ border: none;
1535
+ background: transparent;
1536
+ color: var(--fg-muted);
1537
+ cursor: pointer;
1538
+ border-radius: 4px;
1539
+ }
1540
+ .view-toggle button.active {
1541
+ background: rgba(94, 234, 212, 0.15);
1542
+ color: var(--accent);
1543
+ }
1544
+
1545
+ /* === 目录视图(engrams tree) === */
1546
+ .tree-view {
1547
+ background: rgba(148, 163, 184, 0.04);
1548
+ border: 1px solid var(--border);
1549
+ border-radius: 8px;
1550
+ padding: 0.5rem 0.75rem;
1551
+ }
1552
+ .tree-view details { margin: 0.15rem 0; }
1553
+ .tree-view summary {
1554
+ cursor: pointer;
1555
+ padding: 0.35rem 0.25rem;
1556
+ font-weight: 500;
1557
+ font-size: 0.9rem;
1558
+ border-radius: 4px;
1559
+ user-select: none;
1560
+ list-style: none;
1561
+ }
1562
+ .tree-view summary::-webkit-details-marker { display: none; }
1563
+ .tree-view summary:hover { background: rgba(94, 234, 212, 0.06); }
1564
+ .tree-view summary::before {
1565
+ content: '▸';
1566
+ display: inline-block;
1567
+ width: 1rem;
1568
+ color: var(--fg-muted);
1569
+ transition: transform 0.15s;
1570
+ }
1571
+ .tree-view details[open] > summary::before { transform: rotate(90deg); }
1572
+ .tree-group > summary { font-size: 0.95rem; font-weight: 600; }
1573
+ .tree-subgroup > summary { padding-left: 1.5rem; font-size: 0.85rem; color: var(--fg); }
1574
+ .tree-folder-icon { margin-right: 0.35rem; }
1575
+ .tree-count {
1576
+ display: inline-block;
1577
+ padding: 0 0.4rem;
1578
+ font-size: 0.7rem;
1579
+ color: var(--fg-muted);
1580
+ background: rgba(148, 163, 184, 0.12);
1581
+ border-radius: 8px;
1582
+ margin-left: 0.4rem;
1583
+ }
1584
+ .tree-group-body {
1585
+ padding-left: 0.5rem;
1586
+ border-left: 1px dashed var(--border);
1587
+ margin-left: 0.5rem;
1588
+ }
1589
+ .tree-leaf-group { padding-left: 2.5rem; }
1590
+ .tree-leaf {
1591
+ padding: 0.3rem 0.5rem;
1592
+ cursor: pointer;
1593
+ font-size: 0.85rem;
1594
+ border-radius: 4px;
1595
+ display: flex;
1596
+ align-items: center;
1597
+ gap: 0.4rem;
1598
+ }
1599
+ .tree-leaf:hover { background: rgba(94, 234, 212, 0.1); color: var(--accent); }
1600
+
1601
+ /* === 贡献者排名表格 === */
1602
+ .data-table {
1603
+ width: 100%;
1604
+ border-collapse: collapse;
1605
+ font-size: 0.88rem;
1606
+ }
1607
+ .data-table th, .data-table td {
1608
+ padding: 0.4rem 0.6rem;
1609
+ text-align: left;
1610
+ border-bottom: 1px solid var(--border);
1611
+ }
1612
+ .data-table th {
1613
+ font-weight: 600;
1614
+ color: var(--fg-muted);
1615
+ font-size: 0.8rem;
1616
+ background: rgba(148, 163, 184, 0.05);
1617
+ }
1618
+
1619
+ /* === 突触编辑器:optgroup 分组样式 === */
1620
+ .drawer select optgroup {
1621
+ background: rgba(10, 15, 31, 1);
1622
+ color: var(--accent);
1623
+ font-weight: 600;
1624
+ font-style: normal;
1625
+ }
1626
+ .drawer select option {
1627
+ background: rgba(10, 15, 31, 1);
1628
+ color: var(--fg);
1629
+ padding-left: 0.8rem;
1630
+ }
1631
+ `;
1632
+ //# sourceMappingURL=styles.js.map