ttp-agent-sdk 2.34.8 → 2.34.10

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.
@@ -12236,6 +12236,10 @@ var AgentSDK = /*#__PURE__*/function () {
12236
12236
  _this.onAgentSpeaking(true);
12237
12237
  // Call audio start playing hook
12238
12238
  _this.onAudioStartPlaying();
12239
+ // Call playback started callback if set
12240
+ if (_this.onPlaybackStarted && typeof _this.onPlaybackStarted === 'function') {
12241
+ _this.onPlaybackStarted();
12242
+ }
12239
12243
  });
12240
12244
  this.voiceSDK.on('playbackStopped', function () {
12241
12245
  _this.onAgentSpeaking(false);
@@ -15707,6 +15711,17 @@ var VoiceInterface = /*#__PURE__*/function () {
15707
15711
  _this.updateTranscript(text);
15708
15712
  };
15709
15713
 
15714
+ // Handle playback started - update status to "listening" when audio actually plays
15715
+ this.sdk.onPlaybackStarted = function () {
15716
+ console.log('🔊 [VOICE INTERFACE] Playback started - updating status to listening');
15717
+ if (_this.isMobile) {
15718
+ _this.updateMobileStatus('listening');
15719
+ } else {
15720
+ // Desktop: update status to listening
15721
+ _this.updateDesktopStatus();
15722
+ }
15723
+ };
15724
+
15710
15725
  // Handle agent speaking state
15711
15726
  this.sdk.onAgentSpeaking = function (isStart) {
15712
15727
  var avatar = _this.shadowRoot.getElementById('voiceAvatarActive');
@@ -16432,11 +16447,6 @@ var VoiceInterface = /*#__PURE__*/function () {
16432
16447
  _context5.n = 15;
16433
16448
  break;
16434
16449
  }
16435
- // ✅ Connection is ready (hello_ack received) - update status BEFORE audio can start
16436
- // This ensures status is "listening" when agent starts speaking
16437
- if (this.isMobile) {
16438
- this.updateMobileStatus('listening');
16439
- }
16440
16450
  return _context5.a(3, 17);
16441
16451
  case 15:
16442
16452
  _context5.n = 16;
@@ -16477,15 +16487,8 @@ var VoiceInterface = /*#__PURE__*/function () {
16477
16487
  }
16478
16488
  console.log('✅ WebSocket ready, starting listening...');
16479
16489
 
16480
- // CRITICAL: Update status to "listening" IMMEDIATELY after hello_ack
16481
- // This ensures status is correct BEFORE agent starts sending audio
16482
- // Agent can start sending audio immediately after hello_ack, so we need
16483
- // to update status now, not after startListening() completes
16484
- if (this.isMobile) {
16485
- // Status was already updated to "listening" in the hello_ack wait loop above
16486
- // But ensure it's set here too in case we didn't go through that path
16487
- this.updateMobileStatus('listening');
16488
- }
16490
+ // Keep status as "connecting" until audio actually starts playing
16491
+ // Status will be updated to "listening" when playbackStarted event fires
16489
16492
 
16490
16493
  // CRITICAL: startListening() will request microphone permission
16491
16494
  // This must be called directly from user interaction (button click)
@@ -16541,12 +16544,13 @@ var VoiceInterface = /*#__PURE__*/function () {
16541
16544
  }
16542
16545
  // Start waveform animation
16543
16546
  this.startWaveformAnimation();
16544
- // Update status to listening (was connecting before)
16545
- this.updateMobileStatus('listening');
16547
+ // Keep status as "connecting" until audio actually plays
16548
+ // Status will be updated to "listening" when playbackStarted event fires
16546
16549
  } else {
16547
16550
  // Desktop: initialize UI
16548
16551
  this.startDesktopWaveformAnimation();
16549
- this.updateDesktopStatus();
16552
+ // Keep status as "connecting" until audio actually plays
16553
+ // Status will be updated to "listening" when playbackStarted event fires
16550
16554
  // Start live waveform animation interval (delegated to desktop module)
16551
16555
  this.desktop.startLiveWaveformInterval();
16552
16556
  }
@@ -16673,12 +16677,13 @@ var VoiceInterface = /*#__PURE__*/function () {
16673
16677
  }
16674
16678
  // Start waveform animation
16675
16679
  this.startWaveformAnimation();
16676
- // Update status to listening (was connecting before)
16677
- this.updateMobileStatus('listening');
16680
+ // Keep status as "connecting" until audio actually plays
16681
+ // Status will be updated to "listening" when playbackStarted event fires
16678
16682
  } else {
16679
16683
  // Desktop: initialize UI
16680
16684
  this.startDesktopWaveformAnimation();
16681
- this.updateDesktopStatus();
16685
+ // Keep status as "connecting" until audio actually plays
16686
+ // Status will be updated to "listening" when playbackStarted event fires
16682
16687
  // Start live waveform animation interval (delegated to desktop module)
16683
16688
  this.desktop.startLiveWaveformInterval();
16684
16689
  }
@@ -18856,7 +18861,7 @@ var Styles = /*#__PURE__*/function () {
18856
18861
  }, {
18857
18862
  key: "_getSharedMobileCSS",
18858
18863
  value: function _getSharedMobileCSS(important) {
18859
- return "\n .mobile-duration-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background-color: #ef4444;\n animation: mobilePulse 1.5s ease-in-out infinite;\n }\n\n @keyframes mobilePulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.95); }\n }\n\n .mobile-voice-bar {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 50%, #c084fc 100%);\n border-radius: 24px 24px 0 0;\n box-shadow: 0 -8px 32px rgba(124, 58, 237, 0.5), 0 -2px 8px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.2);\n width: 100%;\n max-width: 100%;\n pointer-events: auto;\n }\n\n .mobile-top-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n position: relative;\n }\n\n .mobile-status-indicator {\n display: flex;\n align-items: center;\n gap: 5px;\n min-width: 85px;\n }\n\n .mobile-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background-color: #22c55e;\n box-shadow: 0 0 8px #22c55e;\n transition: all 0.3s ease;\n }\n\n .mobile-status-text {\n font-size: 11px;\n font-weight: 700;\n color: rgba(255,255,255,0.95);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n }\n\n .mobile-waveform-center {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n height: 24px;\n }\n\n .mobile-waveform-bar {\n width: 4px;\n height: 4px;\n background-color: #fff;\n border-radius: 2px;\n transition: height 0.15s ease;\n box-shadow: 0 0 8px rgba(255,255,255,0.5);\n }\n\n .mobile-controls {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .mobile-control-btn {\n display: flex".concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n width: 32px").concat(important, ";\n height: 32px").concat(important, ";\n min-width: 32px").concat(important, ";\n min-height: 32px").concat(important, ";\n max-width: 32px").concat(important, ";\n max-height: 32px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n cursor: pointer").concat(important, ";\n transition: all 0.2s ease;\n background-color: rgba(255,255,255,0.15)").concat(important, ";\n position: relative").concat(important, ";\n overflow: hidden").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n\n .mobile-control-btn:hover {\n background-color: rgba(255,255,255,0.25)").concat(important, ";\n }\n\n .mobile-control-btn.muted {\n background-color: rgba(239, 68, 68, 0.3)").concat(important, ";\n }\n\n .mobile-control-btn svg {\n position: absolute").concat(important, ";\n top: 50%").concat(important, ";\n left: 50%").concat(important, ";\n transform: translate(-50%, -50%)").concat(important, ";\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n width: 15px").concat(important, ";\n height: 15px").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n }\n\n .mobile-mic-off-icon,\n .mobile-speaker-off-icon {\n display: none !important;\n }\n\n .mobile-control-btn.muted .mobile-mic-icon,\n .mobile-control-btn.muted .mobile-speaker-icon {\n display: none !important;\n }\n\n .mobile-control-btn.muted .mobile-mic-off-icon,\n .mobile-control-btn.muted .mobile-speaker-off-icon {\n display: block !important;\n }\n\n .mobile-end-call-btn {\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n width: 36px").concat(important, ";\n height: 36px").concat(important, ";\n min-width: 36px").concat(important, ";\n min-height: 36px").concat(important, ";\n max-width: 36px").concat(important, ";\n max-height: 36px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n cursor: pointer").concat(important, ";\n background-color: #ef4444").concat(important, ";\n box-shadow: 0 4px 14px rgba(239, 68, 68, 0.5);\n transition: all 0.2s ease;\n overflow: hidden").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n\n .mobile-end-call-btn svg {\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n width: 15px").concat(important, ";\n height: 15px").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n position: relative").concat(important, ";\n }\n\n /* ID-specific selectors for WordPress compatibility */\n #mobileMuteBtn.mobile-control-btn,\n #mobileSpeakerBtn.mobile-control-btn,\n #mobileEndCallBtn.mobile-end-call-btn {\n border-radius: 50% !important;\n overflow: hidden !important;\n }\n \n /* Mobile microphone button background color */\n #mobileMuteBtn.mobile-control-btn {\n background: ").concat(this.config.micButtonColor || this.config.controlButtonColor || '#FFFFFF').concat(important, ";\n }\n\n #mobileMuteBtn.mobile-control-btn,\n #mobileSpeakerBtn.mobile-control-btn {\n width: 32px !important;\n height: 32px !important;\n min-width: 32px !important;\n min-height: 32px !important;\n max-width: 32px !important;\n max-height: 32px !important;\n }\n\n #mobileEndCallBtn.mobile-end-call-btn {\n width: 36px !important;\n height: 36px !important;\n min-width: 36px !important;\n min-height: 36px !important;\n max-width: 36px !important;\n max-height: 36px !important;\n }\n\n #mobileMuteBtn.mobile-control-btn svg,\n #mobileSpeakerBtn.mobile-control-btn svg,\n #mobileEndCallBtn.mobile-end-call-btn svg {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 15px !important;\n height: 15px !important;\n margin: 0 !important;\n padding: 0 !important;\n }\n\n .mobile-end-call-btn:hover {\n transform: scale(1.05);\n }\n\n .mobile-transcript-row {\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n background: rgba(255,255,255,0.18);\n border-radius: 14px;\n border: none;\n cursor: pointer;\n text-align: left;\n backdrop-filter: blur(4px);\n transition: background 0.2s ease;\n }\n\n .mobile-transcript-row:hover {\n background: rgba(255,255,255,0.25);\n }\n\n .mobile-transcript-text {\n margin: 0;\n font-size: 13px;\n color: #fff;\n line-height: 1.4;\n font-weight: 500;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .mobile-transcript-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .mobile-expand-hint {\n font-size: 10px;\n color: rgba(255,255,255,0.6);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n font-weight: 600;\n }\n\n .mobile-transcript-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0,0,0,0.6);\n display: flex;\n align-items: flex-end;\n padding: 12px;\n z-index: 100000;\n pointer-events: auto;\n }\n\n .mobile-expanded-transcript {\n width: 100%;\n max-height: 75%;\n background: #fff;\n border-radius: 24px 24px 16px 16px;\n overflow: hidden;\n box-shadow: 0 -8px 40px rgba(0,0,0,0.3);\n display: flex;\n flex-direction: column;\n }\n\n .mobile-transcript-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 16px;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n flex-shrink: 0;\n }\n\n .mobile-header-left {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .mobile-header-status {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .mobile-header-status-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background-color: #22c55e;\n box-shadow: 0 0 6px #22c55e;\n }\n\n .mobile-header-status-text {\n font-size: 10px;\n font-weight: 700;\n color: rgba(255,255,255,0.9);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .mobile-header-duration {\n font-size: 10px;\n font-weight: 600;\n color: rgba(255,255,255,0.7);\n margin-left: 8px;\n }\n\n .mobile-transcript-label {\n font-size: 11px;\n font-weight: 800;\n color: rgba(255,255,255,0.7);\n letter-spacing: 1px;\n }\n\n .mobile-close-transcript-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: none;\n background: rgba(255,255,255,0.2);\n color: #fff;\n cursor: pointer;\n }\n\n .mobile-close-transcript-btn:hover {\n background: rgba(255,255,255,0.3);\n }\n\n .mobile-messages-container {\n flex: 1;\n padding: 16px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .mobile-message-bubble {\n max-width: 85%;\n padding: 12px 16px;\n border-radius: 18px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .mobile-message-bubble.assistant {\n align-self: flex-start;\n background-color: #f3f4f6;\n color: #374151;\n border-bottom-left-radius: 4px;\n }\n\n .mobile-message-bubble.user {\n align-self: flex-end;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n color: #fff;\n border-bottom-right-radius: 4px;\n }\n\n .mobile-input-area {\n padding: 12px 16px 16px;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n flex-shrink: 0;\n }\n\n .mobile-input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 4px 4px 16px;\n background: #fff;\n border-radius: 24px;\n border: 2px solid #e5e7eb;\n }\n\n .mobile-text-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 14px;\n color: #374151;\n background: transparent;\n padding: 10px 0;\n }\n\n .mobile-text-input::placeholder {\n color: #9ca3af;\n }\n\n .mobile-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n color: #fff;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .mobile-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n }\n\n .mobile-send-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .mobile-input-hint {\n margin: 8px 0 0;\n font-size: 11px;\n color: #9ca3af;\n text-align: center;\n transition: color 0.2s ease;\n }\n\n /* Mobile text input status states */\n .mobile-input-hint--sending {\n color: #666;\n }\n\n .mobile-input-hint--success {\n color: #28a745;\n }\n\n .mobile-input-hint--queued {\n color: #ffc107;\n }\n\n .mobile-input-hint--error {\n color: #dc3545;\n }\n\n /* Disabled mobile input styling */\n #mobileTextInput:disabled {\n background-color: #f5f5f5;\n cursor: not-allowed;\n }\n\n #mobileSendBtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n ");
18864
+ return "\n .mobile-duration-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background-color: #ef4444;\n animation: mobilePulse 1.5s ease-in-out infinite;\n }\n\n @keyframes mobilePulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.95); }\n }\n\n .mobile-voice-bar {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 50%, #c084fc 100%);\n border-radius: 24px 24px 0 0;\n box-shadow: 0 -8px 32px rgba(124, 58, 237, 0.5), 0 -2px 8px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.2);\n width: 100%;\n max-width: 100%;\n pointer-events: auto;\n }\n\n .mobile-top-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n position: relative;\n }\n\n .mobile-status-indicator {\n display: flex;\n align-items: center;\n gap: 5px;\n min-width: 85px;\n }\n\n .mobile-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background-color: #22c55e;\n box-shadow: 0 0 8px #22c55e;\n transition: all 0.3s ease;\n }\n\n .mobile-status-text {\n font-size: 11px;\n font-weight: 700;\n color: rgba(255,255,255,0.95);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n }\n\n .mobile-waveform-center {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n height: 24px;\n }\n\n .mobile-waveform-bar {\n width: 4px;\n height: 4px;\n background-color: #fff;\n border-radius: 2px;\n transition: height 0.15s ease;\n box-shadow: 0 0 8px rgba(255,255,255,0.5);\n }\n\n .mobile-controls {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .mobile-control-btn {\n display: flex".concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n width: 32px").concat(important, ";\n height: 32px").concat(important, ";\n min-width: 32px").concat(important, ";\n min-height: 32px").concat(important, ";\n max-width: 32px").concat(important, ";\n max-height: 32px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n cursor: pointer").concat(important, ";\n transition: all 0.2s ease;\n background-color: rgba(255,255,255,0.15)").concat(important, ";\n position: relative").concat(important, ";\n overflow: hidden").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n\n .mobile-control-btn:hover {\n background-color: rgba(255,255,255,0.25)").concat(important, ";\n }\n\n .mobile-control-btn.muted {\n background-color: rgba(239, 68, 68, 0.3)").concat(important, ";\n }\n\n .mobile-control-btn svg {\n position: absolute").concat(important, ";\n top: 50%").concat(important, ";\n left: 50%").concat(important, ";\n transform: translate(-50%, -50%)").concat(important, ";\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n width: 15px").concat(important, ";\n height: 15px").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n }\n\n .mobile-mic-off-icon,\n .mobile-speaker-off-icon {\n display: none !important;\n }\n\n .mobile-control-btn.muted .mobile-mic-icon,\n .mobile-control-btn.muted .mobile-speaker-icon {\n display: none !important;\n }\n\n .mobile-control-btn.muted .mobile-mic-off-icon,\n .mobile-control-btn.muted .mobile-speaker-off-icon {\n display: block !important;\n }\n\n .mobile-end-call-btn {\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n width: 36px").concat(important, ";\n height: 36px").concat(important, ";\n min-width: 36px").concat(important, ";\n min-height: 36px").concat(important, ";\n max-width: 36px").concat(important, ";\n max-height: 36px").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n cursor: pointer").concat(important, ";\n background-color: #ef4444").concat(important, ";\n box-shadow: 0 4px 14px rgba(239, 68, 68, 0.5);\n transition: all 0.2s ease;\n overflow: hidden").concat(important, ";\n padding: 0").concat(important, ";\n margin: 0").concat(important, ";\n box-sizing: border-box").concat(important, ";\n }\n\n .mobile-end-call-btn svg {\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n width: 15px").concat(important, ";\n height: 15px").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n position: relative").concat(important, ";\n }\n\n /* ID-specific selectors for WordPress compatibility */\n #mobileMuteBtn.mobile-control-btn,\n #mobileSpeakerBtn.mobile-control-btn,\n #mobileEndCallBtn.mobile-end-call-btn {\n border-radius: 50% !important;\n overflow: hidden !important;\n }\n\n #mobileMuteBtn.mobile-control-btn,\n #mobileSpeakerBtn.mobile-control-btn {\n width: 32px !important;\n height: 32px !important;\n min-width: 32px !important;\n min-height: 32px !important;\n max-width: 32px !important;\n max-height: 32px !important;\n }\n\n #mobileEndCallBtn.mobile-end-call-btn {\n width: 36px !important;\n height: 36px !important;\n min-width: 36px !important;\n min-height: 36px !important;\n max-width: 36px !important;\n max-height: 36px !important;\n }\n\n #mobileMuteBtn.mobile-control-btn svg,\n #mobileSpeakerBtn.mobile-control-btn svg,\n #mobileEndCallBtn.mobile-end-call-btn svg {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 15px !important;\n height: 15px !important;\n margin: 0 !important;\n padding: 0 !important;\n }\n\n .mobile-end-call-btn:hover {\n transform: scale(1.05);\n }\n\n .mobile-transcript-row {\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n background: rgba(255,255,255,0.18);\n border-radius: 14px;\n border: none;\n cursor: pointer;\n text-align: left;\n backdrop-filter: blur(4px);\n transition: background 0.2s ease;\n }\n\n .mobile-transcript-row:hover {\n background: rgba(255,255,255,0.25);\n }\n\n .mobile-transcript-text {\n margin: 0;\n font-size: 13px;\n color: #fff;\n line-height: 1.4;\n font-weight: 500;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .mobile-transcript-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .mobile-expand-hint {\n font-size: 10px;\n color: rgba(255,255,255,0.6);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n font-weight: 600;\n }\n\n .mobile-transcript-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0,0,0,0.6);\n display: flex;\n align-items: flex-end;\n padding: 12px;\n z-index: 100000;\n pointer-events: auto;\n }\n\n .mobile-expanded-transcript {\n width: 100%;\n max-height: 75%;\n background: #fff;\n border-radius: 24px 24px 16px 16px;\n overflow: hidden;\n box-shadow: 0 -8px 40px rgba(0,0,0,0.3);\n display: flex;\n flex-direction: column;\n }\n\n .mobile-transcript-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 16px;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n flex-shrink: 0;\n }\n\n .mobile-header-left {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .mobile-header-status {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .mobile-header-status-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background-color: #22c55e;\n box-shadow: 0 0 6px #22c55e;\n }\n\n .mobile-header-status-text {\n font-size: 10px;\n font-weight: 700;\n color: rgba(255,255,255,0.9);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .mobile-header-duration {\n font-size: 10px;\n font-weight: 600;\n color: rgba(255,255,255,0.7);\n margin-left: 8px;\n }\n\n .mobile-transcript-label {\n font-size: 11px;\n font-weight: 800;\n color: rgba(255,255,255,0.7);\n letter-spacing: 1px;\n }\n\n .mobile-close-transcript-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: none;\n background: rgba(255,255,255,0.2);\n color: #fff;\n cursor: pointer;\n }\n\n .mobile-close-transcript-btn:hover {\n background: rgba(255,255,255,0.3);\n }\n\n .mobile-messages-container {\n flex: 1;\n padding: 16px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .mobile-message-bubble {\n max-width: 85%;\n padding: 12px 16px;\n border-radius: 18px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .mobile-message-bubble.assistant {\n align-self: flex-start;\n background-color: #f3f4f6;\n color: #374151;\n border-bottom-left-radius: 4px;\n }\n\n .mobile-message-bubble.user {\n align-self: flex-end;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n color: #fff;\n border-bottom-right-radius: 4px;\n }\n\n .mobile-input-area {\n padding: 12px 16px 16px;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n flex-shrink: 0;\n }\n\n .mobile-input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 4px 4px 16px;\n background: #fff;\n border-radius: 24px;\n border: 2px solid #e5e7eb;\n }\n\n .mobile-text-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 14px;\n color: #374151;\n background: transparent;\n padding: 10px 0;\n }\n\n .mobile-text-input::placeholder {\n color: #9ca3af;\n }\n\n .mobile-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n color: #fff;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .mobile-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n }\n\n .mobile-send-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .mobile-input-hint {\n margin: 8px 0 0;\n font-size: 11px;\n color: #9ca3af;\n text-align: center;\n transition: color 0.2s ease;\n }\n\n /* Mobile text input status states */\n .mobile-input-hint--sending {\n color: #666;\n }\n\n .mobile-input-hint--success {\n color: #28a745;\n }\n\n .mobile-input-hint--queued {\n color: #ffc107;\n }\n\n .mobile-input-hint--error {\n color: #dc3545;\n }\n\n /* Disabled mobile input styling */\n #mobileTextInput:disabled {\n background-color: #f5f5f5;\n cursor: not-allowed;\n }\n\n #mobileSendBtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n ");
18860
18865
  }
18861
18866
 
18862
18867
  /**