agent-embassy 2.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/CONTRIBUTING.md +23 -36
  3. package/README.md +123 -222
  4. package/SECURITY.md +72 -93
  5. package/dist/src/errors.d.ts +10 -1
  6. package/dist/src/errors.js +3 -1
  7. package/dist/src/errors.js.map +1 -1
  8. package/dist/src/gateway/claude-helper-protocol.d.ts +8 -11
  9. package/dist/src/gateway/claude-helper-protocol.js +12 -11
  10. package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
  11. package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -5
  12. package/dist/src/gateway/claude-helper-supervisor.js +45 -17
  13. package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
  14. package/dist/src/gateway/claude-helper.js +6 -6
  15. package/dist/src/gateway/claude-helper.js.map +1 -1
  16. package/dist/src/gateway/claude-peer.d.ts +0 -3
  17. package/dist/src/gateway/claude-peer.js +7 -19
  18. package/dist/src/gateway/claude-peer.js.map +1 -1
  19. package/dist/src/gateway/cli.d.ts +17 -7
  20. package/dist/src/gateway/cli.js +945 -265
  21. package/dist/src/gateway/cli.js.map +1 -1
  22. package/dist/src/gateway/codex-socket-holder.d.ts +26 -0
  23. package/dist/src/gateway/codex-socket-holder.js +76 -0
  24. package/dist/src/gateway/codex-socket-holder.js.map +1 -0
  25. package/dist/src/gateway/codex-stateless-transport.js +1 -1
  26. package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
  27. package/dist/src/gateway/config.d.ts +1 -10
  28. package/dist/src/gateway/config.js +4 -10
  29. package/dist/src/gateway/config.js.map +1 -1
  30. package/dist/src/gateway/control.d.ts +66 -80
  31. package/dist/src/gateway/control.js +92 -147
  32. package/dist/src/gateway/control.js.map +1 -1
  33. package/dist/src/gateway/federation-nodes.d.ts +29 -2
  34. package/dist/src/gateway/federation-nodes.js +177 -7
  35. package/dist/src/gateway/federation-nodes.js.map +1 -1
  36. package/dist/src/gateway/peer-client.d.ts +4 -3
  37. package/dist/src/gateway/peer-client.js +22 -13
  38. package/dist/src/gateway/peer-client.js.map +1 -1
  39. package/dist/src/gateway/peer-protocol.d.ts +13 -11
  40. package/dist/src/gateway/peer-protocol.js +14 -12
  41. package/dist/src/gateway/peer-protocol.js.map +1 -1
  42. package/dist/src/gateway/provenance-envelope.d.ts +0 -1
  43. package/dist/src/gateway/provenance-envelope.js +4 -19
  44. package/dist/src/gateway/provenance-envelope.js.map +1 -1
  45. package/dist/src/gateway/providers.d.ts +11 -7
  46. package/dist/src/gateway/providers.js +49 -50
  47. package/dist/src/gateway/providers.js.map +1 -1
  48. package/dist/src/gateway/server.d.ts +4 -14
  49. package/dist/src/gateway/server.js +32 -54
  50. package/dist/src/gateway/server.js.map +1 -1
  51. package/dist/src/gateway/service-agent.d.ts +187 -0
  52. package/dist/src/gateway/service-agent.js +758 -0
  53. package/dist/src/gateway/service-agent.js.map +1 -0
  54. package/dist/src/gateway/service.d.ts +119 -38
  55. package/dist/src/gateway/service.js +754 -798
  56. package/dist/src/gateway/service.js.map +1 -1
  57. package/dist/src/gateway/status-view.d.ts +119 -0
  58. package/dist/src/gateway/status-view.js +484 -0
  59. package/dist/src/gateway/status-view.js.map +1 -0
  60. package/dist/src/gateway/store.d.ts +106 -21
  61. package/dist/src/gateway/store.js +463 -537
  62. package/dist/src/gateway/store.js.map +1 -1
  63. package/dist/src/gateway/types.d.ts +64 -102
  64. package/dist/src/gateway/types.js +40 -86
  65. package/dist/src/gateway/types.js.map +1 -1
  66. package/docs/CONFIGURATION.md +174 -45
  67. package/docs/DELIVERY.md +11 -11
  68. package/docs/GATEWAY-ARCHITECTURE.md +292 -384
  69. package/package.json +4 -12
  70. package/skills/embassy-peer/SKILL.md +69 -92
  71. package/skills/embassy-peer/agents/openai.yaml +1 -1
  72. package/README.zh-CN.md +0 -275
  73. package/assets/live-dashboard/app.css +0 -1619
  74. package/assets/vendor/react/LICENSE +0 -21
  75. package/assets/vendor/react/react-dom.production.min.js +0 -267
  76. package/assets/vendor/react/react.production.min.js +0 -31
  77. package/dist/src/gateway/acp-client.d.ts +0 -110
  78. package/dist/src/gateway/acp-client.js +0 -407
  79. package/dist/src/gateway/acp-client.js.map +0 -1
  80. package/dist/src/gateway/acp-provider.d.ts +0 -66
  81. package/dist/src/gateway/acp-provider.js +0 -275
  82. package/dist/src/gateway/acp-provider.js.map +0 -1
  83. package/dist/src/gateway/claude-helper-client.d.ts +0 -2
  84. package/dist/src/gateway/claude-helper-client.js +0 -2
  85. package/dist/src/gateway/claude-helper-client.js.map +0 -1
  86. package/dist/src/gateway/cli-copy.d.ts +0 -8
  87. package/dist/src/gateway/cli-copy.en.d.ts +0 -22
  88. package/dist/src/gateway/cli-copy.en.js +0 -62
  89. package/dist/src/gateway/cli-copy.en.js.map +0 -1
  90. package/dist/src/gateway/cli-copy.js +0 -27
  91. package/dist/src/gateway/cli-copy.js.map +0 -1
  92. package/dist/src/gateway/cli-copy.zh-CN.d.ts +0 -22
  93. package/dist/src/gateway/cli-copy.zh-CN.js +0 -62
  94. package/dist/src/gateway/cli-copy.zh-CN.js.map +0 -1
  95. package/dist/src/gateway/codex-doctor.d.ts +0 -36
  96. package/dist/src/gateway/codex-doctor.js +0 -127
  97. package/dist/src/gateway/codex-doctor.js.map +0 -1
  98. package/dist/src/gateway/dashboard-copy.d.ts +0 -7
  99. package/dist/src/gateway/dashboard-copy.en.d.ts +0 -504
  100. package/dist/src/gateway/dashboard-copy.en.js +0 -505
  101. package/dist/src/gateway/dashboard-copy.en.js.map +0 -1
  102. package/dist/src/gateway/dashboard-copy.js +0 -514
  103. package/dist/src/gateway/dashboard-copy.js.map +0 -1
  104. package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +0 -504
  105. package/dist/src/gateway/dashboard-copy.zh-CN.js +0 -505
  106. package/dist/src/gateway/dashboard-copy.zh-CN.js.map +0 -1
  107. package/dist/src/gateway/dashboard-model.d.ts +0 -343
  108. package/dist/src/gateway/dashboard-model.js +0 -1061
  109. package/dist/src/gateway/dashboard-model.js.map +0 -1
  110. package/dist/src/gateway/dashboard.d.ts +0 -20
  111. package/dist/src/gateway/dashboard.js +0 -874
  112. package/dist/src/gateway/dashboard.js.map +0 -1
  113. package/dist/src/gateway/deepseek-detect.d.ts +0 -14
  114. package/dist/src/gateway/deepseek-detect.js +0 -41
  115. package/dist/src/gateway/deepseek-detect.js.map +0 -1
  116. package/dist/src/gateway/live-dashboard-app/app.js +0 -2385
  117. package/dist/src/gateway/live-dashboard-assets.d.ts +0 -10
  118. package/dist/src/gateway/live-dashboard-assets.js +0 -74
  119. package/dist/src/gateway/live-dashboard-assets.js.map +0 -1
  120. package/dist/src/gateway/live-dashboard-command.d.ts +0 -60
  121. package/dist/src/gateway/live-dashboard-command.js +0 -334
  122. package/dist/src/gateway/live-dashboard-command.js.map +0 -1
  123. package/dist/src/gateway/live-dashboard-http.d.ts +0 -39
  124. package/dist/src/gateway/live-dashboard-http.js +0 -383
  125. package/dist/src/gateway/live-dashboard-http.js.map +0 -1
  126. package/dist/src/gateway/live-dashboard-protocol.d.ts +0 -34
  127. package/dist/src/gateway/live-dashboard-protocol.js +0 -114
  128. package/dist/src/gateway/live-dashboard-protocol.js.map +0 -1
  129. package/dist/src/gateway/live-dashboard-server.d.ts +0 -33
  130. package/dist/src/gateway/live-dashboard-server.js +0 -144
  131. package/dist/src/gateway/live-dashboard-server.js.map +0 -1
  132. package/dist/src/gateway/live-dashboard-stream.d.ts +0 -46
  133. package/dist/src/gateway/live-dashboard-stream.js +0 -234
  134. package/dist/src/gateway/live-dashboard-stream.js.map +0 -1
  135. package/dist/src/gateway/live-dashboard.d.ts +0 -28
  136. package/dist/src/gateway/live-dashboard.js +0 -154
  137. package/dist/src/gateway/live-dashboard.js.map +0 -1
  138. package/dist/src/gateway/locale.d.ts +0 -4
  139. package/dist/src/gateway/locale.js +0 -10
  140. package/dist/src/gateway/locale.js.map +0 -1
  141. package/dist/src/gateway/progress-watch-machine.d.ts +0 -45
  142. package/dist/src/gateway/progress-watch-machine.js +0 -70
  143. package/dist/src/gateway/progress-watch-machine.js.map +0 -1
  144. package/docs/CONFIGURATION.zh-CN.md +0 -97
  145. package/docs/DASHBOARD.md +0 -98
  146. package/docs/DASHBOARD.zh-CN.md +0 -49
  147. package/docs/DELIVERY.zh-CN.md +0 -55
