thurview 0.1.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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/bin/thurview.js +8 -0
  4. package/dist/cli.js +1101 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/diff.js +65 -0
  7. package/dist/diff.js.map +1 -0
  8. package/dist/document/compile.js +418 -0
  9. package/dist/document/compile.js.map +1 -0
  10. package/dist/document/parse.js +139 -0
  11. package/dist/document/parse.js.map +1 -0
  12. package/dist/document/schema.js +129 -0
  13. package/dist/document/schema.js.map +1 -0
  14. package/dist/flags.js +66 -0
  15. package/dist/flags.js.map +1 -0
  16. package/dist/git.js +206 -0
  17. package/dist/git.js.map +1 -0
  18. package/dist/highlight-theme.js +93 -0
  19. package/dist/highlight-theme.js.map +1 -0
  20. package/dist/highlight.js +163 -0
  21. package/dist/highlight.js.map +1 -0
  22. package/dist/main.js +3 -0
  23. package/dist/main.js.map +1 -0
  24. package/dist/server/server.js +387 -0
  25. package/dist/server/server.js.map +1 -0
  26. package/dist/store.js +100 -0
  27. package/dist/store.js.map +1 -0
  28. package/dist/symbols.js +192 -0
  29. package/dist/symbols.js.map +1 -0
  30. package/dist/theme.js +301 -0
  31. package/dist/theme.js.map +1 -0
  32. package/dist/threads.js +87 -0
  33. package/dist/threads.js.map +1 -0
  34. package/dist/ui/app.css +1415 -0
  35. package/dist/ui/app.js +2303 -0
  36. package/dist/ui/app.js.map +7 -0
  37. package/dist/ui/assets/fonts/inter-400.woff2 +0 -0
  38. package/dist/ui/assets/fonts/jetbrains-mono-400.woff2 +0 -0
  39. package/dist/ui/assets/fonts/press-start-2p-400.woff2 +0 -0
  40. package/dist/ui/assets/inter-400.woff2 +0 -0
  41. package/dist/ui/assets/jetbrains-mono-400.woff2 +0 -0
  42. package/dist/ui/assets/press-start-2p-400.woff2 +0 -0
  43. package/dist/ui/index.html +13 -0
  44. package/dist/version.js +6 -0
  45. package/dist/version.js.map +1 -0
  46. package/package.json +70 -0
  47. package/skills/thurview/SKILL.md +219 -0
  48. package/skills/thurview/references/components.md +120 -0
  49. package/skills/thurview/references/document-authoring.md +107 -0
  50. package/skills/thurview/references/lifecycle.md +88 -0
  51. package/skills/thurview/references/software-map.md +42 -0
  52. package/skills/thurview/references/theme.md +90 -0
