@livelayer/react 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/styles.css CHANGED
@@ -117,48 +117,83 @@
117
117
  }
118
118
 
119
119
  /* ── Hidden mode: edge chevron tab ────────────────────────────────── */
120
+ /* Solid-black tab docked to the screen edge with a white chevron.
121
+ Designed to be unmistakably visible on light AND dark pages — no
122
+ transparency, no backdrop-blur tricks. Drag vertically to
123
+ reposition; click to reopen.
120
124
 
121
- .ll-hidden {
125
+ Why `.ll-widget .ll-hidden` instead of bare `.ll-hidden`:
126
+ the upstream `.ll-widget button` reset (background:none, border:none,
127
+ color:inherit) has specificity (0,1,1) and would zero out background
128
+ and border on the bare class. Compound selector wins at (0,2,0). */
129
+
130
+ .ll-widget .ll-hidden {
122
131
  display: flex;
123
132
  align-items: center;
124
133
  justify-content: center;
125
- width: 28px;
126
- height: 56px;
127
- background: var(--ll-color-chrome-bg);
128
- color: var(--ll-color-chrome-fg);
129
- border-radius: 12px 0 0 12px;
130
- box-shadow: var(--ll-shadow-pill);
131
- transition: transform var(--ll-transition-base), width var(--ll-transition-base);
132
- /* Re-anchor to edge (ignore .ll-widget's 16px corner inset) */
134
+ width: 36px;
135
+ height: 72px;
136
+ background: #0d0d0d;
137
+ color: #fff;
138
+ border: 1px solid rgba(255, 255, 255, 0.18);
139
+ box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45),
140
+ 0 2px 6px rgba(0, 0, 0, 0.3);
141
+ cursor: grab;
142
+ transition: background 0.18s ease, width 0.18s ease;
143
+ /* Re-anchor to edge (ignore .ll-widget's 16px corner inset). The
144
+ drag handler overrides `top` (and clears the transform) once a
145
+ position is loaded; until then this CSS-only centering keeps
146
+ SSR / first-paint sane. */
133
147
  position: fixed;
134
148
  top: 50%;
135
149
  transform: translateY(-50%);
150
+ padding: 0;
151
+ touch-action: none;
152
+ user-select: none;
153
+ -webkit-user-select: none;
136
154
  }
137
155
 
