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.
@@ -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: grid;
75
- place-items: center;
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
- overflow: hidden;
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: 560px;
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-8) var(--space-8) var(--space-5);
145
+ padding: var(--space-6) var(--space-8) var(--space-5);
116
146
  border-bottom: 1px solid var(--color-border);
117
- text-align: center;
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: clamp(1.5rem, 4vw, 1.875rem);
122
- font-weight: 800;
166
+ font-size: 15px;
167
+ font-weight: var(--font-semibold);
123
168
  color: var(--color-text);
124
- letter-spacing: -0.03em;
169
+ letter-spacing: -0.01em;
125
170
  line-height: 1.1;
126
171
  }
127
172
 
128
- .wizard-subtitle {
129
- margin-top: var(--space-2);
130
- font-size: var(--text-sm);
131
- color: var(--color-text-secondary);
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
- /* ── Step Indicators ───────────────────────────────────────────────────── */
142
- .step-indicators {
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
- .step-dot {
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
- align-items: center;
162
- justify-content: center;
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
- .step-dot:disabled {
170
- opacity: 0.5;
171
- cursor: not-allowed;
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
- .step-dot.active {
175
- border-color: var(--color-primary);
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
- .step-dot.completed {
183
- border-color: var(--color-success);
184
- background: var(--color-success);
185
- color: #fff;
186
- cursor: pointer;
211
+ .prog-labels {
212
+ display: flex;
213
+ gap: 3px;
187
214
  }
188
215
 
189
- .step-dot.completed:hover {
190
- box-shadow: 0 0 0 4px rgba(64, 192, 87, 0.15);
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
- .step-line {
194
- flex: 1;
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
- .step-line.active {
202
- background: var(--color-success);
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
- margin-top: auto;
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
- border-top: 1px solid var(--color-border);
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
- /* ── Connection Type Cards ─────────────────────────────────────────────── */
379
- .conn-card {
502
+ /* ── Provider Card Grid ──────────────────────────────────────────────── */
503
+ .provider-grid {
380
504
  display: flex;
381
- align-items: center;
382
- gap: var(--space-4);
383
- width: 100%;
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
- .conn-card:last-child { margin-bottom: 0; }
396
-
397
- .conn-card:hover {
398
- border-color: var(--color-primary);
399
- box-shadow: 0 0 0 3px var(--color-primary-subtle), 0 4px 12px rgba(0, 0, 0, 0.06);
400
- transform: translateY(-1px);
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
- .conn-card:active {
404
- transform: translateY(0);
405
- box-shadow: 0 0 0 3px var(--color-primary-subtle);
406
- transition-duration: 60ms;
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
- .conn-icon {
410
- flex-shrink: 0;
411
- width: 44px;
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
- .conn-icon--cloud { background: rgba(51, 154, 240, 0.1); color: #339af0; }
421
- .conn-icon--local { background: rgba(64, 192, 87, 0.1); color: #40c057; }
422
- .conn-card:hover .conn-icon--cloud { background: rgba(51, 154, 240, 0.18); }
423
- .conn-card:hover .conn-icon--local { background: rgba(64, 192, 87, 0.18); }
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
- .conn-badge {
432
- display: inline-flex;
433
- align-items: center;
434
- padding: 1px 7px;
435
- font-size: 0.6875rem;
436
- font-weight: var(--font-semibold);
437
- letter-spacing: 0.03em;
438
- border-radius: var(--radius-full);
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
- .conn-badge--local { background: rgba(64, 192, 87, 0.1); color: #2f9e44; border-color: rgba(64, 192, 87, 0.2); }
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
- .conn-arrow {
447
- flex-shrink: 0;
448
- color: var(--color-text-tertiary);
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
- .conn-card:hover .conn-arrow { color: var(--color-primary); transform: translateX(2px); }
557
+ .pcard.verified {
558
+ border-color: var(--color-success);
559
+ background: var(--color-success-bg);
560
+ }
455
561
 
456
- /* ── Connections Hub List ──────────────────────────────────────────────── */
457
- .hub-list {
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
- .hub-row {
566
+ .pcard-header {
467
567
  display: flex;
468
- justify-content: space-between;
469
568
  align-items: center;
470
- gap: var(--space-3);
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
- .hub-row-info { display: flex; align-items: center; gap: var(--space-2); flex: 1; min-width: 0; flex-wrap: wrap; }
478
- .hub-row-name { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--color-text); }
479
-
480
- .hub-row-badge {
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
- color: var(--color-text-secondary);
487
- display: inline-flex;
488
- align-items: center;
489
- gap: 4px;
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
- .hub-row-tested {
493
- border-color: var(--color-success-border);
494
- background: var(--color-success-bg);
495
- color: var(--color-success);
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
- .hub-row-url {
598
+ .pcard-desc {
499
599
  font-size: var(--text-xs);
500
600
  color: var(--color-text-tertiary);
501
- font-family: var(--font-mono);
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
- .hub-row-actions { display: flex; gap: var(--space-1); flex-shrink: 0; }
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
- .hub-action {
511
- background: none;
512
- border: 1px solid var(--color-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
- .hub-action:hover { background: var(--color-bg-secondary); border-color: var(--color-border-hover); color: var(--color-text); }
523
- .hub-action--danger:hover { border-color: #fca5a5; background: #fef2f2; color: #dc2626; }
625
+ .pcard.verified .pcard-check {
626
+ background: var(--color-success);
627
+ border-color: var(--color-success);
628
+ }
524
629
 
525
- .hub-empty {
526
- padding: var(--space-6) var(--space-4);
527
- text-align: center;
528
- background: var(--color-bg-secondary);
529
- border: 1px dashed var(--color-border);
530
- border-radius: var(--radius-lg);
531
- margin-bottom: var(--space-4);
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
- .hub-empty-headline { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); margin: 0 0 var(--space-2); }
535
- .hub-empty-body { font-size: var(--text-sm); color: var(--color-text-secondary); margin: 0 0 var(--space-4); line-height: 1.5; }
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
- /* ── Connection Details ────────────────────────────────────────────────── */
538
- .connection-mode-card {
539
- margin-bottom: var(--space-5);
540
- padding: var(--space-4);
541
- border: 1px solid var(--color-border);
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
- .connection-mode-card--local { border-color: rgba(64, 192, 87, 0.35); }
547
- .connection-mode-card--cloud { border-color: rgba(51, 154, 240, 0.28); }
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
- .connection-mode-header { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
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
- .connection-mode-badge {
553
- display: inline-flex;
554
- align-items: center;
555
- padding: 4px 10px;
556
- border-radius: var(--radius-full);
557
- font-size: var(--text-xs);
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
- .connection-mode-card p { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--color-text-secondary); line-height: 1.5; }
564
- .connection-mode-list { margin: 0; padding-left: 1.1rem; color: var(--color-text); display: grid; gap: var(--space-2); }
565
- .connection-mode-list li { font-size: var(--text-sm); line-height: 1.45; }
566
-
567
- /* Provider quick-picks (cloud) */
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
- .provider-chip {
571
- padding: 6px 14px;
572
- font-size: var(--text-xs);
573
- font-weight: var(--font-medium);
574
- border: 1px solid var(--color-border);
575
- border-radius: var(--radius-full);
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
- cursor: pointer;
579
- transition: all var(--transition-fast);
679
+ font-size: 13px;
680
+ font-family: var(--font-mono);
681
+ outline: none;
682
+ transition: border-color 0.15s;
580
683
  }
581
684
 
582
- .provider-chip:hover { border-color: var(--color-primary); color: var(--color-primary); }
583
- .provider-chip.selected { border-color: var(--color-primary); background: var(--color-primary); color: #000; }
685
+ .auth-row input:focus {
686
+ border-color: var(--color-primary);
687
+ }
584
688
 
585
- /* Local provider detection */
586
- .provider-option {
587
- display: flex;
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
- gap: var(--space-3);
590
- width: 100%;
591
- padding: var(--space-3) var(--space-4);
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
- font-size: var(--text-sm);
597
- color: var(--color-text);
598
- margin-bottom: var(--space-2);
599
- transition: all var(--transition-fast);
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
- .provider-option:hover { border-color: var(--color-primary); background: var(--color-bg-secondary); }
603
- .provider-option.selected { border-color: var(--color-primary); background: rgba(80, 200, 120, 0.08); }
725
+ .auth-feedback-ok {
726
+ background: var(--color-green-soft);
727
+ border: 1px solid #bbf7d0;
728
+ color: #15803d;
729
+ }
604
730
 
605
- .provider-option-status { display: flex; align-items: center; }
606
- .status-dot--ok { width: 8px; height: 8px; border-radius: 50%; background: var(--color-success); }
607
- .provider-option-label { flex: 1; font-weight: var(--font-medium); }
608
- .provider-option-hint { font-size: var(--text-xs); color: var(--color-text-tertiary); }
731
+ .auth-feedback-err {
732
+ background: var(--color-red-soft);
733
+ border: 1px solid #fecaca;
734
+ color: #b91c1c;
735
+ }
609
736
 
610
- /* Ollama enable section */
611
- .enable-ollama-section {
612
- padding: var(--space-4);
737
+ /* ── Ollama Mode Prompt ──────────────────────────────────────────────── */
738
+ .ollama-mode-prompt {
613
739
  background: var(--color-bg-secondary);
614
- border: 1px dashed var(--color-border);
615
- border-radius: var(--radius-md);
616
- margin-bottom: var(--space-4);
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
- .enable-ollama-info { margin-bottom: var(--space-3); }
620
- .enable-ollama-title { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--color-text); margin: 0 0 var(--space-1); }
621
- .enable-ollama-desc { font-size: var(--text-xs); color: var(--color-text-secondary); margin: 0; line-height: 1.4; }
622
- .enable-ollama-btn { width: 100%; }
623
- .ollama-progress { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text-secondary); padding: var(--space-2) 0; }
746
+ .ollama-mode-prompt p {
747
+ font-size: 13px;
748
+ color: var(--color-text-secondary);
749
+ margin-bottom: 10px;
750
+ }
624
751
 
625
- .connection-success {
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
- gap: var(--space-2);
629
- padding: var(--space-2) var(--space-3);
630
- background: var(--color-success-bg);
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
- font-size: var(--text-sm);
634
- color: var(--color-text);
635
- margin-bottom: var(--space-2);
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
- /* ── Model Card (Required Models) ──────────────────────────────────────── */
639
- .model-card {
640
- background: var(--color-bg-secondary);
641
- border: 1px solid var(--color-border);
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: var(--space-4);
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-card-header { margin-bottom: var(--space-4); }
648
- .model-card-title { display: block; font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); margin-bottom: var(--space-1); }
649
- .model-card-help { display: block; font-size: var(--text-xs); color: var(--color-text-secondary); line-height: 1.4; }
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
- .add-connection-link {
652
- display: block;
653
- margin-bottom: var(--space-2);
654
- background: none;
655
- border: none;
656
- color: var(--color-primary);
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
- cursor: pointer;
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
- /* ── Optional Add-ons ──────────────────────────────────────────────────── */
665
- .addon-row {
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
- margin-bottom: var(--space-3);
669
- overflow: hidden;
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
- .addon-row--active { border-color: var(--color-primary); }
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
- .addon-toggle-row {
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
- align-items: flex-start;
677
- gap: var(--space-3);
678
- padding: var(--space-3) var(--space-4);
1005
+ justify-content: space-between;
1006
+ align-items: center;
679
1007
  }
680
1008
 
681
- .addon-toggle-label {
1009
+ .review-row {
682
1010
  display: flex;
683
1011
  align-items: center;
684
- gap: var(--space-2);
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
- flex-shrink: 0;
1057
+ transition: all 0.15s;
1058
+ font-family: var(--font-sans);
687
1059
  }
688
1060
 
689
- .addon-label-text { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--color-text); }
690
- .addon-help { font-size: var(--text-xs); color: var(--color-text-secondary); line-height: 1.4; padding-top: 2px; }
1061
+ .btn-json-toggle:hover {
1062
+ border-color: var(--color-border-hover);
1063
+ color: var(--color-text);
1064
+ }
691
1065
 
692
- .addon-fields {
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
- /* Radio */
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; }