@@ -1,1619 +0,0 @@
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-radius: var(--radius-sm);
770
- padding: 12px 16px;
771
- font-size: 13px;
772
- line-height: 1.5;
773
- color: var(--ink);
774
- }
775
- .notice[data-tone="info"] {
776
- border-color: var(--border-light);
777
- background: var(--pale-blue);
778
- }
779
- .notice[data-tone="warning"] {
780
- border-color: var(--coral-soft);
781
- background: var(--coral-wash-soft);
782
- }
783
- .notice[data-tone="error"] {
784
- border-color: var(--coral-soft);
785
- background: var(--error-tint);
786
- }
787
- .notice__label {
788
- font-family: var(--font-mono);
789
- font-size: 11px;
790
- letter-spacing: var(--mono-ls);
791
- text-transform: uppercase;
792
- color: var(--slate);
793
- white-space: nowrap;
794
- }
795
-
796
- /* --- 5.8 Exchange board (Overview) --------------------------------------- */
797
-
798
- .exchange-board {
799
- background: var(--soft-stone);
800
- border-radius: var(--radius-lg);
801
- padding: 32px;
802
- display: flex;
803
- flex-wrap: wrap;
804
- gap: 8px;
805
- align-items: stretch;
806
- justify-content: center;
807
- }
808
- .exchange-node {
809
- background: var(--canvas);
810
- border: 1px solid var(--hairline);
811
- border-radius: var(--radius-sm);
812
- padding: 20px;
813
- min-width: 210px;
814
- display: grid;
815
- gap: 10px;
816
- align-content: start;
817
- }
818
- .exchange-node__title {
819
- font-family: var(--font-mono);
820
- font-size: 14px;
821
- letter-spacing: var(--mono-ls);
822
- color: var(--ink);
823
- }
824
- .exchange-node__sub {
825
- font-family: var(--font-mono);
826
- font-size: 10px;
827
- letter-spacing: var(--mono-ls);
828
- text-transform: uppercase;
829
- color: var(--muted);
830
- margin-top: 4px;
831
- }
832
- .exchange-node__line { font-size: 13px; color: var(--body-muted); }
833
-
834
- .exchange-edges {
835
- display: grid;
836
- align-content: center;
837
- gap: 10px;
838
- }
839
- .exchange-edge {
840
- display: grid;
841
- gap: 6px;
842
- justify-items: center;
843
- align-self: center;
844
- padding: 0 8px;
845
- }
846
- .edge-label {
847
- font-family: var(--font-mono);
848
- font-size: 11px;
849
- letter-spacing: var(--mono-ls);
850
- text-transform: uppercase;
851
- color: var(--muted);
852
- }
853
- .edge-line {
854
- width: 110px;
855
- border-top: 1px solid var(--hairline);
856
- position: relative;
857
- }
858
- .edge-arrow {
859
- position: absolute;
860
- top: -8px;
861
- color: var(--slate);
862
- }
863
- .edge-arrow--in { left: -2px; }
864
- .edge-arrow--out { right: -2px; }
865
- .edge-queue {
866
- font-size: 13px;
867
- color: var(--muted);
868
- text-align: center;
869
- }
870
- .edge-queue[data-active="true"] { color: var(--ink); }
871
-
872
- /* Legible "no pair" state — informative, not alarming. */
873
- .no-pair {
874
- display: grid;
875
- align-content: center;
876
- justify-items: center;
877
- padding: 0 16px;
878
- max-width: 200px;
879
- }
880
- .no-pair__label {
881
- font-family: var(--font-mono);
882
- font-size: 11px;
883
- letter-spacing: var(--mono-ls);
884
- text-transform: uppercase;
885
- color: var(--slate);
886
- border: 1px dashed var(--hairline);
887
- border-radius: var(--radius-xs);
888
- padding: 4px 10px;
889
- }
890
- .no-pair__body {
891
- font-size: 12px;
892
- color: var(--body-muted);
893
- text-align: center;
894
- margin-top: 8px;
895
- }
896
- /* Long next-action / no-pair sentences render once beneath the board. */
897
- .exchange-notes { margin-top: 14px; }
898
- .inbound-policy {
899
- display: flex;
900
- align-items: center;
901
- gap: 10px;
902
- margin-bottom: 14px;
903
- padding: 9px 12px;
904
- border: 1px solid var(--hairline);
905
- border-radius: var(--radius-xs);
906
- color: var(--body-muted);
907
- font-size: 12px;
908
- }
909
- .inbound-policy[data-inbound-mode="open"] {
910
- border-color: var(--coral-deep);
911
- background: var(--coral-wash-soft);
912
- color: var(--ink);
913
- }
914
-
915
- /* --- 5.9 Attention list --------------------------------------------------- */
916
-
917
- .attention-list { display: grid; gap: 12px; }
918
- .attention-list + .footnote { margin-top: 12px; }
919
- .attention-item {
920
- border: 1px solid var(--hairline);
921
- border-radius: var(--radius-sm);
922
- padding: 18px 20px;
923
- display: grid;
924
- gap: 12px;
925
- }
926
- .attention-item__head {
927
- display: flex;
928
- gap: 12px;
929
- align-items: baseline;
930
- flex-wrap: wrap;
931
- }
932
- .attention-item__title { font-size: 16px; line-height: 1.5; }
933
- .attention-item__body { font-size: 14px; line-height: 1.5; color: var(--body-muted); }
934
- .attention-item__scope {
935
- font-family: var(--font-mono);
936
- font-size: 12px;
937
- letter-spacing: var(--mono-ls);
938
- color: var(--slate);
939
- }
940
- .attention-item__action { min-width: 340px; }
941
-
942
- /* --- 5.10 Pulse bars ------------------------------------------------------ */
943
-
944
- .pulse {
945
- display: flex;
946
- gap: 28px;
947
- align-items: flex-end;
948
- flex-wrap: wrap;
949
- }
950
- .pulse-bar-btn {
951
- background: none;
952
- border: none;
953
- padding: 0;
954
- cursor: pointer;
955
- display: grid;
956
- gap: 8px;
957
- justify-items: center;
958
- }
959
- .pulse-count { font-size: 14px; color: var(--ink); }
960
- /* Height comes from the React style prop (dynamic numeric). content-box
961
- restores the prototype's geometry (44px + border = 46px, height H + 2px). */
962
- .pulse-bar {
963
- display: block;
964
- box-sizing: content-box;
965
- width: 44px;
966
- min-height: 6px;
967
- border: 1px solid transparent;
968
- border-radius: var(--radius-xs);
969
- background: var(--soft-stone);
970
- }
971
- .pulse-bar[data-kind="positive"] { background: var(--pale-green); }
972
- .pulse-bar[data-kind="qualified"] { background: transparent; border-color: var(--deep-green); }
973
- .pulse-bar[data-kind="active"] { background: var(--pale-blue); }
974
- .pulse-bar[data-kind="progress"] { background: var(--soft-stone); }
975
- .pulse-bar[data-kind="warning"] { background: var(--coral-tint); }
976
- .pulse-bar[data-kind="indeterminate"] { background: var(--purple-tint); }
977
- .pulse-bar[data-kind="failure"] { background: var(--error-tint); }
978
- .pulse-bar[data-kind="inert"] { background: transparent; border-color: var(--hairline); }
979
- .pulse-bar[data-empty="true"] { border-color: var(--hairline); }
980
- .pulse-caption { font-size: 12px; color: var(--muted); margin-top: 14px; }
981
- .pulse-empty {
982
- font-size: 14px;
983
- color: var(--body-muted);
984
- margin-bottom: 14px;
985
- }
986
-
987
- /* --- 5.11 Topology (Routes) ---------------------------------------------- */
988
-
989
- .topology {
990
- background: var(--canvas);
991
- border: 1px solid var(--hairline);
992
- border-radius: var(--radius-lg);
993
- padding: 24px 28px;
994
- }
995
- .topology__heads {
996
- display: flex;
997
- justify-content: space-between;
998
- margin-bottom: 2px;
999
- }
1000
- .topology__head--claude { color: var(--coral-accent); }
1001
- .topology__head--codex { color: var(--action-blue); }
1002
- .topology__cols {
1003
- display: flex;
1004
- align-items: flex-start;
1005
- }
1006
- .topology__col {
1007
- flex: 1 1 0;
1008
- min-width: 0;
1009
- padding-top: 18px;
1010
- }
1011
- .topology__svg {
1012
- flex-shrink: 0;
1013
- display: block;
1014
- }
1015
- .topology__empty {
1016
- font-size: 13px;
1017
- color: var(--body-muted);
1018
- padding-top: 8px;
1019
- }
1020
- .topology__edge-list {
1021
- display: grid;
1022
- gap: 8px;
1023
- margin: 16px 0 0;
1024
- padding: 14px 0 0;
1025
- border-top: 1px solid var(--hairline);
1026
- list-style: none;
1027
- }
1028
- .topology__edge-list li {
1029
- display: flex;
1030
- flex-wrap: wrap;
1031
- align-items: center;
1032
- gap: 8px;
1033
- color: var(--body-muted);
1034
- font-family: var(--font-mono);
1035
- font-size: 12px;
1036
- overflow-wrap: anywhere;
1037
- }
1038
- .topo-row {
1039
- height: 64px;
1040
- display: flex;
1041
- align-items: center;
1042
- }
1043
- .topo-row--left { justify-content: flex-end; }
1044
- .topo-row--right { justify-content: flex-start; }
1045
- .topo-chip {
1046
- font-family: var(--font-mono);
1047
- font-size: 13px;
1048
- letter-spacing: var(--mono-ls);
1049
- padding: 7px 15px;
1050
- border: 1px solid var(--hairline);
1051
- border-radius: var(--radius-xl);
1052
- background: var(--canvas);
1053
- color: var(--ink);
1054
- max-width: 100%;
1055
- overflow: hidden;
1056
- text-overflow: ellipsis;
1057
- white-space: nowrap;
1058
- cursor: default;
1059
- transition: background-color .15s, border-color .15s, color .15s, opacity .15s;
1060
- }
1061
- .topo-chip[data-side="claude"] { border-color: var(--coral-accent); color: var(--ink); }
1062
- .topo-chip[data-side="codex"] { border-color: var(--action-blue); color: var(--action-blue); }
1063
- .topo-chip[data-candidate="true"] { border-style: dashed; color: var(--slate); }
1064
- .topo-chip[data-highlight="on"][data-side="claude"] { background: var(--coral-wash-hl); }
1065
- .topo-chip[data-highlight="on"][data-side="codex"] { background: var(--pale-blue); }
1066
- .topo-chip[data-highlight="off"] {
1067
- border-color: var(--hairline);
1068
- color: var(--muted);
1069
- opacity: .45;
1070
- }
1071
-
1072
- /* --- 5.12 Accordion (Routes detail) -------------------------------------- */
1073
-
1074
- .accordion { display: block; }
1075
- .accordion__row {
1076
- width: 100%;
1077
- display: flex;
1078
- gap: 14px;
1079
- align-items: center;
1080
- padding: 16px 8px;
1081
- border: none;
1082
- border-top: 1px solid var(--hairline);
1083
- background: transparent;
1084
- color: var(--ink);
1085
- text-align: left;
1086
- cursor: pointer;
1087
- }
1088
- .accordion__alias {
1089
- font-family: var(--font-mono);
1090
- font-size: 14px;
1091
- letter-spacing: var(--mono-ls);
1092
- flex: 1 1 auto;
1093
- min-width: 0;
1094
- overflow: hidden;
1095
- text-overflow: ellipsis;
1096
- white-space: nowrap;
1097
- }
1098
- .accordion__marker {
1099
- color: var(--muted);
1100
- flex-shrink: 0;
1101
- }
1102
- /* Green presence dot: selected sessions and registered codex routes. */
1103
- .status-dot {
1104
- width: 8px;
1105
- height: 8px;
1106
- border-radius: var(--radius-full);
1107
- background: #1e8e5a;
1108
- display: inline-block;
1109
- flex-shrink: 0;
1110
- }
1111
- .accordion__panel {
1112
- padding: 4px 8px 20px;
1113
- display: grid;
1114
- gap: 8px;
1115
- font-size: 14px;
1116
- color: var(--body-muted);
1117
- }
1118
- .accordion__panel .details-block { margin: 4px -8px 0; }
1119
- .accordion__panel .details-block > summary { padding-left: 8px; }
1120
- .detail-list { display: grid; gap: 8px; }
1121
- .detail-row { font-size: 14px; color: var(--body-muted); }
1122
- .detail-label { color: var(--muted); }
1123
- .detail-value { color: var(--ink); }
1124
- .detail-value--mono {
1125
- font-family: var(--font-mono);
1126
- font-size: 13px;
1127
- letter-spacing: var(--mono-ls);
1128
- }
1129
-
1130
- /* --- 5.13 Deliveries layout, rows, lifecycle ------------------------------ */
1131
-
1132
- .deliveries-layout {
1133
- display: grid;
1134
- grid-template-columns: minmax(0, 1fr) 360px;
1135
- gap: 48px;
1136
- align-items: start;
1137
- }
1138
- .deliveries-main { min-width: 0; }
1139
- .deliveries-rail {
1140
- border-left: 1px solid var(--hairline);
1141
- padding-left: 32px;
1142
- min-height: 300px;
1143
- min-width: 0;
1144
- }
1145
-
1146
- .watch-register {
1147
- margin: 24px 0 32px;
1148
- padding: 20px;
1149
- border: 1px solid var(--hairline);
1150
- background: var(--surface-warm);
1151
- }
1152
- .watch-register h2 { margin: 4px 0 0; font-size: 20px; }
1153
- .watch-register__empty { margin: 16px 0 0; color: var(--body-muted); }
1154
- .watch-grid {
1155
- display: grid;
1156
- grid-template-columns: repeat(2, minmax(0, 1fr));
1157
- gap: 12px;
1158
- margin-top: 16px;
1159
- }
1160
- .watch-card {
1161
- min-width: 0;
1162
- padding: 16px;
1163
- border: 1px solid var(--hairline);
1164
- background: var(--surface-card);
1165
- }
1166
- .watch-card[data-phase="episode"] { border-color: var(--coral-soft); background: var(--coral-wash-soft); }
1167
- .watch-card__head { display: flex; justify-content: space-between; gap: 12px; align-items: center; }
1168
- .watch-card > strong { display: block; margin-top: 10px; overflow-wrap: anywhere; }
1169
- .watch-card__facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0 0; }
1170
- .watch-card__facts div { min-width: 0; }
1171
- .watch-card__facts dt { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
1172
- .watch-card__facts dd { margin: 3px 0 0; font-size: 13px; overflow-wrap: anywhere; }
1173
- .watch-history { margin-top: 16px; color: var(--body-muted); }
1174
- .watch-history summary { cursor: pointer; }
1175
- .watch-history ol { margin: 10px 0 0; padding-left: 22px; }
1176
- .watch-history li { margin: 5px 0; }
1177
-
1178
- .delivery-group { margin-bottom: 28px; }
1179
- .delivery-group__head {
1180
- display: flex;
1181
- gap: 10px;
1182
- align-items: baseline;
1183
- margin-bottom: 4px;
1184
- flex-wrap: wrap;
1185
- }
1186
- .delivery-group__key {
1187
- font-family: var(--font-mono);
1188
- font-size: 12px;
1189
- letter-spacing: var(--mono-ls);
1190
- color: var(--slate);
1191
- }
1192
-
1193
- .delivery-list { display: block; }
1194
- .delivery-row {
1195
- width: 100%;
1196
- display: grid;
1197
- grid-template-columns: 150px minmax(0, 1fr) auto auto;
1198
- gap: 16px;
1199
- align-items: center;
1200
- padding: 16px 8px;
1201
- border: none;
1202
- border-top: 1px solid var(--hairline);
1203
- background: transparent;
1204
- color: var(--ink);
1205
- text-align: left;
1206
- cursor: pointer;
1207
- }
1208
- .delivery-row[aria-selected="true"] { background: var(--pale-blue); }
1209
- .delivery-row__id {
1210
- font-family: var(--font-mono);
1211
- font-size: 13px;
1212
- letter-spacing: var(--mono-ls);
1213
- }
1214
- .delivery-row__route {
1215
- font-size: 14px;
1216
- color: var(--body-muted);
1217
- overflow: hidden;
1218
- text-overflow: ellipsis;
1219
- white-space: nowrap;
1220
- }
1221
- .delivery-row__time { white-space: nowrap; }
1222
-
1223
- .detail-pane {
1224
- display: grid;
1225
- gap: 20px;
1226
- align-content: start;
1227
- }
1228
- .detail-pane__id {
1229
- font-family: var(--font-mono);
1230
- font-size: 14px;
1231
- letter-spacing: var(--mono-ls);
1232
- }
1233
- .detail-pane__head { display: grid; gap: 6px; }
1234
- .detail-pane__sub { font-size: 13px; color: var(--muted); }
1235
- .detail-pane__message-body {
1236
- margin: 6px 0 0;
1237
- padding: 10px 12px;
1238
- max-height: 240px;
1239
- overflow: auto;
1240
- font-family: var(--mono);
1241
- font-size: 12.5px;
1242
- line-height: 1.55;
1243
- white-space: pre-wrap;
1244
- overflow-wrap: anywhere;
1245
- border: 1px solid var(--hairline);
1246
- background: var(--surface-warm);
1247
- }
1248
- .detail-pane__empty {
1249
- font-size: 14px;
1250
- color: var(--muted);
1251
- padding-top: 8px;
1252
- }
1253
-
1254
- /* Lifecycle timeline: 8px dots + 1px connector */
1255
- .lifecycle { display: grid; gap: 0; }
1256
- .lifecycle-item {
1257
- display: grid;
1258
- grid-template-columns: 14px minmax(0, 1fr);
1259
- gap: 14px;
1260
- }
1261
- .lifecycle-rail {
1262
- display: grid;
1263
- grid-template-rows: auto 1fr;
1264
- justify-items: center;
1265
- }
1266
- .lifecycle-dot {
1267
- width: 8px;
1268
- height: 8px;
1269
- border-radius: var(--radius-full);
1270
- margin-top: 6px;
1271
- background: var(--hairline);
1272
- }
1273
- .lifecycle-dot[data-kind="positive"] { background: var(--deep-green); }
1274
- .lifecycle-dot[data-kind="qualified"] { background: var(--deep-green); }
1275
- .lifecycle-dot[data-kind="active"] { background: var(--action-blue); }
1276
- .lifecycle-dot[data-kind="progress"] { background: var(--slate); }
1277
- .lifecycle-dot[data-kind="warning"] { background: var(--coral-deep); }
1278
- .lifecycle-dot[data-kind="indeterminate"] { background: var(--purple-deep); }
1279
- .lifecycle-dot[data-kind="failure"] { background: var(--error); }
1280
- .lifecycle-dot[data-kind="inert"] { background: var(--muted); }
1281
- .lifecycle-dot[data-kind="unknown"] { background: var(--canvas); box-shadow: inset 0 0 0 1px var(--error); }
1282
- .lifecycle-connector {
1283
- width: 1px;
1284
- height: 100%;
1285
- background: var(--hairline);
1286
- }
1287
- .lifecycle-body { padding-bottom: 16px; }
1288
- .lifecycle-item:last-child .lifecycle-body { padding-bottom: 0; }
1289
- .lifecycle-head {
1290
- display: flex;
1291
- gap: 10px;
1292
- align-items: baseline;
1293
- flex-wrap: wrap;
1294
- }
1295
- .lifecycle-abs { font-size: 12px; color: var(--muted); }
1296
- .lifecycle-note { font-size: 13px; color: var(--body-muted); margin-top: 4px; }
1297
- .lifecycle-meaning { font-size: 12px; color: var(--muted); margin-top: 2px; }
1298
- .truncation-note { font-size: 12px; color: var(--muted); margin-top: 8px; }
1299
-
1300
- /* Frames (safe codes) */
1301
- .frames-list { display: grid; gap: 6px; }
1302
- .frame-item {
1303
- display: flex;
1304
- gap: 12px;
1305
- align-items: baseline;
1306
- flex-wrap: wrap;
1307
- }
1308
- .frame-code {
1309
- font-family: var(--font-mono);
1310
- font-size: 12px;
1311
- letter-spacing: var(--mono-ls);
1312
- border: 1px solid var(--hairline);
1313
- border-radius: var(--radius-xs);
1314
- padding: 2px 8px;
1315
- white-space: nowrap;
1316
- }
1317
-
1318
- .raw-json {
1319
- background: var(--soft-stone);
1320
- border-radius: var(--radius-xs);
1321
- padding: 12px;
1322
- font-family: var(--font-mono);
1323
- font-size: 12px;
1324
- line-height: 1.5;
1325
- overflow-x: auto;
1326
- margin: 10px 0 0;
1327
- }
1328
-
1329
- .empty-state {
1330
- display: grid;
1331
- gap: 12px;
1332
- padding: 24px 0;
1333
- }
1334
- .empty-state__text { font-size: 14px; color: var(--body-muted); }
1335
- .empty-state--activity { padding: 16px 0; max-width: none; }
1336
-
1337
- /* --- 5.14 Activity -------------------------------------------------------- */
1338
-
1339
- .activity-list { display: block; }
1340
- .activity-row {
1341
- display: grid;
1342
- grid-template-columns: 110px 110px minmax(0, 1fr);
1343
- gap: 16px;
1344
- align-items: baseline;
1345
- padding: 14px 8px;
1346
- border-top: 1px solid var(--hairline);
1347
- }
1348
- .activity-kind {
1349
- font-family: var(--font-mono);
1350
- font-size: 11px;
1351
- letter-spacing: var(--mono-ls);
1352
- text-transform: uppercase;
1353
- color: var(--slate);
1354
- }
1355
- .activity-text { font-size: 14px; line-height: 1.5; }
1356
-
1357
- /* --- 5.15 Tables & counters (Diagnostics) --------------------------------- */
1358
-
1359
- .data-table {
1360
- width: 100%;
1361
- border-collapse: collapse;
1362
- text-align: left;
1363
- }
1364
- .data-table th,
1365
- .data-table td {
1366
- padding: 12px 8px;
1367
- font-size: 14px;
1368
- font-weight: 400;
1369
- text-align: left;
1370
- border-top: 1px solid var(--hairline);
1371
- vertical-align: baseline;
1372
- }
1373
- .data-table thead th {
1374
- border-top: none;
1375
- font-family: var(--font-mono);
1376
- font-size: 12px;
1377
- letter-spacing: var(--mono-ls);
1378
- text-transform: uppercase;
1379
- color: var(--muted);
1380
- white-space: nowrap;
1381
- }
1382
- .data-table td.is-mono,
1383
- .data-table .cell-mono {
1384
- font-family: var(--font-mono);
1385
- font-size: 14px;
1386
- letter-spacing: 0;
1387
- }
1388
- .data-table caption.table-caption {
1389
- caption-side: top;
1390
- text-align: left;
1391
- padding: 0 0 8px;
1392
- font-family: var(--font-mono);
1393
- font-size: 12px;
1394
- letter-spacing: var(--mono-ls);
1395
- text-transform: uppercase;
1396
- color: var(--muted);
1397
- }
1398
-
1399
- /* Disclosure reads as a text link ("counters · show"), not a block header. */
1400
- .details-block { border-top: none; }
1401
- .details-block > summary {
1402
- width: fit-content;
1403
- list-style: none;
1404
- cursor: pointer;
1405
- padding: 0;
1406
- font-family: var(--font-body);
1407
- font-size: 14px;
1408
- letter-spacing: normal;
1409
- text-transform: none;
1410
- color: var(--action-blue);
1411
- text-decoration: underline;
1412
- text-underline-offset: 3px;
1413
- }
1414
- .details-block > summary::-webkit-details-marker { display: none; }
1415
- .details-block > summary:hover { opacity: .92; color: var(--action-blue); }
1416
- .details-block > summary:focus-visible { outline-offset: 2px; }
1417
- .details-block__content { padding: 14px 0 20px; }
1418
-
1419
- /* Counters render as a real table (caption + row headers kept for AT) with
1420
- the prototype's list geometry. */
1421
- .counters-list { max-width: 480px; }
1422
- .data-table--counters th,
1423
- .data-table--counters td { padding: 10px 8px; }
1424
- .data-table--counters th[scope="row"] { color: var(--body-muted); }
1425
- .data-table--counters td { text-align: right; }
1426
-
1427
- .env-name {
1428
- font-family: var(--font-mono);
1429
- font-size: 12px;
1430
- letter-spacing: var(--mono-ls);
1431
- color: var(--body-muted);
1432
- }
1433
- .setting-list { display: grid; gap: 12px; }
1434
- .setting-row {
1435
- display: grid;
1436
- gap: 6px;
1437
- padding: 12px 0;
1438
- border-top: 1px solid var(--hairline);
1439
- font-size: 14px;
1440
- }
1441
-
1442
- /* --- 5.16 Misc affordances ------------------------------------------------ */
1443
-
1444
- /* The small round "i" that carries a tooltip; focusable for keyboard users. */
1445
- .info-dot {
1446
- box-sizing: content-box; /* 16px + 1px border = the prototype's 18px dot */
1447
- width: 16px;
1448
- height: 16px;
1449
- border-radius: var(--radius-full);
1450
- border: 1px solid var(--hairline);
1451
- color: var(--muted);
1452
- font-family: var(--font-body);
1453
- font-size: 10px;
1454
- line-height: 1;
1455
- display: inline-flex;
1456
- align-items: center;
1457
- justify-content: center;
1458
- cursor: default;
1459
- flex-shrink: 0;
1460
- }
1461
- .time-ago {
1462
- color: var(--muted);
1463
- font-size: 14px;
1464
- white-space: nowrap;
1465
- }
1466
- .succession-card {
1467
- border: 1px solid var(--hairline);
1468
- border-radius: var(--radius-sm);
1469
- padding: 20px;
1470
- display: grid;
1471
- gap: 8px;
1472
- font-size: 14px;
1473
- max-width: 640px;
1474
- }
1475
- .succession-card__head {
1476
- display: flex;
1477
- justify-content: space-between;
1478
- gap: 12px;
1479
- flex-wrap: wrap;
1480
- }
1481
- .succession-card__title { font-size: 14px; line-height: 1.4; }
1482
- .succession-note {
1483
- font-size: 14px;
1484
- color: var(--body-muted);
1485
- font-style: italic;
1486
- }
1487
-
1488
- /* ==========================================================================
1489
- 6. TOOLTIP (tokenized; hover AND keyboard)
1490
- ========================================================================== */
1491
-
1492
- [data-tip] { position: relative; }
1493
-
1494
- /* Focusable tooltip wrapper hugs its dot so the anchor and focus ring trace
1495
- the circle, not the line box. */
1496
- .tooltip {
1497
- display: inline-flex;
1498
- align-items: center;
1499
- border-radius: var(--radius-full);
1500
- }
1501
-
1502
- [data-tip]:hover::after,
1503
- [data-tip]:focus-visible::after {
1504
- content: attr(data-tip);
1505
- position: absolute;
1506
- top: calc(100% + 6px);
1507
- right: 0;
1508
- background: var(--primary);
1509
- color: var(--on-primary);
1510
- font: 400 12px/1.4 var(--font-body);
1511
- padding: 4px 10px;
1512
- border-radius: var(--radius-xs);
1513
- white-space: nowrap;
1514
- z-index: 10;
1515
- pointer-events: none;
1516
- }
1517
-
1518
- [data-tip-wrap][data-tip]:hover::after,
1519
- [data-tip-wrap][data-tip]:focus-visible::after {
1520
- white-space: normal;
1521
- width: 320px;
1522
- max-width: 80vw;
1523
- left: 0;
1524
- right: auto;
1525
- }
1526
-
1527
- /* ==========================================================================
1528
- 7. RESPONSIVE — single breakpoint
1529
- ========================================================================== */
1530
-
1531
- @media (max-width: 760px) {
1532
- .header-bar { padding: 16px 20px 0; gap: 16px; }
1533
- .app-nav { padding: 14px 20px 0; gap: 18px; }
1534
- .app-main { padding: 28px 20px 64px; }
1535
- .app-footer { padding: 0 20px 32px; }
1536
-
1537
- .header-spacer { display: none; }
1538
- .header-search { width: 100%; flex: 1 1 100%; box-sizing: border-box; }
1539
- .header-meta { width: 100%; }
1540
-
1541
- .grid-2 { grid-template-columns: 1fr; }
1542
- .action-panel { grid-template-columns: 1fr; }
1543
- .grid-cards { grid-template-columns: 1fr; }
1544
-
1545
- .deliveries-layout {
1546
- grid-template-columns: minmax(0, 1fr);
1547
- gap: 28px;
1548
- }
1549
- .watch-grid { grid-template-columns: minmax(0, 1fr); }
1550
- .deliveries-rail {
1551
- border-left: none;
1552
- border-top: 1px solid var(--hairline);
1553
- padding-left: 0;
1554
- padding-top: 24px;
1555
- min-height: 0;
1556
- }
1557
-
1558
- .delivery-row {
1559
- grid-template-columns: minmax(0, 1fr) auto;
1560
- row-gap: 8px;
1561
- }
1562
- .activity-row {
1563
- grid-template-columns: 96px minmax(0, 1fr);
1564
- grid-template-areas: "time kind" "time text";
1565
- }
1566
- .activity-row > .time-ago { grid-area: time; }
1567
- .activity-kind { grid-area: kind; }
1568
- .activity-row > .activity-text { grid-area: text; }
1569
-
1570
- .exchange-board { padding: 20px; }
1571
- .panel { padding: 20px; }
1572
- .panel--warm { padding: 20px; }
1573
- .topology { padding: 18px 16px; }
1574
- .topology__cols { flex-wrap: wrap; }
1575
- .topology__svg { display: none; }
1576
- .topology__col { flex: 1 1 100%; padding-top: 8px; }
1577
- .topo-row { height: auto; padding: 6px 0; justify-content: flex-start; }
1578
-
1579
- .filters { gap: 18px; }
1580
- .pulse { gap: 16px; }
1581
- }
1582
-
1583
- /* ==========================================================================
1584
- 8. REDUCED MOTION
1585
- ========================================================================== */
1586
-
1587
- @media (prefers-reduced-motion: reduce) {
1588
- *,
1589
- *::before,
1590
- *::after {
1591
- transition: none !important;
1592
- animation: none !important;
1593
- scroll-behavior: auto !important;
1594
- }
1595
- }
1596
-
1597
- /* ==========================================================================
1598
- 9. FORCED COLORS — meaning must never rest on background alone
1599
- ========================================================================== */
1600
-
1601
- @media (forced-colors: active) {
1602
- .chip { border: 1px solid ButtonText; }
1603
- .pill[aria-pressed="true"] { outline: 2px solid Highlight; }
1604
- .lifecycle-dot {
1605
- forced-color-adjust: none;
1606
- border: 1px solid ButtonText;
1607
- }
1608
- .pulse-bar {
1609
- forced-color-adjust: none;
1610
- border: 1px solid ButtonText;
1611
- }
1612
- .topo-chip {
1613
- border: 1px solid ButtonText;
1614
- opacity: 1;
1615
- }
1616
- .topo-chip[data-highlight="on"] { outline: 2px solid Highlight; }
1617
- .delivery-row[aria-selected="true"] { outline: 2px solid Highlight; }
1618
- .notice { border: 1px solid CanvasText; }
1619
- }