dsh-codegraph-visualizer 0.3.0 → 0.3.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.
@@ -2385,6 +2385,65 @@ body[data-ds-dark-theme] .cg-type-badge.cg-function {
2385
2385
  color: var(--cg-success);
2386
2386
  text-align: center;
2387
2387
  }
2388
+
2389
+ /* ---- Batch action bar (cycle-149 多选链路消费面) -------------------------- */
2390
+ /*
2391
+ * 悬浮在画布底部、状态栏上方的批量操作条。仅在 `multiSelectedIds.size > 0` 时由
2392
+ * BatchActionBar 渲染;空选区返回 null,因此这里无需 hidden 态样式。
2393
+ * 定位锚定 `.cg-panel`(position: absolute + z-index: var(--cg-z-panel)),
2394
+ * 与 health-score-card 等面板级浮层同层——不遮 ContextMenu(z-context-menu 更高)。
2395
+ */
2396
+
2397
+ .cg-batch-bar {
2398
+ position: absolute;
2399
+ bottom: 44px; /* 状态栏上方(状态栏高度 ≈ 32px + 间距) */
2400
+ left: 50%;
2401
+ transform: translateX(-50%);
2402
+ display: flex;
2403
+ align-items: center;
2404
+ gap: 8px;
2405
+ padding: 6px 10px;
2406
+ border-radius: var(--cg-radius-sm);
2407
+ border: 1px solid var(--cg-border-strong);
2408
+ background: var(--cg-surface);
2409
+ box-shadow: var(--cg-shadow-lg);
2410
+ z-index: var(--cg-z-panel);
2411
+ max-width: calc(100% - 32px);
2412
+ }
2413
+
2414
+ .cg-batch-bar-count {
2415
+ font-size: 12px;
2416
+ font-weight: 600;
2417
+ color: var(--cg-accent);
2418
+ white-space: nowrap;
2419
+ }
2420
+
2421
+ .cg-batch-bar-btn {
2422
+ padding: 4px 10px;
2423
+ border-radius: var(--cg-radius-xs);
2424
+ border: 1px solid var(--cg-border-strong);
2425
+ background: var(--cg-surface);
2426
+ color: var(--cg-text);
2427
+ font-size: 12px;
2428
+ cursor: pointer;
2429
+ white-space: nowrap;
2430
+ transition: background var(--cg-transition), border-color var(--cg-transition);
2431
+ }
2432
+
2433
+ .cg-batch-bar-btn:hover {
2434
+ background: var(--cg-surface-hover);
2435
+ }
2436
+
2437
+ .cg-batch-bar-btn:focus-visible {
2438
+ outline: 2px solid var(--cg-accent);
2439
+ outline-offset: 1px;
2440
+ }
2441
+
2442
+ /* 清除按钮的破坏性语义:hover 提示「这会丢掉选区」,但不用 error 底色(非错误态)。 */
2443
+ .cg-batch-bar-btn-clear:hover {
2444
+ border-color: var(--cg-error);
2445
+ color: var(--cg-error);
2446
+ }
2388
2447
 
2389
2448
  /* ---- Graph container ----------------------------------------------------- */
2390
2449
 
@@ -6129,993 +6188,1050 @@ button.cg-legend-row.cg-legend-toggle:hover {
6129
6188
  opacity: 0.4;
6130
6189
  cursor: not-allowed;
6131
6190
  }
