@allin-ai/agent-client 0.1.1 → 0.2.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 (146) hide show
  1. package/README.md +75 -42
  2. package/dist/cli/commands.d.ts +9 -0
  3. package/dist/cli/commands.d.ts.map +1 -1
  4. package/dist/cli/commands.js +244 -7
  5. package/dist/cli/commands.js.map +1 -1
  6. package/dist/client/index.d.ts +7 -0
  7. package/dist/client/index.d.ts.map +1 -0
  8. package/dist/client/index.js +6 -0
  9. package/dist/client/index.js.map +1 -0
  10. package/dist/client/state-store.d.ts +1 -1
  11. package/dist/client/state-store.d.ts.map +1 -1
  12. package/dist/client/state-store.js +1 -1
  13. package/dist/client/state-store.js.map +1 -1
  14. package/dist/client/supervisor.d.ts +37 -1
  15. package/dist/client/supervisor.d.ts.map +1 -1
  16. package/dist/client/supervisor.js +159 -10
  17. package/dist/client/supervisor.js.map +1 -1
  18. package/dist/client/transport.d.ts +5 -1
  19. package/dist/client/transport.d.ts.map +1 -1
  20. package/dist/client/types.d.ts +6 -64
  21. package/dist/client/types.d.ts.map +1 -1
  22. package/dist/client/types.js +9 -12
  23. package/dist/client/types.js.map +1 -1
  24. package/dist/client/wire.d.ts +2 -31
  25. package/dist/client/wire.d.ts.map +1 -1
  26. package/dist/client/wire.js +2 -301
  27. package/dist/client/wire.js.map +1 -1
  28. package/dist/client/ws-transport.d.ts +5 -1
  29. package/dist/client/ws-transport.d.ts.map +1 -1
  30. package/dist/client/ws-transport.js +30 -6
  31. package/dist/client/ws-transport.js.map +1 -1
  32. package/dist/config.d.ts +10 -1
  33. package/dist/config.d.ts.map +1 -1
  34. package/dist/config.js +30 -1
  35. package/dist/config.js.map +1 -1
  36. package/dist/control.d.ts +6 -0
  37. package/dist/control.d.ts.map +1 -1
  38. package/dist/control.js +25 -0
  39. package/dist/control.js.map +1 -1
  40. package/dist/demo/index.d.ts +3 -0
  41. package/dist/demo/index.d.ts.map +1 -0
  42. package/dist/demo/index.js +2 -0
  43. package/dist/demo/index.js.map +1 -0
  44. package/dist/demo/observable-store.d.ts +55 -0
  45. package/dist/demo/observable-store.d.ts.map +1 -0
  46. package/dist/demo/observable-store.js +88 -0
  47. package/dist/demo/observable-store.js.map +1 -0
  48. package/dist/demo/projection.d.ts +23 -0
  49. package/dist/demo/projection.d.ts.map +1 -0
  50. package/dist/demo/projection.js +47 -0
  51. package/dist/demo/projection.js.map +1 -0
  52. package/dist/demo/site.d.ts +30 -0
  53. package/dist/demo/site.d.ts.map +1 -0
  54. package/dist/demo/site.js +330 -0
  55. package/dist/demo/site.js.map +1 -0
  56. package/dist/demo/static.d.ts +5 -0
  57. package/dist/demo/static.d.ts.map +1 -0
  58. package/dist/demo/static.js +53 -0
  59. package/dist/demo/static.js.map +1 -0
  60. package/dist/demo/token-registry.d.ts +20 -0
  61. package/dist/demo/token-registry.d.ts.map +1 -0
  62. package/dist/demo/token-registry.js +34 -0
  63. package/dist/demo/token-registry.js.map +1 -0
  64. package/dist/demo/types.d.ts +8 -0
  65. package/dist/demo/types.d.ts.map +1 -0
  66. package/dist/demo/types.js +2 -0
  67. package/dist/demo/types.js.map +1 -0
  68. package/dist/hub/agent-hub.d.ts +4 -0
  69. package/dist/hub/agent-hub.d.ts.map +1 -0
  70. package/dist/hub/agent-hub.js +352 -0
  71. package/dist/hub/agent-hub.js.map +1 -0
  72. package/dist/hub/index.d.ts +3 -0
  73. package/dist/hub/index.d.ts.map +1 -0
  74. package/dist/hub/index.js +2 -0
  75. package/dist/hub/index.js.map +1 -0
  76. package/dist/hub/testkit/index.d.ts +4 -0
  77. package/dist/hub/testkit/index.d.ts.map +1 -0
  78. package/dist/hub/testkit/index.js +4 -0
  79. package/dist/hub/testkit/index.js.map +1 -0
  80. package/dist/hub/testkit/memory-hub.d.ts +23 -0
  81. package/dist/hub/testkit/memory-hub.d.ts.map +1 -0
  82. package/dist/hub/testkit/memory-hub.js +33 -0
  83. package/dist/hub/testkit/memory-hub.js.map +1 -0
  84. package/dist/hub/testkit/memory-store.d.ts +62 -0
  85. package/dist/hub/testkit/memory-store.d.ts.map +1 -0
  86. package/dist/hub/testkit/memory-store.js +186 -0
  87. package/dist/hub/testkit/memory-store.js.map +1 -0
  88. package/dist/hub/types.d.ts +118 -0
  89. package/dist/hub/types.d.ts.map +1 -0
  90. package/dist/hub/types.js +2 -0
  91. package/dist/hub/types.js.map +1 -0
  92. package/dist/hub.d.ts +2 -82
  93. package/dist/hub.d.ts.map +1 -1
  94. package/dist/hub.js +2 -411
  95. package/dist/hub.js.map +1 -1
  96. package/dist/index.d.ts +3 -4
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +4 -4
  99. package/dist/index.js.map +1 -1
  100. package/dist/login.d.ts +22 -0
  101. package/dist/login.d.ts.map +1 -0
  102. package/dist/login.js +94 -0
  103. package/dist/login.js.map +1 -0
  104. package/dist/protocol/index.d.ts +3 -0
  105. package/dist/protocol/index.d.ts.map +1 -0
  106. package/dist/protocol/index.js +3 -0
  107. package/dist/protocol/index.js.map +1 -0
  108. package/dist/protocol/types.d.ts +111 -0
  109. package/dist/protocol/types.d.ts.map +1 -0
  110. package/dist/protocol/types.js +13 -0
  111. package/dist/protocol/types.js.map +1 -0
  112. package/dist/protocol/wire.d.ts +25 -0
  113. package/dist/protocol/wire.d.ts.map +1 -0
  114. package/dist/protocol/wire.js +337 -0
  115. package/dist/protocol/wire.js.map +1 -0
  116. package/dist/runtime/claude.d.ts +32 -9
  117. package/dist/runtime/claude.d.ts.map +1 -1
  118. package/dist/runtime/claude.js +18 -2
  119. package/dist/runtime/claude.js.map +1 -1
  120. package/dist/runtime/codex.d.ts +12 -0
  121. package/dist/runtime/codex.d.ts.map +1 -1
  122. package/dist/runtime/codex.js +31 -6
  123. package/dist/runtime/codex.js.map +1 -1
  124. package/dist/runtime/index.d.ts +4 -4
  125. package/dist/runtime/index.d.ts.map +1 -1
  126. package/dist/runtime/index.js +1 -1
  127. package/dist/runtime/index.js.map +1 -1
  128. package/dist/runtime/pi.d.ts +25 -2
  129. package/dist/runtime/pi.d.ts.map +1 -1
  130. package/dist/runtime/pi.js +20 -3
  131. package/dist/runtime/pi.js.map +1 -1
  132. package/dist/runtime/registry.d.ts +9 -4
  133. package/dist/runtime/registry.d.ts.map +1 -1
  134. package/dist/runtime/registry.js +7 -7
  135. package/dist/runtime/registry.js.map +1 -1
  136. package/dist/runtime/runner-child.js +48 -4
  137. package/dist/runtime/runner-child.js.map +1 -1
  138. package/dist/wire.d.ts +2 -23
  139. package/dist/wire.d.ts.map +1 -1
  140. package/dist/wire.js +2 -6
  141. package/dist/wire.js.map +1 -1
  142. package/package.json +80 -24
  143. package/web/app.js +253 -0
  144. package/web/index.html +421 -0
  145. package/web/login.html +85 -0
  146. package/web/style.css +484 -0