138
- .ll-hidden:hover {
139
- width: 32px;
156
+ .ll-widget .ll-hidden:hover {
157
+ background: #1a1a1a;
158
+ width: 42px;
159
+ }
160
+
161
+ .ll-widget .ll-hidden.is-dragging {
162
+ cursor: grabbing;
163
+ transition: none;
164
+ background: #1a1a1a;
140
165
  }
141
166
 
142
- .ll-hidden--right {
167
+ .ll-widget .ll-hidden--right {
143
168
  right: 0;
144
- border-radius: 12px 0 0 12px;
169
+ border-right: none;
170
+ border-radius: 14px 0 0 14px;
145
171
  }
146
- .ll-hidden--left {
172
+ .ll-widget .ll-hidden--left {
147
173
  left: 0;
148
- border-radius: 0 12px 12px 0;
174
+ border-left: none;
175
+ border-radius: 0 14px 14px 0;
149
176
  }
150
177
 
151
- .ll-hidden--mobile {
152
- width: 32px;
153
- height: 64px;
178
+ .ll-widget .ll-hidden--mobile {
179
+ width: 40px;
180
+ height: 80px;
154
181
  }
155
182
 
156
- .ll-hidden__chevron {
157
- width: 14px;
158
- height: 14px;
183
+ .ll-widget .ll-hidden__chevron {
184
+ /* Centered visually inside the tab. The SVG's stroke handles color;
185
+ `display: block` prevents any baseline gap that would offset the
186
+ icon vertically. */
187
+ display: block;
188
+ width: 18px;
189
+ height: 18px;
190
+ stroke: #fff;
191
+ stroke-width: 2.25;
192
+ opacity: 1;
193
+ pointer-events: none;
159
194
  }
160
195
 
161
- .ll-hidden--speaking {
196
+ .ll-widget .ll-hidden--speaking {
162
197
  animation: ll-pulse 1.5s ease-in-out infinite;
163
198
  }
164
199
 
@@ -350,398 +385,778 @@
350
385
  50% { opacity: 0.5; }
351
386
  }
352
387
 
353
- /* ── Expanded mode ────────────────────────────────────────────── */
388
+ /* ── Expanded mode ────────────────────────────────────────────────── */
389
+ /* Full-bleed avatar with glass pills overlaid on top. No card chrome. */
354
390
 
355
391
  .ll-expanded {
392
+ position: relative;
393
+ overflow: hidden;
394
+ background: #1a1a1a;
395
+ color: #fff;
396
+ box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
397
+ font-family: inherit;
356
398
  display: flex;
357
399
  flex-direction: column;
358
- background: var(--ll-color-bg);
359
- border-radius: var(--ll-radius-panel);
360
- box-shadow: var(--ll-shadow-card);
361
- overflow: hidden;
362
400
  }
363
401
 
364
402
  .ll-expanded--desktop {
365
403
  width: 400px;
366
- height: 600px;
367
- max-height: calc(100vh - 48px);
404
+ height: 560px;
405
+ border-radius: 20px;
368
406
  }
369
407
 
370
408
  .ll-expanded--mobile {
371
409
  width: 100vw;
372
410
  height: 80dvh;
373
- border-radius: 20px 20px 0 0;
374
- padding-bottom: env(safe-area-inset-bottom);
375
- animation: ll-slide-up 250ms ease;
411
+ border-top-left-radius: 20px;
412
+ border-top-right-radius: 20px;
413
+ border-bottom-left-radius: 0;
414
+ border-bottom-right-radius: 0;
376
415
  }
377
416
 
378
- @keyframes ll-slide-up {
379
- from {
380
- transform: translateY(100%);
381
- }
382
- to {
383
- transform: translateY(0);
384
- }
385
- }
417
+ /* ── Background layers ───────────────────────────────────────── */
386
418
 
387
- /* Header */
388
- .ll-expanded__header {
389
- display: flex;
390
- align-items: center;
391
- justify-content: space-between;
392
- padding: 12px 16px;
393
- border-bottom: 1px solid var(--ll-color-border-subtle);
394
- flex-shrink: 0;
419
+ .ll-expanded__bg,
420
+ .ll-expanded__video {
421
+ position: absolute;
422
+ inset: 0;
395
423
  }
396
424
 
397
- .ll-expanded__header-left,
398
- .ll-expanded__header-right {
399
- display: flex;
400
- align-items: center;
401
- gap: 8px;
425
+ .ll-expanded__bg { z-index: 0; }
426
+ .ll-expanded__video { z-index: 1; pointer-events: none; }
427
+
428
+ .ll-expanded__video > video {
429
+ width: 100%;
430
+ height: 100%;
431
+ object-fit: cover;
402
432
  }
403
433
 
404
- .ll-expanded__logo {
405
- width: 24px;
406
- height: 24px;
407
- border-radius: 4px;
434
+ .ll-expanded__bg-img {
435
+ width: 100%;
436
+ height: 100%;
408
437
  object-fit: cover;
438
+ transition: filter 0.3s ease;
409
439
  }
410
440
 
411
- .ll-expanded__name {
412
- font-size: 14px;
413
- font-weight: 600;
414
- color: var(--ll-color-fg);
441
+ /* Idle state: blur the avatar preview so the play button pops. Also
442
+ scale up slightly to hide the blurred edge bleed. Transitions off
443
+ smoothly when the session connects. */
444
+ .ll-expanded[data-state="idle"] .ll-expanded__bg-img {
445
+ filter: blur(10px);
446
+ transform: scale(1.08);
415
447
  }
416
448
 
417
- .ll-expanded__team-trigger {
449
+ /* Darkening overlay sits on top of the bg in idle so the play button
450
+ and copy stay readable against any background color. Only rendered
451
+ when the avatar image is present (via sibling selector below). */
452
+ .ll-expanded[data-state="idle"] .ll-expanded__bg::after {
453
+ content: "";
454
+ position: absolute;
455
+ inset: 0;
456
+ background: linear-gradient(
457
+ 180deg,
458
+ rgba(0, 0, 0, 0.35) 0%,
459
+ rgba(0, 0, 0, 0.25) 45%,
460
+ rgba(0, 0, 0, 0.55) 100%
461
+ );
462
+ pointer-events: none;
463
+ }
464
+
465
+ .ll-expanded__bg-fallback {
466
+ width: 100%;
467
+ height: 100%;
418
468
  display: flex;
419
469
  align-items: center;
420
- gap: 4px;
421
- font-size: 14px;
470
+ justify-content: center;
471
+ background: linear-gradient(135deg, #2a2a2a, #1a1a1a);
472
+ }
473
+
474
+ .ll-expanded__bg-initial {
475
+ font-size: 64px;
422
476
  font-weight: 600;
423
- color: var(--ll-color-fg);
424
- padding: 4px 8px;
425
- border-radius: var(--ll-radius-pill);
426
- transition: background var(--ll-transition-fast);
477
+ color: rgba(255, 255, 255, 0.3);
427
478
  }
428
- .ll-expanded__team-trigger:hover {
429
- background: var(--ll-color-border-subtle);
479
+
480
+ .ll-expanded__bg-idle {
481
+ position: absolute;
482
+ inset: 0;
483
+ width: 100%;
484
+ height: 100%;
485
+ object-fit: cover;
430
486
  }
431
487
 
432
- .ll-expanded__team-chevron {
433
- width: 14px;
434
- height: 14px;
435
- transition: transform var(--ll-transition-base);
488
+ /* ── Overlays (connecting / gesture) ────────────────────────── */
489
+
490
+ .ll-expanded__overlay {
491
+ position: absolute;
492
+ inset: 0;
493
+ z-index: 4;
494
+ display: flex;
495
+ flex-direction: column;
496
+ align-items: center;
497
+ justify-content: center;
498
+ gap: 12px;
499
+ background: rgba(0, 0, 0, 0.35);
500
+ -webkit-backdrop-filter: blur(2px);
501
+ backdrop-filter: blur(2px);
502
+ border: none;
503
+ color: #fff;
504
+ padding: 0;
505
+ font-family: inherit;
436
506
  }
437
- .ll-expanded__team-chevron--open {
438
- transform: rotate(180deg);
507
+
508
+ .ll-expanded__overlay--gesture {
509
+ cursor: pointer;
510
+ background: rgba(0, 0, 0, 0.5);
439
511
  }
440
512
 
441
- .ll-expanded__icon-btn {
513
+ .ll-expanded__overlay-text {
514
+ margin: 0;
515
+ font-size: 13px;
516
+ font-weight: 500;
517
+ color: rgba(255, 255, 255, 0.9);
518
+ letter-spacing: -0.15px;
519
+ }
520
+
521
+ .ll-expanded__spinner {
442
522
  width: 32px;
443
523
  height: 32px;
524
+ border: 2px solid rgba(255, 255, 255, 0.3);
525
+ border-top-color: #fff;
444
526
  border-radius: 50%;
527
+ animation: ll-spin 0.9s linear infinite;
528
+ }
529
+
530
+ @keyframes ll-spin {
531
+ to { transform: rotate(360deg); }
532
+ }
533
+
534
+ /* ── Idle-state header (before connect) ─────────────────────── */
535
+
536
+ .ll-expanded__header {
537
+ position: absolute;
538
+ top: 0;
539
+ left: 0;
540
+ right: 0;
541
+ z-index: 3;
445
542
  display: flex;
446
543
  align-items: center;
447
- justify-content: center;
448
- color: var(--ll-color-fg);
449
- transition: background var(--ll-transition-fast);
544
+ justify-content: space-between;
545
+ padding: 14px 16px;
450
546
  }
451
- .ll-expanded__icon-btn:hover {
452
- background: var(--ll-color-border-subtle);
547
+
548
+ .ll-expanded__header--idle {
549
+ background: linear-gradient(
550
+ to bottom,
551
+ rgba(0, 0, 0, 0.55),
552
+ rgba(0, 0, 0, 0) 100%
553
+ );
453
554
  }
454
555
 
455
- .ll-expanded__icon {
456
- width: 18px;
457
- height: 18px;
556
+ .ll-expanded__brand {
557
+ font-size: 14px;
558
+ font-weight: 600;
559
+ letter-spacing: -0.2px;
560
+ color: #fff;
561
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
562
+ }
563
+
564
+ .ll-expanded__header-actions {
565
+ display: flex;
566
+ gap: 6px;
458
567
  }
459
568
 
460
- /* Team menu dropdown */
461
- .ll-expanded__team-menu {
569
+ /* ── Active top bar (pills) ─────────────────────────────────── */
570
+
571
+ .ll-expanded__topbar {
462
572
  position: absolute;
463
- top: 56px;
464
- left: 16px;
465
- right: 16px;
466
- max-width: 280px;
467
- background: var(--ll-color-bg);
468
- border: 1px solid var(--ll-color-border);
469
- border-radius: var(--ll-radius-card);
470
- box-shadow: var(--ll-shadow-card);
471
- overflow: hidden;
472
- z-index: 10;
573
+ top: 12px;
574
+ left: 12px;
575
+ right: 12px;
576
+ z-index: 3;
577
+ display: flex;
578
+ align-items: center;
579
+ justify-content: space-between;
580
+ gap: 8px;
473
581
  }
474
582
 
475
- .ll-expanded__team-item {
583
+ .ll-expanded__topbar-left {
476
584
  display: flex;
477
585
  align-items: center;
478
- gap: 12px;
479
- padding: 10px 12px;
480
- width: 100%;
481
- text-align: left;
482
- transition: background var(--ll-transition-fast);
586
+ gap: 8px;
587
+ flex-wrap: wrap;
588
+ min-width: 0;
483
589
  }
484
- .ll-expanded__team-item:hover {
485
- background: var(--ll-color-border-subtle);
590
+
591
+ .ll-expanded__pill-wrap {
592
+ position: relative;
486
593
  }
487
- .ll-expanded__team-item--active {
488
- background: var(--ll-color-border-subtle);
594
+
595
+ /* Glass pill (header dropdown trigger) */
596
+ .ll-hpill {
597
+ display: inline-flex;
598
+ align-items: center;
599
+ gap: 6px;
600
+ height: 40px;
601
+ padding: 0 18px;
602
+ border-radius: 999px;
603
+ border: 1px solid rgba(255, 255, 255, 0.16);
604
+ background: rgba(0, 0, 0, 0.4);
605
+ -webkit-backdrop-filter: blur(20px);
606
+ backdrop-filter: blur(20px);
607
+ color: #fff;
608
+ font-family: inherit;
609
+ font-size: 15px;
610
+ font-weight: 500;
611
+ letter-spacing: -0.15px;
612
+ cursor: pointer;
613
+ transition: background 0.15s ease;
489
614
  }
490
615
 
491
- .ll-expanded__team-item-avatar {
492
- width: 36px;
493
- height: 36px;
494
- border-radius: 50%;
495
- object-fit: cover;
496
- flex-shrink: 0;
616
+ .ll-hpill:hover {
617
+ background: rgba(0, 0, 0, 0.55);
618
+ }
619
+
620
+ .ll-hpill__label {
621
+ white-space: nowrap;
622
+ overflow: hidden;
623
+ text-overflow: ellipsis;
624
+ max-width: 160px;
625
+ }
626
+
627
+ /* Ghost icon button (close / minimize) */
628
+ .ll-hbtn {
629
+ display: inline-flex;
630
+ align-items: center;
631
+ justify-content: center;
632
+ width: 40px;
633
+ height: 40px;
634
+ border-radius: 999px;
635
+ border: 1px solid rgba(255, 255, 255, 0.16);
636
+ background: rgba(0, 0, 0, 0.4);
637
+ -webkit-backdrop-filter: blur(20px);
638
+ backdrop-filter: blur(20px);
639
+ color: #fff;
640
+ cursor: pointer;
641
+ transition: background 0.15s ease;
642
+ padding: 0;
643
+ }
644
+
645
+ .ll-hbtn:hover {
646
+ background: rgba(0, 0, 0, 0.65);
497
647
  }
498
648
 
499
- .ll-expanded__team-item-meta {
649
+ .ll-hbtn--ghost {
650
+ background: rgba(0, 0, 0, 0.28);
651
+ }
652
+
653
+ /* Dropdown menu under a pill */
654
+ .ll-hmenu {
655
+ position: absolute;
656
+ top: calc(100% + 6px);
657
+ left: 0;
658
+ z-index: 20;
659
+ min-width: 200px;
660
+ padding: 6px;
661
+ border-radius: 14px;
662
+ border: 1px solid rgba(255, 255, 255, 0.14);
663
+ background: rgba(26, 26, 26, 0.96);
664
+ -webkit-backdrop-filter: blur(24px);
665
+ backdrop-filter: blur(24px);
666
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
500
667
  display: flex;
501
668
  flex-direction: column;
502
669
  gap: 2px;
503
- min-width: 0;
504
670
  }
505
671
 
506
- .ll-expanded__team-item-name {
672
+ .ll-hmenu__item {
673
+ display: flex;
674
+ align-items: center;
675
+ gap: 10px;
676
+ padding: 8px 10px;
677
+ border-radius: 10px;
678
+ border: none;
679
+ background: transparent;
680
+ color: rgba(255, 255, 255, 0.85);
681
+ font-family: inherit;
507
682
  font-size: 13px;
508
683
  font-weight: 500;
509
- color: var(--ll-color-fg);
510
- }
511
- .ll-expanded__team-item-role {
512
- font-size: 11px;
513
- color: var(--ll-color-muted);
684
+ text-align: left;
685
+ cursor: pointer;
686
+ transition: background 0.12s ease;
514
687
  }
515
688
 
516
- /* Avatar surface */
517
- .ll-expanded__avatar-surface {
518
- flex: 1;
519
- position: relative;
520
- background: linear-gradient(180deg, #e8e4df 0%, #d4cfc8 100%);
521
- overflow: hidden;
689
+ .ll-hmenu__item:hover {
690
+ background: rgba(255, 255, 255, 0.08);
522
691
  }
523
692
 
524
- .ll-expanded__avatar-image,
525
- .ll-expanded__avatar-idle-loop,
526
- .ll-expanded__avatar-live {
527
- position: absolute;
528
- inset: 0;
529
- width: 100%;
530
- height: 100%;
693
+ .ll-hmenu__item.is-active {
694
+ color: #fff;
695
+ background: rgba(255, 255, 255, 0.1);
531
696
  }
532
697
 
533
- .ll-expanded__avatar-idle-loop {
698
+ .ll-hmenu__avatar {
699
+ width: 24px;
700
+ height: 24px;
701
+ border-radius: 999px;
534
702
  object-fit: cover;
535
- object-position: top;
536
- z-index: 1;
703
+ flex-shrink: 0;
537
704
  }
538
705
 
539
- .ll-expanded__avatar-live {
540
- z-index: 2;
706
+ .ll-hmenu__name {
707
+ flex: 1;
541
708
  }
542
709
 
543
- .ll-expanded__avatar-live > video {
544
- width: 100%;
545
- height: 100%;
546
- object-fit: cover;
547
- object-position: top;
710
+ .ll-hmenu__role {
711
+ font-size: 11px;
712
+ font-weight: 500;
713
+ color: rgba(255, 255, 255, 0.5);
714
+ letter-spacing: -0.1px;
548
715
  }
549
716
 
550
- .ll-expanded__overlay {
717
+ /* Agent state word */
718
+ .ll-expanded__state {
719
+ font-size: 11px;
720
+ font-weight: 500;
721
+ letter-spacing: -0.1px;
722
+ text-transform: lowercase;
723
+ color: rgba(255, 255, 255, 0.6);
724
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
725
+ }
726
+
727
+ .ll-expanded__state--speaking { color: #68f5ff; }
728
+ .ll-expanded__state--thinking { color: #ffcd68; }
729
+
730
+ /* ── Idle play button ─────────────────────────────────────── */
731
+
732
+ .ll-expanded__play {
551
733
  position: absolute;
552
734
  inset: 0;
553
- z-index: 5;
735
+ z-index: 2;
554
736
  display: flex;
555
737
  flex-direction: column;
556
738
  align-items: center;
557
739
  justify-content: center;
558
- color: white;
559
740
  gap: 8px;
741
+ background: rgba(0, 0, 0, 0);
742
+ border: none;
743
+ color: #fff;
744
+ cursor: pointer;
745
+ padding: 0;
746
+ font-family: inherit;
747
+ transition: background 0.15s ease;
560
748
  }
561
749
 
562
- .ll-expanded__overlay--connecting,
563
- .ll-expanded__overlay--switching {
564
- background: rgba(0, 0, 0, 0.3);
565
- backdrop-filter: blur(2px);
566
- -webkit-backdrop-filter: blur(2px);
567
- }
568
-
569
- .ll-expanded__overlay--gesture,
570
- .ll-expanded__overlay--play {
571
- background: rgba(0, 0, 0, 0.4);
572
- backdrop-filter: blur(4px);
573
- -webkit-backdrop-filter: blur(4px);
574
- transition: background var(--ll-transition-fast);
575
- }
576
- .ll-expanded__overlay--gesture:hover,
577
- .ll-expanded__overlay--play:hover {
578
- background: rgba(0, 0, 0, 0.5);
579
- }
750
+ .ll-expanded__play:hover { background: rgba(0, 0, 0, 0.1); }
580
751
 
581
752
  .ll-expanded__play-circle {
582
- width: 64px;
583
- height: 64px;
584
- border-radius: 50%;
585
- background: rgba(255, 255, 255, 0.95);
586
- color: var(--ll-color-primary);
587
753
  display: flex;
588
754
  align-items: center;
589
755
  justify-content: center;
590
- transition: transform var(--ll-transition-fast);
756
+ width: 64px;
757
+ height: 64px;
758
+ border-radius: 999px;
759
+ background: rgba(0, 0, 0, 0.55);
760
+ -webkit-backdrop-filter: blur(8px);
761
+ backdrop-filter: blur(8px);
762
+ color: #fff;
763
+ padding-left: 3px; /* optical center the triangle */
764
+ transition: transform 0.15s ease, background 0.15s ease;
591
765
  }
592
- .ll-expanded__overlay--play:hover .ll-expanded__play-circle {
593
- transform: scale(1.1);
766
+
767
+ .ll-expanded__play:hover .ll-expanded__play-circle {
768
+ transform: scale(1.08);
769
+ background: rgba(0, 0, 0, 0.75);
594
770
  }
595
771
 
596
- .ll-expanded__overlay-text {
772
+ .ll-expanded__play-label {
597
773
  font-size: 14px;
598
- font-weight: 500;
599
- color: white;
600
- margin: 0;
774
+ font-weight: 600;
775
+ letter-spacing: -0.2px;
776
+ color: #fff;
777
+ text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
601
778
  }
602
779
 
603
- .ll-expanded__overlay-subtext {
780
+ .ll-expanded__play-sublabel {
604
781
  font-size: 12px;
782
+ font-weight: 500;
605
783
  color: rgba(255, 255, 255, 0.75);
606
- margin: 0;
784
+ letter-spacing: -0.15px;
785
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
607
786
  }
608
787
 
609
- .ll-expanded__spinner {
610
- width: 32px;
611
- height: 32px;
612
- border: 2px solid rgba(255, 255, 255, 0.3);
613
- border-top-color: white;
614
- border-radius: 50%;
615
- animation: ll-spin 1s linear infinite;
788
+ /* ── Local PIP (camera / screen share) ──────────────────── */
789
+
790
+ .ll-expanded__pip {
791
+ position: absolute;
792
+ right: 12px;
793
+ bottom: 160px;
794
+ z-index: 5;
795
+ width: 110px;
796
+ height: 82px;
797
+ border-radius: 10px;
798
+ overflow: hidden;
799
+ border: 1px solid rgba(255, 255, 255, 0.2);
800
+ background: #000;
801
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
802
+ opacity: 0;
803
+ pointer-events: none;
804
+ transition: opacity 0.2s ease;
616
805
  }
617
806
 
618
- .ll-expanded__spinner--small {
619
- width: 16px;
620
- height: 16px;
621
- border-width: 2px;
622
- border-top-color: currentColor;
623
- border-color: rgba(13, 13, 13, 0.2);
624
- border-top-color: var(--ll-color-primary);
807
+ .ll-expanded__pip.is-visible {
808
+ opacity: 1;
809
+ pointer-events: auto;
625
810
  }
626
811
 
627
- @keyframes ll-spin {
628
- to {
629
- transform: rotate(360deg);
630
- }
812
+ .ll-expanded__pip-host {
813
+ width: 100%;
814
+ height: 100%;
631
815
  }
632
816
 
633
- .ll-expanded__state-pill-wrap {
634
- position: absolute;
635
- top: 12px;
636
- right: 12px;
637
- z-index: 6;
817
+ .ll-expanded__pip-host.is-hidden {
818
+ display: none;
638
819
  }
639
820
 
640
- .ll-expanded__mic-error {
821
+ /* ── Bottom stack (transcript + toolbar + input) ─────────── */
822
+
823
+ .ll-expanded__bottom {
641
824
  position: absolute;
642
- top: 48px;
643
825
  left: 12px;
644
826
  right: 12px;
645
- z-index: 6;
827
+ bottom: 12px;
828
+ z-index: 3;
646
829
  display: flex;
647
- align-items: center;
830
+ flex-direction: column;
648
831
  gap: 8px;
649
- padding: 8px 12px;
650
- background: rgba(239, 68, 68, 0.9);
651
- color: white;
652
- border-radius: 8px;
653
- font-size: 12px;
654
832
  }
655
833
 
656
- .ll-expanded__mic-error button {
657
- color: white;
658
- font-size: 11px;
659
- font-weight: 500;
660
- text-decoration: underline;
661
- white-space: nowrap;
834
+ .ll-expanded__bottom--idle {
835
+ /* When not yet active, render just transcript / greeting */
836
+ gap: 0;
662
837
  }
663
838
 
664
839
  .ll-expanded__transcript {
665
- position: absolute;
666
- bottom: 12px;
667
- left: 12px;
668
- right: 12px;
669
- z-index: 6;
670
- padding: 10px 14px;
671
- background: rgba(13, 13, 13, 0.45);
672
- backdrop-filter: blur(8px);
673
- -webkit-backdrop-filter: blur(8px);
674
- border-radius: 12px;
675
- color: white;
840
+ padding: 10px 16px;
841
+ border-radius: 14px;
842
+ background: rgba(0, 0, 0, 0.4);
843
+ -webkit-backdrop-filter: blur(14px);
844
+ backdrop-filter: blur(14px);
676
845
  }
677
846
 
678
- .ll-expanded__transcript p {
847
+ .ll-expanded__transcript-text {
679
848
  margin: 0;
680
- font-size: 14px;
681
- font-weight: 500;
849
+ font-size: 13px;
682
850
  line-height: 1.45;
851
+ color: #fff;
852
+ letter-spacing: -0.15px;
683
853
  display: -webkit-box;
684
- -webkit-line-clamp: 3;
854
+ -webkit-line-clamp: 2;
685
855
  -webkit-box-orient: vertical;
686
856
  overflow: hidden;
687
857
  }
688
858
 
689
- /* Footer CTA */
690
- .ll-expanded__footer {
691
- padding: 12px 16px;
692
- flex-shrink: 0;
693
- }
859
+ /* ── Toolbar (mic / camera / screen / speaker) ──────────── */
694
860
 
695
- .ll-expanded__cta {
696
- width: 100%;
697
- padding: 12px 16px;
698
- border-radius: var(--ll-radius-pill);
699
- font-size: 14px;
700
- font-weight: 500;
861
+ .ll-toolbar {
701
862
  display: flex;
702
863
  align-items: center;
703
864
  justify-content: center;
865
+ gap: 4px;
866
+ flex-wrap: wrap;
867
+ }
868
+
869
+ .ll-tool {
870
+ display: inline-flex;
871
+ align-items: center;
872
+ justify-content: center;
873
+ width: 40px;
874
+ height: 40px;
875
+ border-radius: 999px;
876
+ border: 1px solid rgba(255, 255, 255, 0.16);
877
+ background: rgba(0, 0, 0, 0.4);
878
+ -webkit-backdrop-filter: blur(20px);
879
+ backdrop-filter: blur(20px);
880
+ color: rgba(255, 255, 255, 0.85);
881
+ cursor: pointer;
882
+ transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
883
+ padding: 0;
884
+ }
885
+
886
+ .ll-tool:hover {
887
+ color: #fff;
888
+ background: rgba(0, 0, 0, 0.55);
889
+ }
890
+
891
+ .ll-tool.is-on {
892
+ background: rgba(255, 255, 255, 0.2);
893
+ border-color: rgba(255, 255, 255, 0.4);
894
+ color: #fff;
895
+ }
896
+
897
+ .ll-tool.is-muted {
898
+ background: rgba(239, 68, 68, 0.6);
899
+ border-color: rgba(248, 113, 113, 0.4);
900
+ color: #fff;
901
+ }
902
+
903
+ /* Split button: left = toggle, right = device menu */
904
+ .ll-tool-split {
905
+ position: relative;
906
+ display: inline-flex;
907
+ align-items: center;
908
+ height: 40px;
909
+ border-radius: 999px;
910
+ overflow: hidden;
911
+ background: rgba(0, 0, 0, 0.4);
912
+ border: 1px solid rgba(255, 255, 255, 0.16);
913
+ -webkit-backdrop-filter: blur(20px);
914
+ backdrop-filter: blur(20px);
915
+ }
916
+
917
+ .ll-tool-split .ll-tool {
918
+ background: transparent;
919
+ border: none;
920
+ border-radius: 0;
921
+ height: 100%;
922
+ -webkit-backdrop-filter: none;
923
+ backdrop-filter: none;
924
+ }
925
+
926
+ .ll-tool-split .ll-tool--left {
927
+ padding-left: 14px;
928
+ padding-right: 4px;
929
+ width: auto;
930
+ }
931
+
932
+ .ll-tool-split .ll-tool--right {
933
+ padding-left: 4px;
934
+ padding-right: 10px;
935
+ width: auto;
936
+ color: rgba(255, 255, 255, 0.7);
937
+ }
938
+
939
+ .ll-tool-split:has(.is-on) {
940
+ background: rgba(255, 255, 255, 0.2);
941
+ border-color: rgba(255, 255, 255, 0.4);
942
+ }
943
+
944
+ .ll-tool-split:has(.is-muted) {
945
+ background: rgba(239, 68, 68, 0.6);
946
+ border-color: rgba(248, 113, 113, 0.4);
947
+ }
948
+
949
+ /* ── Device selection menu (mic / camera) ───────────────── */
950
+
951
+ .ll-device-menu {
952
+ position: absolute;
953
+ bottom: calc(100% + 8px);
954
+ left: 50%;
955
+ transform: translateX(-50%);
956
+ min-width: 220px;
957
+ padding: 6px;
958
+ border-radius: 12px;
959
+ border: 1px solid rgba(255, 255, 255, 0.14);
960
+ background: rgba(26, 26, 26, 0.96);
961
+ -webkit-backdrop-filter: blur(24px);
962
+ backdrop-filter: blur(24px);
963
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
964
+ z-index: 30;
965
+ display: flex;
966
+ flex-direction: column;
967
+ gap: 2px;
968
+ }
969
+
970
+ .ll-device-menu__label {
971
+ margin: 0;
972
+ padding: 6px 10px 4px;
973
+ font-size: 10px;
974
+ font-weight: 600;
975
+ letter-spacing: 0.08em;
976
+ text-transform: uppercase;
977
+ color: rgba(255, 255, 255, 0.4);
978
+ }
979
+
980
+ .ll-device-menu__item {
981
+ display: flex;
982
+ align-items: center;
704
983
  gap: 8px;
705
- transition: opacity var(--ll-transition-fast),
706
- background var(--ll-transition-fast);
984
+ padding: 8px 10px;
985
+ border-radius: 8px;
986
+ border: none;
987
+ background: transparent;
988
+ color: rgba(255, 255, 255, 0.75);
989
+ text-align: left;
990
+ font-family: inherit;
991
+ font-size: 12px;
992
+ font-weight: 500;
993
+ cursor: pointer;
994
+ transition: background 0.12s ease;
707
995
  }
708
996
 
709
- .ll-expanded__cta--primary {
710
- background: var(--ll-color-primary);
711
- color: white;
997
+ .ll-device-menu__item:hover {
998
+ background: rgba(255, 255, 255, 0.08);
712
999
  }
713
- .ll-expanded__cta--primary:hover {
714
- opacity: 0.88;
1000
+
1001
+ .ll-device-menu__item.is-active {
1002
+ color: #fff;
715
1003
  }
716
1004
 
717
- .ll-expanded__cta--loading {
718
- background: var(--ll-color-border-subtle);
719
- color: var(--ll-color-muted);
720
- opacity: 0.7;
1005
+ .ll-device-menu__dot {
1006
+ color: rgba(255, 255, 255, 0.8);
1007
+ }
1008
+
1009
+ .ll-device-menu__name {
1010
+ flex: 1;
1011
+ }
1012
+
1013
+ /* ── Message input ──────────────────────────────────────── */
1014
+
1015
+ .ll-message-input {
1016
+ height: 40px;
1017
+ border-radius: 999px;
1018
+ background: rgba(0, 0, 0, 0.4);
1019
+ -webkit-backdrop-filter: blur(20px);
1020
+ backdrop-filter: blur(20px);
1021
+ border: 1px solid rgba(255, 255, 255, 0.16);
1022
+ display: flex;
1023
+ align-items: center;
1024
+ padding: 0 6px 0 18px;
1025
+ gap: 8px;
721
1026
  }
722
1027
 
723
- .ll-expanded__cta--danger {
1028
+ .ll-message-input__field {
1029
+ flex: 1;
1030
+ min-width: 0;
724
1031
  background: transparent;
725
- color: var(--ll-color-danger);
726
- border: 1px solid rgba(239, 68, 68, 0.3);
1032
+ border: none;
1033
+ outline: none;
1034
+ color: #fff;
1035
+ font-family: inherit;
1036
+ font-size: 14px;
1037
+ font-weight: 500;
1038
+ letter-spacing: -0.14px;
727
1039
  }
728
- .ll-expanded__cta--danger:hover {
729
- background: var(--ll-color-danger);
730
- color: white;
1040
+
1041
+ .ll-message-input__field::placeholder {
1042
+ color: rgba(255, 255, 255, 0.5);
731
1043
  }
732
1044
 
733
- .ll-expanded__cta-icon {
734
- width: 18px;
735
- height: 18px;
1045
+ .ll-message-input__send {
1046
+ display: inline-flex;
1047
+ align-items: center;
1048
+ justify-content: center;
1049
+ width: 28px;
1050
+ height: 28px;
1051
+ border-radius: 999px;
1052
+ border: none;
1053
+ background: rgba(255, 255, 255, 0.18);
1054
+ color: #fff;
1055
+ cursor: pointer;
1056
+ transition: background 0.12s ease;
1057
+ }
1058
+
1059
+ .ll-message-input__send:hover {
1060
+ background: rgba(255, 255, 255, 0.3);
736
1061
  }
737
1062
 
738
- .ll-expanded__retry {
739
- text-align: center;
1063
+ /* ── End conversation (small secondary button) ──────────── */
1064
+
1065
+ .ll-expanded__end {
1066
+ align-self: center;
1067
+ padding: 6px 14px;
1068
+ border-radius: 999px;
1069
+ border: 1px solid rgba(255, 255, 255, 0.12);
1070
+ background: rgba(0, 0, 0, 0.3);
1071
+ -webkit-backdrop-filter: blur(14px);
1072
+ backdrop-filter: blur(14px);
1073
+ color: rgba(255, 255, 255, 0.7);
1074
+ font-family: inherit;
1075
+ font-size: 11px;
1076
+ font-weight: 500;
1077
+ letter-spacing: -0.1px;
1078
+ cursor: pointer;
1079
+ transition: color 0.15s ease, background 0.15s ease;
740
1080
  }
741
- .ll-expanded__error-text {
1081
+
1082
+ .ll-expanded__end:hover {
1083
+ color: #fff;
1084
+ background: rgba(0, 0, 0, 0.45);
1085
+ }
1086
+
1087
+ /* ── Error banners ──────────────────────────────────────── */
1088
+
1089
+ .ll-expanded__banner {
1090
+ position: absolute;
1091
+ bottom: 210px;
1092
+ left: 12px;
1093
+ right: 12px;
1094
+ z-index: 6;
1095
+ display: flex;
1096
+ align-items: center;
1097
+ gap: 10px;
1098
+ padding: 10px 14px;
1099
+ border-radius: 12px;
1100
+ background: rgba(0, 0, 0, 0.7);
1101
+ -webkit-backdrop-filter: blur(16px);
1102
+ backdrop-filter: blur(16px);
1103
+ color: #fff;
742
1104
  font-size: 12px;
743
- color: var(--ll-color-danger);
744
- margin: 0 0 8px;
1105
+ font-weight: 500;
1106
+ letter-spacing: -0.12px;
1107
+ }
1108
+
1109
+ .ll-expanded__banner--error {
1110
+ background: rgba(180, 35, 35, 0.85);
1111
+ }
1112
+
1113
+ .ll-expanded__banner-x {
1114
+ margin-left: auto;
1115
+ width: 20px;
1116
+ height: 20px;
1117
+ border: none;
1118
+ background: transparent;
1119
+ color: rgba(255, 255, 255, 0.7);
1120
+ font-size: 18px;
1121
+ line-height: 1;
1122
+ cursor: pointer;
1123
+ }
1124
+
1125
+ .ll-expanded__banner-retry {
1126
+ margin-left: auto;
1127
+ padding: 4px 12px;
1128
+ border-radius: 999px;
1129
+ border: none;
1130
+ background: rgba(255, 255, 255, 0.2);
1131
+ color: #fff;
1132
+ font-family: inherit;
1133
+ font-size: 12px;
1134
+ font-weight: 500;
1135
+ cursor: pointer;
1136
+ transition: background 0.12s ease;
1137
+ }
1138
+
1139
+ .ll-expanded__banner-retry:hover {
1140
+ background: rgba(255, 255, 255, 0.3);
1141
+ }
1142
+
1143
+ /* Mobile: tighten paddings so controls fit and avoid notch overlap. */
1144
+ .ll-expanded--mobile .ll-expanded__topbar {
1145
+ top: max(12px, env(safe-area-inset-top));
1146
+ left: 10px;
1147
+ right: 10px;
1148
+ }
1149
+
1150
+ .ll-expanded--mobile .ll-expanded__bottom {
1151
+ left: 10px;
1152
+ right: 10px;
1153
+ bottom: max(10px, env(safe-area-inset-bottom));
1154
+ }
1155
+
1156
+ .ll-expanded--mobile .ll-expanded__pip {
1157
+ right: 10px;
1158
+ width: 96px;
1159
+ height: 72px;
745
1160
  }
746
1161
 
747
1162
  /* ── Error boundary fallback ─────────────────────────────────── */