reactoradar 1.2.3

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 (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +366 -0
  3. package/app.js +2450 -0
  4. package/assets/icon.svg +54 -0
  5. package/bin/cli.js +79 -0
  6. package/bin/open-debugger.sh +9 -0
  7. package/bin/setup.js +473 -0
  8. package/index.html +82 -0
  9. package/main.js +528 -0
  10. package/package.json +76 -0
  11. package/preload.js +31 -0
  12. package/sdk/RNDebugSDK.js +540 -0
  13. package/src/main/main.js +396 -0
  14. package/src/main/preload.js +28 -0
  15. package/src/renderer/app.js +221 -0
  16. package/src/renderer/components/object-tree.js +245 -0
  17. package/src/renderer/index.html +111 -0
  18. package/src/renderer/panels/console.js +248 -0
  19. package/src/renderer/panels/memory.js +60 -0
  20. package/src/renderer/panels/network.js +559 -0
  21. package/src/renderer/panels/performance.js +144 -0
  22. package/src/renderer/panels/react.js +31 -0
  23. package/src/renderer/panels/redux.js +159 -0
  24. package/src/renderer/panels/settings.js +93 -0
  25. package/src/renderer/panels/sources.js +189 -0
  26. package/src/renderer/panels/storage.js +134 -0
  27. package/src/renderer/state.js +132 -0
  28. package/src/renderer/styles/components.css +145 -0
  29. package/src/renderer/styles/console.css +73 -0
  30. package/src/renderer/styles/main.css +229 -0
  31. package/src/renderer/styles/network.css +242 -0
  32. package/src/renderer/styles/performance.css +45 -0
  33. package/src/renderer/styles/redux.css +77 -0
  34. package/src/renderer/styles/settings.css +63 -0
  35. package/src/renderer/styles/sources.css +48 -0
  36. package/src/renderer/styles/storage.css +28 -0
  37. package/src/renderer/styles/theme-light.css +57 -0
  38. package/styles.css +1308 -0
package/styles.css ADDED
@@ -0,0 +1,1308 @@
1
+ /* Fonts loaded via index.html <link> — no duplicate @import */
2
+
3
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
4
+
5
+ :root, [data-theme="dark"] {
6
+ --bg: #0d0e11;
7
+ --bg2: #13151a;
8
+ --bg3: #1a1d24;
9
+ --bg4: #20242e;
10
+ --border: #1e2230;
11
+ --border2: #2a2f40;
12
+ --text: #c0c8dc;
13
+ --text-dim: #4a5068;
14
+ --text-mid: #7a8299;
15
+ --text-bright: #e4e9f6;
16
+ --accent: #4facff;
17
+ --accent2: #9b7fff;
18
+ --green: #3dd68c;
19
+ --yellow: #f5c842;
20
+ --red: #ff5e72;
21
+ --orange: #ff8c42;
22
+ --sidebar-w: 62px;
23
+ --titlebar-h: 44px;
24
+ --app-font-size: 12px;
25
+ }
26
+
27
+ [data-theme="light"] {
28
+ --bg: #f5f6f8;
29
+ --bg2: #ebedf2;
30
+ --bg3: #e0e3ea;
31
+ --bg4: #d4d8e2;
32
+ --border: #cdd1dc;
33
+ --border2: #bcc1d0;
34
+ --text: #2c3040;
35
+ --text-dim: #8890a4;
36
+ --text-mid: #5a6378;
37
+ --text-bright: #1a1e2e;
38
+ --accent: #0969da;
39
+ --accent2: #7c3aed;
40
+ --green: #1a7f37;
41
+ --yellow: #9a6700;
42
+ --red: #cf222e;
43
+ --orange: #bc4c00;
44
+ }
45
+
46
+ [data-theme="monokai"] {
47
+ --bg: #272822;
48
+ --bg2: #2d2e27;
49
+ --bg3: #3e3d32;
50
+ --bg4: #49483e;
51
+ --border: #3e3d32;
52
+ --border2: #49483e;
53
+ --text: #f8f8f2;
54
+ --text-dim: #75715e;
55
+ --text-mid: #a6a28c;
56
+ --text-bright: #f8f8f2;
57
+ --accent: #66d9ef;
58
+ --accent2: #ae81ff;
59
+ --green: #a6e22e;
60
+ --yellow: #e6db74;
61
+ --red: #f92672;
62
+ --orange: #fd971f;
63
+ }
64
+
65
+ [data-theme="dracula"] {
66
+ --bg: #282a36;
67
+ --bg2: #21222c;
68
+ --bg3: #343746;
69
+ --bg4: #3d4056;
70
+ --border: #44475a;
71
+ --border2: #535670;
72
+ --text: #f8f8f2;
73
+ --text-dim: #6272a4;
74
+ --text-mid: #8892b8;
75
+ --text-bright: #f8f8f2;
76
+ --accent: #8be9fd;
77
+ --accent2: #bd93f9;
78
+ --green: #50fa7b;
79
+ --yellow: #f1fa8c;
80
+ --red: #ff5555;
81
+ --orange: #ffb86c;
82
+ }
83
+
84
+ [data-theme="solarized-dark"] {
85
+ --bg: #002b36;
86
+ --bg2: #073642;
87
+ --bg3: #094050;
88
+ --bg4: #0b4d5e;
89
+ --border: #094050;
90
+ --border2: #0b4d5e;
91
+ --text: #839496;
92
+ --text-dim: #586e75;
93
+ --text-mid: #657b83;
94
+ --text-bright: #93a1a1;
95
+ --accent: #268bd2;
96
+ --accent2: #6c71c4;
97
+ --green: #859900;
98
+ --yellow: #b58900;
99
+ --red: #dc322f;
100
+ --orange: #cb4b16;
101
+ }
102
+
103
+ [data-theme="solarized-light"] {
104
+ --bg: #fdf6e3;
105
+ --bg2: #eee8d5;
106
+ --bg3: #e6dfcb;
107
+ --bg4: #ded7c3;
108
+ --border: #d6ceb5;
109
+ --border2: #c9c1a8;
110
+ --text: #657b83;
111
+ --text-dim: #93a1a1;
112
+ --text-mid: #839496;
113
+ --text-bright: #073642;
114
+ --accent: #268bd2;
115
+ --accent2: #6c71c4;
116
+ --green: #859900;
117
+ --yellow: #b58900;
118
+ --red: #dc322f;
119
+ --orange: #cb4b16;
120
+ }
121
+
122
+ [data-theme="nord"] {
123
+ --bg: #2e3440;
124
+ --bg2: #3b4252;
125
+ --bg3: #434c5e;
126
+ --bg4: #4c566a;
127
+ --border: #3b4252;
128
+ --border2: #4c566a;
129
+ --text: #d8dee9;
130
+ --text-dim: #616e88;
131
+ --text-mid: #7b88a1;
132
+ --text-bright: #eceff4;
133
+ --accent: #88c0d0;
134
+ --accent2: #b48ead;
135
+ --green: #a3be8c;
136
+ --yellow: #ebcb8b;
137
+ --red: #bf616a;
138
+ --orange: #d08770;
139
+ }
140
+
141
+ [data-theme="github-dark"] {
142
+ --bg: #0d1117;
143
+ --bg2: #161b22;
144
+ --bg3: #21262d;
145
+ --bg4: #30363d;
146
+ --border: #21262d;
147
+ --border2: #30363d;
148
+ --text: #c9d1d9;
149
+ --text-dim: #484f58;
150
+ --text-mid: #8b949e;
151
+ --text-bright: #f0f6fc;
152
+ --accent: #58a6ff;
153
+ --accent2: #bc8cff;
154
+ --green: #3fb950;
155
+ --yellow: #d29922;
156
+ --red: #f85149;
157
+ --orange: #db6d28;
158
+ }
159
+
160
+ [data-theme="one-dark"] {
161
+ --bg: #282c34;
162
+ --bg2: #21252b;
163
+ --bg3: #2c313a;
164
+ --bg4: #353b45;
165
+ --border: #3e4452;
166
+ --border2: #4b5263;
167
+ --text: #abb2bf;
168
+ --text-dim: #5c6370;
169
+ --text-mid: #7f848e;
170
+ --text-bright: #d7dae0;
171
+ --accent: #61afef;
172
+ --accent2: #c678dd;
173
+ --green: #98c379;
174
+ --yellow: #e5c07b;
175
+ --red: #e06c75;
176
+ --orange: #d19a66;
177
+ }
178
+
179
+ html, body, #app { height: 100%; overflow: hidden; }
180
+ body {
181
+ background: var(--bg);
182
+ color: var(--text);
183
+ font-family: 'JetBrains Mono', monospace;
184
+ font-size: 12px;
185
+ -webkit-font-smoothing: antialiased;
186
+ user-select: text;
187
+ -webkit-user-select: text;
188
+ }
189
+
190
+ /* ── LAYOUT ─────────────────────────────────────────────────────────────────── */
191
+ #app {
192
+ display: grid;
193
+ grid-template-areas: "tb tb" "nav main";
194
+ grid-template-rows: var(--titlebar-h) 1fr;
195
+ grid-template-columns: var(--sidebar-w) 1fr;
196
+ height: 100vh;
197
+ }
198
+
199
+ /* ── INLINE DEVICE STATUS (inside titlebar) ───────────────────────────────── */
200
+ .title-sep { color: var(--text-dim); font-size: 13px; -webkit-app-region: no-drag; }
201
+ .device-status {
202
+ display: flex;
203
+ align-items: center;
204
+ gap: 6px;
205
+ font-size: 11px;
206
+ font-weight: 500;
207
+ transition: color 0.2s;
208
+ -webkit-app-region: no-drag;
209
+ white-space: nowrap;
210
+ }
211
+ .device-status.waiting { color: var(--text-dim); }
212
+ .device-status.connected { color: var(--green); }
213
+ .device-dot {
214
+ width: 7px;
215
+ height: 7px;
216
+ border-radius: 50%;
217
+ flex-shrink: 0;
218
+ }
219
+ .device-status.waiting .device-dot {
220
+ background: var(--text-dim);
221
+ animation: pulse 2s infinite;
222
+ }
223
+ .device-status.connected .device-dot {
224
+ background: var(--green);
225
+ animation: none;
226
+ }
227
+ /* Update banner */
228
+ .update-banner {
229
+ background: rgba(79,172,255,.12);
230
+ color: var(--accent);
231
+ font-size: 11px;
232
+ padding: 6px 14px;
233
+ text-align: center;
234
+ display: flex;
235
+ align-items: center;
236
+ justify-content: center;
237
+ gap: 8px;
238
+ -webkit-app-region: no-drag;
239
+ }
240
+ .update-link { color: var(--accent); text-decoration: underline; cursor: pointer; font-weight: 600; }
241
+ .update-dismiss { cursor: pointer; font-size: 14px; color: var(--text-dim); margin-left: 8px; }
242
+ .update-dismiss:hover { color: var(--text); }
243
+
244
+ @keyframes pulse {
245
+ 0%, 100% { opacity: 1; }
246
+ 50% { opacity: 0.3; }
247
+ }
248
+
249
+ /* ── TITLE BAR ───────────────────────────────────────────────────────────────── */
250
+ #titlebar {
251
+ grid-area: tb;
252
+ display: flex;
253
+ align-items: center;
254
+ gap: 12px;
255
+ padding: 0 12px 0 0;
256
+ background: var(--bg2);
257
+ border-bottom: 1px solid var(--border);
258
+ -webkit-app-region: drag;
259
+ user-select: none;
260
+ }
261
+ .titlebar-drag { width: 76px; flex-shrink: 0; -webkit-app-region: drag; }
262
+ .logo {
263
+ font-family: 'Syne', sans-serif;
264
+ font-weight: 800;
265
+ font-size: 15px;
266
+ letter-spacing: -0.5px;
267
+ color: var(--accent);
268
+ -webkit-app-region: no-drag;
269
+ }
270
+ .logo span { color: var(--text-dim); font-weight: 700; }
271
+
272
+ .titlebar-actions {
273
+ margin-left: auto;
274
+ display: flex;
275
+ align-items: center;
276
+ gap: 8px;
277
+ -webkit-app-region: no-drag;
278
+ }
279
+ .filter-input {
280
+ width: 180px;
281
+ padding: 5px 10px;
282
+ border-radius: 6px;
283
+ border: 1px solid var(--border2);
284
+ background: var(--bg3);
285
+ color: var(--text);
286
+ font-family: inherit;
287
+ font-size: 11px;
288
+ outline: none;
289
+ transition: border 0.15s, box-shadow 0.15s;
290
+ user-select: text;
291
+ -webkit-user-select: text;
292
+ -webkit-app-region: no-drag;
293
+ }
294
+ .filter-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(79,172,255,.12); }
295
+ .filter-input::placeholder { color: var(--text-dim); }
296
+
297
+ .tb-btn {
298
+ padding: 5px 12px;
299
+ border-radius: 6px;
300
+ border: 1px solid var(--border2);
301
+ background: transparent;
302
+ color: var(--text-mid);
303
+ font-family: inherit;
304
+ font-size: 11px;
305
+ font-weight: 500;
306
+ cursor: pointer;
307
+ transition: all 0.15s;
308
+ white-space: nowrap;
309
+ }
310
+ .tb-btn:hover { border-color: var(--accent); color: var(--accent); }
311
+ .tb-btn.primary { border-color: var(--accent); color: var(--accent); background: rgba(79,172,255,.08); }
312
+ .tb-btn.primary:hover { background: rgba(79,172,255,.18); }
313
+
314
+ /* ── SIDEBAR ─────────────────────────────────────────────────────────────────── */
315
+ #sidebar {
316
+ grid-area: nav;
317
+ display: flex;
318
+ flex-direction: column;
319
+ align-items: center;
320
+ padding: 8px 0;
321
+ gap: 2px;
322
+ background: var(--bg2);
323
+ border-right: 1px solid var(--border);
324
+ }
325
+ .nav-btn {
326
+ display: flex;
327
+ flex-direction: column;
328
+ align-items: center;
329
+ gap: 3px;
330
+ width: 54px;
331
+ padding: 8px 4px;
332
+ border-radius: 8px;
333
+ border: none;
334
+ background: transparent;
335
+ color: var(--text-dim);
336
+ font-family: inherit;
337
+ font-size: 11px;
338
+ font-weight: 600;
339
+ letter-spacing: 0.3px;
340
+ text-transform: uppercase;
341
+ cursor: pointer;
342
+ transition: all 0.15s;
343
+ }
344
+ .nav-btn svg { width: 20px; height: 20px; }
345
+ .nav-btn:hover { background: var(--bg3); color: var(--text-mid); }
346
+ .nav-btn.active { background: var(--bg4); color: var(--accent); }
347
+
348
+ /* ── PANELS ──────────────────────────────────────────────────────────────────── */
349
+ #content { grid-area: main; overflow: hidden; position: relative; }
350
+ .panel { display: none; height: 100%; flex-direction: column; overflow: hidden; }
351
+ .panel.active { display: flex; }
352
+
353
+ /* ── PANEL TOOLBAR ─────────────────────────────────────────────────────────── */
354
+ .panel-toolbar {
355
+ display: flex;
356
+ align-items: center;
357
+ gap: 6px;
358
+ padding: 6px 14px;
359
+ border-bottom: 1px solid var(--border);
360
+ background: var(--bg2);
361
+ flex-shrink: 0;
362
+ height: 36px;
363
+ }
364
+ .panel-label { font-family: 'Syne', sans-serif; font-size: 10px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: var(--text-dim); }
365
+ .badge { padding: 1px 6px; border-radius: 8px; font-size: 10px; background: var(--bg4); color: var(--text-dim); border: 1px solid var(--border2); min-width: 24px; text-align: center; }
366
+ .tab-row { display: flex; gap: 3px; }
367
+ .tab { padding: 2px 9px; border-radius: 4px; border: 1px solid transparent; background: transparent; color: var(--text-dim); font-family: inherit; font-size: 10px; font-weight: 500; cursor: pointer; transition: all 0.12s; text-transform: uppercase; letter-spacing: 0.5px; }
368
+ .tab.active { background: var(--bg4); border-color: var(--border2); color: var(--text-bright); }
369
+ .tab:hover:not(.active) { color: var(--text); }
370
+ .ml-auto { margin-left: auto; }
371
+
372
+ /* ── SCROLL AREA ─────────────────────────────────────────────────────────────── */
373
+ .scroll-area { flex: 1; overflow-y: auto; overflow-x: hidden; user-select: text; -webkit-user-select: text; }
374
+ .scroll-area::-webkit-scrollbar { width: 4px; }
375
+ .scroll-area::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; }
376
+
377
+ /* ── EMPTY STATE ─────────────────────────────────────────────────────────────── */
378
+ .empty-state {
379
+ display: flex;
380
+ flex-direction: column;
381
+ align-items: center;
382
+ justify-content: center;
383
+ height: 100%;
384
+ gap: 10px;
385
+ color: var(--text-dim);
386
+ }
387
+ .empty-state .icon { font-size: 36px; opacity: 0.25; }
388
+ .empty-state .label { font-size: 12px; }
389
+ .empty-state .hint { font-size: 10px; color: var(--text-dim); opacity: 0.7; }
390
+
391
+ /* ── ANIMATIONS ──────────────────────────────────────────────────────────────── */
392
+ @keyframes fadeSlide {
393
+ from { opacity: 0; transform: translateY(-3px); }
394
+ to { opacity: 1; transform: none; }
395
+ }
396
+ .entry { animation: fadeSlide 0.15s ease; }
397
+
398
+ /* ─────────────────────────────────────────────────────────────────────────────
399
+ CONSOLE PANEL
400
+ ───────────────────────────────────────────────────────────────────────────── */
401
+ .log-row {
402
+ display: grid;
403
+ grid-template-columns: 58px 44px 1fr;
404
+ gap: 8px;
405
+ align-items: baseline;
406
+ padding: 4px 14px;
407
+ border-bottom: 1px solid transparent;
408
+ transition: background 0.08s;
409
+ cursor: default;
410
+ }
411
+ .log-row:hover { background: var(--bg3); }
412
+ .log-row.warn { background: rgba(245,200,66,.03); border-bottom-color: rgba(245,200,66,.06); }
413
+ .log-row.error { background: rgba(255,94,114,.04); border-bottom-color: rgba(255,94,114,.07); }
414
+
415
+ .log-time { color: var(--text-dim); font-size: 10px; white-space: nowrap; }
416
+
417
+ .lvl-badge { display: inline-block; font-size: 9px; font-weight: 700; padding: 1px 5px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.5px; }
418
+ .lvl-log { background: rgba(200,210,230,.07); color: var(--text-dim); }
419
+ .lvl-info { background: rgba(79,172,255,.12); color: var(--accent); }
420
+ .lvl-warn { background: rgba(245,200,66,.12); color: var(--yellow); }
421
+ .lvl-error { background: rgba(255,94,114,.15); color: var(--red); }
422
+ .lvl-debug { background: rgba(155,127,255,.12); color: var(--accent2); }
423
+
424
+ .log-body-wrap {
425
+ display: flex;
426
+ flex-direction: column;
427
+ cursor: pointer;
428
+ min-width: 0;
429
+ }
430
+ .log-arrow {
431
+ display: inline-block;
432
+ width: 14px;
433
+ font-size: 8px;
434
+ color: var(--text-dim);
435
+ flex-shrink: 0;
436
+ user-select: none;
437
+ -webkit-user-select: none;
438
+ margin-bottom: 1px;
439
+ }
440
+ .log-arrow.expanded { color: var(--accent); }
441
+ .log-preview {
442
+ display: flex;
443
+ align-items: baseline;
444
+ gap: 8px;
445
+ color: var(--text);
446
+ font-size: 11px;
447
+ line-height: 1.5;
448
+ overflow: hidden;
449
+ white-space: nowrap;
450
+ user-select: text;
451
+ -webkit-user-select: text;
452
+ }
453
+ .log-preview > span:first-child {
454
+ overflow: hidden;
455
+ text-overflow: ellipsis;
456
+ flex: 1;
457
+ min-width: 0;
458
+ }
459
+ .log-caller-inline {
460
+ flex-shrink: 0;
461
+ font-size: 10px;
462
+ color: var(--text-dim);
463
+ opacity: 0.7;
464
+ }
465
+ .log-full {
466
+ padding-top: 4px;
467
+ }
468
+ .log-body { color: var(--text); white-space: pre-wrap; word-break: break-word; line-height: 1.55; user-select: text; -webkit-user-select: text; cursor: text; }
469
+ .log-text { color: var(--text); }
470
+ .log-caller { display: block; color: var(--text-dim); font-size: 10px; margin-top: 3px; }
471
+
472
+ /* ── Object Inspector Tree (Chrome DevTools-like) ────────────────────────── */
473
+ .ov-node { margin: 0; }
474
+ .ov-header {
475
+ display: inline-flex;
476
+ align-items: baseline;
477
+ gap: 2px;
478
+ cursor: pointer;
479
+ padding: 1px 0;
480
+ border-radius: 2px;
481
+ }
482
+ .ov-arrow { user-select: none; -webkit-user-select: none; }
483
+ .ov-header:hover { background: var(--bg3); }
484
+ .ov-arrow {
485
+ display: inline-block;
486
+ width: 12px;
487
+ font-size: 8px;
488
+ color: var(--text-dim);
489
+ text-align: center;
490
+ flex-shrink: 0;
491
+ transition: transform 0.1s;
492
+ }
493
+ .ov-key { color: var(--accent); }
494
+ .ov-preview { color: var(--text-dim); font-style: italic; }
495
+ .ov-children { padding-left: 16px; border-left: 1px solid var(--border); margin-left: 5px; }
496
+ .ov-leaf { padding: 1px 0 1px 14px; line-height: 1.55; }
497
+ .ov-meta { color: var(--text-dim); font-style: italic; font-size: 10px; }
498
+
499
+ /* Value type colors */
500
+ .ov-str { color: var(--green); }
501
+ .ov-num { color: var(--orange); }
502
+ .ov-bool { color: var(--accent2); }
503
+ .ov-null { color: var(--text-dim); font-style: italic; }
504
+ .ov-undef { color: var(--text-dim); font-style: italic; }
505
+
506
+ /* ─────────────────────────────────────────────────────────────────────────────
507
+ NETWORK PANEL (Chrome DevTools-style)
508
+ ───────────────────────────────────────────────────────────────────────────── */
509
+ /* Filter bar: search + type filters + throttle */
510
+ .net-filter-bar {
511
+ display: flex;
512
+ align-items: center;
513
+ gap: 8px;
514
+ padding: 4px 10px;
515
+ border-bottom: 1px solid var(--border);
516
+ background: var(--bg2);
517
+ flex-shrink: 0;
518
+ }
519
+ .net-search-input {
520
+ width: 160px;
521
+ padding: 3px 8px;
522
+ border-radius: 4px;
523
+ border: 1px solid var(--border2);
524
+ background: var(--bg3);
525
+ color: var(--text);
526
+ font-family: inherit;
527
+ font-size: 10px;
528
+ outline: none;
529
+ user-select: text;
530
+ -webkit-user-select: text;
531
+ }
532
+ .net-search-input:focus { border-color: var(--accent); }
533
+ .net-search-input::placeholder { color: var(--text-dim); }
534
+ .net-type-filters {
535
+ display: flex;
536
+ align-items: center;
537
+ gap: 1px;
538
+ }
539
+ .net-type-btn {
540
+ padding: 2px 8px;
541
+ border: none;
542
+ border-right: 1px solid var(--border);
543
+ background: transparent;
544
+ color: var(--text-dim);
545
+ font-family: inherit;
546
+ font-size: 10px;
547
+ font-weight: 500;
548
+ cursor: pointer;
549
+ transition: all 0.12s;
550
+ }
551
+ .net-type-btn:last-child { border-right: none; }
552
+ .net-type-btn:hover { color: var(--text); background: var(--bg3); }
553
+ .net-type-btn.active { color: var(--accent); background: rgba(79,172,255,.1); }
554
+ .net-throttle { margin-left: auto; }
555
+ .net-throttle-select {
556
+ padding: 2px 6px;
557
+ border-radius: 4px;
558
+ border: 1px solid var(--border2);
559
+ background: var(--bg3);
560
+ color: var(--text-dim);
561
+ font-family: inherit;
562
+ font-size: 10px;
563
+ outline: none;
564
+ cursor: pointer;
565
+ }
566
+ .net-throttle-select:focus { border-color: var(--accent); }
567
+
568
+ .net-layout { display: flex; flex-direction: row; height: 100%; overflow: hidden; position: relative; }
569
+ .net-table-wrap { flex: 1; min-width: 0; overflow: hidden; display: flex; flex-direction: column; }
570
+
571
+ /* Column header row */
572
+ .net-header {
573
+ display: flex;
574
+ align-items: center;
575
+ background: var(--bg2);
576
+ border-bottom: 1px solid var(--border);
577
+ flex-shrink: 0;
578
+ font-size: 10px;
579
+ font-weight: 600;
580
+ color: var(--text-dim);
581
+ text-transform: uppercase;
582
+ letter-spacing: 0.5px;
583
+ user-select: none;
584
+ }
585
+ .net-hcell {
586
+ padding: 5px 8px;
587
+ position: relative;
588
+ overflow: hidden;
589
+ text-overflow: ellipsis;
590
+ white-space: nowrap;
591
+ flex-shrink: 0;
592
+ border-right: 1px solid #3a3f55;
593
+ }
594
+ .net-hcell:last-child { border-right: none; }
595
+ .net-hcell-label { pointer-events: none; }
596
+ .net-sort-icon { font-size: 8px; color: var(--text-dim); opacity: 0.3; pointer-events: none; }
597
+ .net-sort-icon.active { opacity: 1; color: var(--accent); }
598
+ /* Resize handle — aligned on the border line */
599
+ .net-hcell-resize {
600
+ position: absolute;
601
+ top: 0; right: -3px; bottom: 0;
602
+ width: 6px;
603
+ cursor: col-resize;
604
+ z-index: 2;
605
+ }
606
+ .net-hcell-resize:hover { background: var(--accent); opacity: 0.25; }
607
+ .net-hcell-resize.active { background: var(--accent); opacity: 0.5; }
608
+
609
+ /* Full-height resize overlay — spans the entire table height */
610
+ .net-resize-overlay {
611
+ position: absolute;
612
+ top: 0;
613
+ bottom: 0;
614
+ width: 6px;
615
+ cursor: col-resize;
616
+ z-index: 5;
617
+ }
618
+ .net-resize-overlay:hover {
619
+ background: var(--accent);
620
+ opacity: 0.15;
621
+ }
622
+
623
+ /* Data rows */
624
+ .net-rows { flex: 1; overflow-y: auto; overflow-x: hidden; }
625
+ .net-rows::-webkit-scrollbar { width: 4px; }
626
+ .net-rows::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; }
627
+
628
+ .net-row {
629
+ display: flex;
630
+ align-items: center;
631
+ border-bottom: 1px solid var(--border);
632
+ cursor: pointer;
633
+ transition: background 0.08s;
634
+ font-size: 11px;
635
+ }
636
+ .net-row:hover { background: var(--bg3); }
637
+ .net-row.selected { background: var(--bg4); }
638
+ .net-row.error { background: rgba(255,94,114,.04); }
639
+ .net-cell {
640
+ padding: 6px 8px;
641
+ overflow: hidden;
642
+ text-overflow: ellipsis;
643
+ white-space: nowrap;
644
+ flex-shrink: 0;
645
+ border-right: 1px solid #3a3f55;
646
+ }
647
+ .net-cell:last-child { border-right: none; }
648
+ .net-cell-name { color: var(--text-bright); white-space: normal; word-break: break-all; line-height: 1.4; }
649
+ .net-cell-name .net-path { font-weight: 500; word-break: break-all; }
650
+ .net-cell-name .net-host { color: var(--text-dim); font-size: 10px; display: block; margin-top: 1px; }
651
+ .net-cell-name .method-badge { flex-shrink: 0; vertical-align: middle; }
652
+
653
+ .net-status { font-weight: 700; }
654
+ .s-2 { color: var(--green); }
655
+ .s-3 { color: var(--yellow); }
656
+ .s-4 { color: var(--orange); }
657
+ .s-5 { color: var(--red); }
658
+ .s-pending { color: var(--text-dim); }
659
+ .s-err { color: var(--red); }
660
+
661
+ .net-type { color: var(--text-dim); font-size: 10px; }
662
+ .net-initiator { color: var(--text-dim); font-size: 10px; }
663
+ .net-size { color: var(--text-dim); font-size: 10px; text-align: right; }
664
+ .net-time { color: var(--text-dim); font-size: 10px; text-align: right; }
665
+ .net-time.slow { color: var(--orange); }
666
+
667
+ /* Waterfall bar */
668
+ .net-waterfall { position: relative; height: 14px; }
669
+ .wf-bar {
670
+ position: absolute;
671
+ top: 3px;
672
+ height: 8px;
673
+ border-radius: 2px;
674
+ min-width: 2px;
675
+ }
676
+ .wf-bar.s2 { background: var(--green); opacity: 0.6; }
677
+ .wf-bar.s3 { background: var(--yellow); opacity: 0.6; }
678
+ .wf-bar.s4 { background: var(--orange); opacity: 0.6; }
679
+ .wf-bar.s5 { background: var(--red); opacity: 0.6; }
680
+ .wf-bar.pending { background: var(--text-dim); opacity: 0.3; }
681
+ .wf-bar.err { background: var(--red); opacity: 0.5; }
682
+
683
+ .method-badge { font-size: 9px; font-weight: 700; padding: 1px 4px; border-radius: 3px; letter-spacing: 0.3px; }
684
+ .m-GET { background: rgba(61,214,140,.12); color: var(--green); }
685
+ .m-POST { background: rgba(79,172,255,.12); color: var(--accent); }
686
+ .m-PUT { background: rgba(155,127,255,.12); color: var(--accent2); }
687
+ .m-PATCH { background: rgba(255,140,66,.12); color: var(--orange); }
688
+ .m-DELETE { background: rgba(255,94,114,.12); color: var(--red); }
689
+ .m-other { background: var(--bg4); color: var(--text-dim); }
690
+
691
+ /* Detail pane — overlays on top of Status/Type/etc columns, Name column stays visible */
692
+ .net-detail-pane {
693
+ display: none;
694
+ position: absolute;
695
+ top: 0;
696
+ right: 0;
697
+ bottom: 0;
698
+ border-left: 1px solid #3a3f55;
699
+ flex-direction: column;
700
+ background: var(--bg2);
701
+ overflow: hidden;
702
+ z-index: 10;
703
+ }
704
+ .net-detail-pane.open { display: flex; }
705
+ .net-detail-bar {
706
+ display: flex;
707
+ align-items: center;
708
+ background: var(--bg2);
709
+ border-bottom: 1px solid var(--border);
710
+ flex-shrink: 0;
711
+ }
712
+ [data-theme="light"] .net-detail-pane { border-left-color: #bcc1d0; }
713
+ .detail-tabs { display: flex; gap: 0; flex: 1; }
714
+ .detail-tab {
715
+ padding: 7px 14px;
716
+ border: none;
717
+ border-bottom: 2px solid transparent;
718
+ background: transparent;
719
+ color: var(--text-dim);
720
+ font-family: inherit;
721
+ font-size: 10px;
722
+ font-weight: 600;
723
+ cursor: pointer;
724
+ transition: all 0.12s;
725
+ text-transform: uppercase;
726
+ letter-spacing: 0.5px;
727
+ }
728
+ .detail-tab:hover { color: var(--text); }
729
+ .detail-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
730
+ .detail-close {
731
+ padding: 4px 10px;
732
+ border: none;
733
+ background: transparent;
734
+ color: var(--text-dim);
735
+ font-size: 16px;
736
+ cursor: pointer;
737
+ flex-shrink: 0;
738
+ line-height: 1;
739
+ transition: color 0.1s;
740
+ }
741
+ .detail-close:hover { color: var(--red); }
742
+ .detail-content {
743
+ flex: 1;
744
+ overflow-y: auto;
745
+ padding: 10px 14px;
746
+ white-space: pre-wrap;
747
+ word-break: break-all;
748
+ font-size: 11px;
749
+ line-height: 1.6;
750
+ color: var(--text);
751
+ user-select: text;
752
+ -webkit-user-select: text;
753
+ cursor: text;
754
+ }
755
+ .detail-content::-webkit-scrollbar { width: 3px; }
756
+ .detail-content::-webkit-scrollbar-thumb { background: var(--border2); }
757
+
758
+
759
+ .kv-grid { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; }
760
+ .kv-key { color: var(--accent); font-size: 11px; }
761
+ .kv-val { color: var(--text); word-break: break-all; font-size: 11px; }
762
+ .section-label { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); margin-bottom: 6px; margin-top: 10px; }
763
+ .section-label:first-child { margin-top: 0; }
764
+
765
+ /* Context menu */
766
+ .ctx-menu {
767
+ position: fixed;
768
+ background: var(--bg2);
769
+ border: 1px solid var(--border2);
770
+ border-radius: 6px;
771
+ padding: 4px 0;
772
+ min-width: 180px;
773
+ box-shadow: 0 4px 16px rgba(0,0,0,.3);
774
+ z-index: 1000;
775
+ font-size: 11px;
776
+ }
777
+ .ctx-item {
778
+ padding: 6px 14px;
779
+ cursor: pointer;
780
+ color: var(--text);
781
+ transition: background 0.1s;
782
+ }
783
+ .ctx-item:hover { background: var(--bg4); color: var(--accent); }
784
+
785
+ /* ─────────────────────────────────────────────────────────────────────────────
786
+ REDUX PANEL — single scrollable list
787
+ ───────────────────────────────────────────────────────────────────────────── */
788
+ .rdx-entry {
789
+ border-bottom: 1px solid var(--border);
790
+ }
791
+ .rdx-entry.selected { background: var(--bg2); }
792
+ .rdx-entry.is-prev, .rdx-entry.is-next { background: var(--bg); }
793
+
794
+ /* Entry header (always visible row) */
795
+ .rdx-entry-header {
796
+ display: flex;
797
+ align-items: center;
798
+ gap: 6px;
799
+ padding: 7px 12px;
800
+ cursor: pointer;
801
+ transition: background 0.08s;
802
+ font-size: 11px;
803
+ }
804
+ .rdx-entry-header:hover { background: var(--bg3); }
805
+ .rdx-entry.selected .rdx-entry-header { border-left: 3px solid var(--accent); }
806
+ .rdx-index { font-size: 9px; color: var(--text-dim); min-width: 20px; text-align: right; flex-shrink: 0; }
807
+ .rdx-type { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-bright); font-weight: 500; }
808
+ .rdx-changes {
809
+ font-size: 8px; font-weight: 700; padding: 1px 5px; border-radius: 8px;
810
+ background: rgba(255,94,114,.12); color: var(--red); flex-shrink: 0;
811
+ }
812
+ .rdx-time { font-size: 9px; color: var(--text-dim); flex-shrink: 0; }
813
+ .rdx-role {
814
+ font-size: 8px; font-weight: 700; padding: 1px 5px; border-radius: 3px;
815
+ text-transform: uppercase; letter-spacing: 0.3px; flex-shrink: 0;
816
+ }
817
+ .rdx-role.prev { background: var(--bg4); color: var(--text-dim); }
818
+ .rdx-role.current { background: rgba(79,172,255,.15); color: var(--accent); }
819
+ .rdx-role.next { background: var(--bg4); color: var(--text-dim); }
820
+
821
+ /* Expanded detail (shown for selected + prev + next) */
822
+ .rdx-entry-detail {
823
+ padding: 4px 16px 12px;
824
+ font-size: 11px;
825
+ line-height: 1.5;
826
+ user-select: text;
827
+ -webkit-user-select: text;
828
+ }
829
+
830
+ /* Changed keys */
831
+ .redux-changed-keys { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-bottom: 6px; }
832
+ .redux-changed-label { font-size: 9px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.5px; }
833
+ .redux-changed-key {
834
+ font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 3px;
835
+ background: rgba(255,94,114,.1); color: var(--red); border: 1px solid rgba(255,94,114,.2);
836
+ }
837
+ .redux-section-title { font-size: 9px; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); margin-bottom: 4px; margin-top: 8px; }
838
+
839
+ /* Store diff */
840
+ .rdx-store-diff { margin: 6px 0; padding: 4px 0; border-bottom: 1px solid var(--border); }
841
+ .rdx-store-diff:last-child { border-bottom: none; }
842
+ .rdx-store-key-label { font-size: 11px; font-weight: 600; color: var(--accent); margin-bottom: 4px; }
843
+ .rdx-diff-row { display: flex; align-items: flex-start; gap: 6px; padding: 2px 6px; border-radius: 3px; margin: 2px 0; }
844
+ .rdx-diff-row.removed { background: rgba(255,94,114,.06); }
845
+ .rdx-diff-row.added { background: rgba(61,214,140,.06); }
846
+ .rdx-diff-sign { font-weight: 700; font-size: 11px; flex-shrink: 0; width: 14px; text-align: center; }
847
+ .rdx-diff-row.removed .rdx-diff-sign { color: var(--red); }
848
+ .rdx-diff-row.added .rdx-diff-sign { color: var(--green); }
849
+
850
+ /* JSON syntax highlighting */
851
+ .json-key { color: var(--accent); }
852
+ .json-str { color: var(--green); }
853
+ .json-num { color: var(--orange); }
854
+ .json-bool { color: var(--accent2); }
855
+ .json-null { color: var(--text-dim); }
856
+
857
+ /* time travel toolbar */
858
+ .time-travel-bar {
859
+ display: flex;
860
+ align-items: center;
861
+ gap: 6px;
862
+ padding: 6px 12px;
863
+ border-top: 1px solid var(--border);
864
+ background: var(--bg2);
865
+ }
866
+ .tt-btn {
867
+ padding: 3px 10px;
868
+ border-radius: 4px;
869
+ border: 1px solid var(--border2);
870
+ background: transparent;
871
+ color: var(--text-mid);
872
+ font-family: inherit;
873
+ font-size: 10px;
874
+ cursor: pointer;
875
+ transition: all 0.12s;
876
+ }
877
+ .tt-btn:hover { border-color: var(--accent2); color: var(--accent2); }
878
+ .tt-label { font-size: 10px; color: var(--text-dim); margin-left: auto; }
879
+
880
+ /* ─────────────────────────────────────────────────────────────────────────────
881
+ ASYNC STORAGE PANEL
882
+ ───────────────────────────────────────────────────────────────────────────── */
883
+ .storage-layout { display: grid; grid-template-columns: 240px 1fr; height: 100%; }
884
+ .storage-keys { display: flex; flex-direction: column; border-right: 1px solid var(--border); overflow: hidden; }
885
+ .storage-keys-list { flex: 1; overflow-y: auto; }
886
+ .storage-keys-list::-webkit-scrollbar { width: 3px; }
887
+ .storage-keys-list::-webkit-scrollbar-thumb { background: var(--border2); }
888
+
889
+ .storage-key-row {
890
+ display: flex;
891
+ align-items: center;
892
+ padding: 8px 12px;
893
+ border-bottom: 1px solid var(--border);
894
+ cursor: pointer;
895
+ transition: background 0.08s;
896
+ gap: 8px;
897
+ }
898
+ .storage-key-row:hover { background: var(--bg3); }
899
+ .storage-key-row.selected { background: var(--bg4); border-left: 2px solid var(--accent2); }
900
+ .key-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; color: var(--text-bright); }
901
+ .key-size { font-size: 10px; color: var(--text-dim); }
902
+
903
+ .storage-value-view { display: flex; flex-direction: column; overflow: hidden; }
904
+ .storage-value-toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border); background: var(--bg2); }
905
+ .storage-value-body { flex: 1; overflow-y: auto; padding: 12px; font-size: 11px; line-height: 1.6; white-space: pre-wrap; word-break: break-all; user-select: text; -webkit-user-select: text; cursor: text; }
906
+ .storage-value-body::-webkit-scrollbar { width: 3px; }
907
+ .storage-value-body::-webkit-scrollbar-thumb { background: var(--border2); }
908
+
909
+ /* ─────────────────────────────────────────────────────────────────────────────
910
+ REACT TREE PANEL (iframe wrapper)
911
+ ───────────────────────────────────────────────────────────────────────────── */
912
+ .react-panel-inner {
913
+ display: flex;
914
+ flex-direction: column;
915
+ height: 100%;
916
+ }
917
+ .react-devtools-iframe {
918
+ flex: 1;
919
+ border: none;
920
+ background: #1a1d24;
921
+ width: 100%;
922
+ }
923
+ .react-connect-hint {
924
+ display: flex;
925
+ flex-direction: column;
926
+ align-items: center;
927
+ justify-content: center;
928
+ height: 100%;
929
+ gap: 14px;
930
+ color: var(--text-dim);
931
+ }
932
+ .react-connect-hint code { background: var(--bg3); padding: 3px 8px; border-radius: 4px; color: var(--accent); font-size: 11px; }
933
+ .btn-launch {
934
+ padding: 8px 20px;
935
+ border-radius: 6px;
936
+ border: 1px solid var(--accent);
937
+ background: rgba(79,172,255,.1);
938
+ color: var(--accent);
939
+ font-family: inherit;
940
+ font-size: 12px;
941
+ cursor: pointer;
942
+ transition: all 0.15s;
943
+ }
944
+ .btn-launch:hover { background: rgba(79,172,255,.2); }
945
+
946
+ /* ── Toggle Switch ──────────────────────────────────────────────────────────── */
947
+ .toggle-label {
948
+ display: flex;
949
+ align-items: center;
950
+ gap: 6px;
951
+ cursor: pointer;
952
+ -webkit-app-region: no-drag;
953
+ }
954
+ .toggle-text {
955
+ font-size: 10px;
956
+ font-weight: 500;
957
+ color: var(--text-dim);
958
+ text-transform: uppercase;
959
+ letter-spacing: 0.5px;
960
+ }
961
+ .toggle-input { display: none; }
962
+ .toggle-slider {
963
+ position: relative;
964
+ width: 28px;
965
+ height: 16px;
966
+ border-radius: 8px;
967
+ background: var(--bg4);
968
+ border: 1px solid var(--border2);
969
+ transition: background 0.2s;
970
+ }
971
+ .toggle-slider::after {
972
+ content: '';
973
+ position: absolute;
974
+ top: 2px;
975
+ left: 2px;
976
+ width: 10px;
977
+ height: 10px;
978
+ border-radius: 50%;
979
+ background: var(--text-dim);
980
+ transition: transform 0.2s, background 0.2s;
981
+ }
982
+ .toggle-input:checked + .toggle-slider {
983
+ background: var(--green);
984
+ border-color: var(--green);
985
+ }
986
+ .toggle-input:checked + .toggle-slider::after {
987
+ transform: translateX(12px);
988
+ background: #fff;
989
+ }
990
+
991
+ /* highlight */
992
+ mark { background: rgba(79,172,255,.2); color: var(--accent); border-radius: 2px; padding: 0 1px; }
993
+
994
+ /* ── NAV SPACER ──────────────────────────────────────────────────────────────── */
995
+ .nav-spacer { flex: 1; }
996
+
997
+ /* ─────────────────────────────────────────────────────────────────────────────
998
+ SETTINGS PANEL
999
+ ───────────────────────────────────────────────────────────────────────────── */
1000
+ .settings-content {
1001
+ padding: 24px;
1002
+ max-width: 480px;
1003
+ }
1004
+ .settings-section {
1005
+ margin-bottom: 28px;
1006
+ }
1007
+ .settings-section-title {
1008
+ font-family: 'Syne', sans-serif;
1009
+ font-size: 11px;
1010
+ font-weight: 700;
1011
+ letter-spacing: 1.5px;
1012
+ text-transform: uppercase;
1013
+ color: var(--text-dim);
1014
+ margin-bottom: 14px;
1015
+ }
1016
+ .settings-row {
1017
+ display: flex;
1018
+ align-items: center;
1019
+ justify-content: space-between;
1020
+ padding: 10px 0;
1021
+ border-bottom: 1px solid var(--border);
1022
+ }
1023
+ .settings-row:last-child { border-bottom: none; }
1024
+ .settings-label {
1025
+ font-size: 12px;
1026
+ color: var(--text);
1027
+ }
1028
+ .settings-hint {
1029
+ font-size: 10px;
1030
+ color: var(--text-dim);
1031
+ margin-top: 3px;
1032
+ }
1033
+
1034
+ /* Theme grid */
1035
+ .theme-grid {
1036
+ display: grid;
1037
+ grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
1038
+ gap: 8px;
1039
+ width: 100%;
1040
+ }
1041
+ .theme-card {
1042
+ display: flex;
1043
+ flex-direction: column;
1044
+ align-items: center;
1045
+ gap: 6px;
1046
+ padding: 8px;
1047
+ border: 2px solid var(--border);
1048
+ border-radius: 8px;
1049
+ background: transparent;
1050
+ cursor: pointer;
1051
+ transition: all 0.15s;
1052
+ font-family: inherit;
1053
+ }
1054
+ .theme-card:hover { border-color: var(--text-mid); }
1055
+ .theme-card.active { border-color: var(--accent); background: rgba(79,172,255,.06); }
1056
+ .theme-preview {
1057
+ width: 100%;
1058
+ height: 32px;
1059
+ border-radius: 4px;
1060
+ display: flex;
1061
+ align-items: center;
1062
+ justify-content: center;
1063
+ gap: 4px;
1064
+ padding: 4px;
1065
+ }
1066
+ .theme-preview span {
1067
+ width: 10px;
1068
+ height: 10px;
1069
+ border-radius: 50%;
1070
+ }
1071
+ .theme-name {
1072
+ font-size: 9px;
1073
+ font-weight: 600;
1074
+ color: var(--text);
1075
+ text-align: center;
1076
+ letter-spacing: 0.3px;
1077
+ }
1078
+
1079
+ /* Font size control */
1080
+ .font-size-control {
1081
+ display: flex;
1082
+ align-items: center;
1083
+ gap: 0;
1084
+ border: 1px solid var(--border2);
1085
+ border-radius: 6px;
1086
+ overflow: hidden;
1087
+ }
1088
+ .font-size-btn {
1089
+ padding: 5px 12px;
1090
+ border: none;
1091
+ background: transparent;
1092
+ color: var(--text-dim);
1093
+ font-family: inherit;
1094
+ font-size: 11px;
1095
+ font-weight: 600;
1096
+ cursor: pointer;
1097
+ transition: all 0.15s;
1098
+ }
1099
+ .font-size-btn:hover { color: var(--text); background: var(--bg3); }
1100
+ .font-size-btn:active { background: var(--accent); color: #fff; }
1101
+ .font-size-display {
1102
+ padding: 5px 8px;
1103
+ font-size: 11px;
1104
+ font-weight: 500;
1105
+ color: var(--text-bright);
1106
+ border-left: 1px solid var(--border2);
1107
+ border-right: 1px solid var(--border2);
1108
+ min-width: 38px;
1109
+ text-align: center;
1110
+ }
1111
+
1112
+ /* About section */
1113
+ .settings-about {
1114
+ padding: 12px 0;
1115
+ text-align: center;
1116
+ }
1117
+ .about-name {
1118
+ font-family: 'Syne', sans-serif;
1119
+ font-size: 18px;
1120
+ font-weight: 800;
1121
+ color: var(--accent);
1122
+ letter-spacing: -0.5px;
1123
+ }
1124
+ .about-version {
1125
+ font-size: 11px;
1126
+ color: var(--text-dim);
1127
+ margin-top: 2px;
1128
+ }
1129
+ .about-desc {
1130
+ font-size: 11px;
1131
+ color: var(--text-mid);
1132
+ margin-top: 8px;
1133
+ line-height: 1.5;
1134
+ }
1135
+ .about-links {
1136
+ margin-top: 10px;
1137
+ }
1138
+ .about-link {
1139
+ font-size: 11px;
1140
+ color: var(--accent);
1141
+ cursor: pointer;
1142
+ text-decoration: underline;
1143
+ }
1144
+
1145
+ /* ─────────────────────────────────────────────────────────────────────────────
1146
+ SOURCES PANEL
1147
+ ───────────────────────────────────────────────────────────────────────────── */
1148
+ .sources-layout { display: grid; grid-template-columns: 240px 1fr; height: 100%; }
1149
+ .sources-sidebar { display: flex; flex-direction: column; border-right: 1px solid var(--border); overflow: hidden; }
1150
+ .sources-file-list { flex: 1; overflow-y: auto; }
1151
+ .sources-file-list::-webkit-scrollbar { width: 3px; }
1152
+ .sources-file-list::-webkit-scrollbar-thumb { background: var(--border2); }
1153
+ /* Folder tree */
1154
+ .src-tree-node { user-select: none; -webkit-user-select: none; }
1155
+ .src-tree-folder-header {
1156
+ display: flex;
1157
+ align-items: center;
1158
+ gap: 4px;
1159
+ padding: 3px 8px;
1160
+ cursor: pointer;
1161
+ font-size: 11px;
1162
+ transition: background 0.08s;
1163
+ }
1164
+ .src-tree-folder-header:hover { background: var(--bg3); }
1165
+ .src-tree-arrow {
1166
+ font-size: 8px;
1167
+ width: 12px;
1168
+ text-align: center;
1169
+ color: var(--text-dim);
1170
+ flex-shrink: 0;
1171
+ }
1172
+ .src-tree-arrow.expanded { color: var(--accent); }
1173
+ .src-folder-name { font-weight: 500; }
1174
+ .src-tree-children { }
1175
+ .src-tree-file {
1176
+ display: flex;
1177
+ align-items: center;
1178
+ gap: 5px;
1179
+ padding: 2px 8px;
1180
+ cursor: pointer;
1181
+ font-size: 11px;
1182
+ transition: background 0.08s;
1183
+ }
1184
+ .src-tree-file:hover { background: var(--bg3); }
1185
+ .src-tree-file.selected { background: var(--bg4); border-left: 2px solid var(--accent); }
1186
+ .src-file-icon { font-size: 6px; flex-shrink: 0; }
1187
+ .src-file-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1188
+ .sources-editor { display: flex; flex-direction: column; overflow: hidden; }
1189
+ .sources-code {
1190
+ flex: 1;
1191
+ overflow: auto;
1192
+ font-size: 11px;
1193
+ line-height: 1.6;
1194
+ user-select: text;
1195
+ -webkit-user-select: text;
1196
+ }
1197
+ .source-pre { margin: 0; padding: 0; }
1198
+ .source-line {
1199
+ display: flex;
1200
+ padding: 0 8px;
1201
+ min-height: 18px;
1202
+ }
1203
+ .source-line:hover { background: var(--bg3); }
1204
+ .source-line-num {
1205
+ display: inline-block;
1206
+ width: 44px;
1207
+ flex-shrink: 0;
1208
+ text-align: right;
1209
+ padding-right: 12px;
1210
+ color: var(--text-dim);
1211
+ opacity: 0.5;
1212
+ user-select: none;
1213
+ -webkit-user-select: none;
1214
+ }
1215
+ .source-line-code {
1216
+ flex: 1;
1217
+ white-space: pre;
1218
+ tab-size: 2;
1219
+ }
1220
+
1221
+ /* ─────────────────────────────────────────────────────────────────────────────
1222
+ PERFORMANCE PANEL
1223
+ ───────────────────────────────────────────────────────────────────────────── */
1224
+ .perf-layout { display: flex; flex-direction: column; height: 100%; }
1225
+ .perf-meters {
1226
+ display: flex;
1227
+ gap: 12px;
1228
+ padding: 14px;
1229
+ border-bottom: 1px solid var(--border);
1230
+ flex-shrink: 0;
1231
+ flex-wrap: wrap;
1232
+ }
1233
+ .perf-meter {
1234
+ flex: 1;
1235
+ min-width: 150px;
1236
+ background: var(--bg3);
1237
+ border-radius: 8px;
1238
+ padding: 10px 14px;
1239
+ border: 1px solid var(--border);
1240
+ }
1241
+ .perf-meter-label {
1242
+ font-size: 10px;
1243
+ text-transform: uppercase;
1244
+ letter-spacing: 0.5px;
1245
+ color: var(--text-dim);
1246
+ margin-bottom: 4px;
1247
+ }
1248
+ .perf-meter-value {
1249
+ font-size: 20px;
1250
+ font-weight: 600;
1251
+ color: var(--text-bright);
1252
+ margin-bottom: 8px;
1253
+ }
1254
+ .perf-canvas {
1255
+ width: 100%;
1256
+ height: 60px;
1257
+ border-radius: 4px;
1258
+ background: var(--bg);
1259
+ }
1260
+ .perf-timeline { flex: 1; }
1261
+
1262
+ /* ─────────────────────────────────────────────────────────────────────────────
1263
+ MEMORY PANEL
1264
+ ───────────────────────────────────────────────────────────────────────────── */
1265
+ .memory-layout { display: flex; flex-direction: column; height: 100%; }
1266
+
1267
+ /* ── LIGHT THEME OVERRIDES ───────────────────────────────────────────────────── */
1268
+ [data-theme="light"] .tb-btn.primary {
1269
+ background: rgba(9,105,218,.08);
1270
+ }
1271
+ [data-theme="light"] .tb-btn.primary:hover {
1272
+ background: rgba(9,105,218,.16);
1273
+ }
1274
+ [data-theme="light"] .filter-input:focus {
1275
+ box-shadow: 0 0 0 2px rgba(9,105,218,.15);
1276
+ }
1277
+ [data-theme="light"] .log-row.warn {
1278
+ background: rgba(154,103,0,.05);
1279
+ border-bottom-color: rgba(154,103,0,.1);
1280
+ }
1281
+ [data-theme="light"] .log-row.error {
1282
+ background: rgba(207,34,46,.05);
1283
+ border-bottom-color: rgba(207,34,46,.1);
1284
+ }
1285
+ [data-theme="light"] .lvl-log { background: rgba(44,48,64,.06); }
1286
+ [data-theme="light"] .lvl-info { background: rgba(9,105,218,.1); }
1287
+ [data-theme="light"] .lvl-warn { background: rgba(154,103,0,.1); }
1288
+ [data-theme="light"] .lvl-error { background: rgba(207,34,46,.1); }
1289
+ [data-theme="light"] .lvl-debug { background: rgba(124,58,237,.1); }
1290
+ [data-theme="light"] .m-GET { background: rgba(26,127,55,.1); }
1291
+ [data-theme="light"] .m-POST { background: rgba(9,105,218,.1); }
1292
+ [data-theme="light"] .m-PUT { background: rgba(124,58,237,.1); }
1293
+ [data-theme="light"] .m-PATCH { background: rgba(188,76,0,.1); }
1294
+ [data-theme="light"] .m-DELETE { background: rgba(207,34,46,.1); }
1295
+ [data-theme="light"] .react-devtools-iframe { background: #e0e3ea; }
1296
+ [data-theme="light"] .btn-launch {
1297
+ background: rgba(9,105,218,.08);
1298
+ }
1299
+ [data-theme="light"] .btn-launch:hover {
1300
+ background: rgba(9,105,218,.15);
1301
+ }
1302
+ [data-theme="light"] mark {
1303
+ background: rgba(9,105,218,.15);
1304
+ }
1305
+ [data-theme="light"] .net-hcell,
1306
+ [data-theme="light"] .net-cell {
1307
+ border-right-color: #bcc1d0;
1308
+ }