@nelsonlongxiang/dsh-open-a2a-net 0.5.14 → 0.6.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +243 -121
  2. package/README_zh.md +144 -84
  3. package/assets/nexusDist/assets/index-034h1cNc.js +3 -0
  4. package/assets/nexusDist/assets/index-PG9EieGX.css +1 -0
  5. package/assets/nexusDist/index.html +26 -0
  6. package/assets/stageDist/assets/index-Bj7S2pA1.css +1 -0
  7. package/assets/stageDist/assets/index-C-28k_o5.js +974 -0
  8. package/assets/stageDist/assets/interiors-CQGBjffT.png +0 -0
  9. package/assets/stageDist/assets/office-tileset-CHQT-uYL.png +0 -0
  10. package/assets/stageDist/index.html +13 -0
  11. package/lib/a2a-client.js +190 -13
  12. package/lib/canvas-store.js +218 -0
  13. package/lib/card.js +25 -0
  14. package/lib/client/A2aControl.js +45 -137
  15. package/lib/client/locales.js +16 -40
  16. package/lib/client.js +164 -467
  17. package/lib/client.js.map +1 -1
  18. package/lib/group-store.js +6 -0
  19. package/lib/idempotency-store.js +291 -0
  20. package/lib/index.js +4217 -259
  21. package/lib/joined-store.js +11 -0
  22. package/lib/layout-store.js +155 -0
  23. package/lib/peer-store.js +98 -13
  24. package/lib/receipt-ladder.js +35 -0
  25. package/lib/receipt.js +102 -0
  26. package/lib/self-suppress.js +62 -0
  27. package/lib/session-transcript.js +150 -0
  28. package/lib/skill/SKILL.md +77 -0
  29. package/lib/skill/references/discovery.md +38 -0
  30. package/lib/skill/references/membership.md +50 -0
  31. package/lib/skill/references/pitfalls.md +42 -0
  32. package/lib/skill/references/routing.md +43 -0
  33. package/lib/skill-registration.js +52 -0
  34. package/lib/stage-mount.js +32 -0
  35. package/lib/task-ledger.js +540 -0
  36. package/lib/team-store.js +122 -0
  37. package/lib/teams-bridge.js +18 -0
  38. package/lib/transport-caps.js +31 -0
  39. package/lib/types/a2a-client.d.ts +72 -1
  40. package/lib/types/canvas-store.d.ts +102 -0
  41. package/lib/types/client/A2aControl.d.ts +18 -28
  42. package/lib/types/client/locales.d.ts +1 -1
  43. package/lib/types/group-store.d.ts +6 -0
  44. package/lib/types/idempotency-store.d.ts +164 -0
  45. package/lib/types/index.d.ts +210 -6
  46. package/lib/types/joined-store.d.ts +9 -0
  47. package/lib/types/layout-store.d.ts +63 -0
  48. package/lib/types/peer-store.d.ts +45 -2
  49. package/lib/types/receipt-ladder.d.ts +25 -0
  50. package/lib/types/receipt.d.ts +51 -0
  51. package/lib/types/self-suppress.d.ts +41 -0
  52. package/lib/types/session-transcript.d.ts +37 -0
  53. package/lib/types/skill-registration.d.ts +3 -0
  54. package/lib/types/stage-mount.d.ts +29 -0
  55. package/lib/types/task-ledger.d.ts +308 -0
  56. package/lib/types/team-store.d.ts +55 -0
  57. package/lib/types/teams-bridge.d.ts +112 -0
  58. package/lib/types/transport-caps.d.ts +29 -0
  59. package/lib/types/types.d.ts +43 -0
  60. package/nexus-stage/package-lock.json +2262 -0
  61. package/nexus-stage/package.json +21 -0
  62. package/nexus-stage/scripts/__pycache__/mockhost.cpython-312.pyc +0 -0
  63. package/nexus-stage/scripts/mockhost.py +253 -0
  64. package/nexus-stage/src/canvas-ops.ts +175 -0
  65. package/nexus-stage/src/canvas-wire.ts +156 -0
  66. package/nexus-stage/src/edges.ts +72 -0
  67. package/nexus-stage/src/fault.ts +56 -0
  68. package/nexus-stage/src/federation.ts +234 -0
  69. package/nexus-stage/src/layout-doc.ts +143 -0
  70. package/nexus-stage/src/layout-wire.ts +158 -0
  71. package/nexus-stage/src/main.ts +361 -0
  72. package/nexus-stage/src/planning-menus.ts +352 -0
  73. package/nexus-stage/src/planning-nodelist.ts +294 -0
  74. package/nexus-stage/src/planning-types.ts +111 -0
  75. package/nexus-stage/src/planning-view.ts +1313 -0
  76. package/nexus-stage/src/planning.css +280 -0
  77. package/nexus-stage/src/seat.ts +35 -0
  78. package/nexus-stage/src/stage-name.ts +13 -0
  79. package/nexus-stage/src/tokens.ts +32 -0
  80. package/nexus-stage/src/viewport.ts +83 -0
  81. package/nexus-stage/src/workbench.css +267 -0
  82. package/nexus-stage/src/workbench.ts +1530 -0
  83. package/nexus-stage/src/world.ts +509 -0
  84. package/nexus-stage/tsconfig.json +25 -0
  85. package/nexus-stage/vite.config.ts +16 -0
  86. package/package.json +83 -22
