fraim-framework 2.0.127 → 2.0.128

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.
@@ -0,0 +1,386 @@
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 .change-link {
108
+ font-size: 13px;
109
+ color: var(--accent-strong);
110
+ text-decoration: none;
111
+ cursor: pointer;
112
+ border: 0;
113
+ background: transparent;
114
+ padding: 4px 6px;
115
+ }
116
+ .row .change-link:hover { text-decoration: underline; }
117
+ .row .change-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
118
+
119
+ .row .row-stream {
120
+ flex-basis: 100%;
121
+ margin: 8px 0 0;
122
+ background: #0d1410;
123
+ color: #c8d3cd;
124
+ font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
125
+ font-size: 12px;
126
+ padding: 10px 12px;
127
+ border-radius: 8px;
128
+ max-height: 80px;
129
+ overflow: auto;
130
+ white-space: pre;
131
+ }
132
+ .row .manual-message {
133
+ flex-basis: 100%;
134
+ margin: 8px 0 0;
135
+ background: var(--warn-soft);
136
+ border: 1px solid var(--warn);
137
+ color: var(--text);
138
+ border-radius: 8px;
139
+ padding: 10px 12px;
140
+ font-size: 13px;
141
+ }
142
+ .row .manual-message code {
143
+ background: var(--surface);
144
+ padding: 2px 4px;
145
+ border-radius: 4px;
146
+ }
147
+
148
+ /* Inline agent picker. No popups; no separate page. */
149
+ .agent-picker {
150
+ flex-basis: 100%;
151
+ margin-top: 10px;
152
+ background: var(--soft);
153
+ border: 1px solid var(--line);
154
+ border-radius: 10px;
155
+ padding: 12px;
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: 10px;
159
+ }
160
+ .agent-picker[hidden] { display: none; }
161
+ .agent-picker .options { display: flex; gap: 8px; flex-wrap: wrap; }
162
+ .agent-picker .option {
163
+ background: var(--surface);
164
+ border: 1px solid var(--line);
165
+ border-radius: 8px;
166
+ padding: 8px 12px;
167
+ cursor: pointer;
168
+ font-size: 14px;
169
+ }
170
+ .agent-picker .option:hover { background: var(--soft); border-color: var(--accent); }
171
+ .agent-picker .option:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
172
+ .agent-picker .option[aria-pressed="true"] {
173
+ border-color: var(--accent);
174
+ background: var(--accent-soft);
175
+ color: var(--accent-strong);
176
+ font-weight: 600;
177
+ }
178
+ .agent-picker details { margin-top: 4px; }
179
+ .agent-picker summary {
180
+ cursor: pointer;
181
+ color: var(--muted);
182
+ font-size: 13px;
183
+ }
184
+ .agent-picker .custom-warning {
185
+ background: var(--warn-soft);
186
+ border: 1px solid var(--warn);
187
+ color: var(--text);
188
+ border-radius: 8px;
189
+ padding: 10px 12px;
190
+ font-size: 13px;
191
+ margin-top: 8px;
192
+ }
193
+ .agent-picker .custom-form {
194
+ display: grid;
195
+ grid-template-columns: 1fr 1fr auto;
196
+ gap: 8px;
197
+ margin-top: 8px;
198
+ }
199
+ .agent-picker .custom-form input {
200
+ border: 1px solid var(--line);
201
+ border-radius: 8px;
202
+ padding: 8px 10px;
203
+ font: inherit;
204
+ }
205
+ .agent-picker .custom-form button {
206
+ background: var(--accent);
207
+ color: #fff;
208
+ border: 0;
209
+ border-radius: 8px;
210
+ padding: 8px 14px;
211
+ cursor: pointer;
212
+ font: inherit;
213
+ }
214
+
215
+ /* Project row picker affordances */
216
+ .row .project-picker {
217
+ display: flex;
218
+ gap: 8px;
219
+ align-items: center;
220
+ flex-basis: 100%;
221
+ margin-top: 8px;
222
+ }
223
+ .row .project-picker input {
224
+ flex: 1;
225
+ border: 1px solid var(--line);
226
+ border-radius: 8px;
227
+ padding: 8px 12px;
228
+ font: inherit;
229
+ }
230
+ .row .project-picker .browse {
231
+ background: var(--surface);
232
+ border: 1px solid var(--line);
233
+ border-radius: 8px;
234
+ padding: 8px 12px;
235
+ cursor: pointer;
236
+ font: inherit;
237
+ }
238
+ .row .project-picker .browse:hover { background: var(--soft); border-color: var(--accent); }
239
+
240
+ /* Preflight summary — shown above the Continue button on the project row.
241
+ Tells the user exactly which side effects FRAIM will perform when they
242
+ click Continue. The "no surprises" half of the non-tech-user invariant. */
243
+ .row .preflight-summary {
244
+ flex-basis: 100%;
245
+ margin-top: 12px;
246
+ padding: 12px 14px;
247
+ border: 1px solid var(--line);
248
+ background: var(--soft);
249
+ border-radius: 8px;
250
+ font-size: 13px;
251
+ color: var(--muted);
252
+ }
253
+ .row .preflight-heading {
254
+ color: var(--text);
255
+ font-weight: 600;
256
+ margin-bottom: 6px;
257
+ }
258
+ .row .preflight-list {
259
+ margin: 0;
260
+ padding-left: 18px;
261
+ }
262
+ .row .preflight-list li { margin: 2px 0; }
263
+
264
+ .actions {
265
+ display: flex;
266
+ justify-content: flex-end;
267
+ gap: 8px;
268
+ margin-top: 20px;
269
+ }
270
+
271
+ /* Primary button — same geometry as Hub's send-button (R5.2). */
272
+ .primary-button {
273
+ background: var(--accent);
274
+ color: #fff;
275
+ border: 0;
276
+ border-radius: 10px;
277
+ padding: 10px 18px;
278
+ font: inherit;
279
+ font-weight: 600;
280
+ cursor: pointer;
281
+ }
282
+ .primary-button:hover { background: var(--accent-strong); }
283
+ .primary-button:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
284
+ .primary-button:disabled { background: #c5d2cb; cursor: not-allowed; }
285
+
286
+ .status {
287
+ margin: 16px 0 0;
288
+ padding: 12px 14px;
289
+ border-radius: 10px;
290
+ background: var(--soft);
291
+ border: 1px solid var(--line);
292
+ color: var(--muted);
293
+ font-size: 14px;
294
+ min-height: 1em;
295
+ }
296
+ .status:empty { display: none; }
297
+ .status[data-tone="error"] {
298
+ background: #fbf1f1;
299
+ border-color: var(--danger);
300
+ color: var(--danger);
301
+ }
302
+
303
+ /* Error frame — R6.1 single visual contract. */
304
+ .error-frame {
305
+ flex-basis: 100%;
306
+ margin-top: 10px;
307
+ background: #fbf1f1;
308
+ border: 1px solid var(--danger);
309
+ border-radius: 10px;
310
+ padding: 12px 14px;
311
+ display: flex;
312
+ flex-direction: column;
313
+ gap: 8px;
314
+ }
315
+ .error-frame .what-tried {
316
+ color: var(--danger);
317
+ font-weight: 600;
318
+ }
319
+ .error-frame .what-happened {
320
+ background: #0d1410;
321
+ color: #f1c0c0;
322
+ font-family: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
323
+ font-size: 12px;
324
+ padding: 10px 12px;
325
+ border-radius: 8px;
326
+ max-height: 88px;
327
+ overflow: auto;
328
+ white-space: pre;
329
+ margin: 0;
330
+ }
331
+ .error-frame .show-full {
332
+ align-self: flex-start;
333
+ font-size: 12px;
334
+ color: var(--muted);
335
+ cursor: pointer;
336
+ background: 0;
337
+ border: 0;
338
+ padding: 0;
339
+ text-decoration: underline;
340
+ }
341
+ .error-frame .actions {
342
+ display: flex;
343
+ gap: 8px;
344
+ margin-top: 4px;
345
+ justify-content: flex-start;
346
+ }
347
+ .error-frame .action {
348
+ border-radius: 8px;
349
+ padding: 8px 14px;
350
+ cursor: pointer;
351
+ font: inherit;
352
+ font-weight: 500;
353
+ border: 1px solid var(--line);
354
+ background: var(--surface);
355
+ color: var(--text);
356
+ }
357
+ .error-frame .action[data-variant="primary"] {
358
+ background: var(--accent);
359
+ color: #fff;
360
+ border-color: var(--accent);
361
+ }
362
+ .error-frame .action[data-variant="primary"]:hover { background: var(--accent-strong); }
363
+ .error-frame .action[data-variant="secondary"]:hover {
364
+ border-color: var(--accent);
365
+ color: var(--accent-strong);
366
+ }
367
+ .error-frame .action[data-variant="ghost"] {
368
+ background: transparent;
369
+ border-color: transparent;
370
+ color: var(--accent-strong);
371
+ }
372
+
373
+ /* Below ~600px the row's flex layout starts compressing the verb text and
374
+ * clipping the project-picker. First-run is desktop-by-spec but we still
375
+ * want the surface to degrade gracefully for users who happen to open it
376
+ * in a narrow window. Stack the label / verb / change link vertically and
377
+ * let the row breathe. */
378
+ @media (max-width: 600px) {
379
+ .page { padding: 24px 16px 24px; }
380
+ .checklist .row { gap: 8px; padding: 12px 14px; }
381
+ .row .label { min-width: 0; }
382
+ .row .verb { flex: 1 1 100%; }
383
+ .row .change-link { margin-left: auto; }
384
+ .row .project-picker { gap: 8px; }
385
+ .row .project-picker input { width: 100%; min-width: 0; }
386
+ }