@nelsonlongxiang/dsh-open-a2a-net 0.6.41 → 0.6.42
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/README.md +1 -1
- package/README_zh.md +1 -1
- package/assets/stageDist/assets/index-Bj7S2pA1.css +1 -1
- package/assets/stageDist/assets/index-C-28k_o5.js +974 -974
- package/assets/stageDist/index.html +12 -12
- package/lib/client.js +64 -64
- package/lib/client.js.map +1 -1
- package/lib/index.js +57 -9
- package/lib/origin-claim.js +4 -0
- package/lib/skill/SKILL.md +117 -117
- package/lib/skill/references/collaboration.md +428 -428
- package/lib/skill/references/discovery.md +78 -78
- package/lib/skill/references/intake.md +107 -107
- package/lib/skill/references/membership.md +73 -73
- package/lib/skill/references/pitfalls.md +51 -51
- package/lib/skill/references/router.md +96 -96
- package/lib/skill/references/routing.md +65 -65
- package/lib/types/origin-claim.d.ts +2 -0
- package/nexus-stage/package.json +21 -21
- package/nexus-stage/scripts/mockhost.py +261 -261
- package/nexus-stage/src/canvas-ops.ts +191 -191
- package/nexus-stage/src/canvas-wire.ts +164 -164
- package/nexus-stage/src/cli-home-picker.ts +42 -42
- package/nexus-stage/src/fault.ts +56 -56
- package/nexus-stage/src/federation-overlay.ts +103 -103
- package/nexus-stage/src/federation.ts +241 -241
- package/nexus-stage/src/layout-doc.ts +145 -145
- package/nexus-stage/src/main.ts +513 -513
- package/nexus-stage/src/planning-card-text.ts +73 -73
- package/nexus-stage/src/planning-card.ts +63 -63
- package/nexus-stage/src/planning-edges.ts +26 -26
- package/nexus-stage/src/planning-fit.ts +45 -45
- package/nexus-stage/src/planning-frame-hue.ts +13 -13
- package/nexus-stage/src/planning-legend.ts +39 -39
- package/nexus-stage/src/planning-member-handles.ts +61 -61
- package/nexus-stage/src/planning-menus.ts +422 -422
- package/nexus-stage/src/planning-mirror.ts +75 -75
- package/nexus-stage/src/planning-nodelist.ts +294 -294
- package/nexus-stage/src/planning-overlap.ts +159 -159
- package/nexus-stage/src/planning-reachability.ts +28 -28
- package/nexus-stage/src/planning-relayout.ts +121 -121
- package/nexus-stage/src/planning-roster.ts +15 -15
- package/nexus-stage/src/planning-search.ts +168 -168
- package/nexus-stage/src/planning-types.ts +115 -115
- package/nexus-stage/src/planning-undo.ts +68 -68
- package/nexus-stage/src/planning-view.ts +1499 -1499
- package/nexus-stage/src/planning.css +340 -340
- package/nexus-stage/src/seat-name-editor.ts +31 -31
- package/nexus-stage/src/session-drag.ts +64 -64
- package/nexus-stage/src/viewport.ts +106 -106
- package/nexus-stage/src/wb-chat.ts +684 -684
- package/nexus-stage/src/wb-directory.ts +237 -237
- package/nexus-stage/src/wb-ledger.ts +279 -279
- package/nexus-stage/src/wb-names.ts +43 -43
- package/nexus-stage/src/wb-rail.ts +147 -147
- package/nexus-stage/src/workbench.css +388 -388
- package/nexus-stage/src/workbench.ts +1272 -1272
- package/nexus-stage/src/world.ts +509 -509
- package/nexus-stage/tsconfig.json +24 -24
- package/nexus-stage/vite.config.ts +15 -15
- package/package.json +1 -1
|
@@ -1,340 +1,340 @@
|
|
|
1
|
-
/* Planning mode (2D infinite canvas) — ported from the approved wireframe
|
|
2
|
-
(feedback/2026-08-27-nexus-canvas-ux/prototype-v1.html) with the design
|
|
3
|
-
system's three-layer token discipline. Tokens are scoped to #dsh-plan
|
|
4
|
-
(token sovereignty: the stage owns its theme, detached from any host).
|
|
5
|
-
Deviations from the prototype, all for computable geometry:
|
|
6
|
-
- .frame-head is horizontally centered with a fixed 24px border-box
|
|
7
|
-
height, so the star-edge origin is exactly (fx + fw/2, fy + 11);
|
|
8
|
-
- .node has a fixed 56px border-box height matching world.NODE_H, with
|
|
9
|
-
nowrap/ellipsis so the card can never outgrow the edge math.
|
|
10
|
-
Layers (z): grid 0 < world 1 < marquee 2 < HUD 3. */
|
|
11
|
-
|
|
12
|
-
#dsh-plan *,#dsh-plan *::before,#dsh-plan *::after{box-sizing:border-box}
|
|
13
|
-
|
|
14
|
-
#dsh-plan{
|
|
15
|
-
/* primitive — bound to the workbench tokens (--n-*, workbench.css) so the
|
|
16
|
-
board follows the same dark/light theme as the rail; the literal after
|
|
17
|
-
each comma is the stage's own dark value, kept so the board still
|
|
18
|
-
renders on a host that ships without workbench.css (token sovereignty). */
|
|
19
|
-
--uupm-ink-0:var(--n-ink,#dde3f0); --uupm-ink-1:var(--n-ink-muted,#7a86a0);
|
|
20
|
-
--uupm-bg-0:var(--n-bg,#060a12); --uupm-bg-1:var(--n-panel,#0d1322); --uupm-bg-2:var(--n-raised,#131b2e);
|
|
21
|
-
--uupm-accent:var(--n-accent,#9673f7); --uupm-live:var(--n-live,#4ade80); --uupm-cold:var(--n-cold,#7a86a0);
|
|
22
|
-
--uupm-edge-member:var(--n-canvas,#22d3ee);
|
|
23
|
-
--uupm-warn:var(--n-act,#f59e0b); --uupm-error:var(--n-danger,#f87171); --uupm-indigo:var(--n-federal,#6366f1);
|
|
24
|
-
/* accent washes (hover 8% / active 12-18% / tint 5-10%), one definition each */
|
|
25
|
-
--uupm-wash-5:color-mix(in srgb,var(--uupm-accent) 5%,transparent);
|
|
26
|
-
--uupm-wash-8:color-mix(in srgb,var(--uupm-accent) 8%,transparent);
|
|
27
|
-
--uupm-wash-12:color-mix(in srgb,var(--uupm-accent) 12%,transparent);
|
|
28
|
-
--uupm-wash-15:color-mix(in srgb,var(--uupm-accent) 15%,transparent);
|
|
29
|
-
--uupm-wash-18:color-mix(in srgb,var(--uupm-accent) 18%,transparent);
|
|
30
|
-
/* semantic */
|
|
31
|
-
--surface:var(--uupm-bg-1); --ink:var(--uupm-ink-0); --ink-muted:var(--uupm-ink-1);
|
|
32
|
-
--accent:var(--uupm-accent); --edge-live:var(--uupm-live); --edge-cold:var(--uupm-cold);
|
|
33
|
-
--federal:var(--uupm-indigo);
|
|
34
|
-
/* component */
|
|
35
|
-
--card-bg:var(--surface); --card-line:var(--n-card-line,#5c6680); --card-line-hover:var(--uupm-ink-1);
|
|
36
|
-
--toolbar-bg:color-mix(in srgb,var(--uupm-bg-1) 92%,transparent);
|
|
37
|
-
--grid-dot:color-mix(in srgb,var(--uupm-ink-1) 22%,transparent);
|
|
38
|
-
--scrim:color-mix(in srgb,var(--uupm-bg-0) 60%,transparent);
|
|
39
|
-
--error-ink:var(--n-error-ink,#fecaca); --error-panel:var(--n-error-panel,#2a0d10f2);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
#dsh-plan{
|
|
43
|
-
position:absolute; inset:0; overflow:hidden; background:var(--uupm-bg-0); color:var(--ink);
|
|
44
|
-
font-size:13px; line-height:1.5; outline:none;
|
|
45
|
-
}
|
|
46
|
-
#dsh-plan .mono{font-family:ui-monospace,Cascadia,Consolas,monospace}
|
|
47
|
-
#dsh-plan:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
|
|
48
|
-
|
|
49
|
-
/* ── dot-grid world layer: screen-fixed, positioned by JS from the viewport ── */
|
|
50
|
-
#dsh-plan .p-grid{position:absolute; inset:0; z-index:0; pointer-events:none;
|
|
51
|
-
background-image:radial-gradient(circle, var(--grid-dot) 1px, transparent 1px);
|
|
52
|
-
background-size:24px 24px; background-position:0 0}
|
|
53
|
-
|
|
54
|
-
/* ── transformed world container ── */
|
|
55
|
-
#dsh-plan .p-world{position:absolute; inset:0; z-index:1; transform-origin:0 0}
|
|
56
|
-
#dsh-plan .p-layer{position:absolute; inset:0; pointer-events:none}
|
|
57
|
-
#dsh-plan .p-edges{position:absolute; overflow:visible; width:100%; height:100%; pointer-events:none}
|
|
58
|
-
/* The team frame is a grouping surface, not an interactive one: left
|
|
59
|
-
event-transparent so real drags reach the member cards inside it (the
|
|
60
|
-
frame head opts back in for group-drag/menu/Delete). */
|
|
61
|
-
#dsh-plan .p-frame{pointer-events:none}
|
|
62
|
-
#dsh-plan .p-frame-head{pointer-events:auto}
|
|
63
|
-
#dsh-plan .p-node{pointer-events:auto}
|
|
64
|
-
#dsh-plan .e-member{stroke:var(--uupm-edge-member); stroke-opacity:.38; stroke-width:1.5}
|
|
65
|
-
#dsh-plan .e-member.dashed{stroke-dasharray:3 4}
|
|
66
|
-
|
|
67
|
-
/* ── team frame ── */
|
|
68
|
-
/* --frame-line is the team hue set inline per frame (frameHue); --frame-ink is
|
|
69
|
-
what the frame actually paints with — the hue itself on dark, shaded 72%
|
|
70
|
-
toward black on light, where amber/lime/teal outlines fell to 1.8-2.2:1. */
|
|
71
|
-
#dsh-plan .p-frame{--frame-ink:var(--frame-line,#8B5CF6)}
|
|
72
|
-
@media (prefers-color-scheme: light){
|
|
73
|
-
#dsh-plan .p-frame{--frame-ink:color-mix(in srgb,var(--frame-line,#8B5CF6) 72%,black)}
|
|
74
|
-
}
|
|
75
|
-
#dsh-plan .p-frame{position:absolute; border:1px solid var(--frame-ink); border-radius:10px;
|
|
76
|
-
background:var(--frame-bg,var(--uupm-wash-5)); min-width:120px; min-height:60px}
|
|
77
|
-
#dsh-plan .p-frame-head{position:absolute; top:-13px; left:50%; transform:translateX(-50%);
|
|
78
|
-
height:24px; padding:0 10px; border-radius:6px; display:flex; gap:8px; align-items:center;
|
|
79
|
-
background:var(--uupm-bg-2); border:1px solid var(--frame-ink);
|
|
80
|
-
font-size:12px; font-weight:600; letter-spacing:.02em; white-space:nowrap; cursor:grab}
|
|
81
|
-
#dsh-plan .p-frame-head:active{cursor:grabbing}
|
|
82
|
-
#dsh-plan .p-frame-head:hover{border-color:var(--card-line-hover)}
|
|
83
|
-
#dsh-plan .p-frame-head .cnt{color:var(--ink-muted); font-weight:400}
|
|
84
|
-
#dsh-plan .p-frame-head .route{font-size:10.5px; color:var(--ink-muted)}
|
|
85
|
-
#dsh-plan .p-frame.is-mirror{border-style:dashed}
|
|
86
|
-
#dsh-plan .p-frame.is-roster{border-style:double;border-width:3px}
|
|
87
|
-
#dsh-plan .p-frame.is-roster .p-frame-head{border-style:dashed}
|
|
88
|
-
#dsh-plan .p-frame.is-syncing .p-frame-head .route{color:var(--accent)}
|
|
89
|
-
#dsh-plan .p-frame.is-unreachable{opacity:.76;border-style:dashed}
|
|
90
|
-
#dsh-plan .p-frame-unreachable{position:absolute;left:8px;top:20px;max-width:calc(100% - 16px);color:var(--uupm-error);font-size:11px;pointer-events:none}
|
|
91
|
-
#dsh-plan .p-node.remote.is-unreachable{opacity:.72;border-left-color:var(--uupm-error)}
|
|
92
|
-
#dsh-plan .p-node.remote.is-unreachable .sub{color:var(--uupm-error)}
|
|
93
|
-
|
|
94
|
-
/* ── node card (fixed 56px border-box height = world.NODE_H) ── */
|
|
95
|
-
#dsh-plan .p-node{position:absolute; width:172px; height:56px; padding:8px 26px 8px 14px;
|
|
96
|
-
background:var(--card-bg); border:1px solid var(--card-line); border-left:3px solid var(--edge-live);
|
|
97
|
-
border-radius:8px; cursor:grab; user-select:none;
|
|
98
|
-
transition:border-color 120ms cubic-bezier(0.2,0,0,1), transform 120ms cubic-bezier(0.2,0,0,1)}
|
|
99
|
-
#dsh-plan .p-node:hover{border-color:var(--card-line-hover)}
|
|
100
|
-
#dsh-plan .p-node:active{cursor:grabbing}
|
|
101
|
-
#dsh-plan .p-node:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
|
|
102
|
-
#dsh-plan .p-node.selected{outline:2px solid var(--accent); outline-offset:1px}
|
|
103
|
-
#dsh-plan .p-node.dragging{transform:scale(1.02); border-color:var(--accent)}
|
|
104
|
-
#dsh-plan .p-node.cold{border-left-color:var(--edge-cold)}
|
|
105
|
-
#dsh-plan .p-node .nm{font-weight:600; display:flex; align-items:center; gap:7px;
|
|
106
|
-
overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
107
|
-
/* The name span clips with an ellipsis (min-width:0 lets it shrink inside
|
|
108
|
-
the flex row) — without it a long peer address was hard-cut mid-digit.
|
|
109
|
-
属主令 W2: TWO-LINE clamp for the name (long Chinese team titles read
|
|
110
|
-
fully); the card's 172x56 geometry is untouched — the clamp absorbs the
|
|
111
|
-
overflow. The handle line (.sub) stays single-line ellipsis below. */
|
|
112
|
-
#dsh-plan .p-node .nm-text{min-width:0; overflow:hidden; white-space:normal;
|
|
113
|
-
display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; line-height:1.25}
|
|
114
|
-
/* A peer address has no break point, so the two-line clamp clipped it to one
|
|
115
|
-
line under the badge; let it wrap anywhere onto the second line. */
|
|
116
|
-
#dsh-plan .p-node.remote .nm-text{overflow-wrap:anywhere}
|
|
117
|
-
#dsh-plan .p-node .dot{width:8px; height:8px; border-radius:50%; background:var(--edge-live); flex:none}
|
|
118
|
-
#dsh-plan .p-node.cold .dot{background:transparent; border:1.5px solid var(--edge-cold)}
|
|
119
|
-
#dsh-plan .p-node .sub-row{display:flex; align-items:baseline; gap:6px; margin-top:2px; min-width:0}
|
|
120
|
-
#dsh-plan .p-node .sub-row .sub{flex:1 1 auto; min-width:0; margin-top:0}
|
|
121
|
-
#dsh-plan .p-node .work{flex:none; font-size:10.5px; font-weight:500; color:var(--ink-muted); white-space:nowrap}
|
|
122
|
-
#dsh-plan .p-node .work:empty{display:none}
|
|
123
|
-
#dsh-plan .p-node.is-working .work{color:var(--edge-live)}
|
|
124
|
-
#dsh-plan .p-node.is-working .dot{animation:p-working 1.4s ease-in-out infinite}
|
|
125
|
-
@keyframes p-working{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--edge-live) 55%,transparent)}50%{box-shadow:0 0 0 4px transparent}}
|
|
126
|
-
@media (prefers-reduced-motion: reduce){#dsh-plan .p-node.is-working .dot{animation:none}}
|
|
127
|
-
#dsh-plan .p-node .sub{font-size:11px; color:var(--ink-muted); margin-top:2px;
|
|
128
|
-
overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
129
|
-
/* W1: a picked search hit pulses its card for 1.2s (class removed on timer). */
|
|
130
|
-
#dsh-plan .p-node.pulse{box-shadow:0 0 0 2px var(--accent), 0 0 14px 4px var(--uupm-wash-15); border-color:var(--accent)}
|
|
131
|
-
/* W1: toolbar search box + hit list. */
|
|
132
|
-
#dsh-plan .p-search{position:relative}
|
|
133
|
-
#dsh-plan .p-search-input{width:170px; min-height:28px; padding:2px 8px; font-size:12px;
|
|
134
|
-
background:transparent; color:var(--ink); border:1px solid var(--card-line); border-radius:6px}
|
|
135
|
-
#dsh-plan .p-search-input:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
136
|
-
#dsh-plan .p-search-list{position:absolute; top:100%; left:0; margin-top:4px; display:none;
|
|
137
|
-
min-width:240px; max-height:220px; overflow:auto; z-index:9;
|
|
138
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:6px}
|
|
139
|
-
#dsh-plan .p-search-hit{padding:5px 10px; font-size:12px; color:var(--ink); cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
|
|
140
|
-
#dsh-plan .p-search-hit:hover, #dsh-plan .p-search-hit.active{background:var(--uupm-wash-15)}
|
|
141
|
-
#dsh-plan .p-node .prio{position:absolute; top:6px; right:8px; font-size:10px; color:var(--ink-muted);
|
|
142
|
-
border:1px solid var(--card-line); border-radius:4px; padding:0 5px}
|
|
143
|
-
|
|
144
|
-
/* ── marquee ── */
|
|
145
|
-
#dsh-plan .p-marquee{position:absolute; z-index:2; display:none; pointer-events:none;
|
|
146
|
-
border:1px solid var(--accent); background:var(--uupm-wash-8)}
|
|
147
|
-
|
|
148
|
-
/* ── HUD ── */
|
|
149
|
-
#dsh-plan .p-toolbar{position:absolute; top:16px; left:16px; z-index:3; display:flex; gap:6px; align-items:center;
|
|
150
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:6px 8px}
|
|
151
|
-
#dsh-plan .p-tabs{position:absolute; top:16px; left:50%; transform:translateX(-50%); z-index:3; display:flex; gap:4px;
|
|
152
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:4px}
|
|
153
|
-
#dsh-plan .p-tabs [role=tab]{background:transparent; color:var(--ink-muted); border:1px solid transparent; border-radius:6px;
|
|
154
|
-
padding:4px 12px; font:inherit; cursor:pointer}
|
|
155
|
-
#dsh-plan .p-tabs [role=tab]:hover{color:var(--ink); border-color:var(--card-line)}
|
|
156
|
-
#dsh-plan .p-tabs [role=tab][aria-selected=true]{color:var(--ink); border-color:var(--accent); background:var(--uupm-wash-12)}
|
|
157
|
-
#dsh-plan .p-tabs [role=tab]:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
158
|
-
#dsh-plan .p-toolbar button{background:transparent; color:var(--ink); border:1px solid var(--card-line); border-radius:6px;
|
|
159
|
-
padding:4px 10px; font:inherit; cursor:pointer; white-space:nowrap}
|
|
160
|
-
#dsh-plan .p-toolbar button:hover{border-color:var(--accent)}
|
|
161
|
-
#dsh-plan .p-toolbar button:active{background:var(--uupm-wash-15)}
|
|
162
|
-
#dsh-plan .p-toolbar button:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
163
|
-
#dsh-plan .p-zoom{min-width:44px; text-align:center; font-size:11px; color:var(--ink-muted)}
|
|
164
|
-
/* Toolbar groups (view | arrange | network): a hairline between them. */
|
|
165
|
-
#dsh-plan .p-sep{align-self:stretch; width:1px; margin:2px 4px; background:var(--card-line)}
|
|
166
|
-
#dsh-plan .p-lamp{display:flex; align-items:center; gap:6px; font-size:11px; color:var(--ink-muted); padding:0 6px}
|
|
167
|
-
#dsh-plan .p-lamp i{width:7px; height:7px; border-radius:50%; background:var(--ink-muted); transition:background 140ms ease}
|
|
168
|
-
#dsh-plan .p-lamp.saved i{background:var(--edge-live)}
|
|
169
|
-
#dsh-plan .p-lamp.pending i{background:var(--uupm-warn)}
|
|
170
|
-
#dsh-plan .p-lamp.error{color:var(--uupm-error); cursor:pointer}
|
|
171
|
-
#dsh-plan .p-lamp.error i{background:var(--uupm-error)}
|
|
172
|
-
#dsh-plan .p-lamp.error:hover{border:1px solid var(--uupm-error); border-radius:4px}
|
|
173
|
-
|
|
174
|
-
#dsh-plan .p-status{position:absolute; top:16px; right:16px; z-index:3; display:flex; gap:14px;
|
|
175
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:8px 14px; font-size:12px}
|
|
176
|
-
#dsh-plan .p-status b{font-weight:600}
|
|
177
|
-
#dsh-plan .ok{color:var(--edge-live)} #dsh-plan .warn{color:var(--uupm-warn)} #dsh-plan .mut{color:var(--ink-muted)}
|
|
178
|
-
|
|
179
|
-
#dsh-plan .p-legend{position:absolute; bottom:16px; left:16px; z-index:3; font-size:11px; color:var(--ink-muted);
|
|
180
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:4px 10px}
|
|
181
|
-
#dsh-plan .p-legend summary{cursor:pointer; padding:2px 0; user-select:none}
|
|
182
|
-
#dsh-plan .p-legend summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
|
|
183
|
-
#dsh-plan .p-legend[open]{padding-bottom:8px}
|
|
184
|
-
#dsh-plan .p-legend-rows{display:grid; gap:4px; margin-top:4px}
|
|
185
|
-
#dsh-plan .p-legend i{display:inline-block; width:18px; border-top:2px solid var(--uupm-edge-member);
|
|
186
|
-
vertical-align:middle; margin-right:6px}
|
|
187
|
-
#dsh-plan .p-legend i.dashed{border-top-style:dashed}
|
|
188
|
-
|
|
189
|
-
/* ── narrow board (<680px): the HUD stacks instead of colliding ──
|
|
190
|
-
The toolbar, status chip and legend are absolutely placed for a wide
|
|
191
|
-
board; on a phone they overlapped each other and the toolbar's CJK
|
|
192
|
-
labels wrapped one glyph per line. The one-row sideways scroll that
|
|
193
|
-
followed hid the search box and half the actions off-screen (review
|
|
194
|
-
2026-10-27), so the toolbar and status chip now flow at the top of the
|
|
195
|
-
board instead: the toolbar wraps, search first on its own row, and the
|
|
196
|
-
status chip sits under whatever height that takes. The legend (reference,
|
|
197
|
-
not state) hides. */
|
|
198
|
-
@media (max-width:680px){
|
|
199
|
-
#dsh-plan .p-toolbar{position:relative; top:auto; left:auto; margin:8px 8px 0; flex-wrap:wrap; row-gap:6px}
|
|
200
|
-
#dsh-plan .p-toolbar > *{flex:none}
|
|
201
|
-
#dsh-plan .p-toolbar .p-search{order:-1; flex:1 1 100%}
|
|
202
|
-
#dsh-plan .p-toolbar .p-sep{display:none}
|
|
203
|
-
#dsh-plan .p-toolbar .p-search-input{width:100%; box-sizing:border-box}
|
|
204
|
-
#dsh-plan .p-status{position:relative; top:auto; right:auto; left:auto; width:fit-content; margin:6px 8px 0; padding:6px 10px; gap:10px; flex-wrap:wrap}
|
|
205
|
-
#dsh-plan .p-legend{display:none}
|
|
206
|
-
}
|
|
207
|
-
@media (pointer:coarse){
|
|
208
|
-
#dsh-plan .p-toolbar button{min-height:36px; min-width:36px}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/* ── reduced motion: zero animation, state carried by text (hard baseline) ── */
|
|
212
|
-
@media (prefers-reduced-motion: reduce){
|
|
213
|
-
#dsh-plan *{transition:none !important; animation:none !important}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/* ── PR C: drop-target highlight, context menu, name dialog, notices ── */
|
|
217
|
-
#dsh-plan .p-frame.drop-target{border-color:var(--accent); border-width:2px; background:var(--uupm-wash-12)}
|
|
218
|
-
#dsh-plan .p-frame-head:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
219
|
-
|
|
220
|
-
/* ── PR D: federation overlay — peer badges, activity/federal edges, status fly ── */
|
|
221
|
-
/* Peer cards: the 'peer' tag is ~36px wide against the 26px gutter a P0–P9
|
|
222
|
-
tag fits in, so it sat on top of the address text — widen the gutter. */
|
|
223
|
-
#dsh-plan .p-node.remote{border-left-color:var(--federal); padding-right:46px}
|
|
224
|
-
#dsh-plan .p-node.remote .dot{background:var(--federal)}
|
|
225
|
-
#dsh-plan .p-node.remote .prio{color:var(--ink)}
|
|
226
|
-
/* gh#20 W-A link badge: linked green / stranger gray (fleet reserved);
|
|
227
|
-
the ✓/✗ verified mark rides inside the same chip. */
|
|
228
|
-
#dsh-plan .p-node .prio.lnk-linked{color:var(--live, #2e9e5b); border-color:var(--live, #2e9e5b)}
|
|
229
|
-
#dsh-plan .p-node .prio.lnk-stranger{color:var(--ink-muted); border-color:var(--card-line)}
|
|
230
|
-
#dsh-plan .e-activity{stroke:var(--accent); stroke-width:2; stroke-dasharray:8 6; stroke-opacity:.9}
|
|
231
|
-
#dsh-plan .e-federal{stroke:var(--federal); stroke-width:1.5; stroke-dasharray:6 5; stroke-opacity:.5}
|
|
232
|
-
#dsh-plan .edge-label{font-size:10.5px; fill:var(--ink-muted)}
|
|
233
|
-
/* in-flight routes flow only when motion is welcome; reduced-motion keeps
|
|
234
|
-
the zero-animation baseline (state stays in the label text). */
|
|
235
|
-
@media (prefers-reduced-motion: no-preference){
|
|
236
|
-
#dsh-plan .e-activity{animation:p-activity-flow 1.1s linear infinite}
|
|
237
|
-
}
|
|
238
|
-
@keyframes p-activity-flow{to{stroke-dashoffset:-28}}
|
|
239
|
-
#dsh-plan .p-status{cursor:pointer}
|
|
240
|
-
#dsh-plan .p-status:hover{border-color:var(--accent)}
|
|
241
|
-
#dsh-plan .p-status:active{background:var(--uupm-wash-12)}
|
|
242
|
-
#dsh-plan .p-status:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
|
|
243
|
-
|
|
244
|
-
#dsh-plan .p-menu{position:fixed; z-index:5; min-width:170px; display:grid; padding:4px; gap:2px;
|
|
245
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px}
|
|
246
|
-
#dsh-plan .p-menu [role=menuitem]{background:transparent; color:var(--ink); border:1px solid transparent;
|
|
247
|
-
border-radius:6px; padding:6px 10px; font:inherit; text-align:left; cursor:pointer; white-space:nowrap}
|
|
248
|
-
#dsh-plan .p-menu [role=menuitem]:hover{border-color:var(--card-line); background:var(--uupm-wash-8)}
|
|
249
|
-
#dsh-plan .p-menu [role=menuitem]:active{background:var(--uupm-wash-18)}
|
|
250
|
-
#dsh-plan .p-menu [role=menuitem]:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
251
|
-
#dsh-plan .p-menu [role=menuitem][aria-disabled=true]{color:var(--ink-muted); cursor:not-allowed}
|
|
252
|
-
|
|
253
|
-
#dsh-plan .p-dialog{position:absolute; inset:0; z-index:6; display:grid; place-items:center;
|
|
254
|
-
background:var(--scrim)}
|
|
255
|
-
#dsh-plan .p-dialog-panel{min-width:300px; padding:14px 16px; display:grid; gap:10px;
|
|
256
|
-
background:var(--uupm-bg-2); border:1px solid var(--card-line); border-radius:10px}
|
|
257
|
-
#dsh-plan .p-dialog-title{font-weight:600; font-size:12.5px; color:var(--ink)}
|
|
258
|
-
#dsh-plan .p-dialog-input{font:inherit; color:var(--ink); background:var(--uupm-bg-0);
|
|
259
|
-
border:1px solid var(--card-line); border-radius:6px; padding:7px 10px}
|
|
260
|
-
#dsh-plan .p-dialog-input:hover{border-color:color-mix(in srgb,var(--uupm-ink-1) 55%,transparent)}
|
|
261
|
-
#dsh-plan .p-dialog-input:focus-visible{outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent)}
|
|
262
|
-
#dsh-plan .p-dialog-err{min-height:1.2em; font-size:11px; color:var(--uupm-error)}
|
|
263
|
-
#dsh-plan .p-dialog-kind{display:grid; grid-template-columns:1fr 1fr; gap:4px; padding:3px;
|
|
264
|
-
background:var(--uupm-bg-0); border:1px solid var(--card-line); border-radius:8px}
|
|
265
|
-
#dsh-plan .p-dialog-kind button{font:inherit; color:var(--ink-muted); background:transparent; border:1px solid transparent;
|
|
266
|
-
border-radius:6px; padding:6px 10px; cursor:pointer}
|
|
267
|
-
#dsh-plan .p-dialog-kind button:hover{color:var(--ink); background:var(--uupm-wash-8)}
|
|
268
|
-
#dsh-plan .p-dialog-kind button[aria-checked=true]{color:var(--ink); font-weight:600; background:var(--uupm-wash-15);
|
|
269
|
-
border-color:var(--accent)}
|
|
270
|
-
#dsh-plan .p-dialog-kind button:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
271
|
-
#dsh-plan .p-dialog-hint{font-size:11px; color:var(--ink-muted); max-width:340px}
|
|
272
|
-
#dsh-plan .p-dialog-row{display:flex; gap:8px; justify-content:flex-end}
|
|
273
|
-
#dsh-plan .p-dialog-row button{background:transparent; color:var(--ink); border:1px solid var(--card-line);
|
|
274
|
-
border-radius:6px; padding:5px 12px; font:inherit; cursor:pointer}
|
|
275
|
-
#dsh-plan .p-dialog-row button:hover{border-color:var(--accent)}
|
|
276
|
-
#dsh-plan .p-dialog-row button:active{background:var(--uupm-wash-15)}
|
|
277
|
-
#dsh-plan .p-dialog-row button:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
278
|
-
|
|
279
|
-
#dsh-plan .p-notice-stack{position:absolute; bottom:52px; left:50%; transform:translateX(-50%); z-index:5;
|
|
280
|
-
display:grid; gap:6px; justify-items:center; pointer-events:none}
|
|
281
|
-
#dsh-plan .p-notice{max-width:60ch; padding:7px 12px; font-size:12px; color:var(--ink);
|
|
282
|
-
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; white-space:nowrap;
|
|
283
|
-
overflow:hidden; text-overflow:ellipsis}
|
|
284
|
-
#dsh-plan .p-notice.error{color:var(--error-ink); border-color:var(--uupm-error); background:var(--error-panel)}
|
|
285
|
-
|
|
286
|
-
/* Panel-slim migration: the unjoined-sessions join affordance on the toolbar. */
|
|
287
|
-
#dsh-plan .p-netbtn{color:var(--ink-muted)}
|
|
288
|
-
#dsh-plan .p-netbtn:not([disabled]){color:var(--ink)}
|
|
289
|
-
#dsh-plan .p-netmenu{max-height:240px; overflow:auto}
|
|
290
|
-
|
|
291
|
-
/* ── Node list drawer (network-membership-display): teamed nodes hold the
|
|
292
|
-
canvas; every other session is managed here, switched by host. ── */
|
|
293
|
-
#dsh-plan .p-nodebtn{color:var(--ink)}
|
|
294
|
-
#dsh-plan .p-nodelist{min-width:300px; max-width:340px; max-height:420px; overflow:auto; padding:6px}
|
|
295
|
-
#dsh-plan .p-nodelist-head{display:flex; align-items:center; justify-content:space-between; gap:8px;
|
|
296
|
-
padding:2px 4px 6px; border-bottom:1px solid var(--card-line)}
|
|
297
|
-
#dsh-plan .p-nodelist-title{font-size:12px; font-weight:600; color:var(--ink)}
|
|
298
|
-
#dsh-plan .p-nodesel{font:inherit; font-size:11.5px; color:var(--ink); background:var(--uupm-bg-0);
|
|
299
|
-
border:1px solid var(--card-line); border-radius:6px; padding:2px 6px; max-width:220px}
|
|
300
|
-
#dsh-plan .p-nodesel:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
301
|
-
#dsh-plan .p-nodelist-group{font-size:11px; color:var(--ink-muted); padding:8px 4px 3px;
|
|
302
|
-
display:flex; align-items:baseline; gap:8px}
|
|
303
|
-
#dsh-plan .p-nodelist-note{font-size:10px; color:var(--ink-muted); opacity:.8}
|
|
304
|
-
#dsh-plan .p-noderow{display:flex; align-items:center; gap:6px; padding:3px 4px; border-radius:6px;
|
|
305
|
-
font-size:12px; color:var(--ink)}
|
|
306
|
-
#dsh-plan .p-noderow:hover{background:var(--uupm-wash-8)}
|
|
307
|
-
#dsh-plan .p-nodedot{flex:none; width:7px; height:7px; border-radius:50%; background:var(--edge-live)}
|
|
308
|
-
#dsh-plan .p-nodedot.cold{background:var(--ink-muted)}
|
|
309
|
-
#dsh-plan .p-nodedot.off{background:transparent; border:1px solid var(--ink-muted)}
|
|
310
|
-
#dsh-plan .p-nodename{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
311
|
-
#dsh-plan .p-nonet{flex:none; font-size:10px; color:var(--uupm-warn); border:1px solid var(--uupm-warn);
|
|
312
|
-
border-radius:4px; padding:0 4px}
|
|
313
|
-
#dsh-plan .p-teamcount{flex:none; font-size:10px; color:var(--ink-muted); border:1px solid var(--card-line);
|
|
314
|
-
border-radius:4px; padding:0 4px}
|
|
315
|
-
#dsh-plan .p-listbtn{flex:none; background:transparent; color:var(--ink); border:1px solid var(--card-line);
|
|
316
|
-
border-radius:5px; padding:1px 7px; font:inherit; font-size:11px; cursor:pointer}
|
|
317
|
-
#dsh-plan .p-listbtn:hover{border-color:var(--card-line-hover); background:var(--uupm-wash-8)}
|
|
318
|
-
#dsh-plan .p-listbtn:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
319
|
-
#dsh-plan .p-nodelist-empty{padding:10px 4px; font-size:11.5px; color:var(--ink-muted)}
|
|
320
|
-
|
|
321
|
-
/* ── Frame resize handles (owner ruling: frames stretch/adjust) — eight
|
|
322
|
-
invisible hit zones that show the grip on hover. ── */
|
|
323
|
-
#dsh-plan .p-frame{position:absolute}
|
|
324
|
-
#dsh-plan .p-frame-handle{position:absolute; pointer-events:auto; width:10px; height:10px; z-index:2; opacity:0;
|
|
325
|
-
transition:opacity 120ms ease}
|
|
326
|
-
#dsh-plan .p-frame:hover .p-frame-handle{opacity:1}
|
|
327
|
-
#dsh-plan .p-frame-handle::after{content:''; position:absolute; inset:2px; background:var(--frame-ink);
|
|
328
|
-
border-radius:2px}
|
|
329
|
-
#dsh-plan .p-h-n{top:-5px; left:calc(50% - 12px); width:24px; height:8px; cursor:ns-resize}
|
|
330
|
-
#dsh-plan .p-h-s{bottom:-5px; left:calc(50% - 12px); width:24px; height:8px; cursor:ns-resize}
|
|
331
|
-
#dsh-plan .p-h-e{right:-5px; top:calc(50% - 12px); width:8px; height:24px; cursor:ew-resize}
|
|
332
|
-
#dsh-plan .p-h-w{left:-5px; top:calc(50% - 12px); width:8px; height:24px; cursor:ew-resize}
|
|
333
|
-
#dsh-plan .p-h-ne{top:-5px; right:-5px; cursor:nesw-resize}
|
|
334
|
-
#dsh-plan .p-h-nw{top:-5px; left:-5px; cursor:nwse-resize}
|
|
335
|
-
#dsh-plan .p-h-se{bottom:-5px; right:-5px; cursor:nwse-resize}
|
|
336
|
-
#dsh-plan .p-h-sw{bottom:-5px; left:-5px; cursor:nesw-resize}
|
|
337
|
-
#dsh-plan .p-h-ne::after, #dsh-plan .p-h-sw::after{transform:rotate(45deg)}
|
|
338
|
-
#dsh-plan .p-h-nw::after, #dsh-plan .p-h-se::after{transform:rotate(-45deg)}
|
|
339
|
-
#dsh-plan .p-frame.selected .p-frame-handle{opacity:1}
|
|
340
|
-
#dsh-plan .p-frame.selected{outline:1px solid var(--frame-ink)}
|
|
1
|
+
/* Planning mode (2D infinite canvas) — ported from the approved wireframe
|
|
2
|
+
(feedback/2026-08-27-nexus-canvas-ux/prototype-v1.html) with the design
|
|
3
|
+
system's three-layer token discipline. Tokens are scoped to #dsh-plan
|
|
4
|
+
(token sovereignty: the stage owns its theme, detached from any host).
|
|
5
|
+
Deviations from the prototype, all for computable geometry:
|
|
6
|
+
- .frame-head is horizontally centered with a fixed 24px border-box
|
|
7
|
+
height, so the star-edge origin is exactly (fx + fw/2, fy + 11);
|
|
8
|
+
- .node has a fixed 56px border-box height matching world.NODE_H, with
|
|
9
|
+
nowrap/ellipsis so the card can never outgrow the edge math.
|
|
10
|
+
Layers (z): grid 0 < world 1 < marquee 2 < HUD 3. */
|
|
11
|
+
|
|
12
|
+
#dsh-plan *,#dsh-plan *::before,#dsh-plan *::after{box-sizing:border-box}
|
|
13
|
+
|
|
14
|
+
#dsh-plan{
|
|
15
|
+
/* primitive — bound to the workbench tokens (--n-*, workbench.css) so the
|
|
16
|
+
board follows the same dark/light theme as the rail; the literal after
|
|
17
|
+
each comma is the stage's own dark value, kept so the board still
|
|
18
|
+
renders on a host that ships without workbench.css (token sovereignty). */
|
|
19
|
+
--uupm-ink-0:var(--n-ink,#dde3f0); --uupm-ink-1:var(--n-ink-muted,#7a86a0);
|
|
20
|
+
--uupm-bg-0:var(--n-bg,#060a12); --uupm-bg-1:var(--n-panel,#0d1322); --uupm-bg-2:var(--n-raised,#131b2e);
|
|
21
|
+
--uupm-accent:var(--n-accent,#9673f7); --uupm-live:var(--n-live,#4ade80); --uupm-cold:var(--n-cold,#7a86a0);
|
|
22
|
+
--uupm-edge-member:var(--n-canvas,#22d3ee);
|
|
23
|
+
--uupm-warn:var(--n-act,#f59e0b); --uupm-error:var(--n-danger,#f87171); --uupm-indigo:var(--n-federal,#6366f1);
|
|
24
|
+
/* accent washes (hover 8% / active 12-18% / tint 5-10%), one definition each */
|
|
25
|
+
--uupm-wash-5:color-mix(in srgb,var(--uupm-accent) 5%,transparent);
|
|
26
|
+
--uupm-wash-8:color-mix(in srgb,var(--uupm-accent) 8%,transparent);
|
|
27
|
+
--uupm-wash-12:color-mix(in srgb,var(--uupm-accent) 12%,transparent);
|
|
28
|
+
--uupm-wash-15:color-mix(in srgb,var(--uupm-accent) 15%,transparent);
|
|
29
|
+
--uupm-wash-18:color-mix(in srgb,var(--uupm-accent) 18%,transparent);
|
|
30
|
+
/* semantic */
|
|
31
|
+
--surface:var(--uupm-bg-1); --ink:var(--uupm-ink-0); --ink-muted:var(--uupm-ink-1);
|
|
32
|
+
--accent:var(--uupm-accent); --edge-live:var(--uupm-live); --edge-cold:var(--uupm-cold);
|
|
33
|
+
--federal:var(--uupm-indigo);
|
|
34
|
+
/* component */
|
|
35
|
+
--card-bg:var(--surface); --card-line:var(--n-card-line,#5c6680); --card-line-hover:var(--uupm-ink-1);
|
|
36
|
+
--toolbar-bg:color-mix(in srgb,var(--uupm-bg-1) 92%,transparent);
|
|
37
|
+
--grid-dot:color-mix(in srgb,var(--uupm-ink-1) 22%,transparent);
|
|
38
|
+
--scrim:color-mix(in srgb,var(--uupm-bg-0) 60%,transparent);
|
|
39
|
+
--error-ink:var(--n-error-ink,#fecaca); --error-panel:var(--n-error-panel,#2a0d10f2);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#dsh-plan{
|
|
43
|
+
position:absolute; inset:0; overflow:hidden; background:var(--uupm-bg-0); color:var(--ink);
|
|
44
|
+
font-size:13px; line-height:1.5; outline:none;
|
|
45
|
+
}
|
|
46
|
+
#dsh-plan .mono{font-family:ui-monospace,Cascadia,Consolas,monospace}
|
|
47
|
+
#dsh-plan:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
|
|
48
|
+
|
|
49
|
+
/* ── dot-grid world layer: screen-fixed, positioned by JS from the viewport ── */
|
|
50
|
+
#dsh-plan .p-grid{position:absolute; inset:0; z-index:0; pointer-events:none;
|
|
51
|
+
background-image:radial-gradient(circle, var(--grid-dot) 1px, transparent 1px);
|
|
52
|
+
background-size:24px 24px; background-position:0 0}
|
|
53
|
+
|
|
54
|
+
/* ── transformed world container ── */
|
|
55
|
+
#dsh-plan .p-world{position:absolute; inset:0; z-index:1; transform-origin:0 0}
|
|
56
|
+
#dsh-plan .p-layer{position:absolute; inset:0; pointer-events:none}
|
|
57
|
+
#dsh-plan .p-edges{position:absolute; overflow:visible; width:100%; height:100%; pointer-events:none}
|
|
58
|
+
/* The team frame is a grouping surface, not an interactive one: left
|
|
59
|
+
event-transparent so real drags reach the member cards inside it (the
|
|
60
|
+
frame head opts back in for group-drag/menu/Delete). */
|
|
61
|
+
#dsh-plan .p-frame{pointer-events:none}
|
|
62
|
+
#dsh-plan .p-frame-head{pointer-events:auto}
|
|
63
|
+
#dsh-plan .p-node{pointer-events:auto}
|
|
64
|
+
#dsh-plan .e-member{stroke:var(--uupm-edge-member); stroke-opacity:.38; stroke-width:1.5}
|
|
65
|
+
#dsh-plan .e-member.dashed{stroke-dasharray:3 4}
|
|
66
|
+
|
|
67
|
+
/* ── team frame ── */
|
|
68
|
+
/* --frame-line is the team hue set inline per frame (frameHue); --frame-ink is
|
|
69
|
+
what the frame actually paints with — the hue itself on dark, shaded 72%
|
|
70
|
+
toward black on light, where amber/lime/teal outlines fell to 1.8-2.2:1. */
|
|
71
|
+
#dsh-plan .p-frame{--frame-ink:var(--frame-line,#8B5CF6)}
|
|
72
|
+
@media (prefers-color-scheme: light){
|
|
73
|
+
#dsh-plan .p-frame{--frame-ink:color-mix(in srgb,var(--frame-line,#8B5CF6) 72%,black)}
|
|
74
|
+
}
|
|
75
|
+
#dsh-plan .p-frame{position:absolute; border:1px solid var(--frame-ink); border-radius:10px;
|
|
76
|
+
background:var(--frame-bg,var(--uupm-wash-5)); min-width:120px; min-height:60px}
|
|
77
|
+
#dsh-plan .p-frame-head{position:absolute; top:-13px; left:50%; transform:translateX(-50%);
|
|
78
|
+
height:24px; padding:0 10px; border-radius:6px; display:flex; gap:8px; align-items:center;
|
|
79
|
+
background:var(--uupm-bg-2); border:1px solid var(--frame-ink);
|
|
80
|
+
font-size:12px; font-weight:600; letter-spacing:.02em; white-space:nowrap; cursor:grab}
|
|
81
|
+
#dsh-plan .p-frame-head:active{cursor:grabbing}
|
|
82
|
+
#dsh-plan .p-frame-head:hover{border-color:var(--card-line-hover)}
|
|
83
|
+
#dsh-plan .p-frame-head .cnt{color:var(--ink-muted); font-weight:400}
|
|
84
|
+
#dsh-plan .p-frame-head .route{font-size:10.5px; color:var(--ink-muted)}
|
|
85
|
+
#dsh-plan .p-frame.is-mirror{border-style:dashed}
|
|
86
|
+
#dsh-plan .p-frame.is-roster{border-style:double;border-width:3px}
|
|
87
|
+
#dsh-plan .p-frame.is-roster .p-frame-head{border-style:dashed}
|
|
88
|
+
#dsh-plan .p-frame.is-syncing .p-frame-head .route{color:var(--accent)}
|
|
89
|
+
#dsh-plan .p-frame.is-unreachable{opacity:.76;border-style:dashed}
|
|
90
|
+
#dsh-plan .p-frame-unreachable{position:absolute;left:8px;top:20px;max-width:calc(100% - 16px);color:var(--uupm-error);font-size:11px;pointer-events:none}
|
|
91
|
+
#dsh-plan .p-node.remote.is-unreachable{opacity:.72;border-left-color:var(--uupm-error)}
|
|
92
|
+
#dsh-plan .p-node.remote.is-unreachable .sub{color:var(--uupm-error)}
|
|
93
|
+
|
|
94
|
+
/* ── node card (fixed 56px border-box height = world.NODE_H) ── */
|
|
95
|
+
#dsh-plan .p-node{position:absolute; width:172px; height:56px; padding:8px 26px 8px 14px;
|
|
96
|
+
background:var(--card-bg); border:1px solid var(--card-line); border-left:3px solid var(--edge-live);
|
|
97
|
+
border-radius:8px; cursor:grab; user-select:none;
|
|
98
|
+
transition:border-color 120ms cubic-bezier(0.2,0,0,1), transform 120ms cubic-bezier(0.2,0,0,1)}
|
|
99
|
+
#dsh-plan .p-node:hover{border-color:var(--card-line-hover)}
|
|
100
|
+
#dsh-plan .p-node:active{cursor:grabbing}
|
|
101
|
+
#dsh-plan .p-node:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
|
|
102
|
+
#dsh-plan .p-node.selected{outline:2px solid var(--accent); outline-offset:1px}
|
|
103
|
+
#dsh-plan .p-node.dragging{transform:scale(1.02); border-color:var(--accent)}
|
|
104
|
+
#dsh-plan .p-node.cold{border-left-color:var(--edge-cold)}
|
|
105
|
+
#dsh-plan .p-node .nm{font-weight:600; display:flex; align-items:center; gap:7px;
|
|
106
|
+
overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
107
|
+
/* The name span clips with an ellipsis (min-width:0 lets it shrink inside
|
|
108
|
+
the flex row) — without it a long peer address was hard-cut mid-digit.
|
|
109
|
+
属主令 W2: TWO-LINE clamp for the name (long Chinese team titles read
|
|
110
|
+
fully); the card's 172x56 geometry is untouched — the clamp absorbs the
|
|
111
|
+
overflow. The handle line (.sub) stays single-line ellipsis below. */
|
|
112
|
+
#dsh-plan .p-node .nm-text{min-width:0; overflow:hidden; white-space:normal;
|
|
113
|
+
display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; line-height:1.25}
|
|
114
|
+
/* A peer address has no break point, so the two-line clamp clipped it to one
|
|
115
|
+
line under the badge; let it wrap anywhere onto the second line. */
|
|
116
|
+
#dsh-plan .p-node.remote .nm-text{overflow-wrap:anywhere}
|
|
117
|
+
#dsh-plan .p-node .dot{width:8px; height:8px; border-radius:50%; background:var(--edge-live); flex:none}
|
|
118
|
+
#dsh-plan .p-node.cold .dot{background:transparent; border:1.5px solid var(--edge-cold)}
|
|
119
|
+
#dsh-plan .p-node .sub-row{display:flex; align-items:baseline; gap:6px; margin-top:2px; min-width:0}
|
|
120
|
+
#dsh-plan .p-node .sub-row .sub{flex:1 1 auto; min-width:0; margin-top:0}
|
|
121
|
+
#dsh-plan .p-node .work{flex:none; font-size:10.5px; font-weight:500; color:var(--ink-muted); white-space:nowrap}
|
|
122
|
+
#dsh-plan .p-node .work:empty{display:none}
|
|
123
|
+
#dsh-plan .p-node.is-working .work{color:var(--edge-live)}
|
|
124
|
+
#dsh-plan .p-node.is-working .dot{animation:p-working 1.4s ease-in-out infinite}
|
|
125
|
+
@keyframes p-working{0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--edge-live) 55%,transparent)}50%{box-shadow:0 0 0 4px transparent}}
|
|
126
|
+
@media (prefers-reduced-motion: reduce){#dsh-plan .p-node.is-working .dot{animation:none}}
|
|
127
|
+
#dsh-plan .p-node .sub{font-size:11px; color:var(--ink-muted); margin-top:2px;
|
|
128
|
+
overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
129
|
+
/* W1: a picked search hit pulses its card for 1.2s (class removed on timer). */
|
|
130
|
+
#dsh-plan .p-node.pulse{box-shadow:0 0 0 2px var(--accent), 0 0 14px 4px var(--uupm-wash-15); border-color:var(--accent)}
|
|
131
|
+
/* W1: toolbar search box + hit list. */
|
|
132
|
+
#dsh-plan .p-search{position:relative}
|
|
133
|
+
#dsh-plan .p-search-input{width:170px; min-height:28px; padding:2px 8px; font-size:12px;
|
|
134
|
+
background:transparent; color:var(--ink); border:1px solid var(--card-line); border-radius:6px}
|
|
135
|
+
#dsh-plan .p-search-input:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
136
|
+
#dsh-plan .p-search-list{position:absolute; top:100%; left:0; margin-top:4px; display:none;
|
|
137
|
+
min-width:240px; max-height:220px; overflow:auto; z-index:9;
|
|
138
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:6px}
|
|
139
|
+
#dsh-plan .p-search-hit{padding:5px 10px; font-size:12px; color:var(--ink); cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
|
|
140
|
+
#dsh-plan .p-search-hit:hover, #dsh-plan .p-search-hit.active{background:var(--uupm-wash-15)}
|
|
141
|
+
#dsh-plan .p-node .prio{position:absolute; top:6px; right:8px; font-size:10px; color:var(--ink-muted);
|
|
142
|
+
border:1px solid var(--card-line); border-radius:4px; padding:0 5px}
|
|
143
|
+
|
|
144
|
+
/* ── marquee ── */
|
|
145
|
+
#dsh-plan .p-marquee{position:absolute; z-index:2; display:none; pointer-events:none;
|
|
146
|
+
border:1px solid var(--accent); background:var(--uupm-wash-8)}
|
|
147
|
+
|
|
148
|
+
/* ── HUD ── */
|
|
149
|
+
#dsh-plan .p-toolbar{position:absolute; top:16px; left:16px; z-index:3; display:flex; gap:6px; align-items:center;
|
|
150
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:6px 8px}
|
|
151
|
+
#dsh-plan .p-tabs{position:absolute; top:16px; left:50%; transform:translateX(-50%); z-index:3; display:flex; gap:4px;
|
|
152
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:4px}
|
|
153
|
+
#dsh-plan .p-tabs [role=tab]{background:transparent; color:var(--ink-muted); border:1px solid transparent; border-radius:6px;
|
|
154
|
+
padding:4px 12px; font:inherit; cursor:pointer}
|
|
155
|
+
#dsh-plan .p-tabs [role=tab]:hover{color:var(--ink); border-color:var(--card-line)}
|
|
156
|
+
#dsh-plan .p-tabs [role=tab][aria-selected=true]{color:var(--ink); border-color:var(--accent); background:var(--uupm-wash-12)}
|
|
157
|
+
#dsh-plan .p-tabs [role=tab]:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
158
|
+
#dsh-plan .p-toolbar button{background:transparent; color:var(--ink); border:1px solid var(--card-line); border-radius:6px;
|
|
159
|
+
padding:4px 10px; font:inherit; cursor:pointer; white-space:nowrap}
|
|
160
|
+
#dsh-plan .p-toolbar button:hover{border-color:var(--accent)}
|
|
161
|
+
#dsh-plan .p-toolbar button:active{background:var(--uupm-wash-15)}
|
|
162
|
+
#dsh-plan .p-toolbar button:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
163
|
+
#dsh-plan .p-zoom{min-width:44px; text-align:center; font-size:11px; color:var(--ink-muted)}
|
|
164
|
+
/* Toolbar groups (view | arrange | network): a hairline between them. */
|
|
165
|
+
#dsh-plan .p-sep{align-self:stretch; width:1px; margin:2px 4px; background:var(--card-line)}
|
|
166
|
+
#dsh-plan .p-lamp{display:flex; align-items:center; gap:6px; font-size:11px; color:var(--ink-muted); padding:0 6px}
|
|
167
|
+
#dsh-plan .p-lamp i{width:7px; height:7px; border-radius:50%; background:var(--ink-muted); transition:background 140ms ease}
|
|
168
|
+
#dsh-plan .p-lamp.saved i{background:var(--edge-live)}
|
|
169
|
+
#dsh-plan .p-lamp.pending i{background:var(--uupm-warn)}
|
|
170
|
+
#dsh-plan .p-lamp.error{color:var(--uupm-error); cursor:pointer}
|
|
171
|
+
#dsh-plan .p-lamp.error i{background:var(--uupm-error)}
|
|
172
|
+
#dsh-plan .p-lamp.error:hover{border:1px solid var(--uupm-error); border-radius:4px}
|
|
173
|
+
|
|
174
|
+
#dsh-plan .p-status{position:absolute; top:16px; right:16px; z-index:3; display:flex; gap:14px;
|
|
175
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:8px 14px; font-size:12px}
|
|
176
|
+
#dsh-plan .p-status b{font-weight:600}
|
|
177
|
+
#dsh-plan .ok{color:var(--edge-live)} #dsh-plan .warn{color:var(--uupm-warn)} #dsh-plan .mut{color:var(--ink-muted)}
|
|
178
|
+
|
|
179
|
+
#dsh-plan .p-legend{position:absolute; bottom:16px; left:16px; z-index:3; font-size:11px; color:var(--ink-muted);
|
|
180
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; padding:4px 10px}
|
|
181
|
+
#dsh-plan .p-legend summary{cursor:pointer; padding:2px 0; user-select:none}
|
|
182
|
+
#dsh-plan .p-legend summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
|
|
183
|
+
#dsh-plan .p-legend[open]{padding-bottom:8px}
|
|
184
|
+
#dsh-plan .p-legend-rows{display:grid; gap:4px; margin-top:4px}
|
|
185
|
+
#dsh-plan .p-legend i{display:inline-block; width:18px; border-top:2px solid var(--uupm-edge-member);
|
|
186
|
+
vertical-align:middle; margin-right:6px}
|
|
187
|
+
#dsh-plan .p-legend i.dashed{border-top-style:dashed}
|
|
188
|
+
|
|
189
|
+
/* ── narrow board (<680px): the HUD stacks instead of colliding ──
|
|
190
|
+
The toolbar, status chip and legend are absolutely placed for a wide
|
|
191
|
+
board; on a phone they overlapped each other and the toolbar's CJK
|
|
192
|
+
labels wrapped one glyph per line. The one-row sideways scroll that
|
|
193
|
+
followed hid the search box and half the actions off-screen (review
|
|
194
|
+
2026-10-27), so the toolbar and status chip now flow at the top of the
|
|
195
|
+
board instead: the toolbar wraps, search first on its own row, and the
|
|
196
|
+
status chip sits under whatever height that takes. The legend (reference,
|
|
197
|
+
not state) hides. */
|
|
198
|
+
@media (max-width:680px){
|
|
199
|
+
#dsh-plan .p-toolbar{position:relative; top:auto; left:auto; margin:8px 8px 0; flex-wrap:wrap; row-gap:6px}
|
|
200
|
+
#dsh-plan .p-toolbar > *{flex:none}
|
|
201
|
+
#dsh-plan .p-toolbar .p-search{order:-1; flex:1 1 100%}
|
|
202
|
+
#dsh-plan .p-toolbar .p-sep{display:none}
|
|
203
|
+
#dsh-plan .p-toolbar .p-search-input{width:100%; box-sizing:border-box}
|
|
204
|
+
#dsh-plan .p-status{position:relative; top:auto; right:auto; left:auto; width:fit-content; margin:6px 8px 0; padding:6px 10px; gap:10px; flex-wrap:wrap}
|
|
205
|
+
#dsh-plan .p-legend{display:none}
|
|
206
|
+
}
|
|
207
|
+
@media (pointer:coarse){
|
|
208
|
+
#dsh-plan .p-toolbar button{min-height:36px; min-width:36px}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* ── reduced motion: zero animation, state carried by text (hard baseline) ── */
|
|
212
|
+
@media (prefers-reduced-motion: reduce){
|
|
213
|
+
#dsh-plan *{transition:none !important; animation:none !important}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* ── PR C: drop-target highlight, context menu, name dialog, notices ── */
|
|
217
|
+
#dsh-plan .p-frame.drop-target{border-color:var(--accent); border-width:2px; background:var(--uupm-wash-12)}
|
|
218
|
+
#dsh-plan .p-frame-head:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
219
|
+
|
|
220
|
+
/* ── PR D: federation overlay — peer badges, activity/federal edges, status fly ── */
|
|
221
|
+
/* Peer cards: the 'peer' tag is ~36px wide against the 26px gutter a P0–P9
|
|
222
|
+
tag fits in, so it sat on top of the address text — widen the gutter. */
|
|
223
|
+
#dsh-plan .p-node.remote{border-left-color:var(--federal); padding-right:46px}
|
|
224
|
+
#dsh-plan .p-node.remote .dot{background:var(--federal)}
|
|
225
|
+
#dsh-plan .p-node.remote .prio{color:var(--ink)}
|
|
226
|
+
/* gh#20 W-A link badge: linked green / stranger gray (fleet reserved);
|
|
227
|
+
the ✓/✗ verified mark rides inside the same chip. */
|
|
228
|
+
#dsh-plan .p-node .prio.lnk-linked{color:var(--live, #2e9e5b); border-color:var(--live, #2e9e5b)}
|
|
229
|
+
#dsh-plan .p-node .prio.lnk-stranger{color:var(--ink-muted); border-color:var(--card-line)}
|
|
230
|
+
#dsh-plan .e-activity{stroke:var(--accent); stroke-width:2; stroke-dasharray:8 6; stroke-opacity:.9}
|
|
231
|
+
#dsh-plan .e-federal{stroke:var(--federal); stroke-width:1.5; stroke-dasharray:6 5; stroke-opacity:.5}
|
|
232
|
+
#dsh-plan .edge-label{font-size:10.5px; fill:var(--ink-muted)}
|
|
233
|
+
/* in-flight routes flow only when motion is welcome; reduced-motion keeps
|
|
234
|
+
the zero-animation baseline (state stays in the label text). */
|
|
235
|
+
@media (prefers-reduced-motion: no-preference){
|
|
236
|
+
#dsh-plan .e-activity{animation:p-activity-flow 1.1s linear infinite}
|
|
237
|
+
}
|
|
238
|
+
@keyframes p-activity-flow{to{stroke-dashoffset:-28}}
|
|
239
|
+
#dsh-plan .p-status{cursor:pointer}
|
|
240
|
+
#dsh-plan .p-status:hover{border-color:var(--accent)}
|
|
241
|
+
#dsh-plan .p-status:active{background:var(--uupm-wash-12)}
|
|
242
|
+
#dsh-plan .p-status:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
|
|
243
|
+
|
|
244
|
+
#dsh-plan .p-menu{position:fixed; z-index:5; min-width:170px; display:grid; padding:4px; gap:2px;
|
|
245
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px}
|
|
246
|
+
#dsh-plan .p-menu [role=menuitem]{background:transparent; color:var(--ink); border:1px solid transparent;
|
|
247
|
+
border-radius:6px; padding:6px 10px; font:inherit; text-align:left; cursor:pointer; white-space:nowrap}
|
|
248
|
+
#dsh-plan .p-menu [role=menuitem]:hover{border-color:var(--card-line); background:var(--uupm-wash-8)}
|
|
249
|
+
#dsh-plan .p-menu [role=menuitem]:active{background:var(--uupm-wash-18)}
|
|
250
|
+
#dsh-plan .p-menu [role=menuitem]:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
251
|
+
#dsh-plan .p-menu [role=menuitem][aria-disabled=true]{color:var(--ink-muted); cursor:not-allowed}
|
|
252
|
+
|
|
253
|
+
#dsh-plan .p-dialog{position:absolute; inset:0; z-index:6; display:grid; place-items:center;
|
|
254
|
+
background:var(--scrim)}
|
|
255
|
+
#dsh-plan .p-dialog-panel{min-width:300px; padding:14px 16px; display:grid; gap:10px;
|
|
256
|
+
background:var(--uupm-bg-2); border:1px solid var(--card-line); border-radius:10px}
|
|
257
|
+
#dsh-plan .p-dialog-title{font-weight:600; font-size:12.5px; color:var(--ink)}
|
|
258
|
+
#dsh-plan .p-dialog-input{font:inherit; color:var(--ink); background:var(--uupm-bg-0);
|
|
259
|
+
border:1px solid var(--card-line); border-radius:6px; padding:7px 10px}
|
|
260
|
+
#dsh-plan .p-dialog-input:hover{border-color:color-mix(in srgb,var(--uupm-ink-1) 55%,transparent)}
|
|
261
|
+
#dsh-plan .p-dialog-input:focus-visible{outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent)}
|
|
262
|
+
#dsh-plan .p-dialog-err{min-height:1.2em; font-size:11px; color:var(--uupm-error)}
|
|
263
|
+
#dsh-plan .p-dialog-kind{display:grid; grid-template-columns:1fr 1fr; gap:4px; padding:3px;
|
|
264
|
+
background:var(--uupm-bg-0); border:1px solid var(--card-line); border-radius:8px}
|
|
265
|
+
#dsh-plan .p-dialog-kind button{font:inherit; color:var(--ink-muted); background:transparent; border:1px solid transparent;
|
|
266
|
+
border-radius:6px; padding:6px 10px; cursor:pointer}
|
|
267
|
+
#dsh-plan .p-dialog-kind button:hover{color:var(--ink); background:var(--uupm-wash-8)}
|
|
268
|
+
#dsh-plan .p-dialog-kind button[aria-checked=true]{color:var(--ink); font-weight:600; background:var(--uupm-wash-15);
|
|
269
|
+
border-color:var(--accent)}
|
|
270
|
+
#dsh-plan .p-dialog-kind button:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
271
|
+
#dsh-plan .p-dialog-hint{font-size:11px; color:var(--ink-muted); max-width:340px}
|
|
272
|
+
#dsh-plan .p-dialog-row{display:flex; gap:8px; justify-content:flex-end}
|
|
273
|
+
#dsh-plan .p-dialog-row button{background:transparent; color:var(--ink); border:1px solid var(--card-line);
|
|
274
|
+
border-radius:6px; padding:5px 12px; font:inherit; cursor:pointer}
|
|
275
|
+
#dsh-plan .p-dialog-row button:hover{border-color:var(--accent)}
|
|
276
|
+
#dsh-plan .p-dialog-row button:active{background:var(--uupm-wash-15)}
|
|
277
|
+
#dsh-plan .p-dialog-row button:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
278
|
+
|
|
279
|
+
#dsh-plan .p-notice-stack{position:absolute; bottom:52px; left:50%; transform:translateX(-50%); z-index:5;
|
|
280
|
+
display:grid; gap:6px; justify-items:center; pointer-events:none}
|
|
281
|
+
#dsh-plan .p-notice{max-width:60ch; padding:7px 12px; font-size:12px; color:var(--ink);
|
|
282
|
+
background:var(--toolbar-bg); border:1px solid var(--card-line); border-radius:8px; white-space:nowrap;
|
|
283
|
+
overflow:hidden; text-overflow:ellipsis}
|
|
284
|
+
#dsh-plan .p-notice.error{color:var(--error-ink); border-color:var(--uupm-error); background:var(--error-panel)}
|
|
285
|
+
|
|
286
|
+
/* Panel-slim migration: the unjoined-sessions join affordance on the toolbar. */
|
|
287
|
+
#dsh-plan .p-netbtn{color:var(--ink-muted)}
|
|
288
|
+
#dsh-plan .p-netbtn:not([disabled]){color:var(--ink)}
|
|
289
|
+
#dsh-plan .p-netmenu{max-height:240px; overflow:auto}
|
|
290
|
+
|
|
291
|
+
/* ── Node list drawer (network-membership-display): teamed nodes hold the
|
|
292
|
+
canvas; every other session is managed here, switched by host. ── */
|
|
293
|
+
#dsh-plan .p-nodebtn{color:var(--ink)}
|
|
294
|
+
#dsh-plan .p-nodelist{min-width:300px; max-width:340px; max-height:420px; overflow:auto; padding:6px}
|
|
295
|
+
#dsh-plan .p-nodelist-head{display:flex; align-items:center; justify-content:space-between; gap:8px;
|
|
296
|
+
padding:2px 4px 6px; border-bottom:1px solid var(--card-line)}
|
|
297
|
+
#dsh-plan .p-nodelist-title{font-size:12px; font-weight:600; color:var(--ink)}
|
|
298
|
+
#dsh-plan .p-nodesel{font:inherit; font-size:11.5px; color:var(--ink); background:var(--uupm-bg-0);
|
|
299
|
+
border:1px solid var(--card-line); border-radius:6px; padding:2px 6px; max-width:220px}
|
|
300
|
+
#dsh-plan .p-nodesel:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
301
|
+
#dsh-plan .p-nodelist-group{font-size:11px; color:var(--ink-muted); padding:8px 4px 3px;
|
|
302
|
+
display:flex; align-items:baseline; gap:8px}
|
|
303
|
+
#dsh-plan .p-nodelist-note{font-size:10px; color:var(--ink-muted); opacity:.8}
|
|
304
|
+
#dsh-plan .p-noderow{display:flex; align-items:center; gap:6px; padding:3px 4px; border-radius:6px;
|
|
305
|
+
font-size:12px; color:var(--ink)}
|
|
306
|
+
#dsh-plan .p-noderow:hover{background:var(--uupm-wash-8)}
|
|
307
|
+
#dsh-plan .p-nodedot{flex:none; width:7px; height:7px; border-radius:50%; background:var(--edge-live)}
|
|
308
|
+
#dsh-plan .p-nodedot.cold{background:var(--ink-muted)}
|
|
309
|
+
#dsh-plan .p-nodedot.off{background:transparent; border:1px solid var(--ink-muted)}
|
|
310
|
+
#dsh-plan .p-nodename{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
|
311
|
+
#dsh-plan .p-nonet{flex:none; font-size:10px; color:var(--uupm-warn); border:1px solid var(--uupm-warn);
|
|
312
|
+
border-radius:4px; padding:0 4px}
|
|
313
|
+
#dsh-plan .p-teamcount{flex:none; font-size:10px; color:var(--ink-muted); border:1px solid var(--card-line);
|
|
314
|
+
border-radius:4px; padding:0 4px}
|
|
315
|
+
#dsh-plan .p-listbtn{flex:none; background:transparent; color:var(--ink); border:1px solid var(--card-line);
|
|
316
|
+
border-radius:5px; padding:1px 7px; font:inherit; font-size:11px; cursor:pointer}
|
|
317
|
+
#dsh-plan .p-listbtn:hover{border-color:var(--card-line-hover); background:var(--uupm-wash-8)}
|
|
318
|
+
#dsh-plan .p-listbtn:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
|
|
319
|
+
#dsh-plan .p-nodelist-empty{padding:10px 4px; font-size:11.5px; color:var(--ink-muted)}
|
|
320
|
+
|
|
321
|
+
/* ── Frame resize handles (owner ruling: frames stretch/adjust) — eight
|
|
322
|
+
invisible hit zones that show the grip on hover. ── */
|
|
323
|
+
#dsh-plan .p-frame{position:absolute}
|
|
324
|
+
#dsh-plan .p-frame-handle{position:absolute; pointer-events:auto; width:10px; height:10px; z-index:2; opacity:0;
|
|
325
|
+
transition:opacity 120ms ease}
|
|
326
|
+
#dsh-plan .p-frame:hover .p-frame-handle{opacity:1}
|
|
327
|
+
#dsh-plan .p-frame-handle::after{content:''; position:absolute; inset:2px; background:var(--frame-ink);
|
|
328
|
+
border-radius:2px}
|
|
329
|
+
#dsh-plan .p-h-n{top:-5px; left:calc(50% - 12px); width:24px; height:8px; cursor:ns-resize}
|
|
330
|
+
#dsh-plan .p-h-s{bottom:-5px; left:calc(50% - 12px); width:24px; height:8px; cursor:ns-resize}
|
|
331
|
+
#dsh-plan .p-h-e{right:-5px; top:calc(50% - 12px); width:8px; height:24px; cursor:ew-resize}
|
|
332
|
+
#dsh-plan .p-h-w{left:-5px; top:calc(50% - 12px); width:8px; height:24px; cursor:ew-resize}
|
|
333
|
+
#dsh-plan .p-h-ne{top:-5px; right:-5px; cursor:nesw-resize}
|
|
334
|
+
#dsh-plan .p-h-nw{top:-5px; left:-5px; cursor:nwse-resize}
|
|
335
|
+
#dsh-plan .p-h-se{bottom:-5px; right:-5px; cursor:nwse-resize}
|
|
336
|
+
#dsh-plan .p-h-sw{bottom:-5px; left:-5px; cursor:nesw-resize}
|
|
337
|
+
#dsh-plan .p-h-ne::after, #dsh-plan .p-h-sw::after{transform:rotate(45deg)}
|
|
338
|
+
#dsh-plan .p-h-nw::after, #dsh-plan .p-h-se::after{transform:rotate(-45deg)}
|
|
339
|
+
#dsh-plan .p-frame.selected .p-frame-handle{opacity:1}
|
|
340
|
+
#dsh-plan .p-frame.selected{outline:1px solid var(--frame-ink)}
|