package/web/style.css ADDED
@@ -0,0 +1,484 @@
1
+ /* 设计基线:dark-tech 单主题;单一强调色 emerald;统一 10px 圆角;
2
+ 系统字体栈(零依赖,无外部资源);动效仅 hover/feedback 过渡。 */
3
+
4
+ :root {
5
+ color-scheme: dark;
6
+ --bg: #0a0f0d;
7
+ --bg-raised: #101815;
8
+ --bg-tint: rgba(52, 211, 153, 0.08);
9
+ --border: rgba(154, 168, 161, 0.18);
10
+ --border-strong: rgba(154, 168, 161, 0.34);
11
+ --text: #e7edea;
12
+ --text-dim: #93a39b;
13
+ --accent: #34d399;
14
+ --accent-ink: #06281c;
15
+ --danger: #f0a4a4;
16
+ --radius: 10px;
17
+ --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
18
+ --sans: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
19
+ }
20
+
21
+ * { box-sizing: border-box; }
22
+
23
+ html { scroll-behavior: smooth; }
24
+ @media (prefers-reduced-motion: reduce) {
25
+ html { scroll-behavior: auto; }
26
+ }
27
+
28
+ body {
29
+ margin: 0;
30
+ background: var(--bg);
31
+ color: var(--text);
32
+ font-family: var(--sans);
33
+ line-height: 1.7;
34
+ }
35
+
36
+ /* ---------- nav ---------- */
37
+
38
+ .nav {
39
+ position: sticky;
40
+ top: 0;
41
+ z-index: 10;
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: space-between;
45
+ height: 60px;
46
+ padding: 0 clamp(1rem, 4vw, 3rem);
47
+ background: rgba(10, 15, 13, 0.92);
48
+ backdrop-filter: blur(8px);
49
+ border-bottom: 1px solid var(--border);
50
+ }
51
+
52
+ .brand {
53
+ font-family: var(--mono);
54
+ font-size: 0.95rem;
55
+ color: var(--text);
56
+ text-decoration: none;
57
+ }
58
+ .brand::before {
59
+ content: "▮ ";
60
+ color: var(--accent);
61
+ }
62
+
63
+ .nav-links { display: flex; gap: 1.75rem; }
64
+ .nav-links a {
65
+ color: var(--text-dim);
66
+ text-decoration: none;
67
+ font-size: 0.9rem;
68
+ transition: color 0.2s ease;
69
+ }
70
+ .nav-links a:hover { color: var(--text); }
71
+
72
+ main {
73
+ max-width: 1080px;
74
+ margin: 0 auto;
75
+ padding: 0 clamp(1rem, 4vw, 3rem);
76
+ }
77
+
78
+ /* ---------- hero ---------- */
79
+
80
+ .hero {
81
+ display: grid;
82
+ grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
83
+ gap: clamp(2rem, 5vw, 4.5rem);
84
+ align-items: center;
85
+ min-height: calc(100dvh - 60px);
86
+ padding: 4rem 0 5rem;
87
+ }
88
+
89
+ .hero-copy h1 {
90
+ margin: 0;
91
+ font-size: clamp(2.2rem, 4.5vw, 3.4rem);
92
+ line-height: 1.15;
93
+ letter-spacing: -0.02em;
94
+ font-weight: 700;
95
+ }
96
+
97
+ .subtext {
98
+ margin: 1.25rem 0 2rem;
99
+ max-width: 34em;
100
+ color: var(--text-dim);
101
+ font-size: 1rem;
102
+ }
103
+
104
+ .cta-row { display: flex; gap: 0.9rem; flex-wrap: wrap; }
105
+
106
+ .btn {
107
+ display: inline-flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ padding: 0.65rem 1.4rem;
111
+ border-radius: var(--radius);
112
+ border: 1px solid transparent;
113
+ font: inherit;
114
+ font-size: 0.95rem;
115
+ text-decoration: none;
116
+ cursor: pointer;
117
+ transition: transform 0.15s ease, border-color 0.2s ease, background 0.2s ease;
118
+ }
119
+ .btn:active { transform: translateY(1px); }
120
+
121
+ .btn.primary {
122
+ background: var(--accent);
123
+ color: var(--accent-ink);
124
+ font-weight: 600;
125
+ }
126
+ .btn.primary:hover { filter: brightness(1.08); }
127
+
128
+ .btn.ghost {
129
+ border-color: var(--border-strong);
130
+ color: var(--text);
131
+ }
132
+ .btn.ghost:hover { border-color: var(--accent); }
133
+
134
+ .btn.full { width: 100%; margin-top: 0.5rem; }
135
+
136
+ /* hero terminal(真实命令,非截图) */
137
+
138
+ .hero-terminal {
139
+ border: 1px solid var(--border);
140
+ border-radius: var(--radius);
141
+ background: var(--bg-raised);
142
+ overflow: hidden;
143
+ box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
144
+ }
145
+
146
+ .term-bar {
147
+ display: flex;
148
+ align-items: center;
149
+ gap: 0.6rem;
150
+ padding: 0.55rem 0.9rem;
151
+ border-bottom: 1px solid var(--border);
152
+ }
153
+
154
+ .term-dot {
155
+ width: 9px;
156
+ height: 9px;
157
+ border-radius: 50%;
158
+ background: var(--accent);
159
+ }
160
+ .term-title {
161
+ font-family: var(--mono);
162
+ font-size: 0.78rem;
163
+ color: var(--text-dim);
164
+ flex: 1;
165
+ }
166
+
167
+ .copy-btn {
168
+ font: inherit;
169
+ font-size: 0.75rem;
170
+ color: var(--text-dim);
171
+ background: none;
172
+ border: 1px solid var(--border);
173
+ border-radius: var(--radius);
174
+ padding: 0.15rem 0.6rem;
175
+ cursor: pointer;
176
+ transition: color 0.2s ease, border-color 0.2s ease;
177
+ }
178
+ .copy-btn:hover { color: var(--accent); border-color: var(--accent); }
179
+
180
+ .term-body {
181
+ margin: 0;
182
+ padding: 1.1rem 1.25rem 1.25rem;
183
+ font-family: var(--mono);
184
+ font-size: 0.83rem;
185
+ line-height: 1.9;
186
+ overflow-x: auto;
187
+ color: var(--text);
188
+ }
189
+ .term-body .c { color: var(--text-dim); }
190
+
191
+ /* ---------- sections ---------- */
192
+
193
+ .section { padding: 4.5rem 0; }
194
+ .section > h2 {
195
+ margin: 0 0 2rem;
196
+ font-size: clamp(1.4rem, 2.5vw, 1.8rem);
197
+ letter-spacing: -0.01em;
198
+ }
199
+
200
+ /* steps:编号行式,非等宽卡片 */
201
+
202
+ .steps {
203
+ list-style: none;
204
+ margin: 0;
205
+ padding: 0;
206
+ display: grid;
207
+ gap: 1.5rem;
208
+ }
209
+ .steps li {
210
+ display: grid;
211
+ grid-template-columns: 3.5rem 1fr;
212
+ gap: 1.25rem;
213
+ align-items: start;
214
+ }
215
+ .step-no {
216
+ font-family: var(--mono);
217
+ font-size: 1.5rem;
218
+ color: var(--accent);
219
+ line-height: 1.2;
220
+ }
221
+ .steps h3 { margin: 0 0 0.35rem; font-size: 1.05rem; }
222
+ .steps p { margin: 0; color: var(--text-dim); max-width: 62ch; }
223
+
224
+ /* scenarios:场景块 = 说明行 + 代码块,区别于 steps/exports 的版式 */
225
+
226
+ .scenario {
227
+ border: 1px solid var(--border);
228
+ border-radius: var(--radius);
229
+ background: var(--bg-raised);
230
+ margin-bottom: 1.1rem;
231
+ overflow: hidden;
232
+ }
233
+ .scenario-head {
234
+ display: grid;
235
+ grid-template-columns: 3rem 1fr;
236
+ gap: 1rem;
237
+ align-items: start;
238
+ padding: 1.1rem 1.25rem 0.25rem;
239
+ }
240
+ .scenario-head .step-no { font-size: 1.1rem; }
241
+ .scenario-head h3 { margin: 0 0 0.3rem; font-size: 1.02rem; }
242
+ .scenario-head p { margin: 0; color: var(--text-dim); font-size: 0.9rem; max-width: 62ch; }
243
+
244
+ .code-block {
245
+ margin: 1rem 0 0;
246
+ padding: 1rem 1.25rem 1.15rem;
247
+ background: var(--bg);
248
+ border-top: 1px solid var(--border);
249
+ font-family: var(--mono);
250
+ font-size: 0.8rem;
251
+ line-height: 1.85;
252
+ overflow-x: auto;
253
+ color: var(--text);
254
+ }
255
+ .code-block .c { color: var(--text-dim); }
256
+
257
+ /* ---------- exports ---------- */
258
+
259
+ .exports-grid {
260
+ display: grid;
261
+ grid-template-columns: repeat(2, 1fr);
262
+ gap: 0.9rem;
263
+ }
264
+ .export-cell {
265
+ border: 1px solid var(--border);
266
+ border-radius: var(--radius);
267
+ padding: 1rem 1.2rem;
268
+ }
269
+ .export-cell.tint { background: var(--bg-tint); border-color: rgba(52, 211, 153, 0.35); }
270
+ .export-cell code {
271
+ font-family: var(--mono);
272
+ font-size: 0.88rem;
273
+ color: var(--accent);
274
+ }
275
+ .export-cell p { margin: 0.35rem 0 0; color: var(--text-dim); font-size: 0.9rem; }
276
+
277
+ /* ---------- console ---------- */
278
+
279
+ .console-head {
280
+ display: flex;
281
+ align-items: baseline;
282
+ justify-content: space-between;
283
+ gap: 1rem;
284
+ }
285
+ .console-head h2 { margin: 0; }
286
+
287
+ /* 状态点为真实语义(SSE 连接状态),全页仅此一处 */
288
+ .sse-status {
289
+ font-family: var(--mono);
290
+ font-size: 0.78rem;
291
+ color: var(--text-dim);
292
+ display: inline-flex;
293
+ align-items: center;
294
+ gap: 0.5rem;
295
+ }
296
+ .sse-status::before {
297
+ content: "";
298
+ width: 8px;
299
+ height: 8px;
300
+ border-radius: 50%;
301
+ background: var(--text-dim);
302
+ }
303
+ .sse-status[data-state="online"] { color: var(--accent); }
304
+ .sse-status[data-state="online"]::before { background: var(--accent); }
305
+ .sse-status[data-state="offline"] { color: var(--danger); }
306
+ .sse-status[data-state="offline"]::before { background: var(--danger); }
307
+
308
+ .hint { color: var(--text-dim); font-size: 0.88rem; margin: 0.75rem 0 0; }
309
+ .error { color: var(--danger); }
310
+
311
+ .console-grid {
312
+ display: grid;
313
+ grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
314
+ gap: 0.9rem;
315
+ margin-top: 1.5rem;
316
+ }
317
+ .console-left { display: grid; gap: 0.9rem; align-content: start; }
318
+
319
+ .panel {
320
+ border: 1px solid var(--border);
321
+ border-radius: var(--radius);
322
+ padding: 1.1rem 1.25rem;
323
+ background: var(--bg-raised);
324
+ }
325
+ .panel h3 { margin: 0 0 0.85rem; font-size: 0.95rem; color: var(--text); }
326
+
327
+ .client-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.45rem; }
328
+ .client-list li {
329
+ font-family: var(--mono);
330
+ font-size: 0.82rem;
331
+ display: flex;
332
+ justify-content: space-between;
333
+ gap: 1rem;
334
+ }
335
+ .client-list li.empty {
336
+ font-family: var(--sans);
337
+ color: var(--text-dim);
338
+ font-size: 0.88rem;
339
+ }
340
+ .client-list .state-on { color: var(--accent); }
341
+ .client-list .state-off { color: var(--text-dim); }
342
+
343
+ .field-label {
344
+ display: block;
345
+ font-size: 0.8rem;
346
+ color: var(--text-dim);
347
+ margin: 0.75rem 0 0.3rem;
348
+ }
349
+ .field-label:first-of-type { margin-top: 0; }
350
+
351
+ select, textarea {
352
+ display: block;
353
+ width: 100%;
354
+ font: inherit;
355
+ font-size: 0.9rem;
356
+ color: var(--text);
357
+ background: var(--bg);
358
+ border: 1px solid var(--border-strong);
359
+ border-radius: var(--radius);
360
+ padding: 0.5rem 0.65rem;
361
+ }
362
+ select:focus-visible, textarea:focus-visible {
363
+ outline: 2px solid var(--accent);
364
+ outline-offset: 1px;
365
+ }
366
+ textarea { resize: vertical; font-family: var(--mono); font-size: 0.84rem; }
367
+ textarea::placeholder { color: var(--text-dim); }
368
+
369
+ .timeline-panel { display: flex; flex-direction: column; min-height: 320px; }
370
+ .timeline {
371
+ list-style: none;
372
+ margin: 0;
373
+ padding: 0;
374
+ flex: 1;
375
+ overflow-y: auto;
376
+ max-height: 460px;
377
+ font-family: var(--mono);
378
+ font-size: 0.8rem;
379
+ display: grid;
380
+ gap: 0.4rem;
381
+ align-content: start;
382
+ }
383
+ .timeline li { color: var(--text-dim); }
384
+ .timeline li:first-child { color: var(--text); }
385
+ .timeline li .t { color: var(--accent); }
386
+
387
+ /* inventory tables:等宽字体 + 行分隔线,对齐面板内列表风格 */
388
+ #inventory-platforms h4,
389
+ #inventory-plugins h4 {
390
+ margin: 0.9rem 0 0.4rem;
391
+ font-size: 0.82rem;
392
+ color: var(--text-dim);
393
+ font-weight: 600;
394
+ }
395
+ .inventory-table {
396
+ width: 100%;
397
+ border-collapse: collapse;
398
+ font-family: var(--mono);
399
+ font-size: 0.78rem;
400
+ }
401
+ .inventory-table th {
402
+ text-align: left;
403
+ color: var(--text-dim);
404
+ font-weight: 500;
405
+ padding: 0.3rem 0.5rem 0.3rem 0;
406
+ border-bottom: 1px solid var(--border-strong);
407
+ }
408
+ .inventory-table td {
409
+ padding: 0.3rem 0.5rem 0.3rem 0;
410
+ border-bottom: 1px solid var(--border);
411
+ color: var(--text);
412
+ word-break: break-all;
413
+ }
414
+ .inventory-table tr:last-child td { border-bottom: none; }
415
+ .inventory-table .row-failed td { color: var(--danger); }
416
+ .inventory-table .row-muted td { opacity: 0.5; }
417
+
418
+ /* ---------- footer ---------- */
419
+
420
+ .footer {
421
+ max-width: 1080px;
422
+ margin: 0 auto;
423
+ padding: 2.5rem clamp(1rem, 4vw, 3rem) 3rem;
424
+ display: flex;
425
+ justify-content: space-between;
426
+ color: var(--text-dim);
427
+ font-size: 0.85rem;
428
+ border-top: 1px solid var(--border);
429
+ }
430
+
431
+ /* ---------- login page ---------- */
432
+
433
+ .login-wrap {
434
+ min-height: 100dvh;
435
+ display: grid;
436
+ place-items: center;
437
+ padding: 1.5rem;
438
+ }
439
+
440
+ .login-card {
441
+ width: min(26rem, 100%);
442
+ border: 1px solid var(--border);
443
+ border-radius: var(--radius);
444
+ background: var(--bg-raised);
445
+ padding: 2rem 2.2rem 2.2rem;
446
+ box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
447
+ }
448
+ .login-card .brand { display: inline-block; margin-bottom: 1.5rem; }
449
+ .login-card h1 { margin: 0 0 0.5rem; font-size: 1.5rem; letter-spacing: -0.01em; }
450
+ .login-card .subtext { margin: 0 0 1.5rem; }
451
+
452
+ .login-client {
453
+ border: 1px solid var(--border);
454
+ border-radius: var(--radius);
455
+ background: var(--bg);
456
+ padding: 0.75rem 1rem;
457
+ margin-bottom: 1.25rem;
458
+ }
459
+ .login-client code {
460
+ font-family: var(--mono);
461
+ font-size: 0.9rem;
462
+ color: var(--accent);
463
+ word-break: break-all;
464
+ }
465
+ .login-card .cta-row { margin-top: 1.5rem; }
466
+ .login-card .hint { margin: 0; }
467
+
468
+ /* ---------- responsive ---------- */
469
+
470
+ @media (max-width: 880px) {
471
+ .hero {
472
+ grid-template-columns: 1fr;
473
+ min-height: 0;
474
+ padding: 3rem 0 3.5rem;
475
+ gap: 2.25rem;
476
+ }
477
+ .exports-grid { grid-template-columns: 1fr; }
478
+ .console-grid { grid-template-columns: 1fr; }
479
+ .steps li { grid-template-columns: 2.5rem 1fr; }
480
+ }
481
+
482
+ @media (prefers-reduced-motion: reduce) {
483
+ * { transition: none !important; }
484
+ }