openpalm 0.9.7 → 0.9.9
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.
- package/bin/openpalm.js +5 -0
- package/package.json +4 -2
- package/playwright.config.ts +16 -0
- package/src/commands/install-file.test.ts +306 -0
- package/src/commands/install-services.test.ts +12 -7
- package/src/commands/install-services.ts +1 -1
- package/src/commands/install.ts +113 -30
- package/src/commands/restart.ts +2 -35
- package/src/commands/service.ts +0 -17
- package/src/commands/start.ts +5 -43
- package/src/commands/status.ts +0 -9
- package/src/commands/stop.ts +4 -36
- package/src/commands/uninstall.ts +23 -14
- package/src/commands/update.ts +0 -9
- package/src/lib/docker.ts +25 -7
- package/src/lib/env.ts +6 -59
- package/src/lib/paths.ts +11 -1
- package/src/lib/staging.ts +3 -3
- package/src/main.test.ts +67 -83
- package/src/main.ts +1 -1
- package/src/setup-wizard/index.html +114 -180
- package/src/setup-wizard/server-errors.test.ts +429 -0
- package/src/setup-wizard/server-integration.test.ts +511 -0
- package/src/setup-wizard/server.test.ts +6 -6
- package/src/setup-wizard/server.ts +17 -5
- package/src/setup-wizard/standalone.ts +166 -0
- package/src/setup-wizard/wizard.css +892 -299
- package/src/setup-wizard/wizard.js +1172 -559
- package/src/lib/admin.ts +0 -107
|
@@ -51,6 +51,19 @@
|
|
|
51
51
|
--color-danger: #dc2626;
|
|
52
52
|
--color-error: #dc2626;
|
|
53
53
|
|
|
54
|
+
/* Additional colors from reference design */
|
|
55
|
+
--color-blue: #2563EB;
|
|
56
|
+
--color-blue-soft: #EFF6FF;
|
|
57
|
+
--color-teal: #0d9488;
|
|
58
|
+
--color-teal-soft: #f0fdfa;
|
|
59
|
+
--color-purple: #7c3aed;
|
|
60
|
+
--color-purple-soft: #f5f3ff;
|
|
61
|
+
--color-red-soft: #fef2f2;
|
|
62
|
+
--color-green-soft: #f0fdf4;
|
|
63
|
+
--color-yellow: #FFD21E;
|
|
64
|
+
--color-yellow-soft: #FFF3C4;
|
|
65
|
+
--color-yellow-dark: #F59E0B;
|
|
66
|
+
|
|
54
67
|
/* Transitions */
|
|
55
68
|
--transition-fast: 0.15s ease;
|
|
56
69
|
}
|
|
@@ -71,21 +84,33 @@ body {
|
|
|
71
84
|
/* ── Page Layout ───────────────────────────────────────────────────────── */
|
|
72
85
|
.setup-page {
|
|
73
86
|
min-height: 100vh;
|
|
74
|
-
display:
|
|
75
|
-
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
/* flex instead of grid+place-items avoids the grid column being sized to the
|
|
91
|
+
card's max-width, which caused the card to exceed the viewport width on
|
|
92
|
+
narrow screens (< 720px). */
|
|
76
93
|
padding: var(--space-6);
|
|
77
94
|
background:
|
|
78
95
|
radial-gradient(ellipse 80% 60% at 15% 10%, rgba(255, 157, 0, 0.06) 0%, transparent 60%),
|
|
79
96
|
radial-gradient(ellipse 60% 50% at 85% 90%, rgba(99, 102, 241, 0.05) 0%, transparent 55%),
|
|
80
97
|
#f8f9fb;
|
|
81
98
|
position: relative;
|
|
82
|
-
|
|
99
|
+
/* Only clip horizontally (to hide the decorative radial-gradient bleed).
|
|
100
|
+
overflow:hidden was clipping the card vertically on short viewports. */
|
|
101
|
+
overflow-x: hidden;
|
|
102
|
+
overflow-y: auto;
|
|
83
103
|
}
|
|
84
104
|
|
|
85
105
|
/* ── Wizard Card ───────────────────────────────────────────────────────── */
|
|
86
106
|
.wizard-card {
|
|
87
107
|
width: 100%;
|
|
88
|
-
max-width:
|
|
108
|
+
max-width: min(100%, 720px);
|
|
109
|
+
/* Cap height so the card never taller than the viewport minus the page
|
|
110
|
+
padding (2 × 24px). The body scrolls internally; step-actions sticks
|
|
111
|
+
at the bottom of the visible card area, not at the bottom of the
|
|
112
|
+
full scroll-height. Use calc() so it responds to any viewport height. */
|
|
113
|
+
max-height: calc(100vh - 48px);
|
|
89
114
|
background: var(--color-bg);
|
|
90
115
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
91
116
|
border-radius: 20px;
|
|
@@ -107,28 +132,48 @@ body {
|
|
|
107
132
|
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
108
133
|
}
|
|
109
134
|
|
|
135
|
+
@keyframes fadeIn {
|
|
136
|
+
from { opacity: 0; transform: translateY(6px); }
|
|
137
|
+
to { opacity: 1; transform: translateY(0); }
|
|
138
|
+
}
|
|
139
|
+
|
|
110
140
|
@media (prefers-reduced-motion: reduce) {
|
|
111
141
|
.wizard-card { animation: none; }
|
|
112
142
|
}
|
|
113
143
|
|
|
114
144
|
.wizard-header {
|
|
115
|
-
padding: var(--space-
|
|
145
|
+
padding: var(--space-6) var(--space-8) var(--space-5);
|
|
116
146
|
border-bottom: 1px solid var(--color-border);
|
|
117
|
-
|
|
147
|
+
display: flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
gap: 10px;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.hdr-logo {
|
|
153
|
+
width: 30px;
|
|
154
|
+
height: 30px;
|
|
155
|
+
border-radius: 8px;
|
|
156
|
+
background: var(--color-primary);
|
|
157
|
+
display: grid;
|
|
158
|
+
place-items: center;
|
|
159
|
+
font-weight: 700;
|
|
160
|
+
font-size: 12px;
|
|
161
|
+
color: #1a1a1a;
|
|
162
|
+
flex-shrink: 0;
|
|
118
163
|
}
|
|
119
164
|
|
|
120
165
|
.wizard-header h1 {
|
|
121
|
-
font-size:
|
|
122
|
-
font-weight:
|
|
166
|
+
font-size: 15px;
|
|
167
|
+
font-weight: var(--font-semibold);
|
|
123
168
|
color: var(--color-text);
|
|
124
|
-
letter-spacing: -0.
|
|
169
|
+
letter-spacing: -0.01em;
|
|
125
170
|
line-height: 1.1;
|
|
126
171
|
}
|
|
127
172
|
|
|
128
|
-
.
|
|
129
|
-
|
|
130
|
-
font-
|
|
131
|
-
|
|
173
|
+
.hdr-suffix {
|
|
174
|
+
color: var(--color-text-tertiary);
|
|
175
|
+
font-weight: 400;
|
|
176
|
+
margin-left: 4px;
|
|
132
177
|
}
|
|
133
178
|
|
|
134
179
|
.wizard-body {
|
|
@@ -136,70 +181,54 @@ body {
|
|
|
136
181
|
flex: 1;
|
|
137
182
|
display: flex;
|
|
138
183
|
flex-direction: column;
|
|
184
|
+
overflow-y: auto;
|
|
185
|
+
min-height: 0;
|
|
139
186
|
}
|
|
140
187
|
|
|
141
|
-
/* ──
|
|
142
|
-
.
|
|
143
|
-
display: flex;
|
|
144
|
-
align-items: center;
|
|
188
|
+
/* ── Segmented Progress Bar ───────────────────────────────────────────── */
|
|
189
|
+
.prog-bar {
|
|
145
190
|
margin-bottom: var(--space-6);
|
|
146
|
-
padding: var(--space-2) 0;
|
|
147
|
-
gap: 0;
|
|
148
191
|
}
|
|
149
192
|
|
|
150
|
-
.
|
|
151
|
-
width: 36px;
|
|
152
|
-
height: 36px;
|
|
153
|
-
flex-shrink: 0;
|
|
154
|
-
border-radius: 50%;
|
|
155
|
-
border: 2px solid var(--color-border-hover);
|
|
156
|
-
background: var(--color-bg);
|
|
157
|
-
color: var(--color-text-secondary);
|
|
158
|
-
font-size: var(--text-xs);
|
|
159
|
-
font-weight: var(--font-bold);
|
|
193
|
+
.prog-segments {
|
|
160
194
|
display: flex;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
cursor: pointer;
|
|
164
|
-
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
165
|
-
position: relative;
|
|
166
|
-
z-index: 1;
|
|
195
|
+
gap: 3px;
|
|
196
|
+
margin-bottom: 6px;
|
|
167
197
|
}
|
|
168
198
|
|
|
169
|
-
.
|
|
170
|
-
|
|
171
|
-
|
|
199
|
+
.prog-seg {
|
|
200
|
+
flex: 1;
|
|
201
|
+
height: 3px;
|
|
202
|
+
border-radius: 2px;
|
|
203
|
+
background: var(--color-border);
|
|
204
|
+
transition: background 0.3s;
|
|
172
205
|
}
|
|
173
206
|
|
|
174
|
-
.
|
|
175
|
-
|
|
176
|
-
background: var(--color-primary);
|
|
177
|
-
color: #000;
|
|
178
|
-
transform: scale(1.1);
|
|
179
|
-
box-shadow: 0 0 0 4px rgba(255, 157, 0, 0.15), 0 0 0 8px rgba(255, 157, 0, 0.05);
|
|
207
|
+
.prog-seg.on {
|
|
208
|
+
background: var(--color-primary-hover);
|
|
180
209
|
}
|
|
181
210
|
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
color: #fff;
|
|
186
|
-
cursor: pointer;
|
|
211
|
+
.prog-labels {
|
|
212
|
+
display: flex;
|
|
213
|
+
gap: 3px;
|
|
187
214
|
}
|
|
188
215
|
|
|
189
|
-
.
|
|
190
|
-
|
|
216
|
+
.prog-lbl {
|
|
217
|
+
flex: 1;
|
|
218
|
+
font-size: 11px;
|
|
219
|
+
font-weight: var(--font-medium);
|
|
220
|
+
color: var(--color-text-tertiary);
|
|
221
|
+
transition: color 0.3s;
|
|
222
|
+
cursor: pointer;
|
|
191
223
|
}
|
|
192
224
|
|
|
193
|
-
.
|
|
194
|
-
|
|
195
|
-
min-width: var(--space-4);
|
|
196
|
-
height: 2px;
|
|
197
|
-
background: var(--color-border);
|
|
198
|
-
transition: background 0.4s ease;
|
|
225
|
+
.prog-lbl.on {
|
|
226
|
+
color: var(--color-text-secondary);
|
|
199
227
|
}
|
|
200
228
|
|
|
201
|
-
.
|
|
202
|
-
|
|
229
|
+
.prog-lbl.active {
|
|
230
|
+
color: var(--color-text);
|
|
231
|
+
font-weight: var(--font-semibold);
|
|
203
232
|
}
|
|
204
233
|
|
|
205
234
|
/* ── Step Content ──────────────────────────────────────────────────────── */
|
|
@@ -207,6 +236,7 @@ body {
|
|
|
207
236
|
display: flex;
|
|
208
237
|
flex-direction: column;
|
|
209
238
|
flex: 1;
|
|
239
|
+
animation: fadeIn 0.25s ease;
|
|
210
240
|
}
|
|
211
241
|
|
|
212
242
|
.step-content h2 {
|
|
@@ -224,14 +254,80 @@ body {
|
|
|
224
254
|
line-height: 1.5;
|
|
225
255
|
}
|
|
226
256
|
|
|
257
|
+
/* ── Welcome Hero ──────────────────────────────────────────────────────── */
|
|
258
|
+
.welcome-hero {
|
|
259
|
+
text-align: center;
|
|
260
|
+
padding: 40px 0 24px;
|
|
261
|
+
animation: fadeIn 0.25s ease;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.welcome-icon {
|
|
265
|
+
font-size: 48px;
|
|
266
|
+
margin-bottom: var(--space-4);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.welcome-hero h2 {
|
|
270
|
+
font-size: 28px;
|
|
271
|
+
text-align: center;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.welcome-subtitle {
|
|
275
|
+
max-width: 380px;
|
|
276
|
+
margin: 8px auto 28px;
|
|
277
|
+
font-size: var(--text-sm);
|
|
278
|
+
color: var(--color-text-secondary);
|
|
279
|
+
line-height: 1.5;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.welcome-pills {
|
|
283
|
+
display: flex;
|
|
284
|
+
gap: 8px;
|
|
285
|
+
justify-content: center;
|
|
286
|
+
flex-wrap: wrap;
|
|
287
|
+
margin-bottom: var(--space-8);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.pill {
|
|
291
|
+
font-size: 13px;
|
|
292
|
+
color: var(--color-text-secondary);
|
|
293
|
+
background: var(--color-bg);
|
|
294
|
+
border: 1px solid var(--color-border);
|
|
295
|
+
padding: 5px 14px;
|
|
296
|
+
border-radius: 100px;
|
|
297
|
+
}
|
|
298
|
+
|
|
227
299
|
/* ── Step Actions ──────────────────────────────────────────────────────── */
|
|
228
300
|
.step-actions {
|
|
229
301
|
display: flex;
|
|
230
302
|
justify-content: flex-end;
|
|
303
|
+
align-items: center;
|
|
231
304
|
gap: var(--space-3);
|
|
232
|
-
|
|
305
|
+
/* Stick to the bottom of the visible wizard-body scroll area. This keeps
|
|
306
|
+
nav buttons permanently in view on content-heavy steps (providers,
|
|
307
|
+
models, voice, options, review) where the step-content scroll height
|
|
308
|
+
exceeds the body's client height.
|
|
309
|
+
NOTE: negative margins break sticky in most browsers, so the separator
|
|
310
|
+
is achieved with a box-shadow inset rather than a border-top + bleed. */
|
|
311
|
+
position: sticky;
|
|
312
|
+
bottom: 0;
|
|
313
|
+
background: var(--color-bg);
|
|
233
314
|
padding-top: var(--space-5);
|
|
234
|
-
|
|
315
|
+
padding-bottom: var(--space-2);
|
|
316
|
+
/* Use inset box-shadow as top separator — avoids needing negative-margin
|
|
317
|
+
bleed that would break sticky positioning. */
|
|
318
|
+
box-shadow: 0 -1px 0 var(--color-border);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.nav-info {
|
|
322
|
+
font-size: var(--text-xs);
|
|
323
|
+
color: var(--color-text-tertiary);
|
|
324
|
+
margin-right: auto;
|
|
325
|
+
margin-left: var(--space-2);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.nav-info b {
|
|
329
|
+
color: var(--color-success);
|
|
330
|
+
font-weight: var(--font-semibold);
|
|
235
331
|
}
|
|
236
332
|
|
|
237
333
|
/* ── Buttons ───────────────────────────────────────────────────────────── */
|
|
@@ -277,6 +373,34 @@ body {
|
|
|
277
373
|
transition-duration: 0.1s;
|
|
278
374
|
}
|
|
279
375
|
|
|
376
|
+
.btn-primary-lg {
|
|
377
|
+
background: var(--color-primary);
|
|
378
|
+
color: #1a1a1a;
|
|
379
|
+
border-color: transparent;
|
|
380
|
+
padding: 12px 32px;
|
|
381
|
+
font-size: 15px;
|
|
382
|
+
font-weight: var(--font-bold);
|
|
383
|
+
border-radius: var(--radius-lg);
|
|
384
|
+
box-shadow: 0 1px 3px rgba(255, 157, 0, 0.3), 0 4px 12px rgba(255, 157, 0, 0.2);
|
|
385
|
+
display: inline-flex;
|
|
386
|
+
align-items: center;
|
|
387
|
+
gap: var(--space-2);
|
|
388
|
+
font-family: var(--font-sans);
|
|
389
|
+
line-height: 1.4;
|
|
390
|
+
cursor: pointer;
|
|
391
|
+
transition: all 0.2s ease;
|
|
392
|
+
white-space: nowrap;
|
|
393
|
+
justify-content: center;
|
|
394
|
+
text-decoration: none;
|
|
395
|
+
border: none;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.btn-primary-lg:hover {
|
|
399
|
+
background: var(--color-primary-hover);
|
|
400
|
+
box-shadow: 0 2px 6px rgba(255, 157, 0, 0.4), 0 8px 20px rgba(255, 157, 0, 0.25);
|
|
401
|
+
transform: translateY(-1px);
|
|
402
|
+
}
|
|
403
|
+
|
|
280
404
|
.btn-secondary {
|
|
281
405
|
background: var(--color-bg);
|
|
282
406
|
color: var(--color-text);
|
|
@@ -375,333 +499,586 @@ body {
|
|
|
375
499
|
line-height: 1.5;
|
|
376
500
|
}
|
|
377
501
|
|
|
378
|
-
/* ──
|
|
379
|
-
.
|
|
502
|
+
/* ── Provider Card Grid ──────────────────────────────────────────────── */
|
|
503
|
+
.provider-grid {
|
|
380
504
|
display: flex;
|
|
381
|
-
|
|
382
|
-
gap: var(--space-
|
|
383
|
-
|
|
384
|
-
padding: var(--space-5);
|
|
385
|
-
background: var(--color-bg);
|
|
386
|
-
border: 1.5px solid var(--color-border);
|
|
387
|
-
border-radius: var(--radius-lg);
|
|
388
|
-
cursor: pointer;
|
|
389
|
-
text-align: left;
|
|
390
|
-
margin-bottom: var(--space-3);
|
|
391
|
-
transition: border-color 180ms ease, box-shadow 180ms ease, background 180ms ease, transform 120ms ease;
|
|
392
|
-
will-change: transform;
|
|
505
|
+
flex-direction: column;
|
|
506
|
+
gap: var(--space-5);
|
|
507
|
+
margin-bottom: var(--space-4);
|
|
393
508
|
}
|
|
394
509
|
|
|
395
|
-
.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
510
|
+
.provider-group-header {
|
|
511
|
+
display: flex;
|
|
512
|
+
align-items: baseline;
|
|
513
|
+
gap: var(--space-3);
|
|
514
|
+
margin-bottom: var(--space-2);
|
|
515
|
+
padding-bottom: var(--space-2);
|
|
516
|
+
border-bottom: 1px solid var(--color-border);
|
|
401
517
|
}
|
|
402
518
|
|
|
403
|
-
.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
519
|
+
.provider-group-label {
|
|
520
|
+
font-size: var(--text-base);
|
|
521
|
+
font-weight: var(--font-semibold);
|
|
522
|
+
color: var(--color-fg);
|
|
523
|
+
margin: 0;
|
|
407
524
|
}
|
|
408
525
|
|
|
409
|
-
.
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
height: 44px;
|
|
413
|
-
display: flex;
|
|
414
|
-
align-items: center;
|
|
415
|
-
justify-content: center;
|
|
416
|
-
border-radius: var(--radius-md);
|
|
417
|
-
transition: background 180ms ease, color 180ms ease;
|
|
526
|
+
.provider-group-desc {
|
|
527
|
+
font-size: var(--text-sm);
|
|
528
|
+
color: var(--color-fg-muted);
|
|
418
529
|
}
|
|
419
530
|
|
|
420
|
-
.
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
.conn-body { display: flex; flex-direction: column; gap: var(--space-1); flex: 1; min-width: 0; }
|
|
426
|
-
.conn-label { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-base); font-weight: var(--font-semibold); color: var(--color-text); line-height: var(--leading-tight); }
|
|
427
|
-
.conn-desc { font-size: var(--text-sm); color: var(--color-text-secondary); line-height: 1.45; }
|
|
428
|
-
.conn-note { font-size: var(--text-xs); color: var(--color-text-tertiary); line-height: 1.4; }
|
|
429
|
-
.conn-note--recommended { color: #2f9e44; font-weight: var(--font-medium); }
|
|
531
|
+
.provider-group-cards {
|
|
532
|
+
display: grid;
|
|
533
|
+
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
|
534
|
+
gap: 8px;
|
|
535
|
+
}
|
|
430
536
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
background: rgba(51, 154, 240, 0.1);
|
|
440
|
-
color: #1c7ed6;
|
|
441
|
-
border: 1px solid rgba(51, 154, 240, 0.2);
|
|
537
|
+
/* ── Provider Cards ──────────────────────────────────────────────────── */
|
|
538
|
+
.pcard {
|
|
539
|
+
background: var(--color-bg);
|
|
540
|
+
border: 1.5px solid var(--color-border);
|
|
541
|
+
border-radius: var(--radius-lg);
|
|
542
|
+
padding: 14px;
|
|
543
|
+
cursor: pointer;
|
|
544
|
+
transition: all 0.15s;
|
|
442
545
|
}
|
|
443
546
|
|
|
444
|
-
.
|
|
547
|
+
.pcard:hover {
|
|
548
|
+
border-color: var(--color-border-hover);
|
|
549
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
550
|
+
}
|
|
445
551
|
|
|
446
|
-
.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
transition: color 180ms ease, transform 180ms ease;
|
|
450
|
-
display: flex;
|
|
451
|
-
align-items: center;
|
|
552
|
+
.pcard.selected {
|
|
553
|
+
border-color: var(--color-primary-hover);
|
|
554
|
+
background: var(--color-primary-subtle);
|
|
452
555
|
}
|
|
453
556
|
|
|
454
|
-
.
|
|
557
|
+
.pcard.verified {
|
|
558
|
+
border-color: var(--color-success);
|
|
559
|
+
background: var(--color-success-bg);
|
|
560
|
+
}
|
|
455
561
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
list-style: none;
|
|
459
|
-
padding: 0;
|
|
460
|
-
margin: 0 0 var(--space-4);
|
|
461
|
-
display: flex;
|
|
462
|
-
flex-direction: column;
|
|
463
|
-
gap: var(--space-2);
|
|
562
|
+
.pcard.wide {
|
|
563
|
+
grid-column: 1 / -1;
|
|
464
564
|
}
|
|
465
565
|
|
|
466
|
-
.
|
|
566
|
+
.pcard-header {
|
|
467
567
|
display: flex;
|
|
468
|
-
justify-content: space-between;
|
|
469
568
|
align-items: center;
|
|
470
|
-
gap:
|
|
471
|
-
padding: var(--space-3) var(--space-4);
|
|
472
|
-
background: var(--color-bg);
|
|
473
|
-
border: 1px solid var(--color-border);
|
|
474
|
-
border-radius: var(--radius-md);
|
|
569
|
+
gap: 10px;
|
|
475
570
|
}
|
|
476
571
|
|
|
477
|
-
.
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
font-size: var(--text-xs);
|
|
482
|
-
padding: 2px 8px;
|
|
483
|
-
border-radius: var(--radius-full);
|
|
484
|
-
border: 1px solid var(--color-border);
|
|
572
|
+
.pcard-icon {
|
|
573
|
+
width: 36px;
|
|
574
|
+
height: 36px;
|
|
575
|
+
border-radius: var(--radius-md);
|
|
485
576
|
background: var(--color-bg-secondary);
|
|
486
|
-
|
|
487
|
-
display:
|
|
488
|
-
|
|
489
|
-
|
|
577
|
+
border: 1px solid var(--color-border);
|
|
578
|
+
display: grid;
|
|
579
|
+
place-items: center;
|
|
580
|
+
font-size: 18px;
|
|
581
|
+
flex-shrink: 0;
|
|
490
582
|
}
|
|
491
583
|
|
|
492
|
-
.
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
584
|
+
.pcard-info {
|
|
585
|
+
flex: 1;
|
|
586
|
+
min-width: 0;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.pcard-name {
|
|
590
|
+
font-size: var(--text-sm);
|
|
591
|
+
font-weight: var(--font-semibold);
|
|
592
|
+
display: flex;
|
|
593
|
+
align-items: center;
|
|
594
|
+
gap: 6px;
|
|
595
|
+
flex-wrap: wrap;
|
|
496
596
|
}
|
|
497
597
|
|
|
498
|
-
.
|
|
598
|
+
.pcard-desc {
|
|
499
599
|
font-size: var(--text-xs);
|
|
500
600
|
color: var(--color-text-tertiary);
|
|
501
|
-
|
|
601
|
+
margin-top: 1px;
|
|
502
602
|
overflow: hidden;
|
|
503
603
|
text-overflow: ellipsis;
|
|
504
604
|
white-space: nowrap;
|
|
505
|
-
max-width: 200px;
|
|
506
605
|
}
|
|
507
606
|
|
|
508
|
-
.
|
|
607
|
+
.pcard-check {
|
|
608
|
+
width: 18px;
|
|
609
|
+
height: 18px;
|
|
610
|
+
border-radius: 6px;
|
|
611
|
+
border: 2px solid var(--color-border);
|
|
612
|
+
flex-shrink: 0;
|
|
613
|
+
display: grid;
|
|
614
|
+
place-items: center;
|
|
615
|
+
font-size: 11px;
|
|
616
|
+
color: white;
|
|
617
|
+
transition: all 0.15s;
|
|
618
|
+
}
|
|
509
619
|
|
|
510
|
-
.
|
|
511
|
-
background:
|
|
512
|
-
border:
|
|
513
|
-
border-radius: var(--radius-md);
|
|
514
|
-
color: var(--color-text-secondary);
|
|
515
|
-
font-size: var(--text-xs);
|
|
516
|
-
font-weight: var(--font-medium);
|
|
517
|
-
padding: 4px 10px;
|
|
518
|
-
cursor: pointer;
|
|
519
|
-
transition: all 0.15s ease;
|
|
620
|
+
.pcard.selected .pcard-check {
|
|
621
|
+
background: var(--color-primary-hover);
|
|
622
|
+
border-color: var(--color-primary-hover);
|
|
520
623
|
}
|
|
521
624
|
|
|
522
|
-
.
|
|
523
|
-
|
|
625
|
+
.pcard.verified .pcard-check {
|
|
626
|
+
background: var(--color-success);
|
|
627
|
+
border-color: var(--color-success);
|
|
628
|
+
}
|
|
524
629
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
630
|
+
/* ── Badges ──────────────────────────────────────────────────────────── */
|
|
631
|
+
.badge {
|
|
632
|
+
font-size: 10px;
|
|
633
|
+
font-weight: var(--font-semibold);
|
|
634
|
+
letter-spacing: 0.04em;
|
|
635
|
+
text-transform: uppercase;
|
|
636
|
+
padding: 1px 6px;
|
|
637
|
+
border-radius: 4px;
|
|
532
638
|
}
|
|
533
639
|
|
|
534
|
-
.
|
|
535
|
-
.
|
|
640
|
+
.badge-cloud { background: var(--color-blue-soft); color: var(--color-blue); }
|
|
641
|
+
.badge-local { background: var(--color-teal-soft); color: var(--color-teal); }
|
|
642
|
+
.badge-hybrid { background: var(--color-purple-soft); color: var(--color-purple); }
|
|
536
643
|
|
|
537
|
-
/* ──
|
|
538
|
-
.
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
border-radius: var(--radius-lg);
|
|
543
|
-
background: linear-gradient(180deg, rgba(255,255,255,0.96) 0%, rgba(248,249,251,0.96) 100%);
|
|
644
|
+
/* ── Verification Status ─────────────────────────────────────────────── */
|
|
645
|
+
.vs {
|
|
646
|
+
font-size: var(--text-sm);
|
|
647
|
+
flex-shrink: 0;
|
|
648
|
+
margin-left: 2px;
|
|
544
649
|
}
|
|
545
650
|
|
|
546
|
-
.
|
|
547
|
-
.
|
|
651
|
+
.vs-ok { color: var(--color-success); }
|
|
652
|
+
.vs-err { color: var(--color-error); }
|
|
653
|
+
.vs-wait { color: var(--color-primary-hover); animation: blink 1.2s ease infinite; }
|
|
548
654
|
|
|
549
|
-
|
|
550
|
-
.connection-mode-header h3 { font-size: var(--text-base); margin: 0; color: var(--color-text); }
|
|
655
|
+
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
|
|
551
656
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
padding:
|
|
556
|
-
border-
|
|
557
|
-
|
|
558
|
-
font-weight: var(--font-semibold);
|
|
559
|
-
background: var(--color-primary-subtle);
|
|
560
|
-
color: var(--color-text);
|
|
657
|
+
/* ── Inline Auth Panel ───────────────────────────────────────────────── */
|
|
658
|
+
.pcard-auth {
|
|
659
|
+
margin-top: var(--space-3);
|
|
660
|
+
padding-top: var(--space-3);
|
|
661
|
+
border-top: 1px solid var(--color-border);
|
|
662
|
+
animation: fadeIn 0.2s ease;
|
|
561
663
|
}
|
|
562
664
|
|
|
563
|
-
.
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
.provider-quick-picks { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
|
|
665
|
+
.auth-row {
|
|
666
|
+
display: flex;
|
|
667
|
+
gap: 6px;
|
|
668
|
+
margin-bottom: var(--space-2);
|
|
669
|
+
}
|
|
569
670
|
|
|
570
|
-
.
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
border:
|
|
575
|
-
border
|
|
671
|
+
.auth-row input {
|
|
672
|
+
flex: 1;
|
|
673
|
+
min-width: 0;
|
|
674
|
+
padding: 9px 12px;
|
|
675
|
+
border-radius: var(--radius-md);
|
|
676
|
+
border: 1.5px solid var(--color-border);
|
|
576
677
|
background: var(--color-bg);
|
|
577
678
|
color: var(--color-text);
|
|
578
|
-
|
|
579
|
-
|
|
679
|
+
font-size: 13px;
|
|
680
|
+
font-family: var(--font-mono);
|
|
681
|
+
outline: none;
|
|
682
|
+
transition: border-color 0.15s;
|
|
580
683
|
}
|
|
581
684
|
|
|
582
|
-
.
|
|
583
|
-
|
|
685
|
+
.auth-row input:focus {
|
|
686
|
+
border-color: var(--color-primary);
|
|
687
|
+
}
|
|
584
688
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
689
|
+
.auth-row input::placeholder {
|
|
690
|
+
color: var(--color-text-tertiary);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.auth-btn {
|
|
694
|
+
display: inline-flex;
|
|
588
695
|
align-items: center;
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
padding:
|
|
592
|
-
background: var(--color-bg);
|
|
593
|
-
border: 1px solid var(--color-border);
|
|
696
|
+
justify-content: center;
|
|
697
|
+
gap: 5px;
|
|
698
|
+
padding: 9px 14px;
|
|
594
699
|
border-radius: var(--radius-md);
|
|
700
|
+
border: none;
|
|
701
|
+
font-family: var(--font-sans);
|
|
702
|
+
font-size: 13px;
|
|
703
|
+
font-weight: var(--font-semibold);
|
|
595
704
|
cursor: pointer;
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
705
|
+
transition: all 0.15s;
|
|
706
|
+
white-space: nowrap;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.auth-btn:hover:not(:disabled) { filter: brightness(0.95); }
|
|
710
|
+
.auth-btn:disabled { opacity: 0.35; cursor: not-allowed; }
|
|
711
|
+
.auth-btn-verify { background: var(--color-primary); color: #1a1a1a; }
|
|
712
|
+
.auth-btn-verified { background: var(--color-success-bg); color: var(--color-success); border: 1px solid var(--color-success-border); }
|
|
713
|
+
.auth-btn-detect { background: var(--color-teal); color: white; }
|
|
714
|
+
.auth-btn-detected { background: var(--color-teal-soft); color: var(--color-teal); border: 1px solid #99f6e4; }
|
|
715
|
+
|
|
716
|
+
/* ── Auth Feedback ───────────────────────────────────────────────────── */
|
|
717
|
+
.auth-feedback {
|
|
718
|
+
margin-top: var(--space-2);
|
|
719
|
+
padding: var(--space-2) var(--space-3);
|
|
720
|
+
border-radius: var(--radius-md);
|
|
721
|
+
font-size: var(--text-xs);
|
|
722
|
+
animation: fadeIn 0.2s;
|
|
600
723
|
}
|
|
601
724
|
|
|
602
|
-
.
|
|
603
|
-
|
|
725
|
+
.auth-feedback-ok {
|
|
726
|
+
background: var(--color-green-soft);
|
|
727
|
+
border: 1px solid #bbf7d0;
|
|
728
|
+
color: #15803d;
|
|
729
|
+
}
|
|
604
730
|
|
|
605
|
-
.
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
731
|
+
.auth-feedback-err {
|
|
732
|
+
background: var(--color-red-soft);
|
|
733
|
+
border: 1px solid #fecaca;
|
|
734
|
+
color: #b91c1c;
|
|
735
|
+
}
|
|
609
736
|
|
|
610
|
-
/* Ollama
|
|
611
|
-
.
|
|
612
|
-
padding: var(--space-4);
|
|
737
|
+
/* ── Ollama Mode Prompt ──────────────────────────────────────────────── */
|
|
738
|
+
.ollama-mode-prompt {
|
|
613
739
|
background: var(--color-bg-secondary);
|
|
614
|
-
border: 1px
|
|
615
|
-
border-radius: var(--radius-
|
|
616
|
-
|
|
740
|
+
border: 1px solid var(--color-border);
|
|
741
|
+
border-radius: var(--radius-lg);
|
|
742
|
+
padding: 14px;
|
|
743
|
+
text-align: center;
|
|
617
744
|
}
|
|
618
745
|
|
|
619
|
-
.
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
746
|
+
.ollama-mode-prompt p {
|
|
747
|
+
font-size: 13px;
|
|
748
|
+
color: var(--color-text-secondary);
|
|
749
|
+
margin-bottom: 10px;
|
|
750
|
+
}
|
|
624
751
|
|
|
625
|
-
.
|
|
752
|
+
.ollama-mode-buttons {
|
|
626
753
|
display: flex;
|
|
754
|
+
gap: 8px;
|
|
755
|
+
justify-content: center;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
.ollama-mode-btn {
|
|
759
|
+
display: inline-flex;
|
|
627
760
|
align-items: center;
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
border: 1px solid var(--color-success-border);
|
|
761
|
+
justify-content: center;
|
|
762
|
+
gap: 5px;
|
|
763
|
+
padding: 9px 18px;
|
|
632
764
|
border-radius: var(--radius-md);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
765
|
+
border: none;
|
|
766
|
+
font-family: var(--font-sans);
|
|
767
|
+
font-size: 13px;
|
|
768
|
+
font-weight: var(--font-semibold);
|
|
769
|
+
cursor: pointer;
|
|
770
|
+
transition: all 0.15s;
|
|
771
|
+
white-space: nowrap;
|
|
636
772
|
}
|
|
637
773
|
|
|
638
|
-
|
|
639
|
-
.
|
|
640
|
-
|
|
641
|
-
|
|
774
|
+
.ollama-mode-btn:hover { filter: brightness(0.95); }
|
|
775
|
+
.ollama-mode-btn-detect { background: var(--color-teal); color: white; }
|
|
776
|
+
.ollama-mode-btn-stack { background: var(--color-bg); color: var(--color-text-secondary); border: 1px solid var(--color-border); }
|
|
777
|
+
.ollama-mode-btn-stack:hover { border-color: var(--color-border-hover); color: var(--color-text); }
|
|
778
|
+
|
|
779
|
+
/* ── Advanced Toggle ─────────────────────────────────────────────────── */
|
|
780
|
+
.adv-toggle {
|
|
781
|
+
grid-column: 1 / -1;
|
|
782
|
+
display: flex;
|
|
783
|
+
align-items: center;
|
|
784
|
+
gap: 8px;
|
|
785
|
+
padding: 8px 0;
|
|
786
|
+
cursor: pointer;
|
|
787
|
+
color: var(--color-text-tertiary);
|
|
788
|
+
font-size: 13px;
|
|
789
|
+
font-weight: var(--font-medium);
|
|
790
|
+
user-select: none;
|
|
791
|
+
border: none;
|
|
792
|
+
background: none;
|
|
793
|
+
width: 100%;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.adv-toggle:hover { color: var(--color-text-secondary); }
|
|
797
|
+
.adv-toggle::before, .adv-toggle::after {
|
|
798
|
+
content: '';
|
|
799
|
+
flex: 1;
|
|
800
|
+
height: 1px;
|
|
801
|
+
background: var(--color-border);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
.adv-toggle .arr {
|
|
805
|
+
display: inline-block;
|
|
806
|
+
transition: transform 0.2s;
|
|
807
|
+
font-size: 10px;
|
|
808
|
+
margin-left: 2px;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
.adv-toggle.open .arr { transform: rotate(90deg); }
|
|
812
|
+
|
|
813
|
+
/* ── Model Groups ────────────────────────────────────────────────────── */
|
|
814
|
+
.model-group {
|
|
815
|
+
background: var(--color-bg);
|
|
816
|
+
border: 1.5px solid var(--color-border);
|
|
642
817
|
border-radius: var(--radius-lg);
|
|
643
818
|
padding: var(--space-4);
|
|
644
|
-
margin-bottom:
|
|
819
|
+
margin-bottom: 10px;
|
|
820
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
821
|
+
/* Constrain model option lists so each group shows ~5 options before
|
|
822
|
+
scrolling, rather than expanding to show all 100+ models and pushing
|
|
823
|
+
the step-actions button 600px below the visible area. */
|
|
824
|
+
display: flex;
|
|
825
|
+
flex-direction: column;
|
|
645
826
|
}
|
|
646
827
|
|
|
647
|
-
.model-
|
|
648
|
-
.model-
|
|
649
|
-
.model-
|
|
828
|
+
/* The list of .model-opt rows within a group scrolls independently */
|
|
829
|
+
.model-group .model-filter-row ~ .model-opt,
|
|
830
|
+
.model-group > .model-opt {
|
|
831
|
+
/* Handled via the scroll container below */
|
|
832
|
+
}
|
|
650
833
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
834
|
+
/* Wrap the scrollable option list so only options scroll, not the header */
|
|
835
|
+
.model-opts-scroll {
|
|
836
|
+
max-height: 220px;
|
|
837
|
+
overflow-y: auto;
|
|
838
|
+
/* Subtle inner shadow indicates there is more content to scroll */
|
|
839
|
+
mask-image: linear-gradient(to bottom, black calc(100% - 24px), transparent 100%);
|
|
840
|
+
-webkit-mask-image: linear-gradient(to bottom, black calc(100% - 24px), transparent 100%);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
.model-group-header {
|
|
844
|
+
display: flex;
|
|
845
|
+
align-items: center;
|
|
846
|
+
gap: 8px;
|
|
847
|
+
margin-bottom: 2px;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.model-group-title {
|
|
657
851
|
font-size: var(--text-sm);
|
|
658
|
-
|
|
659
|
-
padding: var(--space-2) 0;
|
|
660
|
-
text-decoration: underline;
|
|
661
|
-
text-underline-offset: 2px;
|
|
852
|
+
font-weight: var(--font-bold);
|
|
662
853
|
}
|
|
663
854
|
|
|
664
|
-
|
|
665
|
-
|
|
855
|
+
.model-group-tag {
|
|
856
|
+
font-size: 10px;
|
|
857
|
+
font-weight: var(--font-semibold);
|
|
858
|
+
padding: 1px 6px;
|
|
859
|
+
border-radius: 4px;
|
|
860
|
+
letter-spacing: 0.04em;
|
|
861
|
+
text-transform: uppercase;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.model-group-tag-required {
|
|
865
|
+
background: var(--color-primary-subtle);
|
|
866
|
+
color: var(--color-primary-hover);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
.model-group-tag-optional {
|
|
870
|
+
background: var(--color-teal-soft);
|
|
871
|
+
color: var(--color-teal);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.model-group-desc {
|
|
875
|
+
font-size: var(--text-xs);
|
|
876
|
+
color: var(--color-text-tertiary);
|
|
877
|
+
margin-bottom: var(--space-3);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/* ── Model Search Filter ──────────────────────────────────────────── */
|
|
881
|
+
.model-filter-row {
|
|
882
|
+
margin-bottom: 6px;
|
|
883
|
+
}
|
|
884
|
+
.model-filter-input {
|
|
885
|
+
width: 100%;
|
|
886
|
+
padding: 8px 12px;
|
|
666
887
|
border: 1px solid var(--color-border);
|
|
667
888
|
border-radius: var(--radius-md);
|
|
668
|
-
|
|
669
|
-
|
|
889
|
+
font-size: 0.85rem;
|
|
890
|
+
background: var(--color-surface);
|
|
891
|
+
color: var(--color-text-primary);
|
|
892
|
+
outline: none;
|
|
893
|
+
transition: border-color 0.15s;
|
|
894
|
+
}
|
|
895
|
+
.model-filter-input:focus {
|
|
896
|
+
border-color: var(--color-primary);
|
|
897
|
+
}
|
|
898
|
+
.model-filter-input::placeholder {
|
|
899
|
+
color: var(--color-text-tertiary);
|
|
900
|
+
}
|
|
901
|
+
.model-opt-filtered {
|
|
902
|
+
display: none !important;
|
|
670
903
|
}
|
|
671
904
|
|
|
672
|
-
|
|
905
|
+
/* ── Model Option (radio-style) ──────────────────────────────────────── */
|
|
906
|
+
.model-opt {
|
|
907
|
+
display: flex;
|
|
908
|
+
align-items: center;
|
|
909
|
+
gap: 10px;
|
|
910
|
+
padding: 10px 12px;
|
|
911
|
+
border-radius: var(--radius-md);
|
|
912
|
+
cursor: pointer;
|
|
913
|
+
transition: all 0.1s;
|
|
914
|
+
margin-bottom: 2px;
|
|
915
|
+
border: 1.5px solid transparent;
|
|
916
|
+
}
|
|
673
917
|
|
|
674
|
-
.
|
|
918
|
+
.model-opt:hover { background: var(--color-bg-secondary); }
|
|
919
|
+
|
|
920
|
+
.model-opt.on {
|
|
921
|
+
background: var(--color-primary-subtle);
|
|
922
|
+
border-color: #fde68a;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
.model-opt-dot {
|
|
926
|
+
width: 16px;
|
|
927
|
+
height: 16px;
|
|
928
|
+
border-radius: 50%;
|
|
929
|
+
border: 2px solid var(--color-border);
|
|
930
|
+
flex-shrink: 0;
|
|
931
|
+
display: grid;
|
|
932
|
+
place-items: center;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
.model-opt.on .model-opt-dot {
|
|
936
|
+
border-color: var(--color-primary-hover);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.model-opt-dot-inner {
|
|
940
|
+
width: 7px;
|
|
941
|
+
height: 7px;
|
|
942
|
+
border-radius: 50%;
|
|
943
|
+
background: transparent;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.model-opt.on .model-opt-dot-inner {
|
|
947
|
+
background: var(--color-primary-hover);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.model-opt-name {
|
|
951
|
+
font-size: 13px;
|
|
952
|
+
color: var(--color-text-secondary);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
.model-opt.on .model-opt-name {
|
|
956
|
+
color: var(--color-text);
|
|
957
|
+
font-weight: var(--font-medium);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.model-opt-meta {
|
|
961
|
+
font-size: 11px;
|
|
962
|
+
color: var(--color-text-tertiary);
|
|
963
|
+
margin-top: 1px;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.model-opt-badge {
|
|
967
|
+
font-size: 9px;
|
|
968
|
+
font-weight: var(--font-semibold);
|
|
969
|
+
padding: 1px 6px;
|
|
970
|
+
border-radius: 4px;
|
|
971
|
+
letter-spacing: 0.04em;
|
|
972
|
+
text-transform: uppercase;
|
|
973
|
+
margin-left: auto;
|
|
974
|
+
flex-shrink: 0;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
.model-opt-badge-top {
|
|
978
|
+
background: var(--color-primary-subtle);
|
|
979
|
+
color: var(--color-primary-hover);
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
.model-opt-badge-auto {
|
|
983
|
+
background: var(--color-blue-soft);
|
|
984
|
+
color: var(--color-blue);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/* ── Review Summary ──────────────────────────────────────────────────── */
|
|
988
|
+
.review-card {
|
|
989
|
+
background: var(--color-bg);
|
|
990
|
+
border: 1.5px solid var(--color-border);
|
|
991
|
+
border-radius: var(--radius-lg);
|
|
992
|
+
padding: 18px;
|
|
993
|
+
margin-bottom: var(--space-4);
|
|
994
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
.review-card-title {
|
|
998
|
+
font-size: 11px;
|
|
999
|
+
font-weight: var(--font-semibold);
|
|
1000
|
+
letter-spacing: 0.06em;
|
|
1001
|
+
text-transform: uppercase;
|
|
1002
|
+
color: var(--color-text-tertiary);
|
|
1003
|
+
margin-bottom: 8px;
|
|
675
1004
|
display: flex;
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
padding: var(--space-3) var(--space-4);
|
|
1005
|
+
justify-content: space-between;
|
|
1006
|
+
align-items: center;
|
|
679
1007
|
}
|
|
680
1008
|
|
|
681
|
-
.
|
|
1009
|
+
.review-row {
|
|
682
1010
|
display: flex;
|
|
683
1011
|
align-items: center;
|
|
684
|
-
|
|
1012
|
+
justify-content: space-between;
|
|
1013
|
+
padding: 6px 0;
|
|
1014
|
+
border-bottom: 1px solid var(--color-bg-secondary);
|
|
1015
|
+
font-size: 13px;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.review-row:last-child { border-bottom: none; }
|
|
1019
|
+
|
|
1020
|
+
.review-row-label {
|
|
1021
|
+
color: var(--color-text-secondary);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.review-row-value {
|
|
1025
|
+
font-family: var(--font-mono);
|
|
1026
|
+
font-size: var(--text-xs);
|
|
1027
|
+
color: var(--color-text);
|
|
1028
|
+
text-align: right;
|
|
1029
|
+
/* Raised from 240px — model names like
|
|
1030
|
+
"adrienbrault/nous-hermes2theta-llama3-8b:q4_K_M (Ollama)" are 404px wide
|
|
1031
|
+
and were always truncated. 60% of the row gives the value enough room
|
|
1032
|
+
while keeping the label readable. */
|
|
1033
|
+
max-width: 60%;
|
|
1034
|
+
overflow: hidden;
|
|
1035
|
+
text-overflow: ellipsis;
|
|
1036
|
+
white-space: nowrap;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.review-row-value-ok {
|
|
1040
|
+
color: var(--color-success);
|
|
1041
|
+
font-family: var(--font-sans);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.review-json-toggle {
|
|
1045
|
+
margin-bottom: var(--space-3);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.btn-json-toggle {
|
|
1049
|
+
background: none;
|
|
1050
|
+
border: 1px solid var(--color-border);
|
|
1051
|
+
border-radius: var(--radius-md);
|
|
1052
|
+
color: var(--color-text-secondary);
|
|
1053
|
+
font-size: var(--text-xs);
|
|
1054
|
+
font-weight: var(--font-medium);
|
|
1055
|
+
padding: 6px 12px;
|
|
685
1056
|
cursor: pointer;
|
|
686
|
-
|
|
1057
|
+
transition: all 0.15s;
|
|
1058
|
+
font-family: var(--font-sans);
|
|
687
1059
|
}
|
|
688
1060
|
|
|
689
|
-
.
|
|
690
|
-
|
|
1061
|
+
.btn-json-toggle:hover {
|
|
1062
|
+
border-color: var(--color-border-hover);
|
|
1063
|
+
color: var(--color-text);
|
|
1064
|
+
}
|
|
691
1065
|
|
|
692
|
-
.
|
|
693
|
-
padding: var(--space-3) var(--space-4) var(--space-4);
|
|
694
|
-
border-top: 1px solid var(--color-border);
|
|
1066
|
+
.review-json pre {
|
|
695
1067
|
background: var(--color-bg-secondary);
|
|
1068
|
+
border: 1px solid var(--color-border);
|
|
1069
|
+
border-radius: var(--radius-lg);
|
|
1070
|
+
padding: 14px;
|
|
1071
|
+
font-family: var(--font-mono);
|
|
1072
|
+
font-size: 11px;
|
|
1073
|
+
line-height: 1.6;
|
|
1074
|
+
color: var(--color-text-secondary);
|
|
1075
|
+
white-space: pre;
|
|
1076
|
+
overflow-x: auto;
|
|
1077
|
+
max-height: 360px;
|
|
1078
|
+
margin-bottom: var(--space-3);
|
|
696
1079
|
}
|
|
697
1080
|
|
|
698
|
-
/*
|
|
699
|
-
.radio-fieldset { border: none; padding: 0; margin: 0; }
|
|
700
|
-
.radio-legend { display: block; font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); margin-bottom: var(--space-2); padding: 0; }
|
|
701
|
-
.radio-group { display: flex; flex-direction: column; gap: var(--space-2); }
|
|
702
|
-
.radio-label { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text); cursor: pointer; }
|
|
703
|
-
|
|
704
|
-
/* ── Review Grid ───────────────────────────────────────────────────────── */
|
|
1081
|
+
/* ── Legacy Review Grid (kept for backward compat / tests) ───────────── */
|
|
705
1082
|
.review-grid {
|
|
706
1083
|
display: flex;
|
|
707
1084
|
flex-direction: column;
|
|
@@ -775,6 +1152,34 @@ body {
|
|
|
775
1152
|
|
|
776
1153
|
.install-error { margin-top: var(--space-3); color: var(--color-danger); font-size: var(--text-sm); }
|
|
777
1154
|
|
|
1155
|
+
/* ── Optional Add-ons ──────────────────────────────────────────────────── */
|
|
1156
|
+
.addon-row {
|
|
1157
|
+
border: 1px solid var(--color-border);
|
|
1158
|
+
border-radius: var(--radius-md);
|
|
1159
|
+
margin-bottom: var(--space-3);
|
|
1160
|
+
overflow: hidden;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
.addon-row--active { border-color: var(--color-primary); }
|
|
1164
|
+
|
|
1165
|
+
.addon-toggle-row {
|
|
1166
|
+
display: flex;
|
|
1167
|
+
align-items: flex-start;
|
|
1168
|
+
gap: var(--space-3);
|
|
1169
|
+
padding: var(--space-3) var(--space-4);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.addon-toggle-label {
|
|
1173
|
+
display: flex;
|
|
1174
|
+
align-items: center;
|
|
1175
|
+
gap: var(--space-2);
|
|
1176
|
+
cursor: pointer;
|
|
1177
|
+
flex-shrink: 0;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.addon-label-text { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--color-text); }
|
|
1181
|
+
.addon-help { font-size: var(--text-xs); color: var(--color-text-secondary); line-height: 1.4; padding-top: 2px; }
|
|
1182
|
+
|
|
778
1183
|
/* ── Deploy Screen ─────────────────────────────────────────────────────── */
|
|
779
1184
|
.deploy-header { text-align: center; margin-bottom: var(--space-6); }
|
|
780
1185
|
|
|
@@ -865,8 +1270,6 @@ body {
|
|
|
865
1270
|
.deploy-failure-kicker { display: inline-block; margin-bottom: var(--space-1); font-size: var(--text-xs); font-weight: var(--font-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: #b91c1c; }
|
|
866
1271
|
.deploy-failure-header h3 { margin: 0; font-size: var(--text-lg); color: var(--color-text); }
|
|
867
1272
|
.deploy-failure-summary { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--color-text-secondary); line-height: 1.55; }
|
|
868
|
-
.deploy-failure-list { margin: 0; padding-left: 1.1rem; display: grid; gap: var(--space-2); }
|
|
869
|
-
.deploy-failure-list li { font-size: var(--text-sm); color: var(--color-text); line-height: 1.5; }
|
|
870
1273
|
|
|
871
1274
|
/* Deploy tips */
|
|
872
1275
|
.deploy-tips {
|
|
@@ -937,14 +1340,204 @@ body {
|
|
|
937
1340
|
border-radius: var(--radius-full);
|
|
938
1341
|
}
|
|
939
1342
|
|
|
1343
|
+
/* ── Voice Hint ───────────────────────────────────────────────────────── */
|
|
1344
|
+
.voice-hint {
|
|
1345
|
+
font-size: var(--text-sm);
|
|
1346
|
+
color: var(--color-text-secondary);
|
|
1347
|
+
background: var(--color-bg-secondary);
|
|
1348
|
+
border: 1px solid var(--color-border);
|
|
1349
|
+
border-radius: var(--radius-md);
|
|
1350
|
+
padding: var(--space-3) var(--space-4);
|
|
1351
|
+
margin-bottom: var(--space-4);
|
|
1352
|
+
line-height: 1.5;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
/* ── Options Sections ─────────────────────────────────────────────────── */
|
|
1356
|
+
.options-section {
|
|
1357
|
+
margin-bottom: var(--space-5);
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
.options-section-title {
|
|
1361
|
+
font-size: var(--text-base);
|
|
1362
|
+
font-weight: var(--font-bold);
|
|
1363
|
+
color: var(--color-text);
|
|
1364
|
+
margin-bottom: var(--space-1);
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
.options-section-desc {
|
|
1368
|
+
font-size: var(--text-xs);
|
|
1369
|
+
color: var(--color-text-secondary);
|
|
1370
|
+
margin-bottom: var(--space-3);
|
|
1371
|
+
line-height: 1.5;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
/* ── Toggle Card Grid ─────────────────────────────────────────────────── */
|
|
1375
|
+
.toggle-grid {
|
|
1376
|
+
display: flex;
|
|
1377
|
+
flex-direction: column;
|
|
1378
|
+
gap: 6px;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
.toggle-card {
|
|
1382
|
+
background: var(--color-bg);
|
|
1383
|
+
border: 1.5px solid var(--color-border);
|
|
1384
|
+
border-radius: var(--radius-md);
|
|
1385
|
+
padding: 10px 14px;
|
|
1386
|
+
cursor: pointer;
|
|
1387
|
+
transition: all 0.15s;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
.toggle-card:hover {
|
|
1391
|
+
border-color: var(--color-border-hover);
|
|
1392
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
.toggle-card.on {
|
|
1396
|
+
border-color: var(--color-primary-hover);
|
|
1397
|
+
background: var(--color-primary-subtle);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
.toggle-card.locked {
|
|
1401
|
+
cursor: default;
|
|
1402
|
+
opacity: 0.85;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
.toggle-card.locked:hover {
|
|
1406
|
+
box-shadow: none;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
.toggle-card-header {
|
|
1410
|
+
display: flex;
|
|
1411
|
+
align-items: center;
|
|
1412
|
+
gap: 10px;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
.toggle-card-icon {
|
|
1416
|
+
width: 32px;
|
|
1417
|
+
height: 32px;
|
|
1418
|
+
border-radius: var(--radius-sm);
|
|
1419
|
+
background: var(--color-bg-secondary);
|
|
1420
|
+
border: 1px solid var(--color-border);
|
|
1421
|
+
display: grid;
|
|
1422
|
+
place-items: center;
|
|
1423
|
+
font-size: 16px;
|
|
1424
|
+
flex-shrink: 0;
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
.toggle-card-info {
|
|
1428
|
+
flex: 1;
|
|
1429
|
+
min-width: 0;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
.toggle-card-name {
|
|
1433
|
+
font-size: var(--text-sm);
|
|
1434
|
+
font-weight: var(--font-semibold);
|
|
1435
|
+
display: flex;
|
|
1436
|
+
align-items: center;
|
|
1437
|
+
gap: 6px;
|
|
1438
|
+
flex-wrap: wrap;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
.toggle-card-desc {
|
|
1442
|
+
font-size: var(--text-xs);
|
|
1443
|
+
color: var(--color-text-tertiary);
|
|
1444
|
+
margin-top: 1px;
|
|
1445
|
+
overflow: hidden;
|
|
1446
|
+
text-overflow: ellipsis;
|
|
1447
|
+
white-space: nowrap;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
.toggle-card-switch {
|
|
1451
|
+
flex-shrink: 0;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
/* ── Toggle Track (iOS-style) ─────────────────────────────────────────── */
|
|
1455
|
+
.toggle-track {
|
|
1456
|
+
width: 36px;
|
|
1457
|
+
height: 20px;
|
|
1458
|
+
border-radius: 10px;
|
|
1459
|
+
background: var(--color-border);
|
|
1460
|
+
position: relative;
|
|
1461
|
+
transition: background 0.2s;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.toggle-track.on {
|
|
1465
|
+
background: var(--color-primary-hover);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
.toggle-track.locked {
|
|
1469
|
+
background: var(--color-success);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
.toggle-thumb {
|
|
1473
|
+
width: 16px;
|
|
1474
|
+
height: 16px;
|
|
1475
|
+
border-radius: 50%;
|
|
1476
|
+
background: white;
|
|
1477
|
+
position: absolute;
|
|
1478
|
+
top: 2px;
|
|
1479
|
+
left: 2px;
|
|
1480
|
+
transition: transform 0.2s;
|
|
1481
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.toggle-track.on .toggle-thumb,
|
|
1485
|
+
.toggle-track.locked .toggle-thumb {
|
|
1486
|
+
transform: translateX(16px);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
/* ── Channel Credential Expansion ─────────────────────────────────────── */
|
|
1490
|
+
.toggle-card.wide {
|
|
1491
|
+
grid-column: 1 / -1;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
.toggle-card .pcard-auth {
|
|
1495
|
+
margin-top: var(--space-3);
|
|
1496
|
+
padding-top: var(--space-3);
|
|
1497
|
+
border-top: 1px solid var(--color-border);
|
|
1498
|
+
animation: fadeIn 0.2s ease;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
.channel-cred-label {
|
|
1502
|
+
display: block;
|
|
1503
|
+
font-size: var(--text-xs);
|
|
1504
|
+
font-weight: var(--font-semibold);
|
|
1505
|
+
color: var(--color-text-secondary);
|
|
1506
|
+
margin-bottom: 4px;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
.channel-cred-required {
|
|
1510
|
+
color: var(--color-error, #ef4444);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
940
1513
|
/* ── Hidden utility ────────────────────────────────────────────────────── */
|
|
941
1514
|
.hidden { display: none !important; }
|
|
942
1515
|
|
|
943
1516
|
/* ── Responsive ────────────────────────────────────────────────────────── */
|
|
1517
|
+
@media (min-width: 900px) {
|
|
1518
|
+
.wizard-card { max-width: 800px; }
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
@media (min-width: 1200px) {
|
|
1522
|
+
/* On wide displays give the card more room so the provider grid and
|
|
1523
|
+
model lists don't feel cramped with 400px of empty gutter on each side. */
|
|
1524
|
+
.wizard-card { max-width: 920px; }
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
@media (max-width: 540px) {
|
|
1528
|
+
/* Reduce page padding so the card has more usable width on phones */
|
|
1529
|
+
.setup-page { padding: var(--space-3); }
|
|
1530
|
+
.wizard-card {
|
|
1531
|
+
max-height: calc(100vh - 24px);
|
|
1532
|
+
min-height: 0;
|
|
1533
|
+
border-radius: 16px;
|
|
1534
|
+
}
|
|
1535
|
+
.wizard-header { padding: var(--space-4) var(--space-5) var(--space-3); }
|
|
1536
|
+
.wizard-body { padding: var(--space-4) var(--space-5) var(--space-4); }
|
|
1537
|
+
/* No margin compensation needed — step-actions no longer uses negative margins */
|
|
1538
|
+
}
|
|
1539
|
+
|
|
944
1540
|
@media (max-width: 480px) {
|
|
945
|
-
.wizard-card { padding: 0; }
|
|
946
|
-
.wizard-header { padding: var(--space-5) var(--space-5) var(--space-4); }
|
|
947
|
-
.wizard-body { padding: var(--space-4) var(--space-5) var(--space-5); }
|
|
948
1541
|
.review-item { flex-direction: column; align-items: flex-start; }
|
|
949
1542
|
.review-value { text-align: left; }
|
|
950
1543
|
.deploy-service-row { grid-template-columns: 28px 1fr; }
|