fraim-hub 2.0.204

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 (120) hide show
  1. package/README.md +467 -0
  2. package/bin/fraim-hub.js +17 -0
  3. package/dist/src/ai-hub/brand-store.js +17 -0
  4. package/dist/src/ai-hub/catalog.js +412 -0
  5. package/dist/src/ai-hub/cert-store.js +70 -0
  6. package/dist/src/ai-hub/cli.js +212 -0
  7. package/dist/src/ai-hub/configured-agents.js +283 -0
  8. package/dist/src/ai-hub/conversation-store.js +428 -0
  9. package/dist/src/ai-hub/desktop-main.js +449 -0
  10. package/dist/src/ai-hub/hosts.js +1669 -0
  11. package/dist/src/ai-hub/hub-latest-version.js +52 -0
  12. package/dist/src/ai-hub/hub-launch-decision.js +57 -0
  13. package/dist/src/ai-hub/hub-runtime-file.js +43 -0
  14. package/dist/src/ai-hub/managed-browser.js +269 -0
  15. package/dist/src/ai-hub/manager-turns.js +64 -0
  16. package/dist/src/ai-hub/office-sideload.js +156 -0
  17. package/dist/src/ai-hub/openclaw-bridge.js +250 -0
  18. package/dist/src/ai-hub/preferences.js +201 -0
  19. package/dist/src/ai-hub/remote-hub-gateway.js +88 -0
  20. package/dist/src/ai-hub/server.js +4013 -0
  21. package/dist/src/ai-hub/types.js +2 -0
  22. package/dist/src/ai-hub/url-safety.js +19 -0
  23. package/dist/src/api/admin/payments.js +33 -0
  24. package/dist/src/api/admin/sales-leads.js +21 -0
  25. package/dist/src/api/payment/create-session.js +338 -0
  26. package/dist/src/api/payment/dashboard-link.js +149 -0
  27. package/dist/src/api/payment/session-details.js +31 -0
  28. package/dist/src/api/payment/webhook.js +587 -0
  29. package/dist/src/api/sales/contact.js +44 -0
  30. package/dist/src/cli/api/get-provider-client.js +41 -0
  31. package/dist/src/cli/api/provider-client.js +107 -0
  32. package/dist/src/cli/commands/add-ide.js +462 -0
  33. package/dist/src/cli/fraim-hub.js +50 -0
  34. package/dist/src/cli/internal/device-flow-service.js +83 -0
  35. package/dist/src/cli/mcp/command-resolution.js +81 -0
  36. package/dist/src/cli/mcp/fraim-mcp-latest-launcher.js +136 -0
  37. package/dist/src/cli/mcp/ide-formats.js +317 -0
  38. package/dist/src/cli/mcp/mcp-server-builder.js +48 -0
  39. package/dist/src/cli/mcp/mcp-server-registry.js +173 -0
  40. package/dist/src/cli/providers/local-provider-registry.js +165 -0
  41. package/dist/src/cli/providers/provider-registry.js +230 -0
  42. package/dist/src/cli/setup/claude-code-telemetry.js +59 -0
  43. package/dist/src/cli/setup/codex-local-config.js +37 -0
  44. package/dist/src/cli/setup/ide-detector.js +383 -0
  45. package/dist/src/cli/setup/ide-global-integration.js +100 -0
  46. package/dist/src/cli/setup/ide-invocation-surfaces.js +160 -0
  47. package/dist/src/cli/setup/mcp-config-generator.js +225 -0
  48. package/dist/src/cli/setup/provider-prompts.js +339 -0
  49. package/dist/src/cli/utils/managed-agent-paths.js +118 -0
  50. package/dist/src/cli/utils/script-sync-utils.js +221 -0
  51. package/dist/src/cli/utils/user-config.js +100 -0
  52. package/dist/src/cli/utils/version-utils.js +35 -0
  53. package/dist/src/config/ai-manager-hiring.js +121 -0
  54. package/dist/src/config/feature-flags.js +25 -0
  55. package/dist/src/config/persona-capability-bundles.js +277 -0
  56. package/dist/src/config/persona-hiring.js +270 -0
  57. package/dist/src/config/portfolio-slug-overrides.js +17 -0
  58. package/dist/src/config/pricing.js +37 -0
  59. package/dist/src/config/stripe.js +43 -0
  60. package/dist/src/core/brand-store.js +232 -0
  61. package/dist/src/core/quality-evidence.js +331 -0
  62. package/dist/src/core/utils/git-utils.js +194 -0
  63. package/dist/src/core/utils/ports.js +32 -0
  64. package/dist/src/core/utils/project-fraim-paths.js +220 -0
  65. package/dist/src/db/payment-repository.js +61 -0
  66. package/dist/src/first-run/types.js +93 -0
  67. package/dist/src/fraim/db-service.js +2409 -0
  68. package/dist/src/local-mcp-server/agent-token-prices.js +167 -0
  69. package/dist/src/local-mcp-server/learning-context-builder.js +975 -0
  70. package/dist/src/middleware/rate-limit.js +110 -0
  71. package/dist/src/models/payment.js +2 -0
  72. package/dist/src/routes/payment-routes.js +186 -0
  73. package/dist/src/routes/persona-catalog-routes.js +84 -0
  74. package/dist/src/services/dashboard-access.js +27 -0
  75. package/dist/src/services/email-service.js +951 -0
  76. package/dist/src/services/persona-entitlement-service.js +352 -0
  77. package/dist/src/services/workspace-identity.js +21 -0
  78. package/dist/src/types/analytics.js +2 -0
  79. package/dist/src/utils/payment-calculator.js +52 -0
  80. package/extensions/office-word/favicon.ico +0 -0
  81. package/extensions/office-word/icon-64.png +0 -0
  82. package/extensions/office-word/manifest.xml +33 -0
  83. package/extensions/office-word/taskpane.html +242 -0
  84. package/index.js +85 -0
  85. package/package.json +106 -0
  86. package/public/ai-hub/index.html +910 -0
  87. package/public/ai-hub/powerpoint-taskpane/icon-64.png +0 -0
  88. package/public/ai-hub/powerpoint-taskpane/index.html +236 -0
  89. package/public/ai-hub/powerpoint-taskpane/manifest.xml +30 -0
  90. package/public/ai-hub/review.css +444 -0
  91. package/public/ai-hub/script.js +11737 -0
  92. package/public/ai-hub/styles.css +5102 -0
  93. package/public/first-run/error-frame.js +100 -0
  94. package/public/first-run/index.html +35 -0
  95. package/public/first-run/script.js +739 -0
  96. package/public/first-run/styles.css +929 -0
  97. package/public/portfolio/ashley.html +523 -0
  98. package/public/portfolio/auditya.html +83 -0
  99. package/public/portfolio/banke.html +83 -0
  100. package/public/portfolio/beza.html +659 -0
  101. package/public/portfolio/careena.html +632 -0
  102. package/public/portfolio/casey.html +568 -0
  103. package/public/portfolio/celia.html +490 -0
  104. package/public/portfolio/deidre.html +642 -0
  105. package/public/portfolio/gautam.html +597 -0
  106. package/public/portfolio/hari.html +469 -0
  107. package/public/portfolio/huxley.html +1354 -0
  108. package/public/portfolio/index.html +741 -0
  109. package/public/portfolio/maestro.html +518 -0
  110. package/public/portfolio/mandy.html +590 -0
  111. package/public/portfolio/mona.html +597 -0
  112. package/public/portfolio/pam.html +887 -0
  113. package/public/portfolio/procella.html +107 -0
  114. package/public/portfolio/qasm.html +569 -0
  115. package/public/portfolio/ricardo.html +489 -0
  116. package/public/portfolio/sade.html +560 -0
  117. package/public/portfolio/sam.html +654 -0
  118. package/public/portfolio/sechar.html +580 -0
  119. package/public/portfolio/sreya.html +599 -0
  120. package/public/portfolio/swen.html +601 -0