@@ -0,0 +1,267 @@
1
+ /* A2A workbench styles (0.6.2 merged shell): the planning board is the stage,
2
+ the operational panels ride a collapsible rail, the inspector is an overlay
3
+ card. Responsive tiers are CSS-only:
4
+ - ≥1440px rail 340px, everything docked
5
+ - 1024–1439 rail 300px
6
+ - <1024 rail becomes a left drawer (☰), inspector becomes a bottom sheet
7
+ Dark default, light via prefers-color-scheme. Panels are data surfaces,
8
+ not decoration — rows are monospaced data lines. */
9
+ :root{
10
+ color-scheme:dark;
11
+ --n-bg:#060a12; --n-ink:#dde3f0; --n-ink-muted:#7a86a0; --n-panel:#0d1322;
12
+ --n-live:#4ade80; --n-cold:#7a86a0; --n-border:#223052; --n-act:#f59e0b;
13
+ --n-danger:#f87171; --n-accent:#9673f7; --n-rail-w:300px;
14
+ --n-canvas:#22d3ee; --n-line:var(--n-border);
15
+ --n-raised:#131b2e; --n-federal:#6366f1; --n-card-line:#5c6680;
16
+ --n-error-ink:#fecaca; --n-error-panel:#2a0d10f2; --n-shadow:rgba(0,0,0,.35);
17
+ --n-role-user:#7dd3fc; --n-role-user-bg:rgba(56,189,248,.16);
18
+ --n-role-assistant:#6ee7b7; --n-role-assistant-bg:rgba(52,211,153,.14);
19
+ }
20
+ @media (prefers-color-scheme: light){
21
+ :root{ --n-bg:#eef2fa; --n-ink:#1a2438; --n-ink-muted:#5a6580; --n-panel:#ffffff;
22
+ --n-live:#157a37; --n-border:#c6d0e6; --n-act:#a84d08;
23
+ --n-danger:#b91c1c; --n-accent:#6d28d9;
24
+ --n-cold:#636c81; --n-canvas:#0e7490;
25
+ --n-raised:#ffffff; --n-federal:#4f46e5; --n-card-line:#8a95ae;
26
+ --n-error-ink:#b91c1c; --n-error-panel:#fef2f2f2; --n-shadow:rgba(26,36,56,.16);
27
+ --n-role-user:#075985; --n-role-user-bg:rgba(14,116,144,.12);
28
+ --n-role-assistant:#065f46; --n-role-assistant-bg:rgba(5,150,105,.12); }
29
+ }
30
+ @media (min-width:1440px){ :root{ --n-rail-w:340px } }
31
+ html,body,#app{height:100%;margin:0}
32
+ body{background:var(--n-bg);color:var(--n-ink);font:13px/1.45 system-ui,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif}
33
+
34
+ .wb{display:flex;flex-direction:column;height:100%}
35
+ .wb-header{display:flex;align-items:center;gap:12px;padding:8px 14px;border-bottom:1px solid var(--n-border);background:var(--n-panel)}
36
+ .wb-title{display:flex;align-items:center;gap:10px;font-weight:600;font-size:14px;white-space:nowrap}
37
+ .wb-badge{font-size:11px;font-weight:400;color:var(--n-ink-muted);border:1px solid var(--n-border);border-radius:99px;padding:1px 8px}
38
+ .wb-header-stats{display:flex;gap:16px;font-size:12px;color:var(--n-ink-muted);flex-wrap:wrap;min-width:0}
39
+ .wb-header-stats .wb-kv{display:flex;gap:6px}
40
+ .wb-header-stats .wb-kv-k{color:var(--n-ink-muted)}
41
+ .wb-header-stats .wb-kv-v{color:var(--n-ink)}
42
+ /* Header verdict: exceptions only (results-first). Quiet when healthy. */
43
+ .wb-header-ok{color:var(--n-ink-muted)}
44
+ .wb-alert{border:1px solid currentColor;border-radius:99px;padding:0 9px;line-height:20px;white-space:nowrap;cursor:help}
45
+ .wb-alert-danger{color:var(--n-danger)}
46
+ .wb-alert-warn{color:var(--n-act)}
47
+ .wb-forensics{font-family:ui-monospace,Consolas,monospace;font-size:11px}
48
+ .wb-icon-btn{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:8px;
49
+ width:30px;height:30px;display:none;align-items:center;justify-content:center;font:inherit;font-size:14px;
50
+ cursor:pointer;flex:none}
51
+ .wb-icon-btn:hover{border-color:var(--n-accent)}
52
+ .wb-menu{margin-left:0}
53
+ .wb-rail-toggle{margin-left:auto}
54
+ .wb.is-rail-collapsed .wb-rail{display:none}
55
+
56
+ .wb-body{position:relative;display:grid;grid-template-columns:minmax(0,var(--n-rail-w)) minmax(0,1fr);flex:1;min-height:0}
57
+
58
+ /* ── Rail (directory + operational panels in canvas mode) ── */
59
+ .wb-rail{border-right:1px solid var(--n-border);overflow-y:auto;min-width:0;background:color-mix(in srgb,var(--n-panel) 60%,var(--n-bg))}
60
+ .wb-sec{border-bottom:1px solid color-mix(in srgb,var(--n-border) 60%,transparent)}
61
+ .wb-sec-head{display:flex;justify-content:space-between;align-items:center;gap:8px;width:100%;
62
+ background:none;border:none;color:var(--n-ink);font:inherit;font-weight:600;font-size:12.5px;
63
+ padding:8px 12px;cursor:pointer;text-transform:uppercase;letter-spacing:.05em}
64
+ .wb-sec-head:hover{color:var(--n-accent)}
65
+ .wb-sec-count{font-weight:400;font-size:11px;color:var(--n-ink-muted)}
66
+ .wb-sec.is-collapsed .wb-sec-body{display:none}
67
+ .wb-sec-body{padding:2px 10px 10px}
68
+ /* Data mode: the three panels move to the stage — their rail seats hide. */
69
+ .wb[data-mode="data"] .wb-sec[data-sec="ledger"],
70
+ .wb[data-mode="data"] .wb-sec[data-sec="activity"],
71
+ .wb[data-mode="data"] .wb-sec[data-sec="plan"]{display:none}
72
+
73
+ .wb-side-head{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--n-ink-muted);margin:10px 2px 4px}
74
+ .wb-item{display:flex;gap:7px;align-items:center;width:100%;text-align:left;background:none;border:none;
75
+ color:var(--n-ink);font:inherit;padding:3px 6px;border-radius:6px;cursor:pointer}
76
+ .wb-item:hover{background:color-mix(in srgb,var(--n-accent) 14%,transparent)}
77
+ .wb-dot{font-size:10px}
78
+ .wb-dot-live{color:var(--n-live)} .wb-dot-cold{color:var(--n-cold)} .wb-dot-canvas{color:var(--n-canvas)}
79
+ .wb-dot-peer{color:var(--n-accent)} .wb-dot-remote{color:var(--n-act)}
80
+ .wb-item-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
81
+
82
+ /* ── Directory toolbar: unified search + category filters (0.6.6) ── */
83
+ .wb-dir-tools{display:flex;flex-direction:column;gap:6px;padding:8px 6px 4px}
84
+ .wb-search{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);
85
+ border-radius:6px;padding:4px 8px;font:inherit;font-size:12.5px;min-width:0}
86
+ .wb-search:focus{outline:1px solid var(--n-accent)}
87
+ .wb-filters{display:flex;flex-wrap:wrap;gap:4px}
88
+ .wb-filter{background:none;border:1px solid var(--n-border);color:var(--n-ink-muted);
89
+ border-radius:99px;padding:1px 9px;font:inherit;font-size:11.5px;cursor:pointer}
90
+ .wb-filter:hover{border-color:var(--n-accent);color:var(--n-ink)}
91
+ .wb-filter.is-active{border-color:var(--n-accent);color:var(--n-ink);
92
+ background:color-mix(in srgb,var(--n-accent) 16%,transparent)}
93
+ .wb-item-badge{flex:none;font-size:10.5px;color:var(--n-canvas);border:1px solid color-mix(in srgb,var(--n-canvas) 45%,transparent);
94
+ border-radius:99px;padding:0 6px;line-height:17px;white-space:nowrap}
95
+ /* 0.6.10: .wb-item-open (the ↗ jump affordance) removed by ruling —
96
+ 禁止任何跳转,全部使用响应式布局. */
97
+ .wb-item-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:46%}
98
+
99
+ /* ── Canvas member management (inspector, 0.6.6) ── */
100
+ .wb-member-row{display:flex;align-items:center;gap:8px;padding:3px 2px;border-radius:6px}
101
+ .wb-member-row:hover{background:color-mix(in srgb,var(--n-accent) 10%,transparent)}
102
+ .wb-member-dot{flex:none;font-size:11px;color:var(--n-ink-muted);min-width:44px}
103
+ .wb-member-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
104
+ .wb-member-remove,.wb-member-submit{background:none;border:1px solid var(--n-border);color:var(--n-ink);
105
+ border-radius:6px;padding:1px 8px;font:inherit;font-size:11.5px;cursor:pointer;flex:none}
106
+ .wb-member-remove:hover:not(:disabled),.wb-member-submit:hover:not(:disabled){border-color:var(--n-danger)}
107
+ .wb-member-submit:hover:not(:disabled){border-color:var(--n-accent)}
108
+ .wb-member-add{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
109
+ .wb-member-pick,.wb-member-manual{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);
110
+ border-radius:6px;padding:3px 8px;font:inherit;font-size:12px;min-width:0}
111
+ .wb-member-pick{flex:1 1 150px}
112
+ .wb-member-manual{flex:1 1 130px}
113
+ .wb-member-pick:focus,.wb-member-manual:focus{outline:1px solid var(--n-accent)}
114
+ .wb-hint{margin-top:10px;font-size:11px;color:var(--n-ink-muted);line-height:1.5}
115
+ /* Quick dispatch (0.6.9): one human message to a routing team. */
116
+ .wb-dispatch{margin-top:12px;border-top:1px dashed var(--n-border);padding-top:8px}
117
+ .wb-dispatch-form{display:flex;flex-direction:column;gap:6px;margin-top:6px}
118
+ .wb-dispatch-text{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);
119
+ border-radius:6px;padding:5px 8px;font:inherit;font-size:12px;min-height:52px;resize:vertical}
120
+ .wb-dispatch-text:focus{outline:1px solid var(--n-accent)}
121
+ .wb-dispatch-submit{align-self:flex-end;background:none;border:1px solid var(--n-border);color:var(--n-ink);
122
+ border-radius:6px;padding:2px 14px;font:inherit;font-size:11.5px;cursor:pointer}
123
+ .wb-dispatch-submit:hover:not(:disabled){border-color:var(--n-accent)}
124
+ .wb-dispatch-note{font-size:11px;color:var(--n-ink-muted);line-height:1.4;min-height:0}
125
+ /* 0.6.11 inline transcript: read-only tail of a local session's own log. */
126
+ .wb-transcript{display:flex;flex-direction:column;gap:6px}
127
+ .wb-transcript-title{font-size:12px;color:var(--n-ink-muted)}
128
+ .wb-transcript-body.is-folded{display:none}
129
+ .wb-transcript-refresh{margin-left:auto;font-size:11px;padding:1px 8px;border-radius:999px;border:1px solid var(--n-line);background:transparent;color:var(--n-ink-muted);cursor:pointer}
130
+ .wb-transcript-body{display:flex;flex-direction:column;gap:4px;max-height:220px;overflow-y:auto}
131
+ .wb-transcript-row{display:flex;gap:6px;align-items:flex-start;font-size:12px;line-height:1.45}
132
+ .wb-transcript-role{flex:0 0 auto;font-size:10px;padding:0 5px;border-radius:999px;margin-top:2px}
133
+ .wb-transcript-user .wb-transcript-role{background:var(--n-role-user-bg);color:var(--n-role-user)}
134
+ .wb-transcript-assistant .wb-transcript-role{background:var(--n-role-assistant-bg);color:var(--n-role-assistant)}
135
+ .wb-transcript-text{flex:1 1 auto;min-width:0;color:var(--n-ink);word-break:break-word}
136
+
137
+ /* ── Stage: board (canvas mode) or the data stack (data mode) ── */
138
+ .wb-stage{position:relative;min-width:0;min-height:0;display:flex;flex-direction:column}
139
+ .wb-stage-board{position:absolute;inset:0;overflow:hidden}
140
+ .wb-stage-board.is-hidden{display:none}
141
+ .wb-data{display:flex;flex-direction:column;gap:14px;padding:10px 14px;overflow-y:auto;min-height:0}
142
+ .wb-data.is-hidden{display:none}
143
+
144
+ .wb-pane-head{font-size:12px;color:var(--n-ink-muted);margin:4px 0 8px}
145
+ .wb-pane-subhead{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--n-ink-muted);margin:12px 0 6px}
146
+ .wb-table,.wb-row{display:flex;gap:10px;align-items:baseline}
147
+ .wb-table{flex-direction:column;gap:2px}
148
+ .wb-row{font-family:ui-monospace,Consolas,monospace;font-size:12px;background:color-mix(in srgb,var(--n-panel) 55%,transparent);
149
+ border:1px solid var(--n-border);border-radius:6px;padding:3px 8px;flex-wrap:wrap}
150
+ .wb-row-id{min-width:130px}
151
+ .wb-row-team{color:var(--n-accent);min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
152
+ .wb-row-meta{color:var(--n-ink-muted)}
153
+ /* Owner signal (2026-10-21): the ledger is a RESULTS face — brief-first
154
+ rows, exception-driven color, quiet normals. */
155
+ .wb-row-result{flex-direction:column;align-items:stretch;gap:2px;flex-wrap:nowrap}
156
+ .wb-row-head{color:var(--n-ink);font-size:12.5px;font-family:Avenir Next,Segoe UI Variable,Segoe UI,sans-serif;
157
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
158
+ .wb-row-meta-line{color:var(--n-ink-muted);font-family:ui-monospace,Consolas,monospace;font-size:11px;
159
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
160
+ .wb-row-result:not(.wb-row-alert) .wb-row-head{color:var(--n-ink-muted)}
161
+ .wb-row-alert{border-color:var(--n-danger)}
162
+ .wb-row-alert .wb-row-head{color:var(--n-danger)}
163
+ /* The dispatch brief is the row's only human-readable payload — give it the
164
+ remaining width and clip rather than wrapping the table into unreadability
165
+ (full text stays in the title tooltip). */
166
+ .wb-row-brief{flex:1 1 160px;min-width:0;color:var(--n-ink);overflow:hidden;
167
+ text-overflow:ellipsis;white-space:nowrap}
168
+ .wb-row-brief:empty{flex:0 0 0;display:none}
169
+ .wb-row-badges{color:var(--n-live)}
170
+ .wb-row-dir{min-width:16px}
171
+ .wb-row-dir.is-fail{color:var(--n-danger)}
172
+ .wb-btn{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;
173
+ padding:2px 10px;font:inherit;font-size:12px;cursor:pointer;margin-left:auto}
174
+ .wb-btn:hover:not(:disabled){border-color:var(--n-accent)}
175
+ .wb-btn:disabled{opacity:.5;cursor:default}
176
+ .wb-btn-primary{border-color:var(--n-accent);color:var(--n-ink)}
177
+ .wb-action{display:flex;gap:10px;align-items:baseline;font-size:12.5px;padding:5px 8px;border-radius:6px;
178
+ border:1px solid var(--n-border);margin-bottom:4px}
179
+ .wb-action-high{border-color:var(--n-danger)}
180
+ .wb-action-text{flex:1}
181
+ .wb-draft{display:flex;flex-direction:column;gap:8px;max-width:560px;margin-top:6px}
182
+ .wb-select,.wb-textarea{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);
183
+ border-radius:8px;padding:6px 9px;font:inherit}
184
+ .wb-textarea{resize:vertical}
185
+ .wb-select:focus,.wb-textarea:focus{outline:1px solid var(--n-accent)}
186
+
187
+ /* ── Inspector: overlay card on the stage; bottom sheet when narrow. ── */
188
+ .wb-inspector{position:absolute;top:8px;right:8px;width:280px;max-height:calc(100% - 16px);
189
+ overflow-y:auto;background:var(--n-panel);border:1px solid var(--n-border);border-radius:10px;
190
+ padding:10px;z-index:20;box-shadow:0 8px 24px var(--n-shadow);display:none}
191
+ .wb-inspector.is-open{display:block}
192
+ .wb-inspector-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px}
193
+ .wb-inspector-title{font-weight:600;font-size:12.5px}
194
+ .wb-inspector .wb-icon-btn{display:inline-flex;width:24px;height:24px;font-size:12px}
195
+ .wb-card{display:flex;flex-direction:column;gap:6px}
196
+ .wb-kv{display:flex;gap:8px;font-size:12px}
197
+ .wb-kv-k{color:var(--n-ink-muted);min-width:58px;flex:none}
198
+ .wb-kv-v{word-break:break-all}
199
+ .wb-muted{color:var(--n-ink-muted)}
200
+
201
+ /* ── Node chat drawer (0.6.13): right-side conversation face. ── */
202
+ .wb-chat{position:absolute;top:8px;right:8px;bottom:8px;width:360px;max-width:calc(100% - 16px);
203
+ display:flex;flex-direction:column;background:var(--n-panel);border:1px solid var(--n-border);
204
+ border-radius:10px;z-index:22;box-shadow:0 8px 24px var(--n-shadow);
205
+ transform:translateX(calc(100% + 12px));transition:transform .18s ease;pointer-events:none}
206
+ .wb-chat.is-open{transform:translateX(0);pointer-events:auto}
207
+ .wb-chat-head{display:flex;align-items:center;gap:8px;padding:10px 10px 8px;border-bottom:1px solid var(--n-border)}
208
+ .wb-chat-dot{flex:none;font-size:11px}
209
+ .wb-chat-dot.is-live{color:var(--n-accent)}
210
+ .wb-chat-dot.is-cold{color:var(--n-ink-muted)}
211
+ .wb-chat-dot.is-peer{color:var(--n-act)}
212
+ .wb-chat-title{font-weight:600;font-size:13px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
213
+ .wb-chat-sub{flex:1 1 auto;min-width:0;font-size:11px;color:var(--n-ink-muted);
214
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
215
+ .wb-chat .wb-icon-btn{display:inline-flex;width:24px;height:24px;font-size:12px;flex:none}
216
+ .wb-chat-body{flex:1 1 auto;overflow-y:auto;padding:10px;display:flex;flex-direction:column;gap:10px}
217
+ .wb-chat-note{font-size:12px;color:var(--n-ink-muted);border:1px dashed var(--n-border);
218
+ border-radius:8px;padding:8px 10px}
219
+
220
+ /* ── Ledger density: stat strip, age histogram, load rows ── */
221
+ .wb-stats{display:flex;gap:8px;flex-wrap:wrap;margin:2px 0 10px}
222
+ .wb-stat{display:inline-flex;align-items:baseline;gap:6px;padding:4px 10px;border-radius:8px;
223
+ border:1px solid var(--n-border);background:color-mix(in srgb,var(--n-panel) 70%,transparent);cursor:help}
224
+ .wb-stat-k{font-size:11px;color:var(--n-ink-muted)}
225
+ .wb-stat-v{font-family:ui-monospace,Consolas,monospace;font-size:14px;font-weight:600}
226
+ .wb-stat-warn{border-color:var(--n-act)}
227
+ .wb-stat-warn .wb-stat-v{color:var(--n-act)}
228
+ .wb-stat-danger{border-color:var(--n-danger)}
229
+ .wb-stat-danger .wb-stat-v{color:var(--n-danger)}
230
+ .wb-hist{display:flex;flex-direction:column;gap:3px;margin:2px 0 8px;max-width:420px}
231
+ .wb-bar-row{display:flex;align-items:center;gap:8px;font-size:11px}
232
+ .wb-bar-k{color:var(--n-ink-muted);min-width:52px;flex:none;text-align:right}
233
+ .wb-bar-track{flex:1;height:9px;border-radius:4px;overflow:hidden;
234
+ background:color-mix(in srgb,var(--n-border) 55%,transparent)}
235
+ .wb-bar-fill{display:block;height:100%;border-radius:4px;background:var(--n-accent)}
236
+ .wb-bar-v{font-family:ui-monospace,Consolas,monospace;color:var(--n-ink-muted);min-width:28px}
237
+
238
+ /* The one fault badge (planning.css carried a second, conflicting copy —
239
+ the cascade mixed the two). Honesty surface: always above the board. */
240
+ .nexus-fault{display:none;position:fixed;top:10px;right:12px;z-index:50;max-width:420px;
241
+ font:12px/1.5 ui-monospace,Consolas,monospace;color:var(--n-error-ink);background:var(--n-error-panel);
242
+ border:1px solid var(--n-danger);border-radius:8px;padding:6px 10px;pointer-events:none}
243
+
244
+ /* ── Responsive tiers ── */
245
+ @media (max-width:1023px){
246
+ .wb-menu{display:inline-flex}
247
+ .wb-rail-toggle{display:none}
248
+ .wb-body{grid-template-columns:minmax(0,1fr)}
249
+ .wb-rail{position:fixed;left:0;top:0;bottom:0;width:min(86vw,320px);z-index:40;
250
+ background:var(--n-panel);border-right:1px solid var(--n-border);
251
+ transform:translateX(-102%);transition:transform .18s ease;box-shadow:8px 0 24px var(--n-shadow)}
252
+ .wb.is-rail-open .wb-rail{transform:translateX(0)}
253
+ .wb-inspector{left:8px;right:8px;width:auto;top:auto;bottom:8px;max-height:45%}
254
+ .wb-chat{left:8px;right:8px;width:auto;top:auto;bottom:8px;max-height:70%;
255
+ transform:translateY(102%)}
256
+ .wb-chat.is-open{transform:translateY(0)}
257
+ }
258
+ @media (pointer:coarse){
259
+ .wb-filter,.wb-item,.wb-sec-head{min-height:36px}
260
+ .wb-icon-btn,.wb-inspector .wb-icon-btn,.wb-chat .wb-icon-btn{width:36px;height:36px}
261
+ }
262
+ @media (max-width:680px){
263
+ .wb-header{flex-wrap:wrap;row-gap:4px}
264
+ .wb-header-stats{order:3;width:100%}
265
+ .wb-row-team{min-width:0;flex:1 1 auto}
266
+ .wb-data{padding:8px}
267
+ }