agent-embassy 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/CONTRIBUTING.md +122 -0
  3. package/LICENSE +21 -0
  4. package/README.md +185 -0
  5. package/README.zh-CN.md +185 -0
  6. package/SECURITY.md +224 -0
  7. package/assets/live-dashboard/app.css +1610 -0
  8. package/assets/mark-seal.svg +7 -0
  9. package/assets/mark.svg +7 -0
  10. package/assets/social-preview.png +0 -0
  11. package/assets/vendor/react/LICENSE +21 -0
  12. package/assets/vendor/react/react-dom.production.min.js +267 -0
  13. package/assets/vendor/react/react.production.min.js +31 -0
  14. package/dist/src/errors.d.ts +5 -0
  15. package/dist/src/errors.js +11 -0
  16. package/dist/src/errors.js.map +1 -0
  17. package/dist/src/gateway/claude-compatibility-scratch.d.ts +18 -0
  18. package/dist/src/gateway/claude-compatibility-scratch.js +158 -0
  19. package/dist/src/gateway/claude-compatibility-scratch.js.map +1 -0
  20. package/dist/src/gateway/claude-helper-client.d.ts +43 -0
  21. package/dist/src/gateway/claude-helper-client.js +212 -0
  22. package/dist/src/gateway/claude-helper-client.js.map +1 -0
  23. package/dist/src/gateway/claude-helper-protocol.d.ts +172 -0
  24. package/dist/src/gateway/claude-helper-protocol.js +373 -0
  25. package/dist/src/gateway/claude-helper-protocol.js.map +1 -0
  26. package/dist/src/gateway/claude-helper-supervisor.d.ts +74 -0
  27. package/dist/src/gateway/claude-helper-supervisor.js +497 -0
  28. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -0
  29. package/dist/src/gateway/claude-helper.d.ts +1 -0
  30. package/dist/src/gateway/claude-helper.js +269 -0
  31. package/dist/src/gateway/claude-helper.js.map +1 -0
  32. package/dist/src/gateway/claude-peer.d.ts +273 -0
  33. package/dist/src/gateway/claude-peer.js +2359 -0
  34. package/dist/src/gateway/claude-peer.js.map +1 -0
  35. package/dist/src/gateway/claude-runtime.d.ts +40 -0
  36. package/dist/src/gateway/claude-runtime.js +302 -0
  37. package/dist/src/gateway/claude-runtime.js.map +1 -0
  38. package/dist/src/gateway/cli-copy.d.ts +8 -0
  39. package/dist/src/gateway/cli-copy.en.d.ts +13 -0
  40. package/dist/src/gateway/cli-copy.en.js +43 -0
  41. package/dist/src/gateway/cli-copy.en.js.map +1 -0
  42. package/dist/src/gateway/cli-copy.js +19 -0
  43. package/dist/src/gateway/cli-copy.js.map +1 -0
  44. package/dist/src/gateway/cli-copy.zh-CN.d.ts +13 -0
  45. package/dist/src/gateway/cli-copy.zh-CN.js +43 -0
  46. package/dist/src/gateway/cli-copy.zh-CN.js.map +1 -0
  47. package/dist/src/gateway/cli.d.ts +44 -0
  48. package/dist/src/gateway/cli.js +969 -0
  49. package/dist/src/gateway/cli.js.map +1 -0
  50. package/dist/src/gateway/codex-app-server.d.ts +310 -0
  51. package/dist/src/gateway/codex-app-server.js +1746 -0
  52. package/dist/src/gateway/codex-app-server.js.map +1 -0
  53. package/dist/src/gateway/codex-local-transport.d.ts +81 -0
  54. package/dist/src/gateway/codex-local-transport.js +617 -0
  55. package/dist/src/gateway/codex-local-transport.js.map +1 -0
  56. package/dist/src/gateway/codex-registration-generation.d.ts +5 -0
  57. package/dist/src/gateway/codex-registration-generation.js +19 -0
  58. package/dist/src/gateway/codex-registration-generation.js.map +1 -0
  59. package/dist/src/gateway/codex-registration-succession.d.ts +209 -0
  60. package/dist/src/gateway/codex-registration-succession.js +588 -0
  61. package/dist/src/gateway/codex-registration-succession.js.map +1 -0
  62. package/dist/src/gateway/compatibility.d.ts +70 -0
  63. package/dist/src/gateway/compatibility.js +252 -0
  64. package/dist/src/gateway/compatibility.js.map +1 -0
  65. package/dist/src/gateway/config.d.ts +24 -0
  66. package/dist/src/gateway/config.js +130 -0
  67. package/dist/src/gateway/config.js.map +1 -0
  68. package/dist/src/gateway/control.d.ts +308 -0
  69. package/dist/src/gateway/control.js +1573 -0
  70. package/dist/src/gateway/control.js.map +1 -0
  71. package/dist/src/gateway/dashboard-copy.d.ts +7 -0
  72. package/dist/src/gateway/dashboard-copy.en.d.ts +506 -0
  73. package/dist/src/gateway/dashboard-copy.en.js +507 -0
  74. package/dist/src/gateway/dashboard-copy.en.js.map +1 -0
  75. package/dist/src/gateway/dashboard-copy.js +516 -0
  76. package/dist/src/gateway/dashboard-copy.js.map +1 -0
  77. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +506 -0
  78. package/dist/src/gateway/dashboard-copy.zh-CN.js +507 -0
  79. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +1 -0
  80. package/dist/src/gateway/dashboard-model.d.ts +207 -0
  81. package/dist/src/gateway/dashboard-model.js +720 -0
  82. package/dist/src/gateway/dashboard-model.js.map +1 -0
  83. package/dist/src/gateway/dashboard.d.ts +26 -0
  84. package/dist/src/gateway/dashboard.js +941 -0
  85. package/dist/src/gateway/dashboard.js.map +1 -0
  86. package/dist/src/gateway/delivery-machine.d.ts +235 -0
  87. package/dist/src/gateway/delivery-machine.js +540 -0
  88. package/dist/src/gateway/delivery-machine.js.map +1 -0
  89. package/dist/src/gateway/instance-lease.d.ts +21 -0
  90. package/dist/src/gateway/instance-lease.js +549 -0
  91. package/dist/src/gateway/instance-lease.js.map +1 -0
  92. package/dist/src/gateway/live-dashboard-app/app.js +2914 -0
  93. package/dist/src/gateway/live-dashboard-assets.d.ts +10 -0
  94. package/dist/src/gateway/live-dashboard-assets.js +73 -0
  95. package/dist/src/gateway/live-dashboard-assets.js.map +1 -0
  96. package/dist/src/gateway/live-dashboard-bootstrap.d.ts +36 -0
  97. package/dist/src/gateway/live-dashboard-bootstrap.js +176 -0
  98. package/dist/src/gateway/live-dashboard-bootstrap.js.map +1 -0
  99. package/dist/src/gateway/live-dashboard-command.d.ts +54 -0
  100. package/dist/src/gateway/live-dashboard-command.js +324 -0
  101. package/dist/src/gateway/live-dashboard-command.js.map +1 -0
  102. package/dist/src/gateway/live-dashboard-http.d.ts +41 -0
  103. package/dist/src/gateway/live-dashboard-http.js +445 -0
  104. package/dist/src/gateway/live-dashboard-http.js.map +1 -0
  105. package/dist/src/gateway/live-dashboard-protocol.d.ts +38 -0
  106. package/dist/src/gateway/live-dashboard-protocol.js +156 -0
  107. package/dist/src/gateway/live-dashboard-protocol.js.map +1 -0
  108. package/dist/src/gateway/live-dashboard-server.d.ts +33 -0
  109. package/dist/src/gateway/live-dashboard-server.js +130 -0
  110. package/dist/src/gateway/live-dashboard-server.js.map +1 -0
  111. package/dist/src/gateway/live-dashboard-stream.d.ts +46 -0
  112. package/dist/src/gateway/live-dashboard-stream.js +233 -0
  113. package/dist/src/gateway/live-dashboard-stream.js.map +1 -0
  114. package/dist/src/gateway/live-dashboard.d.ts +31 -0
  115. package/dist/src/gateway/live-dashboard.js +190 -0
  116. package/dist/src/gateway/live-dashboard.js.map +1 -0
  117. package/dist/src/gateway/locale.d.ts +4 -0
  118. package/dist/src/gateway/locale.js +10 -0
  119. package/dist/src/gateway/locale.js.map +1 -0
  120. package/dist/src/gateway/progress-watch-machine.d.ts +97 -0
  121. package/dist/src/gateway/progress-watch-machine.js +172 -0
  122. package/dist/src/gateway/progress-watch-machine.js.map +1 -0
  123. package/dist/src/gateway/providers.d.ts +287 -0
  124. package/dist/src/gateway/providers.js +2451 -0
  125. package/dist/src/gateway/providers.js.map +1 -0
  126. package/dist/src/gateway/server.d.ts +57 -0
  127. package/dist/src/gateway/server.js +264 -0
  128. package/dist/src/gateway/server.js.map +1 -0
  129. package/dist/src/gateway/service.d.ts +449 -0
  130. package/dist/src/gateway/service.js +4831 -0
  131. package/dist/src/gateway/service.js.map +1 -0
  132. package/dist/src/gateway/store.d.ts +340 -0
  133. package/dist/src/gateway/store.js +4047 -0
  134. package/dist/src/gateway/store.js.map +1 -0
  135. package/dist/src/gateway/types.d.ts +514 -0
  136. package/dist/src/gateway/types.js +414 -0
  137. package/dist/src/gateway/types.js.map +1 -0
  138. package/dist/src/mutex.d.ts +4 -0
  139. package/dist/src/mutex.js +23 -0
  140. package/dist/src/mutex.js.map +1 -0
  141. package/docs/DESIGN.md +134 -0
  142. package/docs/GATEWAY-ARCHITECTURE.md +858 -0
  143. package/package.json +80 -0
  144. package/skills/embassy-peer/SKILL.md +198 -0
  145. package/skills/embassy-peer/agents/openai.yaml +4 -0
