@proteus-vue/devtools 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/style.css ADDED
@@ -0,0 +1,1248 @@
1
+ /* @proteus-vue/devtools style.css —— Vue DevTools 质感暗色主题(VS Code 风格)
2
+ 设计对照:侧栏导航 + 内容区 + 等宽数据 + 类型着色 + 强调色 #4fc3f7 */
3
+
4
+ :root {
5
+ /* 色板(VS Code 深色) */
6
+ --pd-bg: #1e1e1e;
7
+ --pd-bg-panel: #252526;
8
+ --pd-bg-hover: #2a2d2e;
9
+ --pd-bg-active: #37373d;
10
+ --pd-border: #3e3e42;
11
+ --pd-border-soft: #333333;
12
+ --pd-text: #cccccc;
13
+ --pd-text-dim: #8a8a8a;
14
+ --pd-text-faint: #6b6b6b;
15
+ --pd-accent: #4fc3f7;
16
+ --pd-green: #4ec9b0;
17
+ --pd-orange: #ce9178;
18
+ --pd-red: #f14c4c;
19
+ --pd-yellow: #dcdcaa;
20
+ --pd-purple: #c586c0;
21
+ --pd-blue: #569cd6;
22
+ --pd-mono: 'SF Mono', 'Cascadia Code', Consolas, 'Courier New', monospace;
23
+ /* 类型着色(状态 inspector) */
24
+ --pd-t-number: #b5cea8;
25
+ --pd-t-string: #ce9178;
26
+ --pd-t-boolean: #569cd6;
27
+ --pd-t-null: #808080;
28
+ --pd-t-key: #9cdcfe;
29
+ --pd-t-obj: #dcdcaa;
30
+ }
31
+
32
+ body.pd-body {
33
+ margin: 0;
34
+ background: var(--pd-bg);
35
+ color: var(--pd-text);
36
+ font: 13px/1.5 -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif;
37
+ -webkit-font-smoothing: antialiased;
38
+ }
39
+
40
+ /* ── 面板骨架:顶栏 + 侧栏 + 内容 ───────────────────────────── */
41
+ .pd-panel {
42
+ display: flex;
43
+ flex-direction: column;
44
+ height: 100vh;
45
+ background: var(--pd-bg);
46
+ }
47
+
48
+ .pd-header {
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 10px;
52
+ padding: 0 14px;
53
+ height: 40px;
54
+ background: var(--pd-bg-panel);
55
+ border-bottom: 1px solid var(--pd-border);
56
+ flex-shrink: 0;
57
+ }
58
+
59
+ .pd-header-title {
60
+ font-weight: 600;
61
+ font-size: 13px;
62
+ color: var(--pd-text);
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 8px;
66
+ }
67
+
68
+ .pd-header-title::before {
69
+ content: '◈';
70
+ color: var(--pd-accent);
71
+ font-size: 15px;
72
+ }
73
+
74
+ .pd-header-status {
75
+ margin-left: auto;
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 6px;
79
+ font-size: 11px;
80
+ color: var(--pd-text-faint);
81
+ }
82
+
83
+ .pd-dot {
84
+ width: 8px;
85
+ height: 8px;
86
+ border-radius: 50%;
87
+ background: var(--pd-text-faint);
88
+ }
89
+
90
+ .pd-dot-on {
91
+ background: var(--pd-green);
92
+ box-shadow: 0 0 6px var(--pd-green);
93
+ }
94
+
95
+ .pd-body-row {
96
+ display: flex;
97
+ flex: 1;
98
+ min-height: 0;
99
+ }
100
+
101
+ /* 侧栏导航(Vue DevTools Inspector 风格) */
102
+ .pd-sidebar {
103
+ width: 150px;
104
+ flex-shrink: 0;
105
+ background: var(--pd-bg-panel);
106
+ border-right: 1px solid var(--pd-border);
107
+ padding: 6px 0;
108
+ overflow-y: auto;
109
+ }
110
+
111
+ .pd-nav-item {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 8px;
115
+ padding: 6px 14px;
116
+ font-size: 12px;
117
+ color: var(--pd-text-dim);
118
+ cursor: pointer;
119
+ user-select: none;
120
+ border-left: 2px solid transparent;
121
+ }
122
+
123
+ .pd-nav-item:hover {
124
+ background: var(--pd-bg-hover);
125
+ color: var(--pd-text);
126
+ }
127
+
128
+ .pd-nav-active {
129
+ background: var(--pd-bg-active);
130
+ color: var(--pd-text);
131
+ border-left-color: var(--pd-accent);
132
+ }
133
+
134
+ .pd-nav-icon {
135
+ width: 14px;
136
+ text-align: center;
137
+ font-size: 13px;
138
+ }
139
+
140
+ /* 内容区 */
141
+ .pd-content {
142
+ flex: 1;
143
+ min-width: 0;
144
+ overflow-y: auto;
145
+ padding: 12px 16px;
146
+ }
147
+
148
+ .pd-view {
149
+ display: none;
150
+ height: 100%;
151
+ }
152
+
153
+ .pd-view-active {
154
+ display: block;
155
+ }
156
+
157
+ /* ── 通用控件 ──────────────────────────────────────────────── */
158
+ .pd-toolbar {
159
+ display: flex;
160
+ align-items: center;
161
+ gap: 8px;
162
+ margin-bottom: 10px;
163
+ font-size: 11px;
164
+ color: var(--pd-text-faint);
165
+ }
166
+
167
+ .pd-btn {
168
+ background: var(--pd-bg-active);
169
+ border: 1px solid var(--pd-border);
170
+ color: var(--pd-text);
171
+ padding: 3px 10px;
172
+ border-radius: 3px;
173
+ font-size: 12px;
174
+ cursor: pointer;
175
+ }
176
+
177
+ .pd-btn:hover {
178
+ border-color: var(--pd-accent);
179
+ color: var(--pd-accent);
180
+ }
181
+
182
+ .pd-empty {
183
+ color: var(--pd-text-faint);
184
+ padding: 40px 0;
185
+ text-align: center;
186
+ font-size: 12px;
187
+ }
188
+
189
+ /* ── Timeline 视图 ─────────────────────────────────────────── */
190
+ .pd-ruler {
191
+ display: flex;
192
+ border-bottom: 1px solid var(--pd-border-soft);
193
+ margin-bottom: 6px;
194
+ height: 18px;
195
+ font-size: 10px;
196
+ color: var(--pd-text-faint);
197
+ }
198
+
199
+ .pd-lane {
200
+ display: flex;
201
+ margin: 3px 0;
202
+ align-items: center;
203
+ }
204
+
205
+ .pd-lane-label {
206
+ width: 96px;
207
+ flex-shrink: 0;
208
+ color: var(--pd-accent);
209
+ text-align: right;
210
+ padding-right: 10px;
211
+ font-size: 11px;
212
+ overflow: hidden;
213
+ white-space: nowrap;
214
+ font-family: var(--pd-mono);
215
+ }
216
+
217
+ .pd-lane-track {
218
+ position: relative;
219
+ flex: 1;
220
+ height: 22px;
221
+ background: var(--pd-bg-panel);
222
+ border-radius: 3px;
223
+ overflow: hidden;
224
+ }
225
+
226
+ .pd-span {
227
+ position: absolute;
228
+ top: 2px;
229
+ height: 18px;
230
+ background: #2e7d32;
231
+ border-radius: 2px;
232
+ overflow: hidden;
233
+ white-space: nowrap;
234
+ font-size: 10px;
235
+ color: #e8f5e9;
236
+ cursor: default;
237
+ transition: filter 0.12s;
238
+ }
239
+
240
+ .pd-span:hover {
241
+ filter: brightness(1.35);
242
+ z-index: 2;
243
+ }
244
+
245
+ .pd-span-pending {
246
+ background: #b26a00;
247
+ }
248
+
249
+ .pd-span-dot {
250
+ background: #546e7a;
251
+ }
252
+
253
+ /* 虚拟滚动(万级 span 分块渲染):spacer 占位 + 泳道绝对定位 */
254
+ .pd-timeline-spacer {
255
+ position: relative;
256
+ width: 100%;
257
+ }
258
+
259
+ /* ── Flamegraph 视图 ───────────────────────────────────────── */
260
+ .pd-fg-board {
261
+ position: relative;
262
+ background: var(--pd-bg-panel);
263
+ border-radius: 4px;
264
+ }
265
+
266
+ .pd-fg-node {
267
+ position: absolute;
268
+ background: #1a5276;
269
+ border: 1px solid #2471a3;
270
+ border-radius: 2px;
271
+ overflow: hidden;
272
+ white-space: nowrap;
273
+ font-size: 10px;
274
+ color: #d4e6f1;
275
+ cursor: pointer;
276
+ transition: filter 0.12s;
277
+ }
278
+
279
+ .pd-fg-node:hover {
280
+ filter: brightness(1.4);
281
+ z-index: 2;
282
+ }
283
+
284
+ .pd-fg-zero {
285
+ background: #3d3d3d;
286
+ border-color: #555;
287
+ }
288
+
289
+ /* ★合成「录制会话」根(视图层包装):虚线边框 + 降透明度区分容器,与真实节点区分 */
290
+ .pd-fg-session {
291
+ border-style: dashed;
292
+ opacity: 0.85;
293
+ cursor: default;
294
+ }
295
+
296
+ /* ★嵌套子容器(子块相对父块定位——经典火焰图堆叠) */
297
+ .pd-fg-children {
298
+ position: absolute;
299
+ }
300
+
301
+ /* ★聚焦缩放:面包屑 + 返回上级 */
302
+ .pd-fg-crumb {
303
+ display: flex;
304
+ align-items: center;
305
+ gap: 4px;
306
+ flex-wrap: wrap;
307
+ padding: 4px 0;
308
+ }
309
+
310
+ .pd-fg-crumb-item {
311
+ background: var(--pd-bg-panel);
312
+ border: 1px solid var(--pd-border-soft);
313
+ border-radius: 3px;
314
+ color: var(--pd-text-dim);
315
+ font-size: 10px;
316
+ padding: 1px 6px;
317
+ cursor: pointer;
318
+ }
319
+
320
+ .pd-fg-crumb-item:hover {
321
+ border-color: var(--pd-accent);
322
+ color: var(--pd-accent);
323
+ }
324
+
325
+ .pd-fg-up {
326
+ margin-left: auto;
327
+ font-size: 10px;
328
+ padding: 1px 8px;
329
+ }
330
+
331
+ /* 对比模式:±10% 高亮(regression 红 / improvement 绿) */
332
+ .pd-fg-reg {
333
+ background: #7b241c;
334
+ border-color: #e74c3c;
335
+ }
336
+
337
+ .pd-fg-imp {
338
+ background: #1e5128;
339
+ border-color: #27ae60;
340
+ }
341
+
342
+ /* ── M8 设备面板:概览卡片 + 能力表 + 内存曲线 ────────────────────── */
343
+ .pd-dev-overview {
344
+ display: flex;
345
+ flex-wrap: wrap;
346
+ gap: 8px;
347
+ padding: 10px 12px 4px;
348
+ }
349
+
350
+ .pd-dev-card {
351
+ background: var(--pd-bg-panel);
352
+ border: 1px solid var(--pd-border-soft);
353
+ border-radius: 6px;
354
+ padding: 8px 12px;
355
+ min-width: 120px;
356
+ }
357
+
358
+ .pd-dev-card-label {
359
+ font-size: 10px;
360
+ color: var(--pd-text-faint);
361
+ }
362
+
363
+ .pd-dev-card-value {
364
+ font-family: var(--pd-mono);
365
+ font-size: 13px;
366
+ color: var(--pd-accent);
367
+ margin-top: 2px;
368
+ }
369
+
370
+ .pd-dev-card-hint {
371
+ font-size: 10px;
372
+ color: var(--pd-yellow);
373
+ margin-top: 2px;
374
+ }
375
+
376
+ .pd-dev-ua {
377
+ padding: 2px 12px 8px;
378
+ font-size: 10px;
379
+ color: var(--pd-text-faint);
380
+ overflow: hidden;
381
+ text-overflow: ellipsis;
382
+ white-space: nowrap;
383
+ }
384
+
385
+ .pd-dev-memory {
386
+ padding: 0 12px 10px;
387
+ }
388
+
389
+ .pd-dev-mem-chart {
390
+ display: flex;
391
+ align-items: flex-end;
392
+ gap: 1px;
393
+ height: 64px;
394
+ background: var(--pd-bg-panel);
395
+ border: 1px solid var(--pd-border-soft);
396
+ border-radius: 4px;
397
+ padding: 4px;
398
+ overflow: hidden;
399
+ }
400
+
401
+ .pd-dev-mem-col {
402
+ position: relative;
403
+ flex: 1;
404
+ height: 100%;
405
+ min-width: 2px;
406
+ }
407
+
408
+ .pd-dev-mem-total {
409
+ position: absolute;
410
+ bottom: 0;
411
+ left: 0;
412
+ right: 0;
413
+ background: #3a3a3e;
414
+ }
415
+
416
+ .pd-dev-mem-used {
417
+ position: absolute;
418
+ bottom: 0;
419
+ left: 0;
420
+ right: 0;
421
+ background: var(--pd-accent);
422
+ opacity: 0.85;
423
+ }
424
+
425
+ .pd-dev-mem-stat {
426
+ margin-top: 4px;
427
+ font-family: var(--pd-mono);
428
+ font-size: 10px;
429
+ color: var(--pd-text-dim);
430
+ }
431
+
432
+ .pd-dev-caps {
433
+ padding: 0 12px 12px;
434
+ }
435
+
436
+ .pd-dev-cap {
437
+ display: flex;
438
+ align-items: center;
439
+ gap: 8px;
440
+ padding: 5px 8px;
441
+ border-bottom: 1px solid var(--pd-border-soft);
442
+ font-size: 12px;
443
+ }
444
+
445
+ .pd-dev-cap-mark {
446
+ width: 18px;
447
+ text-align: center;
448
+ }
449
+
450
+ .pd-dev-cap-ok .pd-dev-cap-name {
451
+ color: var(--pd-green);
452
+ }
453
+
454
+ .pd-dev-cap-no .pd-dev-cap-name {
455
+ color: var(--pd-text-dim);
456
+ text-decoration: line-through;
457
+ }
458
+
459
+ .pd-dev-cap-meta {
460
+ margin-left: auto;
461
+ font-size: 10px;
462
+ color: var(--pd-text-faint);
463
+ font-family: var(--pd-mono);
464
+ }
465
+
466
+ .pd-cmp {
467
+ border: 1px solid var(--pd-border-soft);
468
+ border-radius: 4px;
469
+ padding: 6px 10px;
470
+ margin-bottom: 8px;
471
+ background: var(--pd-bg-panel);
472
+ }
473
+
474
+ .pd-cmp-head {
475
+ font-size: 11px;
476
+ color: var(--pd-text-dim);
477
+ margin-bottom: 4px;
478
+ }
479
+
480
+ .pd-cmp-row {
481
+ display: flex;
482
+ align-items: center;
483
+ gap: 8px;
484
+ padding: 2px 4px;
485
+ font-family: var(--pd-mono);
486
+ font-size: 11px;
487
+ border-radius: 3px;
488
+ }
489
+
490
+ .pd-cmp-row:hover {
491
+ background: var(--pd-bg-hover);
492
+ }
493
+
494
+ /* ★P1:选中组件行(高亮 + 详情面板触发) */
495
+ .pd-cmp-active {
496
+ background: var(--pd-bg-hover);
497
+ outline: 1px solid var(--pd-accent);
498
+ }
499
+
500
+ /* ★P1:组件详情面板(props/state inspector 树) */
501
+ .pd-cmp-detail {
502
+ margin-top: 8px;
503
+ padding: 6px 10px;
504
+ border-top: 1px dashed var(--pd-border-soft);
505
+ }
506
+
507
+ .pd-cmp-detail-section {
508
+ margin-top: 6px;
509
+ }
510
+
511
+ .pd-cmp-detail-label {
512
+ font-size: 10px;
513
+ color: var(--pd-text-dim);
514
+ text-transform: uppercase;
515
+ letter-spacing: 0.5px;
516
+ margin-bottom: 2px;
517
+ }
518
+
519
+ /* ★P1:页面元素高亮(install 侧选中组件 → 描边闪烁) */
520
+ .pd-cmp-highlight {
521
+ outline: 3px solid var(--pd-accent) !important;
522
+ outline-offset: 2px;
523
+ transition: outline-color 0.3s ease;
524
+ }
525
+
526
+ /* ★P1.5:DOM 元素树(组件详情面板) */
527
+ .pd-dom-node {
528
+ display: flex;
529
+ align-items: baseline;
530
+ gap: 4px;
531
+ font-family: var(--pd-mono);
532
+ font-size: 11px;
533
+ padding: 1px 0;
534
+ }
535
+
536
+ .pd-dom-tag {
537
+ color: var(--pd-accent);
538
+ }
539
+
540
+ .pd-dom-id {
541
+ color: var(--pd-t-key);
542
+ }
543
+
544
+ .pd-dom-cls {
545
+ color: var(--pd-text-faint);
546
+ }
547
+
548
+ .pd-cmp-name {
549
+ flex: 1;
550
+ overflow: hidden;
551
+ white-space: nowrap;
552
+ text-overflow: ellipsis;
553
+ }
554
+
555
+ .pd-cmp-delta {
556
+ flex-shrink: 0;
557
+ }
558
+
559
+ .pd-cmp-regression .pd-cmp-delta { color: var(--pd-red); }
560
+ .pd-cmp-improvement .pd-cmp-delta { color: var(--pd-green); }
561
+
562
+ /* ── State 视图(key-value inspector 树) ─────────────────── */
563
+ /* ★Pinia 面板布局:store 选择器 + 详情(state 树 + actions 时间线) */
564
+ .pd-store-picker {
565
+ display: flex;
566
+ flex-wrap: wrap;
567
+ gap: 6px;
568
+ margin-bottom: 8px;
569
+ }
570
+
571
+ .pd-store-chip {
572
+ background: var(--pd-bg-active);
573
+ border: 1px solid var(--pd-border);
574
+ color: var(--pd-text-dim);
575
+ padding: 3px 10px;
576
+ border-radius: 10px;
577
+ font-size: 11px;
578
+ font-family: var(--pd-mono);
579
+ cursor: pointer;
580
+ }
581
+
582
+ .pd-store-chip:hover {
583
+ color: var(--pd-text);
584
+ }
585
+
586
+ .pd-store-chip-active {
587
+ border-color: var(--pd-accent);
588
+ color: var(--pd-accent);
589
+ }
590
+
591
+ .pd-store-head {
592
+ padding: 6px 10px;
593
+ color: var(--pd-accent);
594
+ font-family: var(--pd-mono);
595
+ font-size: 12px;
596
+ font-weight: 600;
597
+ }
598
+
599
+ .pd-store-timeline {
600
+ margin-top: 4px;
601
+ }
602
+
603
+ .pd-tl-row {
604
+ display: flex;
605
+ align-items: baseline;
606
+ gap: 8px;
607
+ padding: 3px 10px;
608
+ font-family: var(--pd-mono);
609
+ font-size: 11px;
610
+ cursor: pointer;
611
+ border-left: 2px solid transparent;
612
+ }
613
+
614
+ .pd-tl-row:hover {
615
+ background: var(--pd-bg-hover);
616
+ border-left-color: var(--pd-accent);
617
+ }
618
+
619
+ .pd-tl-badge {
620
+ font-size: 9px;
621
+ padding: 0 6px;
622
+ border-radius: 8px;
623
+ flex-shrink: 0;
624
+ }
625
+
626
+ .pd-tl-action {
627
+ background: rgba(197, 134, 192, 0.18);
628
+ color: var(--pd-purple);
629
+ }
630
+
631
+ .pd-tl-patch {
632
+ background: rgba(78, 201, 176, 0.15);
633
+ color: var(--pd-green);
634
+ }
635
+
636
+ .pd-tl-name {
637
+ color: var(--pd-text);
638
+ }
639
+
640
+ .pd-tl-meta {
641
+ margin-left: auto;
642
+ color: var(--pd-text-faint);
643
+ font-size: 10px;
644
+ }
645
+ .pd-store {
646
+ margin-bottom: 8px;
647
+ background: var(--pd-bg-panel);
648
+ border: 1px solid var(--pd-border-soft);
649
+ border-radius: 4px;
650
+ }
651
+
652
+ .pd-store summary {
653
+ padding: 6px 10px;
654
+ color: var(--pd-accent);
655
+ cursor: pointer;
656
+ font-family: var(--pd-mono);
657
+ font-size: 12px;
658
+ }
659
+
660
+ .pd-store summary:hover {
661
+ background: var(--pd-bg-hover);
662
+ }
663
+
664
+ .pd-inspector {
665
+ padding: 4px 0;
666
+ font-family: var(--pd-mono);
667
+ font-size: 12px;
668
+ max-height: 300px;
669
+ overflow-y: auto;
670
+ }
671
+
672
+ .pd-kv {
673
+ display: flex;
674
+ align-items: baseline;
675
+ padding: 1px 10px;
676
+ cursor: default;
677
+ }
678
+
679
+ .pd-kv:hover {
680
+ background: var(--pd-bg-hover);
681
+ }
682
+
683
+ .pd-kv-toggle {
684
+ width: 14px;
685
+ flex-shrink: 0;
686
+ color: var(--pd-text-faint);
687
+ cursor: pointer;
688
+ user-select: none;
689
+ }
690
+
691
+ .pd-kv-key {
692
+ color: var(--pd-t-key);
693
+ margin-right: 8px;
694
+ flex-shrink: 0;
695
+ }
696
+
697
+ .pd-kv-value {
698
+ color: var(--pd-text);
699
+ word-break: break-all;
700
+ }
701
+
702
+ .pd-t-number { color: var(--pd-t-number); }
703
+ .pd-t-string { color: var(--pd-t-string); }
704
+ .pd-t-boolean { color: var(--pd-t-boolean); }
705
+ .pd-t-null { color: var(--pd-t-null); font-style: italic; }
706
+ .pd-t-obj { color: var(--pd-t-obj); }
707
+ .pd-t-key { color: var(--pd-t-key); }
708
+
709
+ /* ★双向调试:值编辑(可编辑提示 + 输入框) */
710
+ .pd-kv-editable {
711
+ cursor: text;
712
+ border-radius: 3px;
713
+ padding: 0 3px;
714
+ }
715
+
716
+ .pd-kv-editable:hover {
717
+ background: var(--pd-bg-active);
718
+ outline: 1px solid var(--pd-border);
719
+ }
720
+
721
+ .pd-kv-edit {
722
+ background: var(--pd-bg-active);
723
+ border: 1px solid var(--pd-accent);
724
+ border-radius: 3px;
725
+ color: var(--pd-text);
726
+ font-family: var(--pd-mono);
727
+ font-size: 12px;
728
+ padding: 0 4px;
729
+ min-width: 80px;
730
+ outline: none;
731
+ }
732
+
733
+ /* ── Route 视图 ────────────────────────────────────────────── */
734
+ .pd-nav {
735
+ border: 1px solid var(--pd-border-soft);
736
+ border-radius: 4px;
737
+ padding: 8px 10px;
738
+ margin: 6px 0;
739
+ background: var(--pd-bg-panel);
740
+ }
741
+
742
+ .pd-nav-path {
743
+ display: flex;
744
+ align-items: center;
745
+ gap: 6px;
746
+ font-family: var(--pd-mono);
747
+ font-size: 12px;
748
+ }
749
+
750
+ .pd-route {
751
+ color: var(--pd-purple);
752
+ }
753
+
754
+ .pd-arrow {
755
+ color: var(--pd-text-faint);
756
+ }
757
+
758
+ .pd-nav-meta {
759
+ color: var(--pd-text-faint);
760
+ margin-left: auto;
761
+ font-size: 11px;
762
+ }
763
+
764
+ .pd-guards {
765
+ margin-top: 6px;
766
+ display: flex;
767
+ flex-wrap: wrap;
768
+ gap: 4px;
769
+ }
770
+
771
+ .pd-guard {
772
+ font-size: 10px;
773
+ padding: 1px 8px;
774
+ border-radius: 8px;
775
+ font-family: var(--pd-mono);
776
+ }
777
+
778
+ .pd-guard-next { background: rgba(78, 201, 176, 0.15); color: var(--pd-green); }
779
+ .pd-guard-redirect { background: rgba(206, 145, 120, 0.15); color: var(--pd-orange); }
780
+ .pd-guard-cancel, .pd-guard-error { background: rgba(241, 76, 76, 0.15); color: var(--pd-red); }
781
+
782
+ /* ── Errors 视图 ───────────────────────────────────────────── */
783
+ .pd-error-card {
784
+ border: 1px solid var(--pd-border);
785
+ border-left: 3px solid var(--pd-red);
786
+ border-radius: 4px;
787
+ padding: 10px 12px;
788
+ margin: 8px 0;
789
+ background: var(--pd-bg-panel);
790
+ }
791
+
792
+ .pd-error-title {
793
+ font-weight: 600;
794
+ font-family: var(--pd-mono);
795
+ font-size: 12px;
796
+ }
797
+
798
+ .pd-error-attr {
799
+ color: var(--pd-yellow);
800
+ margin-top: 3px;
801
+ font-size: 12px;
802
+ }
803
+
804
+ .pd-error-chain {
805
+ display: flex;
806
+ flex-direction: column;
807
+ align-items: flex-start;
808
+ margin: 8px 0;
809
+ font-family: var(--pd-mono);
810
+ font-size: 11px;
811
+ }
812
+
813
+ .pd-chain-node {
814
+ color: var(--pd-text-dim);
815
+ padding: 2px 10px;
816
+ }
817
+
818
+ .pd-chain-root {
819
+ color: #ff8a80;
820
+ font-weight: 600;
821
+ background: rgba(241, 76, 76, 0.1);
822
+ border-radius: 3px;
823
+ }
824
+
825
+ .pd-chain-up {
826
+ color: var(--pd-text-faint);
827
+ font-size: 10px;
828
+ padding-left: 14px;
829
+ }
830
+
831
+ .pd-error-impact {
832
+ display: flex;
833
+ gap: 4px;
834
+ margin: 6px 0;
835
+ }
836
+
837
+ .pd-chip {
838
+ background: #263238;
839
+ color: var(--pd-green);
840
+ border-radius: 8px;
841
+ padding: 1px 8px;
842
+ font-size: 10px;
843
+ font-family: var(--pd-mono);
844
+ }
845
+
846
+ .pd-repro {
847
+ margin: 6px 0 0;
848
+ color: var(--pd-text-dim);
849
+ font-size: 11px;
850
+ padding-left: 18px;
851
+ }
852
+
853
+ .pd-repro li {
854
+ margin: 2px 0;
855
+ }
856
+
857
+ /* ── Tooltip 浮层(Vue DevTools 质感:暗色 + 边框 + 阴影 + mono) ── */
858
+ .pd-tooltip {
859
+ position: fixed;
860
+ z-index: 1000;
861
+ pointer-events: none;
862
+ background: var(--pd-bg-panel);
863
+ border: 1px solid var(--pd-border);
864
+ border-radius: 4px;
865
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.55);
866
+ padding: 6px 10px;
867
+ max-width: 320px;
868
+ font-family: var(--pd-mono);
869
+ font-size: 11px;
870
+ line-height: 1.55;
871
+ }
872
+
873
+ .pd-tooltip-title {
874
+ font-weight: 600;
875
+ color: var(--pd-accent);
876
+ margin-bottom: 2px;
877
+ white-space: nowrap;
878
+ }
879
+
880
+ .pd-tooltip-line {
881
+ color: var(--pd-text-dim);
882
+ white-space: nowrap;
883
+ }
884
+
885
+ /* 滚动条 */
886
+ .pd-content::-webkit-scrollbar,
887
+ .pd-inspector::-webkit-scrollbar,
888
+ .pd-sidebar::-webkit-scrollbar {
889
+ width: 8px;
890
+ }
891
+
892
+ .pd-content::-webkit-scrollbar-thumb,
893
+ .pd-inspector::-webkit-scrollbar-thumb,
894
+ .pd-sidebar::-webkit-scrollbar-thumb {
895
+ background: var(--pd-border);
896
+ border-radius: 4px;
897
+ }
898
+
899
+ /* ── Web 端浮动挂载(installProteusDevtools:右下角 ◈ 按钮 + 覆盖层) ── */
900
+ .pd-floating-toggle {
901
+ position: fixed;
902
+ right: 16px;
903
+ bottom: 16px;
904
+ z-index: 9999;
905
+ width: 40px;
906
+ height: 40px;
907
+ border-radius: 50%;
908
+ background: #252526;
909
+ color: var(--pd-accent);
910
+ border: 1px solid var(--pd-border);
911
+ font-size: 16px;
912
+ cursor: pointer;
913
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
914
+ }
915
+
916
+ .pd-floating-toggle:hover {
917
+ border-color: var(--pd-accent);
918
+ }
919
+
920
+ .pd-floating-host {
921
+ position: fixed;
922
+ right: 16px;
923
+ bottom: 64px;
924
+ z-index: 9998;
925
+ width: min(760px, calc(100vw - 32px));
926
+ height: min(540px, calc(100vh - 80px));
927
+ border-radius: 8px;
928
+ overflow: hidden;
929
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.55);
930
+ }
931
+
932
+ /* ★拖拽把手(面板 header):光标 + 禁止选中文本 */
933
+ .pd-floating-host .pd-header.pd-floating-draggable {
934
+ cursor: move;
935
+ user-select: none;
936
+ }
937
+
938
+ .pd-floating-host .pd-header.pd-floating-draggable:active {
939
+ cursor: grabbing;
940
+ }
941
+
942
+ /* ── M9 插件:network 瀑布 / 命令面板 / 崩溃占位 ────────────── */
943
+ .pd-net {
944
+ display: flex;
945
+ flex-direction: column;
946
+ gap: 2px;
947
+ }
948
+
949
+ .pd-net-row {
950
+ display: flex;
951
+ align-items: center;
952
+ gap: 8px;
953
+ padding: 3px 10px;
954
+ background: var(--pd-bg-panel);
955
+ border: 1px solid var(--pd-border-soft);
956
+ border-left: 3px solid var(--pd-green);
957
+ border-radius: 3px;
958
+ font-family: var(--pd-mono);
959
+ font-size: 11px;
960
+ }
961
+
962
+ .pd-net-row:hover {
963
+ background: var(--pd-bg-hover);
964
+ }
965
+
966
+ .pd-net-error {
967
+ border-left-color: var(--pd-red);
968
+ }
969
+
970
+ .pd-net-name {
971
+ flex: 1;
972
+ overflow: hidden;
973
+ white-space: nowrap;
974
+ text-overflow: ellipsis;
975
+ }
976
+
977
+ .pd-net-meta {
978
+ flex-shrink: 0;
979
+ color: var(--pd-text-dim);
980
+ }
981
+
982
+ .pd-net-error .pd-net-meta {
983
+ color: var(--pd-red);
984
+ }
985
+
986
+ .pd-palette-btn {
987
+ margin-left: auto;
988
+ }
989
+
990
+ .pd-palette {
991
+ position: absolute;
992
+ top: 40px;
993
+ right: 14px;
994
+ min-width: 220px;
995
+ max-height: 320px;
996
+ overflow-y: auto;
997
+ background: var(--pd-bg-panel);
998
+ border: 1px solid var(--pd-border);
999
+ border-radius: 4px;
1000
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
1001
+ z-index: 900;
1002
+ padding: 4px 0;
1003
+ }
1004
+
1005
+ .pd-palette-item {
1006
+ padding: 5px 12px;
1007
+ font-family: var(--pd-mono);
1008
+ font-size: 11px;
1009
+ color: var(--pd-text);
1010
+ cursor: pointer;
1011
+ }
1012
+
1013
+ .pd-palette-item:hover {
1014
+ background: var(--pd-bg-active);
1015
+ color: var(--pd-accent);
1016
+ }
1017
+
1018
+ .pd-palette-empty {
1019
+ padding: 8px 12px;
1020
+ font-size: 11px;
1021
+ color: var(--pd-text-faint);
1022
+ }
1023
+
1024
+ .pd-plugin-crash {
1025
+ border: 1px solid var(--pd-red);
1026
+ border-radius: 4px;
1027
+ padding: 10px 12px;
1028
+ margin: 8px 0;
1029
+ background: rgba(241, 76, 76, 0.08);
1030
+ }
1031
+
1032
+ .pd-plugin-crash-title {
1033
+ font-weight: 600;
1034
+ font-family: var(--pd-mono);
1035
+ font-size: 12px;
1036
+ color: var(--pd-red);
1037
+ }
1038
+
1039
+ .pd-plugin-crash-msg {
1040
+ margin-top: 4px;
1041
+ font-size: 11px;
1042
+ color: var(--pd-text-dim);
1043
+ font-family: var(--pd-mono);
1044
+ word-break: break-all;
1045
+ }
1046
+
1047
+ /* ── Components 视图(组件树) ────────────────────────────── */
1048
+ .pd-cmp-row {
1049
+ display: flex;
1050
+ align-items: baseline;
1051
+ padding: 2px 6px;
1052
+ font-family: var(--pd-mono);
1053
+ font-size: 12px;
1054
+ cursor: pointer;
1055
+ }
1056
+
1057
+ .pd-cmp-row:hover {
1058
+ background: var(--pd-bg-hover);
1059
+ }
1060
+
1061
+ .pd-cmp-name {
1062
+ color: var(--pd-t-key);
1063
+ }
1064
+
1065
+ .pd-cmp-meta {
1066
+ margin-left: auto;
1067
+ color: var(--pd-text-faint);
1068
+ font-size: 10px;
1069
+ padding-right: 8px;
1070
+ }
1071
+
1072
+ /* ── Pages 视图 ───────────────────────────────────────────── */
1073
+ .pd-section-head {
1074
+ font-size: 11px;
1075
+ color: var(--pd-text-dim);
1076
+ margin: 8px 0 4px;
1077
+ font-weight: 600;
1078
+ }
1079
+
1080
+ .pd-page-stack,
1081
+ .pd-page-group {
1082
+ background: var(--pd-bg-panel);
1083
+ border: 1px solid var(--pd-border-soft);
1084
+ border-radius: 4px;
1085
+ padding: 6px 10px;
1086
+ margin-bottom: 8px;
1087
+ }
1088
+
1089
+ .pd-page-row {
1090
+ display: flex;
1091
+ align-items: baseline;
1092
+ gap: 8px;
1093
+ padding: 2px 0;
1094
+ font-family: var(--pd-mono);
1095
+ font-size: 11px;
1096
+ }
1097
+
1098
+ .pd-page-current {
1099
+ color: var(--pd-accent);
1100
+ font-weight: 600;
1101
+ }
1102
+
1103
+ .pd-page-depth {
1104
+ color: var(--pd-text-faint);
1105
+ min-width: 14px;
1106
+ text-align: right;
1107
+ }
1108
+
1109
+ .pd-page-name {
1110
+ color: var(--pd-green);
1111
+ }
1112
+
1113
+ .pd-page-meta {
1114
+ margin-left: auto;
1115
+ color: var(--pd-text-faint);
1116
+ font-size: 10px;
1117
+ }
1118
+
1119
+ /* ── Graph 依赖图视图(路由树) ───────────────────────────── */
1120
+ .pd-graph {
1121
+ background: var(--pd-bg-panel);
1122
+ border: 1px solid var(--pd-border-soft);
1123
+ border-radius: 4px;
1124
+ padding: 6px 10px;
1125
+ }
1126
+
1127
+ .pd-graph-node {
1128
+ display: flex;
1129
+ align-items: baseline;
1130
+ gap: 6px;
1131
+ font-family: var(--pd-mono);
1132
+ font-size: 11px;
1133
+ padding: 1px 0;
1134
+ }
1135
+
1136
+ .pd-graph-root .pd-graph-name {
1137
+ color: var(--pd-accent);
1138
+ font-weight: 600;
1139
+ }
1140
+
1141
+ .pd-graph-line {
1142
+ color: var(--pd-text-faint);
1143
+ white-space: pre;
1144
+ }
1145
+
1146
+ .pd-graph-name {
1147
+ color: var(--pd-t-key);
1148
+ }
1149
+
1150
+ .pd-graph-meta {
1151
+ margin-left: auto;
1152
+ color: var(--pd-text-faint);
1153
+ font-size: 10px;
1154
+ padding-right: 8px;
1155
+ }
1156
+
1157
+ /* ── Ownership 所有权视图(G-43 B4) ─────────────────────── */
1158
+ .pd-ownership {
1159
+ background: var(--pd-bg-panel);
1160
+ border: 1px solid var(--pd-border-soft);
1161
+ border-radius: 4px;
1162
+ padding: 6px 10px;
1163
+ }
1164
+
1165
+ .pd-own-card-title {
1166
+ color: var(--pd-text-faint);
1167
+ font-size: 10px;
1168
+ text-transform: uppercase;
1169
+ letter-spacing: 0.5px;
1170
+ margin: 8px 0 4px;
1171
+ border-bottom: 1px solid var(--pd-border-soft);
1172
+ padding-bottom: 2px;
1173
+ }
1174
+
1175
+ .pd-own-summary:first-child .pd-own-card-title {
1176
+ margin-top: 0;
1177
+ }
1178
+
1179
+ .pd-own-stats {
1180
+ font-family: var(--pd-mono);
1181
+ font-size: 11px;
1182
+ color: var(--pd-text-strong);
1183
+ }
1184
+
1185
+ .pd-own-types {
1186
+ font-family: var(--pd-mono);
1187
+ font-size: 10px;
1188
+ color: var(--pd-text-faint);
1189
+ margin-top: 2px;
1190
+ }
1191
+
1192
+ .pd-own-alert {
1193
+ font-family: var(--pd-mono);
1194
+ font-size: 11px;
1195
+ padding: 1px 0;
1196
+ }
1197
+
1198
+ .pd-own-alert-orphan {
1199
+ color: #f87171;
1200
+ }
1201
+
1202
+ .pd-own-alert-leak,
1203
+ .pd-own-alert-crosspage {
1204
+ color: #fbbf24;
1205
+ }
1206
+
1207
+ .pd-own-alert-longborrow {
1208
+ color: var(--pd-accent);
1209
+ }
1210
+
1211
+ .pd-own-chain {
1212
+ font-family: var(--pd-mono);
1213
+ font-size: 10px;
1214
+ color: var(--pd-text-faint);
1215
+ white-space: pre-wrap;
1216
+ }
1217
+
1218
+ .pd-own-ok {
1219
+ font-size: 11px;
1220
+ color: #4ade80;
1221
+ }
1222
+
1223
+ .pd-own-owner {
1224
+ font-family: var(--pd-mono);
1225
+ font-size: 11px;
1226
+ color: var(--pd-t-key);
1227
+ font-weight: 600;
1228
+ padding: 2px 0 1px;
1229
+ }
1230
+
1231
+ .pd-own-resource {
1232
+ font-family: var(--pd-mono);
1233
+ font-size: 11px;
1234
+ color: var(--pd-text-mute);
1235
+ padding-left: 10px;
1236
+ }
1237
+
1238
+ .pd-own-tl {
1239
+ font-family: var(--pd-mono);
1240
+ font-size: 10px;
1241
+ color: var(--pd-text-mute);
1242
+ padding: 1px 0 1px 10px;
1243
+ }
1244
+
1245
+ .pd-own-tl-unpaired {
1246
+ color: #fbbf24;
1247
+ background: rgba(251, 191, 36, 0.08);
1248
+ }