@preact/signals-devtools-ui 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/styles.css CHANGED
@@ -1,5 +1,244 @@
1
1
  /* DevTools Panel Styles */
2
2
 
3
+ /* ===== Theme Variables ===== */
4
+ .signals-devtools {
5
+ /* Backgrounds */
6
+ --bg-primary: #f5f5f5;
7
+ --bg-secondary: #fff;
8
+ --bg-tertiary: #f8f9fa;
9
+ --bg-hover: #f0f0f0;
10
+ --bg-active-tab: #f5f0ff;
11
+ --bg-active-tab-border: #d0c0e8;
12
+
13
+ /* Borders */
14
+ --border-primary: #e0e0e0;
15
+ --border-secondary: #ccc;
16
+
17
+ /* Text */
18
+ --text-primary: #333;
19
+ --text-secondary: #555;
20
+ --text-muted: #666;
21
+ --text-faint: #999;
22
+ --text-time: #757575;
23
+ --text-connection: #444;
24
+
25
+ /* Brand colors */
26
+ --brand-purple: #5e35b1;
27
+ --brand-purple-hover: #673ab7;
28
+ --brand-blue: #2196f3;
29
+ --brand-blue-hover: #1976d2;
30
+ --brand-blue-deep: #1565c0;
31
+
32
+ /* Shadows */
33
+ --shadow-color: rgba(0, 0, 0, 0.15);
34
+ --shadow-light: rgba(0, 0, 0, 0.08);
35
+ --shadow-medium: rgba(0, 0, 0, 0.12);
36
+
37
+ /* Graph */
38
+ --graph-bg: #f8fafc;
39
+ --graph-grid: #e5e7eb;
40
+ --graph-link: #94a3b8;
41
+ --graph-link-highlight: #673ab7;
42
+ --graph-controls-bg: rgba(255, 255, 255, 0.95);
43
+ --graph-controls-border: #e2e8f0;
44
+ --graph-controls-text: #334155;
45
+ --graph-controls-active: #eeeeee;
46
+ --graph-zoom-text: #64748b;
47
+ --graph-zoom-bg: rgba(255, 255, 255, 0.9);
48
+ --graph-node-stroke: #fff;
49
+ --graph-export-bg: white;
50
+
51
+ /* Tooltip */
52
+ --tooltip-bg: #1e293b;
53
+ --tooltip-text: white;
54
+ --tooltip-id: #94a3b8;
55
+
56
+ /* Toast */
57
+ --toast-bg: #323232;
58
+
59
+ /* Value change */
60
+ --value-prev: #d32f2f;
61
+ --value-new: #388e3c;
62
+ --value-arrow: #666;
63
+
64
+ /* Component update */
65
+ --component-update-bg: #f8fff8;
66
+ --component-badge-bg: #e8f5e9;
67
+ --component-badge-text: #2e7d32;
68
+
69
+ /* Effect badge */
70
+ --effect-badge-bg: #fff3e0;
71
+ --effect-badge-text: #e65100;
72
+
73
+ /* Scrollbar */
74
+ --scrollbar-track: #f5f5f5;
75
+ --scrollbar-thumb: #ccc;
76
+ --scrollbar-thumb-hover: #999;
77
+
78
+ /* Settings */
79
+ --settings-border: #d0d0d0;
80
+ }
81
+
82
+ .signals-devtools[data-theme="dark"] {
83
+ /* Backgrounds */
84
+ --bg-primary: #1a1a2e;
85
+ --bg-secondary: #16213e;
86
+ --bg-tertiary: #1e2a45;
87
+ --bg-hover: #2a3a5c;
88
+ --bg-active-tab: #2d1b69;
89
+ --bg-active-tab-border: #4a3580;
90
+
91
+ /* Borders */
92
+ --border-primary: #2a3a5c;
93
+ --border-secondary: #3a4a6c;
94
+
95
+ /* Text */
96
+ --text-primary: #e0e0e0;
97
+ --text-secondary: #b0b0b0;
98
+ --text-muted: #888;
99
+ --text-faint: #666;
100
+ --text-time: #888;
101
+ --text-connection: #b0b0b0;
102
+
103
+ /* Brand colors */
104
+ --brand-purple: #b39ddb;
105
+ --brand-purple-hover: #9575cd;
106
+ --brand-blue: #64b5f6;
107
+ --brand-blue-hover: #42a5f5;
108
+ --brand-blue-deep: #64b5f6;
109
+
110
+ /* Shadows */
111
+ --shadow-color: rgba(0, 0, 0, 0.4);
112
+ --shadow-light: rgba(0, 0, 0, 0.3);
113
+ --shadow-medium: rgba(0, 0, 0, 0.35);
114
+
115
+ /* Graph */
116
+ --graph-bg: #1a1a2e;
117
+ --graph-grid: #2a3a5c;
118
+ --graph-link: #5a6a8c;
119
+ --graph-link-highlight: #9575cd;
120
+ --graph-controls-bg: rgba(22, 33, 62, 0.95);
121
+ --graph-controls-border: #2a3a5c;
122
+ --graph-controls-text: #b0b0b0;
123
+ --graph-controls-active: #2a3a5c;
124
+ --graph-zoom-text: #888;
125
+ --graph-zoom-bg: rgba(22, 33, 62, 0.9);
126
+ --graph-node-stroke: #16213e;
127
+ --graph-export-bg: #16213e;
128
+
129
+ /* Tooltip */
130
+ --tooltip-bg: #0f1629;
131
+ --tooltip-text: #e0e0e0;
132
+ --tooltip-id: #5a6a8c;
133
+
134
+ /* Toast */
135
+ --toast-bg: #0f1629;
136
+
137
+ /* Value change */
138
+ --value-prev: #ef5350;
139
+ --value-new: #66bb6a;
140
+ --value-arrow: #888;
141
+
142
+ /* Component update */
143
+ --component-update-bg: #1a2e1a;
144
+ --component-badge-bg: #1a3a1a;
145
+ --component-badge-text: #66bb6a;
146
+
147
+ /* Effect badge */
148
+ --effect-badge-bg: #2e1a00;
149
+ --effect-badge-text: #ffb74d;
150
+
151
+ /* Scrollbar */
152
+ --scrollbar-track: #1a1a2e;
153
+ --scrollbar-thumb: #3a4a6c;
154
+ --scrollbar-thumb-hover: #5a6a8c;
155
+
156
+ /* Settings */
157
+ --settings-border: #2a3a5c;
158
+ }
159
+
160
+ @media (prefers-color-scheme: dark) {
161
+ .signals-devtools:not([data-theme="light"]) {
162
+ /* Backgrounds */
163
+ --bg-primary: #1a1a2e;
164
+ --bg-secondary: #16213e;
165
+ --bg-tertiary: #1e2a45;
166
+ --bg-hover: #2a3a5c;
167
+ --bg-active-tab: #2d1b69;
168
+ --bg-active-tab-border: #4a3580;
169
+
170
+ /* Borders */
171
+ --border-primary: #2a3a5c;
172
+ --border-secondary: #3a4a6c;
173
+
174
+ /* Text */
175
+ --text-primary: #e0e0e0;
176
+ --text-secondary: #b0b0b0;
177
+ --text-muted: #888;
178
+ --text-faint: #666;
179
+ --text-time: #888;
180
+ --text-connection: #b0b0b0;
181
+
182
+ /* Brand colors */
183
+ --brand-purple: #b39ddb;
184
+ --brand-purple-hover: #9575cd;
185
+ --brand-blue: #64b5f6;
186
+ --brand-blue-hover: #42a5f5;
187
+ --brand-blue-deep: #64b5f6;
188
+
189
+ /* Shadows */
190
+ --shadow-color: rgba(0, 0, 0, 0.4);
191
+ --shadow-light: rgba(0, 0, 0, 0.3);
192
+ --shadow-medium: rgba(0, 0, 0, 0.35);
193
+
194
+ /* Graph */
195
+ --graph-bg: #1a1a2e;
196
+ --graph-grid: #2a3a5c;
197
+ --graph-link: #5a6a8c;
198
+ --graph-link-highlight: #9575cd;
199
+ --graph-controls-bg: rgba(22, 33, 62, 0.95);
200
+ --graph-controls-border: #2a3a5c;
201
+ --graph-controls-text: #b0b0b0;
202
+ --graph-controls-active: #2a3a5c;
203
+ --graph-zoom-text: #888;
204
+ --graph-zoom-bg: rgba(22, 33, 62, 0.9);
205
+ --graph-node-stroke: #16213e;
206
+ --graph-export-bg: #16213e;
207
+
208
+ /* Tooltip */
209
+ --tooltip-bg: #0f1629;
210
+ --tooltip-text: #e0e0e0;
211
+ --tooltip-id: #5a6a8c;
212
+
213
+ /* Toast */
214
+ --toast-bg: #0f1629;
215
+
216
+ /* Value change */
217
+ --value-prev: #ef5350;
218
+ --value-new: #66bb6a;
219
+ --value-arrow: #888;
220
+
221
+ /* Component update */
222
+ --component-update-bg: #1a2e1a;
223
+ --component-badge-bg: #1a3a1a;
224
+ --component-badge-text: #66bb6a;
225
+
226
+ /* Effect badge */
227
+ --effect-badge-bg: #2e1a00;
228
+ --effect-badge-text: #ffb74d;
229
+
230
+ /* Scrollbar */
231
+ --scrollbar-track: #1a1a2e;
232
+ --scrollbar-thumb: #3a4a6c;
233
+ --scrollbar-thumb-hover: #5a6a8c;
234
+
235
+ /* Settings */
236
+ --settings-border: #2a3a5c;
237
+ }
238
+ }
239
+
240
+ /* ===== Base Styles ===== */
241
+
3
242
  * {
4
243
  box-sizing: border-box;
5
244
  margin: 0;
@@ -11,21 +250,17 @@ body {
11
250
  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
12
251
  font-size: 13px;
13
252
  line-height: 1.4;
14
- color: #333;
15
- background: #f5f5f5;
16
253
  overflow: hidden;
17
254
  }
18
255
 
19
256
  #app {
20
257
  height: 100vh;
21
- display: flex;
22
- flex-direction: column;
23
258
  }
