voyageai-cli 1.33.2 → 1.33.4

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.
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Voyage AI Playground</title>
6
+ <title>VAI Playground</title>
7
7
  <link rel="icon" type="image/png" sizes="32x32" href="/icons/dark/32.png">
8
8
  <link rel="icon" type="image/png" sizes="16x16" href="/icons/dark/16.png">
9
9
  <style>
@@ -159,192 +159,6 @@ body {
159
159
  .update-progress-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width 0.3s ease; width: 0%; }
160
160
  .update-progress-label { font-size: 12px; font-family: var(--mono); color: var(--accent); min-width: 40px; text-align: right; }
161
161
 
162
- /* ── Onboarding Walkthrough ── */
163
- .onboarding-overlay {
164
- display: none;
165
- position: fixed;
166
- inset: 0;
167
- z-index: 10000;
168
- }
169
- .onboarding-overlay.active { display: block; }
170
- .onboarding-backdrop {
171
- position: absolute;
172
- inset: 0;
173
- background: rgba(0,0,0,0.6);
174
- transition: opacity 0.3s;
175
- }
176
- .onboarding-spotlight {
177
- position: absolute;
178
- border-radius: var(--radius);
179
- box-shadow: 0 0 0 9999px rgba(0,0,0,0.55);
180
- transition: all 0.4s cubic-bezier(0.4,0,0.2,1);
181
- z-index: 10001;
182
- pointer-events: none;
183
- }
184
- .onboarding-tooltip {
185
- position: absolute;
186
- z-index: 10002;
187
- background: var(--bg-card);
188
- border: 1px solid var(--accent);
189
- border-radius: 12px;
190
- padding: 24px 28px 20px;
191
- width: 380px;
192
- max-width: 90vw;
193
- box-shadow: 0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px rgba(0,212,170,0.15);
194
- transition: all 0.4s cubic-bezier(0.4,0,0.2,1);
195
- opacity: 0;
196
- transform: translateY(10px);
197
- }
198
- .onboarding-tooltip.visible {
199
- opacity: 1;
200
- transform: translateY(0);
201
- }
202
- .onboarding-tooltip-arrow {
203
- position: absolute;
204
- width: 12px;
205
- height: 12px;
206
- background: var(--bg-card);
207
- border: 1px solid var(--accent);
208
- transform: rotate(45deg);
209
- }
210
- .onboarding-tooltip-arrow.top {
211
- top: -7px;
212
- left: 30px;
213
- border-right: none;
214
- border-bottom: none;
215
- }
216
- .onboarding-tooltip-arrow.bottom {
217
- bottom: -7px;
218
- left: 30px;
219
- border-left: none;
220
- border-top: none;
221
- }
222
- .onboarding-tooltip-arrow.left {
223
- left: -7px;
224
- top: 24px;
225
- border-right: none;
226
- border-top: none;
227
- }
228
- .onboarding-step-icon {
229
- font-size: 28px;
230
- margin-bottom: 8px;
231
- }
232
- .onboarding-step-title {
233
- font-size: 16px;
234
- font-weight: 700;
235
- color: var(--accent-text);
236
- margin-bottom: 6px;
237
- }
238
- .onboarding-step-body {
239
- font-size: 13px;
240
- color: var(--text-dim);
241
- line-height: 1.6;
242
- margin-bottom: 18px;
243
- }
244
- .onboarding-step-body strong { color: var(--accent); }
245
- .onboarding-footer {
246
- display: flex;
247
- align-items: center;
248
- justify-content: space-between;
249
- gap: 12px;
250
- }
251
- .onboarding-dots {
252
- display: flex;
253
- gap: 6px;
254
- }
255
- .onboarding-dot {
256
- width: 8px;
257
- height: 8px;
258
- border-radius: 50%;
259
- background: var(--border);
260
- transition: background 0.2s;
261
- }
262
- .onboarding-dot.active { background: var(--accent); }
263
- .onboarding-dot.completed { background: var(--accent-dim); }
264
- .onboarding-actions {
265
- display: flex;
266
- gap: 8px;
267
- align-items: center;
268
- }
269
- .onboarding-skip {
270
- background: none;
271
- border: none;
272
- color: var(--text-muted);
273
- font-size: 12px;
274
- cursor: pointer;
275
- font-family: var(--font);
276
- padding: 6px 10px;
277
- border-radius: 6px;
278
- transition: color 0.15s;
279
- }
280
- .onboarding-skip:hover { color: var(--text); }
281
- .onboarding-next {
282
- background: var(--accent);
283
- color: var(--bg);
284
- border: none;
285
- border-radius: 6px;
286
- padding: 8px 20px;
287
- font-size: 13px;
288
- font-weight: 600;
289
- cursor: pointer;
290
- font-family: var(--font);
291
- transition: opacity 0.15s;
292
- }
293
- .onboarding-next:hover { opacity: 0.85; }
294
- .onboarding-welcome-center {
295
- position: fixed;
296
- inset: 0;
297
- z-index: 10002;
298
- display: flex;
299
- align-items: center;
300
- justify-content: center;
301
- pointer-events: none;
302
- }
303
- .onboarding-welcome-card {
304
- background: var(--bg-card);
305
- border: 1px solid var(--accent);
306
- border-radius: 16px;
307
- padding: 40px 44px 32px;
308
- width: 460px;
309
- max-width: 90vw;
310
- text-align: center;
311
- box-shadow: 0 20px 60px rgba(0,0,0,0.5), 0 0 80px rgba(0,212,170,0.08);
312
- pointer-events: auto;
313
- opacity: 0;
314
- transform: scale(0.95);
315
- transition: all 0.4s cubic-bezier(0.4,0,0.2,1);
316
- }
317
- .onboarding-welcome-card.visible {
318
- opacity: 1;
319
- transform: scale(1);
320
- }
321
- .onboarding-welcome-logo {
322
- width: 64px;
323
- height: 64px;
324
- margin-bottom: 16px;
325
- }
326
- .onboarding-welcome-title {
327
- font-size: 24px;
328
- font-weight: 700;
329
- color: var(--accent-text);
330
- margin-bottom: 8px;
331
- }
332
- .onboarding-welcome-sub {
333
- font-size: 14px;
334
- color: var(--text-dim);
335
- line-height: 1.6;
336
- margin-bottom: 28px;
337
- }
338
- [data-theme="light"] .onboarding-tooltip {
339
- box-shadow: 0 12px 40px rgba(0,30,43,0.15), 0 0 0 1px rgba(0,158,128,0.2);
340
- }
341
- [data-theme="light"] .onboarding-welcome-card {
342
- box-shadow: 0 20px 60px rgba(0,30,43,0.18), 0 0 80px rgba(0,158,128,0.06);
343
- }
344
- [data-theme="light"] .onboarding-backdrop {
345
- background: rgba(0,30,43,0.45);
346
- }
347
-
348
162
  /* ── App Shell: sidebar + content layout ── */