@@ -0,0 +1,1415 @@
1
+ /* thurview theme: warm charcoal, blood-red accent, pixel chrome.
2
+ Chrome (bars, buttons, panels, headings) is retro; body copy and code stay readable. */
3
+
4
+ @font-face {
5
+ font-family: Inter;
6
+ font-style: normal;
7
+ font-weight: 400 700;
8
+ font-display: swap;
9
+ src: url("/assets/fonts/inter-400.woff2") format("woff2");
10
+ }
11
+ @font-face {
12
+ font-family: "JetBrains Mono";
13
+ font-style: normal;
14
+ font-weight: 400 700;
15
+ font-display: swap;
16
+ src: url("/assets/fonts/jetbrains-mono-400.woff2") format("woff2");
17
+ }
18
+ @font-face {
19
+ font-family: "Press Start 2P";
20
+ font-style: normal;
21
+ font-weight: 400;
22
+ font-display: swap;
23
+ src: url("/assets/fonts/press-start-2p-400.woff2") format("woff2");
24
+ }
25
+
26
+ :root {
27
+ color-scheme: dark;
28
+ --bg: #15120f;
29
+ --bg2: #1e1a16;
30
+ --bg3: #2a241e;
31
+ --bg-code: #0d0b09;
32
+ --hud-bg: #14110e;
33
+ --hud-deep: #0a0807;
34
+ --fg: #e0e0e0;
35
+ --fg2: #a0a0a0;
36
+ --muted: #948a7d;
37
+ --line: #36302a;
38
+ --line2: #26211c;
39
+ --hud-edge: #3a322b;
40
+ --accent: #ff5c54;
41
+ --red: #ff3b30;
42
+ --doom: #e8180b;
43
+ --doom-bright: #ff3326;
44
+ --ember: #ff5c1f;
45
+ --green: #6eff6e;
46
+ --yellow: #ffb627;
47
+ --purple: #ff8c8c;
48
+ --blue: #00d9ff;
49
+ --ok: var(--green);
50
+ --warn: var(--yellow);
51
+ --del: var(--red);
52
+ --glow-red: 0 0 5px rgb(255 92 84 / 0.7), 0 0 12px rgb(255 59 48 / 0.4);
53
+ --glow-green: 0 0 5px rgb(110 255 110 / 0.7), 0 0 12px rgb(110 255 110 / 0.4);
54
+ --bevel-light: rgb(255 255 255 / 0.14);
55
+ --bevel-dark: rgb(0 0 0 / 0.62);
56
+ --bevel-frame: #07060a;
57
+ --bevel:
58
+ 0 0 0 2px var(--bevel-frame), inset 2px 2px 0 0 var(--bevel-light),
59
+ inset -2px -2px 0 0 var(--bevel-dark);
60
+ --bevel-glow-red:
61
+ 0 0 0 2px #07060a, 0 0 12px rgb(232 24 11 / 0.5), inset 2px 2px 0 0 var(--bevel-light),
62
+ inset -2px -2px 0 0 var(--bevel-dark);
63
+ --scanline: rgb(0 0 0 / 0.1);
64
+ --add-bg: rgb(110 255 110 / 0.09);
65
+ --del-bg: rgb(255 59 48 / 0.12);
66
+ --sel: rgb(255 182 39 / 0.14);
67
+ --accent-bg: rgb(255 92 84 / 0.14);
68
+ --font-display: "Press Start 2P", "JetBrains Mono", monospace;
69
+ --font-mono: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
70
+ --font-body: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
71
+ --transition: 200ms ease;
72
+ --radius: 0;
73
+ --heading-transform: uppercase;
74
+ }
75
+ * {
76
+ box-sizing: border-box;
77
+ }
78
+ html,
79
+ body {
80
+ margin: 0;
81
+ height: 100%;
82
+ }
83
+ body {
84
+ background: var(--bg) radial-gradient(ellipse at 50% -10%, rgb(255 59 48 / 0.05), transparent 55%)
85
+ fixed;
86
+ color: var(--fg);
87
+ font: 14px/1.55 var(--font-body);
88
+ -webkit-font-smoothing: antialiased;
89
+ overflow: hidden;
90
+ }
91
+ /* CRT scanlines, click-through, subtle enough for code */
92
+ body::after {
93
+ content: "";
94
+ position: fixed;
95
+ inset: 0;
96
+ z-index: 9999;
97
+ pointer-events: none;
98
+ background: repeating-linear-gradient(
99
+ to bottom,
100
+ transparent 0,
101
+ transparent 2px,
102
+ var(--scanline) 2px,
103
+ var(--scanline) 3px
104
+ );
105
+ mix-blend-mode: multiply;
106
+ }
107
+ a {
108
+ color: var(--green);
109
+ text-decoration: none;
110
+ transition:
111
+ color var(--transition),
112
+ text-shadow var(--transition);
113
+ }
114
+ a:hover {
115
+ text-shadow: var(--glow-green);
116
+ }
117
+ ::selection {
118
+ background: rgb(255 92 84 / 0.35);
119
+ }
120
+
121
+ button {
122
+ white-space: nowrap;
123
+ font-family: var(--font-display);
124
+ font-size: 0.5rem;
125
+ text-transform: uppercase;
126
+ letter-spacing: 0.04em;
127
+ line-height: 1;
128
+ color: var(--fg2);
129
+ background: var(--bg2);
130
+ border: 2px solid var(--hud-edge);
131
+ border-radius: var(--radius);
132
+ padding: 8px 12px;
133
+ cursor: pointer;
134
+ box-shadow: var(--bevel);
135
+ transition: all var(--transition);
136
+ }
137
+ button:hover {
138
+ color: var(--fg);
139
+ border-color: var(--fg2);
140
+ text-shadow: var(--glow-red);
141
+ transform: translateY(-1px);
142
+ }
143
+ button.primary {
144
+ background: var(--doom);
145
+ color: #fff;
146
+ border-color: var(--doom-bright);
147
+ box-shadow: var(--bevel-glow-red);
148
+ }
149
+ button.primary:hover {
150
+ background: var(--doom-bright);
151
+ }
152
+ button.ok {
153
+ background: var(--green);
154
+ color: #0a2e0a;
155
+ border-color: var(--green);
156
+ box-shadow:
157
+ var(--bevel),
158
+ 0 0 10px rgb(110 255 110 / 0.5);
159
+ text-shadow: none;
160
+ }
161
+ button.ok:hover {
162
+ background: #8cff8c;
163
+ color: #0a2e0a;
164
+ }
165
+ button.ghost {
166
+ background: transparent;
167
+ border-color: transparent;
168
+ box-shadow: none;
169
+ }
170
+ button.ghost:hover {
171
+ background: var(--bg3);
172
+ transform: none;
173
+ }
174
+ button.small {
175
+ padding: 5px 8px;
176
+ font-size: 0.5rem;
177
+ }
178
+ textarea,
179
+ input[type="text"],
180
+ select {
181
+ font: 13px/1.5 var(--font-mono);
182
+ color: var(--fg);
183
+ background: var(--bg-code);
184
+ border: 1px solid var(--hud-edge);
185
+ border-radius: var(--radius);
186
+ padding: 6px 8px;
187
+ width: 100%;
188
+ box-shadow: var(--bevel);
189
+ }
190
+ textarea:focus,
191
+ input:focus {
192
+ outline: none;
193
+ border-color: var(--accent);
194
+ }
195
+ select {
196
+ width: auto;
197
+ padding: 3px 6px;
198
+ box-shadow: none;
199
+ }
200
+ code,
201
+ pre,
202
+ .code,
203
+ .mono {
204
+ font-family: var(--font-mono);
205
+ font-size: 12.5px;
206
+ }
207
+ code {
208
+ background: var(--bg2);
209
+ color: var(--accent);
210
+ padding: 0.1em 0.4em;
211
+ }
212
+ pre code {
213
+ background: none;
214
+ padding: 0;
215
+ color: var(--fg);
216
+ }
217
+ pre {
218
+ background: var(--bg-code);
219
+ border: 1px solid var(--hud-edge);
220
+ box-shadow: var(--bevel);
221
+ padding: 10px 12px;
222
+ overflow-x: auto;
223
+ }
224
+ .badge {
225
+ border-radius: var(--radius);
226
+ display: inline-flex;
227
+ align-items: center;
228
+ gap: 4px;
229
+ font-family: var(--font-mono);
230
+ font-size: 11px;
231
+ padding: 2px 8px;
232
+ border: 1px solid var(--line);
233
+ color: var(--fg2);
234
+ background: transparent;
235
+ white-space: nowrap;
236
+ }
237
+ .badge.ok {
238
+ color: var(--green);
239
+ border-color: var(--green);
240
+ }
241
+ .badge.warn {
242
+ color: var(--yellow);
243
+ border-color: var(--yellow);
244
+ }
245
+ .badge.del {
246
+ color: var(--red);
247
+ border-color: var(--red);
248
+ }
249
+ .badge.accent {
250
+ color: var(--accent);
251
+ border-color: var(--accent);
252
+ }
253
+ .muted {
254
+ color: var(--muted);
255
+ }
256
+ kbd {
257
+ font-family: var(--font-mono);
258
+ font-size: 11px;
259
+ border: 1px solid var(--line);
260
+ padding: 0 4px;
261
+ background: var(--bg2);
262
+ }
263
+
264
+ #app {
265
+ display: flex;
266
+ flex-direction: column;
267
+ height: 100%;
268
+ }
269
+ /* HUD top bar */
270
+ .topbar {
271
+ display: flex;
272
+ align-items: center;
273
+ gap: 12px;
274
+ padding: 0 16px;
275
+ height: 52px;
276
+ background: var(--hud-bg);
277
+ border-bottom: 2px solid var(--hud-deep);
278
+ box-shadow: inset 0 -1px 0 0 rgb(232 24 11 / 0.45);
279
+ flex-wrap: nowrap;
280
+ overflow: hidden;
281
+ }
282
+ .topbar .brand {
283
+ font-family: var(--font-display);
284
+ font-size: 0.8rem;
285
+ text-transform: var(--heading-transform);
286
+ color: var(--accent);
287
+ text-shadow: var(--glow-red);
288
+ letter-spacing: 0.02em;
289
+ white-space: nowrap;
290
+ }
291
+ .topbar .brand:hover {
292
+ text-shadow:
293
+ var(--glow-red),
294
+ 0 0 20px rgb(255 59 48 / 0.6);
295
+ }
296
+ .topbar .title {
297
+ font-family: var(--font-mono);
298
+ font-weight: 700;
299
+ font-size: 14px;
300
+ white-space: nowrap;
301
+ overflow: hidden;
302
+ text-overflow: ellipsis;
303
+ max-width: 28vw;
304
+ }
305
+ .topbar > * {
306
+ flex: none;
307
+ }
308
+ .topbar .title {
309
+ flex: 0 1 auto;
310
+ min-width: 60px;
311
+ }
312
+ .topbar .tabs {
313
+ display: flex;
314
+ gap: 2px;
315
+ margin-left: 8px;
316
+ }
317
+ .tabs button {
318
+ border: none;
319
+ background: transparent;
320
+ box-shadow: none;
321
+ padding: 8px 10px;
322
+ color: var(--fg2);
323
+ font-size: 0.5rem;
324
+ }
325
+ .tabs button::before {
326
+ content: "\25B6";
327
+ display: inline-block;
328
+ width: 0;
329
+ margin-right: 0;
330
+ overflow: hidden;
331
+ opacity: 0;
332
+ color: var(--doom-bright);
333
+ font-size: 0.7em;
334
+ transition:
335
+ width var(--transition),
336
+ margin-right var(--transition),
337
+ opacity var(--transition);
338
+ }
339
+ .tabs button:hover,
340
+ .tabs button.active {
341
+ color: var(--fg);
342
+ transform: none;
343
+ }
344
+ .tabs button.active {
345
+ color: var(--accent);
346
+ text-shadow: var(--glow-red);
347
+ }
348
+ .tabs button:hover::before,
349
+ .tabs button.active::before {
350
+ width: 0.9em;
351
+ margin-right: 0.4em;
352
+ opacity: 1;
353
+ text-shadow: var(--glow-red);
354
+ }
355
+ .topbar .spacer {
356
+ flex: 1;
357
+ }
358
+ .main {
359
+ flex: 1;
360
+ display: flex;
361
+ min-height: 0;
362
+ }
363
+ .center {
364
+ flex: 1;
365
+ min-width: 0;
366
+ overflow: auto;
367
+ }
368
+ .side {
369
+ width: var(--side-w, 520px);
370
+ min-width: 320px;
371
+ max-width: 70vw;
372
+ border-left: 2px solid var(--hud-deep);
373
+ background: var(--bg2);
374
+ display: flex;
375
+ flex-direction: column;
376
+ min-height: 0;
377
+ box-shadow: inset 2px 0 0 0 var(--bevel-light);
378
+ }
379
+ .side.hidden {
380
+ display: none;
381
+ }
382
+ .resizer {
383
+ width: 5px;
384
+ cursor: col-resize;
385
+ background: transparent;
386
+ }
387
+ .resizer:hover {
388
+ background: var(--accent);
389
+ box-shadow: var(--glow-red);
390
+ }
391
+ .side-head {
392
+ display: flex;
393
+ align-items: center;
394
+ gap: 8px;
395
+ padding: 8px 12px;
396
+ border-bottom: 1px solid var(--hud-edge);
397
+ background: var(--hud-bg);
398
+ }
399
+ .side-head .path {
400
+ font-family: var(--font-mono);
401
+ font-size: 12px;
402
+ flex: 1;
403
+ min-width: 0;
404
+ overflow: hidden;
405
+ text-overflow: ellipsis;
406
+ white-space: nowrap;
407
+ color: var(--fg2);
408
+ cursor: pointer;
409
+ }
410
+ .side-head .path:hover {
411
+ color: var(--green);
412
+ }
413
+ .side-body {
414
+ flex: 1;
415
+ overflow: auto;
416
+ }
417
+
418
+ /* Review document */
419
+ .doc-layout {
420
+ display: grid;
421
+ grid-template-columns: 220px minmax(0, 1fr);
422
+ gap: 24px;
423
+ max-width: 1200px;
424
+ margin: 0 auto;
425
+ padding: 24px 24px 80px;
426
+ }
427
+ .toc {
428
+ position: sticky;
429
+ top: 24px;
430
+ align-self: start;
431
+ font-size: 13px;
432
+ }
433
+ .toc a {
434
+ display: block;
435
+ color: var(--fg2);
436
+ padding: 4px 10px;
437
+ border-left: 2px solid transparent;
438
+ font-family: var(--font-mono);
439
+ font-size: 12px;
440
+ }
441
+ .toc a.l3 {
442
+ padding-left: 22px;
443
+ }
444
+ .toc a:hover,
445
+ .toc a.active {
446
+ color: var(--fg);
447
+ border-left-color: var(--accent);
448
+ background: var(--bg2);
449
+ text-shadow: none;
450
+ }
451
+ .doc {
452
+ max-width: 780px;
453
+ }
454
+ .doc h1 {
455
+ font-family: var(--font-display);
456
+ font-weight: 400;
457
+ text-transform: var(--heading-transform);
458
+ letter-spacing: 0.02em;
459
+ color: var(--accent);
460
+ text-shadow: var(--glow-red);
461
+ font-size: clamp(0.95rem, 2.4vw, 1.3rem);
462
+ line-height: 1.6;
463
+ margin: 0 0 14px;
464
+ }
465
+ .doc h2 {
466
+ font-family: var(--font-display);
467
+ font-weight: 400;
468
+ text-transform: var(--heading-transform);
469
+ letter-spacing: 0.02em;
470
+ color: var(--accent);
471
+ text-shadow: var(--glow-red);
472
+ font-size: 0.8rem;
473
+ line-height: 1.6;
474
+ margin: 36px 0 10px;
475
+ padding-top: 16px;
476
+ border-top: 1px solid var(--line);
477
+ }
478
+ .doc h3 {
479
+ font-family: var(--font-mono);
480
+ font-weight: 700;
481
+ font-size: 15px;
482
+ margin: 22px 0 6px;
483
+ color: var(--fg);
484
+ }
485
+ .doc p,
486
+ .doc ul,
487
+ .doc ol {
488
+ margin: 8px 0;
489
+ color: var(--fg2);
490
+ }
491
+ .doc strong {
492
+ color: var(--fg);
493
+ }
494
+ .doc li {
495
+ margin: 2px 0;
496
+ }
497
+ .doc table {
498
+ border-collapse: collapse;
499
+ margin: 10px 0;
500
+ }
501
+ .doc th,
502
+ .doc td {
503
+ border: 1px solid var(--line);
504
+ padding: 4px 10px;
505
+ text-align: left;
506
+ }
507
+ .doc blockquote {
508
+ margin: 8px 0;
509
+ padding: 2px 12px;
510
+ border-left: 3px solid var(--accent);
511
+ color: var(--fg2);
512
+ }
513
+ .block {
514
+ position: relative;
515
+ }
516
+ .block > .block-actions {
517
+ position: absolute;
518
+ left: -36px;
519
+ top: 2px;
520
+ opacity: 0;
521
+ transition: opacity 0.1s;
522
+ }
523
+ .block:hover > .block-actions,
524
+ .block.has-threads > .block-actions {
525
+ opacity: 1;
526
+ }
527
+ .block-actions button {
528
+ width: 26px;
529
+ height: 26px;
530
+ padding: 0;
531
+ font-family: var(--font-mono);
532
+ font-size: 13px;
533
+ box-shadow: var(--bevel);
534
+ }
535
+ .block-actions button.count {
536
+ background: var(--doom);
537
+ color: #fff;
538
+ border-color: var(--doom-bright);
539
+ font-size: 11px;
540
+ }
541
+ .section-collapsed > .block:not(.heading) {
542
+ display: none;
543
+ }
544
+ .heading-toggle {
545
+ margin-left: 10px;
546
+ font-family: var(--font-mono);
547
+ font-size: 11px;
548
+ color: var(--muted);
549
+ cursor: pointer;
550
+ user-select: none;
551
+ text-shadow: none;
552
+ text-transform: none;
553
+ letter-spacing: 0;
554
+ }
555
+ .heading-toggle:hover {
556
+ color: var(--green);
557
+ }
558
+ .anchor-link {
559
+ color: var(--green);
560
+ border-bottom: 1px dashed var(--green);
561
+ }
562
+ .anchor-link:hover,
563
+ .anchor-link.active {
564
+ background: rgb(110 255 110 / 0.1);
565
+ text-shadow: var(--glow-green);
566
+ }
567
+ .thread-pins {
568
+ margin: 6px 0 14px;
569
+ display: flex;
570
+ flex-direction: column;
571
+ gap: 6px;
572
+ }
573
+ .thread-pin {
574
+ border-radius: var(--radius);
575
+ font-size: 12.5px;
576
+ background: var(--bg2);
577
+ border: 1px solid var(--hud-edge);
578
+ box-shadow: var(--bevel);
579
+ padding: 6px 10px;
580
+ cursor: pointer;
581
+ display: flex;
582
+ gap: 8px;
583
+ align-items: baseline;
584
+ }
585
+ .thread-pin:hover {
586
+ border-color: var(--doom);
587
+ box-shadow: var(--bevel-glow-red);
588
+ }
589
+ .thread-pin .who {
590
+ font-family: var(--font-mono);
591
+ font-weight: 700;
592
+ color: var(--yellow);
593
+ }
594
+ .thread-pin.resolved {
595
+ opacity: 0.55;
596
+ }
597
+ .comment-popover {
598
+ border-radius: var(--radius);
599
+ position: absolute;
600
+ z-index: 20;
601
+ background: var(--bg2);
602
+ border: 1px solid var(--hud-edge);
603
+ box-shadow:
604
+ var(--bevel),
605
+ 0 8px 30px rgb(0 0 0 / 0.6);
606
+ width: 400px;
607
+ padding: 10px;
608
+ }
609
+ .comment-popover textarea {
610
+ min-height: 70px;
611
+ }
612
+ .comment-popover .row {
613
+ display: flex;
614
+ gap: 8px;
615
+ align-items: center;
616
+ margin-top: 8px;
617
+ flex-wrap: wrap;
618
+ }
619
+ .comment-popover .quote {
620
+ font-size: 12px;
621
+ color: var(--fg2);
622
+ border-left: 2px solid var(--accent);
623
+ padding-left: 8px;
624
+ margin-bottom: 6px;
625
+ max-height: 60px;
626
+ overflow: hidden;
627
+ font-style: italic;
628
+ }
629
+ .selection-btn {
630
+ position: absolute;
631
+ z-index: 19;
632
+ }
633
+
634
+ /* code surfaces */
635
+ .code-frame {
636
+ border-radius: var(--radius);
637
+ border: 1px solid var(--hud-edge);
638
+ box-shadow:
639
+ var(--bevel),
640
+ 0 8px 30px rgb(0 0 0 / 0.4);
641
+ margin: 14px 0;
642
+ overflow: hidden;
643
+ background: var(--bg-code);
644
+ }
645
+ .code-frame .frame-head {
646
+ display: flex;
647
+ align-items: center;
648
+ gap: 10px;
649
+ padding: 8px 12px;
650
+ background: var(--bg2);
651
+ border-bottom: 1px solid var(--line);
652
+ font-size: 12px;
653
+ }
654
+ .code-frame .frame-head .path {
655
+ font-family: var(--font-mono);
656
+ flex: 1;
657
+ min-width: 0;
658
+ overflow: hidden;
659
+ text-overflow: ellipsis;
660
+ white-space: nowrap;
661
+ color: var(--muted);
662
+ cursor: pointer;
663
+ }
664
+ .code-frame .frame-head .path:hover {
665
+ color: var(--green);
666
+ }
667
+ .code-frame .frame-head .title {
668
+ font-family: var(--font-mono);
669
+ font-weight: 700;
670
+ color: var(--fg);
671
+ }
672
+ .code {
673
+ overflow-x: auto;
674
+ background: var(--bg-code);
675
+ }
676
+ .code table {
677
+ border-collapse: collapse;
678
+ width: 100%;
679
+ }
680
+ .code td {
681
+ padding: 0 10px;
682
+ white-space: pre;
683
+ vertical-align: top;
684
+ line-height: 21px;
685
+ color: var(--fg);
686
+ }
687
+ .code td.ln {
688
+ text-align: right;
689
+ color: var(--muted);
690
+ user-select: none;
691
+ width: 1%;
692
+ min-width: 46px;
693
+ cursor: pointer;
694
+ position: relative;
695
+ border-right: 1px solid var(--line2);
696
+ }
697
+ .code td.ln:hover {
698
+ color: var(--green);
699
+ }
700
+ .code tr:hover td.ln::after,
701
+ .code tr.range-sel td.ln::after {
702
+ content: "+";
703
+ position: absolute;
704
+ left: 4px;
705
+ top: 3px;
706
+ width: 15px;
707
+ height: 15px;
708
+ line-height: 15px;
709
+ text-align: center;
710
+ font-size: 12px;
711
+ font-weight: 700;
712
+ color: #0a2e0a;
713
+ background: var(--green);
714
+ box-shadow: var(--glow-green);
715
+ }
716
+ .code tr.range-sel {
717
+ background: var(--sel);
718
+ box-shadow: inset 3px 0 0 0 var(--green);
719
+ }
720
+ .file-head .hint {
721
+ font-size: 11px;
722
+ font-family: var(--font-mono);
723
+ }
724
+ .code tr.hl {
725
+ background: var(--sel);
726
+ box-shadow: inset 3px 0 0 0 var(--yellow);
727
+ }
728
+ .code tr.add {
729
+ background: var(--add-bg);
730
+ }
731
+ .code tr.del {
732
+ background: var(--del-bg);
733
+ }
734
+ .code tr.commented td.ln {
735
+ color: var(--accent);
736
+ font-weight: 700;
737
+ text-shadow: var(--glow-red);
738
+ }
739
+ .code tr.gap td {
740
+ background: var(--bg2);
741
+ color: var(--muted);
742
+ text-align: center;
743
+ font-size: 11px;
744
+ cursor: pointer;
745
+ font-family: var(--font-mono);
746
+ }
747
+ .code tr.gap td:hover {
748
+ color: var(--green);
749
+ }
750
+ .code tr.thread-row td {
751
+ white-space: normal;
752
+ padding: 6px 12px;
753
+ background: var(--bg2);
754
+ border-top: 1px solid var(--line);
755
+ border-bottom: 1px solid var(--line);
756
+ }
757
+ .expand-bar {
758
+ display: flex;
759
+ justify-content: center;
760
+ gap: 12px;
761
+ padding: 4px;
762
+ background: var(--bg2);
763
+ font-size: 11px;
764
+ font-family: var(--font-mono);
765
+ }
766
+ .def-popover {
767
+ border-radius: var(--radius);
768
+ position: absolute;
769
+ z-index: 30;
770
+ background: var(--bg2);
771
+ border: 1px solid var(--hud-edge);
772
+ box-shadow:
773
+ var(--bevel),
774
+ 0 8px 30px rgb(0 0 0 / 0.6);
775
+ min-width: 260px;
776
+ max-width: 480px;
777
+ font-size: 12.5px;
778
+ }
779
+ .def-popover .item {
780
+ padding: 7px 10px;
781
+ cursor: pointer;
782
+ display: flex;
783
+ gap: 8px;
784
+ border-bottom: 1px solid var(--line2);
785
+ font-family: var(--font-mono);
786
+ font-size: 12px;
787
+ }
788
+ .def-popover .item:last-child {
789
+ border-bottom: none;
790
+ }
791
+ .def-popover .item:hover {
792
+ background: var(--bg3);
793
+ color: var(--green);
794
+ }
795
+ .def-popover .kind {
796
+ color: var(--muted);
797
+ width: 70px;
798
+ }
799
+ .def-popover .empty {
800
+ padding: 8px 10px;
801
+ color: var(--muted);
802
+ }
803
+
804
+ /* Files */
805
+ .files-layout {
806
+ display: flex;
807
+ height: 100%;
808
+ }
809
+ .file-list {
810
+ width: 300px;
811
+ min-width: 200px;
812
+ border-right: 1px solid var(--hud-edge);
813
+ overflow: auto;
814
+ background: var(--bg2);
815
+ font-size: 12.5px;
816
+ }
817
+ .file-list .item {
818
+ padding: 6px 10px;
819
+ cursor: pointer;
820
+ display: flex;
821
+ gap: 8px;
822
+ align-items: baseline;
823
+ border-left: 2px solid transparent;
824
+ }
825
+ .file-list .item:hover {
826
+ background: var(--bg3);
827
+ }
828
+ .file-list .item.active {
829
+ border-left-color: var(--accent);
830
+ background: var(--bg3);
831
+ }
832
+ .file-list .item .name {
833
+ font-family: var(--font-mono);
834
+ flex: 1;
835
+ min-width: 0;
836
+ overflow: hidden;
837
+ text-overflow: ellipsis;
838
+ white-space: nowrap;
839
+ direction: rtl;
840
+ text-align: left;
841
+ }
842
+ .file-list .stat {
843
+ font-family: var(--font-mono);
844
+ font-size: 11px;
845
+ white-space: nowrap;
846
+ }
847
+ .stat .a {
848
+ color: var(--green);
849
+ }
850
+ .stat .d {
851
+ color: var(--red);
852
+ }
853
+ .file-view {
854
+ flex: 1;
855
+ min-width: 0;
856
+ overflow: auto;
857
+ }
858
+ .file-view .file-head {
859
+ position: sticky;
860
+ top: 0;
861
+ z-index: 5;
862
+ display: flex;
863
+ align-items: center;
864
+ gap: 12px;
865
+ padding: 8px 14px;
866
+ background: var(--hud-bg);
867
+ border-bottom: 1px solid var(--hud-edge);
868
+ font-size: 12px;
869
+ }
870
+ .file-view .file-head .path {
871
+ font-family: var(--font-mono);
872
+ flex: 1;
873
+ color: var(--fg);
874
+ }
875
+ .split {
876
+ display: grid;
877
+ grid-template-columns: 1fr 1fr;
878
+ }
879
+ .split .code {
880
+ border-right: 1px solid var(--hud-edge);
881
+ }
882
+ .code td.empty {
883
+ background: var(--bg2);
884
+ }
885
+
886
+ /* Commits */
887
+ .commits {
888
+ max-width: 900px;
889
+ margin: 0 auto;
890
+ padding: 24px;
891
+ }
892
+ .commit {
893
+ border-radius: var(--radius);
894
+ border: 1px solid var(--hud-edge);
895
+ box-shadow: var(--bevel);
896
+ background: var(--bg2);
897
+ padding: 12px 16px;
898
+ margin-bottom: 12px;
899
+ }
900
+ .commit .subject {
901
+ font-family: var(--font-mono);
902
+ font-weight: 700;
903
+ }
904
+ .commit .files {
905
+ margin-top: 8px;
906
+ font-family: var(--font-mono);
907
+ font-size: 12px;
908
+ }
909
+ .commit .files span {
910
+ cursor: pointer;
911
+ color: var(--green);
912
+ margin-right: 12px;
913
+ }
914
+ .commit pre {
915
+ white-space: pre-wrap;
916
+ margin: 8px 0 0;
917
+ font-size: 12.5px;
918
+ box-shadow: none;
919
+ }
920
+
921
+ /* Map */
922
+ .map-layout {
923
+ display: flex;
924
+ height: 100%;
925
+ }
926
+ .map-canvas {
927
+ flex: 1;
928
+ min-width: 0;
929
+ overflow: auto;
930
+ padding: 24px;
931
+ }
932
+ .map-side {
933
+ width: 340px;
934
+ border-left: 1px solid var(--hud-edge);
935
+ background: var(--bg2);
936
+ overflow: auto;
937
+ padding: 14px 16px;
938
+ font-size: 13px;
939
+ }
940
+ .map-side h3 {
941
+ font-family: var(--font-mono);
942
+ }
943
+ .crumbs {
944
+ font-family: var(--font-mono);
945
+ font-size: 12px;
946
+ margin-bottom: 14px;
947
+ }
948
+ .crumbs span {
949
+ cursor: pointer;
950
+ color: var(--green);
951
+ }
952
+ .crumbs span:last-child {
953
+ color: var(--fg);
954
+ cursor: default;
955
+ font-weight: 700;
956
+ }
957
+ .map-grid {
958
+ display: grid;
959
+ grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
960
+ gap: 16px;
961
+ }
962
+ .map-node {
963
+ border-radius: var(--radius);
964
+ border: 1px solid var(--hud-edge);
965
+ box-shadow: var(--bevel);
966
+ padding: 12px 14px;
967
+ background: var(--bg2);
968
+ cursor: pointer;
969
+ position: relative;
970
+ transition:
971
+ border-color var(--transition),
972
+ box-shadow var(--transition);
973
+ }
974
+ .map-node:hover {
975
+ border-color: var(--doom);
976
+ box-shadow:
977
+ var(--bevel-glow-red),
978
+ 0 4px 14px rgb(0 0 0 / 0.5);
979
+ }
980
+ .map-node.selected {
981
+ outline: 2px solid var(--accent);
982
+ }
983
+ .map-node .kind {
984
+ font-family: var(--font-mono);
985
+ font-size: 10px;
986
+ text-transform: uppercase;
987
+ letter-spacing: 0.08em;
988
+ color: var(--muted);
989
+ }
990
+ .map-node .label {
991
+ font-family: var(--font-mono);
992
+ font-weight: 700;
993
+ margin: 3px 0;
994
+ }
995
+ .map-node .desc {
996
+ font-size: 12.5px;
997
+ color: var(--fg2);
998
+ }
999
+ .map-node .children {
1000
+ font-family: var(--font-mono);
1001
+ font-size: 11px;
1002
+ color: var(--muted);
1003
+ margin-top: 8px;
1004
+ }
1005
+ .map-node.added {
1006
+ border-color: var(--green);
1007
+ }
1008
+ .map-node.removed {
1009
+ border-color: var(--red);
1010
+ opacity: 0.7;
1011
+ }
1012
+ .map-node.changed {
1013
+ border-color: var(--yellow);
1014
+ }
1015
+ .map-node .status {
1016
+ position: absolute;
1017
+ top: 8px;
1018
+ right: 10px;
1019
+ }
1020
+ .map-edges {
1021
+ margin-top: 20px;
1022
+ font-size: 13px;
1023
+ }
1024
+ .map-edges .edge {
1025
+ padding: 5px 0;
1026
+ border-top: 1px solid var(--line);
1027
+ display: flex;
1028
+ gap: 8px;
1029
+ font-family: var(--font-mono);
1030
+ font-size: 12px;
1031
+ }
1032
+ .map-edges .edge b {
1033
+ cursor: pointer;
1034
+ color: var(--green);
1035
+ }
1036
+ .map-side .file {
1037
+ font-family: var(--font-mono);
1038
+ font-size: 12px;
1039
+ cursor: pointer;
1040
+ color: var(--green);
1041
+ display: block;
1042
+ }
1043
+
1044
+ /* Diagrams */
1045
+ .diagram {
1046
+ border-radius: var(--radius);
1047
+ border: 1px solid var(--hud-edge);
1048
+ box-shadow: var(--bevel);
1049
+ margin: 16px 0;
1050
+ background: var(--bg2);
1051
+ }
1052
+ .diagram .dhead {
1053
+ padding: 7px 12px;
1054
+ font-family: var(--font-mono);
1055
+ font-size: 12px;
1056
+ font-weight: 700;
1057
+ border-bottom: 1px solid var(--line);
1058
+ color: var(--fg);
1059
+ }
1060
+ .diagram svg {
1061
+ display: block;
1062
+ width: 100%;
1063
+ height: auto;
1064
+ }
1065
+ .seq text {
1066
+ font: 12px var(--font-mono);
1067
+ fill: var(--fg);
1068
+ }
1069
+ .seq .actor rect {
1070
+ fill: var(--bg-code);
1071
+ stroke: var(--hud-edge);
1072
+ }
1073
+ .seq .life {
1074
+ stroke: var(--line);
1075
+ stroke-dasharray: 4 4;
1076
+ }
1077
+ .seq .msg line {
1078
+ stroke: var(--fg2);
1079
+ marker-end: url(#arr);
1080
+ }
1081
+ .seq .msg text {
1082
+ fill: var(--green);
1083
+ cursor: pointer;
1084
+ }
1085
+ .seq .msg text:hover {
1086
+ text-decoration: underline;
1087
+ }
1088
+ .callstack {
1089
+ font-family: var(--font-mono);
1090
+ font-size: 12.5px;
1091
+ }
1092
+ .callstack .row {
1093
+ display: flex;
1094
+ gap: 10px;
1095
+ padding: 4px 12px;
1096
+ cursor: pointer;
1097
+ }
1098
+ .callstack .row:hover {
1099
+ background: var(--bg3);
1100
+ }
1101
+ .callstack .row.add {
1102
+ background: var(--add-bg);
1103
+ }
1104
+ .callstack .row.del {
1105
+ background: var(--del-bg);
1106
+ }
1107
+ .callstack .sign {
1108
+ width: 10px;
1109
+ color: var(--muted);
1110
+ }
1111
+ .callstack .row.add .sign {
1112
+ color: var(--green);
1113
+ }
1114
+ .callstack .row.del .sign {
1115
+ color: var(--red);
1116
+ }
1117
+ .callstack .calls {
1118
+ color: var(--muted);
1119
+ font-style: italic;
1120
+ }
1121
+ .dblens .uc-tabs {
1122
+ display: flex;
1123
+ gap: 6px;
1124
+ padding: 8px 12px;
1125
+ border-bottom: 1px solid var(--line);
1126
+ flex-wrap: wrap;
1127
+ }
1128
+ .dblens .uc-tabs button.active {
1129
+ color: var(--accent);
1130
+ border-color: var(--accent);
1131
+ text-shadow: var(--glow-red);
1132
+ }
1133
+ .dblens .body {
1134
+ display: grid;
1135
+ grid-template-columns: 160px 1fr;
1136
+ gap: 14px;
1137
+ padding: 12px;
1138
+ }
1139
+ .dblens .actors {
1140
+ display: flex;
1141
+ flex-direction: column;
1142
+ gap: 8px;
1143
+ }
1144
+ .dblens .actor {
1145
+ border-radius: var(--radius);
1146
+ border: 1px solid var(--hud-edge);
1147
+ box-shadow: var(--bevel);
1148
+ padding: 7px 10px;
1149
+ background: var(--bg-code);
1150
+ text-align: center;
1151
+ font-family: var(--font-mono);
1152
+ font-weight: 700;
1153
+ font-size: 12.5px;
1154
+ }
1155
+ .dblens .store {
1156
+ border-radius: var(--radius);
1157
+ border: 1px solid var(--hud-edge);
1158
+ background: var(--bg-code);
1159
+ margin-bottom: 10px;
1160
+ }
1161
+ .dblens .store .sname {
1162
+ padding: 6px 10px;
1163
+ font-family: var(--font-mono);
1164
+ font-weight: 700;
1165
+ border-bottom: 1px solid var(--line);
1166
+ font-size: 12.5px;
1167
+ }
1168
+ .dblens .table {
1169
+ padding: 6px 10px;
1170
+ border-bottom: 1px solid var(--line2);
1171
+ }
1172
+ .dblens .table:last-child {
1173
+ border-bottom: none;
1174
+ }
1175
+ .dblens .table .tname {
1176
+ font-family: var(--font-mono);
1177
+ font-size: 12.5px;
1178
+ font-weight: 700;
1179
+ color: var(--yellow);
1180
+ }
1181
+ .dblens .table .cols {
1182
+ font-family: var(--font-mono);
1183
+ font-size: 11.5px;
1184
+ color: var(--muted);
1185
+ }
1186
+ .dblens .table .cols .hit {
1187
+ color: var(--fg);
1188
+ background: var(--sel);
1189
+ padding: 0 3px;
1190
+ }
1191
+ .dblens .table.hit {
1192
+ background: var(--accent-bg);
1193
+ }
1194
+ .dblens .ops {
1195
+ padding: 0 12px 12px;
1196
+ display: flex;
1197
+ flex-direction: column;
1198
+ gap: 4px;
1199
+ font-size: 12.5px;
1200
+ }
1201
+ .dblens .op {
1202
+ display: flex;
1203
+ gap: 8px;
1204
+ align-items: center;
1205
+ cursor: pointer;
1206
+ padding: 3px 6px;
1207
+ }
1208
+ .dblens .op:hover {
1209
+ background: var(--bg3);
1210
+ }
1211
+ .dblens .op .dir {
1212
+ font-family: var(--font-mono);
1213
+ color: var(--muted);
1214
+ }
1215
+ .dblens .op.read .dir {
1216
+ color: var(--blue);
1217
+ }
1218
+ .dblens .op.write .dir {
1219
+ color: var(--yellow);
1220
+ }
1221
+
1222
+ /* threads panel */
1223
+ .threads {
1224
+ padding: 12px;
1225
+ display: flex;
1226
+ flex-direction: column;
1227
+ gap: 12px;
1228
+ }
1229
+ .thread {
1230
+ border-radius: var(--radius);
1231
+ border: 1px solid var(--hud-edge);
1232
+ box-shadow: var(--bevel);
1233
+ background: var(--bg);
1234
+ }
1235
+ .thread.active {
1236
+ border-color: var(--doom);
1237
+ box-shadow: var(--bevel-glow-red);
1238
+ }
1239
+ .thread .thead {
1240
+ display: flex;
1241
+ gap: 8px;
1242
+ align-items: center;
1243
+ padding: 6px 10px;
1244
+ border-bottom: 1px solid var(--line);
1245
+ font-size: 12px;
1246
+ background: var(--bg2);
1247
+ }
1248
+ .thread .target {
1249
+ font-family: var(--font-mono);
1250
+ color: var(--green);
1251
+ cursor: pointer;
1252
+ flex: 1;
1253
+ min-width: 0;
1254
+ overflow: hidden;
1255
+ text-overflow: ellipsis;
1256
+ white-space: nowrap;
1257
+ }
1258
+ .thread .msg {
1259
+ padding: 7px 10px;
1260
+ border-bottom: 1px solid var(--line2);
1261
+ font-size: 13px;
1262
+ white-space: pre-wrap;
1263
+ color: var(--fg2);
1264
+ }
1265
+ .thread .msg .who {
1266
+ font-family: var(--font-mono);
1267
+ font-weight: 700;
1268
+ font-size: 12px;
1269
+ margin-right: 6px;
1270
+ color: var(--yellow);
1271
+ }
1272
+ .thread .msg.agent {
1273
+ background: var(--bg2);
1274
+ }
1275
+ .thread .msg.agent .who {
1276
+ color: var(--accent);
1277
+ }
1278
+ .thread .reply {
1279
+ padding: 8px 10px;
1280
+ display: flex;
1281
+ flex-direction: column;
1282
+ gap: 6px;
1283
+ }
1284
+ .thread .reply .row {
1285
+ display: flex;
1286
+ gap: 6px;
1287
+ justify-content: flex-end;
1288
+ }
1289
+ .thread .quote {
1290
+ font-size: 12px;
1291
+ color: var(--muted);
1292
+ padding: 4px 10px;
1293
+ border-bottom: 1px solid var(--line2);
1294
+ font-style: italic;
1295
+ }
1296
+
1297
+ /* dialogs, banners, home */
1298
+ .overlay {
1299
+ position: fixed;
1300
+ inset: 0;
1301
+ background: rgb(0 0 0 / 0.55);
1302
+ z-index: 50;
1303
+ display: flex;
1304
+ align-items: center;
1305
+ justify-content: center;
1306
+ }
1307
+ .dialog {
1308
+ border-radius: var(--radius);
1309
+ background: var(--bg2);
1310
+ border: 1px solid var(--hud-edge);
1311
+ box-shadow:
1312
+ var(--bevel),
1313
+ 0 12px 40px rgb(0 0 0 / 0.7);
1314
+ width: 540px;
1315
+ max-width: 92vw;
1316
+ padding: 18px 20px;
1317
+ }
1318
+ .dialog h3 {
1319
+ margin: 0 0 10px;
1320
+ font-family: var(--font-display);
1321
+ font-weight: 400;
1322
+ font-size: 0.75rem;
1323
+ text-transform: var(--heading-transform);
1324
+ color: var(--accent);
1325
+ text-shadow: var(--glow-red);
1326
+ }
1327
+ .dialog .row {
1328
+ display: flex;
1329
+ gap: 8px;
1330
+ justify-content: flex-end;
1331
+ margin-top: 14px;
1332
+ }
1333
+ .banner[hidden] {
1334
+ display: none;
1335
+ }
1336
+ .banner {
1337
+ background: var(--hud-deep);
1338
+ color: var(--fg);
1339
+ padding: 6px 16px;
1340
+ font-family: var(--font-mono);
1341
+ font-size: 12px;
1342
+ display: flex;
1343
+ gap: 12px;
1344
+ align-items: center;
1345
+ border-bottom: 1px solid var(--hud-edge);
1346
+ }
1347
+ .banner::before {
1348
+ content: "";
1349
+ width: 8px;
1350
+ height: 8px;
1351
+ background: var(--green);
1352
+ box-shadow: var(--glow-green);
1353
+ animation: blink 1.6s ease-in-out infinite;
1354
+ flex: none;
1355
+ }
1356
+ @keyframes blink {
1357
+ 0%,
1358
+ 100% {
1359
+ opacity: 1;
1360
+ }
1361
+ 50% {
1362
+ opacity: 0.35;
1363
+ }
1364
+ }
1365
+ .home {
1366
+ max-width: 900px;
1367
+ margin: 0 auto;
1368
+ padding: 32px 24px;
1369
+ }
1370
+ .home h2,
1371
+ .home h3 {
1372
+ font-family: var(--font-display);
1373
+ font-weight: 400;
1374
+ font-size: 0.85rem;
1375
+ text-transform: var(--heading-transform);
1376
+ color: var(--accent);
1377
+ text-shadow: var(--glow-red);
1378
+ }
1379
+ .home h3 {
1380
+ font-size: 0.65rem;
1381
+ color: var(--muted);
1382
+ text-shadow: none;
1383
+ margin-top: 28px;
1384
+ }
1385
+ .home .item {
1386
+ border-radius: var(--radius);
1387
+ border: 1px solid var(--hud-edge);
1388
+ box-shadow: var(--bevel);
1389
+ background: var(--bg2);
1390
+ padding: 12px 16px;
1391
+ margin-bottom: 10px;
1392
+ display: flex;
1393
+ gap: 12px;
1394
+ align-items: center;
1395
+ cursor: pointer;
1396
+ transition:
1397
+ border-color var(--transition),
1398
+ box-shadow var(--transition);
1399
+ }
1400
+ .home .item:hover {
1401
+ border-color: var(--doom);
1402
+ box-shadow: var(--bevel-glow-red);
1403
+ }
1404
+ .home .item .t {
1405
+ font-family: var(--font-mono);
1406
+ font-weight: 700;
1407
+ flex: 1;
1408
+ }
1409
+ .empty-state {
1410
+ padding: 40px;
1411
+ text-align: center;
1412
+ color: var(--muted);
1413
+ font-family: var(--font-mono);
1414
+ font-size: 13px;
1415
+ }