24
259
 
25
260
  /* Header */
26
261
  .header {
27
- background: #fff;
28
- border-bottom: 1px solid #e0e0e0;
262
+ background: var(--bg-secondary);
263
+ border-bottom: 1px solid var(--border-primary);
29
264
  padding: 8px 12px;
30
265
  display: flex;
31
266
  justify-content: space-between;
@@ -42,7 +277,7 @@ body {
42
277
  .header-title h1 {
43
278
  font-size: 16px;
44
279
  font-weight: 700;
45
- color: #5e35b1;
280
+ color: var(--brand-purple);
46
281
  }
47
282
 
48
283
  .connection-status {
@@ -51,13 +286,13 @@ body {
51
286
  gap: 6px;
52
287
  font-size: 12px;
53
288
  font-weight: 500;
54
- color: #444;
289
+ color: var(--text-connection);
55
290
  }
56
291
 
57
292
  .divider {
58
293
  width: 100%;
59
294
  height: 2px;
60
- background: #e0e0e0;
295
+ background: var(--border-primary);
61
296
  margin: 8px 0;
62
297
  }
63
298
 
@@ -103,9 +338,9 @@ body {
103
338
 
104
339
  /* Buttons */
105
340
  .btn {
106
- border: 1px solid #ccc;
107
- background: #fff;
108
- color: #333;
341
+ border: 1px solid var(--border-secondary);
342
+ background: var(--bg-secondary);
343
+ color: var(--text-primary);
109
344
  padding: 4px 12px;
110
345
  border-radius: 4px;
111
346
  font-size: 12px;
@@ -114,21 +349,21 @@ body {
114
349
  }
115
350
 
116
351
  .btn:hover {
117
- background: #f0f0f0;
352
+ background: var(--bg-hover);
118
353
  }
119
354
 
120
355
  .btn.btn-primary {
121
- background: #2196f3;
122
- border-color: #2196f3;
356
+ background: var(--brand-blue);
357
+ border-color: var(--brand-blue);
123
358
  color: white;
124
359
  }
125
360
 
126
361
  .btn.btn-primary:hover {
127
- background: #1976d2;
362
+ background: var(--brand-blue-hover);
128
363
  }
129
364
 
130
365
  .btn.btn-secondary {
131
- background: #f5f5f5;
366
+ background: var(--bg-primary);
132
367
  }
133
368
 
134
369
  .btn:disabled {
@@ -137,27 +372,47 @@ body {
137
372
  }
138
373
 
139
374
  .btn.active {
140
- background: #673ab7;
141
- border-color: #673ab7;
375
+ background: var(--brand-purple-hover);
376
+ border-color: var(--brand-purple-hover);
142
377
  color: white;
143
378
  }
144
379
 
145
380
  .btn.active:hover {
146
- background: #5e35b1;
147
- border-color: #5e35b1;
381
+ background: var(--brand-purple);
382
+ border-color: var(--brand-purple);
383
+ }
384
+
385
+ /* Theme Toggle */
386
+ .theme-toggle {
387
+ border: 1px solid var(--border-secondary);
388
+ background: var(--bg-secondary);
389
+ color: var(--text-primary);
390
+ padding: 4px 10px;
391
+ border-radius: 4px;
392
+ font-size: 12px;
393
+ cursor: pointer;
394
+ transition: all 0.2s;
395
+ display: flex;
396
+ align-items: center;
397
+ gap: 4px;
148
398
  }
149
399
 
150
- /* Settings Panel */
400
+ .theme-toggle:hover {
401
+ background: var(--bg-hover);
402
+ }
403
+
404
+ /* Settings Panel — popover top-layer resets color, so re-declare */
151
405
  .settings-panel {
152
406
  position: absolute;
153
407
  top: 49px;
154
408
  right: 12px;
155
409
  left: auto;
156
410
  width: 320px;
157
- background: white;
158
- border: 1px solid #d0d0d0;
411
+ background: var(--bg-secondary);
412
+ color: var(--text-primary);
413
+ border: 1px solid var(--settings-border);
159
414
  border-radius: 8px;
160
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
415
+ box-shadow: 0 4px 16px var(--shadow-color);
161
416
  z-index: 1000;
162
417
  overflow-y: auto;
163
418
  }
@@ -186,13 +441,21 @@ body {
186
441
  margin-right: 8px;
187
442
  }
188
443
 
444
+ .setting-description {
445
+ color: var(--text-muted);
446
+ font-size: 11px;
447
+ margin-top: 4px;
448
+ }
449
+
189
450
  .setting-group input[type="number"],
190
451
  .setting-group textarea {
191
452
  width: 100%;
192
453
  padding: 6px 8px;
193
- border: 1px solid #ccc;
454
+ border: 1px solid var(--border-secondary);
194
455
  border-radius: 4px;
195
456
  font-size: 12px;
457
+ background: var(--bg-secondary);
458
+ color: var(--text-primary);
196
459
  }
197
460
 
198
461
  .setting-group textarea {
@@ -210,8 +473,8 @@ body {
210
473
 
211
474
  /* Tabs */
212
475
  .tabs {
213
- background: #fff;
214
- border-bottom: 1px solid #e0e0e0;
476
+ background: var(--bg-secondary);
477
+ border-bottom: 1px solid var(--border-primary);
215
478
  display: flex;
216
479
  flex-shrink: 0;
217
480
  padding: 0 8px;
@@ -225,22 +488,22 @@ body {
225
488
  cursor: pointer;
226
489
  font-size: 13px;
227
490
  font-weight: 500;
228
- color: #555;
491
+ color: var(--text-secondary);
229
492
  transition: all 0.2s;
230
493
  margin-top: 4px;
231
494
  border-radius: 6px 6px 0 0;
232
495
  }
233
496
 
234
497
  .tab:hover {
235
- color: #333;
236
- background: #f0f0f0;
498
+ color: var(--text-primary);
499
+ background: var(--bg-hover);
237
500
  }
238
501
 
239
502
  .tab.active {
240
- color: #673ab7;
241
- background: #f5f0ff;
242
- border-color: #d0c0e8;
243
- border-bottom: 2px solid #fff;
503
+ color: var(--brand-purple-hover);
504
+ background: var(--bg-active-tab);
505
+ border-color: var(--bg-active-tab-border);
506
+ border-bottom: 2px solid var(--bg-secondary);
244
507
  margin-bottom: -1px;
245
508
  font-weight: 600;
246
509
  }
@@ -252,11 +515,14 @@ body {
252
515
  position: relative;
253
516
  display: flex;
254
517
  flex-direction: column;
518
+ background: var(--bg-primary);
255
519
  }
256
520
 
257
521
  .tab-content {
258
522
  flex: 1;
259
523
  overflow: hidden;
524
+ display: flex;
525
+ flex-direction: column;
260
526
  }
261
527
 
262
528
  /* Empty State */
@@ -271,11 +537,11 @@ body {
271
537
  .empty-state-content h2 {
272
538
  font-size: 18px;
273
539
  margin-bottom: 8px;
274
- color: #666;
540
+ color: var(--text-muted);
275
541
  }
276
542
 
277
543
  .empty-state-content p {
278
- color: #999;
544
+ color: var(--text-faint);
279
545
  margin-bottom: 16px;
280
546
  }
281
547
 
@@ -287,8 +553,8 @@ body {
287
553
  }
288
554
 
289
555
  .updates-header {
290
- background: #fff;
291
- border-bottom: 1px solid #e0e0e0;
556
+ background: var(--bg-secondary);
557
+ border-bottom: 1px solid var(--border-primary);
292
558
  padding: 8px 12px;
293
559
  flex-shrink: 0;
294
560
  }
@@ -297,19 +563,20 @@ body {
297
563
  display: flex;
298
564
  gap: 16px;
299
565
  font-size: 12px;
300
- color: #666;
566
+ color: var(--text-muted);
301
567
  }
302
568
 
303
569
  .updates-list {
304
570
  flex: 1;
305
571
  overflow-y: auto;
306
572
  padding: 8px;
573
+ min-height: 200px;
307
574
  }
308
575
 
309
576
  /* Update Items */
310
577
  .update-item {
311
- background: white;
312
- border: 1px solid #e0e0e0;
578
+ background: var(--bg-secondary);
579
+ border: 1px solid var(--border-primary);
313
580
  border-radius: 4px;
314
581
  margin-bottom: 8px;
315
582
  padding: 8px;
@@ -322,26 +589,26 @@ body {
322
589
 
323
590
  .update-item.component {
324
591
  border-left: 4px solid #4caf50;
325
- background-color: #f8fff8;
592
+ background-color: var(--component-update-bg);
326
593
  }
327
594
 
328
595
  .update-type-badge {
329
596
  font-size: 10px;
330
597
  padding: 2px 6px;
331
598
  border-radius: 3px;
332
- background: #e0e0e0;
333
- color: #666;
599
+ background: var(--border-primary);
600
+ color: var(--text-muted);
334
601
  margin-left: 8px;
335
602
  }
336
603
 
337
604
  .update-item.component .update-type-badge {
338
- background: #e8f5e9;
339
- color: #2e7d32;
605
+ background: var(--component-badge-bg);
606
+ color: var(--component-badge-text);
340
607
  }
341
608
 
342
609
  .update-item.effect .update-type-badge {
343
- background: #fff3e0;
344
- color: #e65100;
610
+ background: var(--effect-badge-bg);
611
+ color: var(--effect-badge-text);
345
612
  }
346
613
 
347
614
  .component-name-header {
@@ -354,14 +621,14 @@ body {
354
621
  padding: 0;
355
622
  margin: 0;
356
623
  font-family: monospace;
357
- background: #f8f9fa;
624
+ background: var(--bg-tertiary);
358
625
  padding: 4px 6px;
359
626
  border-radius: 3px;
360
627
  }
361
628
 
362
629
  .update-item.rerender {
363
630
  border-left: 4px solid #9c27b0;
364
- background-color: #fafafa;
631
+ background-color: var(--bg-primary);
365
632
  }
366
633
 
367
634
  .update-item.value {
@@ -377,41 +644,46 @@ body {
377
644
 
378
645
  .signals-devtools {
379
646
  position: relative;
647
+ color: var(--text-primary);
648
+ background: var(--bg-primary);
649
+ min-height: 100%;
650
+ display: flex;
651
+ flex-direction: column;
380
652
  }
381
653
 
382
654
  .update-count {
383
655
  display: inline-block;
384
656
  padding: 0 6px;
385
- background: #e0e0e0;
657
+ background: var(--border-primary);
386
658
  border-radius: 12px;
387
659
  margin: 0 2px;
388
660
  }
389
661
 
390
662
  .signal-name {
391
663
  font-weight: 600;
392
- color: #5e35b1;
664
+ color: var(--brand-purple);
393
665
  }
394
666
 
395
667
  .component-name {
396
668
  font-weight: 500;
397
- color: #1565c0;
669
+ color: var(--brand-blue-deep);
398
670
  font-style: italic;
399
671
  }
400
672
 
401
673
  .update-time {
402
- color: #757575;
674
+ color: var(--text-time);
403
675
  font-size: 11px;
404
676
  }
405
677
 
406
678
  .update-depth {
407
- color: #555;
679
+ color: var(--text-secondary);
408
680
  font-size: 11px;
409
681
  }
410
682
 
411
683
  .value-change {
412
684
  margin: 4px 0;
413
685
  font-family: monospace;
414
- background: #f8f9fa;
686
+ background: var(--bg-tertiary);
415
687
  padding: 4px 6px;
416
688
  border-radius: 3px;
417
689
  }
@@ -427,16 +699,16 @@ body {
427
699
  }
428
700
 
429
701
  .value-prev {
430
- color: #d32f2f;
702
+ color: var(--value-prev);
431
703
  }
432
704
 
433
705
  .value-new {
434
- color: #388e3c;
706
+ color: var(--value-new);
435
707
  }
436
708
 
437
709
  .value-arrow {
438
710
  margin: 0 8px;
439
- color: #666;
711
+ color: var(--value-arrow);
440
712
  }
441
713
 
442
714
  /* Scrollbar styling */
@@ -445,16 +717,16 @@ body {
445
717
  }
446
718
 
447
719
  .updates-list::-webkit-scrollbar-track {
448
- background: #f5f5f5;
720
+ background: var(--scrollbar-track);
449
721
  }
450
722
 
451
723
  .updates-list::-webkit-scrollbar-thumb {
452
- background: #ccc;
724
+ background: var(--scrollbar-thumb);
453
725
  border-radius: 4px;
454
726
  }
455
727
 
456
728
  .updates-list::-webkit-scrollbar-thumb:hover {
457
- background: #999;
729
+ background: var(--scrollbar-thumb-hover);
458
730
  }
459
731
 
460
732
  /* Graph Visualization */
@@ -468,8 +740,9 @@ body {
468
740
  flex: 1;
469
741
  position: relative;
470
742
  background:
471
- linear-gradient(90deg, #e5e7eb 1px, transparent 1px),
472
- linear-gradient(180deg, #e5e7eb 1px, transparent 1px), #f8fafc;
743
+ linear-gradient(90deg, var(--graph-grid) 1px, transparent 1px),
744
+ linear-gradient(180deg, var(--graph-grid) 1px, transparent 1px),
745
+ var(--graph-bg);
473
746
  background-size: 40px 40px;
474
747
  overflow: hidden;
475
748
  user-select: none;
@@ -492,30 +765,30 @@ body {
492
765
 
493
766
  .graph-reset-button,
494
767
  .graph-export-button {
495
- background: rgba(255, 255, 255, 0.95);
768
+ background: var(--graph-controls-bg);
496
769
  backdrop-filter: blur(4px);
497
- border: 1px solid #e2e8f0;
770
+ border: 1px solid var(--graph-controls-border);
498
771
  border-radius: 6px;
499
- color: #334155;
772
+ color: var(--graph-controls-text);
500
773
  padding: 8px 14px;
501
774
  font-size: 12px;
502
775
  font-weight: 500;
503
776
  cursor: pointer;
504
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
777
+ box-shadow: 0 2px 6px var(--shadow-light);
505
778
  transition: all 0.15s ease;
506
779
  }
507
780
 
508
781
  .graph-reset-button:hover,
509
782
  .graph-export-button:hover {
510
- background: #fff;
511
- border-color: #cbd5e1;
512
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
783
+ background: var(--bg-secondary);
784
+ border-color: var(--border-secondary);
785
+ box-shadow: 0 4px 8px var(--shadow-medium);
513
786
  transform: translateY(-1px);
514
787
  }
515
788
 
516
789
  .graph-reset-button:active,
517
790
  .graph-export-button:active {
518
- background: #eeeeee;
791
+ background: var(--graph-controls-active);
519
792
  transform: translateY(1px);
520
793
  }
521
794
 
@@ -528,10 +801,10 @@ body {
528
801
  top: 100%;
529
802
  left: 0;
530
803
  margin-top: 4px;
531
- background: white;
532
- border: 1px solid #e0e0e0;
804
+ background: var(--graph-export-bg);
805
+ border: 1px solid var(--border-primary);
533
806
  border-radius: 4px;
534
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
807
+ box-shadow: 0 4px 8px var(--shadow-color);
535
808
  overflow: hidden;
536
809
  min-width: 180px;
537
810
  }
@@ -539,7 +812,7 @@ body {
539
812
  .graph-export-menu-item {
540
813
  display: block;
541
814
  width: 100%;
542
- background: white;
815
+ background: var(--graph-export-bg);
543
816
  border: none;
544
817
  padding: 10px 12px;
545
818
  font-size: 12px;
@@ -547,31 +820,32 @@ body {
547
820
  cursor: pointer;
548
821
  transition: background 0.2s;
549
822
  white-space: nowrap;
823
+ color: var(--text-primary);
550
824
  }
551
825
 
552
826
  .graph-export-menu-item:hover {
553
- background: #f5f5f5;
827
+ background: var(--bg-primary);
554
828
  }
555
829
 
556
830
  .graph-export-menu-item:active {
557
- background: #eeeeee;
831
+ background: var(--graph-controls-active);
558
832
  }
559
833
 
560
834
  .graph-export-menu-item:not(:last-child) {
561
- border-bottom: 1px solid #e0e0e0;
835
+ border-bottom: 1px solid var(--border-primary);
562
836
  }
563
837
 
564
838
  .graph-zoom-indicator {
565
- background: rgba(255, 255, 255, 0.9);
839
+ background: var(--graph-zoom-bg);
566
840
  backdrop-filter: blur(4px);
567
- border: 1px solid #e0e0e0;
841
+ border: 1px solid var(--border-primary);
568
842
  border-radius: 4px;
569
- color: #64748b;
843
+ color: var(--graph-zoom-text);
570
844
  padding: 6px 10px;
571
845
  font-size: 11px;
572
846
  font-weight: 600;
573
847
  font-family: monospace;
574
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
848
+ box-shadow: 0 2px 4px var(--shadow-light);
575
849
  min-width: 48px;
576
850
  text-align: center;
577
851
  }
@@ -581,9 +855,9 @@ body {
581
855
  transition:
582
856
  transform 0.15s ease,
583
857
  filter 0.15s ease;
584
- stroke: #fff;
858
+ stroke: var(--graph-node-stroke);
585
859
  stroke-width: 2.5;
586
- filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.15));
860
+ filter: drop-shadow(0 3px 6px var(--shadow-color));
587
861
  }
588
862
 
589
863
  .graph-node-group.hovered .graph-node {
@@ -591,6 +865,7 @@ body {
591
865
  stroke-width: 3;
592
866
  }
593
867
 
868
+ /* Identity colors — same in both themes */
594
869
  .graph-node.signal {
595
870
  fill: #2196f3;
596
871
  }
@@ -608,7 +883,7 @@ body {
608
883
  }
609
884
 
610
885
  .graph-link {
611
- stroke: #94a3b8;
886
+ stroke: var(--graph-link);
612
887
  stroke-width: 2;
613
888
  fill: none;
614
889
  transition:
@@ -617,7 +892,7 @@ body {
617
892
  }
618
893
 
619
894
  .graph-link.highlighted {
620
- stroke: #673ab7;
895
+ stroke: var(--graph-link-highlight);
621
896
  stroke-width: 3;
622
897
  }
623
898
 
@@ -635,8 +910,8 @@ body {
635
910
  /* Tooltip */
636
911
  .graph-tooltip {
637
912
  position: absolute;
638
- background: #1e293b;
639
- color: white;
913
+ background: var(--tooltip-bg);
914
+ color: var(--tooltip-text);
640
915
  padding: 10px 14px;
641
916
  border-radius: 8px;
642
917
  font-size: 12px;
@@ -671,6 +946,7 @@ body {
671
946
  font-weight: 600;
672
947
  text-transform: uppercase;
673
948
  letter-spacing: 0.5px;
949
+ color: white;
674
950
  }
675
951
 
676
952
  .tooltip-type.signal {
@@ -697,7 +973,7 @@ body {
697
973
  }
698
974
 
699
975
  .tooltip-id {
700
- color: #94a3b8;
976
+ color: var(--tooltip-id);
701
977
  font-size: 11px;
702
978
  font-family: monospace;
703
979
  }
@@ -706,13 +982,13 @@ body {
706
982
  position: absolute;
707
983
  top: 16px;
708
984
  right: 16px;
709
- background: rgba(255, 255, 255, 0.95);
985
+ background: var(--graph-controls-bg);
710
986
  backdrop-filter: blur(8px);
711
- border: 1px solid #e2e8f0;
987
+ border: 1px solid var(--graph-controls-border);
712
988
  border-radius: 8px;
713
989
  padding: 14px 16px;
714
990
  font-size: 12px;
715
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
991
+ box-shadow: 0 4px 12px var(--shadow-light);
716
992
  }
717
993
 
718
994
  .legend-item {
@@ -730,7 +1006,24 @@ body {
730
1006
  width: 14px;
731
1007
  height: 14px;
732
1008
  border-radius: 50%;
733
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
1009
+ box-shadow: 0 2px 4px var(--shadow-color);
1010
+ }
1011
+
1012
+ /* Legend identity colors */
1013
+ .legend-color.signal {
1014
+ background-color: #2196f3;
1015
+ }
1016
+
1017
+ .legend-color.computed {
1018
+ background-color: #ff9800;
1019
+ }
1020
+
1021
+ .legend-color.effect {
1022
+ background-color: #4caf50;
1023
+ }
1024
+
1025
+ .legend-color.component {
1026
+ background-color: #9c27b0;
734
1027
  }
735
1028
 
736
1029
  .component-boundary {
@@ -748,19 +1041,20 @@ body {
748
1041
  }
749
1042
 
750
1043
  .graph-empty {
1044
+ padding: 32px 0;
751
1045
  display: flex;
752
1046
  align-items: center;
753
1047
  justify-content: center;
754
1048
  height: 100%;
755
1049
  text-align: center;
756
- color: #666;
1050
+ color: var(--text-muted);
757
1051
  }
758
1052
 
759
1053
  .graph-toast {
760
1054
  position: absolute;
761
1055
  top: 16px;
762
1056
  right: 16px;
763
- background: #323232;
1057
+ background: var(--toast-bg);
764
1058
  color: white;
765
1059
  padding: 12px 16px;
766
1060
  border-radius: 4px;
@@ -796,7 +1090,7 @@ body {
796
1090
  .collapse-button {
797
1091
  background: none;
798
1092
  border: none;
799
- color: #666;
1093
+ color: var(--text-muted);
800
1094
  cursor: pointer;
801
1095
  font-size: 12px;
802
1096
  width: 16px;
@@ -811,8 +1105,8 @@ body {
811
1105
  }
812
1106
 
813
1107
  .collapse-button:hover {
814
- color: #333;
815
- background: #f0f0f0;
1108
+ color: var(--text-primary);
1109
+ background: var(--bg-hover);
816
1110
  border-radius: 2px;
817
1111
  }
818
1112
 
@@ -830,7 +1124,7 @@ body {
830
1124
 
831
1125
  .tree-children {
832
1126
  margin-left: 20px;
833
- border-left: 1px solid #e0e0e0;
1127
+ border-left: 1px solid var(--border-primary);
834
1128
  padding-left: 4px;
835
1129
  margin-top: 4px;
836
1130
  }
@@ -844,6 +1138,11 @@ body {
844
1138
  margin-bottom: 0;
845
1139
  }
846
1140
 
1141
+ /* Graph arrowhead color */
1142
+ .graph-arrowhead {
1143
+ fill: var(--graph-link);
1144
+ }
1145
+
847
1146
  /* Responsive adjustments */
848
1147
  @media (max-width: 600px) {
849
1148
  .header {