@@ -0,0 +1,929 @@
1
+ /*
2
+ * FRAIM first-run — Setup checklist surface.
3
+ *
4
+ * The :root variable set below is a STRICT SUBSET of public/ai-hub/styles.css
5
+ * — see R5.1 acceptance and tests/test-installer-service.ts'
6
+ * `testBootstrapCssVarsAreSubsetOfHub`. Adding a token here that does not
7
+ * exist on the Hub side fails CI.
8
+ */
9
+ :root {
10
+ --bg: #f4f6f2;
11
+ --surface: #ffffff;
12
+ --soft: #f7faf6;
13
+ --line: #e3e8df;
14
+ --text: #1f2a24;
15
+ --muted: #6b7a72;
16
+ --accent: #3d8a6e;
17
+ --accent-strong: #2f7359;
18
+ --accent-soft: #eaf3ee;
19
+ --warn: #b08442;
20
+ --warn-soft: #fffaf0;
21
+ --danger: #a24747;
22
+ --shadow: 0 1px 2px rgba(20, 40, 30, 0.04);
23
+ --shadow-lg: 0 12px 36px rgba(20, 40, 30, 0.18);
24
+ }
25
+
26
+ * { box-sizing: border-box; }
27
+ html, body { margin: 0; padding: 0; }
28
+ body {
29
+ font-family: -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
30
+ color: var(--text);
31
+ background: var(--bg);
32
+ line-height: 1.5;
33
+ font-size: 15px;
34
+ }
35
+
36
+ .page {
37
+ max-width: 720px;
38
+ margin: 0 auto;
39
+ padding: 48px 24px 32px;
40
+ }
41
+
42
+ .page-header h1 {
43
+ margin: 0 0 8px;
44
+ font-size: 26px;
45
+ font-weight: 600;
46
+ }
47
+ .page-header .lede {
48
+ margin: 0 0 24px;
49
+ color: var(--muted);
50
+ font-size: 16px;
51
+ line-height: 1.5;
52
+ }
53
+
54
+ .card {
55
+ background: var(--surface);
56
+ border: 1px solid var(--line);
57
+ border-radius: 14px;
58
+ box-shadow: var(--shadow);
59
+ padding: 24px;
60
+ }
61
+
62
+ .checklist {
63
+ list-style: none;
64
+ margin: 0;
65
+ padding: 0;
66
+ display: flex;
67
+ flex-direction: column;
68
+ border: 1px solid var(--line);
69
+ border-radius: 12px;
70
+ overflow: hidden;
71
+ }
72
+
73
+ .checklist .row {
74
+ display: flex;
75
+ flex-wrap: wrap;
76
+ align-items: center;
77
+ gap: 12px;
78
+ padding: 14px 16px;
79
+ border-bottom: 1px solid var(--line);
80
+ background: var(--surface);
81
+ }
82
+ .checklist .row:last-child { border-bottom: 0; }
83
+
84
+ .row .icon {
85
+ width: 22px;
86
+ height: 22px;
87
+ border-radius: 50%;
88
+ display: inline-flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ font-size: 13px;
92
+ font-weight: 700;
93
+ flex-shrink: 0;
94
+ }
95
+ .row[data-row-status="ok"] .icon { background: var(--accent); color: #fff; }
96
+ .row[data-row-status="pending"] .icon { background: var(--line); color: var(--muted); }
97
+ .row[data-row-status="in-progress"] .icon { background: var(--accent-soft); color: var(--accent-strong); }
98
+ .row[data-row-status="manual-required"] .icon { background: var(--warn-soft); color: var(--warn); border: 1px solid var(--warn); }
99
+ .row[data-row-status="error"] .icon { background: #fbf1f1; color: var(--danger); border: 1px solid var(--danger); }
100
+
101
+ .row .label { font-weight: 600; min-width: 124px; }
102
+ .row .verb { color: var(--muted); font-size: 14px; flex: 1; }
103
+ .row[data-row-status="ok"] .verb { color: var(--accent-strong); }
104
+ .row[data-row-status="error"] .verb { color: var(--danger); }
105
+ .row[data-row-status="manual-required"] .verb { color: var(--warn); }
106
+
107
+ .row .detail {
108
+ color: var(--muted);
109
+ font-size: 13px;
110
+ flex-basis: 100%;
111
+ padding-left: 34px;
112
+ }
113
+
114
+ .setup-result {
115
+ display: flex;
116
+ flex-direction: column;
117
+ gap: 8px;
118
+ padding: 16px;
119
+ border-top: 1px solid var(--line);
120
+ background: var(--soft);
121
+ }
122
+ .setup-result strong {
123
+ font-size: 15px;
124
+ font-weight: 600;
125
+ }
126
+ .setup-result p {
127
+ margin: 0;
128
+ color: var(--muted);
129
+ font-size: 14px;
130
+ }
131
+ .surface-list {
132
+ margin: 0;
133
+ padding-left: 18px;
134
+ color: var(--muted);
135
+ font-size: 14px;
136
+ }
137
+
138
+ .row .change-link {
139
+ font-size: 13px;
140
+ color: var(--accent-strong);
141
+ text-decoration: none;
142
+ cursor: pointer;
143
+ border: 0;
144
+ background: transparent;
145
+ padding: 4px 6px;
146
+ }
147
+ .row .change-link:hover { text-decoration: underline; }
148
+ .row .change-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
149
+
150
+ .row .row-stream {
151
+ flex-basis: 100%;
152
+ margin: 8px 0 0;
153
+ background: #0d1410;
154
+ color: #c8d3cd;
155
+ font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
156
+ font-size: 12px;
157
+ padding: 10px 12px;
158
+ border-radius: 8px;
159
+ max-height: 80px;
160
+ overflow: auto;
161
+ white-space: pre;
162
+ }
163
+ .row .manual-message {
164
+ flex-basis: 100%;
165
+ margin: 8px 0 0;
166
+ background: var(--warn-soft);
167
+ border: 1px solid var(--warn);
168
+ color: var(--text);
169
+ border-radius: 8px;
170
+ padding: 10px 12px;
171
+ font-size: 13px;
172
+ }
173
+ .row .manual-message code {
174
+ background: var(--surface);
175
+ padding: 2px 4px;
176
+ border-radius: 4px;
177
+ }
178
+
179
+ /* Inline agent picker. No popups; no separate page. */
180
+ .agent-picker {
181
+ flex-basis: 100%;
182
+ margin-top: 10px;
183
+ background: var(--soft);
184
+ border: 1px solid var(--line);
185
+ border-radius: 10px;
186
+ padding: 12px;
187
+ display: flex;
188
+ flex-direction: column;
189
+ gap: 10px;
190
+ }
191
+ .agent-picker[hidden] { display: none; }
192
+ .agent-picker .options { display: flex; gap: 8px; flex-wrap: wrap; }
193
+ .agent-picker .option {
194
+ background: var(--surface);
195
+ border: 1px solid var(--line);
196
+ border-radius: 8px;
197
+ padding: 8px 12px;
198
+ cursor: pointer;
199
+ font-size: 14px;
200
+ }
201
+ .agent-picker .option:hover { background: var(--soft); border-color: var(--accent); }
202
+ .agent-picker .option:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
203
+ .agent-picker .option[aria-pressed="true"] {
204
+ border-color: var(--accent);
205
+ background: var(--accent-soft);
206
+ color: var(--accent-strong);
207
+ font-weight: 600;
208
+ }
209
+ .agent-picker details { margin-top: 4px; }
210
+ .agent-picker summary {
211
+ cursor: pointer;
212
+ color: var(--muted);
213
+ font-size: 13px;
214
+ }
215
+ .agent-picker .custom-warning {
216
+ background: var(--warn-soft);
217
+ border: 1px solid var(--warn);
218
+ color: var(--text);
219
+ border-radius: 8px;
220
+ padding: 10px 12px;
221
+ font-size: 13px;
222
+ margin-top: 8px;
223
+ }
224
+ .agent-picker .custom-form {
225
+ display: grid;
226
+ grid-template-columns: 1fr 1fr auto;
227
+ gap: 8px;
228
+ margin-top: 8px;
229
+ }
230
+ .agent-picker .custom-form input {
231
+ border: 1px solid var(--line);
232
+ border-radius: 8px;
233
+ padding: 8px 10px;
234
+ font: inherit;
235
+ }
236
+ .agent-picker .custom-form button {
237
+ background: var(--accent);
238
+ color: #fff;
239
+ border: 0;
240
+ border-radius: 8px;
241
+ padding: 8px 14px;
242
+ cursor: pointer;
243
+ font: inherit;
244
+ }
245
+
246
+ /* Project row picker affordances */
247
+ .row .project-picker {
248
+ display: flex;
249
+ gap: 8px;
250
+ align-items: center;
251
+ flex-basis: 100%;
252
+ margin-top: 8px;
253
+ }
254
+ .row .project-picker input {
255
+ flex: 1;
256
+ border: 1px solid var(--line);
257
+ border-radius: 8px;
258
+ padding: 8px 12px;
259
+ font: inherit;
260
+ }
261
+ .row .project-picker .browse {
262
+ background: var(--surface);
263
+ border: 1px solid var(--line);
264
+ border-radius: 8px;
265
+ padding: 8px 12px;
266
+ cursor: pointer;
267
+ font: inherit;
268
+ }
269
+ .row .project-picker .browse:hover { background: var(--soft); border-color: var(--accent); }
270
+
271
+ /* Preflight summary — shown above the Continue button on the project row.
272
+ Tells the user exactly which side effects FRAIM will perform when they
273
+ click Continue. The "no surprises" half of the non-tech-user invariant. */
274
+ .row .preflight-summary {
275
+ flex-basis: 100%;
276
+ margin-top: 12px;
277
+ padding: 12px 14px;
278
+ border: 1px solid var(--line);
279
+ background: var(--soft);
280
+ border-radius: 8px;
281
+ font-size: 13px;
282
+ color: var(--muted);
283
+ }
284
+ .row .preflight-heading {
285
+ color: var(--text);
286
+ font-weight: 600;
287
+ margin-bottom: 6px;
288
+ }
289
+ .row .preflight-list {
290
+ margin: 0;
291
+ padding-left: 18px;
292
+ }
293
+ .row .preflight-list li { margin: 2px 0; }
294
+
295
+ .actions {
296
+ display: flex;
297
+ justify-content: flex-end;
298
+ gap: 8px;
299
+ margin-top: 20px;
300
+ }
301
+
302
+ /* Primary button — same geometry as Hub's send-button (R5.2). */
303
+ .primary-button {
304
+ background: var(--accent);
305
+ color: #fff;
306
+ border: 0;
307
+ border-radius: 10px;
308
+ padding: 10px 18px;
309
+ font: inherit;
310
+ font-weight: 600;
311
+ cursor: pointer;
312
+ }
313
+ .primary-button:hover { background: var(--accent-strong); }
314
+ .primary-button:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
315
+ .primary-button:disabled { background: #c5d2cb; cursor: not-allowed; }
316
+
317
+ .status {
318
+ margin: 16px 0 0;
319
+ padding: 12px 14px;
320
+ border-radius: 10px;
321
+ background: var(--soft);
322
+ border: 1px solid var(--line);
323
+ color: var(--muted);
324
+ font-size: 14px;
325
+ min-height: 1em;
326
+ }
327
+ .status:empty { display: none; }
328
+ .status[data-tone="error"] {
329
+ background: #fbf1f1;
330
+ border-color: var(--danger);
331
+ color: var(--danger);
332
+ }
333
+
334
+ /* Error frame — R6.1 single visual contract. */
335
+ .error-frame {
336
+ flex-basis: 100%;
337
+ margin-top: 10px;
338
+ background: #fbf1f1;
339
+ border: 1px solid var(--danger);
340
+ border-radius: 10px;
341
+ padding: 12px 14px;
342
+ display: flex;
343
+ flex-direction: column;
344
+ gap: 8px;
345
+ }
346
+ .error-frame .what-tried {
347
+ color: var(--danger);
348
+ font-weight: 600;
349
+ }
350
+ .error-frame .error-hint {
351
+ color: var(--text);
352
+ font-size: 14px;
353
+ line-height: 1.45;
354
+ background: var(--warn-soft);
355
+ border: 1px solid #f0d8b3;
356
+ border-radius: 8px;
357
+ padding: 10px 12px;
358
+ }
359
+ .error-frame .what-happened {
360
+ background: #0d1410;
361
+ color: #f1c0c0;
362
+ font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
363
+ font-size: 12px;
364
+ padding: 10px 12px;
365
+ border-radius: 8px;
366
+ max-height: 88px;
367
+ overflow: auto;
368
+ white-space: pre;
369
+ margin: 0;
370
+ }
371
+ .error-frame .show-full {
372
+ align-self: flex-start;
373
+ font-size: 12px;
374
+ color: var(--muted);
375
+ cursor: pointer;
376
+ background: 0;
377
+ border: 0;
378
+ padding: 0;
379
+ text-decoration: underline;
380
+ }
381
+ .error-frame .actions {
382
+ display: flex;
383
+ gap: 8px;
384
+ margin-top: 4px;
385
+ justify-content: flex-start;
386
+ }
387
+ .error-frame .action {
388
+ border-radius: 8px;
389
+ padding: 8px 14px;
390
+ cursor: pointer;
391
+ font: inherit;
392
+ font-weight: 500;
393
+ border: 1px solid var(--line);
394
+ background: var(--surface);
395
+ color: var(--text);
396
+ }
397
+ .error-frame .action[data-variant="primary"] {
398
+ background: var(--accent);
399
+ color: #fff;
400
+ border-color: var(--accent);
401
+ }
402
+ .error-frame .action[data-variant="primary"]:hover { background: var(--accent-strong); }
403
+ .error-frame .action[data-variant="secondary"]:hover {
404
+ border-color: var(--accent);
405
+ color: var(--accent-strong);
406
+ }
407
+ .error-frame .action[data-variant="ghost"] {
408
+ background: transparent;
409
+ border-color: transparent;
410
+ color: var(--accent-strong);
411
+ }
412
+
413
+ /* User-type selection screen — shown after all 4 setup rows complete.
414
+ .checklist switches to .selection-container so card borders don't
415
+ nest inside the outer bordered list container. */
416
+ .selection-container {
417
+ list-style: none;
418
+ margin: 0;
419
+ padding: 0;
420
+ display: flex;
421
+ flex-direction: column;
422
+ }
423
+
424
+ .setup-shell {
425
+ list-style: none;
426
+ margin: 0;
427
+ padding: 0;
428
+ display: grid;
429
+ grid-template-columns: minmax(190px, 0.85fr) minmax(0, 2fr);
430
+ gap: 20px;
431
+ }
432
+ .setup-steps {
433
+ display: flex;
434
+ flex-direction: column;
435
+ gap: 8px;
436
+ border-right: 1px solid var(--line);
437
+ padding-right: 16px;
438
+ }
439
+ .setup-step {
440
+ width: 100%;
441
+ min-height: 44px;
442
+ display: flex;
443
+ align-items: center;
444
+ gap: 10px;
445
+ border: 1px solid var(--line);
446
+ border-radius: 8px;
447
+ background: var(--surface);
448
+ color: var(--text);
449
+ padding: 9px 10px;
450
+ font: inherit;
451
+ font-weight: 600;
452
+ text-align: left;
453
+ cursor: pointer;
454
+ }
455
+ .setup-step[aria-current="step"] {
456
+ border-color: var(--accent);
457
+ background: var(--accent-soft);
458
+ }
459
+ .setup-step:disabled {
460
+ opacity: 0.55;
461
+ cursor: not-allowed;
462
+ }
463
+ .step-dot {
464
+ width: 24px;
465
+ height: 24px;
466
+ border-radius: 50%;
467
+ display: inline-flex;
468
+ align-items: center;
469
+ justify-content: center;
470
+ background: var(--line);
471
+ color: var(--muted);
472
+ font-size: 12px;
473
+ flex: 0 0 auto;
474
+ }
475
+ .setup-step[data-status="done"] .step-dot {
476
+ background: var(--accent);
477
+ color: #fff;
478
+ }
479
+ .setup-pane {
480
+ min-width: 0;
481
+ display: flex;
482
+ flex-direction: column;
483
+ gap: 14px;
484
+ }
485
+ .setup-pane h2 {
486
+ margin: 0;
487
+ font-size: 18px;
488
+ font-weight: 650;
489
+ }
490
+ .pane-copy,
491
+ .locked-note {
492
+ margin: 0;
493
+ color: var(--muted);
494
+ font-size: 14px;
495
+ }
496
+ .locked-note { color: var(--warn); }
497
+
498
+ /* Issue #646: paste-your-key step (no-terminal macOS installer path). */
499
+ .key-input {
500
+ width: 100%;
501
+ margin: 10px 0 4px;
502
+ padding: 10px 12px;
503
+ font-family: ui-monospace, 'SFMono-Regular', Menlo, monospace;
504
+ font-size: 14px;
505
+ border: 1px solid var(--border, #2c3343);
506
+ border-radius: 8px;
507
+ background: var(--panel, #12151c);
508
+ color: var(--text, #e6e9ef);
509
+ }
510
+ .key-input:focus-visible { outline: 2px solid var(--accent-strong, #6366f1); outline-offset: 1px; }
511
+ .row-list {
512
+ list-style: none;
513
+ margin: 0;
514
+ padding: 0;
515
+ border: 1px solid var(--line);
516
+ border-radius: 10px;
517
+ overflow: hidden;
518
+ }
519
+ .row-list .row {
520
+ display: flex;
521
+ gap: 10px;
522
+ align-items: center;
523
+ padding: 12px;
524
+ border-bottom: 1px solid var(--line);
525
+ }
526
+ .row-list .row:last-child { border-bottom: 0; }
527
+ .agent-grid,
528
+ .choice-grid {
529
+ display: grid;
530
+ grid-template-columns: repeat(2, minmax(0, 1fr));
531
+ gap: 12px;
532
+ }
533
+
534
+ .agent-section-heading {
535
+ margin: 8px 0 -6px;
536
+ font-size: 13px;
537
+ font-weight: 700;
538
+ color: var(--text);
539
+ }
540
+
541
+ .agent-list {
542
+ list-style: none;
543
+ margin: 0;
544
+ padding: 0;
545
+ border: 1px solid var(--line);
546
+ border-radius: 10px;
547
+ overflow: hidden;
548
+ }
549
+
550
+ .agent-row {
551
+ display: flex;
552
+ align-items: center;
553
+ justify-content: space-between;
554
+ padding: 12px 16px;
555
+ border-bottom: 1px solid var(--line);
556
+ background: var(--surface);
557
+ gap: 12px;
558
+ }
559
+
560
+ .agent-row:last-child { border-bottom: 0; }
561
+ .agent-row--detected { background: var(--accent-soft); }
562
+
563
+ .agent-row__name {
564
+ min-width: 0;
565
+ flex: 1;
566
+ font-size: 14px;
567
+ font-weight: 500;
568
+ color: var(--text);
569
+ }
570
+
571
+ .agent-row--detected .agent-row__name { color: var(--accent-strong); }
572
+
573
+ .agent-row__action {
574
+ flex: 0 0 auto;
575
+ }
576
+
577
+ .agent-row__muted {
578
+ font-size: 12px;
579
+ color: var(--muted);
580
+ }
581
+
582
+ .agent-badge {
583
+ display: inline-flex;
584
+ align-items: center;
585
+ min-height: 24px;
586
+ padding: 3px 10px;
587
+ border-radius: 999px;
588
+ font-size: 12px;
589
+ font-weight: 700;
590
+ }
591
+
592
+ .agent-badge--installed {
593
+ background: var(--accent);
594
+ color: #fff;
595
+ }
596
+
597
+ .agent-download-link {
598
+ font-size: 13px;
599
+ font-weight: 600;
600
+ color: var(--accent-strong);
601
+ text-decoration: none;
602
+ }
603
+
604
+ .agent-download-link:hover { text-decoration: underline; }
605
+
606
+ .ready-strip {
607
+ background: var(--accent-soft);
608
+ border: 1px solid var(--accent);
609
+ color: var(--accent-strong);
610
+ border-radius: 8px;
611
+ padding: 10px 12px;
612
+ font-size: 13px;
613
+ font-weight: 600;
614
+ }
615
+ .ready-strip--muted {
616
+ background: var(--soft);
617
+ border-color: var(--line);
618
+ color: var(--muted);
619
+ }
620
+ .ready-strip--error {
621
+ background: #fff1f2;
622
+ border-color: #fb7185;
623
+ color: #9f1239;
624
+ }
625
+ .btn {
626
+ border-radius: 8px;
627
+ padding: 9px 14px;
628
+ font: inherit;
629
+ font-weight: 600;
630
+ cursor: pointer;
631
+ border: 1px solid var(--line);
632
+ align-self: flex-start;
633
+ }
634
+ .btn:disabled {
635
+ opacity: 0.55;
636
+ cursor: not-allowed;
637
+ }
638
+ .btn-primary {
639
+ background: var(--accent);
640
+ border-color: var(--accent);
641
+ color: #fff;
642
+ }
643
+ .btn-primary:hover { background: var(--accent-strong); }
644
+ .btn-secondary {
645
+ background: var(--surface);
646
+ color: var(--accent-strong);
647
+ }
648
+ .btn-secondary:hover {
649
+ border-color: var(--accent);
650
+ background: var(--soft);
651
+ }
652
+ .btn-ghost {
653
+ background: transparent;
654
+ color: var(--muted);
655
+ }
656
+ .modal-backdrop {
657
+ position: fixed;
658
+ inset: 0;
659
+ z-index: 1000;
660
+ display: flex;
661
+ align-items: center;
662
+ justify-content: center;
663
+ padding: 18px;
664
+ background: rgba(31, 42, 36, 0.36);
665
+ }
666
+ .modal {
667
+ width: min(520px, 100%);
668
+ background: var(--surface);
669
+ border: 1px solid var(--line);
670
+ border-radius: 12px;
671
+ box-shadow: var(--shadow-lg);
672
+ padding: 22px;
673
+ display: flex;
674
+ flex-direction: column;
675
+ gap: 14px;
676
+ }
677
+ .modal h2 {
678
+ margin: 0;
679
+ font-size: 19px;
680
+ }
681
+ .install-status {
682
+ margin: 0;
683
+ border: 1px solid var(--line);
684
+ background: var(--soft);
685
+ border-radius: 8px;
686
+ padding: 10px 12px;
687
+ color: var(--muted);
688
+ }
689
+ .install-status[data-tone="error"] {
690
+ color: var(--danger);
691
+ background: #fbf1f1;
692
+ border-color: var(--danger);
693
+ }
694
+ .modal-help {
695
+ margin: -4px 0 0;
696
+ color: var(--muted);
697
+ font-size: 13px;
698
+ line-height: 1.45;
699
+ }
700
+ .install-actions {
701
+ display: flex;
702
+ flex-wrap: wrap;
703
+ gap: 8px;
704
+ }
705
+
706
+ .recruit-container,
707
+ .start-container {
708
+ gap: 12px;
709
+ }
710
+
711
+ .start-container {
712
+ gap: 14px;
713
+ }
714
+
715
+ .user-type-card {
716
+ background: var(--surface);
717
+ border: 1.5px solid var(--line);
718
+ border-radius: 12px;
719
+ padding: 20px;
720
+ display: flex;
721
+ flex-direction: column;
722
+ gap: 16px;
723
+ transition: box-shadow 0.15s ease, border-color 0.15s ease;
724
+ }
725
+ .user-type-card:hover {
726
+ box-shadow: 0 4px 16px rgba(20, 40, 30, 0.10);
727
+ border-color: var(--accent);
728
+ }
729
+ .user-type-card--featured {
730
+ border-color: var(--accent);
731
+ background: var(--accent-soft);
732
+ }
733
+ .user-type-card--featured:hover {
734
+ box-shadow: 0 4px 20px rgba(61, 138, 110, 0.18);
735
+ }
736
+
737
+ .user-type-card--ide-default {
738
+ padding: 24px;
739
+ gap: 18px;
740
+ }
741
+
742
+ .user-type-card--compact {
743
+ padding: 16px 18px;
744
+ gap: 12px;
745
+ }
746
+
747
+ .user-type-card--alpha {
748
+ background: linear-gradient(180deg, #fbfcfa 0%, #f4f7f2 100%);
749
+ }
750
+
751
+ .card-header {
752
+ display: flex;
753
+ gap: 14px;
754
+ align-items: flex-start;
755
+ }
756
+ .card-icon {
757
+ width: 38px;
758
+ height: 38px;
759
+ flex-shrink: 0;
760
+ display: flex;
761
+ align-items: center;
762
+ justify-content: center;
763
+ background: var(--soft);
764
+ border: 1px solid var(--line);
765
+ border-radius: 9px;
766
+ font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
767
+ font-size: 10px;
768
+ font-weight: 700;
769
+ color: var(--accent-strong);
770
+ letter-spacing: -0.5px;
771
+ }
772
+ .user-type-card--featured .card-icon {
773
+ background: #fff;
774
+ border-color: var(--accent);
775
+ }
776
+
777
+ .card-title {
778
+ display: block;
779
+ font-size: 15px;
780
+ font-weight: 600;
781
+ color: var(--text);
782
+ margin-bottom: 3px;
783
+ }
784
+ .card-desc { margin: 0; font-size: 13px; color: var(--muted); line-height: 1.45; }
785
+
786
+ .card-eyebrow {
787
+ display: inline-flex;
788
+ align-self: flex-start;
789
+ padding: 4px 10px;
790
+ border-radius: 999px;
791
+ background: var(--accent-soft);
792
+ color: var(--accent-strong);
793
+ font-size: 11px;
794
+ font-weight: 700;
795
+ letter-spacing: 0.06em;
796
+ text-transform: uppercase;
797
+ }
798
+
799
+ .route-note {
800
+ margin: 0;
801
+ color: var(--muted);
802
+ font-size: 13px;
803
+ line-height: 1.5;
804
+ }
805
+
806
+ .route-note--compact {
807
+ font-size: 12px;
808
+ }
809
+
810
+ .btn {
811
+ display: inline-flex;
812
+ align-items: center;
813
+ justify-content: center;
814
+ border-radius: 8px;
815
+ padding: 10px 18px;
816
+ font: inherit;
817
+ font-weight: 600;
818
+ font-size: 14px;
819
+ cursor: pointer;
820
+ transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
821
+ align-self: flex-start;
822
+ }
823
+ .btn-block { align-self: stretch; width: 100%; }
824
+ .btn-primary {
825
+ background: var(--accent);
826
+ color: #fff;
827
+ border: 1.5px solid var(--accent);
828
+ }
829
+ .btn-primary:hover {
830
+ background: var(--accent-strong);
831
+ border-color: var(--accent-strong);
832
+ box-shadow: 0 2px 8px rgba(61, 138, 110, 0.25);
833
+ }
834
+ .btn-primary:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
835
+ .btn-primary:disabled { background: #c5d2cb; border-color: #c5d2cb; cursor: not-allowed; box-shadow: none; }
836
+ .btn-secondary {
837
+ background: var(--surface);
838
+ color: var(--accent-strong);
839
+ border: 1.5px solid var(--line);
840
+ }
841
+ .btn-secondary:hover {
842
+ border-color: var(--accent);
843
+ background: var(--accent-soft);
844
+ box-shadow: 0 2px 8px rgba(61, 138, 110, 0.10);
845
+ }
846
+ .btn-secondary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
847
+
848
+ /* Recruit cards are informational — no pointer/hover highlight. */
849
+ .recruit-card {
850
+ cursor: default;
851
+ }
852
+
853
+ .byoa-card {
854
+ grid-column: 1 / -1;
855
+ }
856
+
857
+ .byoa-card .cmd-block {
858
+ align-self: flex-start;
859
+ display: inline-block;
860
+ white-space: nowrap;
861
+ word-break: normal;
862
+ }
863
+ .recruit-card:hover {
864
+ box-shadow: none;
865
+ border-color: var(--line);
866
+ }
867
+
868
+ /* IDE command display — shown after choosing "In my IDE". */
869
+ .cmd-block {
870
+ background: #0d1410;
871
+ color: #c8d3cd;
872
+ font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
873
+ font-size: 14px;
874
+ padding: 12px 16px;
875
+ border-radius: 8px;
876
+ word-break: break-all;
877
+ }
878
+
879
+ .command-row {
880
+ display: flex;
881
+ gap: 8px;
882
+ align-items: center;
883
+ margin-bottom: 8px;
884
+ }
885
+ .command-row .cmd-block { flex: 1; }
886
+ .command-row .btn {
887
+ flex-shrink: 0;
888
+ font-size: 12px;
889
+ padding: 6px 10px;
890
+ }
891
+ .text-button {
892
+ align-self: flex-start;
893
+ border: 0;
894
+ background: transparent;
895
+ color: var(--accent-strong);
896
+ padding: 6px 0;
897
+ font: inherit;
898
+ font-size: 13px;
899
+ cursor: pointer;
900
+ text-decoration: underline;
901
+ }
902
+
903
+ /* Below ~600px the row's flex layout starts compressing the verb text and
904
+ * clipping the project-picker. First-run is desktop-by-spec but we still
905
+ * want the surface to degrade gracefully for users who happen to open it
906
+ * in a narrow window. Stack the label / verb / change link vertically and
907
+ * let the row breathe. */
908
+ @media (max-width: 600px) {
909
+ .page { padding: 24px 16px 24px; }
910
+ .setup-shell { grid-template-columns: 1fr; }
911
+ .setup-steps {
912
+ border-right: 0;
913
+ border-bottom: 1px solid var(--line);
914
+ padding-right: 0;
915
+ padding-bottom: 12px;
916
+ }
917
+ .agent-grid,
918
+ .choice-grid { grid-template-columns: 1fr; }
919
+ .checklist .row { gap: 8px; padding: 12px 14px; }
920
+ .row .label { min-width: 0; }
921
+ .row .verb { flex: 1 1 100%; }
922
+ .row .change-link { margin-left: auto; }
923
+ .row .project-picker { gap: 8px; }
924
+ .row .project-picker input { width: 100%; min-width: 0; }
925
+ .user-type-card--ide-default,
926
+ .user-type-card--compact {
927
+ padding: 18px 16px;
928
+ }
929
+ }