@livelayer/react 0.2.0 → 0.2.1

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