6132
- /* ---- Responsive ---------------------------------------------------------- */
6133
-
6134
- /* Extra-narrow panels (DSH sidebar tab minimal width).
6135
- * Hide the remaining toolbar extras to prioritize graph canvas.
6136
- * The center group is already gone at the 600px tier below. */
6137
- @container graphpanel (max-width: 380px) {
6138
- .cg-tour-btn,
6139
- .cg-minimap-btn,
6140
- .cg-legend-btn {
6141
- display: none;
6142
- }
6143
-
6144
- /* The separators are siblings of the `.cg-toolbar-group` elements, not descendants,
6145
- so the previous `.cg-toolbar-group ... .cg-toolbar-separator` selector never
6146
- matched anything. */
6147
- .cg-toolbar-separator {
6148
- display: none;
6149
- }
6150
- }
6151
-
6152
- /* Small panels (DSH sidebar tab, narrow bottom panel).
6153
- * Container queries respond to the PANEL width, not the viewport — the plugin
6154
- * renders inside DSH panels whose width is unrelated to the window size. */
6155
- @container graphpanel (max-width: 480px) {
6156
- .cg-graph-panel {
6157
- border-radius: var(--cg-radius-sm);
6158
- }
6159
-
6160
- .cg-graph-toolbar {
6161
- padding: 0 8px;
6162
- gap: 4px;
6163
- }
6164
-
6165
- .cg-toolbar-left {
6166
- font-size: 11px;
6167
- }
6168
-
6169
- .cg-toolbar-center {
6170
- gap: 4px;
6171
- }
6172
-
6173
- .cg-toolbar-right {
6174
- gap: 4px;
6175
- }
6176
-
6177
- .cg-layout-btn,
6178
- .cg-graph-type-btn,
6179
- .cg-rank-dir-btn {
6180
- padding: 3px 6px;
6181
- font-size: 10px;
6182
- }
6183
-
6184
- .cg-search-btn,
6185
- .cg-theme-btn,
6186
- .cg-export-btn,
6187
- .cg-collapse-btn,
6188
- .cg-chain-btn,
6189
- .cg-cycle-btn,
6190
- .cg-impact-btn,
6191
- .cg-inheritance-btn,
6192
- .cg-minimap-btn,
6193
- .cg-refresh-btn,
6194
- .cg-undo-btn,
6195
- .cg-redo-btn,
6196
- .cg-import-btn,
6197
- .cg-legend-btn,
6198
- .cg-lang-btn,
6199
- .cg-pathfind-btn,
6200
- .cg-health-btn,
6201
- .cg-rules-btn,
6202
- .cg-hotspot-btn,
6203
- .cg-godmodule-btn,
6204
- .cg-corefunction-btn,
6205
- .cg-analysis-dropdown-btn,
6206
- .cg-quality-dropdown-btn,
6207
- .cg-tour-btn {
6208
- width: 26px;
6209
- height: 26px;
6210
- font-size: 12px;
6211
- }
6212
-
6213
- .cg-dropdown-content {
6214
- min-width: 140px;
6215
- }
6216
-
6217
- .cg-node-detail-panel {
6218
- width: calc(100% - 24px);
6219
- left: 12px;
6220
- top: 12px;
6221
- }
6222
-
6223
- .cg-legend-panel {
6224
- width: 140px;
6225
- }
6226
-
6227
- .cg-mini-map {
6228
- width: 140px;
6229
- }
6230
-
6231
- .cg-type-badge {
6232
- display: none;
6233
- }
6234
-
6235
- .cg-toolbar-separator {
6236
- display: none;
6237
- }
6238
-
6239
- .cg-graph-type-buttons {
6240
- display: none;
6241
- }
6242
-
6243
- .cg-view-mode-buttons {
6244
- gap: 1px;
6245
- }
6246
-
6247
- .cg-view-mode-btn {
6248
- padding: 2px 4px;
6249
- font-size: 9px;
6250
- }
6251
-
6252
- .cg-search-panel,
6253
- .cg-path-panel {
6254
- width: calc(100% - 16px);
6255
- max-width: 320px;
6256
- }
6257
-
6258
- .cg-filter-panel {
6259
- width: calc(100% - 16px);
6260
- }
6261
-
6262
- .cg-heatmap-btn--activate,
6263
- .cg-heatmap-btn--deactivate {
6264
- width: 26px;
6265
- height: 26px;
6266
- font-size: 12px;
6267
- }
6268
-
6269
- }
6270
-
6271
- /* Medium panels (DSH sidebar medium width) */
6272
- @container graphpanel (max-width: 768px) {
6273
- .cg-graph-toolbar {
6274
- padding: 0 8px;
6275
- gap: 6px;
6276
- }
6277
-
6278
- .cg-toolbar-center {
6279
- gap: 6px;
6280
- }
6281
-
6282
- .cg-toolbar-right {
6283
- gap: 6px;
6284
- }
6285
-
6286
- .cg-layout-btn,
6287
- .cg-graph-type-btn {
6288
- padding: 3px 8px;
6289
- font-size: 11px;
6290
- }
6291
-
6292
- .cg-node-detail-panel {
6293
- width: 220px;
6294
- }
6295
-
6296
- .cg-legend-panel {
6297
- width: 160px;
6298
- }
6299
-
6300
- .cg-mini-map {
6301
- width: 160px;
6302
- }
6303
-
6304
- .cg-filter-select {
6305
- font-size: 11px;
6306
- }
6307
-
6308
- .cg-toolbar-separator {
6309
- margin: 0 2px;
6310
- }
6311
-
6312
- .cg-tour-btn {
6313
- display: none;
6314
- }
6315
-
6316
- }
6317
-
6318
- /* Medium-narrow panels — hide tour and reduce analysis button clutter */
6319
- @container graphpanel (max-width: 600px) {
6320
- .cg-tour-btn,
6321
- .cg-minimap-btn {
6322
- display: none;
6323
- }
6324
-
6325
- .cg-toolbar-left .cg-type-badge {
6326
- display: none;
6327
- }
6328
-
6329
- /* The center group (layout / view-mode / level) is the widest fixed-width block in the
6330
- toolbar: 150px for its three icon-only triggers, measured on the real host. At a 520px
6331
- panel it was being squeezed to 115px, which wrapped the level trigger onto two lines
6332
- and clipped it; at 600px it still has 45px of slack. Hiding it here instead of letting
6333
- it be crushed keeps the workspace chip and every right-hand control (export / more /
6334
- collapse) reachable. Of the three controls, only the layout keeps an alternative entry
6335
- point (Ctrl+L cycles it, see `usePanelKeyboard`); view mode and hierarchy level lose
6336
- their mouse entry below this tier — see the note in `docs/需求分析.md` §28.3. */
6337
- .cg-toolbar-center {
6338
- display: none;
6339
- }
6340
- }
6341
-
6342
- /* Very small panels */
6343
- @container graphpanel (max-width: 320px) {
6344
- .cg-graph-toolbar {
6345
- gap: 2px;
6346
- flex-wrap: wrap;
6347
- padding: 4px 4px;
6348
- }
6349
-
6350
- .cg-toolbar-left,
6351
- .cg-toolbar-center,
6352
- .cg-toolbar-right {
6353
- flex-wrap: wrap;
6354
- gap: 2px;
6355
- }
6356
-
6357
- .cg-layout-buttons,
6358
- .cg-graph-type-buttons {
6359
- padding: 1px;
6360
- }
6361
-
6362
- .cg-layout-btn,
6363
- .cg-graph-type-btn {
6364
- padding: 2px 4px;
6365
- font-size: 9px;
6366
- }
6367
-
6368
- .cg-filter-select {
6369
- padding: 3px 20px 3px 6px;
6370
- font-size: 10px;
6371
- }
6372
-
6373
- .cg-node-count {
6374
- font-size: 10px;
6375
- }
6376
-
6377
- .cg-legend-panel,
6378
- .cg-mini-map {
6379
- width: 120px;
6380
- }
6381
-
6382
- /* 下拉内容已 portal 到 document.body,不再是本容器的后代,此处的
6383
- * `@container` 抽屉规则永远匹配不到;抽屉形态改由 Dropdown 组件测量面板
6384
- * 宽度后加 `.cg-portal-drawer`(见 layout.css)实现。 */
6385
-
6386
- .cg-search-panel,
6387
- .cg-path-panel,
6388
- .cg-filter-panel {
6389
- width: calc(100% - 8px);
6390
- left: 4px;
6391
- right: 4px;
6392
- }
6393
-
6394
- .cg-view-mode-buttons {
6395
- flex-wrap: wrap;
6396
- }
6397
- }
6398
-
6399
- /* Large screens — allow fixed floating panel */
6400
- @media (min-width: 1200px) {
6401
- .cg-graph-panel.cg-floating {
6402
- position: fixed;
6403
- right: 16px;
6404
- bottom: 16px;
6405
- width: 640px;
6406
- height: 520px;
6407
- }
6408
- }
6409
-
6410
- /* ---- Sidebar tab mode (short height) -------------------------------------- */
6411
- /* When the plugin renders inside a DSH sidebar tab, the panel height can be
6412
- * very limited. Adapt the layout to prioritize the graph canvas. */
6413
- @container graphpanel (max-height: 400px) {
6414
- .cg-graph-toolbar {
6415
- padding: 0 4px;
6416
- gap: 2px;
6417
- }
6418
-
6419
- .cg-toolbar-left .cg-node-count {
6420
- font-size: 10px;
6421
- }
6422
-
6423
- .cg-type-badge {
6424
- display: none;
6425
- }
6426
-
6427
- .cg-toolbar-separator {
6428
- display: none;
6429
- }
6430
-
6431
- .cg-graph-type-buttons {
6432
- display: none;
6433
- }
6434
-
6435
- .cg-view-mode-buttons {
6436
- gap: 1px;
6437
- }
6438
-
6439
- .cg-view-mode-btn {
6440
- padding: 2px 4px;
6441
- font-size: 9px;
6442
- }
6443
-
6444
- .cg-node-detail-panel {
6445
- max-height: calc(100% - 60px);
6446
- overflow-y: auto;
6447
- }
6448
-
6449
- .cg-legend-panel {
6450
- max-height: 120px;
6451
- overflow-y: auto;
6452
- }
6453
-
6454
- .cg-mini-map {
6455
- max-height: 100px;
6456
- }
6457
-
6458
- .cg-search-panel,
6459
- .cg-path-panel,
6460
- .cg-filter-panel {
6461
- max-height: calc(100% - 60px);
6462
- overflow-y: auto;
6463
- }
6464
- }
6465
-
6466
- @container graphpanel (max-height: 240px) {
6467
- .cg-graph-toolbar {
6468
- flex-wrap: wrap;
6469
- padding: 2px;
6470
- }
6471
-
6472
- .cg-toolbar-left,
6473
- .cg-toolbar-center,
6474
- .cg-toolbar-right {
6475
- flex-wrap: wrap;
6476
- gap: 2px;
6477
- }
6478
-
6479
- .cg-layout-buttons {
6480
- display: none;
6481
- }
6482
-
6483
- .cg-rank-dir-buttons {
6484
- display: none;
6485
- }
6486
-
6487
- .cg-cluster-depth-buttons {
6488
- display: none;
6489
- }
6490
-
6491
- .cg-node-detail-panel {
6492
- width: calc(100% - 8px);
6493
- left: 4px;
6494
- top: 4px;
6495
- max-height: calc(100% - 40px);
6496
- }
6497
- }
6498
-
6499
- /* ---- Reduced motion ------------------------------------------------------ */
6500
-
6501
- @media (prefers-reduced-motion: reduce) {
6502
- .cg-graph-panel *,
6503
- .cg-graph-panel *::before,
6504
- .cg-graph-panel *::after,
6505
- .cg-floating-panel *,
6506
- .cg-floating-panel *::before,
6507
- .cg-floating-panel *::after,
6508
- .cg-floating-container *,
6509
- .cg-floating-container *::before,
6510
- .cg-floating-container *::after {
6511
- animation-duration: 0.01ms !important;
6512
- transition-duration: 0.01ms !important;
6513
- }
6514
- }
6515
-
6516
- /* ---- Touch device adaptation --------------------------------------------- */
6517
-
6518
- @media (pointer: coarse) {
6519
- .cg-layout-btn,
6520
- .cg-graph-type-btn,
6521
- .cg-search-btn,
6522
- .cg-theme-btn,
6523
- .cg-export-btn,
6524
- .cg-collapse-btn,
6525
- .cg-chain-btn,
6526
- .cg-cycle-btn,
6527
- .cg-impact-btn,
6528
- .cg-inheritance-btn,
6529
- .cg-minimap-btn,
6530
- .cg-refresh-btn,
6531
- .cg-undo-btn,
6532
- .cg-redo-btn,
6533
- .cg-import-btn,
6534
- .cg-legend-btn,
6535
- .cg-lang-btn,
6536
- .cg-pathfind-btn,
6537
- .cg-health-btn,
6538
- .cg-rules-btn,
6539
- .cg-hotspot-btn,
6540
- .cg-godmodule-btn,
6541
- .cg-corefunction-btn,
6542
- .cg-analysis-dropdown-btn,
6543
- .cg-quality-dropdown-btn,
6544
- .cg-tour-btn {
6545
- min-width: 44px;
6546
- min-height: 44px;
6547
- }
6548
-
6549
- .cg-node-detail-panel .cg-close-btn,
6550
- .cg-legend-close,
6551
- .cg-import-close,
6552
- .cg-close-btn {
6553
- min-width: 44px;
6554
- min-height: 44px;
6555
- }
6556
- }
6557
- /* ---- Responsive for new components ---------------------------------------- */
6558
-
6559
- @container graphpanel (max-width: 480px) {
6560
- .cg-path-bar,
6561
- .cg-health-score-card,
6562
- .cg-rule-panel {
6563
- width: calc(100% - 24px);
6564
- }
6565
-
6566
- .cg-analysis-panel {
6567
- width: calc(100% - 24px);
6568
- }
6569
-
6570
- .cg-focus-label {
6571
- max-width: 120px;
6572
- }
6573
- }
6574
-
6575
- @container graphpanel (max-width: 768px) {
6576
- .cg-path-bar {
6577
- width: 240px;
6578
- }
6579
-
6580
- .cg-health-score-card {
6581
- width: 220px;
6582
- }
6583
-
6584
- .cg-rule-panel {
6585
- width: 240px;
6586
- }
6587
-
6588
- .cg-analysis-panel {
6589
- width: 200px;
6590
- }
6591
- }
6592
- /* ---- Container Queries fallback ------------------------------------------- */
6593
- @supports not (container-type: inline-size) {
6594
- @media (max-width: 380px) {
6595
- .cg-tour-btn,
6596
- .cg-minimap-btn,
6597
- .cg-legend-btn {
6598
- display: none;
6599
- }
6600
- }
6601
-
6602
- @media (max-width: 480px) {
6603
- .cg-graph-panel {
6604
- border-radius: var(--cg-radius-sm);
6605
- }
6606
- .cg-graph-toolbar {
6607
- padding: 0 8px;
6608
- gap: 4px;
6609
- }
6610
- .cg-toolbar-left {
6611
- font-size: 11px;
6612
- }
6613
- .cg-toolbar-center {
6614
- gap: 4px;
6615
- }
6616
- .cg-toolbar-right {
6617
- gap: 4px;
6618
- }
6619
- .cg-layout-btn,
6620
- .cg-graph-type-btn,
6621
- .cg-rank-dir-btn {
6622
- padding: 3px 6px;
6623
- font-size: 10px;
6624
- }
6625
- .cg-search-btn,
6626
- .cg-theme-btn,
6627
- .cg-export-btn,
6628
- .cg-collapse-btn,
6629
- .cg-chain-btn,
6630
- .cg-cycle-btn,
6631
- .cg-impact-btn,
6632
- .cg-inheritance-btn,
6633
- .cg-minimap-btn,
6634
- .cg-refresh-btn,
6635
-
6636
- .cg-undo-btn,
6637
- .cg-redo-btn,
6638
- .cg-import-btn,
6639
- .cg-legend-btn,
6640
- .cg-lang-btn,
6641
- .cg-pathfind-btn,
6642
- .cg-health-btn,
6643
- .cg-rules-btn,
6644
- .cg-hotspot-btn,
6645
- .cg-godmodule-btn,
6646
- .cg-corefunction-btn,
6647
- .cg-analysis-dropdown-btn,
6648
- .cg-quality-dropdown-btn,
6649
- .cg-tour-btn {
6650
- width: 26px;
6651
- height: 26px;
6652
- font-size: 12px;
6653
- }
6654
- .cg-node-detail-panel {
6655
- width: calc(100% - 24px);
6656
- left: 12px;
6657
- top: 12px;
6658
- }
6659
- .cg-legend-panel {
6660
- width: 140px;
6661
- }
6662
- .cg-mini-map {
6663
- width: 140px;
6664
- }
6665
- .cg-type-badge {
6666
- display: none;
6667
- }
6668
- .cg-toolbar-separator {
6669
- display: none;
6670
- }
6671
- .cg-graph-type-buttons {
6672
- display: none;
6673
- }
6674
- .cg-dropdown-content {
6675
- min-width: 140px;
6676
- }
6677
- .cg-view-mode-buttons {
6678
- gap: 1px;
6679
- }
6680
- .cg-view-mode-btn {
6681
- padding: 2px 4px;
6682
- font-size: 9px;
6683
- }
6684
- .cg-search-panel,
6685
- .cg-path-panel {
6686
- width: calc(100% - 16px);
6687
- max-width: 320px;
6688
- }
6689
- .cg-filter-panel {
6690
- width: calc(100% - 16px);
6691
- }
6692
- .cg-heatmap-btn--activate,
6693
- .cg-heatmap-btn--deactivate {
6694
- width: 26px;
6695
- height: 26px;
6696
- font-size: 12px;
6697
- }
6698
- .cg-path-bar,
6699
- .cg-health-score-card,
6700
- .cg-rule-panel {
6701
- width: calc(100% - 24px);
6702
- }
6703
- .cg-analysis-panel {
6704
- width: calc(100% - 24px);
6705
- }
6706
- .cg-focus-label {
6707
- max-width: 120px;
6708
- }
6709
- }
6710
-
6711
- @media (max-width: 768px) {
6712
- .cg-graph-toolbar {
6713
- padding: 0 8px;
6714
- gap: 6px;
6715
- }
6716
- .cg-toolbar-center {
6717
- gap: 6px;
6718
- }
6719
- .cg-toolbar-right {
6720
- gap: 6px;
6721
- }
6722
- .cg-layout-btn,
6723
- .cg-graph-type-btn {
6724
- padding: 3px 8px;
6725
- font-size: 11px;
6726
- }
6727
- .cg-node-detail-panel {
6728
- width: 220px;
6729
- }
6730
- .cg-legend-panel {
6731
- width: 160px;
6732
- }
6733
- .cg-mini-map {
6734
- width: 160px;
6735
- }
6736
- .cg-filter-select {
6737
- font-size: 11px;
6738
- }
6739
- .cg-toolbar-separator {
6740
- margin: 0 2px;
6741
- }
6742
- .cg-tour-btn {
6743
- display: none;
6744
- }
6745
- .cg-path-bar {
6746
- width: 240px;
6747
- }
6748
- .cg-health-score-card {
6749
- width: 220px;
6750
- }
6751
- .cg-rule-panel {
6752
- width: 240px;
6753
- }
6754
- .cg-analysis-panel {
6755
- width: 200px;
6756
- }
6757
- }
6758
-
6759
- @media (max-width: 600px) {
6760
- .cg-tour-btn,
6761
- .cg-minimap-btn {
6762
- display: none;
6763
- }
6764
- .cg-toolbar-left .cg-type-badge {
6765
- display: none;
6766
- }
6767
- /* Mirrors the 600px container tier: the center group needs 150px for its three
6768
- icon-only triggers and gets crushed below that. */
6769
- .cg-toolbar-center {
6770
- display: none;
6771
- }
6772
- }
6773
-
6774
- @media (max-width: 320px) {
6775
- .cg-graph-toolbar {
6776
- gap: 2px;
6777
- flex-wrap: wrap;
6778
- padding: 4px 4px;
6779
- }
6780
- .cg-toolbar-left,
6781
- .cg-toolbar-center,
6782
- .cg-toolbar-right {
6783
- flex-wrap: wrap;
6784
- gap: 2px;
6785
- }
6786
- .cg-layout-buttons,
6787
- .cg-graph-type-buttons {
6788
- padding: 1px;
6789
- }
6790
- .cg-layout-btn,
6791
- .cg-graph-type-btn {
6792
- padding: 2px 4px;
6793
- font-size: 9px;
6794
- }
6795
- .cg-filter-select {
6796
- padding: 3px 20px 3px 6px;
6797
- font-size: 10px;
6798
- }
6799
- .cg-node-count {
6800
- font-size: 10px;
6801
- }
6802
- .cg-legend-panel,
6803
- .cg-mini-map {
6804
- width: 120px;
6805
- }
6806
- /* 同上:portal 到 body 后这里也匹配不到,抽屉由 `.cg-portal-drawer` 接管。 */
6807
- .cg-search-panel,
6808
- .cg-path-panel,
6809
- .cg-filter-panel {
6810
- width: calc(100% - 8px);
6811
- left: 4px;
6812
- right: 4px;
6813
- }
6814
- .cg-view-mode-buttons {
6815
- flex-wrap: wrap;
6816
- }
6817
- }
6818
-
6819
- @media (max-height: 400px) {
6820
- .cg-graph-toolbar {
6821
- padding: 0 4px;
6822
- gap: 2px;
6823
- }
6824
- .cg-toolbar-left .cg-node-count {
6825
- font-size: 10px;
6826
- }
6827
- .cg-type-badge {
6828
- display: none;
6829
- }
6830
- .cg-toolbar-separator {
6831
- display: none;
6832
- }
6833
- .cg-graph-type-buttons {
6834
- display: none;
6835
- }
6836
- .cg-view-mode-buttons {
6837
- gap: 1px;
6838
- }
6839
- .cg-view-mode-btn {
6840
- padding: 2px 4px;
6841
- font-size: 9px;
6842
- }
6843
- .cg-node-detail-panel {
6844
- max-height: calc(100% - 60px);
6845
- overflow-y: auto;
6846
- }
6847
- .cg-legend-panel {
6848
- max-height: 120px;
6849
- overflow-y: auto;
6850
- }
6851
- .cg-mini-map {
6852
- max-height: 100px;
6853
- }
6854
- .cg-search-panel,
6855
- .cg-path-panel,
6856
- .cg-filter-panel {
6857
- max-height: calc(100% - 60px);
6858
- overflow-y: auto;
6859
- }
6860
- }
6861
-
6862
- @media (max-height: 240px) {
6863
- .cg-graph-toolbar {
6864
- flex-wrap: wrap;
6865
- padding: 2px;
6866
- }
6867
- .cg-toolbar-left,
6868
- .cg-toolbar-center,
6869
- .cg-toolbar-right {
6870
- flex-wrap: wrap;
6871
- gap: 2px;
6872
- }
6873
- .cg-layout-buttons {
6874
- display: none;
6875
- }
6876
- .cg-rank-dir-buttons {
6877
- display: none;
6878
- }
6879
- .cg-cluster-depth-buttons {
6880
- display: none;
6881
- }
6882
- .cg-node-detail-panel {
6883
- width: calc(100% - 8px);
6884
- left: 4px;
6885
- top: 4px;
6886
- max-height: calc(100% - 40px);
6887
- }
6888
- }
6889
- }
6890
- /* ---- Conversation View Integration Mode ----------------------------------- */
6891
-
6892
- /* When integrated into DSH's conversation.view slot, the panel fills the
6893
- * conversation area. Toolbar is always visible; graph canvas fills remaining
6894
- * space. The panel must not collapse or float — it's the primary view. */
6895
- [data-cg-integration="conversation-view"] {
6896
- width: 100%;
6897
- height: 100%;
6898
- min-height: 200px;
6899
- display: flex;
6900
- flex-direction: column;
6901
- }
6902
-
6903
- [data-cg-integration="conversation-view"] .cg-graph-toolbar {
6904
- display: flex;
6905
- flex-shrink: 0;
6906
- }
6907
-
6908
- [data-cg-integration="conversation-view"] .cg-graph-container {
6909
- flex: 1;
6910
- min-height: 0;
6911
- }
6912
-
6913
- [data-cg-integration="conversation-view"] .cg-collapse-fab {
6914
- display: none;
6915
- }
6916
-
6917
- [data-cg-integration="conversation-view"] .cg-status-bar {
6918
- flex-shrink: 0;
6919
- }
6920
-
6921
- /* Conversation view integration (conversation.view slot) */
6922
- .cg-conversation-view-wrapper {
6923
- display: flex;
6924
- flex-direction: column;
6925
- width: 100%;
6926
- height: 100%;
6927
- min-height: 0;
6928
- }
6929
-
6930
- .cg-conversation-view-wrapper[data-cg-visible="false"] {
6931
- display: none;
6932
- }
6933
-
6934
- /* Generic host container for host-managed embedded panels
6935
- * (conversation.view / sidebar-right / better-sidebar). */
6936
- .cg-integration-host {
6937
- display: block;
6938
- width: 100%;
6939
- height: 100%;
6940
- min-height: 0;
6941
- }
6942
-
6943
- .cg-integration-host[data-cg-visible="false"] {
6944
- display: none;
6945
- }
6946
-
6947
-
6948
- /* In conversation-view mode, the panel should not have its own border/radius
6949
- * since it's embedded in the DSH conversation area */
6950
- [data-cg-integration="conversation-view"].cg-graph-panel:not(.cg-collapsed) {
6951
- border: none;
6952
- border-radius: 0;
6953
- }
6954
- /* ---- Sidebar Right Tab Integration Mode ----------------------------------- */
6955
-
6956
- /* When integrated into DSH's sidebar.right.pane.tab, the panel is in a
6957
- * right sidebar tab. Width is typically 300-500px, height is full window. */
6958
- [data-cg-integration="sidebar-right"] {
6959
- width: 100%;
6960
- height: 100%;
6961
- min-height: 300px;
6962
- display: flex;
6963
- flex-direction: column;
6964
- }
6965
-
6966
- [data-cg-integration="sidebar-right"] .cg-graph-toolbar {
6967
- display: flex;
6968
- flex-shrink: 0;
6969
- }
6970
-
6971
- [data-cg-integration="sidebar-right"] .cg-graph-container {
6972
- flex: 1;
6973
- min-height: 0;
6974
- }
6975
-
6976
- [data-cg-integration="sidebar-right"] .cg-collapse-fab {
6977
- display: none;
6978
- }
6979
-
6980
- [data-cg-integration="sidebar-right"].cg-graph-panel:not(.cg-collapsed) {
6981
- border: none;
6982
- border-radius: 0;
6983
- }
6984
-
6985
- /* ---- Better Sidebar Integration Mode -------------------------------------- */
6986
-
6987
- /* When integrated via betterSidebar API, the panel is in a sidebar tab.
6988
- * Similar to sidebar-right but may have different container constraints. */
6989
- [data-cg-integration="better-sidebar"] {
6990
- width: 100%;
6991
- height: 100%;
6992
- min-height: 200px;
6993
- display: flex;
6994
- flex-direction: column;
6995
- }
6996
-
6997
- [data-cg-integration="better-sidebar"] .cg-graph-toolbar {
6998
- display: flex;
6999
- flex-shrink: 0;
7000
- }
7001
-
7002
- [data-cg-integration="better-sidebar"] .cg-graph-container {
7003
- flex: 1;
7004
- min-height: 0;
7005
- }
7006
-
7007
- [data-cg-integration="better-sidebar"] .cg-collapse-fab {
7008
- display: none;
7009
- }
7010
-
7011
- [data-cg-integration="better-sidebar"].cg-graph-panel:not(.cg-collapsed) {
7012
- border: none;
7013
- border-radius: 0;
7014
- }
7015
-
7016
- /* ---- Remote narrow-screen carrier adaptation ------------------------------- */
7017
-
7018
- /* `@linxin666/dsh-remote-web-ui` is a real, widely-installed plugin, but it
7019
- * exposes no panel/tab API at all — its client half only occupies the
7020
- * `sidebar.footer.action` seat and writes DOM adaptation marks
7021
- * (`lib/client.js:4155 ACTIVE_CLASS = "dsh-remote-portrait"`, added to
7022
- * `document.body` at `:4368`). So the honest relationship is "detect it and let
7023
- * the layout adapt", not "call its API". The former `remote-web-ui`
7024
- * integration mode was a phantom (`ctx.get('remoteWebUI')` exists in no DSH
7025
- * generation) and has been removed; these rules replace it.
7026
- *
7027
- * The toolbar must stay reachable on a phone-width carrier, so it is allowed to
7028
- * wrap instead of overflowing. */
7029
- body.dsh-remote-portrait .cg-graph-toolbar {
7030
- flex-wrap: wrap;
7031
- row-gap: 4px;
7032
- }
7033
-
7034
- body.dsh-remote-portrait .cg-graph-panel:not(.cg-collapsed) {
7035
- border: none;
7036
- border-radius: 0;
7037
- }
7038
-
7039
- /* Below 480px the toolbar's own compact breakpoint (see Toolbar.tsx) already
7040
- * collapses secondary controls; the graph area just needs the remaining
7041
- * height. */
7042
- body.dsh-remote-portrait .cg-graph-container {
7043
- flex: 1;
7044
- min-height: 0;
7045
- }
7046
-
7047
- /* ---- Toolbar always visible in non-floating modes -------------------------- */
7048
- /* In all sidebar/slot integration modes, the toolbar must remain visible
7049
- * even when there's no graph data. The toolbar is the primary interaction
7050
- * surface and should not disappear.
7051
- * Expressed as one rule over `[data-cg-integration]` (the attribute lives on
7052
- * `.cg-graph-panel` itself, see GraphPanel.tsx) so every current and future
7053
- * integration mode is covered. The `:not(.cg-collapsed)` guard is load-bearing:
7054
- * without it this `!important` declaration outranks
7055
- * `.cg-graph-panel.cg-collapsed .cg-graph-toolbar { display: none }` and the
7056
- * toolbar keeps painting inside the 52px collapsed FAB. */
7057
- .cg-graph-panel[data-cg-integration]:not(.cg-collapsed) .cg-graph-toolbar {
7058
- display: flex !important;
7059
- }
7060
-
7061
- /* ---- Desktop vs Web distinction ------------------------------------------- */
7062
- /* On desktop platforms, the panel may have more space. On web, it's
7063
- * constrained by the browser window. */
7064
- @media (min-width: 1024px) {
7065
- [data-cg-integration="conversation-view"] .cg-graph-toolbar {
7066
- padding: 0 12px;
7067
- gap: 8px;
7068
- }
7069
- }
7070
-
7071
- /* ---- Narrow-tier sheets (cycle-110 / T3) ---------------------------------- */
7072
- /*
7073
- * 窄面板(≤480px)下的两处版式修正:
7074
- * 1. 节点详情面板改为**底部抽屉**(贴边、限高),不再 `max-height: calc(100% - 24px)`
7075
- * 从上往下盖住整个画布;
7076
- * 2. 抽屉打开时小地图与图例**临时让位**,关闭后回归。
7077
- *
7078
- * 为什么两条都要:三者都是 `position: absolute` + `z-index: var(--cg-z-panel)` 的绝对定位
7079
- * 元素,窄档下面板几乎占满高度,小地图(右下 200px)与图例(左下 180px)会被盖住一半,
7080
- * 面板底部的按钮也会与图例重叠 —— 点击落在错误元素上,而所有 DOM 断言照旧通过。
7081
- *
7082
- * 两套机制**声明必须一致**:
7083
- * - `@container graphpanel (max-width: 480px)`:主机制,按面板宽度响应(与视口无关);
7084
- * - `[data-cg-tier="narrow"]`:宿主不支持容器查询、或容器查询尺寸不可读时的兜底,
7085
- * 由 `hooks/usePanelTier.ts` 实测宽度后写在根元素上。
7086
- * `tests/unit/panelTierContract.test.ts` 会逐条比对这两处的声明,任一侧改动都会变红。
7087
- */
7088
- @container graphpanel (max-width: 480px) {
7089
- .cg-node-detail-panel {
7090
- top: auto;
7091
- bottom: calc(var(--cg-statusbar-h) + 8px);
7092
- left: 8px;
7093
- right: 8px;
7094
- width: auto;
7095
- max-height: 52%;
7096
- }
7097
-
7098
- /* 抽屉打开 ⇒ 两个角落的叠加层让位(关闭后自动回归,不需要 JS 复位) */
7099
- .cg-graph-panel[data-cg-sheet="open"] .cg-mini-map,
7100
- .cg-graph-panel[data-cg-sheet="open"] .cg-legend-panel {
7101
- display: none;
7102
- }
7103
- }
7104
-
7105
- /* 兜底机制(JS 实测档位):与上面的容器查询分支**逐条等价** */
7106
- .cg-graph-panel[data-cg-tier="narrow"] .cg-node-detail-panel {
7107
- top: auto;
7108
- bottom: calc(var(--cg-statusbar-h) + 8px);
7109
- left: 8px;
7110
- right: 8px;
7111
- width: auto;
7112
- max-height: 52%;
7113
- }
7114
-
7115
- .cg-graph-panel[data-cg-tier="narrow"][data-cg-sheet="open"] .cg-mini-map,
7116
- .cg-graph-panel[data-cg-tier="narrow"][data-cg-sheet="open"] .cg-legend-panel {
7117
- display: none;
7118
- }
6191
+ /* ---- Responsive ---------------------------------------------------------- */
6192
+
6193
+ /* Extra-narrow panels (DSH sidebar tab minimal width).
6194
+ * Hide the remaining toolbar extras to prioritize graph canvas.
6195
+ * The center group is already gone at the 600px tier below. */
6196
+ @container graphpanel (max-width: 380px) {
6197
+ .cg-tour-btn,
6198
+ .cg-minimap-btn,
6199
+ .cg-legend-btn {
6200
+ display: none;
6201
+ }
6202
+
6203
+ /* The separators are siblings of the `.cg-toolbar-group` elements, not descendants,
6204
+ so the previous `.cg-toolbar-group ... .cg-toolbar-separator` selector never
6205
+ matched anything. */
6206
+ .cg-toolbar-separator {
6207
+ display: none;
6208
+ }
6209
+ }
6210
+
6211
+ /* Small panels (DSH sidebar tab, narrow bottom panel).
6212
+ * Container queries respond to the PANEL width, not the viewport — the plugin
6213
+ * renders inside DSH panels whose width is unrelated to the window size. */
6214
+ @container graphpanel (max-width: 480px) {
6215
+ .cg-graph-panel {
6216
+ border-radius: var(--cg-radius-sm);
6217
+ }
6218
+
6219
+ .cg-graph-toolbar {
6220
+ padding: 0 8px;
6221
+ gap: 4px;
6222
+ }
6223
+
6224
+ .cg-toolbar-left {
6225
+ font-size: 11px;
6226
+ }
6227
+
6228
+ .cg-toolbar-center {
6229
+ gap: 4px;
6230
+ }
6231
+
6232
+ .cg-toolbar-right {
6233
+ gap: 4px;
6234
+ }
6235
+
6236
+ .cg-layout-btn,
6237
+ .cg-graph-type-btn,
6238
+ .cg-rank-dir-btn {
6239
+ padding: 3px 6px;
6240
+ font-size: 10px;
6241
+ }
6242
+
6243
+ .cg-search-btn,
6244
+ .cg-theme-btn,
6245
+ .cg-export-btn,
6246
+ .cg-collapse-btn,
6247
+ .cg-chain-btn,
6248
+ .cg-cycle-btn,
6249
+ .cg-impact-btn,
6250
+ .cg-inheritance-btn,
6251
+ .cg-minimap-btn,
6252
+ .cg-refresh-btn,
6253
+ .cg-undo-btn,
6254
+ .cg-redo-btn,
6255
+ .cg-import-btn,
6256
+ .cg-legend-btn,
6257
+ .cg-lang-btn,
6258
+ .cg-pathfind-btn,
6259
+ .cg-health-btn,
6260
+ .cg-rules-btn,
6261
+ .cg-hotspot-btn,
6262
+ .cg-godmodule-btn,
6263
+ .cg-corefunction-btn,
6264
+ .cg-analysis-dropdown-btn,
6265
+ .cg-quality-dropdown-btn,
6266
+ .cg-tour-btn {
6267
+ width: 26px;
6268
+ height: 26px;
6269
+ font-size: 12px;
6270
+ }
6271
+
6272
+ .cg-dropdown-content {
6273
+ min-width: 140px;
6274
+ }
6275
+
6276
+ .cg-node-detail-panel {
6277
+ width: calc(100% - 24px);
6278
+ left: 12px;
6279
+ top: 12px;
6280
+ }
6281
+
6282
+ .cg-legend-panel {
6283
+ width: 140px;
6284
+ }
6285
+
6286
+ .cg-mini-map {
6287
+ width: 140px;
6288
+ }
6289
+
6290
+ .cg-type-badge {
6291
+ display: none;
6292
+ }
6293
+
6294
+ .cg-toolbar-separator {
6295
+ display: none;
6296
+ }
6297
+
6298
+ .cg-graph-type-buttons {
6299
+ display: none;
6300
+ }
6301
+
6302
+ .cg-view-mode-buttons {
6303
+ gap: 1px;
6304
+ }
6305
+
6306
+ .cg-view-mode-btn {
6307
+ padding: 2px 4px;
6308
+ font-size: 9px;
6309
+ }
6310
+
6311
+ .cg-search-panel,
6312
+ .cg-path-panel {
6313
+ width: calc(100% - 16px);
6314
+ max-width: 320px;
6315
+ }
6316
+
6317
+ .cg-filter-panel {
6318
+ width: calc(100% - 16px);
6319
+ }
6320
+
6321
+ .cg-heatmap-btn--activate,
6322
+ .cg-heatmap-btn--deactivate {
6323
+ width: 26px;
6324
+ height: 26px;
6325
+ font-size: 12px;
6326
+ }
6327
+
6328
+ }
6329
+
6330
+ /* Medium panels (DSH sidebar medium width) */
6331
+ @container graphpanel (max-width: 768px) {
6332
+ .cg-graph-toolbar {
6333
+ padding: 0 8px;
6334
+ gap: 6px;
6335
+ }
6336
+
6337
+ .cg-toolbar-center {
6338
+ gap: 6px;
6339
+ }
6340
+
6341
+ .cg-toolbar-right {
6342
+ gap: 6px;
6343
+ }
6344
+
6345
+ .cg-layout-btn,
6346
+ .cg-graph-type-btn {
6347
+ padding: 3px 8px;
6348
+ font-size: 11px;
6349
+ }
6350
+
6351
+ .cg-node-detail-panel {
6352
+ width: 220px;
6353
+ }
6354
+
6355
+ .cg-legend-panel {
6356
+ width: 160px;
6357
+ }
6358
+
6359
+ .cg-mini-map {
6360
+ width: 160px;
6361
+ }
6362
+
6363
+ .cg-filter-select {
6364
+ font-size: 11px;
6365
+ }
6366
+
6367
+ .cg-toolbar-separator {
6368
+ margin: 0 2px;
6369
+ }
6370
+
6371
+ .cg-tour-btn {
6372
+ display: none;
6373
+ }
6374
+
6375
+ }
6376
+
6377
+ /* Medium-narrow panels — hide tour and reduce analysis button clutter */
6378
+ @container graphpanel (max-width: 600px) {
6379
+ .cg-tour-btn,
6380
+ .cg-minimap-btn {
6381
+ display: none;
6382
+ }
6383
+
6384
+ .cg-toolbar-left .cg-type-badge {
6385
+ display: none;
6386
+ }
6387
+
6388
+ /* The center group (layout / view-mode / level) is the widest fixed-width block in the
6389
+ toolbar: 150px for its three icon-only triggers, measured on the real host. At a 520px
6390
+ panel it was being squeezed to 115px, which wrapped the level trigger onto two lines
6391
+ and clipped it; at 600px it still has 45px of slack. Hiding it here instead of letting
6392
+ it be crushed keeps the workspace chip and every right-hand control (export / more /
6393
+ collapse) reachable. Of the three controls, only the layout keeps an alternative entry
6394
+ point (Ctrl+L cycles it, see `usePanelKeyboard`); view mode and hierarchy level lose
6395
+ their mouse entry below this tier — see the note in `docs/需求分析.md` §28.3. */
6396
+ .cg-toolbar-center {
6397
+ display: none;
6398
+ }
6399
+ }
6400
+
6401
+ /* Very small panels */
6402
+ @container graphpanel (max-width: 320px) {
6403
+ .cg-graph-toolbar {
6404
+ gap: 2px;
6405
+ flex-wrap: wrap;
6406
+ padding: 4px 4px;
6407
+ }
6408
+
6409
+ .cg-toolbar-left,
6410
+ .cg-toolbar-center,
6411
+ .cg-toolbar-right {
6412
+ flex-wrap: wrap;
6413
+ gap: 2px;
6414
+ }
6415
+
6416
+ .cg-layout-buttons,
6417
+ .cg-graph-type-buttons {
6418
+ padding: 1px;
6419
+ }
6420
+
6421
+ .cg-layout-btn,
6422
+ .cg-graph-type-btn {
6423
+ padding: 2px 4px;
6424
+ font-size: 9px;
6425
+ }
6426
+
6427
+ .cg-filter-select {
6428
+ padding: 3px 20px 3px 6px;
6429
+ font-size: 10px;
6430
+ }
6431
+
6432
+ .cg-node-count {
6433
+ font-size: 10px;
6434
+ }
6435
+
6436
+ .cg-legend-panel,
6437
+ .cg-mini-map {
6438
+ width: 120px;
6439
+ }
6440
+
6441
+ /* 下拉内容已 portal 到 document.body,不再是本容器的后代,此处的
6442
+ * `@container` 抽屉规则永远匹配不到;抽屉形态改由 Dropdown 组件测量面板
6443
+ * 宽度后加 `.cg-portal-drawer`(见 layout.css)实现。 */
6444
+
6445
+ .cg-search-panel,
6446
+ .cg-path-panel,
6447
+ .cg-filter-panel {
6448
+ width: calc(100% - 8px);
6449
+ left: 4px;
6450
+ right: 4px;
6451
+ }
6452
+
6453
+ .cg-view-mode-buttons {
6454
+ flex-wrap: wrap;
6455
+ }
6456
+ }
6457
+
6458
+ /* Large screens — allow fixed floating panel */
6459
+ @media (min-width: 1200px) {
6460
+ .cg-graph-panel.cg-floating {
6461
+ position: fixed;
6462
+ right: 16px;
6463
+ bottom: 16px;
6464
+ width: 640px;
6465
+ height: 520px;
6466
+ }
6467
+ }
6468
+
6469
+ /* ---- Sidebar tab mode (short height) -------------------------------------- */
6470
+ /* When the plugin renders inside a DSH sidebar tab, the panel height can be
6471
+ * very limited. Adapt the layout to prioritize the graph canvas. */
6472
+ @container graphpanel (max-height: 400px) {
6473
+ .cg-graph-toolbar {
6474
+ padding: 0 4px;
6475
+ gap: 2px;
6476
+ }
6477
+
6478
+ .cg-toolbar-left .cg-node-count {
6479
+ font-size: 10px;
6480
+ }
6481
+
6482
+ .cg-type-badge {
6483
+ display: none;
6484
+ }
6485
+
6486
+ .cg-toolbar-separator {
6487
+ display: none;
6488
+ }
6489
+
6490
+ .cg-graph-type-buttons {
6491
+ display: none;
6492
+ }
6493
+
6494
+ .cg-view-mode-buttons {
6495
+ gap: 1px;
6496
+ }
6497
+
6498
+ .cg-view-mode-btn {
6499
+ padding: 2px 4px;
6500
+ font-size: 9px;
6501
+ }
6502
+
6503
+ .cg-node-detail-panel {
6504
+ max-height: calc(100% - 60px);
6505
+ overflow-y: auto;
6506
+ }
6507
+
6508
+ .cg-legend-panel {
6509
+ max-height: 120px;
6510
+ overflow-y: auto;
6511
+ }
6512
+
6513
+ .cg-mini-map {
6514
+ max-height: 100px;
6515
+ }
6516
+
6517
+ .cg-search-panel,
6518
+ .cg-path-panel,
6519
+ .cg-filter-panel {
6520
+ max-height: calc(100% - 60px);
6521
+ overflow-y: auto;
6522
+ }
6523
+ }
6524
+
6525
+ @container graphpanel (max-height: 240px) {
6526
+ .cg-graph-toolbar {
6527
+ flex-wrap: wrap;
6528
+ padding: 2px;
6529
+ }
6530
+
6531
+ .cg-toolbar-left,
6532
+ .cg-toolbar-center,
6533
+ .cg-toolbar-right {
6534
+ flex-wrap: wrap;
6535
+ gap: 2px;
6536
+ }
6537
+
6538
+ .cg-layout-buttons {
6539
+ display: none;
6540
+ }
6541
+
6542
+ .cg-rank-dir-buttons {
6543
+ display: none;
6544
+ }
6545
+
6546
+ .cg-cluster-depth-buttons {
6547
+ display: none;
6548
+ }
6549
+
6550
+ .cg-node-detail-panel {
6551
+ width: calc(100% - 8px);
6552
+ left: 4px;
6553
+ top: 4px;
6554
+ max-height: calc(100% - 40px);
6555
+ }
6556
+ }
6557
+
6558
+ /* ---- Reduced motion ------------------------------------------------------ */
6559
+
6560
+ @media (prefers-reduced-motion: reduce) {
6561
+ .cg-graph-panel *,
6562
+ .cg-graph-panel *::before,
6563
+ .cg-graph-panel *::after,
6564
+ .cg-floating-panel *,
6565
+ .cg-floating-panel *::before,
6566
+ .cg-floating-panel *::after,
6567
+ .cg-floating-container *,
6568
+ .cg-floating-container *::before,
6569
+ .cg-floating-container *::after {
6570
+ animation-duration: 0.01ms !important;
6571
+ transition-duration: 0.01ms !important;
6572
+ }
6573
+ }
6574
+
6575
+ /* ---- Touch device adaptation --------------------------------------------- */
6576
+
6577
+ @media (pointer: coarse) {
6578
+ .cg-layout-btn,
6579
+ .cg-graph-type-btn,
6580
+ .cg-search-btn,
6581
+ .cg-theme-btn,
6582
+ .cg-export-btn,
6583
+ .cg-collapse-btn,
6584
+ .cg-chain-btn,
6585
+ .cg-cycle-btn,
6586
+ .cg-impact-btn,
6587
+ .cg-inheritance-btn,
6588
+ .cg-minimap-btn,
6589
+ .cg-refresh-btn,
6590
+ .cg-undo-btn,
6591
+ .cg-redo-btn,
6592
+ .cg-import-btn,
6593
+ .cg-legend-btn,
6594
+ .cg-lang-btn,
6595
+ .cg-pathfind-btn,
6596
+ .cg-health-btn,
6597
+ .cg-rules-btn,
6598
+ .cg-hotspot-btn,
6599
+ .cg-godmodule-btn,
6600
+ .cg-corefunction-btn,
6601
+ .cg-analysis-dropdown-btn,
6602
+ .cg-quality-dropdown-btn,
6603
+ .cg-tour-btn {
6604
+ min-width: 44px;
6605
+ min-height: 44px;
6606
+ }
6607
+
6608
+ .cg-node-detail-panel .cg-close-btn,
6609
+ .cg-legend-close,
6610
+ .cg-import-close,
6611
+ .cg-close-btn {
6612
+ min-width: 44px;
6613
+ min-height: 44px;
6614
+ }
6615
+ }
6616
+ /* ---- Responsive for new components ---------------------------------------- */
6617
+
6618
+ @container graphpanel (max-width: 480px) {
6619
+ .cg-path-bar,
6620
+ .cg-health-score-card,
6621
+ .cg-rule-panel {
6622
+ width: calc(100% - 24px);
6623
+ }
6624
+
6625
+ .cg-analysis-panel {
6626
+ width: calc(100% - 24px);
6627
+ }
6628
+
6629
+ .cg-focus-label {
6630
+ max-width: 120px;
6631
+ }
6632
+ }
6633
+
6634
+ @container graphpanel (max-width: 768px) {
6635
+ .cg-path-bar {
6636
+ width: 240px;
6637
+ }
6638
+
6639
+ .cg-health-score-card {
6640
+ width: 220px;
6641
+ }
6642
+
6643
+ .cg-rule-panel {
6644
+ width: 240px;
6645
+ }
6646
+
6647
+ .cg-analysis-panel {
6648
+ width: 200px;
6649
+ }
6650
+ }
6651
+ /* ---- Container Queries fallback ------------------------------------------- */
6652
+ @supports not (container-type: inline-size) {
6653
+ @media (max-width: 380px) {
6654
+ .cg-tour-btn,
6655
+ .cg-minimap-btn,
6656
+ .cg-legend-btn {
6657
+ display: none;
6658
+ }
6659
+ }
6660
+
6661
+ @media (max-width: 480px) {
6662
+ .cg-graph-panel {
6663
+ border-radius: var(--cg-radius-sm);
6664
+ }
6665
+ .cg-graph-toolbar {
6666
+ padding: 0 8px;
6667
+ gap: 4px;
6668
+ }
6669
+ .cg-toolbar-left {
6670
+ font-size: 11px;
6671
+ }
6672
+ .cg-toolbar-center {
6673
+ gap: 4px;
6674
+ }
6675
+ .cg-toolbar-right {
6676
+ gap: 4px;
6677
+ }
6678
+ .cg-layout-btn,
6679
+ .cg-graph-type-btn,
6680
+ .cg-rank-dir-btn {
6681
+ padding: 3px 6px;
6682
+ font-size: 10px;
6683
+ }
6684
+ .cg-search-btn,
6685
+ .cg-theme-btn,
6686
+ .cg-export-btn,
6687
+ .cg-collapse-btn,
6688
+ .cg-chain-btn,
6689
+ .cg-cycle-btn,
6690
+ .cg-impact-btn,
6691
+ .cg-inheritance-btn,
6692
+ .cg-minimap-btn,
6693
+ .cg-refresh-btn,
6694
+
6695
+ .cg-undo-btn,
6696
+ .cg-redo-btn,
6697
+ .cg-import-btn,
6698
+ .cg-legend-btn,
6699
+ .cg-lang-btn,
6700
+ .cg-pathfind-btn,
6701
+ .cg-health-btn,
6702
+ .cg-rules-btn,
6703
+ .cg-hotspot-btn,
6704
+ .cg-godmodule-btn,
6705
+ .cg-corefunction-btn,
6706
+ .cg-analysis-dropdown-btn,
6707
+ .cg-quality-dropdown-btn,
6708
+ .cg-tour-btn {
6709
+ width: 26px;
6710
+ height: 26px;
6711
+ font-size: 12px;
6712
+ }
6713
+ .cg-node-detail-panel {
6714
+ width: calc(100% - 24px);
6715
+ left: 12px;
6716
+ top: 12px;
6717
+ }
6718
+ .cg-legend-panel {
6719
+ width: 140px;
6720
+ }
6721
+ .cg-mini-map {
6722
+ width: 140px;
6723
+ }
6724
+ .cg-type-badge {
6725
+ display: none;
6726
+ }
6727
+ .cg-toolbar-separator {
6728
+ display: none;
6729
+ }
6730
+ .cg-graph-type-buttons {
6731
+ display: none;
6732
+ }
6733
+ .cg-dropdown-content {
6734
+ min-width: 140px;
6735
+ }
6736
+ .cg-view-mode-buttons {
6737
+ gap: 1px;
6738
+ }
6739
+ .cg-view-mode-btn {
6740
+ padding: 2px 4px;
6741
+ font-size: 9px;
6742
+ }
6743
+ .cg-search-panel,
6744
+ .cg-path-panel {
6745
+ width: calc(100% - 16px);
6746
+ max-width: 320px;
6747
+ }
6748
+ .cg-filter-panel {
6749
+ width: calc(100% - 16px);
6750
+ }
6751
+ .cg-heatmap-btn--activate,
6752
+ .cg-heatmap-btn--deactivate {
6753
+ width: 26px;
6754
+ height: 26px;
6755
+ font-size: 12px;
6756
+ }
6757
+ .cg-path-bar,
6758
+ .cg-health-score-card,
6759
+ .cg-rule-panel {
6760
+ width: calc(100% - 24px);
6761
+ }
6762
+ .cg-analysis-panel {
6763
+ width: calc(100% - 24px);
6764
+ }
6765
+ .cg-focus-label {
6766
+ max-width: 120px;
6767
+ }
6768
+ }
6769
+
6770
+ @media (max-width: 768px) {
6771
+ .cg-graph-toolbar {
6772
+ padding: 0 8px;
6773
+ gap: 6px;
6774
+ }
6775
+ .cg-toolbar-center {
6776
+ gap: 6px;
6777
+ }
6778
+ .cg-toolbar-right {
6779
+ gap: 6px;
6780
+ }
6781
+ .cg-layout-btn,
6782
+ .cg-graph-type-btn {
6783
+ padding: 3px 8px;
6784
+ font-size: 11px;
6785
+ }
6786
+ .cg-node-detail-panel {
6787
+ width: 220px;
6788
+ }
6789
+ .cg-legend-panel {
6790
+ width: 160px;
6791
+ }
6792
+ .cg-mini-map {
6793
+ width: 160px;
6794
+ }
6795
+ .cg-filter-select {
6796
+ font-size: 11px;
6797
+ }
6798
+ .cg-toolbar-separator {
6799
+ margin: 0 2px;
6800
+ }
6801
+ .cg-tour-btn {
6802
+ display: none;
6803
+ }
6804
+ .cg-path-bar {
6805
+ width: 240px;
6806
+ }
6807
+ .cg-health-score-card {
6808
+ width: 220px;
6809
+ }
6810
+ .cg-rule-panel {
6811
+ width: 240px;
6812
+ }
6813
+ .cg-analysis-panel {
6814
+ width: 200px;
6815
+ }
6816
+ }
6817
+
6818
+ @media (max-width: 600px) {
6819
+ .cg-tour-btn,
6820
+ .cg-minimap-btn {
6821
+ display: none;
6822
+ }
6823
+ .cg-toolbar-left .cg-type-badge {
6824
+ display: none;
6825
+ }
6826
+ /* Mirrors the 600px container tier: the center group needs 150px for its three
6827
+ icon-only triggers and gets crushed below that. */
6828
+ .cg-toolbar-center {
6829
+ display: none;
6830
+ }
6831
+ }
6832
+
6833
+ @media (max-width: 320px) {
6834
+ .cg-graph-toolbar {
6835
+ gap: 2px;
6836
+ flex-wrap: wrap;
6837
+ padding: 4px 4px;
6838
+ }
6839
+ .cg-toolbar-left,
6840
+ .cg-toolbar-center,
6841
+ .cg-toolbar-right {
6842
+ flex-wrap: wrap;
6843
+ gap: 2px;
6844
+ }
6845
+ .cg-layout-buttons,
6846
+ .cg-graph-type-buttons {
6847
+ padding: 1px;
6848
+ }
6849
+ .cg-layout-btn,
6850
+ .cg-graph-type-btn {
6851
+ padding: 2px 4px;
6852
+ font-size: 9px;
6853
+ }
6854
+ .cg-filter-select {
6855
+ padding: 3px 20px 3px 6px;
6856
+ font-size: 10px;
6857
+ }
6858
+ .cg-node-count {
6859
+ font-size: 10px;
6860
+ }
6861
+ .cg-legend-panel,
6862
+ .cg-mini-map {
6863
+ width: 120px;
6864
+ }
6865
+ /* 同上:portal 到 body 后这里也匹配不到,抽屉由 `.cg-portal-drawer` 接管。 */
6866
+ .cg-search-panel,
6867
+ .cg-path-panel,
6868
+ .cg-filter-panel {
6869
+ width: calc(100% - 8px);
6870
+ left: 4px;
6871
+ right: 4px;
6872
+ }
6873
+ .cg-view-mode-buttons {
6874
+ flex-wrap: wrap;
6875
+ }
6876
+ }
6877
+
6878
+ @media (max-height: 400px) {
6879
+ .cg-graph-toolbar {
6880
+ padding: 0 4px;
6881
+ gap: 2px;
6882
+ }
6883
+ .cg-toolbar-left .cg-node-count {
6884
+ font-size: 10px;
6885
+ }
6886
+ .cg-type-badge {
6887
+ display: none;
6888
+ }
6889
+ .cg-toolbar-separator {
6890
+ display: none;
6891
+ }
6892
+ .cg-graph-type-buttons {
6893
+ display: none;
6894
+ }
6895
+ .cg-view-mode-buttons {
6896
+ gap: 1px;
6897
+ }
6898
+ .cg-view-mode-btn {
6899
+ padding: 2px 4px;
6900
+ font-size: 9px;
6901
+ }
6902
+ .cg-node-detail-panel {
6903
+ max-height: calc(100% - 60px);
6904
+ overflow-y: auto;
6905
+ }
6906
+ .cg-legend-panel {
6907
+ max-height: 120px;
6908
+ overflow-y: auto;
6909
+ }
6910
+ .cg-mini-map {
6911
+ max-height: 100px;
6912
+ }
6913
+ .cg-search-panel,
6914
+ .cg-path-panel,
6915
+ .cg-filter-panel {
6916
+ max-height: calc(100% - 60px);
6917
+ overflow-y: auto;
6918
+ }
6919
+ }
6920
+
6921
+ @media (max-height: 240px) {
6922
+ .cg-graph-toolbar {
6923
+ flex-wrap: wrap;
6924
+ padding: 2px;
6925
+ }
6926
+ .cg-toolbar-left,
6927
+ .cg-toolbar-center,
6928
+ .cg-toolbar-right {
6929
+ flex-wrap: wrap;
6930
+ gap: 2px;
6931
+ }
6932
+ .cg-layout-buttons {
6933
+ display: none;
6934
+ }
6935
+ .cg-rank-dir-buttons {
6936
+ display: none;
6937
+ }
6938
+ .cg-cluster-depth-buttons {
6939
+ display: none;
6940
+ }
6941
+ .cg-node-detail-panel {
6942
+ width: calc(100% - 8px);
6943
+ left: 4px;
6944
+ top: 4px;
6945
+ max-height: calc(100% - 40px);
6946
+ }
6947
+ }
6948
+ }
6949
+ /* ---- Conversation View Integration Mode ----------------------------------- */
6950
+
6951
+ /* When integrated into DSH's conversation.view slot, the panel fills the
6952
+ * conversation area. Toolbar is always visible; graph canvas fills remaining
6953
+ * space. The panel must not collapse or float — it's the primary view. */
6954
+ [data-cg-integration="conversation-view"] {
6955
+ width: 100%;
6956
+ height: 100%;
6957
+ min-height: 200px;
6958
+ display: flex;
6959
+ flex-direction: column;
6960
+ }
6961
+
6962
+ [data-cg-integration="conversation-view"] .cg-graph-toolbar {
6963
+ display: flex;
6964
+ flex-shrink: 0;
6965
+ }
6966
+
6967
+ [data-cg-integration="conversation-view"] .cg-graph-container {
6968
+ flex: 1;
6969
+ min-height: 0;
6970
+ }
6971
+
6972
+ [data-cg-integration="conversation-view"] .cg-collapse-fab {
6973
+ display: none;
6974
+ }
6975
+
6976
+ [data-cg-integration="conversation-view"] .cg-status-bar {
6977
+ flex-shrink: 0;
6978
+ }
6979
+
6980
+ /* Conversation view integration (conversation.view slot) */
6981
+ .cg-conversation-view-wrapper {
6982
+ display: flex;
6983
+ flex-direction: column;
6984
+ width: 100%;
6985
+ height: 100%;
6986
+ min-height: 0;
6987
+ }
6988
+
6989
+ .cg-conversation-view-wrapper[data-cg-visible="false"] {
6990
+ display: none;
6991
+ }
6992
+
6993
+ /* Generic host container for host-managed embedded panels
6994
+ * (conversation.view / sidebar-right / better-sidebar). */
6995
+ .cg-integration-host {
6996
+ display: block;
6997
+ width: 100%;
6998
+ height: 100%;
6999
+ min-height: 0;
7000
+ }
7001
+
7002
+ .cg-integration-host[data-cg-visible="false"] {
7003
+ display: none;
7004
+ }
7005
+
7006
+
7007
+ /* In conversation-view mode, the panel should not have its own border/radius
7008
+ * since it's embedded in the DSH conversation area */
7009
+ [data-cg-integration="conversation-view"].cg-graph-panel:not(.cg-collapsed) {
7010
+ border: none;
7011
+ border-radius: 0;
7012
+ }
7013
+ /* ---- Sidebar Right Tab Integration Mode ----------------------------------- */
7014
+
7015
+ /* When integrated into DSH's sidebar.right.pane.tab, the panel is in a
7016
+ * right sidebar tab. Width is typically 300-500px, height is full window. */
7017
+ [data-cg-integration="sidebar-right"] {
7018
+ width: 100%;
7019
+ height: 100%;
7020
+ min-height: 300px;
7021
+ display: flex;
7022
+ flex-direction: column;
7023
+ }
7024
+
7025
+ [data-cg-integration="sidebar-right"] .cg-graph-toolbar {
7026
+ display: flex;
7027
+ flex-shrink: 0;
7028
+ }
7029
+
7030
+ [data-cg-integration="sidebar-right"] .cg-graph-container {
7031
+ flex: 1;
7032
+ min-height: 0;
7033
+ }
7034
+
7035
+ [data-cg-integration="sidebar-right"] .cg-collapse-fab {
7036
+ display: none;
7037
+ }
7038
+
7039
+ [data-cg-integration="sidebar-right"].cg-graph-panel:not(.cg-collapsed) {
7040
+ border: none;
7041
+ border-radius: 0;
7042
+ }
7043
+
7044
+ /* ---- Better Sidebar Integration Mode -------------------------------------- */
7045
+
7046
+ /* When integrated via betterSidebar API, the panel is in a sidebar tab.
7047
+ * Similar to sidebar-right but may have different container constraints. */
7048
+ [data-cg-integration="better-sidebar"] {
7049
+ width: 100%;
7050
+ height: 100%;
7051
+ min-height: 200px;
7052
+ display: flex;
7053
+ flex-direction: column;
7054
+ }
7055
+
7056
+ [data-cg-integration="better-sidebar"] .cg-graph-toolbar {
7057
+ display: flex;
7058
+ flex-shrink: 0;
7059
+ }
7060
+
7061
+ [data-cg-integration="better-sidebar"] .cg-graph-container {
7062
+ flex: 1;
7063
+ min-height: 0;
7064
+ }
7065
+
7066
+ [data-cg-integration="better-sidebar"] .cg-collapse-fab {
7067
+ display: none;
7068
+ }
7069
+
7070
+ [data-cg-integration="better-sidebar"].cg-graph-panel:not(.cg-collapsed) {
7071
+ border: none;
7072
+ border-radius: 0;
7073
+ }
7074
+
7075
+ /* ---- Remote narrow-screen carrier adaptation ------------------------------- */
7076
+
7077
+ /* `@linxin666/dsh-remote-web-ui` is a real, widely-installed plugin, but it
7078
+ * exposes no panel/tab API at all — its client half only occupies the
7079
+ * `sidebar.footer.action` seat and writes DOM adaptation marks
7080
+ * (`lib/client.js:4155 ACTIVE_CLASS = "dsh-remote-portrait"`, added to
7081
+ * `document.body` at `:4368`). So the honest relationship is "detect it and let
7082
+ * the layout adapt", not "call its API". The former `remote-web-ui`
7083
+ * integration mode was a phantom (`ctx.get('remoteWebUI')` exists in no DSH
7084
+ * generation) and has been removed; these rules replace it.
7085
+ *
7086
+ * The toolbar must stay reachable on a phone-width carrier, so it is allowed to
7087
+ * wrap instead of overflowing. */
7088
+ body.dsh-remote-portrait .cg-graph-toolbar {
7089
+ flex-wrap: wrap;
7090
+ row-gap: 4px;
7091
+ }
7092
+
7093
+ body.dsh-remote-portrait .cg-graph-panel:not(.cg-collapsed) {
7094
+ border: none;
7095
+ border-radius: 0;
7096
+ }
7097
+
7098
+ /* Below 480px the toolbar's own compact breakpoint (see Toolbar.tsx) already
7099
+ * collapses secondary controls; the graph area just needs the remaining
7100
+ * height. */
7101
+ body.dsh-remote-portrait .cg-graph-container {
7102
+ flex: 1;
7103
+ min-height: 0;
7104
+ }
7105
+
7106
+ /* ---- Toolbar always visible in non-floating modes -------------------------- */
7107
+ /* In all sidebar/slot integration modes, the toolbar must remain visible
7108
+ * even when there's no graph data. The toolbar is the primary interaction
7109
+ * surface and should not disappear.
7110
+ * Expressed as one rule over `[data-cg-integration]` (the attribute lives on
7111
+ * `.cg-graph-panel` itself, see GraphPanel.tsx) so every current and future
7112
+ * integration mode is covered. The `:not(.cg-collapsed)` guard is load-bearing:
7113
+ * without it this `!important` declaration outranks
7114
+ * `.cg-graph-panel.cg-collapsed .cg-graph-toolbar { display: none }` and the
7115
+ * toolbar keeps painting inside the 52px collapsed FAB. */
7116
+ .cg-graph-panel[data-cg-integration]:not(.cg-collapsed) .cg-graph-toolbar {
7117
+ display: flex !important;
7118
+ }
7119
+
7120
+ /* ---- Desktop vs Web distinction ------------------------------------------- */
7121
+ /* On desktop platforms, the panel may have more space. On web, it's
7122
+ * constrained by the browser window. */
7123
+ @media (min-width: 1024px) {
7124
+ [data-cg-integration="conversation-view"] .cg-graph-toolbar {
7125
+ padding: 0 12px;
7126
+ gap: 8px;
7127
+ }
7128
+ }
7129
+
7130
+ /* ---- Narrow-tier sheets (cycle-110 / T3) ---------------------------------- */
7131
+ /*
7132
+ * 窄面板(≤480px)下的两处版式修正:
7133
+ * 1. 节点详情面板改为**底部抽屉**(贴边、限高),不再 `max-height: calc(100% - 24px)`
7134
+ * 从上往下盖住整个画布;
7135
+ * 2. 抽屉打开时小地图与图例**临时让位**,关闭后回归。
7136
+ *
7137
+ * 为什么两条都要:三者都是 `position: absolute` + `z-index: var(--cg-z-panel)` 的绝对定位
7138
+ * 元素,窄档下面板几乎占满高度,小地图(右下 200px)与图例(左下 180px)会被盖住一半,
7139
+ * 面板底部的按钮也会与图例重叠 —— 点击落在错误元素上,而所有 DOM 断言照旧通过。
7140
+ *
7141
+ * 两套机制**声明必须一致**:
7142
+ * - `@container graphpanel (max-width: 480px)`:主机制,按面板宽度响应(与视口无关);
7143
+ * - `[data-cg-tier="narrow"]`:宿主不支持容器查询、或容器查询尺寸不可读时的兜底,
7144
+ * 由 `hooks/usePanelTier.ts` 实测宽度后写在根元素上。
7145
+ * `tests/unit/panelTierContract.test.ts` 会逐条比对这两处的声明,任一侧改动都会变红。
7146
+ */
7147
+ @container graphpanel (max-width: 480px) {
7148
+ .cg-node-detail-panel {
7149
+ top: auto;
7150
+ bottom: calc(var(--cg-statusbar-h) + 8px);
7151
+ left: 8px;
7152
+ right: 8px;
7153
+ width: auto;
7154
+ max-height: 52%;
7155
+ }
7156
+
7157
+ /* 抽屉打开 ⇒ 两个角落的叠加层让位(关闭后自动回归,不需要 JS 复位) */
7158
+ .cg-graph-panel[data-cg-sheet="open"] .cg-mini-map,
7159
+ .cg-graph-panel[data-cg-sheet="open"] .cg-legend-panel {
7160
+ display: none;
7161
+ }
7162
+ }
7163
+
7164
+ /* 兜底机制(JS 实测档位):与上面的容器查询分支**逐条等价** */
7165
+ .cg-graph-panel[data-cg-tier="narrow"] .cg-node-detail-panel {
7166
+ top: auto;
7167
+ bottom: calc(var(--cg-statusbar-h) + 8px);
7168
+ left: 8px;
7169
+ right: 8px;
7170
+ width: auto;
7171
+ max-height: 52%;
7172
+ }
7173
+
7174
+ .cg-graph-panel[data-cg-tier="narrow"][data-cg-sheet="open"] .cg-mini-map,
7175
+ .cg-graph-panel[data-cg-tier="narrow"][data-cg-sheet="open"] .cg-legend-panel {
7176
+ display: none;
7177
+ }
7178
+
7179
+ /* ---- FBX-05: panel stack responsive tiers --------------------------------- */
7180
+ /*
7181
+ * 面板堆栈与栈内面板在窄容器下的收窄:只**新增**规则、不改任何现有行;面板根
7182
+ * 自身的固定 px 宽(160-300px)不在此重写,统一用 `max-width: calc(100% - 16px)`
7183
+ * 封顶(保留左右 8px 呼吸边)。两档阈值必须与 hooks/usePanelTier.ts 的
7184
+ * PANEL_TIER_* 常量同源——tests/unit/panelStackResponsiveContract.test.ts
7185
+ * 逐条比对,任一侧漂移即红。
7186
+ */
7187
+ @container graphpanel (max-width: 768px) {
7188
+ .cg-panel-stack-left .cg-search-bar,
7189
+ .cg-panel-stack-left .cg-path-bar,
7190
+ .cg-panel-stack-left .cg-health-score-card,
7191
+ .cg-panel-stack-left .cg-rule-panel,
7192
+ .cg-panel-stack-left .cg-node-detail-panel,
7193
+ .cg-panel-stack-left .cg-legend-panel,
7194
+ .cg-panel-stack-left .cg-import-panel {
7195
+ max-width: calc(100% - 16px);
7196
+ }
7197
+
7198
+ .cg-panel-stack-left .cg-impact-panel,
7199
+ .cg-panel-stack-left .cg-cycle-panel,
7200
+ .cg-panel-stack-right .cg-analysis-panel,
7201
+ .cg-panel-stack-right .cg-cycle-panel,
7202
+ .cg-panel-stack-right .cg-filter-panel,
7203
+ .cg-panel-stack-right .cg-deadcode-panel {
7204
+ max-width: calc(100% - 16px);
7205
+ }
7206
+ }
7207
+
7208
+ @container graphpanel (max-width: 480px) {
7209
+ .cg-panel-stack-left,
7210
+ .cg-panel-stack-right {
7211
+ left: 8px;
7212
+ right: 8px;
7213
+ max-width: calc(100% - 16px);
7214
+ }
7215
+
7216
+ .cg-panel-stack-left .cg-search-bar,
7217
+ .cg-panel-stack-left .cg-path-bar,
7218
+ .cg-panel-stack-left .cg-health-score-card,
7219
+ .cg-panel-stack-left .cg-rule-panel,
7220
+ .cg-panel-stack-left .cg-node-detail-panel,
7221
+ .cg-panel-stack-left .cg-legend-panel,
7222
+ .cg-panel-stack-left .cg-import-panel {
7223
+ max-width: calc(100% - 16px);
7224
+ }
7225
+
7226
+ .cg-panel-stack-left .cg-impact-panel,
7227
+ .cg-panel-stack-left .cg-cycle-panel,
7228
+ .cg-panel-stack-right .cg-analysis-panel,
7229
+ .cg-panel-stack-right .cg-cycle-panel,
7230
+ .cg-panel-stack-right .cg-filter-panel,
7231
+ .cg-panel-stack-right .cg-deadcode-panel {
7232
+ max-width: calc(100% - 16px);
7233
+ }
7234
+ }
7119
7235
 
7120
7236
  /* Visually hidden — for screen reader only content */
7121
7237
  .cg-visually-hidden {