349
163
  .app-shell {
350
164
  display: flex;
@@ -354,8 +168,8 @@ body {
354
168
 
355
169
  /* ── Sidebar ── */
356
170
  .sidebar {
357
- width: 220px;
358
- min-width: 220px;
171
+ width: 316px;
172
+ min-width: 316px;
359
173
  background: var(--bg-surface);
360
174
  border-right: 1px solid var(--border);
361
175
  display: flex;
@@ -365,34 +179,26 @@ body {
365
179
  transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1), min-width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
366
180
  }
367
181
  .sidebar.collapsed {
368
- width: 56px;
369
- min-width: 56px;
182
+ width: 72px;
183
+ min-width: 72px;
370
184
  }
371
- .sidebar.collapsed .sidebar-title,
372
- .sidebar.collapsed .sidebar-nav-label,
373
- .sidebar.collapsed .sidebar-nav-divider,
185
+ .sidebar.collapsed .sidebar-brand-copy,
186
+ .sidebar.collapsed .sidebar-panel,
374
187
  .sidebar.collapsed .status-label,
375
188
  .sidebar.collapsed .sidebar-bug-label,
376
189
  .sidebar.collapsed .sidebar-docs-link span,
377
- .sidebar.collapsed .sidebar-model-group,
190
+ .sidebar.collapsed #appVersionLabel,
191
+ .sidebar.collapsed .theme-toggle,
192
+ .sidebar.collapsed .sidebar-search-btn,
378
193
  .sidebar.collapsed .sidebar-footer > div:last-child { display: none; }
379
- .sidebar.collapsed .sidebar-footer { overflow: hidden; padding: 8px 0; align-items: center; border-top: none; }
380
- .sidebar.collapsed .sidebar-footer > div:first-child { justify-content: center; }
381
- .sidebar.collapsed .sidebar-footer .theme-toggle { display: none; }
382
- .sidebar.collapsed #appVersionLabel { display: none; }
383
- .sidebar.collapsed .sidebar-docs-link { display: none; }
384
- .sidebar.collapsed .tab-btn {
385
- justify-content: center;
386
- padding: 10px;
387
- border-left-width: 2px;
388
- }
389
- .sidebar.collapsed .tab-btn span:not(.tab-btn-icon) { display: none; }
390
- .sidebar.collapsed .sidebar-settings-btn { display: none; }
194
+ .sidebar.collapsed .sidebar-footer { overflow: hidden; padding: 12px 0 56px; align-items: center; border-top: none; }
195
+ .sidebar.collapsed .sidebar-footer > div:first-child { justify-content: center; width: 100%; }
391
196
  .sidebar.collapsed .sidebar-drag-region { justify-content: center; padding: 0; padding-top: 52px; }
392
197
  body:not(.is-electron) .sidebar.collapsed .sidebar-drag-region { padding-top: 16px; padding-bottom: 12px; }
393
198
 
394
199
  /* Sidebar collapse toggle */
395
- .sidebar-collapse-btn {
200
+ .sidebar-collapse-btn,
201
+ .sidebar-search-btn {
396
202
  -webkit-app-region: no-drag;
397
203
  background: none;
398
204
  border: none;
@@ -408,15 +214,19 @@ body:not(.is-electron) .sidebar.collapsed .sidebar-drag-region { padding-top: 16
408
214
  font-size: 14px;
409
215
  line-height: 1;
410
216
  }
411
- .sidebar-collapse-btn:hover { color: var(--text); background: rgba(255,255,255,0.06); }
412
- [data-theme="light"] .sidebar-collapse-btn:hover { background: rgba(0,0,0,0.04); }
217
+ .sidebar-collapse-btn:hover,
218
+ .sidebar-search-btn:hover,
219
+ .sidebar-brand:hover { color: var(--text); background: rgba(255,255,255,0.06); }
220
+ [data-theme="light"] .sidebar-collapse-btn:hover,
221
+ [data-theme="light"] .sidebar-search-btn:hover,
222
+ [data-theme="light"] .sidebar-brand:hover { background: rgba(0,0,0,0.04); }
413
223
  .sidebar.collapsed .sidebar-collapse-btn { transform: rotate(180deg); }
414
224
 
415
225
  /* Sidebar tooltip for collapsed mode */
416
- .sidebar.collapsed .tab-btn {
226
+ .sidebar.collapsed .sidebar-rail-btn {
417
227
  position: relative;
418
228
  }
419
- .sidebar.collapsed .tab-btn::after {
229
+ .sidebar.collapsed .sidebar-rail-btn::after {
420
230
  content: attr(data-tooltip);
421
231
  position: absolute;
422
232
  left: calc(100% + 8px);
@@ -433,19 +243,19 @@ body:not(.is-electron) .sidebar.collapsed .sidebar-drag-region { padding-top: 16
433
243
  transition: opacity 0.15s 0.15s;
434
244
  z-index: 1000;
435
245
  }
436
- .sidebar.collapsed .tab-btn:hover::after {
246
+ .sidebar.collapsed .sidebar-rail-btn:hover::after {
437
247
  opacity: 1;
438
248
  }
439
249
 
440
250
  .sidebar-drag-region {
441
251
  -webkit-app-region: drag;
442
- height: 78px;
443
- min-height: 78px;
444
- padding: 0 16px;
252
+ min-height: 82px;
253
+ padding: 0 12px;
445
254
  padding-top: 52px; /* Clear macOS traffic lights fully */
446
255
  display: flex;
447
256
  align-items: center;
448
- gap: 10px;
257
+ justify-content: space-between;
258
+ gap: 12px;
449
259
  }
450
260
  body:not(.is-electron) .sidebar-drag-region {
451
261
  height: auto;
@@ -462,142 +272,255 @@ body:not(.is-electron) .sidebar-drag-region {
462
272
  object-fit: contain;
463
273
  }
464
274
 
275
+ .sidebar-brand {
276
+ -webkit-app-region: no-drag;
277
+ background: none;
278
+ border: none;
279
+ cursor: pointer;
280
+ color: inherit;
281
+ padding: 8px 10px;
282
+ border-radius: 12px;
283
+ display: flex;
284
+ align-items: center;
285
+ gap: 10px;
286
+ flex: 1;
287
+ min-width: 0;
288
+ transition: background 0.15s ease, color 0.15s ease;
289
+ }
290
+
291
+ .sidebar-brand-copy {
292
+ display: flex;
293
+ flex-direction: column;
294
+ gap: 2px;
295
+ min-width: 0;
296
+ align-items: flex-start;
297
+ }
298
+
465
299
  .sidebar-title {
466
300
  font-size: 14px;
467
301
  font-weight: 700;
468
302
  color: var(--accent-text);
469
303
  white-space: nowrap;
470
304
  letter-spacing: -0.2px;
471
- flex: 1;
472
305
  }
473
306
 
474
- .sidebar-settings-btn {
475
- -webkit-app-region: no-drag;
476
- background: none;
477
- border: none;
478
- cursor: pointer;
307
+ .sidebar-subtitle {
308
+ font-size: 11px;
479
309
  color: var(--text-muted);
480
- padding: 4px;
481
- border-radius: 4px;
310
+ letter-spacing: 0.02em;
311
+ white-space: nowrap;
312
+ overflow: hidden;
313
+ text-overflow: ellipsis;
314
+ }
315
+
316
+ .sidebar-header-actions {
482
317
  display: flex;
483
318
  align-items: center;
484
- justify-content: center;
485
- transition: all 0.15s;
486
- flex-shrink: 0;
319
+ gap: 6px;
320
+ -webkit-app-region: no-drag;
487
321
  }
488
- .sidebar-settings-btn:hover { color: var(--text); background: rgba(255,255,255,0.06); }
489
- .sidebar-settings-btn.active { color: var(--accent); }
490
- [data-theme="light"] .sidebar-settings-btn:hover { background: rgba(0,0,0,0.04); }
491
322
 
492
- .sidebar-nav {
323
+ .sidebar-nav-shell {
493
324
  flex: 1;
494
- overflow-y: auto;
495
- padding: 8px;
325
+ min-height: 0;
496
326
  display: flex;
497
- flex-direction: column;
498
- gap: 1px;
327
+ overflow: hidden;
499
328
  }
500
329
 
501
- .sidebar-nav-group {
330
+ .sidebar-rail {
331
+ width: 84px;
332
+ min-width: 84px;
333
+ border-right: 1px solid var(--border);
334
+ padding: 10px 8px 12px;
502
335
  display: flex;
503
336
  flex-direction: column;
504
- gap: 1px;
505
- }
506
- .sidebar-nav-divider {
507
- height: 1px;
508
- background: var(--border);
509
- margin: 8px 12px;
510
- opacity: 0.5;
337
+ gap: 6px;
338
+ overflow-y: auto;
511
339
  }
512
- .sidebar-nav-label {
513
- font-size: 10px;
514
- font-weight: 600;
515
- text-transform: uppercase;
516
- letter-spacing: 0.8px;
517
- color: var(--text-muted);
518
- padding: 10px 12px 4px;
340
+
341
+ .sidebar.collapsed .sidebar-rail {
342
+ width: 100%;
343
+ min-width: 0;
344
+ border-right: none;
345
+ padding-inline: 6px;
519
346
  }
520
347
 
521
- .tab-btn {
348
+ .sidebar-rail-btn {
349
+ background: none;
350
+ border: 1px solid transparent;
351
+ border-radius: 12px;
352
+ color: var(--text-muted);
353
+ padding: 10px 6px 8px;
354
+ min-height: 60px;
522
355
  display: flex;
356
+ flex-direction: column;
523
357
  align-items: center;
524
- gap: 10px;
525
- width: 100%;
526
- background: none;
527
- border: none;
528
- border-left: 3px solid transparent;
529
- border-radius: 0 6px 6px 0;
530
- color: var(--text-dim);
531
- padding: 10px 12px;
532
- font-size: 13px;
533
- font-weight: 500;
534
- font-family: var(--font);
358
+ gap: 6px;
535
359
  cursor: pointer;
536
- transition: all 0.15s;
537
- white-space: nowrap;
538
- text-align: left;
539
- position: relative;
360
+ transition: all 0.15s ease;
361
+ font-family: var(--font);
362
+ font-size: 9px;
363
+ font-weight: 600;
364
+ letter-spacing: 0.02em;
365
+ text-transform: uppercase;
540
366
  }
541
- .tab-btn:hover {
367
+
368
+ .sidebar-rail-btn:hover {
542
369
  color: var(--text);
543
- background: rgba(255,255,255,0.05);
544
- }
545
- .tab-btn:hover .tab-btn-icon {
546
- transform: scale(1.1);
370
+ background: rgba(255,255,255,0.04);
547
371
  }
548
- .tab-btn.active {
549
- color: var(--accent);
372
+
373
+ .sidebar-rail-btn.active {
374
+ color: var(--accent-text);
550
375
  background: var(--accent-glow);
551
- border-left-color: var(--accent);
552
- font-weight: 600;
376
+ border-color: rgba(0,212,170,0.14);
553
377
  }
554
- .tab-btn-icon {
378
+
379
+ [data-theme="light"] .sidebar-rail-btn:hover { background: rgba(0,30,43,0.04); }
380
+ [data-theme="light"] .sidebar-rail-btn.active { background: rgba(0,158,128,0.08); }
381
+
382
+ .sidebar-rail-btn-icon {
555
383
  width: 18px;
556
384
  height: 18px;
557
- flex-shrink: 0;
558
- transition: transform 0.15s;
559
385
  display: flex;
560
386
  align-items: center;
561
387
  justify-content: center;
562
388
  }
563
- .tab-btn-icon svg {
389
+
390
+ .sidebar-rail-btn-icon svg {
564
391
  width: 16px;
565
392
  height: 16px;
566
393
  }
567
- [data-theme="light"] .tab-btn:hover { background: rgba(0,30,43,0.04); }
568
- [data-theme="light"] .tab-btn.active { background: rgba(0,158,128,0.08); }
569
394
 
570
- .sidebar-footer {
571
- padding: 12px 16px;
572
- padding-bottom: 56px; /* Clear the fixed cost status bar */
573
- border-top: 1px solid var(--border);
574
- display: flex;
575
- flex-direction: column;
576
- gap: 8px;
395
+ .sidebar-rail-btn-label {
396
+ display: block;
397
+ width: 100%;
398
+ text-align: center;
399
+ line-height: 1.1;
400
+ white-space: nowrap;
577
401
  }
578
402
 
579
- .sidebar-model-group {
580
- display: flex;
581
- flex-direction: column;
582
- gap: 4px;
403
+ .sidebar.collapsed .sidebar-rail-btn {
404
+ padding: 10px 0;
405
+ min-height: 44px;
406
+ }
407
+
408
+ .sidebar.collapsed .sidebar-rail-btn-label {
409
+ display: none;
410
+ }
411
+
412
+ .sidebar-panel {
413
+ flex: 1;
414
+ min-width: 0;
415
+ display: flex;
416
+ flex-direction: column;
417
+ }
418
+
419
+ .sidebar-panel-header {
420
+ padding: 14px 16px 12px;
421
+ border-bottom: 1px solid var(--border);
583
422
  }
584
- .sidebar-model-label {
423
+
424
+ .sidebar-panel-eyebrow {
585
425
  font-size: 10px;
586
- font-weight: 600;
426
+ font-weight: 700;
587
427
  text-transform: uppercase;
588
- letter-spacing: 0.5px;
428
+ letter-spacing: 0.08em;
589
429
  color: var(--text-muted);
430
+ margin-bottom: 4px;
590
431
  }
591
- .nav-model-select {
592
- background: var(--bg-input);
593
- border: 1px solid var(--border);
432
+
433
+ .sidebar-panel-title {
434
+ font-size: 13px;
435
+ font-weight: 600;
594
436
  color: var(--text);
595
- padding: 6px 10px;
596
- border-radius: var(--radius);
597
- font-size: 12px;
598
- font-family: var(--mono);
599
- cursor: pointer;
437
+ letter-spacing: -0.02em;
438
+ }
439
+
440
+ .sidebar-nav {
441
+ flex: 1;
442
+ overflow-y: auto;
443
+ padding: 10px 8px 12px;
444
+ display: flex;
445
+ flex-direction: column;
446
+ gap: 12px;
447
+ }
448
+
449
+ .sidebar-nav-group {
450
+ display: none;
451
+ flex-direction: column;
452
+ gap: 2px;
453
+ }
454
+
455
+ .sidebar-nav-group.active {
456
+ display: flex;
457
+ }
458
+
459
+ .sidebar-nav-section {
460
+ font-size: 10px;
461
+ font-weight: 700;
462
+ text-transform: uppercase;
463
+ letter-spacing: 0.08em;
464
+ color: var(--text-muted);
465
+ padding: 0 8px 8px;
466
+ }
467
+
468
+ .tab-btn {
469
+ display: flex;
470
+ align-items: center;
471
+ gap: 10px;
600
472
  width: 100%;
473
+ background: none;
474
+ border: 1px solid transparent;
475
+ border-radius: 10px;
476
+ color: var(--text-dim);
477
+ padding: 10px 12px;
478
+ font-size: 13px;
479
+ font-weight: 500;
480
+ font-family: var(--font);
481
+ cursor: pointer;
482
+ transition: all 0.15s;
483
+ white-space: nowrap;
484
+ text-align: left;
485
+ position: relative;
486
+ }
487
+ .tab-btn:hover {
488
+ color: var(--text);
489
+ background: rgba(255,255,255,0.05);
490
+ border-color: rgba(255,255,255,0.05);
491
+ }
492
+ .tab-btn:hover .tab-btn-icon {
493
+ transform: scale(1.1);
494
+ }
495
+ .tab-btn.active {
496
+ color: var(--accent);
497
+ background: var(--accent-glow);
498
+ border-color: rgba(0,212,170,0.18);
499
+ font-weight: 600;
500
+ }
501
+ .tab-btn-icon {
502
+ width: 18px;
503
+ height: 18px;
504
+ flex-shrink: 0;
505
+ transition: transform 0.15s;
506
+ display: flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ }
510
+ .tab-btn-icon svg {
511
+ width: 16px;
512
+ height: 16px;
513
+ }
514
+ [data-theme="light"] .tab-btn:hover { background: rgba(0,30,43,0.04); border-color: rgba(0,30,43,0.06); }
515
+ [data-theme="light"] .tab-btn.active { background: rgba(0,158,128,0.08); }
516
+
517
+ .sidebar-footer {
518
+ padding: 12px 16px;
519
+ padding-bottom: 56px; /* Clear the fixed cost status bar */
520
+ border-top: 1px solid var(--border);
521
+ display: flex;
522
+ flex-direction: column;
523
+ gap: 8px;
601
524
  }
602
525
 
603
526
  .sidebar-controls {
@@ -1176,16 +1099,33 @@ select:focus { outline: none; border-color: var(--accent); }
1176
1099
  .models-hero {
1177
1100
  position: relative;
1178
1101
  overflow: hidden;
1179
- background: linear-gradient(135deg, rgba(0, 212, 170, 0.06), rgba(64, 224, 255, 0.06));
1102
+ background:
1103
+ linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(255, 255, 255, 0)),
1104
+ radial-gradient(circle at top right, rgba(64, 224, 255, 0.10), transparent 34%),
1105
+ linear-gradient(135deg, rgba(0, 212, 170, 0.06), rgba(64, 224, 255, 0.05)),
1106
+ var(--bg-card);
1180
1107
  border: 1px solid rgba(0, 212, 170, 0.2);
1181
1108
  margin-bottom: 24px;
1109
+ isolation: isolate;
1182
1110
  }
1183
- .models-hero-shape {
1111
+ .models-hero::before {
1112
+ content: '';
1184
1113
  position: absolute;
1185
1114
  top: -30px;
1186
1115
  right: -30px;
1187
1116
  width: 200px;
1188
1117
  height: 200px;
1118
+ border-radius: 50%;
1119
+ background: radial-gradient(circle, rgba(0, 212, 170, 0.18) 0%, rgba(64, 224, 255, 0.10) 38%, rgba(64, 224, 255, 0) 72%);
1120
+ pointer-events: none;
1121
+ z-index: 0;
1122
+ }
1123
+ .models-hero::after {
1124
+ content: '';
1125
+ position: absolute;
1126
+ inset: 0;
1127
+ border-radius: inherit;
1128
+ border: 1px solid rgba(64, 224, 255, 0.08);
1189
1129
  pointer-events: none;
1190
1130
  z-index: 0;
1191
1131
  }
@@ -1223,6 +1163,94 @@ select:focus { outline: none; border-color: var(--accent); }
1223
1163
  gap: 8px;
1224
1164
  flex-wrap: wrap;
1225
1165
  }
1166
+ .models-hero-spotlight {
1167
+ display: grid;
1168
+ grid-template-columns: minmax(0, 1fr) auto;
1169
+ gap: 16px;
1170
+ align-items: center;
1171
+ margin-bottom: 16px;
1172
+ padding: 16px 18px;
1173
+ border-radius: 14px;
1174
+ border: 1px solid rgba(64, 224, 255, 0.16);
1175
+ background:
1176
+ linear-gradient(135deg, rgba(64, 224, 255, 0.10), rgba(0, 212, 170, 0.06)),
1177
+ rgba(0, 30, 43, 0.24);
1178
+ }
1179
+ .models-hero-spotlight-badge {
1180
+ display: inline-flex;
1181
+ align-items: center;
1182
+ gap: 6px;
1183
+ margin-bottom: 8px;
1184
+ font-size: 11px;
1185
+ font-weight: 700;
1186
+ letter-spacing: 0.08em;
1187
+ text-transform: uppercase;
1188
+ color: var(--accent-text);
1189
+ }
1190
+ .models-hero-spotlight-title {
1191
+ font-size: 16px;
1192
+ font-weight: 700;
1193
+ color: var(--text);
1194
+ margin-bottom: 6px;
1195
+ }
1196
+ .models-hero-spotlight-copy {
1197
+ font-size: 13px;
1198
+ line-height: 1.6;
1199
+ color: var(--text-dim);
1200
+ max-width: 720px;
1201
+ }
1202
+ .models-hero-spotlight-note {
1203
+ font-size: 12px;
1204
+ color: var(--text-muted);
1205
+ margin-top: 8px;
1206
+ }
1207
+ .models-hero-spotlight-actions {
1208
+ display: flex;
1209
+ gap: 8px;
1210
+ flex-wrap: wrap;
1211
+ justify-content: flex-end;
1212
+ }
1213
+ .models-hero-spotlight-link {
1214
+ display: inline-flex;
1215
+ align-items: center;
1216
+ gap: 6px;
1217
+ padding: 8px 12px;
1218
+ border-radius: 8px;
1219
+ border: 1px solid var(--border);
1220
+ background: rgba(255, 255, 255, 0.02);
1221
+ color: var(--text);
1222
+ text-decoration: none;
1223
+ font-size: 12px;
1224
+ font-weight: 600;
1225
+ cursor: pointer;
1226
+ transition: all 0.15s;
1227
+ }
1228
+ .models-hero-spotlight-link:hover {
1229
+ border-color: var(--accent);
1230
+ color: var(--accent-text);
1231
+ background: rgba(0, 212, 170, 0.08);
1232
+ }
1233
+ .models-hero-spotlight-link.primary {
1234
+ background: linear-gradient(135deg, rgba(0, 212, 170, 0.20), rgba(64, 224, 255, 0.12));
1235
+ border-color: rgba(0, 212, 170, 0.28);
1236
+ }
1237
+ [data-theme="light"] .models-hero-spotlight {
1238
+ background:
1239
+ linear-gradient(135deg, rgba(0, 136, 204, 0.08), rgba(0, 158, 128, 0.05)),
1240
+ rgba(255, 255, 255, 0.85);
1241
+ border-color: rgba(0, 136, 204, 0.16);
1242
+ }
1243
+ [data-theme="light"] .models-hero-spotlight-link {
1244
+ background: rgba(255, 255, 255, 0.7);
1245
+ }
1246
+ @media (max-width: 860px) {
1247
+ .models-hero-spotlight {
1248
+ grid-template-columns: 1fr;
1249
+ }
1250
+ .models-hero-spotlight-actions {
1251
+ justify-content: flex-start;
1252
+ }
1253
+ }
1226
1254
  .model-chip {
1227
1255
  display: inline-flex;
1228
1256
  align-items: center;
@@ -1277,7 +1305,10 @@ select:focus { outline: none; border-color: var(--accent); }
1277
1305
  gap: 14px;
1278
1306
  }
1279
1307
  .model-card {
1280
- background: var(--bg-card);
1308
+ background:
1309
+ linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(255, 255, 255, 0)),
1310
+ radial-gradient(circle at top right, rgba(64, 224, 255, 0.08), transparent 38%),
1311
+ var(--bg-card);
1281
1312
  border: 1px solid var(--border);
1282
1313
  border-radius: var(--radius);
1283
1314
  padding: 18px;
@@ -1285,11 +1316,46 @@ select:focus { outline: none; border-color: var(--accent); }
1285
1316
  transition: all 0.2s;
1286
1317
  position: relative;
1287
1318
  overflow: hidden;
1319
+ isolation: isolate;
1320
+ }
1321
+ .model-card::before {
1322
+ content: '';
1323
+ position: absolute;
1324
+ top: -34px;
1325
+ right: -24px;
1326
+ width: 132px;
1327
+ height: 132px;
1328
+ border-radius: 50%;
1329
+ background: radial-gradient(circle, rgba(0, 212, 170, 0.14) 0%, rgba(64, 224, 255, 0.08) 40%, rgba(64, 224, 255, 0) 72%);
1330
+ opacity: 0.9;
1331
+ pointer-events: none;
1332
+ transition: transform 0.2s ease, opacity 0.2s ease;
1333
+ z-index: 0;
1334
+ }
1335
+ .model-card::after {
1336
+ content: '';
1337
+ position: absolute;
1338
+ inset: 0;
1339
+ border-radius: inherit;
1340
+ border: 1px solid rgba(64, 224, 255, 0.06);
1341
+ pointer-events: none;
1342
+ z-index: 0;
1343
+ }
1344
+ .model-card > * {
1345
+ position: relative;
1346
+ z-index: 1;
1288
1347
  }
1289
1348
  .model-card:hover {
1290
1349
  border-color: var(--accent);
1291
1350
  transform: translateY(-2px);
1292
- box-shadow: 0 4px 20px rgba(0, 212, 170, 0.1);
1351
+ box-shadow: 0 10px 26px rgba(0, 212, 170, 0.12);
1352
+ }
1353
+ .model-card:hover::before {
1354
+ transform: translate3d(-6px, 4px, 0) scale(1.04);
1355
+ opacity: 1;
1356
+ }
1357
+ .model-card:hover::after {
1358
+ border-color: rgba(64, 224, 255, 0.14);
1293
1359
  }
1294
1360
  .model-card.legacy {
1295
1361
  opacity: 0.5;
@@ -1297,15 +1363,6 @@ select:focus { outline: none; border-color: var(--accent); }
1297
1363
  .model-card.legacy:hover {
1298
1364
  opacity: 0.7;
1299
1365
  }
1300
- .model-card-nebula {
1301
- position: absolute;
1302
- top: -40px;
1303
- right: -40px;
1304
- width: 140px;
1305
- height: 140px;
1306
- pointer-events: none;
1307
- z-index: 0;
1308
- }
1309
1366
  .model-card-header {
1310
1367
  display: flex;
1311
1368
  align-items: center;
@@ -1626,7 +1683,28 @@ select:focus { outline: none; border-color: var(--accent); }
1626
1683
  border-color: var(--accent);
1627
1684
  }
1628
1685
  [data-theme="light"] .model-card:hover {
1629
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
1686
+ box-shadow: 0 10px 22px rgba(0, 0, 0, 0.09);
1687
+ }
1688
+ [data-theme="light"] .models-hero {
1689
+ background:
1690
+ linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(255, 255, 255, 0.86)),
1691
+ radial-gradient(circle at top right, rgba(0, 136, 204, 0.10), transparent 34%),
1692
+ linear-gradient(135deg, rgba(0, 212, 170, 0.06), rgba(64, 224, 255, 0.04)),
1693
+ var(--bg-card);
1694
+ }
1695
+ [data-theme="light"] .models-hero::before,
1696
+ [data-theme="light"] .model-card::before {
1697
+ opacity: 0.7;
1698
+ }
1699
+ [data-theme="light"] .models-hero::after,
1700
+ [data-theme="light"] .model-card::after {
1701
+ border-color: rgba(0, 136, 204, 0.08);
1702
+ }
1703
+ [data-theme="light"] .model-card {
1704
+ background:
1705
+ linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(255, 255, 255, 0.86)),
1706
+ radial-gradient(circle at top right, rgba(0, 136, 204, 0.08), transparent 38%),
1707
+ var(--bg-card);
1630
1708
  }
1631
1709
 
1632
1710
  /* Explore modal */
@@ -3830,10 +3908,14 @@ select:focus { outline: none; border-color: var(--accent); }
3830
3908
  .mm-grid { grid-template-columns: 1fr; }
3831
3909
  .mm-gallery-grid { grid-template-columns: repeat(3, 1fr); }
3832
3910
  .compare-grid, .search-results { grid-template-columns: 1fr; }
3833
- .sidebar { width: 56px; min-width: 56px; }
3834
- .sidebar-title, .status-label, .sidebar-bug-label { display: none; }
3835
- .tab-btn { justify-content: center; padding: 10px; }
3836
- .tab-btn span:not(.tab-btn-icon) { display: none; }
3911
+ .sidebar { width: 72px; min-width: 72px; }
3912
+ .sidebar-brand-copy, .sidebar-search-btn, .sidebar-panel, .status-label, .sidebar-bug-label { display: none; }
3913
+ .sidebar-drag-region { justify-content: center; padding: 16px 0 12px; min-height: auto; }
3914
+ .sidebar-rail { width: 100%; min-width: 0; border-right: none; padding: 8px 6px; }
3915
+ .sidebar-rail-btn { padding: 10px 0; }
3916
+ .sidebar-rail-btn-label { display: none; }
3917
+ .sidebar-footer { padding: 12px 0 56px; align-items: center; border-top: none; }
3918
+ .sidebar-footer > div:last-child, .theme-toggle { display: none; }
3837
3919
  .main { padding: 16px; }
3838
3920
  .settings-row { flex-direction: column; align-items: flex-start; gap: 8px; }
3839
3921
  .settings-select, .settings-input { min-width: 100%; }
@@ -6133,138 +6215,628 @@ select:focus { outline: none; border-color: var(--accent); }
6133
6215
  opacity: 0.9;
6134
6216
  }
6135
6217
 
6136
- [data-theme="light"] .home-newsletter-cta {
6137
- box-shadow: 0 4px 24px rgba(0, 30, 43, 0.06);
6218
+ [data-theme="light"] .home-newsletter-cta {
6219
+ box-shadow: 0 4px 24px rgba(0, 30, 43, 0.06);
6220
+ }
6221
+
6222
+ .home-newsletter-cta-badge {
6223
+ display: inline-block;
6224
+ font-size: 11px;
6225
+ font-weight: 600;
6226
+ letter-spacing: 0.06em;
6227
+ text-transform: uppercase;
6228
+ color: var(--accent);
6229
+ margin-bottom: 16px;
6230
+ padding: 6px 12px;
6231
+ background: var(--accent-glow);
6232
+ border-radius: 20px;
6233
+ }
6234
+
6235
+ .home-newsletter-cta-title {
6236
+ font-size: 24px;
6237
+ font-weight: 700;
6238
+ color: var(--accent-text);
6239
+ margin: 0 0 12px 0;
6240
+ letter-spacing: -0.02em;
6241
+ line-height: 1.25;
6242
+ }
6243
+
6244
+ .home-newsletter-cta-desc {
6245
+ font-size: 15px;
6246
+ color: var(--text-dim);
6247
+ line-height: 1.6;
6248
+ margin: 0 0 20px 0;
6249
+ max-width: 480px;
6250
+ margin-left: auto;
6251
+ margin-right: auto;
6252
+ }
6253
+
6254
+ .home-newsletter-cta-benefits {
6255
+ display: flex;
6256
+ flex-wrap: wrap;
6257
+ justify-content: center;
6258
+ gap: 12px 24px;
6259
+ margin-bottom: 28px;
6260
+ list-style: none;
6261
+ }
6262
+
6263
+ .home-newsletter-cta-benefits li {
6264
+ display: flex;
6265
+ align-items: center;
6266
+ gap: 8px;
6267
+ font-size: 13px;
6268
+ color: var(--text-dim);
6269
+ }
6270
+
6271
+ .home-newsletter-cta-benefits li svg {
6272
+ flex-shrink: 0;
6273
+ width: 16px;
6274
+ height: 16px;
6275
+ color: var(--accent);
6276
+ }
6277
+
6278
+ .home-newsletter-cta-button {
6279
+ display: inline-flex;
6280
+ align-items: center;
6281
+ justify-content: center;
6282
+ gap: 10px;
6283
+ background: linear-gradient(135deg, #00D4AA, #40E0FF);
6284
+ color: white;
6285
+ text-decoration: none;
6286
+ font-weight: 600;
6287
+ font-size: 15px;
6288
+ padding: 14px 28px;
6289
+ border-radius: 10px;
6290
+ transition: all 0.2s;
6291
+ box-shadow: 0 4px 16px rgba(0, 212, 170, 0.25);
6292
+ }
6293
+
6294
+ .home-newsletter-cta-button:hover {
6295
+ transform: translateY(-2px);
6296
+ box-shadow: 0 8px 24px rgba(0, 212, 170, 0.4);
6297
+ }
6298
+
6299
+ .home-newsletter-cta-button .arrow {
6300
+ width: 16px;
6301
+ height: 16px;
6302
+ transition: transform 0.2s;
6303
+ }
6304
+
6305
+ .home-newsletter-cta-button:hover .arrow {
6306
+ transform: translateX(3px);
6307
+ }
6308
+
6309
+ .home-newsletter-cta-note {
6310
+ margin-top: 16px;
6311
+ font-size: 12px;
6312
+ color: var(--text-muted);
6313
+ }
6314
+
6315
+ /* Footer */
6316
+ .home-footer {
6317
+ margin-top: 64px;
6318
+ padding-top: 32px;
6319
+ border-top: 1px solid var(--border);
6320
+ text-align: center;
6321
+ position: relative;
6322
+ overflow: hidden;
6323
+ }
6324
+
6325
+ .home-footer-links {
6326
+ display: flex;
6327
+ justify-content: center;
6328
+ gap: 24px;
6329
+ margin-bottom: 16px;
6330
+ flex-wrap: wrap;
6331
+ }
6332
+
6333
+ .home-footer-links a {
6334
+ color: var(--text-dim);
6335
+ text-decoration: none;
6336
+ font-size: 12px;
6337
+ transition: color 0.2s;
6338
+ }
6339
+
6340
+ .home-footer-links a:hover {
6341
+ color: var(--accent);
6342
+ }
6343
+
6344
+ .home-footer-branding {
6345
+ display: flex;
6346
+ flex-direction: column;
6347
+ gap: 4px;
6348
+ color: var(--text-muted);
6349
+ font-size: 11px;
6350
+ }
6351
+
6352
+ /* Simplified Home Dashboard */
6353
+ .home-hero-panel,
6354
+ .home-overview-card {
6355
+ background: linear-gradient(145deg, var(--bg-card) 0%, var(--bg-surface) 100%);
6356
+ border: 1px solid var(--border);
6357
+ border-radius: 18px;
6358
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
6359
+ }
6360
+
6361
+ [data-theme="light"] .home-hero-panel,
6362
+ [data-theme="light"] .home-overview-card {
6363
+ box-shadow: 0 8px 24px rgba(0, 30, 43, 0.05);
6364
+ }
6365
+
6366
+ .home-hero-panel {
6367
+ display: grid;
6368
+ grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
6369
+ gap: 24px;
6370
+ padding: 28px;
6371
+ margin-bottom: 32px;
6372
+ position: relative;
6373
+ overflow: hidden;
6374
+ }
6375
+
6376
+ .home-hero-panel::before {
6377
+ content: '';
6378
+ position: absolute;
6379
+ inset: 0;
6380
+ background:
6381
+ radial-gradient(circle at top right, rgba(64, 224, 255, 0.12), transparent 32%),
6382
+ radial-gradient(circle at bottom left, rgba(0, 212, 170, 0.09), transparent 28%);
6383
+ pointer-events: none;
6384
+ }
6385
+
6386
+ .home-hero-copy,
6387
+ .home-hero-side,
6388
+ .home-hero-actions,
6389
+ .home-footer-links,
6390
+ .home-footer-branding {
6391
+ position: relative;
6392
+ z-index: 1;
6393
+ }
6394
+
6395
+ .home-kicker {
6396
+ display: inline-flex;
6397
+ align-items: center;
6398
+ gap: 8px;
6399
+ margin-bottom: 14px;
6400
+ padding: 6px 12px;
6401
+ border-radius: 999px;
6402
+ border: 1px solid rgba(0, 212, 170, 0.25);
6403
+ background: rgba(0, 212, 170, 0.08);
6404
+ color: var(--accent);
6405
+ font-size: 11px;
6406
+ font-weight: 700;
6407
+ letter-spacing: 0.06em;
6408
+ text-transform: uppercase;
6409
+ }
6410
+
6411
+ .home-kicker::before {
6412
+ content: '';
6413
+ width: 8px;
6414
+ height: 8px;
6415
+ border-radius: 50%;
6416
+ background: currentColor;
6417
+ opacity: 0.75;
6418
+ }
6419
+
6420
+ .home-hero-title {
6421
+ margin: 0 0 12px 0;
6422
+ font-size: 34px;
6423
+ line-height: 1.1;
6424
+ letter-spacing: -0.03em;
6425
+ color: var(--accent-text);
6426
+ }
6427
+
6428
+ .home-hero-description {
6429
+ margin: 0;
6430
+ max-width: 620px;
6431
+ color: var(--text-dim);
6432
+ font-size: 15px;
6433
+ line-height: 1.65;
6434
+ }
6435
+
6436
+ .home-hero-links {
6437
+ display: flex;
6438
+ flex-wrap: wrap;
6439
+ gap: 10px;
6440
+ margin-top: 20px;
6441
+ }
6442
+
6443
+ .home-hero-side {
6444
+ display: flex;
6445
+ flex-direction: column;
6446
+ gap: 16px;
6447
+ align-items: stretch;
6448
+ }
6449
+
6450
+ .home-hero-robot-wrap {
6451
+ display: flex;
6452
+ align-items: center;
6453
+ justify-content: space-between;
6454
+ gap: 18px;
6455
+ padding: 18px 20px;
6456
+ border: 1px solid rgba(0, 212, 170, 0.16);
6457
+ border-radius: 16px;
6458
+ background: linear-gradient(145deg, rgba(255, 255, 255, 0.03), rgba(0, 212, 170, 0.04));
6459
+ }
6460
+
6461
+ .home-hero-robot-copy {
6462
+ min-width: 0;
6463
+ }
6464
+
6465
+ .home-hero-robot-kicker {
6466
+ display: inline-block;
6467
+ margin-bottom: 8px;
6468
+ color: var(--accent);
6469
+ font-size: 11px;
6470
+ font-weight: 700;
6471
+ text-transform: uppercase;
6472
+ letter-spacing: 0.06em;
6473
+ }
6474
+
6475
+ .home-hero-robot-copy p {
6476
+ margin: 0;
6477
+ color: var(--text-dim);
6478
+ font-size: 13px;
6479
+ line-height: 1.55;
6480
+ max-width: 220px;
6481
+ }
6482
+
6483
+ .home-hero-robot {
6484
+ flex-shrink: 0;
6485
+ width: 112px;
6486
+ height: 112px;
6487
+ display: flex;
6488
+ align-items: center;
6489
+ justify-content: center;
6490
+ border-radius: 16px;
6491
+ background: radial-gradient(circle at 50% 50%, rgba(64, 224, 255, 0.12), transparent 68%);
6492
+ }
6493
+
6494
+ .home-hero-robot svg {
6495
+ display: block;
6496
+ width: 96px;
6497
+ height: 96px;
6498
+ image-rendering: pixelated;
6499
+ filter: drop-shadow(0 8px 24px rgba(0, 212, 170, 0.16));
6500
+ }
6501
+
6502
+ .home-link-button {
6503
+ display: inline-flex;
6504
+ align-items: center;
6505
+ gap: 8px;
6506
+ padding: 9px 14px;
6507
+ background: transparent;
6508
+ border: 1px solid var(--border);
6509
+ border-radius: 10px;
6510
+ color: var(--text-dim);
6511
+ text-decoration: none;
6512
+ font-size: 13px;
6513
+ font-weight: 500;
6514
+ cursor: pointer;
6515
+ transition: all 0.2s;
6516
+ }
6517
+
6518
+ .home-link-button:hover {
6519
+ color: var(--text);
6520
+ border-color: var(--accent);
6521
+ background: var(--bg-card);
6522
+ }
6523
+
6524
+ .home-hero-actions {
6525
+ display: grid;
6526
+ grid-template-columns: repeat(2, minmax(0, 1fr));
6527
+ gap: 12px;
6528
+ align-content: start;
6529
+ }
6530
+
6531
+ .home-primary-action {
6532
+ display: flex;
6533
+ align-items: flex-start;
6534
+ gap: 12px;
6535
+ width: 100%;
6536
+ text-align: left;
6537
+ padding: 16px;
6538
+ background: rgba(255, 255, 255, 0.02);
6539
+ border: 1px solid var(--border);
6540
+ border-radius: 14px;
6541
+ color: var(--text);
6542
+ cursor: pointer;
6543
+ transition: all 0.2s;
6544
+ }
6545
+
6546
+ .home-primary-action:hover {
6547
+ transform: translateY(-2px);
6548
+ border-color: var(--accent);
6549
+ background: var(--bg-card);
6550
+ box-shadow: 0 10px 24px rgba(0, 212, 170, 0.08);
6551
+ }
6552
+
6553
+ .home-primary-action-icon {
6554
+ display: inline-flex;
6555
+ align-items: center;
6556
+ justify-content: center;
6557
+ width: 40px;
6558
+ height: 40px;
6559
+ border-radius: 12px;
6560
+ background: rgba(0, 212, 170, 0.12);
6561
+ color: var(--accent);
6562
+ flex-shrink: 0;
6563
+ }
6564
+
6565
+ .home-primary-action-icon svg {
6566
+ width: 20px;
6567
+ height: 20px;
6568
+ }
6569
+
6570
+ .home-primary-action-body {
6571
+ display: flex;
6572
+ flex-direction: column;
6573
+ gap: 4px;
6574
+ min-width: 0;
6575
+ }
6576
+
6577
+ .home-primary-action-body strong {
6578
+ font-size: 14px;
6579
+ line-height: 1.3;
6580
+ color: var(--accent-text);
6581
+ }
6582
+
6583
+ .home-primary-action-body span {
6584
+ color: var(--text-dim);
6585
+ font-size: 12px;
6586
+ line-height: 1.5;
6587
+ }
6588
+
6589
+ .home-overview-grid,
6590
+ .home-main-grid {
6591
+ display: grid;
6592
+ gap: 24px;
6593
+ }
6594
+
6595
+ .home-overview-grid {
6596
+ grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
6597
+ margin-bottom: 24px;
6598
+ }
6599
+
6600
+ .home-main-grid {
6601
+ grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
6602
+ }
6603
+
6604
+ .home-overview-card {
6605
+ padding: 24px;
6606
+ margin-bottom: 0;
6607
+ }
6608
+
6609
+ .home-overview-card .home-section-header {
6610
+ margin-bottom: 18px;
6611
+ }
6612
+
6613
+ .home-overview-card .home-section-header h3 {
6614
+ font-size: 18px;
6615
+ }
6616
+
6617
+ .home-status-grid {
6618
+ display: grid;
6619
+ grid-template-columns: repeat(2, minmax(0, 1fr));
6620
+ gap: 14px;
6621
+ }
6622
+
6623
+ .home-status-card {
6624
+ display: flex;
6625
+ flex-direction: column;
6626
+ gap: 8px;
6627
+ min-height: 152px;
6628
+ padding: 16px;
6629
+ background: var(--bg);
6630
+ border: 1px solid var(--border);
6631
+ border-radius: 14px;
6632
+ }
6633
+
6634
+ .home-status-card.is-ok {
6635
+ border-color: rgba(0, 212, 170, 0.28);
6636
+ }
6637
+
6638
+ .home-status-card.is-warning {
6639
+ border-color: rgba(255, 201, 16, 0.32);
6640
+ }
6641
+
6642
+ .home-status-label {
6643
+ font-size: 12px;
6644
+ font-weight: 600;
6645
+ color: var(--text-muted);
6646
+ text-transform: uppercase;
6647
+ letter-spacing: 0.05em;
6648
+ }
6649
+
6650
+ .home-status-value {
6651
+ font-size: 20px;
6652
+ font-weight: 700;
6653
+ color: var(--accent-text);
6654
+ letter-spacing: -0.02em;
6655
+ }
6656
+
6657
+ .home-status-description {
6658
+ color: var(--text-dim);
6659
+ font-size: 13px;
6660
+ line-height: 1.5;
6661
+ flex: 1;
6662
+ }
6663
+
6664
+ .home-status-action {
6665
+ align-self: flex-start;
6138
6666
  }
6139
6667
 
6140
- .home-newsletter-cta-badge {
6141
- display: inline-block;
6142
- font-size: 11px;
6668
+ .home-resume-main {
6669
+ display: flex;
6670
+ align-items: center;
6671
+ justify-content: space-between;
6672
+ gap: 16px;
6673
+ padding: 16px 18px;
6674
+ background: var(--bg);
6675
+ border: 1px solid var(--border);
6676
+ border-radius: 14px;
6677
+ margin-bottom: 16px;
6678
+ }
6679
+
6680
+ .home-resume-label {
6681
+ display: block;
6682
+ color: var(--text-muted);
6683
+ font-size: 12px;
6143
6684
  font-weight: 600;
6144
- letter-spacing: 0.06em;
6145
6685
  text-transform: uppercase;
6146
- color: var(--accent);
6147
- margin-bottom: 16px;
6148
- padding: 6px 12px;
6149
- background: var(--accent-glow);
6150
- border-radius: 20px;
6686
+ letter-spacing: 0.05em;
6687
+ margin-bottom: 6px;
6151
6688
  }
6152
6689
 
6153
- .home-newsletter-cta-title {
6154
- font-size: 24px;
6155
- font-weight: 700;
6690
+ .home-resume-title {
6691
+ display: block;
6156
6692
  color: var(--accent-text);
6157
- margin: 0 0 12px 0;
6158
- letter-spacing: -0.02em;
6159
- line-height: 1.25;
6693
+ font-size: 18px;
6694
+ font-weight: 700;
6695
+ margin-bottom: 4px;
6160
6696
  }
6161
6697
 
6162
- .home-newsletter-cta-desc {
6163
- font-size: 15px;
6698
+ .home-resume-description {
6164
6699
  color: var(--text-dim);
6165
- line-height: 1.6;
6166
- margin: 0 0 20px 0;
6167
- max-width: 480px;
6168
- margin-left: auto;
6169
- margin-right: auto;
6700
+ font-size: 13px;
6701
+ line-height: 1.5;
6170
6702
  }
6171
6703
 
6172
- .home-newsletter-cta-benefits {
6704
+ .home-recent-list {
6173
6705
  display: flex;
6174
- flex-wrap: wrap;
6175
- justify-content: center;
6176
- gap: 12px 24px;
6177
- margin-bottom: 28px;
6178
- list-style: none;
6706
+ flex-direction: column;
6707
+ gap: 10px;
6179
6708
  }
6180
6709
 
6181
- .home-newsletter-cta-benefits li {
6710
+ .home-recent-item {
6182
6711
  display: flex;
6183
6712
  align-items: center;
6184
- gap: 8px;
6185
- font-size: 13px;
6186
- color: var(--text-dim);
6713
+ justify-content: space-between;
6714
+ gap: 14px;
6715
+ padding: 14px 16px;
6716
+ background: var(--bg);
6717
+ border: 1px solid var(--border);
6718
+ border-radius: 12px;
6187
6719
  }
6188
6720
 
6189
- .home-newsletter-cta-benefits li svg {
6190
- flex-shrink: 0;
6191
- width: 16px;
6192
- height: 16px;
6193
- color: var(--accent);
6721
+ .home-recent-item-main {
6722
+ min-width: 0;
6194
6723
  }
6195
6724
 
6196
- .home-newsletter-cta-button {
6197
- display: inline-flex;
6198
- align-items: center;
6199
- justify-content: center;
6200
- gap: 10px;
6201
- background: linear-gradient(135deg, #00D4AA, #40E0FF);
6202
- color: white;
6203
- text-decoration: none;
6725
+ .home-recent-item-title {
6726
+ font-size: 14px;
6204
6727
  font-weight: 600;
6205
- font-size: 15px;
6206
- padding: 14px 28px;
6207
- border-radius: 10px;
6208
- transition: all 0.2s;
6209
- box-shadow: 0 4px 16px rgba(0, 212, 170, 0.25);
6728
+ color: var(--text);
6729
+ margin-bottom: 2px;
6210
6730
  }
6211
6731
 
6212
- .home-newsletter-cta-button:hover {
6213
- transform: translateY(-2px);
6214
- box-shadow: 0 8px 24px rgba(0, 212, 170, 0.4);
6732
+ .home-recent-item-meta {
6733
+ color: var(--text-muted);
6734
+ font-size: 12px;
6735
+ line-height: 1.45;
6215
6736
  }
6216
6737
 
6217
- .home-newsletter-cta-button .arrow {
6218
- width: 16px;
6219
- height: 16px;
6220
- transition: transform 0.2s;
6738
+ .home-empty-state {
6739
+ padding: 20px;
6740
+ border: 1px dashed var(--border);
6741
+ border-radius: 14px;
6742
+ background: var(--bg);
6743
+ color: var(--text-dim);
6744
+ font-size: 13px;
6745
+ line-height: 1.6;
6221
6746
  }
6222
6747
 
6223
- .home-newsletter-cta-button:hover .arrow {
6224
- transform: translateX(3px);
6748
+ .home-update-card {
6749
+ padding: 20px;
6750
+ border-radius: 14px;
6751
+ border: 1px solid var(--border);
6752
+ background: var(--bg);
6225
6753
  }
6226
6754
 
6227
- .home-newsletter-cta-note {
6228
- margin-top: 16px;
6755
+ .home-update-kicker {
6756
+ display: inline-flex;
6757
+ align-items: center;
6758
+ gap: 8px;
6759
+ margin-bottom: 14px;
6760
+ color: var(--accent);
6229
6761
  font-size: 12px;
6230
- color: var(--text-muted);
6762
+ font-weight: 700;
6763
+ text-transform: uppercase;
6764
+ letter-spacing: 0.05em;
6231
6765
  }
6232
6766
 
6233
- /* Footer */
6234
- .home-footer {
6235
- margin-top: 64px;
6236
- padding-top: 32px;
6237
- border-top: 1px solid var(--border);
6238
- text-align: center;
6239
- position: relative;
6240
- overflow: hidden;
6767
+ .home-update-title {
6768
+ margin: 0 0 6px 0;
6769
+ color: var(--accent-text);
6770
+ font-size: 22px;
6241
6771
  }
6242
6772
 
6243
- .home-footer-links {
6244
- display: flex;
6245
- justify-content: center;
6246
- gap: 24px;
6773
+ .home-update-date {
6774
+ color: var(--text-muted);
6775
+ font-size: 12px;
6247
6776
  margin-bottom: 16px;
6248
- flex-wrap: wrap;
6249
6777
  }
6250
6778
 
6251
- .home-footer-links a {
6779
+ .home-update-summary {
6252
6780
  color: var(--text-dim);
6253
- text-decoration: none;
6254
- font-size: 12px;
6255
- transition: color 0.2s;
6781
+ line-height: 1.6;
6256
6782
  }
6257
6783
 
6258
- .home-footer-links a:hover {
6259
- color: var(--accent);
6784
+ .home-update-highlights {
6785
+ margin: 16px 0 0 0;
6786
+ padding-left: 18px;
6787
+ color: var(--text-dim);
6260
6788
  }
6261
6789
 
6262
- .home-footer-branding {
6790
+ .home-update-highlights li + li {
6791
+ margin-top: 8px;
6792
+ }
6793
+
6794
+ .home-workflow-stack {
6263
6795
  display: flex;
6264
6796
  flex-direction: column;
6265
- gap: 4px;
6266
- color: var(--text-muted);
6797
+ gap: 12px;
6798
+ }
6799
+
6800
+ .home-workflow-spotlight {
6801
+ padding: 16px;
6802
+ border-radius: 14px;
6803
+ border: 1px solid var(--border);
6804
+ background: var(--bg);
6805
+ }
6806
+
6807
+ .home-workflow-spotlight h4 {
6808
+ margin: 0 0 8px 0;
6809
+ font-size: 15px;
6810
+ color: var(--accent-text);
6811
+ }
6812
+
6813
+ .home-workflow-spotlight p {
6814
+ margin: 0 0 12px 0;
6815
+ color: var(--text-dim);
6816
+ font-size: 13px;
6817
+ line-height: 1.55;
6818
+ }
6819
+
6820
+ .home-workflow-spotlight-meta {
6821
+ display: flex;
6822
+ align-items: center;
6823
+ gap: 8px;
6824
+ margin-bottom: 14px;
6825
+ flex-wrap: wrap;
6826
+ }
6827
+
6828
+ .home-workflow-spotlight .home-workflow-domain {
6829
+ background: rgba(0, 212, 170, 0.1);
6830
+ color: var(--accent);
6831
+ padding: 4px 8px;
6832
+ border-radius: 999px;
6267
6833
  font-size: 11px;
6834
+ font-weight: 600;
6835
+ }
6836
+
6837
+ .home-workflow-spotlight .home-workflow-author {
6838
+ color: var(--text-muted);
6839
+ font-size: 12px;
6268
6840
  }
6269
6841
 
6270
6842
  /* Animations */
@@ -6300,6 +6872,20 @@ select:focus { outline: none; border-color: var(--accent); }
6300
6872
  .home-content {
6301
6873
  padding: 24px;
6302
6874
  }
6875
+
6876
+ .home-hero-panel,
6877
+ .home-overview-grid,
6878
+ .home-main-grid {
6879
+ grid-template-columns: 1fr;
6880
+ }
6881
+
6882
+ .home-hero-robot-copy p {
6883
+ max-width: none;
6884
+ }
6885
+
6886
+ .home-status-grid {
6887
+ grid-template-columns: 1fr;
6888
+ }
6303
6889
 
6304
6890
  .home-quick-actions {
6305
6891
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
@@ -6318,6 +6904,34 @@ select:focus { outline: none; border-color: var(--accent); }
6318
6904
  .home-content {
6319
6905
  padding: 16px;
6320
6906
  }
6907
+
6908
+ .home-hero-panel,
6909
+ .home-overview-card {
6910
+ padding: 20px;
6911
+ }
6912
+
6913
+ .home-hero-title {
6914
+ font-size: 28px;
6915
+ }
6916
+
6917
+ .home-hero-actions {
6918
+ grid-template-columns: 1fr;
6919
+ }
6920
+
6921
+ .home-hero-robot-wrap {
6922
+ flex-direction: column;
6923
+ align-items: flex-start;
6924
+ }
6925
+
6926
+ .home-hero-robot {
6927
+ align-self: center;
6928
+ }
6929
+
6930
+ .home-resume-main,
6931
+ .home-recent-item {
6932
+ flex-direction: column;
6933
+ align-items: flex-start;
6934
+ }
6321
6935
 
6322
6936
  .home-section-header {
6323
6937
  flex-direction: column;
@@ -7612,39 +8226,73 @@ select:focus { outline: none; border-color: var(--accent); }
7612
8226
  <!-- Sidebar -->
7613
8227
  <aside class="sidebar">
7614
8228
  <div class="sidebar-drag-region">
7615
- <img class="sidebar-logo" id="sidebarLogo" src="/icons/dark/64.png" alt="Vai">
7616
- <span class="sidebar-title">Vai</span>
7617
- <button class="sidebar-collapse-btn" id="sidebarCollapseBtn" onclick="toggleSidebarCollapse()" title="Toggle sidebar"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg></button>
7618
- <button class="sidebar-search-btn" onclick="toggleCommandPalette()" title="Search commands (⌘K)"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></button>
7619
- <button class="sidebar-settings-btn" data-tab="settings" title="Settings"><svg width="16" height="16" viewBox="0 0 24 24"><use href="#lg-config"/></svg></button>
7620
- </div>
7621
- <nav class="sidebar-nav">
7622
- <div class="sidebar-nav-group" role="tablist" aria-label="Build">
7623
- <div class="sidebar-nav-label" id="nav-build-label">Build</div>
7624
- <button class="tab-btn active" data-tab="home" data-tooltip="Home" role="tab" aria-selected="true" aria-controls="tab-home" id="tab-btn-home"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg></span><span>Home</span></button>
7625
- <button class="tab-btn" data-tab="embed" data-tooltip="Embed" role="tab" aria-selected="false" aria-controls="tab-embed" id="tab-btn-embed"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-lightning"/></svg></span><span>Embed</span></button>
7626
- <button class="tab-btn" data-tab="compare" data-tooltip="Compare" role="tab" aria-selected="false" aria-controls="tab-compare" id="tab-btn-compare"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-arrows"/></svg></span><span>Compare</span></button>
7627
- <button class="tab-btn" data-tab="search" data-tooltip="Search" role="tab" aria-selected="false" aria-controls="tab-search" id="tab-btn-search"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-search"/></svg></span><span>Search</span></button>
7628
- <button class="tab-btn" data-tab="multimodal" data-tooltip="Multimodal" role="tab" aria-selected="false" aria-controls="tab-multimodal" id="tab-btn-multimodal"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-image"/></svg></span><span>Multimodal</span></button>
7629
- <button class="tab-btn" data-tab="generate" data-tooltip="Generate" role="tab" aria-selected="false" aria-controls="tab-generate" id="tab-btn-generate"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-code"/></svg></span><span>Generate</span></button>
7630
- <button class="tab-btn" data-tab="chat" data-tooltip="Chat" role="tab" aria-selected="false" aria-controls="tab-chat" id="tab-btn-chat"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-chat"/></svg></span><span>Chat</span></button>
7631
- <button class="tab-btn" data-tab="workflows" data-tooltip="Workflows" role="tab" aria-selected="false" aria-controls="tab-workflows" id="tab-btn-workflows"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="12" r="3"/><circle cx="19" cy="6" r="3"/><circle cx="19" cy="18" r="3"/><line x1="7.7" y1="10.7" x2="16.3" y2="7.3"/><line x1="7.7" y1="13.3" x2="16.3" y2="16.7"/></svg></span><span>Workflows</span></button>
7632
- </div>
7633
- <div class="sidebar-nav-divider"></div>
7634
- <div class="sidebar-nav-group" role="tablist" aria-label="Analyze">
7635
- <div class="sidebar-nav-label" id="nav-analyze-label">Analyze</div>
7636
- <button class="tab-btn" data-tab="benchmark" data-tooltip="Benchmark" role="tab" aria-selected="false" aria-controls="tab-benchmark" id="tab-btn-benchmark"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-gauge"/></svg></span><span>Benchmark</span></button>
7637
- <button class="tab-btn" data-tab="optimize" data-tooltip="Optimize" role="tab" aria-selected="false" aria-controls="tab-optimize" id="tab-btn-optimize"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8v8m4-4H8"/><circle cx="12" cy="12" r="10"/></svg></span><span>Optimize</span></button>
7638
- <button class="tab-btn" data-tab="explore" data-tooltip="Explore" role="tab" aria-selected="false" aria-controls="tab-explore" id="tab-btn-explore"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-bulb"/></svg></span><span>Explore</span></button>
7639
- <button class="tab-btn" data-tab="nano" data-tooltip="Local Inference" role="tab" aria-selected="false" aria-controls="tab-nano" id="tab-btn-nano"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/></svg></span><span>Local Inference</span></button>
8229
+ <button class="sidebar-brand" id="sidebarHomeBtn" type="button" title="Overview">
8230
+ <img class="sidebar-logo" id="sidebarLogo" src="/icons/dark/64.png" alt="Vai">
8231
+ <span class="sidebar-brand-copy">
8232
+ <span class="sidebar-title">Vai</span>
8233
+ <span class="sidebar-subtitle">Overview dashboard</span>
8234
+ </span>
8235
+ </button>
8236
+ <div class="sidebar-header-actions">
8237
+ <button class="sidebar-search-btn" onclick="toggleCommandPalette()" title="Search commands (⌘K)"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></button>
8238
+ <button class="sidebar-collapse-btn" id="sidebarCollapseBtn" onclick="toggleSidebarCollapse()" title="Toggle sidebar"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg></button>
7640
8239
  </div>
7641
- <div class="sidebar-nav-divider"></div>
7642
- <div class="sidebar-nav-group" role="tablist" aria-label="Reference">
7643
- <div class="sidebar-nav-label" id="nav-reference-label">Reference</div>
7644
- <button class="tab-btn" data-tab="models" data-tooltip="Models" role="tab" aria-selected="false" aria-controls="tab-models" id="tab-btn-models"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-bot"/></svg></span><span>Models</span></button>
7645
- <button class="tab-btn" data-tab="about" data-tooltip="About" role="tab" aria-selected="false" aria-controls="tab-about" id="tab-btn-about"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-info"/></svg></span><span>About</span></button>
8240
+ </div>
8241
+ <div class="sidebar-nav-shell">
8242
+ <nav class="sidebar-rail" aria-label="Primary navigation">
8243
+ <button class="sidebar-rail-btn active" data-section="build" data-default-tab="embed" data-tooltip="Build" type="button">
8244
+ <span class="sidebar-rail-btn-icon" aria-hidden="true"><svg><use href="#lg-lightning"/></svg></span>
8245
+ <span class="sidebar-rail-btn-label">Build</span>
8246
+ </button>
8247
+ <button class="sidebar-rail-btn" data-section="evaluate" data-default-tab="compare" data-tooltip="Evaluate" type="button">
8248
+ <span class="sidebar-rail-btn-icon" aria-hidden="true"><svg><use href="#lg-gauge"/></svg></span>
8249
+ <span class="sidebar-rail-btn-label">Evaluate</span>
8250
+ </button>
8251
+ <button class="sidebar-rail-btn" data-section="reference" data-default-tab="models" data-tooltip="Reference" type="button">
8252
+ <span class="sidebar-rail-btn-icon" aria-hidden="true"><svg><use href="#lg-bot"/></svg></span>
8253
+ <span class="sidebar-rail-btn-label">Reference</span>
8254
+ </button>
8255
+ <button class="sidebar-rail-btn" data-section="settings" data-default-tab="settings" data-tooltip="Settings" type="button">
8256
+ <span class="sidebar-rail-btn-icon" aria-hidden="true"><svg><use href="#lg-config"/></svg></span>
8257
+ <span class="sidebar-rail-btn-label">Settings</span>
8258
+ </button>
8259
+ </nav>
8260
+ <div class="sidebar-panel">
8261
+ <div class="sidebar-panel-header">
8262
+ <div class="sidebar-panel-eyebrow" id="sidebarPanelEyebrow">Build</div>
8263
+ <div class="sidebar-panel-title" id="sidebarPanelTitle">Create and run core workflows</div>
8264
+ </div>
8265
+ <nav class="sidebar-nav" aria-label="Section navigation">
8266
+ <div class="sidebar-nav-group active" data-section="build" role="tablist" aria-label="Build tools">
8267
+ <div class="sidebar-nav-section">Core tools</div>
8268
+ <button class="tab-btn" data-tab="embed" data-tooltip="Embed" role="tab" aria-selected="false" aria-controls="tab-embed" id="tab-btn-embed"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-lightning"/></svg></span><span>Embed</span></button>
8269
+ <button class="tab-btn" data-tab="search" data-tooltip="Rerank" role="tab" aria-selected="false" aria-controls="tab-search" id="tab-btn-search"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-search"/></svg></span><span>Rerank</span></button>
8270
+ <button class="tab-btn" data-tab="multimodal" data-tooltip="Multimodal" role="tab" aria-selected="false" aria-controls="tab-multimodal" id="tab-btn-multimodal"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-image"/></svg></span><span>Multimodal</span></button>
8271
+ <div class="sidebar-nav-section">Advanced tools</div>
8272
+ <button class="tab-btn" data-tab="generate" data-tooltip="Generate" role="tab" aria-selected="false" aria-controls="tab-generate" id="tab-btn-generate"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-code"/></svg></span><span>Generate</span></button>
8273
+ <button class="tab-btn" data-tab="chat" data-tooltip="Chat" role="tab" aria-selected="false" aria-controls="tab-chat" id="tab-btn-chat"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-chat"/></svg></span><span>Chat</span></button>
8274
+ <button class="tab-btn" data-tab="workflows" data-tooltip="Workflows" role="tab" aria-selected="false" aria-controls="tab-workflows" id="tab-btn-workflows"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="12" r="3"/><circle cx="19" cy="6" r="3"/><circle cx="19" cy="18" r="3"/><line x1="7.7" y1="10.7" x2="16.3" y2="7.3"/><line x1="7.7" y1="13.3" x2="16.3" y2="16.7"/></svg></span><span>Workflows</span></button>
8275
+ </div>
8276
+ <div class="sidebar-nav-group" data-section="evaluate" role="tablist" aria-label="Evaluate tools" hidden>
8277
+ <div class="sidebar-nav-section">Inspect and compare</div>
8278
+ <button class="tab-btn" data-tab="compare" data-tooltip="Compare" role="tab" aria-selected="false" aria-controls="tab-compare" id="tab-btn-compare"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-arrows"/></svg></span><span>Compare</span></button>
8279
+ <button class="tab-btn" data-tab="benchmark" data-tooltip="Benchmark" role="tab" aria-selected="false" aria-controls="tab-benchmark" id="tab-btn-benchmark"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-gauge"/></svg></span><span>Benchmark</span></button>
8280
+ <button class="tab-btn" data-tab="optimize" data-tooltip="Optimize" role="tab" aria-selected="false" aria-controls="tab-optimize" id="tab-btn-optimize"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8v8m4-4H8"/><circle cx="12" cy="12" r="10"/></svg></span><span>Optimize</span></button>
8281
+ <button class="tab-btn" data-tab="explore" data-tooltip="Explore" role="tab" aria-selected="false" aria-controls="tab-explore" id="tab-btn-explore"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-bulb"/></svg></span><span>Explore</span></button>
8282
+ <button class="tab-btn" data-tab="nano" data-tooltip="Local Inference" role="tab" aria-selected="false" aria-controls="tab-nano" id="tab-btn-nano"><span class="tab-btn-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/></svg></span><span>Local Inference</span></button>
8283
+ </div>
8284
+ <div class="sidebar-nav-group" data-section="reference" role="tablist" aria-label="Reference tools" hidden>
8285
+ <div class="sidebar-nav-section">Library</div>
8286
+ <button class="tab-btn" data-tab="models" data-tooltip="Models" role="tab" aria-selected="false" aria-controls="tab-models" id="tab-btn-models"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-bot"/></svg></span><span>Models</span></button>
8287
+ <button class="tab-btn" data-tab="about" data-tooltip="About" role="tab" aria-selected="false" aria-controls="tab-about" id="tab-btn-about"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-info"/></svg></span><span>About</span></button>
8288
+ </div>
8289
+ <div class="sidebar-nav-group" data-section="settings" role="tablist" aria-label="Settings" hidden>
8290
+ <div class="sidebar-nav-section">Preferences</div>
8291
+ <button class="tab-btn" data-tab="settings" data-tooltip="Settings" role="tab" aria-selected="false" aria-controls="tab-settings" id="tab-btn-settings"><span class="tab-btn-icon" aria-hidden="true"><svg><use href="#lg-config"/></svg></span><span>Settings</span></button>
8292
+ </div>
8293
+ </nav>
7646
8294
  </div>
7647
- </nav>
8295
+ </div>
7648
8296
  <div class="sidebar-footer">
7649
8297
  <div style="display:flex;align-items:center;gap:8px;justify-content:space-between;">
7650
8298
  <div style="display:flex;align-items:center;gap:5px;">
@@ -7689,7 +8337,7 @@ select:focus { outline: none; border-color: var(--accent); }
7689
8337
  <div class="main">
7690
8338
 
7691
8339
  <!-- ========== HOME TAB ========== -->
7692
- <div class="tab-panel active" id="tab-home" role="tabpanel" aria-labelledby="tab-btn-home" tabindex="0">
8340
+ <div class="tab-panel active" id="tab-home" role="tabpanel" aria-labelledby="sidebarHomeBtn" tabindex="0">
7693
8341
  <!-- Header Bar -->
7694
8342
  <div class="home-header">
7695
8343
  <div class="home-header-left">
@@ -7704,158 +8352,241 @@ select:focus { outline: none; border-color: var(--accent); }
7704
8352
  </div>
7705
8353
  </div>
7706
8354
 
7707
- <!-- API Key Warning Banner (hidden by default) -->
7708
- <div class="home-api-warning" id="homeApiWarning" style="display: none;">
7709
- <div class="home-api-warning-content">
7710
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
7711
- <triangle cx="12" cy="12" r="10"/>
7712
- <line x1="12" y1="8" x2="12" y2="12"/>
7713
- <line x1="12" y1="16" x2="12.01" y2="16"/>
7714
- </svg>
7715
- <span>Set up your Voyage AI API key to get started</span>
7716
- <button onclick="switchTab('settings')">Settings →</button>
7717
- </div>
7718
- </div>
7719
-
7720
8355
  <div class="home-content">
7721
- <!-- Announcements Banner -->
7722
- <div class="home-announcements" id="homeAnnouncements" style="display: none;">
7723
- <div class="home-announcements-carousel" id="announcementsCarousel">
7724
- <!-- Cards will be inserted here -->
7725
- </div>
7726
- <div class="home-announcements-dots" id="announcementsDots">
7727
- <!-- Dots will be inserted here -->
7728
- </div>
7729
- <div class="home-announcements-restore" id="announcementsRestore" style="display: none;">
7730
- <button onclick="restoreAnnouncements()">Show dismissed announcements</button>
7731
- </div>
7732
- </div>
7733
-
7734
- <div class="home-section-divider" id="divider1"></div>
7735
-
7736
- <!-- What's New (Release Notes) -->
7737
- <div class="home-section" id="homeReleases">
7738
- <div class="home-section-header">
7739
- <h3>What's New</h3>
7740
- <a href="https://github.com/mrlynn/voyageai-cli/releases" target="_blank" rel="noopener">View All →</a>
7741
- </div>
7742
- <div class="home-releases-timeline" id="releasesTimeline">
7743
- <!-- Release items will be inserted here -->
7744
- </div>
7745
- </div>
7746
-
7747
- <div class="home-section-divider" id="divider2"></div>
7748
-
7749
- <!-- Marketplace Spotlight -->
7750
- <div class="home-section">
7751
- <div class="home-section-header">
7752
- <h3>Marketplace Spotlight</h3>
7753
- <button class="home-marketplace-cta" onclick="switchTab('workflows')">
7754
- Explore the Marketplace →
7755
- </button>
7756
- </div>
7757
-
7758
- <!-- Featured Workflows -->
7759
- <div class="home-subsection">
7760
- <h4>Featured Workflows</h4>
7761
- <div class="home-workflows-carousel" id="featuredWorkflows">
7762
- <!-- Workflow cards will be inserted here -->
7763
- </div>
7764
- </div>
7765
-
7766
- <!-- Browse by Domain -->
7767
- <div class="home-subsection">
7768
- <h4>Browse by Domain</h4>
7769
- <div class="home-domain-pills">
7770
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('Healthcare')">Healthcare</button>
7771
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('Finance')">Finance</button>
7772
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('Legal')">Legal</button>
7773
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('DevOps')">DevOps</button>
7774
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('Education')">Education</button>
7775
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('E-Commerce')">E-Commerce</button>
7776
- <button class="home-domain-pill" onclick="filterAndSwitchWorkflows('Marketing')">Marketing</button>
8356
+ <section class="home-hero-panel">
8357
+ <div class="home-hero-copy">
8358
+ <span class="home-kicker">Desktop workspace</span>
8359
+ <h2 class="home-hero-title">Build, test, and ship with Voyage AI</h2>
8360
+ <p class="home-hero-description">Use one focused desktop app to generate embeddings, compare models, rerank results, and run production-friendly workflows without bouncing between docs, scripts, and browser tabs.</p>
8361
+ <div class="home-hero-links">
8362
+ <button class="home-link-button" onclick="switchTab('settings')">Open settings</button>
8363
+ <button class="home-link-button" onclick="toggleCommandPalette()">Command palette</button>
8364
+ <a class="home-link-button" href="https://docs.vaicli.com" target="_blank" rel="noopener">Documentation</a>
7777
8365
  </div>
7778
8366
  </div>
7779
-
7780
- <!-- Community Workflows -->
7781
- <div class="home-subsection">
7782
- <div class="home-subsection-header">
7783
- <h4>Community Workflows</h4>
7784
- <div class="home-sort-tabs">
7785
- <button class="home-sort-tab active" data-sort="trending" onclick="sortCommunityWorkflows('trending')">Trending</button>
7786
- <button class="home-sort-tab" data-sort="newest" onclick="sortCommunityWorkflows('newest')">Newest</button>
7787
- <button class="home-sort-tab" data-sort="installs" onclick="sortCommunityWorkflows('installs')">Most Installed</button>
8367
+ <div class="home-hero-side">
8368
+ <div class="home-hero-robot-wrap">
8369
+ <div class="home-hero-robot-copy">
8370
+ <span class="home-hero-robot-kicker">Workspace guide</span>
8371
+ <p>Your pixel robot lives in the corner now, adding personality without turning the screen into another promo panel.</p>
7788
8372
  </div>
7789
- </div>
7790
- <div class="home-community-grid" id="communityWorkflows">
7791
- <!-- Community workflow cards will be inserted here -->
7792
- </div>
7793
- </div>
7794
- </div>
7795
-
7796
- <div class="home-section-divider" id="divider3"></div>
7797
-
7798
- <!-- Quick Actions -->
7799
- <div class="home-section">
7800
- <div class="home-section-header">
7801
- <h3>Quick Actions</h3>
7802
- </div>
7803
- <div class="home-quick-actions">
7804
- <button class="home-quick-action" onclick="switchTab('embed')" title="Generate embeddings for text">
7805
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
7806
- <path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/>
7807
- </svg>
7808
- <span>New Embedding</span>
8373
+ <div class="home-hero-robot" aria-hidden="true">
8374
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" shape-rendering="crispEdges">
8375
+ <rect x="40" y="20" width="10" height="10" fill="#00d4aa"/>
8376
+ <rect x="50" y="20" width="10" height="10" fill="#00d4aa"/>
8377
+ <rect x="60" y="20" width="10" height="10" fill="#00d4aa"/>
8378
+ <rect x="70" y="20" width="10" height="10" fill="#00d4aa"/>
8379
+ <rect x="80" y="20" width="10" height="10" fill="#00d4aa"/>
8380
+ <rect x="90" y="20" width="10" height="10" fill="#00d4aa"/>
8381
+ <rect x="100" y="20" width="10" height="10" fill="#00d4aa"/>
8382
+ <rect x="110" y="20" width="10" height="10" fill="#00d4aa"/>
8383
+ <rect x="30" y="30" width="10" height="10" fill="#00d4aa"/>
8384
+ <rect x="40" y="30" width="10" height="10" fill="#00d4aa"/>
8385
+ <rect x="50" y="30" width="10" height="10" fill="#00d4aa"/>
8386
+ <rect x="60" y="30" width="10" height="10" fill="#00d4aa"/>
8387
+ <rect x="70" y="30" width="10" height="10" fill="#00d4aa"/>
8388
+ <rect x="80" y="30" width="10" height="10" fill="#00d4aa"/>
8389
+ <rect x="90" y="30" width="10" height="10" fill="#00d4aa"/>
8390
+ <rect x="100" y="30" width="10" height="10" fill="#00d4aa"/>
8391
+ <rect x="110" y="30" width="10" height="10" fill="#00d4aa"/>
8392
+ <rect x="120" y="30" width="10" height="10" fill="#00d4aa"/>
8393
+ <rect x="30" y="40" width="10" height="10" fill="#00d4aa"/>
8394
+ <rect x="40" y="40" width="10" height="10" fill="#00d4aa"/>
8395
+ <rect x="60" y="40" width="10" height="10" fill="#0d1117"/>
8396
+ <rect x="70" y="40" width="10" height="10" fill="#0d1117"/>
8397
+ <rect x="100" y="40" width="10" height="10" fill="#0d1117"/>
8398
+ <rect x="110" y="40" width="10" height="10" fill="#0d1117"/>
8399
+ <rect x="130" y="40" width="10" height="10" fill="#00d4aa"/>
8400
+ <rect x="140" y="40" width="10" height="10" fill="#00d4aa"/>
8401
+ <rect x="30" y="50" width="10" height="10" fill="#00d4aa"/>
8402
+ <rect x="40" y="50" width="10" height="10" fill="#00d4aa"/>
8403
+ <rect x="60" y="50" width="10" height="10" fill="#0d1117"/>
8404
+ <rect x="70" y="50" width="10" height="10" fill="#40e0ff"/>
8405
+ <rect x="100" y="50" width="10" height="10" fill="#0d1117"/>
8406
+ <rect x="110" y="50" width="10" height="10" fill="#40e0ff"/>
8407
+ <rect x="130" y="50" width="10" height="10" fill="#00d4aa"/>
8408
+ <rect x="140" y="50" width="10" height="10" fill="#00d4aa"/>
8409
+ <rect x="30" y="60" width="10" height="10" fill="#00d4aa"/>
8410
+ <rect x="40" y="60" width="10" height="10" fill="#00d4aa"/>
8411
+ <rect x="50" y="60" width="10" height="10" fill="#00d4aa"/>
8412
+ <rect x="60" y="60" width="10" height="10" fill="#00d4aa"/>
8413
+ <rect x="70" y="60" width="10" height="10" fill="#00d4aa"/>
8414
+ <rect x="80" y="60" width="10" height="10" fill="#00d4aa"/>
8415
+ <rect x="90" y="60" width="10" height="10" fill="#00d4aa"/>
8416
+ <rect x="100" y="60" width="10" height="10" fill="#00d4aa"/>
8417
+ <rect x="110" y="60" width="10" height="10" fill="#00d4aa"/>
8418
+ <rect x="120" y="60" width="10" height="10" fill="#00d4aa"/>
8419
+ <rect x="30" y="70" width="10" height="10" fill="#00d4aa"/>
8420
+ <rect x="40" y="70" width="10" height="10" fill="#00d4aa"/>
8421
+ <rect x="50" y="70" width="10" height="10" fill="#00d4aa"/>
8422
+ <rect x="60" y="70" width="10" height="10" fill="#00d4aa"/>
8423
+ <rect x="70" y="70" width="10" height="10" fill="#00d4aa"/>
8424
+ <rect x="80" y="70" width="10" height="10" fill="#00d4aa"/>
8425
+ <rect x="90" y="70" width="10" height="10" fill="#00d4aa"/>
8426
+ <rect x="100" y="70" width="10" height="10" fill="#00d4aa"/>
8427
+ <rect x="110" y="70" width="10" height="10" fill="#00d4aa"/>
8428
+ <rect x="120" y="70" width="10" height="10" fill="#00d4aa"/>
8429
+ <rect x="20" y="80" width="10" height="10" fill="#00d4aa"/>
8430
+ <rect x="30" y="80" width="10" height="10" fill="#00d4aa"/>
8431
+ <rect x="40" y="80" width="10" height="10" fill="#00d4aa"/>
8432
+ <rect x="50" y="80" width="10" height="10" fill="#00d4aa"/>
8433
+ <rect x="60" y="80" width="10" height="10" fill="#00d4aa"/>
8434
+ <rect x="70" y="80" width="10" height="10" fill="#00d4aa"/>
8435
+ <rect x="80" y="80" width="10" height="10" fill="#00d4aa"/>
8436
+ <rect x="90" y="80" width="10" height="10" fill="#00d4aa"/>
8437
+ <rect x="100" y="80" width="10" height="10" fill="#00d4aa"/>
8438
+ <rect x="110" y="80" width="10" height="10" fill="#00d4aa"/>
8439
+ <rect x="120" y="80" width="10" height="10" fill="#00d4aa"/>
8440
+ <rect x="130" y="80" width="10" height="10" fill="#00d4aa"/>
8441
+ <rect x="20" y="90" width="10" height="10" fill="#00d4aa"/>
8442
+ <rect x="30" y="90" width="10" height="10" fill="#00d4aa"/>
8443
+ <rect x="60" y="90" width="10" height="10" fill="#0d1117"/>
8444
+ <rect x="70" y="90" width="10" height="10" fill="#0d1117"/>
8445
+ <rect x="80" y="90" width="10" height="10" fill="#0d1117"/>
8446
+ <rect x="90" y="90" width="10" height="10" fill="#0d1117"/>
8447
+ <rect x="100" y="90" width="10" height="10" fill="#0d1117"/>
8448
+ <rect x="110" y="90" width="10" height="10" fill="#0d1117"/>
8449
+ <rect x="130" y="90" width="10" height="10" fill="#00d4aa"/>
8450
+ <rect x="140" y="90" width="10" height="10" fill="#00d4aa"/>
8451
+ <rect x="20" y="100" width="10" height="10" fill="#00d4aa"/>
8452
+ <rect x="30" y="100" width="10" height="10" fill="#00d4aa"/>
8453
+ <rect x="60" y="100" width="10" height="10" fill="#0d1117"/>
8454
+ <rect x="70" y="100" width="10" height="10" fill="#00d4aa"/>
8455
+ <rect x="80" y="100" width="10" height="10" fill="#40e0ff"/>
8456
+ <rect x="90" y="100" width="10" height="10" fill="#0d1117"/>
8457
+ <rect x="100" y="100" width="10" height="10" fill="#00d4aa"/>
8458
+ <rect x="130" y="100" width="10" height="10" fill="#00d4aa"/>
8459
+ <rect x="140" y="100" width="10" height="10" fill="#00d4aa"/>
8460
+ <rect x="20" y="110" width="10" height="10" fill="#00d4aa"/>
8461
+ <rect x="30" y="110" width="10" height="10" fill="#00d4aa"/>
8462
+ <rect x="60" y="110" width="10" height="10" fill="#0d1117"/>
8463
+ <rect x="70" y="110" width="10" height="10" fill="#0d1117"/>
8464
+ <rect x="80" y="110" width="10" height="10" fill="#00d4aa"/>
8465
+ <rect x="90" y="110" width="10" height="10" fill="#0d1117"/>
8466
+ <rect x="100" y="110" width="10" height="10" fill="#0d1117"/>
8467
+ <rect x="130" y="110" width="10" height="10" fill="#00d4aa"/>
8468
+ <rect x="140" y="110" width="10" height="10" fill="#00d4aa"/>
8469
+ <rect x="20" y="120" width="10" height="10" fill="#00d4aa"/>
8470
+ <rect x="30" y="120" width="10" height="10" fill="#00d4aa"/>
8471
+ <rect x="40" y="120" width="10" height="10" fill="#00d4aa"/>
8472
+ <rect x="50" y="120" width="10" height="10" fill="#00d4aa"/>
8473
+ <rect x="60" y="120" width="10" height="10" fill="#00d4aa"/>
8474
+ <rect x="70" y="120" width="10" height="10" fill="#00d4aa"/>
8475
+ <rect x="80" y="120" width="10" height="10" fill="#00d4aa"/>
8476
+ <rect x="90" y="120" width="10" height="10" fill="#00d4aa"/>
8477
+ <rect x="100" y="120" width="10" height="10" fill="#00d4aa"/>
8478
+ <rect x="110" y="120" width="10" height="10" fill="#00d4aa"/>
8479
+ <rect x="120" y="120" width="10" height="10" fill="#00d4aa"/>
8480
+ <rect x="130" y="120" width="10" height="10" fill="#00d4aa"/>
8481
+ <rect x="40" y="130" width="10" height="10" fill="#00d4aa"/>
8482
+ <rect x="50" y="130" width="10" height="10" fill="#00d4aa"/>
8483
+ <rect x="60" y="130" width="10" height="10" fill="#00d4aa"/>
8484
+ <rect x="70" y="130" width="10" height="10" fill="#00d4aa"/>
8485
+ <rect x="90" y="130" width="10" height="10" fill="#00d4aa"/>
8486
+ <rect x="100" y="130" width="10" height="10" fill="#00d4aa"/>
8487
+ <rect x="110" y="130" width="10" height="10" fill="#00d4aa"/>
8488
+ <rect x="120" y="130" width="10" height="10" fill="#00d4aa"/>
8489
+ <rect x="40" y="140" width="10" height="10" fill="#00d4aa"/>
8490
+ <rect x="50" y="140" width="10" height="10" fill="#00d4aa"/>
8491
+ <rect x="60" y="140" width="10" height="10" fill="#00d4aa"/>
8492
+ <rect x="70" y="140" width="10" height="10" fill="#00d4aa"/>
8493
+ <rect x="90" y="140" width="10" height="10" fill="#00d4aa"/>
8494
+ <rect x="100" y="140" width="10" height="10" fill="#00d4aa"/>
8495
+ <rect x="110" y="140" width="10" height="10" fill="#00d4aa"/>
8496
+ <rect x="120" y="140" width="10" height="10" fill="#00d4aa"/>
8497
+ </svg>
8498
+ </div>
8499
+ </div>
8500
+ <div class="home-hero-actions">
8501
+ <button class="home-primary-action" onclick="switchTab('embed')" title="Generate embeddings for text">
8502
+ <span class="home-primary-action-icon" aria-hidden="true">
8503
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/></svg>
8504
+ </span>
8505
+ <span class="home-primary-action-body">
8506
+ <strong>New embedding</strong>
8507
+ <span>Generate vectors and inspect dimensions, usage, and heatmaps.</span>
8508
+ </span>
7809
8509
  </button>
7810
- <button class="home-quick-action" onclick="switchTab('compare')" title="Compare model similarities">
7811
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
7812
- <path d="M21 12c0 1.2-4.03 6-9 6s-9-4.8-9-6c0-1.2 4.03-6 9-6s9 4.8 9 6"/>
7813
- <circle cx="12" cy="12" r="3"/>
7814
- </svg>
7815
- <span>Compare Models</span>
8510
+ <button class="home-primary-action" onclick="switchTab('compare')" title="Compare model similarities">
8511
+ <span class="home-primary-action-icon" aria-hidden="true">
8512
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M8 3 4 7l4 4M4 7h16M16 21l4-4-4-4M20 17H4"/></svg>
8513
+ </span>
8514
+ <span class="home-primary-action-body">
8515
+ <strong>Compare text</strong>
8516
+ <span>Check semantic similarity between two inputs side by side.</span>
8517
+ </span>
7816
8518
  </button>
7817
- <button class="home-quick-action" onclick="switchTab('search')" title="Search through vectors">
7818
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
7819
- <circle cx="11" cy="11" r="8"/>
7820
- <path d="m21 21-4.35-4.35"/>
7821
- </svg>
7822
- <span>Search Vectors</span>
8519
+ <button class="home-primary-action" onclick="switchTab('search')" title="Rerank documents">
8520
+ <span class="home-primary-action-icon" aria-hidden="true">
8521
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
8522
+ </span>
8523
+ <span class="home-primary-action-body">
8524
+ <strong>Rerank results</strong>
8525
+ <span>Score and reorder candidate documents against a query.</span>
8526
+ </span>
7823
8527
  </button>
7824
- <button class="home-quick-action" onclick="switchTab('workflows')" title="View installed workflows">
7825
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
7826
- <circle cx="5" cy="12" r="3"/>
7827
- <circle cx="19" cy="6" r="3"/>
7828
- <circle cx="19" cy="18" r="3"/>
7829
- <line x1="7.7" y1="10.7" x2="16.3" y2="7.3"/>
7830
- <line x1="7.7" y1="13.3" x2="16.3" y2="16.7"/>
7831
- </svg>
7832
- <span>My Workflows</span>
8528
+ <button class="home-primary-action" onclick="switchTab('workflows')" title="Open workflows">
8529
+ <span class="home-primary-action-icon" aria-hidden="true">
8530
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><circle cx="5" cy="12" r="3"/><circle cx="19" cy="6" r="3"/><circle cx="19" cy="18" r="3"/><line x1="7.7" y1="10.7" x2="16.3" y2="7.3"/><line x1="7.7" y1="13.3" x2="16.3" y2="16.7"/></svg>
8531
+ </span>
8532
+ <span class="home-primary-action-body">
8533
+ <strong>Run workflows</strong>
8534
+ <span>Open the canvas, inspect installed flows, and execute them quickly.</span>
8535
+ </span>
7833
8536
  </button>
7834
- <button class="home-quick-action" onclick="publishWorkflow()" title="Publish a new workflow">
7835
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
7836
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
7837
- <polyline points="17,8 12,3 7,8"/>
7838
- <line x1="12" y1="3" x2="12" y2="15"/>
7839
- </svg>
7840
- <span>Publish Workflow</span>
8537
+ <button class="home-primary-action" onclick="switchTab('benchmark')" title="Benchmark models">
8538
+ <span class="home-primary-action-icon" aria-hidden="true">
8539
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M12 20V10M18 20V4M6 20v-4"/></svg>
8540
+ </span>
8541
+ <span class="home-primary-action-body">
8542
+ <strong>Benchmark models</strong>
8543
+ <span>Compare latency, ranking quality, and cost from the same workspace.</span>
8544
+ </span>
7841
8545
  </button>
8546
+ </div>
7842
8547
  </div>
8548
+ </section>
8549
+
8550
+ <div class="home-overview-grid">
8551
+ <section class="home-section home-overview-card">
8552
+ <div class="home-section-header">
8553
+ <h3>Workspace status</h3>
8554
+ </div>
8555
+ <div class="home-status-grid" id="homeStatusGrid">
8556
+ <div class="home-empty-state">Loading workspace status...</div>
8557
+ </div>
8558
+ </section>
8559
+
8560
+ <section class="home-section home-overview-card">
8561
+ <div class="home-section-header">
8562
+ <h3>Continue where you left off</h3>
8563
+ </div>
8564
+ <div id="homeRecentActivity">
8565
+ <div class="home-empty-state">Open a tool and your recent session activity will appear here.</div>
8566
+ </div>
8567
+ </section>
7843
8568
  </div>
7844
8569
 
7845
- <!-- Newsletter CTA -->
7846
- <div class="home-section">
7847
- <div class="home-newsletter-cta">
7848
- <span class="home-newsletter-cta-badge">Newsletter</span>
7849
- <h3 class="home-newsletter-cta-title">Ship smarter. Get the field notes.</h3>
7850
- <p class="home-newsletter-cta-desc">Practical updates on the VAI CLI, embedding workflows, and real-world AI engineering—written by a forward-deployed engineer. No fluff, no spam.</p>
7851
- <ul class="home-newsletter-cta-benefits" aria-hidden="true">
7852
- <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17l-5-5"/></svg> New features and release notes</li>
7853
- <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17l-5-5"/></svg> Guides and best practices</li>
7854
- <li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17l-5-5"/></svg> Field notes from production</li>
7855
- </ul>
7856
- <a href="https://vaicli.com/newsletter/subscribe" target="_blank" rel="noopener" class="home-newsletter-cta-button">Subscribe free<svg class="arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
7857
- <p class="home-newsletter-cta-note">One email when it matters. Unsubscribe anytime.</p>
7858
- </div>
8570
+ <div class="home-main-grid">
8571
+ <section class="home-section home-overview-card">
8572
+ <div class="home-section-header">
8573
+ <h3>Latest update</h3>
8574
+ <a href="https://github.com/mrlynn/voyageai-cli/releases" target="_blank" rel="noopener">All releases →</a>
8575
+ </div>
8576
+ <div id="homeUpdateContent">
8577
+ <div class="home-empty-state">Loading the latest release notes...</div>
8578
+ </div>
8579
+ </section>
8580
+
8581
+ <section class="home-section home-overview-card">
8582
+ <div class="home-section-header">
8583
+ <h3>Workflow spotlight</h3>
8584
+ <button class="home-link-button" onclick="switchTab('workflows')">Open workflows</button>
8585
+ </div>
8586
+ <div class="home-workflow-stack" id="homeWorkflowSpotlight">
8587
+ <div class="home-empty-state">Loading featured workflows...</div>
8588
+ </div>
8589
+ </section>
7859
8590
  </div>
7860
8591
 
7861
8592
  <!-- Footer -->
@@ -9174,7 +9905,7 @@ Reranking models rescore initial search results to improve relevance ordering.</
9174
9905
  <div class="about-text">
9175
9906
  <strong>⚡ Embed</strong> — Generate vector embeddings for any text<br>
9176
9907
  <strong>⚖️ Compare</strong> — Measure similarity with cosine, dot product &amp; euclidean distance<br>
9177
- <strong>🔍 Search</strong> — Semantic search with optional reranking<br>
9908
+ <strong>🔍 Rerank</strong> — Semantic search with optional reranking<br>
9178
9909
  <strong>🔮 Multimodal</strong> — Compare images and text in the same vector space with voyage-multimodal-3.5<br>
9179
9910
  <strong>🛠️ Generate</strong> — Generate code snippets and scaffold full projects with templates<br>
9180
9911
  <strong>💬 Chat</strong> — RAG-powered chat with your documents, configurable system prompts<br>
@@ -9455,6 +10186,23 @@ Reranking models rescore initial search results to improve relevance ordering.</
9455
10186
  Index documents with the large model for best quality, then query with the lite model at a fraction of the cost.
9456
10187
  No re-indexing required.
9457
10188
  </div>
10189
+ <div class="models-hero-spotlight">
10190
+ <div>
10191
+ <div class="models-hero-spotlight-badge">Major Announcement</div>
10192
+ <div class="models-hero-spotlight-title">voyage-4-nano is open-weight and local-capable</div>
10193
+ <div class="models-hero-spotlight-copy">
10194
+ The Voyage 4 family now includes <code>voyage-4-nano</code>, an open-weight model for local development and prototyping. It lives in the same shared embedding space as voyage-4-large, voyage-4, and voyage-4-lite, so you can prototype locally and move into asymmetric retrieval workflows without rebuilding your index.
10195
+ </div>
10196
+ <div class="models-hero-spotlight-note">
10197
+ Run locally and compare local vs cloud vectors, and use it as a zero-query-cost option in hybrid retrieval workflows.
10198
+ </div>
10199
+ </div>
10200
+ <div class="models-hero-spotlight-actions">
10201
+ <button class="models-hero-spotlight-link primary" onclick="switchTab('nano')">Try Local Nano</button>
10202
+ <button class="models-hero-spotlight-link" onclick="scrollToModelCard('voyage-4-nano')">View Model Card</button>
10203
+ <a class="models-hero-spotlight-link" href="https://blog.voyageai.com/2026/01/15/voyage-4/" target="_blank" rel="noopener">Read Announcement</a>
10204
+ </div>
10205
+ </div>
9458
10206
  <div class="models-hero-models" id="modelsHeroModels"></div>
9459
10207
  </div>
9460
10208
  </div>
@@ -9820,7 +10568,7 @@ Retrieval augmented generation combines search with LLMs</textarea>
9820
10568
  </div>
9821
10569
 
9822
10570
  <!-- ========== SETTINGS TAB ========== -->
9823
- <div class="tab-panel" id="tab-settings">
10571
+ <div class="tab-panel" id="tab-settings" role="tabpanel" aria-labelledby="tab-btn-settings" tabindex="0">
9824
10572
  <div class="settings-layout">
9825
10573
  <!-- Settings left nav -->
9826
10574
  <nav class="settings-nav">
@@ -9920,16 +10668,20 @@ Retrieval augmented generation combines search with LLMs</textarea>
9920
10668
  </div>
9921
10669
  <div class="settings-control">
9922
10670
  <select class="settings-select" id="settingsDefaultTab">
9923
- <option value="home" selected>Home</option>
10671
+ <option value="home" selected>Overview</option>
9924
10672
  <option value="embed">Embed</option>
9925
10673
  <option value="compare">Compare</option>
9926
- <option value="search">Search</option>
10674
+ <option value="search">Rerank</option>
9927
10675
  <option value="multimodal">Multimodal</option>
9928
10676
  <option value="generate">Generate</option>
9929
10677
  <option value="chat">Chat</option>
9930
10678
  <option value="workflows">Workflows</option>
9931
10679
  <option value="benchmark">Benchmark</option>
9932
10680
  <option value="explore">Explore</option>
10681
+ <option value="nano">Local Inference</option>
10682
+ <option value="models">Models</option>
10683
+ <option value="about">About</option>
10684
+ <option value="settings">Settings</option>
9933
10685
  </select>
9934
10686
  </div>
9935
10687
  </div>
@@ -10127,18 +10879,6 @@ Retrieval augmented generation combines search with LLMs</textarea>
10127
10879
  </div>
10128
10880
  </div>
10129
10881
  </div>
10130
- <div class="settings-section">
10131
- <div class="settings-section-title">Help</div>
10132
- <div class="settings-row">
10133
- <div class="settings-label">
10134
- <span class="settings-label-text">Welcome Tour</span>
10135
- <span class="settings-label-hint">Replay the onboarding walkthrough</span>
10136
- </div>
10137
- <div class="settings-control">
10138
- <button class="settings-reset-btn" id="settingsShowTour" style="background:var(--accent);color:var(--bg);">Show Welcome Tour</button>
10139
- </div>
10140
- </div>
10141
- </div>
10142
10882
  <!-- Version Info (visible in Electron only) -->
10143
10883
  <div class="settings-section" id="settingsVersionSection" style="display:none;">
10144
10884
  <div class="settings-section-title">Version</div>
@@ -10215,38 +10955,6 @@ Retrieval augmented generation combines search with LLMs</textarea>
10215
10955
  </div><!-- .content-area -->
10216
10956
  </div><!-- .app-shell -->
10217
10957
 
10218
- <!-- Onboarding Walkthrough Overlay -->
10219
- <div class="onboarding-overlay" id="onboardingOverlay">
10220
- <div class="onboarding-backdrop" id="onboardingBackdrop"></div>
10221
- <div class="onboarding-spotlight" id="onboardingSpotlight"></div>
10222
- <!-- Welcome card (step 0) -->
10223
- <div class="onboarding-welcome-center" id="onboardingWelcomeWrap">
10224
- <div class="onboarding-welcome-card" id="onboardingWelcomeCard">
10225
- <img class="onboarding-welcome-logo" id="onboardingLogo" src="/icons/dark/64.png" alt="Vai">
10226
- <div class="onboarding-welcome-title">Welcome to Vai</div>
10227
- <div class="onboarding-welcome-sub">Explore embeddings, compare text similarity, and search with vector models — all from one playground.</div>
10228
- <div class="onboarding-footer" style="justify-content:center;">
10229
- <button class="onboarding-skip" id="onboardingWelcomeSkip">Skip tour</button>
10230
- <button class="onboarding-next" id="onboardingWelcomeNext">Take the tour →</button>
10231
- </div>
10232
- </div>
10233
- </div>
10234
- <!-- Tooltip for steps 1-4 -->
10235
- <div class="onboarding-tooltip" id="onboardingTooltip">
10236
- <div class="onboarding-tooltip-arrow top" id="onboardingArrow"></div>
10237
- <div class="onboarding-step-icon" id="onboardingIcon"></div>
10238
- <div class="onboarding-step-title" id="onboardingTitle"></div>
10239
- <div class="onboarding-step-body" id="onboardingBody"></div>
10240
- <div class="onboarding-footer">
10241
- <div class="onboarding-dots" id="onboardingDots"></div>
10242
- <div class="onboarding-actions">
10243
- <button class="onboarding-skip" id="onboardingSkip">Skip</button>
10244
- <button class="onboarding-next" id="onboardingNext">Next</button>
10245
- </div>
10246
- </div>
10247
- </div>
10248
- </div>
10249
-
10250
10958
  <script>
10251
10959
  // Apply saved theme immediately to prevent flash
10252
10960
  (function() {
@@ -10607,9 +11315,106 @@ async function init() {
10607
11315
  }
10608
11316
 
10609
11317
  // ── Tabs ──
11318
+ const NAV_SECTION_CONFIG = {
11319
+ build: {
11320
+ label: 'Build',
11321
+ title: 'Create and run core workflows',
11322
+ defaultTab: 'embed'
11323
+ },
11324
+ evaluate: {
11325
+ label: 'Evaluate',
11326
+ title: 'Inspect, compare, and tune results',
11327
+ defaultTab: 'compare'
11328
+ },
11329
+ reference: {
11330
+ label: 'Reference',
11331
+ title: 'Browse models and product context',
11332
+ defaultTab: 'models'
11333
+ },
11334
+ settings: {
11335
+ label: 'Settings',
11336
+ title: 'Configure the app and environment',
11337
+ defaultTab: 'settings'
11338
+ }
11339
+ };
11340
+
11341
+ const NAV_TAB_TO_SECTION = {
11342
+ embed: 'build',
11343
+ search: 'build',
11344
+ multimodal: 'build',
11345
+ generate: 'build',
11346
+ chat: 'build',
11347
+ workflows: 'build',
11348
+ compare: 'evaluate',
11349
+ benchmark: 'evaluate',
11350
+ optimize: 'evaluate',
11351
+ explore: 'evaluate',
11352
+ nano: 'evaluate',
11353
+ models: 'reference',
11354
+ about: 'reference',
11355
+ settings: 'settings'
11356
+ };
11357
+
11358
+ let activeNavSection = 'build';
11359
+ const navLastTabBySection = {
11360
+ build: 'embed',
11361
+ evaluate: 'compare',
11362
+ reference: 'models',
11363
+ settings: 'settings'
11364
+ };
11365
+
11366
+ function setActiveNavSection(section) {
11367
+ const meta = NAV_SECTION_CONFIG[section];
11368
+ if (!meta) return;
11369
+ activeNavSection = section;
11370
+
11371
+ document.querySelectorAll('.sidebar-rail-btn').forEach(btn => {
11372
+ const isActive = btn.dataset.section === section;
11373
+ btn.classList.toggle('active', isActive);
11374
+ btn.setAttribute('aria-pressed', isActive ? 'true' : 'false');
11375
+ });
11376
+
11377
+ document.querySelectorAll('.sidebar-nav-group').forEach(group => {
11378
+ const isActive = group.dataset.section === section;
11379
+ group.classList.toggle('active', isActive);
11380
+ group.hidden = !isActive;
11381
+ });
11382
+
11383
+ const eyebrow = document.getElementById('sidebarPanelEyebrow');
11384
+ const title = document.getElementById('sidebarPanelTitle');
11385
+ if (eyebrow) eyebrow.textContent = meta.label;
11386
+ if (title) title.textContent = meta.title;
11387
+ }
11388
+
11389
+ function syncNavSectionForTab(tab) {
11390
+ const section = NAV_TAB_TO_SECTION[tab];
11391
+ if (section) {
11392
+ navLastTabBySection[section] = tab;
11393
+ setActiveNavSection(section);
11394
+ return;
11395
+ }
11396
+
11397
+ setActiveNavSection(activeNavSection || 'build');
11398
+ }
11399
+
11400
+ function navigateToNavSection(section) {
11401
+ const meta = NAV_SECTION_CONFIG[section];
11402
+ if (!meta) return;
11403
+ setActiveNavSection(section);
11404
+ switchTab(navLastTabBySection[section] || meta.defaultTab);
11405
+ }
11406
+
11407
+ function getActiveTabId() {
11408
+ return document.querySelector('.tab-btn.active')?.dataset?.tab || 'home';
11409
+ }
11410
+
11411
+ function getActiveTabLabel() {
11412
+ if (getActiveTabId() === 'home') return 'Overview';
11413
+ return document.querySelector('.tab-btn.active span:last-child')?.textContent?.trim() || 'Overview';
11414
+ }
11415
+
10610
11416
  function setupTabs() {
10611
11417
  const tabBtns = document.querySelectorAll('.tab-btn');
10612
- const tabList = Array.from(tabBtns);
10613
11418
 
10614
11419
  tabBtns.forEach(btn => {
10615
11420
  btn.addEventListener('click', () => {
@@ -10618,40 +11423,79 @@ function setupTabs() {
10618
11423
 
10619
11424
  // Keyboard navigation for accessibility
10620
11425
  btn.addEventListener('keydown', (e) => {
10621
- const currentIndex = tabList.indexOf(btn);
11426
+ const visibleTabList = Array.from(btn.closest('.sidebar-nav-group')?.querySelectorAll('.tab-btn') || []);
11427
+ const currentIndex = visibleTabList.indexOf(btn);
10622
11428
  let nextIndex = -1;
10623
11429
 
10624
11430
  if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
10625
11431
  e.preventDefault();
10626
- nextIndex = (currentIndex + 1) % tabList.length;
11432
+ nextIndex = (currentIndex + 1) % visibleTabList.length;
10627
11433
  } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
10628
11434
  e.preventDefault();
10629
- nextIndex = (currentIndex - 1 + tabList.length) % tabList.length;
11435
+ nextIndex = (currentIndex - 1 + visibleTabList.length) % visibleTabList.length;
10630
11436
  } else if (e.key === 'Home') {
10631
11437
  e.preventDefault();
10632
11438
  nextIndex = 0;
10633
11439
  } else if (e.key === 'End') {
10634
11440
  e.preventDefault();
10635
- nextIndex = tabList.length - 1;
11441
+ nextIndex = visibleTabList.length - 1;
10636
11442
  }
10637
11443
 
10638
11444
  if (nextIndex >= 0) {
10639
- tabList[nextIndex].focus();
10640
- switchTab(tabList[nextIndex].dataset.tab);
11445
+ visibleTabList[nextIndex].focus();
11446
+ switchTab(visibleTabList[nextIndex].dataset.tab);
10641
11447
  }
10642
11448
  });
10643
11449
  });
10644
11450
 
10645
- // Settings cog in header
10646
- const settingsCog = document.querySelector('.sidebar-settings-btn');
10647
- if (settingsCog) {
10648
- settingsCog.addEventListener('click', () => {
10649
- switchTab(settingsCog.dataset.tab);
11451
+ const homeBtn = document.getElementById('sidebarHomeBtn');
11452
+ if (homeBtn) {
11453
+ homeBtn.addEventListener('click', () => {
11454
+ switchTab('home');
10650
11455
  });
10651
11456
  }
11457
+
11458
+ const railBtns = Array.from(document.querySelectorAll('.sidebar-rail-btn'));
11459
+ railBtns.forEach(btn => {
11460
+ btn.addEventListener('click', () => {
11461
+ navigateToNavSection(btn.dataset.section);
11462
+ });
11463
+
11464
+ btn.addEventListener('keydown', (e) => {
11465
+ const currentIndex = railBtns.indexOf(btn);
11466
+ let nextIndex = -1;
11467
+
11468
+ if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
11469
+ e.preventDefault();
11470
+ nextIndex = (currentIndex + 1) % railBtns.length;
11471
+ } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
11472
+ e.preventDefault();
11473
+ nextIndex = (currentIndex - 1 + railBtns.length) % railBtns.length;
11474
+ } else if (e.key === 'Home') {
11475
+ e.preventDefault();
11476
+ nextIndex = 0;
11477
+ } else if (e.key === 'End') {
11478
+ e.preventDefault();
11479
+ nextIndex = railBtns.length - 1;
11480
+ }
11481
+
11482
+ if (nextIndex >= 0) {
11483
+ railBtns[nextIndex].focus();
11484
+ }
11485
+ });
11486
+ });
11487
+
11488
+ setActiveNavSection(activeNavSection);
10652
11489
  }
10653
11490
 
10654
11491
  function switchTab(tab) {
11492
+ if (!document.getElementById('tab-' + tab)) {
11493
+ tab = 'home';
11494
+ }
11495
+
11496
+ if (tab !== 'home') {
11497
+ localStorage.setItem('vai-last-active-tab', tab);
11498
+ }
10655
11499
  document.querySelectorAll('.tab-btn').forEach(b => {
10656
11500
  const isActive = b.dataset.tab === tab;
10657
11501
  b.classList.toggle('active', isActive);
@@ -10665,9 +11509,7 @@ function switchTab(tab) {
10665
11509
  // Hide inactive panels from screen readers
10666
11510
  p.setAttribute('aria-hidden', isActive ? 'false' : 'true');
10667
11511
  });
10668
- // Sync settings cog highlight
10669
- const settingsBtn = document.querySelector('.sidebar-settings-btn');
10670
- if (settingsBtn) settingsBtn.classList.toggle('active', tab === 'settings');
11512
+ syncNavSectionForTab(tab);
10671
11513
  // Track tab views
10672
11514
  sendTelemetry('tab_view', { tab });
10673
11515
  sendTelemetry('playground_tab', { tab });
@@ -10675,6 +11517,7 @@ function switchTab(tab) {
10675
11517
  // Initialize Home page if switching to it
10676
11518
  if (tab === 'home') {
10677
11519
  homeInit();
11520
+ renderHomeRecentActivity();
10678
11521
  }
10679
11522
  if (tab === 'models') {
10680
11523
  modelsInit();
@@ -11199,50 +12042,36 @@ let homeData = {
11199
12042
  featuredWorkflows: null,
11200
12043
  communityWorkflows: null,
11201
12044
  currentAnnouncementIndex: 0,
11202
- sortMode: 'trending'
12045
+ sortMode: 'trending',
12046
+ hasApiKey: false
11203
12047
  };
11204
12048
 
11205
12049
  async function homeInit() {
11206
- // Only initialize once per session
11207
- if (homeData.announcements !== null) return;
11208
-
11209
12050
  try {
11210
- // Load version info
11211
12051
  await updateHomeVersionInfo();
12052
+ await checkApiKeyStatus();
12053
+ renderHomeStatusGrid();
12054
+ renderHomeRecentActivity();
12055
+ renderHomeUpdate();
12056
+ renderHomeWorkflowSpotlight();
11212
12057
 
11213
- // Check API key status and show warning if needed
11214
- checkApiKeyStatus();
11215
-
11216
- // Load announcements and releases first (fast, local data)
11217
- await Promise.all([
11218
- loadAnnouncements(),
11219
- loadReleases(),
11220
- ]);
11221
-
11222
- // Render available sections immediately
11223
- renderAnnouncements();
11224
- renderReleases();
11225
-
11226
- // Populate section dividers with flowing particle fields
11227
- [['divider1', 440], ['divider2', 441], ['divider3', 442]].forEach(([id, seed]) => {
11228
- const el = document.getElementById(id);
11229
- if (el && !el.innerHTML) {
11230
- el.innerHTML = generateParticleFieldSVG(el.offsetWidth || 900, 40, seed, {variant: 'flowing', opacity: 0.4});
11231
- }
11232
- });
11233
-
11234
- // Populate footer lattice background
11235
12058
  const footerLattice = document.getElementById('footerLattice');
11236
12059
  if (footerLattice && !footerLattice.innerHTML) {
11237
12060
  footerLattice.innerHTML = generateLatticeSVG(footerLattice.parentElement.offsetWidth || 900, 80, 780, {variant: 'dense', opacity: 0.05});
11238
12061
  }
11239
12062
 
11240
- // Load marketplace data in background (slower, network-dependent)
11241
- loadMarketplaceData().then(() => {
11242
- renderFeaturedWorkflows();
11243
- renderCommunityWorkflows();
11244
- }).catch(() => {});
11245
-
12063
+ if (homeData.releases === null) {
12064
+ await loadReleases();
12065
+ renderHomeUpdate();
12066
+ }
12067
+
12068
+ if (homeData.featuredWorkflows === null) {
12069
+ loadMarketplaceData().then(() => {
12070
+ renderHomeWorkflowSpotlight();
12071
+ }).catch(() => {
12072
+ renderHomeWorkflowSpotlight();
12073
+ });
12074
+ }
11246
12075
  } catch (err) {
11247
12076
  console.error('Failed to initialize Home page:', err);
11248
12077
  }
@@ -11285,20 +12114,217 @@ async function updateHomeVersionInfo() {
11285
12114
  }
11286
12115
 
11287
12116
  async function checkApiKeyStatus() {
12117
+ const warningEl = document.getElementById('homeApiWarning');
12118
+ if (warningEl) warningEl.style.display = 'none';
12119
+
11288
12120
  try {
11289
12121
  const res = await fetch('/api/config');
11290
12122
  const data = await res.json();
11291
- const warningEl = document.getElementById('homeApiWarning');
11292
-
11293
- if (!data.hasKey) {
11294
- warningEl.style.display = 'block';
11295
- } else {
11296
- warningEl.style.display = 'none';
11297
- }
12123
+ homeData.hasApiKey = Boolean(data.hasKey);
11298
12124
  } catch {
11299
- // If config check fails, assume no API key
11300
- document.getElementById('homeApiWarning').style.display = 'block';
12125
+ homeData.hasApiKey = false;
12126
+ }
12127
+
12128
+ renderHomeStatusGrid();
12129
+ return homeData.hasApiKey;
12130
+ }
12131
+
12132
+ function getHomeLastActiveTab() {
12133
+ const lastTab = localStorage.getItem('vai-last-active-tab');
12134
+ return lastTab && lastTab !== 'home' ? lastTab : 'embed';
12135
+ }
12136
+
12137
+ function formatHomeTabLabel(tab) {
12138
+ const labels = {
12139
+ embed: 'Embed',
12140
+ compare: 'Compare',
12141
+ search: 'Rerank',
12142
+ workflows: 'Workflows',
12143
+ benchmark: 'Benchmark',
12144
+ multimodal: 'Multimodal',
12145
+ generate: 'Generate',
12146
+ chat: 'Chat',
12147
+ explore: 'Explore',
12148
+ optimize: 'Optimize',
12149
+ nano: 'Local Inference',
12150
+ models: 'Models',
12151
+ settings: 'Settings',
12152
+ about: 'About'
12153
+ };
12154
+ return labels[tab] || (tab ? tab.charAt(0).toUpperCase() + tab.slice(1) : 'Embed');
12155
+ }
12156
+
12157
+ function formatHomeRelativeTime(timestamp) {
12158
+ if (!timestamp) return 'Just now';
12159
+ const minutes = Math.max(1, Math.round((Date.now() - timestamp) / 60000));
12160
+ if (minutes < 60) return `${minutes} min ago`;
12161
+ const hours = Math.round(minutes / 60);
12162
+ if (hours < 24) return `${hours} hr ago`;
12163
+ const days = Math.round(hours / 24);
12164
+ return `${days} day${days === 1 ? '' : 's'} ago`;
12165
+ }
12166
+
12167
+ function resumeLastHomeAction() {
12168
+ switchTab(getHomeLastActiveTab());
12169
+ }
12170
+
12171
+ function renderHomeStatusGrid() {
12172
+ const container = document.getElementById('homeStatusGrid');
12173
+ if (!container) return;
12174
+
12175
+ const lastTab = getHomeLastActiveTab();
12176
+ const latestRelease = Array.isArray(homeData.releases) && homeData.releases.length ? homeData.releases[0] : null;
12177
+ const version = window.appVersion || 'dev';
12178
+
12179
+ const cards = [
12180
+ {
12181
+ label: 'API key',
12182
+ value: homeData.hasApiKey ? 'Connected' : 'Needs setup',
12183
+ description: homeData.hasApiKey
12184
+ ? 'Your Voyage AI key is configured and ready for requests.'
12185
+ : 'Add your API key to start embedding, reranking, and workflows.',
12186
+ statusClass: homeData.hasApiKey ? 'is-ok' : 'is-warning',
12187
+ actionLabel: homeData.hasApiKey ? 'View settings' : 'Add key',
12188
+ action: "switchTab('settings')"
12189
+ },
12190
+ {
12191
+ label: 'Next action',
12192
+ value: `Resume ${formatHomeTabLabel(lastTab)}`,
12193
+ description: 'Jump back into the tool you used most recently in this desktop session.',
12194
+ statusClass: 'is-ok',
12195
+ actionLabel: 'Resume',
12196
+ action: 'resumeLastHomeAction()'
12197
+ },
12198
+ {
12199
+ label: 'App version',
12200
+ value: `v${version}`,
12201
+ description: latestRelease
12202
+ ? `Latest release loaded: ${latestRelease.version}`
12203
+ : 'Checking the latest release notes for this build.',
12204
+ statusClass: 'is-ok',
12205
+ actionLabel: 'View updates',
12206
+ action: "document.getElementById('homeUpdateContent')?.scrollIntoView({ behavior: 'smooth', block: 'start' })"
12207
+ },
12208
+ {
12209
+ label: 'Command palette',
12210
+ value: 'Cmd+K',
12211
+ description: 'Search commands, recent actions, and workflow shortcuts from anywhere in the app.',
12212
+ statusClass: 'is-ok',
12213
+ actionLabel: 'Open palette',
12214
+ action: 'toggleCommandPalette()'
12215
+ }
12216
+ ];
12217
+
12218
+ container.innerHTML = cards.map(card => `
12219
+ <div class="home-status-card ${card.statusClass}">
12220
+ <div class="home-status-label">${card.label}</div>
12221
+ <div class="home-status-value">${card.value}</div>
12222
+ <div class="home-status-description">${card.description}</div>
12223
+ <button class="home-link-button home-status-action" onclick="${card.action}">${card.actionLabel}</button>
12224
+ </div>
12225
+ `).join('');
12226
+ }
12227
+
12228
+ function renderHomeRecentActivity() {
12229
+ const container = document.getElementById('homeRecentActivity');
12230
+ if (!container) return;
12231
+
12232
+ const lastTab = getHomeLastActiveTab();
12233
+ const trackerItems = typeof recentItemsTracker !== 'undefined' && Array.isArray(recentItemsTracker.items)
12234
+ ? recentItemsTracker.items
12235
+ : [];
12236
+ const recentItems = trackerItems
12237
+ .filter(item => item.id !== 'nav-home')
12238
+ .slice(0, 3);
12239
+
12240
+ const recentMarkup = recentItems.length ? `
12241
+ <div class="home-recent-list">
12242
+ ${recentItems.map(item => `
12243
+ <div class="home-recent-item">
12244
+ <div class="home-recent-item-main">
12245
+ <div class="home-recent-item-title">${escapeHtml(item.action || 'Recent activity')}</div>
12246
+ <div class="home-recent-item-meta">${escapeHtml(formatHomeRelativeTime(item.timestamp))}</div>
12247
+ </div>
12248
+ </div>
12249
+ `).join('')}
12250
+ </div>
12251
+ ` : `
12252
+ <div class="home-empty-state">Use a few tools and this section will keep your most recent in-app activity visible.</div>
12253
+ `;
12254
+
12255
+ container.innerHTML = `
12256
+ <div class="home-resume-main">
12257
+ <div>
12258
+ <span class="home-resume-label">Last active tool</span>
12259
+ <span class="home-resume-title">${escapeHtml(formatHomeTabLabel(lastTab))}</span>
12260
+ <div class="home-resume-description">Return to the last workspace you opened instead of hunting through the sidebar.</div>
12261
+ </div>
12262
+ <button class="btn" onclick="resumeLastHomeAction()">Resume</button>
12263
+ </div>
12264
+ ${recentMarkup}
12265
+ `;
12266
+ }
12267
+
12268
+ function renderHomeUpdate() {
12269
+ const container = document.getElementById('homeUpdateContent');
12270
+ if (!container) return;
12271
+
12272
+ if (homeData.releases === null) {
12273
+ container.innerHTML = '<div class="home-empty-state">Loading the latest release notes...</div>';
12274
+ return;
12275
+ }
12276
+
12277
+ const release = homeData.releases[0];
12278
+ if (!release) {
12279
+ container.innerHTML = '<div class="home-empty-state">Release notes are not available right now. You can still open the full releases page from GitHub.</div>';
12280
+ return;
12281
+ }
12282
+
12283
+ const highlights = Array.isArray(release.highlights) ? release.highlights.slice(0, 3) : [];
12284
+ container.innerHTML = `
12285
+ <div class="home-update-card">
12286
+ <div class="home-update-kicker">Latest release</div>
12287
+ <h4 class="home-update-title">${escapeHtml(release.version || 'Current release')}</h4>
12288
+ <div class="home-update-date">${escapeHtml(new Date(release.date).toLocaleDateString())}</div>
12289
+ <div class="home-update-summary">A focused snapshot of what changed most recently, so returning users can orient quickly without wading through a feed.</div>
12290
+ ${highlights.length ? `
12291
+ <ul class="home-update-highlights">
12292
+ ${highlights.map(highlight => `<li>${escapeHtml(highlight)}</li>`).join('')}
12293
+ </ul>
12294
+ ` : ''}
12295
+ </div>
12296
+ `;
12297
+ }
12298
+
12299
+ function renderHomeWorkflowSpotlight() {
12300
+ const container = document.getElementById('homeWorkflowSpotlight');
12301
+ if (!container) return;
12302
+
12303
+ if (homeData.featuredWorkflows === null) {
12304
+ container.innerHTML = '<div class="home-empty-state">Loading featured workflows...</div>';
12305
+ return;
11301
12306
  }
12307
+
12308
+ const workflows = (homeData.featuredWorkflows || []).slice(0, 2);
12309
+ if (!workflows.length) {
12310
+ container.innerHTML = '<div class="home-empty-state">Featured workflow suggestions are not available right now. Open the workflows tab to browse your library or install from the store.</div>';
12311
+ return;
12312
+ }
12313
+
12314
+ container.innerHTML = workflows.map(workflow => `
12315
+ <div class="home-workflow-spotlight">
12316
+ <h4>${escapeHtml(workflow.name || 'Untitled workflow')}</h4>
12317
+ <p>${escapeHtml(workflow.description || 'No description available.')}</p>
12318
+ <div class="home-workflow-spotlight-meta">
12319
+ <span class="home-workflow-domain">${escapeHtml(workflow.category || 'utility')}</span>
12320
+ <span class="home-workflow-author">by ${escapeHtml(workflow.author?.name || 'unknown')}</span>
12321
+ </div>
12322
+ <div class="home-workflow-actions">
12323
+ <button class="home-workflow-btn" onclick="wfStoreInstall('${workflow.packageName}', this)">Install</button>
12324
+ <button class="home-workflow-btn" onclick="viewWorkflowDetails('${workflow.packageName}')">Details</button>
12325
+ </div>
12326
+ </div>
12327
+ `).join('');
11302
12328
  }
11303
12329
 
11304
12330
  async function loadAnnouncements() {
@@ -12677,11 +13703,6 @@ function renderModelsHero() {
12677
13703
  '<span class="model-chip-price">' + escapeHtml(m.price) + '</span>' +
12678
13704
  '</div>'
12679
13705
  ).join('');
12680
-
12681
- const shapeEl = document.getElementById('modelsHeroShape');
12682
- if (shapeEl && !shapeEl.innerHTML) {
12683
- shapeEl.innerHTML = generateNebulaSVG(200, 200, 900, {variant: 'rich', opacity: 0.08});
12684
- }
12685
13706
  }
12686
13707
 
12687
13708
  function getModelGroups(models) {
@@ -12764,14 +13785,13 @@ function renderModelCard(model, seedOffset) {
12764
13785
  if (model.multimodal) {
12765
13786
  tryActions = '<button class="model-card-action" onclick="event.stopPropagation(); switchTab(\'multimodal\')">Try in Multimodal</button>';
12766
13787
  } else if (model.type === 'reranking') {
12767
- tryActions = '<button class="model-card-action" onclick="event.stopPropagation(); switchTab(\'search\')">Try in Search</button>';
13788
+ tryActions = '<button class="model-card-action" onclick="event.stopPropagation(); switchTab(\'search\')">Try in Rerank</button>';
12768
13789
  } else if (!model.legacy) {
12769
13790
  tryActions = '<button class="model-card-action" onclick="event.stopPropagation(); switchTab(\'embed\')">Try in Embed</button>' +
12770
- '<button class="model-card-action" onclick="event.stopPropagation(); switchTab(\'search\')">Try in Search</button>';
13791
+ '<button class="model-card-action" onclick="event.stopPropagation(); switchTab(\'search\')">Try in Rerank</button>';
12771
13792
  }
12772
13793
 
12773
13794
  return '<div class="model-card ' + (model.legacy ? 'legacy' : '') + '" data-model="' + model.name + '" data-type="' + typeClass + '" id="model-card-' + model.name + '">' +
12774
- '<div class="model-card-nebula">' + generateNebulaSVG(140, 140, 500 + seedOffset, {variant: 'subtle', opacity: 0.05, sparkles: false}) + '</div>' +
12775
13795
  rtebBadge +
12776
13796
  '<div class="model-card-header">' +
12777
13797
  '<span class="model-card-name">' + escapeHtml(model.name) + '</span>' +
@@ -14679,254 +15699,10 @@ function checkForAppUpdate() {
14679
15699
  // ── Onboarding Walkthrough ──
14680
15700
  function initOnboarding() {
14681
15701
  const ONBOARDING_KEY = 'vai-onboarding-complete';
14682
- const overlay = document.getElementById('onboardingOverlay');
14683
- const welcomeWrap = document.getElementById('onboardingWelcomeWrap');
14684
- const welcomeCard = document.getElementById('onboardingWelcomeCard');
14685
- const tooltip = document.getElementById('onboardingTooltip');
14686
- const spotlight = document.getElementById('onboardingSpotlight');
14687
- const arrow = document.getElementById('onboardingArrow');
14688
- const dotsContainer = document.getElementById('onboardingDots');
14689
- const titleEl = document.getElementById('onboardingTitle');
14690
- const bodyEl = document.getElementById('onboardingBody');
14691
- const iconEl = document.getElementById('onboardingIcon');
14692
-
14693
- if (!overlay) return;
14694
-
14695
- const isElectron = !!(window.vai && window.vai.isElectron);
14696
-
14697
- const steps = [
14698
- {
14699
- target: null, // welcome card, no spotlight
14700
- icon: '🚀',
14701
- title: 'Welcome to Vai',
14702
- body: 'Explore embeddings, build RAG pipelines, generate production code — all from one playground.',
14703
- },
14704
- {
14705
- target: '[data-tab="settings"]',
14706
- icon: '🔑',
14707
- title: 'API Key Setup',
14708
- body: 'First, add your <strong>Voyage AI API key</strong> in Settings. You can get one free at <strong>dash.voyageai.com</strong>.' +
14709
- (isElectron ? '<br><br>💎 On desktop, your key is encrypted via <strong>OS keychain</strong> for secure storage.' : ''),
14710
- arrow: 'left',
14711
- },
14712
- {
14713
- target: '[data-tab="embed"]',
14714
- icon: '⚡',
14715
- title: 'Embed',
14716
- body: 'Turn any text into a <strong>vector embedding</strong> — a numerical fingerprint that captures meaning. Visualize the raw vectors and explore what models produce.',
14717
- arrow: 'left',
14718
- },
14719
- {
14720
- target: '[data-tab="compare"]',
14721
- icon: '🔥',
14722
- title: 'Compare',
14723
- body: 'Paste multiple texts and see a <strong>similarity heatmap</strong> — instantly discover which phrases are semantically close and which are far apart.',
14724
- arrow: 'left',
14725
- },
14726
- {
14727
- target: '[data-tab="search"]',
14728
- icon: '🔍',
14729
- title: 'Search & Rerank',
14730
- body: 'Run <strong>vector search</strong> against a set of documents and optionally <strong>rerank</strong> results for higher precision. Great for building RAG pipelines.',
14731
- arrow: 'left',
14732
- },
14733
- {
14734
- target: '[data-tab="multimodal"]',
14735
- icon: '🖼️',
14736
- title: 'Multimodal',
14737
- body: 'Embed <strong>images and text</strong> in the same vector space. Search images with text queries, or find similar images across your collection.',
14738
- arrow: 'left',
14739
- },
14740
- {
14741
- target: '[data-tab="generate"]',
14742
- icon: '💻',
14743
- title: 'Generate & Scaffold',
14744
- body: '<strong>Generate code snippets</strong> for retrieval, ingestion, and API routes — or <strong>scaffold entire projects</strong> with Next.js, Express, or Flask.' +
14745
- (isElectron ? ' Create projects directly on disk.' : ' Download as ZIP.'),
14746
- arrow: 'left',
14747
- },
14748
- {
14749
- target: '[data-tab="chat"]',
14750
- icon: '💬',
14751
- title: 'RAG Chat',
14752
- body: '<strong>Chat with your knowledge base</strong> using retrieval-augmented generation. Voyage AI finds relevant documents, then your chosen LLM generates grounded answers with source citations.',
14753
- arrow: 'left',
14754
- },
14755
- {
14756
- target: '[data-tab="workflows"]',
14757
- icon: '\u2699\uFE0F',
14758
- title: 'Workflow Visualizer',
14759
- body: '<strong>Visualize and execute workflows</strong> as interactive DAGs. Browse built-in templates, inspect step configuration, and watch execution animate in real time.',
14760
- arrow: 'left',
14761
- },
14762
- {
14763
- target: '[data-tab="benchmark"]',
14764
- icon: '⏱️',
14765
- title: 'Benchmark',
14766
- body: 'Compare model <strong>latency, throughput, and cost</strong>. Test embedding speeds, reranking quality, and quantization trade-offs.',
14767
- arrow: 'left',
14768
- },
14769
- {
14770
- target: '[data-tab="explore"]',
14771
- icon: '💡',
14772
- title: 'Explore & Learn',
14773
- body: 'Dive into <strong>25 interactive explainers</strong> covering embeddings, vector search, RAG, reranking, and more. Each topic links to live demos.',
14774
- arrow: 'left',
14775
- },
14776
- ];
14777
-
14778
- let currentStep = 0;
14779
- const totalSteps = steps.length;
14780
-
14781
- function buildDots() {
14782
- dotsContainer.innerHTML = '';
14783
- for (let i = 1; i < totalSteps; i++) {
14784
- const dot = document.createElement('div');
14785
- dot.className = 'onboarding-dot';
14786
- if (i < currentStep) dot.classList.add('completed');
14787
- if (i === currentStep) dot.classList.add('active');
14788
- dotsContainer.appendChild(dot);
14789
- }
14790
- }
14791
-
14792
- function positionTooltipNear(targetEl) {
14793
- const step = steps[currentStep];
14794
- const rect = targetEl.getBoundingClientRect();
14795
-
14796
- // Position spotlight over the target
14797
- spotlight.style.display = 'block';
14798
- const pad = 6;
14799
- spotlight.style.left = (rect.left - pad) + 'px';
14800
- spotlight.style.top = (rect.top - pad) + 'px';
14801
- spotlight.style.width = (rect.width + pad * 2) + 'px';
14802
- spotlight.style.height = (rect.height + pad * 2) + 'px';
14803
-
14804
- // Reset arrow classes
14805
- arrow.className = 'onboarding-tooltip-arrow';
14806
-
14807
- // Position tooltip to the right of sidebar items
14808
- if (step.arrow === 'left') {
14809
- arrow.classList.add('left');
14810
- tooltip.style.left = (rect.right + 16) + 'px';
14811
- tooltip.style.top = Math.max(8, rect.top - 10) + 'px';
14812
- tooltip.style.right = 'auto';
14813
- tooltip.style.bottom = 'auto';
14814
- } else {
14815
- // Below the target
14816
- arrow.classList.add('top');
14817
- tooltip.style.left = Math.max(8, rect.left) + 'px';
14818
- tooltip.style.top = (rect.bottom + 14) + 'px';
14819
- tooltip.style.right = 'auto';
14820
- tooltip.style.bottom = 'auto';
14821
- }
14822
-
14823
- // Ensure tooltip doesn't overflow viewport
14824
- requestAnimationFrame(() => {
14825
- const tr = tooltip.getBoundingClientRect();
14826
- if (tr.bottom > window.innerHeight - 10) {
14827
- tooltip.style.top = Math.max(8, window.innerHeight - tr.height - 10) + 'px';
14828
- }
14829
- if (tr.right > window.innerWidth - 10) {
14830
- tooltip.style.left = Math.max(8, window.innerWidth - tr.width - 10) + 'px';
14831
- }
14832
- });
14833
- }
14834
-
14835
- function showStep(idx) {
14836
- currentStep = idx;
14837
- const step = steps[idx];
14838
-
14839
- if (idx === 0) {
14840
- // Welcome card — centered, no spotlight
14841
- welcomeWrap.style.display = 'flex';
14842
- tooltip.classList.remove('visible');
14843
- tooltip.style.display = 'none';
14844
- spotlight.style.display = 'none';
14845
- requestAnimationFrame(() => {
14846
- welcomeCard.classList.add('visible');
14847
- });
14848
- return;
14849
- }
14850
-
14851
- // Hide welcome card
14852
- welcomeWrap.style.display = 'none';
14853
- welcomeCard.classList.remove('visible');
14854
-
14855
- // Show tooltip
14856
- tooltip.style.display = 'block';
14857
- tooltip.classList.remove('visible');
14858
- iconEl.textContent = step.icon;
14859
- titleEl.textContent = step.title;
14860
- bodyEl.innerHTML = step.body;
14861
- buildDots();
14862
-
14863
- // Update next button text
14864
- const nextBtn = document.getElementById('onboardingNext');
14865
- nextBtn.textContent = (idx === totalSteps - 1) ? 'Get Started' : 'Next';
14866
-
14867
- // Find target element and position
14868
- const targetEl = document.querySelector(step.target);
14869
- if (targetEl) {
14870
- positionTooltipNear(targetEl);
14871
- }
14872
-
14873
- requestAnimationFrame(() => {
14874
- tooltip.classList.add('visible');
14875
- });
14876
- }
14877
-
14878
- function finish() {
14879
- tooltip.classList.remove('visible');
14880
- welcomeCard.classList.remove('visible');
14881
- spotlight.style.display = 'none';
14882
- setTimeout(() => {
14883
- overlay.classList.remove('active');
14884
- }, 300);
14885
- localStorage.setItem(ONBOARDING_KEY, 'true');
14886
- }
14887
-
14888
- function nextStep() {
14889
- if (currentStep < totalSteps - 1) {
14890
- showStep(currentStep + 1);
14891
- } else {
14892
- finish();
14893
- }
14894
- }
14895
-
14896
- // Wire up buttons
14897
- document.getElementById('onboardingWelcomeNext').addEventListener('click', nextStep);
14898
- document.getElementById('onboardingWelcomeSkip').addEventListener('click', finish);
14899
- document.getElementById('onboardingNext').addEventListener('click', nextStep);
14900
- document.getElementById('onboardingSkip').addEventListener('click', finish);
14901
- document.getElementById('onboardingBackdrop').addEventListener('click', finish);
14902
-
14903
- // "Show Welcome Tour" button in settings
14904
- const tourBtn = document.getElementById('settingsShowTour');
14905
- if (tourBtn) {
14906
- tourBtn.addEventListener('click', () => {
14907
- startOnboarding();
14908
- });
14909
- }
14910
-
14911
- // Auto-start on first visit
14912
- function startOnboarding() {
14913
- // Sync onboarding logo with current theme
14914
- const onboardLogo = document.getElementById('onboardingLogo');
14915
- if (onboardLogo) {
14916
- const theme = localStorage.getItem('vai-theme') || 'dark';
14917
- onboardLogo.src = '/icons/' + (theme === 'light' ? 'light' : 'dark') + '/64.png';
14918
- }
14919
- overlay.classList.add('active');
14920
- showStep(0);
14921
- }
14922
-
14923
- if (!localStorage.getItem(ONBOARDING_KEY)) {
14924
- // Delay slightly so the app is fully rendered
14925
- setTimeout(startOnboarding, 600);
14926
- }
14927
-
14928
- // Expose for manual replay
14929
- window.startOnboarding = startOnboarding;
15702
+ // The legacy welcome tour no longer matches the redesigned interface.
15703
+ // Mark it complete so startup skips the broken onboarding flow.
15704
+ localStorage.setItem(ONBOARDING_KEY, 'true');
15705
+ window.startOnboarding = function() {};
14930
15706
  }
14931
15707
 
14932
15708
  // ── Multimodal Tab ──
@@ -15621,7 +16397,6 @@ let _vsiGameTrigger = 'unknown';
15621
16397
  'exploreModal',
15622
16398
  'costHelpModal',
15623
16399
  'agentInfoModal',
15624
- 'onboardingOverlay',
15625
16400
  'wfStoreOverlay',
15626
16401
  'wfOutputModalBackdrop',
15627
16402
  'wfHelpModalBackdrop',
@@ -21121,8 +21896,7 @@ const DOCS_URLS = {
21121
21896
  document.addEventListener('keydown', (e) => {
21122
21897
  if (e.key === 'F1') {
21123
21898
  e.preventDefault();
21124
- const activeTab = document.querySelector('.tab-btn.active');
21125
- const tabName = activeTab ? activeTab.dataset.tab : '';
21899
+ const tabName = getActiveTabId();
21126
21900
  const url = DOCS_URLS[tabName] || 'https://docs.vaicli.com';
21127
21901
  window.open(url, '_blank', 'noopener');
21128
21902
  }
@@ -21130,8 +21904,7 @@ document.addEventListener('keydown', (e) => {
21130
21904
 
21131
21905
  // Keyboard shortcuts (when workflows tab is active)
21132
21906
  document.addEventListener('keydown', (e) => {
21133
- const activeTab = document.querySelector('.tab-btn.active');
21134
- if (!activeTab || activeTab.dataset.tab !== 'workflows') return;
21907
+ if (getActiveTabId() !== 'workflows') return;
21135
21908
 
21136
21909
  // Ctrl/Cmd+S to save/export in builder mode (works even in inputs)
21137
21910
  if ((e.ctrlKey || e.metaKey) && e.key === 's' && wfState.builderMode) {
@@ -21781,7 +22554,7 @@ let wfInitialized = false;
21781
22554
  const env = {
21782
22555
  platform: navigator.platform,
21783
22556
  source: isElectron ? 'desktop-app' : 'playground',
21784
- currentScreen: document.querySelector('.tab-btn.active')?.textContent?.trim() || 'unknown',
22557
+ currentScreen: getActiveTabLabel(),
21785
22558
  currentUrl: window.location.href,
21786
22559
  sessionId: window._chatExportData?.sessionId || null,
21787
22560
  };
@@ -22914,8 +23687,7 @@ document.addEventListener('keydown', (e) => {
22914
23687
  closeExportDialog();
22915
23688
  } else {
22916
23689
  // Detect current tab context
22917
- const activeTab = document.querySelector('.tab-btn.active');
22918
- const tab = activeTab?.dataset?.tab;
23690
+ const tab = getActiveTabId();
22919
23691
  const contextMap = {
22920
23692
  workflows: 'workflow', search: 'search', chat: 'chat',
22921
23693
  benchmark: 'benchmark', explore: 'explore',
@@ -22931,8 +23703,7 @@ document.addEventListener('keydown', (e) => {
22931
23703
  // ── Electron menu trigger ──
22932
23704
  if (window.vai && window.vai.export && window.vai.export.onTrigger) {
22933
23705
  window.vai.export.onTrigger(() => {
22934
- const activeTab = document.querySelector('.tab-btn.active');
22935
- const tab = activeTab?.dataset?.tab;
23706
+ const tab = getActiveTabId();
22936
23707
  const contextMap = {
22937
23708
  workflows: 'workflow', search: 'search', chat: 'chat',
22938
23709
  benchmark: 'benchmark', explore: 'explore',
@@ -23144,10 +23915,10 @@ function generateContextualCommands() {
23144
23915
  // Static command registry
23145
23916
  const staticCommandRegistry = [
23146
23917
  // Navigation Commands
23147
- { id: 'nav-home', label: 'Home', description: 'Dashboard, announcements, marketplace', category: 'navigation', keywords: ['dashboard', 'landing', 'start'], icon: '🏠', shortcut: '⌘1', priority: 1, execute: () => switchTab('home') },
23918
+ { id: 'nav-home', label: 'Overview', description: 'Dashboard, status, and recent activity', category: 'navigation', keywords: ['dashboard', 'landing', 'start', 'home'], icon: '🏠', shortcut: '⌘1', priority: 1, execute: () => switchTab('home') },
23148
23919
  { id: 'nav-embed', label: 'Embed', description: 'Generate and inspect embeddings', category: 'navigation', keywords: ['embedding', 'generate', 'vector'], icon: '⚡', shortcut: '⌘2', priority: 1, execute: () => switchTab('embed') },
23149
- { id: 'nav-compare', label: 'Compare', description: 'Similarity comparison with scores', category: 'navigation', keywords: ['similarity', 'cosine', 'compare'], icon: '🔗', shortcut: '⌘3', priority: 1, execute: () => switchTab('compare') },
23150
- { id: 'nav-search', label: 'Search', description: 'Vector search with filters', category: 'navigation', keywords: ['find', 'query', 'vector', 'lookup'], icon: '🔍', shortcut: '⌘4', priority: 1, execute: () => switchTab('search') },
23920
+ { id: 'nav-compare', label: 'Compare', description: 'Inspect similarity between inputs and scores', category: 'navigation', keywords: ['similarity', 'cosine', 'compare', 'evaluate'], icon: '🔗', shortcut: '⌘3', priority: 1, execute: () => switchTab('compare') },
23921
+ { id: 'nav-search', label: 'Rerank', description: 'Re-order candidate documents by relevance', category: 'navigation', keywords: ['find', 'query', 'vector', 'lookup', 'rerank', 'search'], icon: '🔍', shortcut: '⌘4', priority: 1, execute: () => switchTab('search') },
23151
23922
  { id: 'nav-multimodal', label: 'Multimodal', description: 'Cross-modal search with images and text', category: 'navigation', keywords: ['image', 'text', 'cross-modal', 'vision'], icon: '🖼️', shortcut: '⌘5', priority: 1, execute: () => switchTab('multimodal') },
23152
23923
  { id: 'nav-generate', label: 'Generate', description: 'Code generation and templates', category: 'navigation', keywords: ['code', 'template', 'scaffold'], icon: '💻', shortcut: '⌘6', priority: 1, execute: () => switchTab('generate') },
23153
23924
  { id: 'nav-chat', label: 'Chat', description: 'Chat with your knowledge base', category: 'navigation', keywords: ['conversation', 'ask', 'rag', 'talk'], icon: '💬', shortcut: '⌘7', priority: 1, execute: () => switchTab('chat') },