@@ -0,0 +1,1610 @@
1
+ /* ==========================================================================
2
+ Embassy live dashboard — app.css
3
+ Served at the instance-scoped app.css route. Self-contained by contract:
4
+ zero imports, zero font files, zero asset references, zero external hosts.
5
+ Section order follows integration spec section 5.
6
+ 1 Tokens · 2 Base · 3 Layout · 4 Chips · 5 Components
7
+ 6 Tooltip · 7 Responsive · 8 Reduced motion · 9 Forced colors
8
+ ========================================================================== */
9
+
10
+ /* ==========================================================================
11
+ 1. TOKENS (spec §5.1) — light only, system fonts only
12
+ ========================================================================== */
13
+
14
+ :root {
15
+ color-scheme: light;
16
+
17
+ /* Surfaces */
18
+ --canvas: #ffffff;
19
+ --soft-stone: #eeece7;
20
+ --pale-blue: #f1f5ff;
21
+ --pale-green: #edfce9;
22
+
23
+ /* Ink & rules */
24
+ --ink: #212121;
25
+ --body-muted: #616161;
26
+ --slate: #75758a;
27
+ --muted: #93939f;
28
+ --hairline: #d9d9dd;
29
+ --border-light: #e5e7eb;
30
+ --card-border: #f2f2f2;
31
+
32
+ /* Accents */
33
+ --cohere-black: #000000;
34
+ --dark-navy: #071829;
35
+ --deep-green: #003c33;
36
+ --action-blue: #1863dc;
37
+ --coral: #ff7759;
38
+ --coral-soft: #ffad9b;
39
+ --error: #b30000;
40
+ --primary: #17171c;
41
+ --on-primary: #ffffff;
42
+ --on-dark: #ffffff;
43
+ --focus-blue: #4c6ee6;
44
+ --form-focus: #9b60aa;
45
+
46
+ /* Chip tints (spec §3.1 — new) */
47
+ --coral-tint: rgba(255, 119, 89, .12);
48
+ --coral-deep: #9a3a20;
49
+ /* Prototype's claude-side accent (RoutesTab CORAL, oklch ≈ #d95737). */
50
+ --coral-accent: oklch(0.62 0.17 35);
51
+ /* Canonical coral washes: .10 topo-chip highlight, .06 warning banner. */
52
+ --coral-wash-hl: rgba(255, 119, 89, .10);
53
+ --coral-wash-soft: rgba(255, 119, 89, .06);
54
+ --purple-tint: rgba(155, 96, 170, .10);
55
+ --purple-deep: #7d4390;
56
+ --error-tint: rgba(179, 0, 0, .07);
57
+
58
+ /* Semantic aliases (tokens/colors.css) — the retheming seam. */
59
+ --surface-page: var(--canvas);
60
+ --surface-card: var(--canvas);
61
+ --surface-warm: var(--soft-stone);
62
+ --surface-band-green: var(--deep-green);
63
+ --surface-band-navy: var(--dark-navy);
64
+ --surface-footer: var(--primary);
65
+ --text-body: var(--ink);
66
+ --text-muted: var(--body-muted);
67
+ --text-meta: var(--muted);
68
+ --rule: var(--hairline);
69
+ --link: var(--action-blue);
70
+ --cta-bg: var(--primary);
71
+ --cta-text: var(--on-primary);
72
+
73
+ /* Radii */
74
+ --radius-xs: 4px;
75
+ --radius-sm: 8px;
76
+ --radius-md: 16px;
77
+ --radius-lg: 22px;
78
+ --radius-xl: 30px;
79
+ --radius-pill: 32px;
80
+ --radius-full: 9999px;
81
+
82
+ /* Spacing scale (tokens/spacing.css) */
83
+ --space-xxs: 2px;
84
+ --space-xs: 6px;
85
+ --space-sm: 8px;
86
+ --space-md: 12px;
87
+ --space-lg: 16px;
88
+ --space-xl: 24px;
89
+ --space-xxl: 32px;
90
+ --space-section: 80px;
91
+
92
+ /* Type */
93
+ --type-body-size: 16px;
94
+ --type-body-lh: 1.5;
95
+ --type-feature-size: 24px;
96
+ --type-feature-lh: 1.3;
97
+ --type-caption-size: 14px;
98
+ --type-caption-lh: 1.4;
99
+ --type-button-size: 14px;
100
+ --type-button-lh: 1.71;
101
+ --type-button-weight: 500;
102
+ --type-mono-size: 14px;
103
+ --type-mono-lh: 1.4;
104
+ --type-mono-ls: 0.28px;
105
+ --type-micro-size: 12px;
106
+ --type-micro-lh: 1.4;
107
+ --mono-ls: var(--type-mono-ls);
108
+ --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
109
+ --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
110
+ --font-display: "Space Grotesk", var(--font-body);
111
+ }
112
+
113
+ /* ==========================================================================
114
+ 2. BASE
115
+ ========================================================================== */
116
+
117
+ *,
118
+ *::before,
119
+ *::after { box-sizing: border-box; }
120
+
121
+ body {
122
+ margin: 0;
123
+ background: var(--surface-page);
124
+ color: var(--text-body);
125
+ font-family: var(--font-body);
126
+ font-size: var(--type-body-size);
127
+ line-height: var(--type-body-lh);
128
+ -webkit-font-smoothing: antialiased;
129
+ }
130
+
131
+ h1, h2, h3, h4 { font-weight: 400; margin: 0; }
132
+ p { margin: 0; }
133
+ code, pre, kbd, samp { font-family: var(--font-mono); }
134
+ pre { margin: 0; }
135
+
136
+ a {
137
+ color: var(--ink);
138
+ text-decoration: underline;
139
+ text-decoration-thickness: 1px;
140
+ text-underline-offset: 3px;
141
+ }
142
+ a:hover { color: var(--action-blue); }
143
+
144
+ ::selection { background: var(--pale-blue); }
145
+
146
+ /* Focus is never removed — inputs included (spec §5.2). */
147
+ :focus-visible {
148
+ outline: 2px solid var(--focus-blue);
149
+ outline-offset: 2px;
150
+ }
151
+
152
+ input, select, textarea, button { font: inherit; color: inherit; }
153
+ /* Form focus tint on any focus (mouse included), matching tokens/base.css;
154
+ the keyboard outline above stays untouched. */
155
+ input:focus,
156
+ textarea:focus,
157
+ select:focus { border-color: var(--form-focus); }
158
+
159
+ /* Uniform press feedback on every enabled button (prototype index.html). */
160
+ button:not(:disabled):hover { opacity: .92; }
161
+
162
+ .sr-only {
163
+ position: absolute;
164
+ width: 1px;
165
+ height: 1px;
166
+ margin: -1px;
167
+ padding: 0;
168
+ border: 0;
169
+ overflow: hidden;
170
+ clip: rect(0 0 0 0);
171
+ clip-path: inset(50%);
172
+ white-space: nowrap;
173
+ }
174
+
175
+ /* Text utilities */
176
+ .mono {
177
+ font-family: var(--font-mono);
178
+ font-size: 13px;
179
+ letter-spacing: var(--mono-ls);
180
+ }
181
+ .mono-label {
182
+ font-family: var(--font-mono);
183
+ font-size: 12px;
184
+ letter-spacing: var(--mono-ls);
185
+ text-transform: uppercase;
186
+ color: var(--muted);
187
+ }
188
+ .section-label { margin-bottom: 14px; }
189
+ /* Per-surface eyebrow gaps (deliveries detail rail). */
190
+ .section-label--lifecycle { margin-bottom: 12px; }
191
+ .section-label--frames { margin-bottom: 10px; }
192
+ .section-label--body { margin-bottom: 8px; }
193
+ /* Eyebrow row: info-dot/lower-bound hugs the label (prototype gap 8px). */
194
+ .row.section-head { gap: 8px; }
195
+ .section-title {
196
+ font-family: var(--font-body);
197
+ font-size: var(--type-feature-size);
198
+ line-height: var(--type-feature-lh);
199
+ color: var(--ink);
200
+ }
201
+ .text-muted { color: var(--muted); }
202
+ .text-body-muted { color: var(--body-muted); }
203
+ .text-sm { font-size: 14px; }
204
+ .text-xs { font-size: 13px; }
205
+ .footnote { font-size: 12px; line-height: 1.5; color: var(--muted); }
206
+ .rule {
207
+ margin: 0;
208
+ border: 0;
209
+ border-top: 1px solid var(--rule);
210
+ height: 0;
211
+ }
212
+
213
+ /* ==========================================================================
214
+ 3. LAYOUT
215
+ ========================================================================== */
216
+
217
+ .app-shell {
218
+ min-height: 100vh;
219
+ background: var(--canvas);
220
+ }
221
+
222
+ .app-header { border-bottom: 1px solid var(--hairline); }
223
+
224
+ .header-bar {
225
+ max-width: 1320px;
226
+ margin: 0 auto;
227
+ padding: 20px 40px 0;
228
+ display: flex;
229
+ align-items: center;
230
+ gap: 24px;
231
+ flex-wrap: wrap;
232
+ }
233
+
234
+ .brand {
235
+ display: flex;
236
+ align-items: baseline;
237
+ gap: 14px;
238
+ flex-wrap: wrap;
239
+ row-gap: 4px;
240
+ }
241
+ /* Posture label: 11px, no forced caps (prototype App.jsx). */
242
+ .brand .mono-label {
243
+ font-size: 11px;
244
+ text-transform: none;
245
+ }
246
+ .brand-mark { align-self: center; flex-shrink: 0; }
247
+ .brand-wordmark {
248
+ font-family: var(--font-display);
249
+ font-size: 26px;
250
+ letter-spacing: -0.52px;
251
+ color: var(--ink);
252
+ }
253
+ .brand-posture {
254
+ display: inline-flex;
255
+ align-items: center;
256
+ gap: 8px;
257
+ }
258
+
259
+ .header-spacer { flex: 1 1 0%; }
260
+
261
+ .header-meta {
262
+ display: flex;
263
+ align-items: center;
264
+ gap: 14px;
265
+ flex-wrap: wrap;
266
+ }
267
+
268
+ .as-of {
269
+ font-size: 13px;
270
+ color: var(--muted);
271
+ white-space: nowrap;
272
+ }
273
+ /* Second header row: staleness note left, connection controls right — the
274
+ primary row keeps the prototype's single-line composition. */
275
+ .header-subrow {
276
+ flex-basis: 100%;
277
+ display: flex;
278
+ align-items: center;
279
+ gap: 16px;
280
+ padding-bottom: 2px;
281
+ }
282
+ .staleness {
283
+ font-size: 13px;
284
+ color: var(--coral-deep);
285
+ }
286
+ .staleness--quiet { color: var(--muted); }
287
+
288
+ .conn-status {
289
+ display: inline-flex;
290
+ align-items: center;
291
+ gap: 8px;
292
+ }
293
+ .conn-controls {
294
+ display: inline-flex;
295
+ align-items: center;
296
+ gap: 8px;
297
+ margin-left: auto;
298
+ }
299
+
300
+ .lang-toggle {
301
+ display: flex;
302
+ border: 1px solid var(--hairline);
303
+ border-radius: var(--radius-xl);
304
+ overflow: hidden;
305
+ }
306
+ .lang-toggle__btn {
307
+ font-family: var(--font-body);
308
+ font-size: 12px;
309
+ font-weight: 400;
310
+ padding: 5px 12px;
311
+ border: none;
312
+ background: transparent;
313
+ color: var(--ink);
314
+ cursor: pointer;
315
+ }
316
+ .lang-toggle__btn[aria-pressed="true"] {
317
+ font-weight: 500;
318
+ background: var(--cta-bg);
319
+ color: var(--cta-text);
320
+ }
321
+ /* Keep the ring inside the clipped pill. */
322
+ .lang-toggle__btn:focus-visible { outline-offset: -3px; }
323
+
324
+ .app-nav {
325
+ max-width: 1320px;
326
+ margin: 0 auto;
327
+ padding: 18px 40px 0;
328
+ display: flex;
329
+ gap: 28px;
330
+ flex-wrap: wrap;
331
+ }
332
+ .tab {
333
+ font-family: var(--font-body);
334
+ font-size: 15px;
335
+ font-weight: 400;
336
+ background: none;
337
+ border: none;
338
+ border-bottom: 2px solid transparent;
339
+ padding: 0 2px 14px;
340
+ color: var(--muted);
341
+ cursor: pointer;
342
+ }
343
+ .tab[aria-selected="true"] {
344
+ color: var(--ink);
345
+ border-bottom-color: var(--ink);
346
+ }
347
+ .tab:focus-visible { outline-offset: 1px; }
348
+
349
+ .app-main {
350
+ max-width: 1320px;
351
+ margin: 0 auto;
352
+ padding: 40px 40px 80px;
353
+ }
354
+
355
+ /* Every tab panel is a 48px section stack. */
356
+ .tab-panel { display: grid; gap: 48px; }
357
+ .tab-panel--narrow { max-width: 860px; }
358
+ .section { display: block; }
359
+ /* Subordinated sub-section (routes CLI panel under the topology card). */
360
+ .section__sub { margin-top: 20px; }
361
+ .stack { display: grid; gap: 12px; }
362
+ /* register-codex teaching block at the foot of the Codex routes section. */
363
+ .routes-register { gap: 10px; margin-top: 16px; }
364
+ .stack-sm { display: grid; gap: 8px; }
365
+ .stack-lg { display: grid; gap: 20px; }
366
+ .row {
367
+ display: flex;
368
+ align-items: center;
369
+ gap: 12px;
370
+ flex-wrap: wrap;
371
+ }
372
+ .row-baseline {
373
+ display: flex;
374
+ align-items: baseline;
375
+ gap: 12px;
376
+ flex-wrap: wrap;
377
+ }
378
+ .row-baseline--split {
379
+ justify-content: space-between;
380
+ align-items: center;
381
+ }
382
+ .grid-2 {
383
+ display: grid;
384
+ grid-template-columns: 1fr 1fr;
385
+ gap: 16px;
386
+ align-items: start;
387
+ }
388
+ .grid-cards {
389
+ display: grid;
390
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
391
+ gap: 16px;
392
+ align-items: start;
393
+ }
394
+
395
+ .app-footer {
396
+ max-width: 1320px;
397
+ margin: 0 auto;
398
+ padding: 0 40px 40px;
399
+ display: grid;
400
+ gap: 6px;
401
+ color: var(--muted);
402
+ font-size: 12px;
403
+ }
404
+ .footer-diagnostic {
405
+ font-family: var(--font-mono);
406
+ font-size: 11px;
407
+ letter-spacing: var(--mono-ls);
408
+ color: var(--muted);
409
+ }
410
+
411
+ /* Any table, pre or wide block scrolls inside itself — the page never does. */
412
+ .table-wrap { overflow-x: auto; }
413
+
414
+ /* ==========================================================================
415
+ 4. CHIPS (spec §3.1) — 8 kinds + loud unknown fallback
416
+ ========================================================================== */
417
+
418
+ .chip {
419
+ display: inline-block;
420
+ font-family: var(--font-mono);
421
+ font-size: 12px;
422
+ line-height: 1.5;
423
+ letter-spacing: var(--mono-ls);
424
+ text-transform: uppercase;
425
+ white-space: nowrap;
426
+ padding: 3px 9px;
427
+ border: 1px solid transparent;
428
+ border-radius: var(--radius-xs);
429
+ background: transparent;
430
+ color: var(--ink);
431
+ }
432
+ .chip--small {
433
+ font-size: 11px;
434
+ padding: 2px 7px;
435
+ }
436
+
437
+ .chip[data-kind="positive"] { background: var(--pale-green); color: var(--deep-green); }
438
+ .chip[data-kind="qualified"] { background: transparent; color: var(--deep-green); border-color: var(--deep-green); }
439
+ .chip[data-kind="active"] { background: var(--pale-blue); color: var(--action-blue); }
440
+ .chip[data-kind="progress"] { background: var(--soft-stone); color: var(--slate); }
441
+ .chip[data-kind="warning"] { background: var(--coral-tint); color: var(--coral-deep); }
442
+ .chip[data-kind="indeterminate"] { background: var(--purple-tint); color: var(--purple-deep); }
443
+ .chip[data-kind="failure"] { background: var(--error-tint); color: var(--error); }
444
+ .chip[data-kind="inert"] { background: transparent; color: var(--muted); border-color: var(--hairline); }
445
+
446
+ /* An unrecognised protocol token must be noticed, never camouflaged. */
447
+ .chip[data-kind="unknown"] {
448
+ background: transparent;
449
+ color: var(--error);
450
+ border: 1px dashed var(--error);
451
+ }
452
+
453
+ .chip-row {
454
+ display: flex;
455
+ gap: 6px;
456
+ flex-wrap: wrap;
457
+ align-items: center;
458
+ }
459
+ /* Activity entries breathe wider than the exchange-node chip row (6px). */
460
+ .activity-row .chip-row { gap: 10px; }
461
+ .lower-bound {
462
+ font-family: var(--font-mono);
463
+ font-size: 11px;
464
+ letter-spacing: var(--mono-ls);
465
+ color: var(--slate);
466
+ border: 1px dashed var(--hairline);
467
+ border-radius: var(--radius-xs);
468
+ padding: 1px 6px;
469
+ white-space: nowrap;
470
+ }
471
+
472
+ /* ==========================================================================
473
+ 5. COMPONENTS
474
+ ========================================================================== */
475
+
476
+ /* --- 5.1 Buttons ---------------------------------------------------------- */
477
+
478
+ .btn {
479
+ font-family: var(--font-body);
480
+ font-size: 13px;
481
+ line-height: 1.5;
482
+ padding: 5px 16px;
483
+ border: 1px solid transparent;
484
+ border-radius: var(--radius-pill);
485
+ background: transparent;
486
+ color: var(--ink);
487
+ cursor: pointer;
488
+ white-space: nowrap;
489
+ }
490
+ .btn--primary {
491
+ font-weight: 500;
492
+ border: none;
493
+ background: var(--cta-bg);
494
+ color: var(--cta-text);
495
+ }
496
+ .btn--ghost { border-color: var(--hairline); }
497
+ .btn:disabled {
498
+ cursor: default;
499
+ background: var(--hairline);
500
+ color: var(--muted);
501
+ border-color: transparent;
502
+ }
503
+ /* Inline text button ("show raw", "hide") */
504
+ .toggle-link {
505
+ background: none;
506
+ border: none;
507
+ padding: 0;
508
+ font-family: var(--font-body);
509
+ font-size: 14px;
510
+ color: var(--action-blue);
511
+ text-decoration: underline;
512
+ text-underline-offset: 3px;
513
+ cursor: pointer;
514
+ }
515
+
516
+ /* --- 5.2 Inputs ----------------------------------------------------------- */
517
+
518
+ .text-input {
519
+ border: 1px solid var(--border-light);
520
+ border-radius: var(--radius-xs);
521
+ padding: 8px 12px;
522
+ font-family: var(--font-body);
523
+ font-size: 13px;
524
+ background: var(--canvas);
525
+ color: var(--ink);
526
+ }
527
+ .text-input::placeholder { color: var(--muted); }
528
+ /* content-box keeps the prototype's 326px outer width (300 + padding +
529
+ border, canonical base has no box-sizing reset); appearance reset drops
530
+ the UA search-cancel affordance the prototype's plain text input lacks. */
531
+ .header-search {
532
+ width: 300px;
533
+ max-width: 100%;
534
+ box-sizing: content-box;
535
+ appearance: none;
536
+ }
537
+ .header-search::-webkit-search-cancel-button { display: none; }
538
+ .filter-input {
539
+ width: 100%;
540
+ padding: 10px 14px;
541
+ font-size: 14px;
542
+ }
543
+
544
+ /* --- 5.3 Cards & panels --------------------------------------------------- */
545
+
546
+ .card {
547
+ border: 1px solid var(--card-border);
548
+ border-radius: var(--radius-sm);
549
+ padding: 20px;
550
+ display: grid;
551
+ gap: 12px;
552
+ align-content: start;
553
+ font-size: 14px;
554
+ background: var(--canvas);
555
+ }
556
+ .card--hairline { border-color: var(--hairline); }
557
+ .card--warn { border-color: var(--coral-soft); }
558
+ .card__head {
559
+ display: flex;
560
+ justify-content: space-between;
561
+ align-items: center;
562
+ gap: 12px;
563
+ }
564
+ .card__title { font-size: 16px; line-height: 1.4; }
565
+ .card__body { font-size: 14px; color: var(--body-muted); }
566
+
567
+ .panel {
568
+ border: 1px solid var(--hairline);
569
+ border-radius: var(--radius-lg);
570
+ padding: 24px 28px;
571
+ background: var(--canvas);
572
+ }
573
+ .panel--warm {
574
+ background: var(--soft-stone);
575
+ border-color: transparent;
576
+ border-radius: var(--radius-lg);
577
+ padding: 32px;
578
+ }
579
+
580
+ /* Status strip (Overview) */
581
+ .status-strip {
582
+ display: flex;
583
+ gap: 12px;
584
+ flex-wrap: wrap;
585
+ }
586
+ .status-card {
587
+ border: 1px solid var(--card-border);
588
+ border-radius: var(--radius-sm);
589
+ padding: 14px 18px;
590
+ display: grid;
591
+ gap: 6px;
592
+ flex: 1 1 170px;
593
+ }
594
+ .status-card__head {
595
+ display: flex;
596
+ justify-content: space-between;
597
+ align-items: center;
598
+ gap: 12px;
599
+ }
600
+ .status-card__label { font-size: 14px; color: var(--body-muted); }
601
+ .status-card__detail { font-size: 13px; color: var(--muted); }
602
+
603
+ /* --- 5.4 Bounded operator actions ----------------------------------------- */
604
+
605
+ .action-panel {
606
+ display: grid;
607
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
608
+ gap: 16px;
609
+ align-items: start;
610
+ }
611
+ .action-card {
612
+ border: 1px solid var(--card-border);
613
+ border-radius: var(--radius-sm);
614
+ padding: 18px 20px;
615
+ display: grid;
616
+ gap: 12px;
617
+ align-content: start;
618
+ }
619
+ .action-card__title {
620
+ font-family: var(--font-mono);
621
+ font-size: 12px;
622
+ letter-spacing: var(--mono-ls);
623
+ text-transform: uppercase;
624
+ color: var(--muted);
625
+ }
626
+ .action-card__consequence,
627
+ .section-teaching {
628
+ font-size: 14px;
629
+ line-height: 1.5;
630
+ color: var(--body-muted);
631
+ }
632
+ .section-teaching { margin-bottom: 12px; }
633
+ .action-card__status {
634
+ margin: 0;
635
+ font-family: var(--font-mono);
636
+ font-size: 12px;
637
+ overflow-wrap: anywhere;
638
+ }
639
+ .action-card__status[data-action-result="success"] { color: var(--deep-green); }
640
+ .action-card__status[data-action-result="failure"] { color: var(--coral-deep); }
641
+ .action-card__buttons { display: flex; flex-wrap: wrap; gap: 8px; }
642
+ .section__sub .action-card { padding: 16px 18px; }
643
+
644
+ /* Honest-absent card: never a dead control. */
645
+ .absent-feature {
646
+ border: 1px dashed var(--hairline);
647
+ border-radius: var(--radius-sm);
648
+ padding: 20px;
649
+ display: grid;
650
+ gap: 10px;
651
+ align-content: start;
652
+ }
653
+ /* Card title (the MonoLabel eyebrow above it already carries the mono
654
+ "not in this build" treatment). */
655
+ .absent-feature__title {
656
+ font-family: var(--font-body);
657
+ font-size: 18px;
658
+ line-height: 1.4;
659
+ color: var(--ink);
660
+ }
661
+ .absent-feature__body {
662
+ font-size: 14px;
663
+ line-height: 1.5;
664
+ color: var(--body-muted);
665
+ }
666
+ .absent-feature__note {
667
+ font-size: 13px;
668
+ line-height: 1.5;
669
+ color: var(--muted);
670
+ }
671
+
672
+ /* --- 5.5 CopyCmd ---------------------------------------------------------- */
673
+
674
+ .copy-cmd {
675
+ display: flex;
676
+ align-items: center;
677
+ gap: 10px;
678
+ background: var(--primary);
679
+ color: rgba(255, 255, 255, .85);
680
+ border-radius: var(--radius-xs);
681
+ padding: 8px 12px;
682
+ font-family: var(--font-mono);
683
+ font-size: 13px;
684
+ letter-spacing: 0.1px;
685
+ max-width: 100%;
686
+ }
687
+ /* The command scrolls; the button stays reachable. */
688
+ .copy-cmd__code {
689
+ flex: 1 1 0%;
690
+ min-width: 0;
691
+ overflow-x: auto;
692
+ white-space: nowrap;
693
+ color: inherit;
694
+ }
695
+ .copy-cmd__button {
696
+ flex-shrink: 0;
697
+ font-family: var(--font-body);
698
+ font-size: 12px;
699
+ font-weight: 500;
700
+ background: var(--canvas);
701
+ color: var(--ink);
702
+ border: none;
703
+ border-radius: var(--radius-pill);
704
+ padding: 3px 12px;
705
+ cursor: pointer;
706
+ }
707
+ .copy-cmd__button:focus-visible { outline-offset: 2px; }
708
+ .copy-cmd__status {
709
+ flex-shrink: 0;
710
+ font-family: var(--font-body);
711
+ font-size: 12px;
712
+ color: rgba(255, 255, 255, .85);
713
+ white-space: nowrap;
714
+ }
715
+ .copy-cmd__status[data-tone="error"] { color: var(--coral-soft); }
716
+
717
+ /* --- 5.6 Pills (filters) -------------------------------------------------- */
718
+
719
+ .filters {
720
+ display: flex;
721
+ gap: 28px;
722
+ flex-wrap: wrap;
723
+ align-items: flex-end;
724
+ margin-bottom: 20px;
725
+ }
726
+ .filter-group { display: grid; gap: 8px; }
727
+ /* Deliveries rail: state block and search get their own bottom rhythm. */
728
+ .filters-block { margin-bottom: 20px; }
729
+ .filters-search { margin-bottom: 24px; }
730
+ .pill-row {
731
+ display: flex;
732
+ gap: 8px;
733
+ flex-wrap: wrap;
734
+ }
735
+ .pill {
736
+ font-family: var(--font-body);
737
+ font-size: 14px;
738
+ font-weight: 400;
739
+ line-height: 1.4;
740
+ padding: 5px 14px;
741
+ border: 1px solid var(--hairline);
742
+ border-radius: var(--radius-xl);
743
+ background: transparent;
744
+ color: var(--ink);
745
+ cursor: pointer;
746
+ }
747
+ .pill[aria-pressed="true"] {
748
+ font-weight: 500;
749
+ border-color: var(--cta-bg);
750
+ background: var(--cta-bg);
751
+ color: var(--cta-text);
752
+ }
753
+ .pill__count {
754
+ font-family: var(--font-mono);
755
+ font-size: 12px;
756
+ letter-spacing: var(--mono-ls);
757
+ color: inherit;
758
+ opacity: .7;
759
+ }
760
+
761
+ /* --- 5.7 Notices ---------------------------------------------------------- */
762
+
763
+ .notice {
764
+ display: flex;
765
+ gap: 12px;
766
+ align-items: baseline;
767
+ flex-wrap: wrap;
768
+ border: 1px solid var(--hairline);
769
+ border-left-width: 3px;
770
+ border-radius: var(--radius-sm);
771
+ padding: 12px 16px;
772
+ font-size: 13px;
773
+ line-height: 1.5;
774
+ color: var(--ink);
775
+ }
776
+ .notice[data-tone="info"] {
777
+ border-color: var(--border-light);
778
+ border-left-color: var(--action-blue);
779
+ background: var(--pale-blue);
780
+ }
781
+ .notice[data-tone="warning"] {
782
+ border-color: var(--coral-soft);
783
+ border-left-color: var(--coral);
784
+ background: var(--coral-wash-soft);
785
+ }
786
+ .notice[data-tone="error"] {
787
+ border-color: var(--coral-soft);
788
+ border-left-color: var(--error);
789
+ background: var(--error-tint);
790
+ }
791
+ .notice__label {
792
+ font-family: var(--font-mono);
793
+ font-size: 11px;
794
+ letter-spacing: var(--mono-ls);
795
+ text-transform: uppercase;
796
+ color: var(--slate);
797
+ white-space: nowrap;
798
+ }
799
+
800
+ /* --- 5.8 Exchange board (Overview) --------------------------------------- */
801
+
802
+ .exchange-board {
803
+ background: var(--soft-stone);
804
+ border-radius: var(--radius-lg);
805
+ padding: 32px;
806
+ display: flex;
807
+ flex-wrap: wrap;
808
+ gap: 8px;
809
+ align-items: stretch;
810
+ justify-content: center;
811
+ }
812
+ .exchange-node {
813
+ background: var(--canvas);
814
+ border: 1px solid var(--hairline);
815
+ border-radius: var(--radius-sm);
816
+ padding: 20px;
817
+ min-width: 210px;
818
+ display: grid;
819
+ gap: 10px;
820
+ align-content: start;
821
+ }
822
+ .exchange-node__title {
823
+ font-family: var(--font-mono);
824
+ font-size: 14px;
825
+ letter-spacing: var(--mono-ls);
826
+ color: var(--ink);
827
+ }
828
+ .exchange-node__sub {
829
+ font-family: var(--font-mono);
830
+ font-size: 10px;
831
+ letter-spacing: var(--mono-ls);
832
+ text-transform: uppercase;
833
+ color: var(--muted);
834
+ margin-top: 4px;
835
+ }
836
+ .exchange-node__line { font-size: 13px; color: var(--body-muted); }
837
+
838
+ .exchange-edges {
839
+ display: grid;
840
+ align-content: center;
841
+ gap: 10px;
842
+ }
843
+ .exchange-edge {
844
+ display: grid;
845
+ gap: 6px;
846
+ justify-items: center;
847
+ align-self: center;
848
+ padding: 0 8px;
849
+ }
850
+ .edge-label {
851
+ font-family: var(--font-mono);
852
+ font-size: 11px;
853
+ letter-spacing: var(--mono-ls);
854
+ text-transform: uppercase;
855
+ color: var(--muted);
856
+ }
857
+ .edge-line {
858
+ width: 110px;
859
+ border-top: 1px solid var(--hairline);
860
+ position: relative;
861
+ }
862
+ .edge-arrow {
863
+ position: absolute;
864
+ top: -8px;
865
+ color: var(--slate);
866
+ }
867
+ .edge-arrow--in { left: -2px; }
868
+ .edge-arrow--out { right: -2px; }
869
+ .edge-queue {
870
+ font-size: 13px;
871
+ color: var(--muted);
872
+ text-align: center;
873
+ }
874
+ .edge-queue[data-active="true"] { color: var(--ink); }
875
+
876
+ /* Legible "no pair" state — informative, not alarming. */
877
+ .no-pair {
878
+ display: grid;
879
+ align-content: center;
880
+ justify-items: center;
881
+ padding: 0 16px;
882
+ max-width: 200px;
883
+ }
884
+ .no-pair__label {
885
+ font-family: var(--font-mono);
886
+ font-size: 11px;
887
+ letter-spacing: var(--mono-ls);
888
+ text-transform: uppercase;
889
+ color: var(--slate);
890
+ border: 1px dashed var(--hairline);
891
+ border-radius: var(--radius-xs);
892
+ padding: 4px 10px;
893
+ }
894
+ .no-pair__body {
895
+ font-size: 12px;
896
+ color: var(--body-muted);
897
+ text-align: center;
898
+ margin-top: 8px;
899
+ }
900
+ /* Long next-action / no-pair sentences render once beneath the board. */
901
+ .exchange-notes { margin-top: 14px; }
902
+ .inbound-policy {
903
+ display: flex;
904
+ align-items: center;
905
+ gap: 10px;
906
+ margin-bottom: 14px;
907
+ padding: 9px 12px;
908
+ border: 1px solid var(--hairline);
909
+ border-radius: var(--radius-xs);
910
+ color: var(--body-muted);
911
+ font-size: 12px;
912
+ }
913
+ .inbound-policy[data-inbound-mode="open"] {
914
+ border-color: var(--coral-deep);
915
+ background: var(--coral-wash-soft);
916
+ color: var(--ink);
917
+ }
918
+
919
+ /* --- 5.9 Attention list --------------------------------------------------- */
920
+
921
+ .attention-list { display: grid; gap: 12px; }
922
+ .attention-list + .footnote { margin-top: 12px; }
923
+ .attention-item {
924
+ border: 1px solid var(--hairline);
925
+ border-radius: var(--radius-sm);
926
+ padding: 18px 20px;
927
+ display: grid;
928
+ gap: 12px;
929
+ }
930
+ .attention-item__head {
931
+ display: flex;
932
+ gap: 12px;
933
+ align-items: baseline;
934
+ flex-wrap: wrap;
935
+ }
936
+ .attention-item__title { font-size: 16px; line-height: 1.5; }
937
+ .attention-item__body { font-size: 14px; line-height: 1.5; color: var(--body-muted); }
938
+ .attention-item__scope {
939
+ font-family: var(--font-mono);
940
+ font-size: 12px;
941
+ letter-spacing: var(--mono-ls);
942
+ color: var(--slate);
943
+ }
944
+ .attention-item__action { min-width: 340px; }
945
+
946
+ /* --- 5.10 Pulse bars ------------------------------------------------------ */
947
+
948
+ .pulse {
949
+ display: flex;
950
+ gap: 28px;
951
+ align-items: flex-end;
952
+ flex-wrap: wrap;
953
+ }
954
+ .pulse-bar-btn {
955
+ background: none;
956
+ border: none;
957
+ padding: 0;
958
+ cursor: pointer;
959
+ display: grid;
960
+ gap: 8px;
961
+ justify-items: center;
962
+ }
963
+ .pulse-count { font-size: 14px; color: var(--ink); }
964
+ /* Height comes from the React style prop (dynamic numeric). content-box
965
+ restores the prototype's geometry (44px + border = 46px, height H + 2px). */
966
+ .pulse-bar {
967
+ display: block;
968
+ box-sizing: content-box;
969
+ width: 44px;
970
+ min-height: 6px;
971
+ border: 1px solid transparent;
972
+ border-radius: var(--radius-xs);
973
+ background: var(--soft-stone);
974
+ }
975
+ .pulse-bar[data-kind="positive"] { background: var(--pale-green); }
976
+ .pulse-bar[data-kind="qualified"] { background: transparent; border-color: var(--deep-green); }
977
+ .pulse-bar[data-kind="active"] { background: var(--pale-blue); }
978
+ .pulse-bar[data-kind="progress"] { background: var(--soft-stone); }
979
+ .pulse-bar[data-kind="warning"] { background: var(--coral-tint); }
980
+ .pulse-bar[data-kind="indeterminate"] { background: var(--purple-tint); }
981
+ .pulse-bar[data-kind="failure"] { background: var(--error-tint); }
982
+ .pulse-bar[data-kind="inert"] { background: transparent; border-color: var(--hairline); }
983
+ .pulse-bar[data-empty="true"] { border-color: var(--hairline); }
984
+ .pulse-caption { font-size: 12px; color: var(--muted); margin-top: 14px; }
985
+ .pulse-empty {
986
+ font-size: 14px;
987
+ color: var(--body-muted);
988
+ margin-bottom: 14px;
989
+ }
990
+
991
+ /* --- 5.11 Topology (Routes) ---------------------------------------------- */
992
+
993
+ .topology {
994
+ background: var(--canvas);
995
+ border: 1px solid var(--hairline);
996
+ border-radius: var(--radius-lg);
997
+ padding: 24px 28px;
998
+ }
999
+ .topology__heads {
1000
+ display: flex;
1001
+ justify-content: space-between;
1002
+ margin-bottom: 2px;
1003
+ }
1004
+ .topology__head--claude { color: var(--coral-accent); }
1005
+ .topology__head--codex { color: var(--action-blue); }
1006
+ .topology__cols {
1007
+ display: flex;
1008
+ align-items: flex-start;
1009
+ }
1010
+ .topology__col {
1011
+ flex: 1 1 0;
1012
+ min-width: 0;
1013
+ padding-top: 18px;
1014
+ }
1015
+ .topology__svg {
1016
+ flex-shrink: 0;
1017
+ display: block;
1018
+ }
1019
+ .topology__empty {
1020
+ font-size: 13px;
1021
+ color: var(--body-muted);
1022
+ padding-top: 8px;
1023
+ }
1024
+ .topology__edge-list {
1025
+ display: grid;
1026
+ gap: 8px;
1027
+ margin: 16px 0 0;
1028
+ padding: 14px 0 0;
1029
+ border-top: 1px solid var(--hairline);
1030
+ list-style: none;
1031
+ }
1032
+ .topology__edge-list li {
1033
+ display: flex;
1034
+ flex-wrap: wrap;
1035
+ align-items: center;
1036
+ gap: 8px;
1037
+ color: var(--body-muted);
1038
+ font-family: var(--font-mono);
1039
+ font-size: 12px;
1040
+ overflow-wrap: anywhere;
1041
+ }
1042
+ .topo-row {
1043
+ height: 64px;
1044
+ display: flex;
1045
+ align-items: center;
1046
+ }
1047
+ .topo-row--left { justify-content: flex-end; }
1048
+ .topo-row--right { justify-content: flex-start; }
1049
+ .topo-chip {
1050
+ font-family: var(--font-mono);
1051
+ font-size: 13px;
1052
+ letter-spacing: var(--mono-ls);
1053
+ padding: 7px 15px;
1054
+ border: 1px solid var(--hairline);
1055
+ border-radius: var(--radius-xl);
1056
+ background: var(--canvas);
1057
+ color: var(--ink);
1058
+ max-width: 100%;
1059
+ overflow: hidden;
1060
+ text-overflow: ellipsis;
1061
+ white-space: nowrap;
1062
+ cursor: default;
1063
+ transition: background-color .15s, border-color .15s, color .15s, opacity .15s;
1064
+ }
1065
+ .topo-chip[data-side="claude"] { border-color: var(--coral-accent); color: var(--ink); }
1066
+ .topo-chip[data-side="codex"] { border-color: var(--action-blue); color: var(--action-blue); }
1067
+ .topo-chip[data-candidate="true"] { border-style: dashed; color: var(--slate); }
1068
+ .topo-chip[data-highlight="on"][data-side="claude"] { background: var(--coral-wash-hl); }
1069
+ .topo-chip[data-highlight="on"][data-side="codex"] { background: var(--pale-blue); }
1070
+ .topo-chip[data-highlight="off"] {
1071
+ border-color: var(--hairline);
1072
+ color: var(--muted);
1073
+ opacity: .45;
1074
+ }
1075
+
1076
+ /* --- 5.12 Accordion (Routes detail) -------------------------------------- */
1077
+
1078
+ .accordion { display: block; }
1079
+ .accordion__row {
1080
+ width: 100%;
1081
+ display: flex;
1082
+ gap: 14px;
1083
+ align-items: center;
1084
+ padding: 16px 8px;
1085
+ border: none;
1086
+ border-top: 1px solid var(--hairline);
1087
+ background: transparent;
1088
+ color: var(--ink);
1089
+ text-align: left;
1090
+ cursor: pointer;
1091
+ }
1092
+ .accordion__alias {
1093
+ font-family: var(--font-mono);
1094
+ font-size: 14px;
1095
+ letter-spacing: var(--mono-ls);
1096
+ flex: 1 1 auto;
1097
+ min-width: 0;
1098
+ overflow: hidden;
1099
+ text-overflow: ellipsis;
1100
+ white-space: nowrap;
1101
+ }
1102
+ .accordion__marker {
1103
+ color: var(--muted);
1104
+ flex-shrink: 0;
1105
+ }
1106
+ /* Green presence dot: selected sessions and registered codex routes. */
1107
+ .status-dot {
1108
+ width: 8px;
1109
+ height: 8px;
1110
+ border-radius: var(--radius-full);
1111
+ background: #1e8e5a;
1112
+ display: inline-block;
1113
+ flex-shrink: 0;
1114
+ }
1115
+ .accordion__panel {
1116
+ padding: 4px 8px 20px;
1117
+ display: grid;
1118
+ gap: 8px;
1119
+ font-size: 14px;
1120
+ color: var(--body-muted);
1121
+ }
1122
+ .accordion__panel .details-block { margin: 4px -8px 0; }
1123
+ .accordion__panel .details-block > summary { padding-left: 8px; }
1124
+ .detail-list { display: grid; gap: 8px; }
1125
+ .detail-row { font-size: 14px; color: var(--body-muted); }
1126
+ .detail-label { color: var(--muted); }
1127
+ .detail-value { color: var(--ink); }
1128
+ .detail-value--mono {
1129
+ font-family: var(--font-mono);
1130
+ font-size: 13px;
1131
+ letter-spacing: var(--mono-ls);
1132
+ }
1133
+
1134
+ /* --- 5.13 Deliveries layout, rows, lifecycle ------------------------------ */
1135
+
1136
+ .deliveries-layout {
1137
+ display: grid;
1138
+ grid-template-columns: minmax(0, 1fr) 360px;
1139
+ gap: 48px;
1140
+ align-items: start;
1141
+ }
1142
+ .deliveries-main { min-width: 0; }
1143
+ .deliveries-rail {
1144
+ border-left: 1px solid var(--hairline);
1145
+ padding-left: 32px;
1146
+ min-height: 300px;
1147
+ min-width: 0;
1148
+ }
1149
+
1150
+ .watch-register {
1151
+ margin: 24px 0 32px;
1152
+ padding: 20px;
1153
+ border: 1px solid var(--hairline);
1154
+ background: var(--surface-warm);
1155
+ }
1156
+ .watch-register h2 { margin: 4px 0 0; font-size: 20px; }
1157
+ .watch-register__empty { margin: 16px 0 0; color: var(--body-muted); }
1158
+ .watch-grid {
1159
+ display: grid;
1160
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1161
+ gap: 12px;
1162
+ margin-top: 16px;
1163
+ }
1164
+ .watch-card {
1165
+ min-width: 0;
1166
+ padding: 16px;
1167
+ border: 1px solid var(--hairline);
1168
+ background: var(--surface-card);
1169
+ }
1170
+ .watch-card[data-phase="episode"] { border-left: 3px solid var(--coral); }
1171
+ .watch-card__head { display: flex; justify-content: space-between; gap: 12px; align-items: center; }
1172
+ .watch-card > strong { display: block; margin-top: 10px; overflow-wrap: anywhere; }
1173
+ .watch-card__facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0 0; }
1174
+ .watch-card__facts div { min-width: 0; }
1175
+ .watch-card__facts dt { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
1176
+ .watch-card__facts dd { margin: 3px 0 0; font-size: 13px; overflow-wrap: anywhere; }
1177
+ .watch-history { margin-top: 16px; color: var(--body-muted); }
1178
+ .watch-history summary { cursor: pointer; }
1179
+ .watch-history ol { margin: 10px 0 0; padding-left: 22px; }
1180
+ .watch-history li { margin: 5px 0; }
1181
+
1182
+ .delivery-group { margin-bottom: 28px; }
1183
+ .delivery-group__head {
1184
+ display: flex;
1185
+ gap: 10px;
1186
+ align-items: baseline;
1187
+ margin-bottom: 4px;
1188
+ flex-wrap: wrap;
1189
+ }
1190
+ .delivery-group__key {
1191
+ font-family: var(--font-mono);
1192
+ font-size: 12px;
1193
+ letter-spacing: var(--mono-ls);
1194
+ color: var(--slate);
1195
+ }
1196
+
1197
+ .delivery-list { display: block; }
1198
+ .delivery-row {
1199
+ width: 100%;
1200
+ display: grid;
1201
+ grid-template-columns: 150px minmax(0, 1fr) auto auto;
1202
+ gap: 16px;
1203
+ align-items: center;
1204
+ padding: 16px 8px;
1205
+ border: none;
1206
+ border-top: 1px solid var(--hairline);
1207
+ background: transparent;
1208
+ color: var(--ink);
1209
+ text-align: left;
1210
+ cursor: pointer;
1211
+ }
1212
+ .delivery-row[aria-selected="true"] { background: var(--pale-blue); }
1213
+ .delivery-row__id {
1214
+ font-family: var(--font-mono);
1215
+ font-size: 13px;
1216
+ letter-spacing: var(--mono-ls);
1217
+ }
1218
+ .delivery-row__route {
1219
+ font-size: 14px;
1220
+ color: var(--body-muted);
1221
+ overflow: hidden;
1222
+ text-overflow: ellipsis;
1223
+ white-space: nowrap;
1224
+ }
1225
+ .delivery-row__time { white-space: nowrap; }
1226
+
1227
+ .detail-pane {
1228
+ display: grid;
1229
+ gap: 20px;
1230
+ align-content: start;
1231
+ }
1232
+ .detail-pane__id {
1233
+ font-family: var(--font-mono);
1234
+ font-size: 14px;
1235
+ letter-spacing: var(--mono-ls);
1236
+ }
1237
+ .detail-pane__head { display: grid; gap: 6px; }
1238
+ .detail-pane__sub { font-size: 13px; color: var(--muted); }
1239
+ .detail-pane__empty {
1240
+ font-size: 14px;
1241
+ color: var(--muted);
1242
+ padding-top: 8px;
1243
+ }
1244
+
1245
+ /* Lifecycle timeline: 8px dots + 1px connector */
1246
+ .lifecycle { display: grid; gap: 0; }
1247
+ .lifecycle-item {
1248
+ display: grid;
1249
+ grid-template-columns: 14px minmax(0, 1fr);
1250
+ gap: 14px;
1251
+ }
1252
+ .lifecycle-rail {
1253
+ display: grid;
1254
+ grid-template-rows: auto 1fr;
1255
+ justify-items: center;
1256
+ }
1257
+ .lifecycle-dot {
1258
+ width: 8px;
1259
+ height: 8px;
1260
+ border-radius: var(--radius-full);
1261
+ margin-top: 6px;
1262
+ background: var(--hairline);
1263
+ }
1264
+ .lifecycle-dot[data-kind="positive"] { background: var(--deep-green); }
1265
+ .lifecycle-dot[data-kind="qualified"] { background: var(--deep-green); }
1266
+ .lifecycle-dot[data-kind="active"] { background: var(--action-blue); }
1267
+ .lifecycle-dot[data-kind="progress"] { background: var(--slate); }
1268
+ .lifecycle-dot[data-kind="warning"] { background: var(--coral-deep); }
1269
+ .lifecycle-dot[data-kind="indeterminate"] { background: var(--purple-deep); }
1270
+ .lifecycle-dot[data-kind="failure"] { background: var(--error); }
1271
+ .lifecycle-dot[data-kind="inert"] { background: var(--muted); }
1272
+ .lifecycle-dot[data-kind="unknown"] { background: var(--canvas); box-shadow: inset 0 0 0 1px var(--error); }
1273
+ .lifecycle-connector {
1274
+ width: 1px;
1275
+ height: 100%;
1276
+ background: var(--hairline);
1277
+ }
1278
+ .lifecycle-body { padding-bottom: 16px; }
1279
+ .lifecycle-item:last-child .lifecycle-body { padding-bottom: 0; }
1280
+ .lifecycle-head {
1281
+ display: flex;
1282
+ gap: 10px;
1283
+ align-items: baseline;
1284
+ flex-wrap: wrap;
1285
+ }
1286
+ .lifecycle-abs { font-size: 12px; color: var(--muted); }
1287
+ .lifecycle-note { font-size: 13px; color: var(--body-muted); margin-top: 4px; }
1288
+ .lifecycle-meaning { font-size: 12px; color: var(--muted); margin-top: 2px; }
1289
+ .truncation-note { font-size: 12px; color: var(--muted); margin-top: 8px; }
1290
+
1291
+ /* Frames (safe codes) */
1292
+ .frames-list { display: grid; gap: 6px; }
1293
+ .frame-item {
1294
+ display: flex;
1295
+ gap: 12px;
1296
+ align-items: baseline;
1297
+ flex-wrap: wrap;
1298
+ }
1299
+ .frame-code {
1300
+ font-family: var(--font-mono);
1301
+ font-size: 12px;
1302
+ letter-spacing: var(--mono-ls);
1303
+ border: 1px solid var(--hairline);
1304
+ border-radius: var(--radius-xs);
1305
+ padding: 2px 8px;
1306
+ white-space: nowrap;
1307
+ }
1308
+
1309
+ .raw-json {
1310
+ background: var(--soft-stone);
1311
+ border-radius: var(--radius-xs);
1312
+ padding: 12px;
1313
+ font-family: var(--font-mono);
1314
+ font-size: 12px;
1315
+ line-height: 1.5;
1316
+ overflow-x: auto;
1317
+ margin: 10px 0 0;
1318
+ }
1319
+
1320
+ .empty-state {
1321
+ display: grid;
1322
+ gap: 12px;
1323
+ padding: 24px 0;
1324
+ }
1325
+ .empty-state__text { font-size: 14px; color: var(--body-muted); }
1326
+ .empty-state--activity { padding: 16px 0; max-width: none; }
1327
+
1328
+ /* --- 5.14 Activity -------------------------------------------------------- */
1329
+
1330
+ .activity-list { display: block; }
1331
+ .activity-row {
1332
+ display: grid;
1333
+ grid-template-columns: 110px 110px minmax(0, 1fr);
1334
+ gap: 16px;
1335
+ align-items: baseline;
1336
+ padding: 14px 8px;
1337
+ border-top: 1px solid var(--hairline);
1338
+ }
1339
+ .activity-kind {
1340
+ font-family: var(--font-mono);
1341
+ font-size: 11px;
1342
+ letter-spacing: var(--mono-ls);
1343
+ text-transform: uppercase;
1344
+ color: var(--slate);
1345
+ }
1346
+ .activity-text { font-size: 14px; line-height: 1.5; }
1347
+
1348
+ /* --- 5.15 Tables & counters (Diagnostics) --------------------------------- */
1349
+
1350
+ .data-table {
1351
+ width: 100%;
1352
+ border-collapse: collapse;
1353
+ text-align: left;
1354
+ }
1355
+ .data-table th,
1356
+ .data-table td {
1357
+ padding: 12px 8px;
1358
+ font-size: 14px;
1359
+ font-weight: 400;
1360
+ text-align: left;
1361
+ border-top: 1px solid var(--hairline);
1362
+ vertical-align: baseline;
1363
+ }
1364
+ .data-table thead th {
1365
+ border-top: none;
1366
+ font-family: var(--font-mono);
1367
+ font-size: 12px;
1368
+ letter-spacing: var(--mono-ls);
1369
+ text-transform: uppercase;
1370
+ color: var(--muted);
1371
+ white-space: nowrap;
1372
+ }
1373
+ .data-table td.is-mono,
1374
+ .data-table .cell-mono {
1375
+ font-family: var(--font-mono);
1376
+ font-size: 14px;
1377
+ letter-spacing: 0;
1378
+ }
1379
+ .data-table caption.table-caption {
1380
+ caption-side: top;
1381
+ text-align: left;
1382
+ padding: 0 0 8px;
1383
+ font-family: var(--font-mono);
1384
+ font-size: 12px;
1385
+ letter-spacing: var(--mono-ls);
1386
+ text-transform: uppercase;
1387
+ color: var(--muted);
1388
+ }
1389
+
1390
+ /* Disclosure reads as a text link ("counters · show"), not a block header. */
1391
+ .details-block { border-top: none; }
1392
+ .details-block > summary {
1393
+ width: fit-content;
1394
+ list-style: none;
1395
+ cursor: pointer;
1396
+ padding: 0;
1397
+ font-family: var(--font-body);
1398
+ font-size: 14px;
1399
+ letter-spacing: normal;
1400
+ text-transform: none;
1401
+ color: var(--action-blue);
1402
+ text-decoration: underline;
1403
+ text-underline-offset: 3px;
1404
+ }
1405
+ .details-block > summary::-webkit-details-marker { display: none; }
1406
+ .details-block > summary:hover { opacity: .92; color: var(--action-blue); }
1407
+ .details-block > summary:focus-visible { outline-offset: 2px; }
1408
+ .details-block__content { padding: 14px 0 20px; }
1409
+
1410
+ /* Counters render as a real table (caption + row headers kept for AT) with
1411
+ the prototype's list geometry. */
1412
+ .counters-list { max-width: 480px; }
1413
+ .data-table--counters th,
1414
+ .data-table--counters td { padding: 10px 8px; }
1415
+ .data-table--counters th[scope="row"] { color: var(--body-muted); }
1416
+ .data-table--counters td { text-align: right; }
1417
+
1418
+ .env-name {
1419
+ font-family: var(--font-mono);
1420
+ font-size: 12px;
1421
+ letter-spacing: var(--mono-ls);
1422
+ color: var(--body-muted);
1423
+ }
1424
+ .setting-list { display: grid; gap: 12px; }
1425
+ .setting-row {
1426
+ display: grid;
1427
+ gap: 6px;
1428
+ padding: 12px 0;
1429
+ border-top: 1px solid var(--hairline);
1430
+ font-size: 14px;
1431
+ }
1432
+
1433
+ /* --- 5.16 Misc affordances ------------------------------------------------ */
1434
+
1435
+ /* The small round "i" that carries a tooltip; focusable for keyboard users. */
1436
+ .info-dot {
1437
+ box-sizing: content-box; /* 16px + 1px border = the prototype's 18px dot */
1438
+ width: 16px;
1439
+ height: 16px;
1440
+ border-radius: var(--radius-full);
1441
+ border: 1px solid var(--hairline);
1442
+ color: var(--muted);
1443
+ font-family: var(--font-body);
1444
+ font-size: 10px;
1445
+ line-height: 1;
1446
+ display: inline-flex;
1447
+ align-items: center;
1448
+ justify-content: center;
1449
+ cursor: default;
1450
+ flex-shrink: 0;
1451
+ }
1452
+ .time-ago {
1453
+ color: var(--muted);
1454
+ font-size: 14px;
1455
+ white-space: nowrap;
1456
+ }
1457
+ .succession-card {
1458
+ border: 1px solid var(--hairline);
1459
+ border-radius: var(--radius-sm);
1460
+ padding: 20px;
1461
+ display: grid;
1462
+ gap: 8px;
1463
+ font-size: 14px;
1464
+ max-width: 640px;
1465
+ }
1466
+ .succession-card__head {
1467
+ display: flex;
1468
+ justify-content: space-between;
1469
+ gap: 12px;
1470
+ flex-wrap: wrap;
1471
+ }
1472
+ .succession-card__title { font-size: 14px; line-height: 1.4; }
1473
+ .succession-note {
1474
+ font-size: 14px;
1475
+ color: var(--body-muted);
1476
+ font-style: italic;
1477
+ }
1478
+
1479
+ /* ==========================================================================
1480
+ 6. TOOLTIP (tokenized; hover AND keyboard)
1481
+ ========================================================================== */
1482
+
1483
+ [data-tip] { position: relative; }
1484
+
1485
+ /* Focusable tooltip wrapper hugs its dot so the anchor and focus ring trace
1486
+ the circle, not the line box. */
1487
+ .tooltip {
1488
+ display: inline-flex;
1489
+ align-items: center;
1490
+ border-radius: var(--radius-full);
1491
+ }
1492
+
1493
+ [data-tip]:hover::after,
1494
+ [data-tip]:focus-visible::after {
1495
+ content: attr(data-tip);
1496
+ position: absolute;
1497
+ top: calc(100% + 6px);
1498
+ right: 0;
1499
+ background: var(--primary);
1500
+ color: var(--on-primary);
1501
+ font: 400 12px/1.4 var(--font-body);
1502
+ padding: 4px 10px;
1503
+ border-radius: var(--radius-xs);
1504
+ white-space: nowrap;
1505
+ z-index: 10;
1506
+ pointer-events: none;
1507
+ }
1508
+
1509
+ [data-tip-wrap][data-tip]:hover::after,
1510
+ [data-tip-wrap][data-tip]:focus-visible::after {
1511
+ white-space: normal;
1512
+ width: 320px;
1513
+ max-width: 80vw;
1514
+ left: 0;
1515
+ right: auto;
1516
+ }
1517
+
1518
+ /* ==========================================================================
1519
+ 7. RESPONSIVE — single breakpoint
1520
+ ========================================================================== */
1521
+
1522
+ @media (max-width: 760px) {
1523
+ .header-bar { padding: 16px 20px 0; gap: 16px; }
1524
+ .app-nav { padding: 14px 20px 0; gap: 18px; }
1525
+ .app-main { padding: 28px 20px 64px; }
1526
+ .app-footer { padding: 0 20px 32px; }
1527
+
1528
+ .header-spacer { display: none; }
1529
+ .header-search { width: 100%; flex: 1 1 100%; box-sizing: border-box; }
1530
+ .header-meta { width: 100%; }
1531
+
1532
+ .grid-2 { grid-template-columns: 1fr; }
1533
+ .action-panel { grid-template-columns: 1fr; }
1534
+ .grid-cards { grid-template-columns: 1fr; }
1535
+
1536
+ .deliveries-layout {
1537
+ grid-template-columns: minmax(0, 1fr);
1538
+ gap: 28px;
1539
+ }
1540
+ .watch-grid { grid-template-columns: minmax(0, 1fr); }
1541
+ .deliveries-rail {
1542
+ border-left: none;
1543
+ border-top: 1px solid var(--hairline);
1544
+ padding-left: 0;
1545
+ padding-top: 24px;
1546
+ min-height: 0;
1547
+ }
1548
+
1549
+ .delivery-row {
1550
+ grid-template-columns: minmax(0, 1fr) auto;
1551
+ row-gap: 8px;
1552
+ }
1553
+ .activity-row {
1554
+ grid-template-columns: 96px minmax(0, 1fr);
1555
+ grid-template-areas: "time kind" "time text";
1556
+ }
1557
+ .activity-row > .time-ago { grid-area: time; }
1558
+ .activity-kind { grid-area: kind; }
1559
+ .activity-row > .activity-text { grid-area: text; }
1560
+
1561
+ .exchange-board { padding: 20px; }
1562
+ .panel { padding: 20px; }
1563
+ .panel--warm { padding: 20px; }
1564
+ .topology { padding: 18px 16px; }
1565
+ .topology__cols { flex-wrap: wrap; }
1566
+ .topology__svg { display: none; }
1567
+ .topology__col { flex: 1 1 100%; padding-top: 8px; }
1568
+ .topo-row { height: auto; padding: 6px 0; justify-content: flex-start; }
1569
+
1570
+ .filters { gap: 18px; }
1571
+ .pulse { gap: 16px; }
1572
+ }
1573
+
1574
+ /* ==========================================================================
1575
+ 8. REDUCED MOTION
1576
+ ========================================================================== */
1577
+
1578
+ @media (prefers-reduced-motion: reduce) {
1579
+ *,
1580
+ *::before,
1581
+ *::after {
1582
+ transition: none !important;
1583
+ animation: none !important;
1584
+ scroll-behavior: auto !important;
1585
+ }
1586
+ }
1587
+
1588
+ /* ==========================================================================
1589
+ 9. FORCED COLORS — meaning must never rest on background alone
1590
+ ========================================================================== */
1591
+
1592
+ @media (forced-colors: active) {
1593
+ .chip { border: 1px solid ButtonText; }
1594
+ .pill[aria-pressed="true"] { outline: 2px solid Highlight; }
1595
+ .lifecycle-dot {
1596
+ forced-color-adjust: none;
1597
+ border: 1px solid ButtonText;
1598
+ }
1599
+ .pulse-bar {
1600
+ forced-color-adjust: none;
1601
+ border: 1px solid ButtonText;
1602
+ }
1603
+ .topo-chip {
1604
+ border: 1px solid ButtonText;
1605
+ opacity: 1;
1606
+ }
1607
+ .topo-chip[data-highlight="on"] { outline: 2px solid Highlight; }
1608
+ .delivery-row[aria-selected="true"] { outline: 2px solid Highlight; }
1609
+ .notice { border: 1px solid CanvasText; }
1610
+ }