ttp-agent-sdk 2.34.13 → 2.35.0

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.
@@ -9704,9 +9704,7 @@ var WebSocketManager = /*#__PURE__*/function (_EventEmitter) {
9704
9704
  // Store resolve/reject for later use
9705
9705
  _this2.connectResolve = resolve;
9706
9706
  _this2.connectReject = reject;
9707
-
9708
- // Get connection from singleton
9709
- var url = _this2.config.signedUrl || _this2.config.websocketUrl;
9707
+ var url = _this2.config.websocketUrl;
9710
9708
  _WebSocketSingleton_js__WEBPACK_IMPORTED_MODULE_1__["default"].getConnection(url, _this2.config).then(function (connection) {
9711
9709
  _this2.ws = connection;
9712
9710
 
@@ -9754,7 +9752,7 @@ var WebSocketManager = /*#__PURE__*/function (_EventEmitter) {
9754
9752
 
9755
9753
  // Use singleton's event forwarding
9756
9754
  var handleOpen = function handleOpen(event, url) {
9757
- var expectedUrl = _this3.config.signedUrl || _this3.config.websocketUrl;
9755
+ var expectedUrl = _this3.config.websocketUrl;
9758
9756
  if (url === expectedUrl) {
9759
9757
  _this3.isConnected = true;
9760
9758
  _this3.emit('connected');
@@ -9768,14 +9766,14 @@ var WebSocketManager = /*#__PURE__*/function (_EventEmitter) {
9768
9766
  }
9769
9767
  };
9770
9768
  var handleClose = function handleClose(event, url) {
9771
- var expectedUrl = _this3.config.signedUrl || _this3.config.websocketUrl;
9769
+ var expectedUrl = _this3.config.websocketUrl;
9772
9770
  if (url === expectedUrl) {
9773
9771
  _this3.isConnected = false;
9774
9772
  _this3.emit('disconnected', event);
9775
9773
  }
9776
9774
  };
9777
9775
  var handleError = function handleError(event, url) {
9778
- var expectedUrl = _this3.config.signedUrl || _this3.config.websocketUrl;
9776
+ var expectedUrl = _this3.config.websocketUrl;
9779
9777
  if (url === expectedUrl) {
9780
9778
  _this3.emit('error', event);
9781
9779
 
@@ -9788,7 +9786,7 @@ var WebSocketManager = /*#__PURE__*/function (_EventEmitter) {
9788
9786
  }
9789
9787
  };
9790
9788
  var handleMessage = function handleMessage(event, url) {
9791
- var expectedUrl = _this3.config.signedUrl || _this3.config.websocketUrl;
9789
+ var expectedUrl = _this3.config.websocketUrl;
9792
9790
  if (url === expectedUrl) {
9793
9791
  _this3.handleMessage(event);
9794
9792
  }
@@ -9824,7 +9822,7 @@ var WebSocketManager = /*#__PURE__*/function (_EventEmitter) {
9824
9822
  }
9825
9823
 
9826
9824
  // Release connection from singleton
9827
- var url = this.config.signedUrl || this.config.websocketUrl;
9825
+ var url = this.config.websocketUrl;
9828
9826
  if (url) {
9829
9827
  _WebSocketSingleton_js__WEBPACK_IMPORTED_MODULE_1__["default"].releaseConnection(url);
9830
9828
  }
@@ -10210,7 +10208,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
10210
10208
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10211
10209
  /**
10212
10210
  * CartSummary - Compact cart summary bar at the bottom of the ecommerce area.
10213
- * Shows item count and total. Hidden when cart is empty.
10211
+ * Shows item count, total, and a "View Cart" link. Hidden when cart is empty.
10214
10212
  */
10215
10213
  var CartSummary = /*#__PURE__*/function () {
10216
10214
  function CartSummary() {
@@ -10218,6 +10216,8 @@ var CartSummary = /*#__PURE__*/function () {
10218
10216
  this.element = null;
10219
10217
  this.itemCount = 0;
10220
10218
  this.total = 0;
10219
+ this.currency = '$';
10220
+ this.cartUrl = '/cart';
10221
10221
  }
10222
10222
  return _createClass(CartSummary, [{
10223
10223
  key: "render",
@@ -10225,19 +10225,20 @@ var CartSummary = /*#__PURE__*/function () {
10225
10225
  var el = document.createElement('div');
10226
10226
  el.className = 'ttp-cart-summary';
10227
10227
  el.style.display = 'none';
10228
- el.innerHTML = "\n <div class=\"ttp-cart-info\">\n <span class=\"ttp-cart-icon\">\uD83D\uDED2</span>\n <span class=\"ttp-cart-count\">0 items</span>\n </div>\n <span class=\"ttp-cart-total\">\u20AA0.00</span>\n ";
10228
+ el.innerHTML = "\n <div class=\"ttp-cart-info\">\n <span class=\"ttp-cart-icon\">\uD83D\uDED2</span>\n <span class=\"ttp-cart-count\">0 items</span>\n <span class=\"ttp-cart-separator\">\xB7</span>\n <span class=\"ttp-cart-total\">".concat(this.currency, "0.00</span>\n </div>\n <a class=\"ttp-cart-view\" href=\"").concat(this.cartUrl, "\" target=\"_top\">View Cart \u203A</a>\n ");
10229
10229
  this.element = el;
10230
10230
  return el;
10231
10231
  }
10232
10232
  }, {
10233
10233
  key: "update",
10234
- value: function update(itemCount, total) {
10234
+ value: function update(itemCount, total, currency) {
10235
10235
  this.itemCount = itemCount;
10236
10236
  this.total = total;
10237
+ if (currency) this.currency = currency;
10237
10238
  if (this.element) {
10238
10239
  this.element.style.display = itemCount > 0 ? 'flex' : 'none';
10239
10240
  this.element.querySelector('.ttp-cart-count').textContent = "".concat(itemCount, " item").concat(itemCount !== 1 ? 's' : '');
10240
- this.element.querySelector('.ttp-cart-total').textContent = "\u20AA".concat(total.toFixed(2));
10241
+ this.element.querySelector('.ttp-cart-total').textContent = "".concat(this.currency).concat(total.toFixed(2));
10241
10242
  }
10242
10243
  }
10243
10244
  }]);
@@ -10453,12 +10454,12 @@ var EcommerceManager = /*#__PURE__*/function () {
10453
10454
  return;
10454
10455
  }
10455
10456
  this._switchToCompactMode();
10456
- this._expandPanel();
10457
10457
  this._setContainerMode('products');
10458
10458
  this.productPicker.hide();
10459
10459
  var effectiveLayout = layout || (products.length <= 4 ? 'cards' : 'list');
10460
10460
  var pickerEl = this.productPicker.show(products, title, effectiveLayout);
10461
10461
  this.container.insertBefore(pickerEl, this.container.firstChild);
10462
+ this._expandPanelToFit(products.length, effectiveLayout);
10462
10463
  }
10463
10464
  }, {
10464
10465
  key: "handleCartUpdated",
@@ -10515,11 +10516,30 @@ var EcommerceManager = /*#__PURE__*/function () {
10515
10516
  }
10516
10517
  }
10517
10518
  }, {
10518
- key: "_expandPanel",
10519
- value: function _expandPanel() {
10519
+ key: "_expandPanelToFit",
10520
+ value: function _expandPanelToFit(productCount, layout) {
10520
10521
  if (!this.shadowRoot) return;
10521
10522
  var panel = this.shadowRoot.getElementById('text-chat-panel');
10522
- if (panel) panel.classList.add('ttp-panel-expanded');
10523
+ if (!panel) return;
10524
+
10525
+ // Compact voice bar: 62px (min-height from CSS)
10526
+ // Picker header: 40px (padding 10px*2 + title 16px + border 1px)
10527
+ // Picker outer margin: 20px (margin 8px*2 + border 2px + shadow)
10528
+ // Conversation area: 150px (transcript + input + padding)
10529
+ var chrome = 62 + 40 + 20 + 150;
10530
+ var productsHeight;
10531
+ if (layout === 'cards') {
10532
+ // Card: image 85 + details ~195 + border 2 = ~282px
10533
+ // Container padding: 24px (12px * 2) + breathing room
10534
+ productsHeight = 360;
10535
+ } else {
10536
+ // List item: ~58px each, container padding 20px
10537
+ productsHeight = Math.min(productCount * 58 + 20, 400);
10538
+ }
10539
+ var totalHeight = chrome + productsHeight;
10540
+ var clampedHeight = Math.min(Math.max(totalHeight, 450), 800);
10541
+ panel.classList.add('ttp-panel-expanded');
10542
+ panel.style.height = "".concat(clampedHeight, "px");
10523
10543
  }
10524
10544
  }, {
10525
10545
  key: "_shrinkPanel",
@@ -10880,6 +10900,7 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
10880
10900
  var _this = this;
10881
10901
  var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10882
10902
  _classCallCheck(this, TTPEcommerceWidget);
10903
+ console.log('[TTPEcommerceWidget] v2.35 initialized');
10883
10904
  this.partnerConfig = config.partner || {};
10884
10905
  this.cartConfig = config.cart || {};
10885
10906
  this.widget = new _widget_TTPChatWidget_js__WEBPACK_IMPORTED_MODULE_0__.TTPChatWidget(config);
@@ -10912,34 +10933,31 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
10912
10933
  }
10913
10934
  var self = this;
10914
10935
  var originalConnect = agentSDK.connect.bind(agentSDK);
10915
- agentSDK.connect = /*#__PURE__*/function () {
10916
- var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(signedUrl) {
10917
- return _regenerator().w(function (_context) {
10918
- while (1) switch (_context.n) {
10919
- case 0:
10920
- _context.n = 1;
10921
- return originalConnect(signedUrl);
10922
- case 1:
10923
- if (this.voiceSDK) {
10924
- this.voiceSDK.on('message', function (message) {
10925
- var type = message.t || message.type;
10926
- if (type === 'show_products') {
10927
- self.ecommerce.handleShowProducts(message);
10928
- } else if (type === 'cart_updated') {
10929
- self._handleCartUpdatedFromServer(message);
10930
- }
10931
- });
10932
- console.log('[TTPEcommerceWidget] E-commerce message listener attached');
10933
- }
10934
- case 2:
10935
- return _context.a(2);
10936
- }
10937
- }, _callee, this);
10938
- }));
10939
- return function (_x) {
10940
- return _ref.apply(this, arguments);
10941
- };
10942
- }();
10936
+ agentSDK.connect = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
10937
+ return _regenerator().w(function (_context) {
10938
+ while (1) switch (_context.n) {
10939
+ case 0:
10940
+ _context.n = 1;
10941
+ return originalConnect();
10942
+ case 1:
10943
+ if (this.voiceSDK) {
10944
+ this.voiceSDK.on('message', function (message) {
10945
+ var type = message.t || message.type;
10946
+ if (type === 'show_products') {
10947
+ self.ecommerce.handleShowProducts(message);
10948
+ } else if (type === 'cart_updated') {
10949
+ self._handleCartUpdatedFromServer(message);
10950
+ } else if (type === 'add_to_store_cart') {
10951
+ self._handleAddToStoreCart(message);
10952
+ }
10953
+ });
10954
+ console.log('[TTPEcommerceWidget] E-commerce message listener attached');
10955
+ }
10956
+ case 2:
10957
+ return _context.a(2);
10958
+ }
10959
+ }, _callee, this);
10960
+ }));
10943
10961
  }
10944
10962
 
10945
10963
  // ═══════════════════════════════════════════
@@ -10994,7 +11012,7 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
10994
11012
  }
10995
11013
  }, _callee2, null, [[0, 2]]);
10996
11014
  }));
10997
- return function (_x2) {
11015
+ return function (_x) {
10998
11016
  return _ref2.apply(this, arguments);
10999
11017
  };
11000
11018
  }());
@@ -11026,6 +11044,88 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
11026
11044
  }
11027
11045
 
11028
11046
  // ═══════════════════════════════════════════
11047
+ // SHOPIFY STORE CART (client-side via AJAX Cart API)
11048
+ // ═══════════════════════════════════════════
11049
+
11050
+ /**
11051
+ * Handle add_to_store_cart message from the backend.
11052
+ * Calls Shopify's /cart/add.js from the browser so the item goes into
11053
+ * the store's session-based cart (not a headless Storefront API cart).
11054
+ *
11055
+ * We don't attempt to refresh the theme's cart UI (icon badge, drawer)
11056
+ * because there's no universal mechanism — every theme is different.
11057
+ * The user will see the updated cart when they navigate to /cart or refresh.
11058
+ * Our own CartToast + CartSummary provide immediate visual feedback.
11059
+ */
11060
+ }, {
11061
+ key: "_handleAddToStoreCart",
11062
+ value: function () {
11063
+ var _handleAddToStoreCart2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(data) {
11064
+ var variantId, quantity, productName, price, _cartResponse$items, _cartResponse$items2, response, cartResponse, cartData, _t3;
11065
+ return _regenerator().w(function (_context4) {
11066
+ while (1) switch (_context4.p = _context4.n) {
11067
+ case 0:
11068
+ variantId = data.variantId, quantity = data.quantity, productName = data.productName, price = data.price;
11069
+ _context4.p = 1;
11070
+ _context4.n = 2;
11071
+ return fetch('/cart/add.js', {
11072
+ method: 'POST',
11073
+ headers: {
11074
+ 'Content-Type': 'application/json'
11075
+ },
11076
+ body: JSON.stringify({
11077
+ items: [{
11078
+ id: parseInt(variantId, 10),
11079
+ quantity: quantity || 1
11080
+ }]
11081
+ })
11082
+ });
11083
+ case 2:
11084
+ response = _context4.v;
11085
+ if (response.ok) {
11086
+ _context4.n = 3;
11087
+ break;
11088
+ }
11089
+ console.error('[TTPEcommerceWidget] Failed to add to Shopify cart:', response.status, response.statusText);
11090
+ return _context4.a(2);
11091
+ case 3:
11092
+ _context4.n = 4;
11093
+ return response.json();
11094
+ case 4:
11095
+ cartResponse = _context4.v;
11096
+ console.log('[TTPEcommerceWidget] Added to Shopify store cart:', cartResponse);
11097
+ _context4.n = 5;
11098
+ return fetch('/cart.js').then(function (r) {
11099
+ return r.json();
11100
+ });
11101
+ case 5:
11102
+ cartData = _context4.v;
11103
+ this._handleCartUpdatedFromServer({
11104
+ action: 'added',
11105
+ product: {
11106
+ id: variantId,
11107
+ name: productName || ((_cartResponse$items = cartResponse.items) === null || _cartResponse$items === void 0 || (_cartResponse$items = _cartResponse$items[0]) === null || _cartResponse$items === void 0 ? void 0 : _cartResponse$items.title) || 'Product',
11108
+ price: price || ((_cartResponse$items2 = cartResponse.items) === null || _cartResponse$items2 === void 0 || (_cartResponse$items2 = _cartResponse$items2[0]) === null || _cartResponse$items2 === void 0 ? void 0 : _cartResponse$items2.price) / 100 || 0
11109
+ },
11110
+ cartTotal: cartData.total_price / 100,
11111
+ cartItemCount: cartData.item_count
11112
+ });
11113
+ _context4.n = 7;
11114
+ break;
11115
+ case 6:
11116
+ _context4.p = 6;
11117
+ _t3 = _context4.v;
11118
+ console.error('[TTPEcommerceWidget] Error adding to Shopify cart:', _t3);
11119
+ case 7:
11120
+ return _context4.a(2);
11121
+ }
11122
+ }, _callee4, this, [[1, 6]]);
11123
+ }));
11124
+ function _handleAddToStoreCart(_x2) {
11125
+ return _handleAddToStoreCart2.apply(this, arguments);
11126
+ }
11127
+ return _handleAddToStoreCart;
11128
+ }() // ═══════════════════════════════════════════
11029
11129
  // PRODUCT SELECTION (server manages cart)
11030
11130
  // ═══════════════════════════════════════════
11031
11131
  }, {
@@ -11081,45 +11181,45 @@ var TTPEcommerceWidget = /*#__PURE__*/function () {
11081
11181
  self.ecommerce.handleMessage(payload);
11082
11182
  },
11083
11183
  showProducts: function () {
11084
- var _showProducts = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(query) {
11184
+ var _showProducts = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(query) {
11085
11185
  var limit,
11086
11186
  sessionId,
11087
11187
  baseUrl,
11088
11188
  response,
11089
11189
  data,
11090
- _args4 = arguments,
11091
- _t3;
11092
- return _regenerator().w(function (_context4) {
11093
- while (1) switch (_context4.p = _context4.n) {
11190
+ _args5 = arguments,
11191
+ _t4;
11192
+ return _regenerator().w(function (_context5) {
11193
+ while (1) switch (_context5.p = _context5.n) {
11094
11194
  case 0:
11095
- limit = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : 5;
11096
- sessionId = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : 'test';
11195
+ limit = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : 5;
11196
+ sessionId = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : 'test';
11097
11197
  baseUrl = window.__TTP_MOCK_API__ || 'https://backend.talktopc.com';
11098
- _context4.p = 1;
11099
- _context4.n = 2;
11198
+ _context5.p = 1;
11199
+ _context5.n = 2;
11100
11200
  return fetch("".concat(baseUrl, "/api/partner/mock-store/products/search?q=").concat(encodeURIComponent(query), "&limit=").concat(limit, "&sessionId=").concat(encodeURIComponent(sessionId)));
11101
11201
  case 2:
11102
- response = _context4.v;
11103
- _context4.n = 3;
11202
+ response = _context5.v;
11203
+ _context5.n = 3;
11104
11204
  return response.json();
11105
11205
  case 3:
11106
- data = _context4.v;
11206
+ data = _context5.v;
11107
11207
  self.ecommerce.handleShowProducts({
11108
11208
  t: 'show_products',
11109
11209
  products: data.products,
11110
11210
  title: "".concat(data.totalCount, " results for \"").concat(query, "\""),
11111
11211
  layout: data.products.length <= 4 ? 'cards' : 'list'
11112
11212
  });
11113
- _context4.n = 5;
11213
+ _context5.n = 5;
11114
11214
  break;
11115
11215
  case 4:
11116
- _context4.p = 4;
11117
- _t3 = _context4.v;
11118
- console.error('[TTPEcommerceWidget] showProducts failed:', _t3);
11216
+ _context5.p = 4;
11217
+ _t4 = _context5.v;
11218
+ console.error('[TTPEcommerceWidget] showProducts failed:', _t4);
11119
11219
  case 5:
11120
- return _context4.a(2);
11220
+ return _context5.a(2);
11121
11221
  }
11122
- }, _callee4, null, [[1, 4]]);
11222
+ }, _callee5, null, [[1, 4]]);
11123
11223
  }));
11124
11224
  function showProducts(_x3) {
11125
11225
  return _showProducts.apply(this, arguments);
@@ -11230,7 +11330,7 @@ __webpack_require__.r(__webpack_exports__);
11230
11330
  * Follows the same pattern as Styles.generateCSS().
11231
11331
  */
11232
11332
  function generateEcommerceCSS() {
11233
- return "\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ECOMMERCE AREA\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/*\n * When products are visible, expand the panel to 800px.\n * When the class is removed, the panel returns to its CSS-defined default.\n */\n#text-chat-panel.ttp-panel-expanded {\n height: 800px !important;\n}\n\n/*\n * Layout overrides when ecommerce layer is active.\n * voiceActiveState is a flex column: [voice-controls] [ecommerce] [conversation].\n * Ecommerce area fills the middle and scrolls; conversation panel stays at bottom.\n */\n#voiceActiveState {\n flex: 1 1 0 !important;\n min-height: 0 !important;\n overflow: hidden !important;\n}\n\n.desktop-voice-section {\n flex-shrink: 1 !important;\n}\n\n.desktop-conversation-panel {\n flex: 1 1 0 !important;\n min-height: 0 !important;\n display: flex !important;\n flex-direction: column !important;\n}\n\n.desktop-conversation-panel .live-transcript-collapsed {\n flex: 1 1 0 !important;\n min-height: 40px !important;\n overflow: hidden !important;\n}\n\n.desktop-conversation-panel .voice-text-input-area {\n margin-top: auto !important;\n padding: 3px 16px !important;\n}\n\n.desktop-conversation-panel .voice-input-hint {\n display: none !important;\n}\n\n#voiceActiveState.ttp-products-visible .desktop-voice-section {\n display: none !important;\n}\n\n#voiceActiveState.ttp-products-visible .compact-voice-section {\n display: flex !important;\n}\n\n#voiceActiveState.ttp-products-visible .desktop-conversation-panel {\n flex: 0 0 auto !important;\n}\n\n#voiceActiveState.ttp-products-visible .conversation-history {\n display: none !important;\n}\n\n#voiceActiveState.ttp-products-visible .live-transcript-collapsed {\n flex: 0 0 auto !important;\n}\n\n.voice-text-input-area {\n flex-shrink: 0 !important;\n}\n\n.conversation-history {\n flex: 1 1 0 !important;\n min-height: 0 !important;\n overflow-y: auto !important;\n}\n\n.ttp-ecommerce-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n flex: 1 1 0;\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n position: relative;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PRODUCT PICKER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-product-picker {\n background: #fff;\n border-radius: 14px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 6px 24px rgba(0,0,0,0.08);\n margin: 8px 12px;\n overflow: hidden;\n animation: ttpSlideUp 0.25s ease;\n display: flex;\n flex-direction: column;\n}\n\n@keyframes ttpSlideUp {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.ttp-picker-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 14px;\n border-bottom: 1px solid #f1f5f9;\n flex-shrink: 0;\n}\n\n.ttp-picker-title {\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n}\n\n.ttp-picker-close {\n background: none;\n border: none;\n cursor: pointer;\n color: #94a3b8;\n font-size: 14px;\n padding: 2px 6px;\n border-radius: 4px;\n}\n.ttp-picker-close:hover {\n background: #f1f5f9;\n color: #475569;\n}\n\n/* Horizontal card layout */\n.ttp-products-horizontal {\n display: flex;\n gap: 10px;\n padding: 12px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: thin;\n}\n.ttp-products-horizontal::-webkit-scrollbar { height: 4px; }\n.ttp-products-horizontal::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 2px; }\n\n/* Vertical list layout */\n.ttp-products-vertical {\n padding: 8px 12px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 6px;\n flex: 1;\n min-height: 0;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PRODUCT CARD (horizontal)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-product-card {\n width: 140px;\n flex-shrink: 0;\n background: #fff;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n overflow: hidden;\n transition: border-color 0.15s;\n}\n.ttp-product-card:hover { border-color: #3b82f6; }\n\n.ttp-product-image {\n height: 85px;\n background: #f8fafc;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n}\n.ttp-product-image img {\n max-width: 90%;\n max-height: 75px;\n object-fit: contain;\n}\n\n.ttp-stock-badge {\n position: absolute;\n top: 4px; right: 4px;\n background: #fef2f2;\n color: #ef4444;\n font-size: 9px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.ttp-product-details {\n padding: 8px 10px 10px;\n}\n\n.ttp-product-name {\n font-size: 12px;\n font-weight: 600;\n color: #1e293b;\n line-height: 1.3;\n min-height: 30px;\n}\n\n.ttp-product-meta {\n font-size: 10px;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.ttp-product-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: 6px;\n}\n\n.ttp-product-price {\n font-size: 14px;\n font-weight: 700;\n color: #1e293b;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PRODUCT COMPACT (list view)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-product-compact {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 10px;\n background: #fff;\n border-radius: 10px;\n border: 1px solid #e5e7eb;\n transition: border-color 0.15s;\n}\n.ttp-product-compact:hover { border-color: #3b82f6; }\n\n.ttp-product-image-sm {\n width: 40px; height: 40px;\n border-radius: 8px;\n background: #f8fafc;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: hidden;\n}\n.ttp-product-image-sm img {\n max-width: 36px;\n max-height: 36px;\n object-fit: contain;\n}\n\n.ttp-product-compact .ttp-product-info {\n flex: 1;\n min-width: 0;\n}\n.ttp-product-compact .ttp-product-name {\n min-height: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ttp-product-compact .ttp-product-action {\n text-align: right;\n flex-shrink: 0;\n}\n.ttp-product-compact .ttp-product-price {\n font-size: 13px;\n}\n\n.ttp-out-of-stock {\n font-size: 10px;\n color: #ef4444;\n font-weight: 500;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ADD BUTTON\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-add-btn {\n padding: 4px 14px;\n border-radius: 8px;\n border: none;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n background: #3b82f6;\n color: #fff;\n transition: all 0.15s;\n}\n.ttp-add-btn:hover { background: #2563eb; }\n.ttp-add-btn:active { transform: scale(0.95); }\n.ttp-add-btn.ttp-added { background: #10b981 !important; }\n.ttp-add-btn:disabled { cursor: default; }\n.ttp-add-btn.ttp-update-btn { background: #f59e0b; }\n.ttp-add-btn.ttp-update-btn:hover { background: #d97706; }\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CART TOAST\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-cart-toast {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n margin: 0 12px;\n background: #f0fdf4;\n border-radius: 12px;\n border: 1px solid #bbf7d0;\n animation: ttpToastIn 0.25s ease;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 10;\n box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n}\n\n@keyframes ttpToastIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ttp-cart-toast.ttp-toast-hiding {\n animation: ttpSlideDown 0.3s ease forwards;\n}\n\n@keyframes ttpSlideDown {\n to { opacity: 0; transform: translateY(-8px); height: 0; padding: 0; margin: 0; overflow: hidden; }\n}\n\n.ttp-toast-icon {\n width: 24px; height: 24px;\n border-radius: 50%;\n background: #10b981;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n.ttp-toast-content { flex: 1; min-width: 0; }\n.ttp-toast-title { font-size: 12px; font-weight: 600; color: #166534; }\n.ttp-toast-product {\n font-size: 11px;\n color: #15803d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ttp-toast-undo {\n background: none;\n border: 1px solid #86efac;\n border-radius: 6px;\n padding: 3px 8px;\n font-size: 10px;\n color: #15803d;\n cursor: pointer;\n font-weight: 600;\n flex-shrink: 0;\n}\n.ttp-toast-undo:hover { background: #dcfce7; }\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CART SUMMARY BAR\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-cart-summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 14px;\n margin: 4px 12px 8px;\n background: #f8fafc;\n border-radius: 10px;\n border: 1px solid #e2e8f0;\n}\n\n.ttp-cart-info {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.ttp-cart-icon { font-size: 14px; }\n.ttp-cart-count { font-size: 12px; font-weight: 600; color: #475569; }\n.ttp-cart-total { font-size: 14px; font-weight: 700; color: #1e293b; }\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n QUANTITY/WEIGHT STEPPER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-stepper {\n display: flex;\n align-items: center;\n gap: 2px;\n margin: 4px 0;\n}\n\n.ttp-stepper-btn {\n width: 24px;\n height: 24px;\n border-radius: 6px;\n border: 1px solid #e2e8f0;\n background: #f8fafc;\n color: #475569;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n line-height: 1;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.ttp-stepper-btn:hover:not(:disabled) {\n background: #e2e8f0;\n border-color: #cbd5e1;\n}\n\n.ttp-stepper-btn:active:not(:disabled) {\n transform: scale(0.9);\n}\n\n.ttp-stepper-btn:disabled,\n.ttp-stepper-disabled {\n opacity: 0.35;\n cursor: default;\n}\n\n.ttp-stepper-value {\n font-size: 12px;\n font-weight: 600;\n color: #1e293b;\n min-width: 36px;\n text-align: center;\n user-select: none;\n}\n\n.ttp-product-compact .ttp-stepper {\n justify-content: flex-end;\n}\n\n.ttp-product-compact .ttp-product-action {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 2px;\n}\n\n.ttp-product-card .ttp-stepper {\n justify-content: center;\n margin: 4px 0;\n}\n\n.ttp-product-card .ttp-product-footer {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n ";
11333
+ return "\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ECOMMERCE AREA\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/*\n * When products are visible, expand the panel dynamically.\n * Actual height is set via inline style by EcommerceManager._expandPanelToFit().\n * When the class is removed, the panel returns to its CSS-defined default.\n */\n#text-chat-panel.ttp-panel-expanded {\n transition: height 0.25s ease;\n}\n\n/*\n * Layout overrides when ecommerce layer is active.\n * voiceActiveState is a flex column: [voice-controls] [ecommerce] [conversation].\n * Ecommerce area fills the middle and scrolls; conversation panel stays at bottom.\n */\n#voiceActiveState {\n flex: 1 1 0 !important;\n min-height: 0 !important;\n overflow: hidden !important;\n}\n\n.desktop-voice-section {\n flex-shrink: 1 !important;\n}\n\n.desktop-conversation-panel {\n flex: 1 1 0 !important;\n min-height: 0 !important;\n display: flex !important;\n flex-direction: column !important;\n}\n\n.desktop-conversation-panel .live-transcript-collapsed {\n flex: 1 1 0 !important;\n min-height: 40px !important;\n overflow: hidden !important;\n}\n\n.desktop-conversation-panel .voice-text-input-area {\n margin-top: auto !important;\n padding: 3px 16px !important;\n}\n\n.desktop-conversation-panel .voice-input-hint {\n display: none !important;\n}\n\n#voiceActiveState.ttp-products-visible .desktop-voice-section {\n display: none !important;\n}\n\n#voiceActiveState.ttp-products-visible .compact-voice-section {\n display: flex !important;\n}\n\n#voiceActiveState.ttp-products-visible .desktop-conversation-panel {\n flex: 0 0 auto !important;\n}\n\n#voiceActiveState.ttp-products-visible .conversation-history {\n display: none !important;\n}\n\n#voiceActiveState.ttp-products-visible .live-transcript-collapsed {\n flex: 0 0 auto !important;\n}\n\n.voice-text-input-area {\n flex-shrink: 0 !important;\n}\n\n.conversation-history {\n flex: 1 1 0 !important;\n min-height: 0 !important;\n overflow-y: auto !important;\n}\n\n.ttp-ecommerce-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n flex: 1 1 0;\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n position: relative;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PRODUCT PICKER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-product-picker {\n background: #fff;\n border-radius: 14px;\n border: 1px solid #e5e7eb;\n box-shadow: 0 6px 24px rgba(0,0,0,0.08);\n margin: 8px 12px;\n overflow: hidden;\n animation: ttpSlideUp 0.25s ease;\n display: flex;\n flex-direction: column;\n}\n\n@keyframes ttpSlideUp {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.ttp-picker-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 14px;\n border-bottom: 1px solid #f1f5f9;\n flex-shrink: 0;\n}\n\n.ttp-picker-title {\n font-size: 12px;\n font-weight: 600;\n color: #64748b;\n}\n\n.ttp-picker-close {\n background: none;\n border: none;\n cursor: pointer;\n color: #94a3b8;\n font-size: 14px;\n padding: 2px 6px;\n border-radius: 4px;\n}\n.ttp-picker-close:hover {\n background: #f1f5f9;\n color: #475569;\n}\n\n/* Horizontal card layout */\n.ttp-products-horizontal {\n display: flex;\n gap: 10px;\n padding: 12px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: thin;\n}\n.ttp-products-horizontal::-webkit-scrollbar { height: 4px; }\n.ttp-products-horizontal::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 2px; }\n\n/* Vertical list layout */\n.ttp-products-vertical {\n padding: 8px 12px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 6px;\n flex: 1;\n min-height: 0;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PRODUCT CARD (horizontal)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-product-card {\n width: 140px;\n flex-shrink: 0;\n background: #fff;\n border-radius: 12px;\n border: 1px solid #e5e7eb;\n overflow: hidden;\n transition: border-color 0.15s;\n}\n.ttp-product-card:hover { border-color: #3b82f6; }\n\n.ttp-product-image {\n height: 85px;\n background: #f8fafc;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n}\n.ttp-product-image img {\n max-width: 90%;\n max-height: 75px;\n object-fit: contain;\n}\n\n.ttp-stock-badge {\n position: absolute;\n top: 4px; right: 4px;\n background: #fef2f2;\n color: #ef4444;\n font-size: 9px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.ttp-product-details {\n padding: 8px 10px 10px;\n}\n\n.ttp-product-name {\n font-size: 12px;\n font-weight: 600;\n color: #1e293b;\n line-height: 1.3;\n min-height: 30px;\n}\n\n.ttp-product-meta {\n font-size: 10px;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.ttp-product-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: 6px;\n}\n\n.ttp-product-price {\n font-size: 14px;\n font-weight: 700;\n color: #1e293b;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PRODUCT COMPACT (list view)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-product-compact {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 10px;\n background: #fff;\n border-radius: 10px;\n border: 1px solid #e5e7eb;\n transition: border-color 0.15s;\n}\n.ttp-product-compact:hover { border-color: #3b82f6; }\n\n.ttp-product-image-sm {\n width: 40px; height: 40px;\n border-radius: 8px;\n background: #f8fafc;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: hidden;\n}\n.ttp-product-image-sm img {\n max-width: 36px;\n max-height: 36px;\n object-fit: contain;\n}\n\n.ttp-product-compact .ttp-product-info {\n flex: 1;\n min-width: 0;\n}\n.ttp-product-compact .ttp-product-name {\n min-height: auto;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ttp-product-compact .ttp-product-action {\n text-align: right;\n flex-shrink: 0;\n}\n.ttp-product-compact .ttp-product-price {\n font-size: 13px;\n}\n\n.ttp-out-of-stock {\n font-size: 10px;\n color: #ef4444;\n font-weight: 500;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ADD BUTTON\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-add-btn {\n padding: 4px 14px;\n border-radius: 8px;\n border: none;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n background: #3b82f6;\n color: #fff;\n transition: all 0.15s;\n}\n.ttp-add-btn:hover { background: #2563eb; }\n.ttp-add-btn:active { transform: scale(0.95); }\n.ttp-add-btn.ttp-added { background: #10b981 !important; }\n.ttp-add-btn:disabled { cursor: default; }\n.ttp-add-btn.ttp-update-btn { background: #f59e0b; }\n.ttp-add-btn.ttp-update-btn:hover { background: #d97706; }\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CART TOAST\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-cart-toast {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n margin: 0 12px;\n background: #f0fdf4;\n border-radius: 12px;\n border: 1px solid #bbf7d0;\n animation: ttpToastIn 0.25s ease;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 10;\n box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n}\n\n@keyframes ttpToastIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ttp-cart-toast.ttp-toast-hiding {\n animation: ttpSlideDown 0.3s ease forwards;\n}\n\n@keyframes ttpSlideDown {\n to { opacity: 0; transform: translateY(-8px); height: 0; padding: 0; margin: 0; overflow: hidden; }\n}\n\n.ttp-toast-icon {\n width: 24px; height: 24px;\n border-radius: 50%;\n background: #10b981;\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n flex-shrink: 0;\n}\n\n.ttp-toast-content { flex: 1; min-width: 0; }\n.ttp-toast-title { font-size: 12px; font-weight: 600; color: #166534; }\n.ttp-toast-product {\n font-size: 11px;\n color: #15803d;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ttp-toast-undo {\n background: none;\n border: 1px solid #86efac;\n border-radius: 6px;\n padding: 3px 8px;\n font-size: 10px;\n color: #15803d;\n cursor: pointer;\n font-weight: 600;\n flex-shrink: 0;\n}\n.ttp-toast-undo:hover { background: #dcfce7; }\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CART SUMMARY BAR\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-cart-summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 14px;\n margin: 4px 12px 8px;\n background: #f8fafc;\n border-radius: 10px;\n border: 1px solid #e2e8f0;\n}\n\n.ttp-cart-info {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.ttp-cart-icon { font-size: 14px; }\n.ttp-cart-count { font-size: 12px; font-weight: 600; color: #475569; }\n.ttp-cart-separator { font-size: 12px; color: #94a3b8; }\n.ttp-cart-total { font-size: 13px; font-weight: 700; color: #1e293b; }\n.ttp-cart-view {\n font-size: 12px;\n font-weight: 600;\n color: #6366f1;\n text-decoration: none;\n cursor: pointer;\n white-space: nowrap;\n}\n.ttp-cart-view:hover {\n color: #4f46e5;\n text-decoration: underline;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n QUANTITY/WEIGHT STEPPER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.ttp-stepper {\n display: flex;\n align-items: center;\n gap: 2px;\n margin: 4px 0;\n}\n\n.ttp-stepper-btn {\n width: 24px;\n height: 24px;\n border-radius: 6px;\n border: 1px solid #e2e8f0;\n background: #f8fafc;\n color: #475569;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n line-height: 1;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.ttp-stepper-btn:hover:not(:disabled) {\n background: #e2e8f0;\n border-color: #cbd5e1;\n}\n\n.ttp-stepper-btn:active:not(:disabled) {\n transform: scale(0.9);\n}\n\n.ttp-stepper-btn:disabled,\n.ttp-stepper-disabled {\n opacity: 0.35;\n cursor: default;\n}\n\n.ttp-stepper-value {\n font-size: 12px;\n font-weight: 600;\n color: #1e293b;\n min-width: 36px;\n text-align: center;\n user-select: none;\n}\n\n.ttp-product-compact .ttp-stepper {\n justify-content: flex-end;\n}\n\n.ttp-product-compact .ttp-product-action {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 2px;\n}\n\n.ttp-product-card .ttp-stepper {\n justify-content: center;\n margin: 4px 0;\n}\n\n.ttp-product-card .ttp-product-footer {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n ";
11234
11334
  }
11235
11335
 
11236
11336
  /***/ }),
@@ -14129,8 +14229,6 @@ function registerVisualTools(registry) {
14129
14229
  });
14130
14230
  if (missingTools.length > 0) {
14131
14231
  console.error('[TTP] ❌ Some visual tools failed to register:', missingTools);
14132
- } else {
14133
- console.log('[TTP] 👁️ Visual assistant tools registered successfully:', registeredTools);
14134
14232
  }
14135
14233
  }
14136
14234
 
@@ -14258,9 +14356,9 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
14258
14356
  _this = _callSuper(this, AudioPlayer);
14259
14357
 
14260
14358
  // Version identification log
14261
- console.log('%c🔊 AUDIO PLAYER - SILENT BUFFER PRIMING FIX ENABLED', 'background: #10b981; color: white; font-size: 14px; font-weight: bold; padding: 4px 8px; border-radius: 4px;');
14262
- console.log('%cAndroid Greeting Cut-Off Fix: Silent buffer priming (150ms) + dynamic startup buffer', 'background: #d1fae5; color: #065f46; font-size: 12px; padding: 2px 6px; border-radius: 3px;');
14263
- console.log('%cBuild: 2026-01-30-SILENT-BUFFER-PRIMING | Look for [scheduleWAV] and priming logs', 'background: #e0e7ff; color: #1e40af; font-size: 11px; padding: 2px 6px; border-radius: 3px;');
14359
+ console.log('%c🔊 AUDIO PLAYER - MIC/SPEAKER RESET ON NEW CALL ENABLED', 'background: #10b981; color: white; font-size: 14px; font-weight: bold; padding: 4px 8px; border-radius: 4px;');
14360
+ console.log('%cFix: Mic/speaker mute state + UI fully reset on call end and call start', 'background: #d1fae5; color: #065f46; font-size: 12px; padding: 2px 6px; border-radius: 3px;');
14361
+ console.log('%cBuild: 2026-02-26-MIC-SPEAKER-RESET', 'background: #e0e7ff; color: #1e40af; font-size: 11px; padding: 2px 6px; border-radius: 3px;');
14264
14362
  console.log('');
14265
14363
  _this.config = config;
14266
14364
  _this.audioContext = null;
@@ -14641,7 +14739,7 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
14641
14739
  value: (function () {
14642
14740
  var _schedulePreparedFrames = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
14643
14741
  var _this4 = this;
14644
- var queuedFrames, targetLookaheadFrames, _this$audioContext2, _this$audioContext3, _this$audioContext4, _this$audioContext5, scheduledCount, _loop, _ret, _t;
14742
+ var queuedFrames, targetLookaheadFrames, scheduledCount, _loop, _ret, _t;
14645
14743
  return _regenerator().w(function (_context3) {
14646
14744
  while (1) switch (_context3.p = _context3.n) {
14647
14745
  case 0:
@@ -14679,12 +14777,9 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
14679
14777
  // ✅ NEW: Wait for AudioContext to be in 'running' state before proceeding
14680
14778
  // This is critical for mobile devices where AudioContext initialization takes time
14681
14779
  // Replaces fixed timeouts with event-driven waiting
14682
- console.log('🔍 [scheduleWAV] BEFORE waitForAudioContextReady - state:', (_this$audioContext2 = this.audioContext) === null || _this$audioContext2 === void 0 ? void 0 : _this$audioContext2.state, 'currentTime:', (_this$audioContext3 = this.audioContext) === null || _this$audioContext3 === void 0 ? void 0 : _this$audioContext3.currentTime);
14683
14780
  _context3.n = 4;
14684
14781
  return this.waitForAudioContextReady();
14685
14782
  case 4:
14686
- console.log('🔍 [scheduleWAV] AFTER waitForAudioContextReady - state:', (_this$audioContext4 = this.audioContext) === null || _this$audioContext4 === void 0 ? void 0 : _this$audioContext4.state, 'currentTime:', (_this$audioContext5 = this.audioContext) === null || _this$audioContext5 === void 0 ? void 0 : _this$audioContext5.currentTime);
14687
-
14688
14783
  // Schedule frames up to target lookahead (ensures smooth playback)
14689
14784
  // Keep scheduling frames as long as we have them and haven't reached the lookahead limit
14690
14785
  scheduledCount = 0;
@@ -15500,20 +15595,13 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
15500
15595
  value: (function () {
15501
15596
  var _waitForAudioContextReady = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
15502
15597
  var _this6 = this;
15503
- var _this$audioContext6, _this$audioContext7, audioContext;
15598
+ var audioContext;
15504
15599
  return _regenerator().w(function (_context5) {
15505
15600
  while (1) switch (_context5.n) {
15506
15601
  case 0:
15507
- console.log('🔍 [waitForAudioContextReady] ENTRY - audioContext exists:', !!this.audioContext);
15508
-
15509
- // ✅ Add null check - ensure AudioContext exists
15510
15602
  if (!this.audioContext) {
15511
- console.log('🔍 [waitForAudioContextReady] Creating AudioContext...');
15512
15603
  this.initializeAudioContext();
15513
- console.log('🔍 [waitForAudioContextReady] After initializeAudioContext - state:', (_this$audioContext6 = this.audioContext) === null || _this$audioContext6 === void 0 ? void 0 : _this$audioContext6.state, 'currentTime:', (_this$audioContext7 = this.audioContext) === null || _this$audioContext7 === void 0 ? void 0 : _this$audioContext7.currentTime);
15514
15604
  }
15515
-
15516
- // ✅ Add null check after initialization
15517
15605
  if (this.audioContext) {
15518
15606
  _context5.n = 1;
15519
15607
  break;
@@ -15522,46 +15610,33 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
15522
15610
  return _context5.a(2, Promise.resolve());
15523
15611
  case 1:
15524
15612
  audioContext = this.audioContext;
15525
- console.log('🔍 [waitForAudioContextReady] Initial state:', audioContext.state, 'currentTime:', audioContext.currentTime);
15526
-
15527
- // If already running, proceed immediately
15528
15613
  if (!(audioContext.state === 'running')) {
15529
15614
  _context5.n = 2;
15530
15615
  break;
15531
15616
  }
15532
- console.log('🔍 [waitForAudioContextReady] Already running - returning immediately, currentTime:', audioContext.currentTime);
15533
15617
  return _context5.a(2, Promise.resolve());
15534
15618
  case 2:
15535
15619
  if (!(audioContext.state === 'suspended')) {
15536
- _context5.n = 5;
15620
+ _context5.n = 4;
15537
15621
  break;
15538
15622
  }
15539
- console.log('🔍 [waitForAudioContextReady] State is suspended - calling resume()...');
15540
15623
  _context5.n = 3;
15541
15624
  return audioContext.resume();
15542
15625
  case 3:
15543
- console.log('🔍 [waitForAudioContextReady] After resume() - state:', audioContext.state, 'currentTime:', audioContext.currentTime);
15544
-
15545
- // Wait for actual state change (not fixed timeout)
15546
15626
  if (!(audioContext.state !== 'running')) {
15547
15627
  _context5.n = 4;
15548
15628
  break;
15549
15629
  }
15550
- console.log('🔍 [waitForAudioContextReady] Still not running after resume() - waiting for statechange event...');
15551
15630
  return _context5.a(2, new Promise(function (resolve) {
15552
15631
  var timeout = setTimeout(function () {
15553
- // ✅ Clean up temporary listener
15554
15632
  if (audioContext && _this6._waitForReadyStateHandler) {
15555
15633
  audioContext.removeEventListener('statechange', _this6._waitForReadyStateHandler);
15556
15634
  _this6._waitForReadyStateHandler = null;
15557
15635
  }
15558
- console.warn('⚠️ AudioPlayer: AudioContext did not become running within timeout - proceeding anyway, state:', audioContext === null || audioContext === void 0 ? void 0 : audioContext.state, 'currentTime:', audioContext === null || audioContext === void 0 ? void 0 : audioContext.currentTime);
15559
- resolve(); // Proceed to avoid blocking
15560
- }, 2000); // 2 second timeout fallback
15561
-
15636
+ console.warn('⚠️ AudioPlayer: AudioContext did not become running within timeout - proceeding anyway');
15637
+ resolve();
15638
+ }, 2000);
15562
15639
  var checkState = function checkState() {
15563
- console.log('🔍 [waitForAudioContextReady] statechange event fired - state:', audioContext === null || audioContext === void 0 ? void 0 : audioContext.state, 'currentTime:', audioContext === null || audioContext === void 0 ? void 0 : audioContext.currentTime);
15564
- // ✅ Add null check - audioContext might be null when handler fires
15565
15640
  if (!audioContext) {
15566
15641
  clearTimeout(timeout);
15567
15642
  _this6._waitForReadyStateHandler = null;
@@ -15571,45 +15646,33 @@ var AudioPlayer = /*#__PURE__*/function (_EventEmitter) {
15571
15646
  }
15572
15647
  if (audioContext.state === 'running') {
15573
15648
  clearTimeout(timeout);
15574
- // ✅ Clean up temporary listener
15575
15649
  if (_this6._waitForReadyStateHandler) {
15576
15650
  audioContext.removeEventListener('statechange', _this6._waitForReadyStateHandler);
15577
15651
  _this6._waitForReadyStateHandler = null;
15578
15652
  }
15579
- console.log('✅ [waitForAudioContextReady] AudioContext became running via statechange, currentTime:', audioContext.currentTime);
15580
15653
  resolve();
15581
15654
  }
15582
15655
  };
15583
-
15584
- // ✅ Store listener reference for cleanup
15585
15656
  _this6._waitForReadyStateHandler = checkState;
15586
15657
  audioContext.addEventListener('statechange', checkState);
15587
-
15588
- // Check immediately in case state changed synchronously
15589
- console.log('🔍 [waitForAudioContextReady] Synchronous check - state:', audioContext === null || audioContext === void 0 ? void 0 : audioContext.state);
15590
15658
  if (audioContext && audioContext.state === 'running') {
15591
15659
  clearTimeout(timeout);
15592
- // ✅ Clean up temporary listener
15593
15660
  if (_this6._waitForReadyStateHandler) {
15594
15661
  audioContext.removeEventListener('statechange', _this6._waitForReadyStateHandler);
15595
15662
  _this6._waitForReadyStateHandler = null;
15596
15663
  }
15597
- console.log('✅ [waitForAudioContextReady] State became running synchronously, currentTime:', audioContext.currentTime);
15598
15664
  resolve();
15599
15665
  }
15600
15666
  }));
15601
15667
  case 4:
15602
- console.log('🔍 [waitForAudioContextReady] State is running after resume() - returning, currentTime:', audioContext.currentTime);
15603
- case 5:
15604
15668
  if (!(audioContext.state === 'closed')) {
15605
- _context5.n = 6;
15669
+ _context5.n = 5;
15606
15670
  break;
15607
15671
  }
15608
15672
  console.warn('⚠️ AudioPlayer: AudioContext was closed, recreating...');
15609
15673
  this.initializeAudioContext();
15610
15674
  return _context5.a(2, this.waitForAudioContextReady());
15611
- case 6:
15612
- console.log('🔍 [waitForAudioContextReady] EXIT - state:', audioContext.state, 'currentTime:', audioContext.currentTime);
15675
+ case 5:
15613
15676
  return _context5.a(2, Promise.resolve());
15614
15677
  }
15615
15678
  }, _callee4, this);
@@ -16454,14 +16517,15 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
16454
16517
  _classCallCheck(this, VoiceSDK_v2);
16455
16518
  _this = _callSuper(this, VoiceSDK_v2);
16456
16519
  _this.version = '2.0.0';
16520
+
16521
+ // Backward compat: signedUrl → websocketUrl
16522
+ if (config.signedUrl && !config.websocketUrl) {
16523
+ console.warn('⚠️ VoiceSDK: signedUrl is deprecated — use websocketUrl for custom backend URLs, or just provide agentId + appId');
16524
+ config.websocketUrl = config.signedUrl;
16525
+ }
16457
16526
  _this.config = {
16458
16527
  // Connection
16459
-
16460
- signedUrl: config.signedUrl || config.websocketUrl || 'wss://speech.talktopc.com/ws/conv',
16461
- // Support both signedUrl and websocketUrl for backward compatibility
16462
- websocketUrl: config.signedUrl || config.websocketUrl || 'wss://speech.talktopc.com/ws/conv',
16463
- // Keep for internal use
16464
-
16528
+ websocketUrl: config.websocketUrl || 'wss://speech.talktopc.com/ws/conv',
16465
16529
  agentId: config.agentId,
16466
16530
  appId: config.appId,
16467
16531
  // Input format (what we send to server)
@@ -16576,12 +16640,6 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
16576
16640
 
16577
16641
  // Setup page unload handler for resume state storage
16578
16642
  _this._setupPageUnloadHandler();
16579
- console.log('🎵 VoiceSDK v2 initialized:', {
16580
- version: _this.version,
16581
- outputContainer: _this.config.outputContainer,
16582
- outputEncoding: _this.config.outputEncoding,
16583
- outputSampleRate: _this.config.outputSampleRate
16584
- });
16585
16643
  return _this;
16586
16644
  }
16587
16645
 
@@ -16693,8 +16751,6 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
16693
16751
  });
16694
16752
  console.error('❌ VoiceSDK: Some visual tools failed to register:', missing);
16695
16753
  console.error(' Registered visual tools:', registeredVisualTools);
16696
- } else {
16697
- console.log('✅ VoiceSDK: All visual tools registered:', registeredVisualTools);
16698
16754
  }
16699
16755
  } catch (error) {
16700
16756
  console.error('❌ VoiceSDK: Error registering visual assistant tools:', error);
@@ -16715,10 +16771,7 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
16715
16771
  console.error('❌ VoiceSDK: Missing internal tools:', _missing);
16716
16772
  console.error(' Expected 7 internal tools:', requiredInternalTools);
16717
16773
  console.error(' Registered:', registeredInternalTools);
16718
- } else {
16719
- console.log('✅ VoiceSDK: All 7 internal tools registered:', registeredInternalTools);
16720
16774
  }
16721
- console.log('🔧 VoiceSDK: All registered tools after _registerBuiltInTools():', allRegisteredTools);
16722
16775
  }
16723
16776
 
16724
16777
  /**
@@ -17031,7 +17084,6 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
17031
17084
  this.emit('error', new Error(outputError));
17032
17085
  return;
17033
17086
  }
17034
- console.log('✅ VoiceSDK v2: Format validation passed');
17035
17087
  }
17036
17088
 
17037
17089
  /**
@@ -17160,37 +17212,28 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
17160
17212
  }, {
17161
17213
  key: "buildWebSocketUrl",
17162
17214
  value: function buildWebSocketUrl() {
17163
- var baseUrl = this.config.signedUrl || this.config.websocketUrl;
17164
-
17165
- // Parse existing URL to check what params are already there
17215
+ var baseUrl = this.config.websocketUrl;
17166
17216
  var url = new URL(baseUrl, 'wss://placeholder.com');
17167
- var existingParams = url.searchParams;
17217
+ var params = url.searchParams;
17168
17218
 
17169
- // Only add agentId if not already in URL
17170
- if (this.config.agentId && !existingParams.has('agentId')) {
17171
- existingParams.append('agentId', this.config.agentId);
17219
+ // Strip any legacy signed_token param
17220
+ params.delete('signed_token');
17221
+ if (this.config.agentId && !params.has('agentId')) {
17222
+ params.append('agentId', this.config.agentId);
17172
17223
  }
17173
-
17174
- // Only add appId if not already in URL
17175
- if (this.config.appId && !existingParams.has('appId')) {
17176
- existingParams.append('appId', this.config.appId);
17224
+ if (this.config.appId && !params.has('appId')) {
17225
+ params.append('appId', this.config.appId);
17177
17226
  }
17178
-
17179
- // Include conversationId for resume attempt (if available)
17180
17227
  var storedConversationId = this.getStoredConversationId();
17181
- if (storedConversationId && !existingParams.has('conversationId')) {
17182
- existingParams.append('conversationId', storedConversationId);
17228
+ if (storedConversationId && !params.has('conversationId')) {
17229
+ params.append('conversationId', storedConversationId);
17183
17230
  console.log('🔄 VoiceSDK v2: Attempting resume via query param:', storedConversationId);
17184
17231
  }
17185
-
17186
- // Include current page for resume context tracking
17187
17232
  var currentPage = window.location.pathname + window.location.search;
17188
- if (currentPage && !existingParams.has('currentPage')) {
17189
- existingParams.append('currentPage', currentPage);
17233
+ if (currentPage && !params.has('currentPage')) {
17234
+ params.append('currentPage', currentPage);
17190
17235
  }
17191
-
17192
- // Reconstruct URL with all params
17193
- var queryString = existingParams.toString();
17236
+ var queryString = params.toString();
17194
17237
  if (queryString) {
17195
17238
  return "".concat(url.origin).concat(url.pathname, "?").concat(queryString);
17196
17239
  }
@@ -17237,7 +17280,6 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
17237
17280
  // Connection opened
17238
17281
 
17239
17282
  _this6.websocket.onopen = function () {
17240
- console.log('✅ VoiceSDK v2: WebSocket connected');
17241
17283
  _this6.isConnected = true;
17242
17284
  _this6.hasEverConnected = true; // Mark that we've successfully connected
17243
17285
 
@@ -17249,7 +17291,6 @@ var VoiceSDK_v2 = /*#__PURE__*/function (_EventEmitter) {
17249
17291
 
17250
17292
  // Verify all tools are registered (safeguard)
17251
17293
  var registeredTools = _this6.clientToolsRegistry.getRegisteredTools();
17252
- console.log('🔧 VoiceSDK v2: Registered tools on connect:', registeredTools);
17253
17294
 
17254
17295
  // Re-register tools if they're missing (safety check)
17255
17296
  // 7 internal tools: read_page, capture_screen, and 5 action tools (matches backend tool names)
@@ -20404,8 +20445,6 @@ var AgentSDK = /*#__PURE__*/function () {
20404
20445
  // Get visualAssistant from config or agentSettingsOverride (same pattern as connect())
20405
20446
  var visualAssistant = this.config.visualAssistant || ((_this$config$agentSet = this.config.agentSettingsOverride) === null || _this$config$agentSet === void 0 ? void 0 : _this$config$agentSet.visualAssistant);
20406
20447
  var tempSDK = new _index_js__WEBPACK_IMPORTED_MODULE_0__.VoiceSDK_v2({
20407
- signedUrl: 'wss://placeholder',
20408
- // Placeholder, won't be used
20409
20448
  autoReconnect: false,
20410
20449
  agentId: this.config.agentId,
20411
20450
  appId: this.config.appId,
@@ -20435,19 +20474,13 @@ var AgentSDK = /*#__PURE__*/function () {
20435
20474
  }, {
20436
20475
  key: "connect",
20437
20476
  value: function () {
20438
- var _connect = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(signedUrl) {
20477
+ var _connect = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
20439
20478
  var _this = this;
20440
20479
  var _this$config$agentSet2, visualAssistant, _iterator, _step, _step$value, name, handler, _t;
20441
20480
  return _regenerator().w(function (_context) {
20442
20481
  while (1) switch (_context.p = _context.n) {
20443
20482
  case 0:
20444
20483
  _context.p = 0;
20445
- if (signedUrl) {
20446
- _context.n = 1;
20447
- break;
20448
- }
20449
- throw new Error('signedUrl is required');
20450
- case 1:
20451
20484
  // Clean up existing connection if any
20452
20485
  if (this.voiceSDK) {
20453
20486
  console.log('🔌 AgentSDK: Cleaning up existing connection');
@@ -20455,13 +20488,10 @@ var AgentSDK = /*#__PURE__*/function () {
20455
20488
  this.voiceSDK = null;
20456
20489
  }
20457
20490
 
20458
- // Create VoiceSDK v2 instance
20459
- // Allow configurable output format, with defaults optimized for widget
20460
20491
  // Get visualAssistant from config or agentSettingsOverride (same pattern as VoiceSDK)
20461
20492
  visualAssistant = this.config.visualAssistant || ((_this$config$agentSet2 = this.config.agentSettingsOverride) === null || _this$config$agentSet2 === void 0 ? void 0 : _this$config$agentSet2.visualAssistant);
20462
20493
  this.voiceSDK = new _index_js__WEBPACK_IMPORTED_MODULE_0__.VoiceSDK_v2({
20463
- signedUrl: signedUrl,
20464
- // Use signedUrl parameter (VoiceSDK_v2 supports both signedUrl and websocketUrl)
20494
+ websocketUrl: this.config.websocketUrl,
20465
20495
  autoReconnect: false,
20466
20496
  agentId: this.config.agentId,
20467
20497
  appId: this.config.appId,
@@ -20620,22 +20650,22 @@ var AgentSDK = /*#__PURE__*/function () {
20620
20650
  }
20621
20651
 
20622
20652
  // Connect using VoiceSDK
20623
- _context.n = 2;
20653
+ _context.n = 1;
20624
20654
  return this.voiceSDK.connect();
20625
- case 2:
20626
- _context.n = 4;
20655
+ case 1:
20656
+ _context.n = 3;
20627
20657
  break;
20628
- case 3:
20629
- _context.p = 3;
20658
+ case 2:
20659
+ _context.p = 2;
20630
20660
  _t = _context.v;
20631
20661
  this.onError(_t);
20632
20662
  throw _t;
20633
- case 4:
20663
+ case 3:
20634
20664
  return _context.a(2);
20635
20665
  }
20636
- }, _callee, this, [[0, 3]]);
20666
+ }, _callee, this, [[0, 2]]);
20637
20667
  }));
20638
- function connect(_x) {
20668
+ function connect() {
20639
20669
  return _connect.apply(this, arguments);
20640
20670
  }
20641
20671
  return connect;
@@ -21025,6 +21055,13 @@ var TTPChatWidget = /*#__PURE__*/function () {
21025
21055
  _classCallCheck(this, TTPChatWidget);
21026
21056
  // Merge user config with defaults (backward compatible with simple config)
21027
21057
  this.config = this.mergeWithDefaults(config);
21058
+
21059
+ // Backward compat: signedUrl → websocketUrl with deprecation warning
21060
+ if (config.signedUrl && !config.websocketUrl) {
21061
+ console.warn('⚠️ TTPChatWidget: signedUrl is deprecated — use websocketUrl for custom backend URLs, or just provide agentId + appId');
21062
+ }
21063
+ // Silently ignore allowOverride (now server-side only)
21064
+
21028
21065
  this.sdk = new _core_TextChatSDK_js__WEBPACK_IMPORTED_MODULE_0__["default"](this.config);
21029
21066
  this.isOpen = false;
21030
21067
  this.isActive = false;
@@ -21059,17 +21096,12 @@ var TTPChatWidget = /*#__PURE__*/function () {
21059
21096
  // Pass through send button color for voice send button
21060
21097
  sendButtonColor: ((_this$config$text2 = this.config.text) === null || _this$config$text2 === void 0 ? void 0 : _this$config$text2.sendButtonColor) || this.config.sendButtonColor || '#7C3AED',
21061
21098
  language: ((_this$config$voice = this.config.voice) === null || _this$config$voice === void 0 ? void 0 : _this$config$voice.language) || this.config.language || 'en',
21062
- signedUrl: this.config.signedUrl,
21063
- // Pass through signedUrl if provided
21099
+ websocketUrl: this.config.websocketUrl,
21064
21100
  agentSettingsOverride: this.config.agentSettingsOverride,
21065
- // Pass through agentSettingsOverride if provided
21066
21101
  visualAssistant: this.config.visualAssistant,
21067
- // Pass through visualAssistant config
21068
21102
  translations: this.translations,
21069
21103
  shadowRoot: this.shadowRoot,
21070
- // Pass shadow root reference
21071
21104
  textSDK: this.sdk,
21072
- // Pass TextChatSDK reference for sending text messages during voice calls
21073
21105
  // Output format defaults for widget: 44100 Hz, 16-bit, PCM, raw
21074
21106
  outputContainer: ((_this$config$voice2 = this.config.voice) === null || _this$config$voice2 === void 0 ? void 0 : _this$config$voice2.outputContainer) || 'raw',
21075
21107
  outputEncoding: ((_this$config$voice3 = this.config.voice) === null || _this$config$voice3 === void 0 ? void 0 : _this$config$voice3.outputEncoding) || 'pcm',
@@ -21268,12 +21300,10 @@ var TTPChatWidget = /*#__PURE__*/function () {
21268
21300
  // Required (agentId is required, appId is optional)
21269
21301
  agentId: userConfig.agentId,
21270
21302
  appId: userConfig.appId,
21271
- signedUrl: userConfig.signedUrl,
21272
- // Optional - signed URL for secure authentication (for voice)
21303
+ websocketUrl: userConfig.websocketUrl || userConfig.signedUrl,
21304
+ // signedUrl accepted as backward-compat alias
21273
21305
  agentSettingsOverride: userConfig.agentSettingsOverride,
21274
- // Optional - agent settings override (requires signed URL with allowOverride=true)
21275
21306
  demo: userConfig.demo !== false,
21276
- // Optional - defaults to true
21277
21307
  direction: userConfig.direction || 'ltr',
21278
21308
  // Optional - text direction: 'ltr' or 'rtl'
21279
21309
  language: userConfig.language || 'en',
@@ -22772,51 +22802,34 @@ var TTPChatWidget = /*#__PURE__*/function () {
22772
22802
  }
22773
22803
  }
22774
22804
  }, {
22775
- key: "getSignedUrl",
22776
- value: function () {
22777
- var _getSignedUrl = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
22778
- var baseUrl, params, wsUrl;
22779
- return _regenerator().w(function (_context4) {
22780
- while (1) switch (_context4.n) {
22781
- case 0:
22782
- if (!this.config.signedUrl) {
22783
- _context4.n = 1;
22784
- break;
22785
- }
22786
- return _context4.a(2, this.config.signedUrl);
22787
- case 1:
22788
- if (this.config.agentId) {
22789
- _context4.n = 2;
22790
- break;
22791
- }
22792
- throw new Error('agentId is required when signedUrl is not provided');
22793
- case 2:
22794
- // Build WebSocket URL directly
22795
- // Default uses backend.talktopc.com for text chat (path may need adjustment)
22796
- baseUrl = this.config.websocketUrl || 'wss://backend.talktopc.com/ws/conv';
22797
- params = new URLSearchParams();
22798
- params.append('agentId', this.config.agentId);
22799
- if (this.config.appId) {
22800
- params.append('appId', this.config.appId);
22801
- }
22805
+ key: "buildWebSocketUrl",
22806
+ value: function buildWebSocketUrl() {
22807
+ if (!this.config.agentId) {
22808
+ throw new Error('agentId is required');
22809
+ }
22810
+ var baseUrl = this.config.websocketUrl || 'wss://backend.talktopc.com/ws/conv';
22811
+ var url = new URL(baseUrl, 'wss://placeholder.com');
22812
+ var params = url.searchParams;
22802
22813
 
22803
- // Add demo flag if in development
22804
- if (this.config.demo !== false) {
22805
- params.append('demo', 'true');
22806
- }
22807
- wsUrl = "".concat(baseUrl, "?").concat(params.toString());
22808
- if (true) {
22809
- console.log('[TTPAgentSDK] WebSocket URL:', wsUrl);
22810
- }
22811
- return _context4.a(2, wsUrl);
22812
- }
22813
- }, _callee4, this);
22814
- }));
22815
- function getSignedUrl() {
22816
- return _getSignedUrl.apply(this, arguments);
22814
+ // Strip any legacy signed_token param
22815
+ params.delete('signed_token');
22816
+ if (!params.has('agentId')) {
22817
+ params.append('agentId', this.config.agentId);
22818
+ }
22819
+ if (this.config.appId && !params.has('appId')) {
22820
+ params.append('appId', this.config.appId);
22817
22821
  }
22818
- return getSignedUrl;
22819
- }() // Delegated to TextInterface
22822
+ if (this.config.demo !== false) {
22823
+ params.append('demo', 'true');
22824
+ }
22825
+ var wsUrl = "".concat(url.origin).concat(url.pathname, "?").concat(params.toString());
22826
+ if (true) {
22827
+ console.log('[TTPAgentSDK] WebSocket URL:', wsUrl);
22828
+ }
22829
+ return wsUrl;
22830
+ }
22831
+
22832
+ // Delegated to TextInterface
22820
22833
  }, {
22821
22834
  key: "addMessage",
22822
22835
  value: function addMessage(type, text) {
@@ -23057,12 +23070,9 @@ var TTPChatWidget = /*#__PURE__*/function () {
23057
23070
  translations: this.translations,
23058
23071
  shadowRoot: this.shadowRoot,
23059
23072
  // Pass shadow root reference
23060
- signedUrl: this.config.signedUrl,
23061
- // Pass through signedUrl if provided
23073
+ websocketUrl: this.config.websocketUrl,
23062
23074
  agentSettingsOverride: this.config.agentSettingsOverride,
23063
- // Pass through agentSettingsOverride if provided
23064
23075
  visualAssistant: this.config.visualAssistant,
23065
- // Pass through visualAssistant config
23066
23076
  // Output format defaults for widget: 44100 Hz, 16-bit, PCM, raw
23067
23077
  outputContainer: ((_this$config$voice8 = this.config.voice) === null || _this$config$voice8 === void 0 ? void 0 : _this$config$voice8.outputContainer) || 'raw',
23068
23078
  outputEncoding: ((_this$config$voice9 = this.config.voice) === null || _this$config$voice9 === void 0 ? void 0 : _this$config$voice9.outputEncoding) || 'pcm',
@@ -23143,19 +23153,19 @@ var TTPChatWidget = /*#__PURE__*/function () {
23143
23153
  }, {
23144
23154
  key: "startVoiceCall",
23145
23155
  value: function () {
23146
- var _startVoiceCall = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
23147
- return _regenerator().w(function (_context5) {
23148
- while (1) switch (_context5.n) {
23156
+ var _startVoiceCall = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
23157
+ return _regenerator().w(function (_context4) {
23158
+ while (1) switch (_context4.n) {
23149
23159
  case 0:
23150
- _context5.n = 1;
23160
+ _context4.n = 1;
23151
23161
  return this.voiceInterface.startVoiceCall();
23152
23162
  case 1:
23153
23163
  // Flush pending tools after SDK connects
23154
23164
  this._flushPendingClientTools();
23155
23165
  case 2:
23156
- return _context5.a(2);
23166
+ return _context4.a(2);
23157
23167
  }
23158
- }, _callee5, this);
23168
+ }, _callee4, this);
23159
23169
  }));
23160
23170
  function startVoiceCall() {
23161
23171
  return _startVoiceCall.apply(this, arguments);
@@ -23208,26 +23218,26 @@ var TTPChatWidget = /*#__PURE__*/function () {
23208
23218
  }, {
23209
23219
  key: "injectData",
23210
23220
  value: (function () {
23211
- var _injectData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(data) {
23221
+ var _injectData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(data) {
23212
23222
  var _this$voiceInterface6;
23213
23223
  var options,
23214
23224
  voiceSDK,
23215
23225
  ack,
23216
- _args6 = arguments,
23226
+ _args5 = arguments,
23217
23227
  _t2;
23218
- return _regenerator().w(function (_context6) {
23219
- while (1) switch (_context6.p = _context6.n) {
23228
+ return _regenerator().w(function (_context5) {
23229
+ while (1) switch (_context5.p = _context5.n) {
23220
23230
  case 0:
23221
- options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
23231
+ options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
23222
23232
  if (!(!data || !data.trim())) {
23223
- _context6.n = 1;
23233
+ _context5.n = 1;
23224
23234
  break;
23225
23235
  }
23226
23236
  console.warn('TTPChatWidget: Cannot inject empty data');
23227
23237
  throw new Error('Cannot inject empty data');
23228
23238
  case 1:
23229
23239
  if (!(!this.voiceInterface || !this.voiceInterface.isActive)) {
23230
- _context6.n = 2;
23240
+ _context5.n = 2;
23231
23241
  break;
23232
23242
  }
23233
23243
  console.warn('TTPChatWidget: Cannot inject data - voice call is not active');
@@ -23236,28 +23246,28 @@ var TTPChatWidget = /*#__PURE__*/function () {
23236
23246
  // Check if SDK is available
23237
23247
  voiceSDK = (_this$voiceInterface6 = this.voiceInterface) === null || _this$voiceInterface6 === void 0 ? void 0 : _this$voiceInterface6.getVoiceSDK();
23238
23248
  if (voiceSDK) {
23239
- _context6.n = 3;
23249
+ _context5.n = 3;
23240
23250
  break;
23241
23251
  }
23242
23252
  console.warn('TTPChatWidget: VoiceSDK not available');
23243
23253
  throw new Error('VoiceSDK not available');
23244
23254
  case 3:
23245
- _context6.p = 3;
23246
- _context6.n = 4;
23255
+ _context5.p = 3;
23256
+ _context5.n = 4;
23247
23257
  return voiceSDK.injectData(data, _objectSpread(_objectSpread({}, options), {}, {
23248
23258
  source: options.source || 'widget_programmatic'
23249
23259
  }));
23250
23260
  case 4:
23251
- ack = _context6.v;
23252
- return _context6.a(2, ack);
23261
+ ack = _context5.v;
23262
+ return _context5.a(2, ack);
23253
23263
  case 5:
23254
- _context6.p = 5;
23255
- _t2 = _context6.v;
23264
+ _context5.p = 5;
23265
+ _t2 = _context5.v;
23256
23266
  throw _t2;
23257
23267
  case 6:
23258
- return _context6.a(2);
23268
+ return _context5.a(2);
23259
23269
  }
23260
- }, _callee6, this, [[3, 5]]);
23270
+ }, _callee5, this, [[3, 5]]);
23261
23271
  }));
23262
23272
  function injectData(_x) {
23263
23273
  return _injectData.apply(this, arguments);
@@ -23986,12 +23996,9 @@ var VoiceInterface = /*#__PURE__*/function () {
23986
23996
  this.sdk = new _index_js__WEBPACK_IMPORTED_MODULE_0__.AgentSDK({
23987
23997
  agentId: config.agentId,
23988
23998
  appId: config.appId,
23989
- signedUrl: config.signedUrl,
23990
- // Pass through signedUrl if provided
23999
+ websocketUrl: config.websocketUrl,
23991
24000
  agentSettingsOverride: config.agentSettingsOverride,
23992
- // Pass through agentSettingsOverride if provided
23993
24001
  visualAssistant: visualAssistant,
23994
- // Pass through visualAssistant config (with fallback to agentSettingsOverride)
23995
24002
  variables: config.variables || {},
23996
24003
  language: config.language || 'en',
23997
24004
  // Output format configuration (defaults to 44100 Hz, 16-bit, PCM, raw)
@@ -24553,7 +24560,7 @@ var VoiceInterface = /*#__PURE__*/function () {
24553
24560
  value: (function () {
24554
24561
  var _proceedWithVoiceCall = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
24555
24562
  var _this3 = this;
24556
- var isResumeCall, panel, header, toggleText, _voiceInterface, originalSection, compactSection, idleState, _panel, fallbackPanel, sampleRate, mediaStream, floatingButton, fallbackButton, existingBar, _floatingButton, _fallbackButton, _idleState, _panel2, _fallbackPanel, deviceInfo, _idleState2, activeState, voiceInterface, signedUrl, connected, serverRejected, originalOnError, originalOnDisconnected, attempts, _this$sdk$voiceSDK, error, _existingBar, _existingBar2, _idleState3, _panel3, _fallbackPanel2, _floatingButton2, _fallbackButton2, updateTimer, _existingBar3, _existingBar4, _idleState4, _panel4, _fallbackPanel3, _floatingButton3, _fallbackButton3, _updateTimer, _deviceInfo, _t2, _t3, _t4, _t5, _t6, _t7;
24563
+ var isResumeCall, panel, header, toggleText, _voiceInterface, originalSection, compactSection, idleState, _panel, fallbackPanel, sampleRate, mediaStream, floatingButton, fallbackButton, existingBar, _floatingButton, _fallbackButton, _idleState, _panel2, _fallbackPanel, deviceInfo, _idleState2, activeState, voiceInterface, connected, serverRejected, originalOnError, originalOnDisconnected, attempts, _this$sdk$voiceSDK, error, _existingBar, _existingBar2, _idleState3, _panel3, _fallbackPanel2, _floatingButton2, _fallbackButton2, updateTimer, _existingBar3, _existingBar4, _idleState4, _panel4, _fallbackPanel3, _floatingButton3, _fallbackButton3, _updateTimer, _deviceInfo, _t2, _t3, _t4, _t5, _t6, _t7;
24557
24564
  return _regenerator().w(function (_context5) {
24558
24565
  while (1) switch (_context5.p = _context5.n) {
24559
24566
  case 0:
@@ -24730,20 +24737,13 @@ var VoiceInterface = /*#__PURE__*/function () {
24730
24737
  voiceInterface.scrollTop = 0;
24731
24738
  }
24732
24739
 
24733
- // Get signed URL and connect
24734
- // On mobile, permission is already granted at this point
24735
- // Get signed URL from config or construct it
24736
- signedUrl = this.config.signedUrl || (this.config.agentId && this.config.appId ? "wss://speech.talktopc.com/ws/conv?agentId=".concat(this.config.agentId, "&appId=").concat(this.config.appId) : null);
24737
- if (signedUrl) {
24740
+ // Connect using agentId + appId (URL built internally by SDK)
24741
+ if (this.config.agentId) {
24738
24742
  _context5.n = 7;
24739
24743
  break;
24740
24744
  }
24741
- throw new Error('signedUrl or agentId+appId required for voice calls');
24745
+ throw new Error('agentId is required for voice calls');
24742
24746
  case 7:
24743
- console.log('🔗 Got signed URL:', signedUrl);
24744
-
24745
- // If SDK is already connected, disconnect first to ensure clean state
24746
- // This is important for retrying after permission errors
24747
24747
  if (!(this.sdk && this.sdk.isConnected)) {
24748
24748
  _context5.n = 11;
24749
24749
  break;
@@ -24751,7 +24751,6 @@ var VoiceInterface = /*#__PURE__*/function () {
24751
24751
  console.log('🔄 SDK already connected, disconnecting for clean retry...');
24752
24752
  _context5.p = 8;
24753
24753
  this.sdk.disconnect();
24754
- // Wait a bit for disconnect to complete
24755
24754
  _context5.n = 9;
24756
24755
  return new Promise(function (resolve) {
24757
24756
  return setTimeout(resolve, 100);
@@ -24765,7 +24764,7 @@ var VoiceInterface = /*#__PURE__*/function () {
24765
24764
  console.warn('Warning: Error disconnecting existing connection:', _t3);
24766
24765
  case 11:
24767
24766
  _context5.n = 12;
24768
- return this.sdk.connect(signedUrl);
24767
+ return this.sdk.connect();
24769
24768
  case 12:
24770
24769
  connected = _context5.v;
24771
24770
  console.log('✅ Connected to WebSocket, connected:', connected);
@@ -24893,6 +24892,7 @@ var VoiceInterface = /*#__PURE__*/function () {
24893
24892
  case 26:
24894
24893
  console.log('🎤 Started listening - permission granted');
24895
24894
  this.isActive = true;
24895
+ this.resetMuteState();
24896
24896
 
24897
24897
  // Update mobile bar if it already exists (created early), otherwise create it
24898
24898
  if (this.isMobile) {
@@ -25026,6 +25026,7 @@ var VoiceInterface = /*#__PURE__*/function () {
25026
25026
  case 34:
25027
25027
  console.log('🎤 Started listening - permission granted');
25028
25028
  this.isActive = true;
25029
+ this.resetMuteState();
25029
25030
 
25030
25031
  // Update mobile bar if it already exists (created early), otherwise create it
25031
25032
  if (this.isMobile) {
@@ -25518,10 +25519,56 @@ var VoiceInterface = /*#__PURE__*/function () {
25518
25519
  }, {
25519
25520
  key: "endVoiceCall",
25520
25521
  value: function endVoiceCall() {
25521
- var _this$sdk2,
25522
- _this4 = this;
25522
+ var _this4 = this,
25523
+ _this$sdk2;
25523
25524
  console.log('🔴 Ending voice call...');
25524
25525
 
25526
+ // Reset mic/speaker state + UI immediately so next call never flashes muted UI
25527
+ this.isMicMuted = false;
25528
+ this.isSpeakerMuted = false;
25529
+
25530
+ // Reset mute button DOM state (desktop original + compact)
25531
+ ['desktopMuteBtn', 'desktopMuteBtnCompact'].forEach(function (id) {
25532
+ var btn = _this4.shadowRoot.getElementById(id);
25533
+ if (!btn) return;
25534
+ btn.classList.remove('muted');
25535
+ var micIcon = btn.querySelector('.desktop-mic-icon');
25536
+ var micOffIcon = btn.querySelector('.desktop-mic-off-icon');
25537
+ if (micIcon) micIcon.style.display = 'block';
25538
+ if (micOffIcon) micOffIcon.style.display = 'none';
25539
+ });
25540
+
25541
+ // Reset speaker button DOM state (desktop original + compact)
25542
+ ['desktopSpeakerBtn', 'desktopSpeakerBtnCompact'].forEach(function (id) {
25543
+ var btn = _this4.shadowRoot.getElementById(id);
25544
+ if (!btn) return;
25545
+ btn.classList.remove('muted');
25546
+ var speakerIcon = btn.querySelector('.desktop-speaker-icon');
25547
+ var speakerOffIcon = btn.querySelector('.desktop-speaker-off-icon');
25548
+ if (speakerIcon) speakerIcon.style.display = 'block';
25549
+ if (speakerOffIcon) speakerOffIcon.style.display = 'none';
25550
+ });
25551
+
25552
+ // Reset mobile mute button
25553
+ var mobileMuteBtn = document.getElementById('mobileMuteBtn');
25554
+ if (mobileMuteBtn) {
25555
+ mobileMuteBtn.classList.remove('muted');
25556
+ var mobileMicIcon = mobileMuteBtn.querySelector('.mobile-mic-icon');
25557
+ var mobileMicOffIcon = mobileMuteBtn.querySelector('.mobile-mic-off-icon');
25558
+ if (mobileMicIcon) mobileMicIcon.style.cssText = 'display: block !important; visibility: visible !important; opacity: 1 !important; width: 15px !important; height: 15px !important; margin: 0 !important; padding: 0 !important;';
25559
+ if (mobileMicOffIcon) mobileMicOffIcon.style.cssText = 'display: none !important; visibility: hidden !important; opacity: 0 !important;';
25560
+ }
25561
+
25562
+ // Reset mobile speaker button
25563
+ var mobileSpeakerBtn = document.getElementById('mobileSpeakerBtn');
25564
+ if (mobileSpeakerBtn) {
25565
+ mobileSpeakerBtn.classList.remove('muted');
25566
+ var mobileSpeakerIcon = mobileSpeakerBtn.querySelector('.mobile-speaker-icon');
25567
+ var mobileSpeakerOffIcon = mobileSpeakerBtn.querySelector('.mobile-speaker-off-icon');
25568
+ if (mobileSpeakerIcon) mobileSpeakerIcon.style.cssText = 'display: block !important; visibility: visible !important; opacity: 1 !important; width: 15px !important; height: 15px !important; margin: 0 !important; padding: 0 !important;';
25569
+ if (mobileSpeakerOffIcon) mobileSpeakerOffIcon.style.cssText = 'display: none !important; visibility: hidden !important; opacity: 0 !important;';
25570
+ }
25571
+
25525
25572
  // Reset resume info so next call is treated as a new call (not resume)
25526
25573
  // Resume info is only valid for the first call after page load/refresh
25527
25574
  this._resumeInfo = null;
@@ -26093,6 +26140,73 @@ var VoiceInterface = /*#__PURE__*/function () {
26093
26140
  return this.mobile.stopWaveformAnimation();
26094
26141
  }
26095
26142
 
26143
+ /**
26144
+ * Reset mic and speaker mute state + UI for a fresh call
26145
+ */
26146
+ }, {
26147
+ key: "resetMuteState",
26148
+ value: function resetMuteState() {
26149
+ var _this$sdk3,
26150
+ _this$sdk4,
26151
+ _this5 = this;
26152
+ this.isMicMuted = false;
26153
+ this.isSpeakerMuted = false;
26154
+ console.log('%c🎤 MIC/SPEAKER RESET - New call starting unmuted', 'background: #10b981; color: white; font-size: 14px; font-weight: bold; padding: 4px 8px; border-radius: 4px;');
26155
+
26156
+ // Ensure audio track is enabled
26157
+ if ((_this$sdk3 = this.sdk) !== null && _this$sdk3 !== void 0 && (_this$sdk3 = _this$sdk3.voiceSDK) !== null && _this$sdk3 !== void 0 && (_this$sdk3 = _this$sdk3.audioRecorder) !== null && _this$sdk3 !== void 0 && _this$sdk3.mediaStream) {
26158
+ var track = this.sdk.voiceSDK.audioRecorder.mediaStream.getAudioTracks()[0];
26159
+ if (track) track.enabled = true;
26160
+ }
26161
+
26162
+ // Ensure speaker is unmuted
26163
+ if ((_this$sdk4 = this.sdk) !== null && _this$sdk4 !== void 0 && (_this$sdk4 = _this$sdk4.voiceSDK) !== null && _this$sdk4 !== void 0 && _this$sdk4.audioPlayer) {
26164
+ this.sdk.voiceSDK.audioPlayer.setMuted(false);
26165
+ }
26166
+
26167
+ // Reset desktop mute buttons (original + compact)
26168
+ ['desktopMuteBtn', 'desktopMuteBtnCompact'].forEach(function (id) {
26169
+ var btn = _this5.shadowRoot.getElementById(id);
26170
+ if (!btn) return;
26171
+ btn.classList.remove('muted');
26172
+ var micIcon = btn.querySelector('.desktop-mic-icon');
26173
+ var micOffIcon = btn.querySelector('.desktop-mic-off-icon');
26174
+ if (micIcon) micIcon.style.display = 'block';
26175
+ if (micOffIcon) micOffIcon.style.display = 'none';
26176
+ });
26177
+
26178
+ // Reset desktop speaker buttons (original + compact)
26179
+ ['desktopSpeakerBtn', 'desktopSpeakerBtnCompact'].forEach(function (id) {
26180
+ var btn = _this5.shadowRoot.getElementById(id);
26181
+ if (!btn) return;
26182
+ btn.classList.remove('muted');
26183
+ var speakerIcon = btn.querySelector('.desktop-speaker-icon');
26184
+ var speakerOffIcon = btn.querySelector('.desktop-speaker-off-icon');
26185
+ if (speakerIcon) speakerIcon.style.display = 'block';
26186
+ if (speakerOffIcon) speakerOffIcon.style.display = 'none';
26187
+ });
26188
+
26189
+ // Reset mobile mute button
26190
+ var mobileMuteBtn = document.getElementById('mobileMuteBtn');
26191
+ if (mobileMuteBtn) {
26192
+ mobileMuteBtn.classList.remove('muted');
26193
+ var mobileMicIcon = mobileMuteBtn.querySelector('.mobile-mic-icon');
26194
+ var mobileMicOffIcon = mobileMuteBtn.querySelector('.mobile-mic-off-icon');
26195
+ if (mobileMicIcon) mobileMicIcon.style.cssText = 'display: block !important; visibility: visible !important; opacity: 1 !important; width: 15px !important; height: 15px !important; margin: 0 !important; padding: 0 !important;';
26196
+ if (mobileMicOffIcon) mobileMicOffIcon.style.cssText = 'display: none !important; visibility: hidden !important; opacity: 0 !important;';
26197
+ }
26198
+
26199
+ // Reset mobile speaker button
26200
+ var mobileSpeakerBtn = document.getElementById('mobileSpeakerBtn');
26201
+ if (mobileSpeakerBtn) {
26202
+ mobileSpeakerBtn.classList.remove('muted');
26203
+ var mobileSpeakerIcon = mobileSpeakerBtn.querySelector('.mobile-speaker-icon');
26204
+ var mobileSpeakerOffIcon = mobileSpeakerBtn.querySelector('.mobile-speaker-off-icon');
26205
+ if (mobileSpeakerIcon) mobileSpeakerIcon.style.cssText = 'display: block !important; visibility: visible !important; opacity: 1 !important; width: 15px !important; height: 15px !important; margin: 0 !important; padding: 0 !important;';
26206
+ if (mobileSpeakerOffIcon) mobileSpeakerOffIcon.style.cssText = 'display: none !important; visibility: hidden !important; opacity: 0 !important;';
26207
+ }
26208
+ }
26209
+
26096
26210
  /**
26097
26211
  * Cleanup resources
26098
26212
  */
@@ -27230,7 +27344,7 @@ var Styles = /*#__PURE__*/function () {
27230
27344
  var endCallBtnColor = this.config.endCallButtonColor || '#ef4444';
27231
27345
  var voiceSendButtonColor = this.config.sendButtonColor || ((_this$config$text = this.config.text) === null || _this$config$text === void 0 ? void 0 : _this$config$text.sendButtonColor) || this.config.voiceSendButtonColor || '#7C3AED';
27232
27346
  var important = ' !important';
27233
- return "\n /* Voice Interface Styles - Ultra-compact for Wix iframes */\n .voice-interface { \n display: none".concat(important, "; \n flex: 1; \n flex-direction: column;\n align-items: stretch; \n justify-content: flex-start; \n padding: 0; \n background: linear-gradient(180deg, #f8fafc 0%, #e0e7ff 100%);\n overflow: hidden;\n min-height: 0;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n }\n .voice-interface.active { display: flex").concat(important, "; }\n \n /* Voice States - Better scaling gaps */\n #voiceIdleState {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n height: 100%;\n min-height: 0;\n justify-content: center;\n overflow: hidden;\n flex: 1;\n box-sizing: border-box;\n gap: clamp(6px, 1.5vh, 12px);\n }\n \n #voiceActiveState {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n height: 100%;\n min-height: 0;\n justify-content: flex-start;\n overflow: hidden;\n flex: 1;\n box-sizing: border-box;\n gap: 0;\n padding: 0;\n }\n \n #voiceActiveState[style*=\"display: none\"] {\n display: none !important;\n }\n \n /* Voice Avatar - Scales better from small to large */\n .voice-avatar,\n .voice-avatar-active {\n width: clamp(80px, 18vh, 160px);\n height: clamp(80px, 18vh, 160px);\n aspect-ratio: 1;\n border-radius: 50%;\n background: linear-gradient(135deg, ").concat(avatarBg, " 0%, ").concat(avatarActiveBg, " 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: clamp(40px, 9vh, 80px);\n margin: 0;\n box-shadow: 0 8px 30px rgba(102, 126, 234, 0.3);\n transition: all 0.3s ease;\n flex-shrink: 0;\n position: relative;\n }\n \n .voice-avatar-active {\n animation: avatarPulse 2s ease-in-out infinite;\n }\n \n @keyframes avatarPulse {\n 0%, 100% { \n transform: scale(1);\n }\n 50% { \n transform: scale(1.05);\n }\n }\n \n .voice-avatar-active.speaking {\n animation: avatarSpeak 0.5s ease-in-out infinite;\n }\n \n @keyframes avatarSpeak {\n 0%, 100% { transform: scale(1); }\n 50% { transform: scale(1.08); }\n }\n \n /* Voice Rings Animation */\n .voice-rings {\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n }\n \n .voice-ring {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n border: 2px solid rgba(102, 126, 234, 0.3);\n border-radius: 50%;\n opacity: 0;\n animation: ringExpand 2s ease-out infinite;\n }\n \n .voice-ring:nth-child(2) { animation-delay: 0.5s; }\n .voice-ring:nth-child(3) { animation-delay: 1s; }\n \n @keyframes ringExpand {\n 0% {\n width: 100%;\n height: 100%;\n opacity: 0.6;\n }\n 100% {\n width: 160%;\n height: 160%;\n opacity: 0;\n }\n }\n \n /* Voice Status - Scales with container */\n .voice-status {\n text-align: center;\n margin: 0;\n flex-shrink: 0;\n min-height: 0;\n }\n \n .voice-status-title {\n font-size: clamp(12px, 3vh, 20px);\n font-weight: 600;\n color: ").concat(statusTitleColor, ";\n margin-bottom: clamp(2px, 0.5vh, 4px);\n line-height: 1.2;\n }\n \n .voice-status-subtitle {\n font-size: clamp(10px, 2vh, 14px);\n color: ").concat(statusSubtitleColor, ";\n line-height: 1.2;\n }\n \n /* Start Call Button - Scales with container */\n .start-call-btn {\n margin: 0;\n width: min(280px, 70vw)").concat(important, ";\n height: clamp(48px, 8vh, 64px)").concat(important, ";\n border-radius: clamp(24px, 4vh, 32px)").concat(important, ";\n border: none").concat(important, ";\n background: ").concat(startCallBtnColor).concat(important, ";\n color: ").concat(startCallBtnTextColor).concat(important, ";\n font-size: clamp(14px, 2.5vh, 18px)").concat(important, ";\n font-weight: 600").concat(important, ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n gap: clamp(8px, 1.5vh, 12px);\n box-shadow: 0 12px 30px rgba(102, 126, 234, 0.4);\n transition: all 0.3s ease;\n flex-shrink: 0;\n }\n \n .start-call-btn svg {\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n width: auto").concat(important, ";\n height: auto").concat(important, ";\n }\n \n .start-call-btn svg {\n width: clamp(22px, 4vh, 32px);\n height: clamp(22px, 4vh, 32px);\n }\n \n .start-call-btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 12px 28px rgba(102, 126, 234, 0.5);\n }\n \n .start-call-btn:active {\n transform: translateY(-1px);\n }\n .start-call-btn:disabled {\n cursor: not-allowed").concat(important, ";\n opacity: 0.6").concat(important, ";\n }\n \n /* Connecting Spinner */\n .connecting-spinner {\n display: inline-block;\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-top-color: ").concat(startCallBtnTextColor, ";\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-right: 8px;\n vertical-align: middle;\n }\n \n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n \n /* Voice Transcript - Scales with container */\n .voice-transcript {\n background: ").concat(transcriptBg, ";\n padding: clamp(6px, 1.5vh, 12px);\n border-radius: 10px;\n width: min(360px, calc(100% - 40px));\n margin: 0;\n min-height: clamp(80px, 15vh, 120px);\n max-height: clamp(100px, 18vh, 140px);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n flex-shrink: 1;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n }\n \n .transcript-label {\n font-size: clamp(8px, 1.4vh, 11px);\n color: ").concat(transcriptLabelColor, ";\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: clamp(3px, 0.6vh, 6px);\n flex-shrink: 0;\n word-wrap: break-word;\n }\n \n .transcript-text {\n font-size: clamp(11px, 2vh, 15px);\n color: ").concat(transcriptTextColor, ";\n line-height: 1.4;\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n word-wrap: break-word;\n overflow-wrap: break-word;\n }\n \n .transcript-text.empty {\n color: #cbd5e1;\n font-style: italic;\n }\n \n /* Voice Text Input Area - Type while on voice call */\n .voice-text-input-area {\n width: 100%;\n padding: 14px 16px;\n margin: 0;\n flex-shrink: 0;\n background: #ffffff;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n box-sizing: border-box;\n }\n \n .voice-input-wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n background: #f1f5f9;\n border-radius: 12px;\n padding: 4px 4px 4px 14px;\n border: 1px solid transparent;\n transition: all 0.2s ease;\n }\n \n .voice-input-wrapper:focus-within {\n background: #fff;\n border-color: #a855f7;\n box-shadow: 0 0 0 3px rgba(168, 85, 247, 0.1);\n }\n \n .voice-text-input {\n flex: 1;\n border: none;\n outline: none;\n font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 14px;\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n background: transparent;\n padding: 10px 0;\n }\n \n .voice-text-input::placeholder {\n color: #94a3b8;\n }\n \n .voice-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n border-radius: 10px;\n border: none;\n background: ").concat(voiceSendButtonColor).concat(important, ";\n color: #fff;\n cursor: pointer;\n transition: transform 0.2s ease;\n flex-shrink: 0;\n }\n \n .voice-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n }\n \n .voice-send-btn:active:not(:disabled) {\n transform: scale(0.95);\n }\n \n .voice-send-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n \n .voice-send-btn svg {\n width: 16px;\n height: 16px;\n }\n \n .voice-input-hint {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n margin-top: 10px;\n font-size: 11px;\n color: #64748b;\n transition: color 0.2s ease;\n }\n \n .voice-input-hint svg {\n width: 12px;\n height: 12px;\n color: #10b981;\n }\n \n /* Text input status states */\n .voice-input-hint--sending {\n color: #666;\n }\n \n .voice-input-hint--success {\n color: #28a745;\n }\n \n .voice-input-hint--queued {\n color: #ffc107;\n }\n \n .voice-input-hint--error {\n color: #dc3545;\n }\n \n /* Disabled input styling */\n .voice-text-input:disabled,\n #mobileTextInput:disabled {\n background-color: #f5f5f5;\n cursor: not-allowed;\n }\n \n .voice-send-btn:disabled,\n #mobileSendBtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n \n /* Voice Controls - Scales with container */\n .voice-controls {\n display: flex;\n gap: clamp(8px, 1.8vh, 14px);\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin: 0;\n padding-top: 0;\n }\n \n .voice-control-btn {\n width: clamp(48px, 9vh, 72px)").concat(important, ";\n height: clamp(48px, 9vh, 72px)").concat(important, ";\n min-width: clamp(48px, 9vh, 72px)").concat(important, ";\n min-height: clamp(48px, 9vh, 72px)").concat(important, ";\n max-width: clamp(48px, 9vh, 72px)").concat(important, ";\n max-height: clamp(48px, 9vh, 72px)").concat(important, ";\n aspect-ratio: 1").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n transition: all 0.2s;\n position: relative").concat(important, ";\n flex-shrink: 0;\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 .voice-control-btn svg {\n width: 48%").concat(important, ";\n height: 48%").concat(important, ";\n min-width: 48%").concat(important, ";\n min-height: 48%").concat(important, ";\n max-width: 48%").concat(important, ";\n max-height: 48%").concat(important, ";\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n position: relative").concat(important, ";\n flex-shrink: 0").concat(important, ";\n }\n \n .voice-control-btn.primary {\n width: clamp(54px, 10vh, 80px)").concat(important, ";\n height: clamp(54px, 10vh, 80px)").concat(important, ";\n min-width: clamp(54px, 10vh, 80px)").concat(important, ";\n min-height: clamp(54px, 10vh, 80px)").concat(important, ";\n max-width: clamp(54px, 10vh, 80px)").concat(important, ";\n max-height: clamp(54px, 10vh, 80px)").concat(important, ";\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)").concat(important, ";\n color: white").concat(important, ";\n box-shadow: 0 6px 18px rgba(102, 126, 234, 0.4);\n }\n \n .voice-control-btn.primary:hover {\n transform: scale(1.05);\n }\n \n .voice-control-btn.primary.active {\n background: ").concat(endCallBtnColor).concat(important, ";\n animation: recordingPulse 1.5s ease-in-out infinite;\n }\n .voice-control-btn.primary.active svg {\n fill: white").concat(important, ";\n }\n \n /* More specific selectors for WordPress compatibility */\n #endCallBtn.voice-control-btn.primary.active,\n #muteBtn.voice-control-btn.secondary,\n #speakerBtn.voice-control-btn.secondary {\n border-radius: 50% !important;\n width: clamp(48px, 9vh, 72px) !important;\n height: clamp(48px, 9vh, 72px) !important;\n min-width: clamp(48px, 9vh, 72px) !important;\n min-height: clamp(48px, 9vh, 72px) !important;\n max-width: clamp(48px, 9vh, 72px) !important;\n max-height: clamp(48px, 9vh, 72px) !important;\n aspect-ratio: 1 !important;\n overflow: hidden !important;\n }\n \n #endCallBtn.voice-control-btn.primary.active {\n width: clamp(54px, 10vh, 80px) !important;\n height: clamp(54px, 10vh, 80px) !important;\n min-width: clamp(54px, 10vh, 80px) !important;\n min-height: clamp(54px, 10vh, 80px) !important;\n max-width: clamp(54px, 10vh, 80px) !important;\n max-height: clamp(54px, 10vh, 80px) !important;\n }\n \n \n /* Microphone button specific background color */\n #muteBtn.voice-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n /* Speaker button specific background color */\n #speakerBtn.voice-control-btn.secondary {\n background: ").concat(speakerButtonColor).concat(important, ";\n }\n \n #endCallBtn.voice-control-btn.primary.active svg,\n #muteBtn.voice-control-btn.secondary svg,\n #speakerBtn.voice-control-btn.secondary svg {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 48% !important;\n height: 48% !important;\n margin: 0 !important;\n padding: 0 !important;\n position: relative !important;\n }\n \n @keyframes recordingPulse {\n 0%, 100% { \n box-shadow: 0 6px 16px rgba(239, 68, 68, 0.4);\n }\n 50% { \n box-shadow: 0 6px 24px rgba(239, 68, 68, 0.7);\n }\n }\n \n .voice-control-btn.secondary {\n background: ").concat(controlBtnColor).concat(important, ";\n color: ").concat(controlBtnSecondaryColor).concat(important, ";\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);\n width: clamp(48px, 9vh, 72px)").concat(important, ";\n height: clamp(48px, 9vh, 72px)").concat(important, ";\n min-width: clamp(48px, 9vh, 72px)").concat(important, ";\n min-height: clamp(48px, 9vh, 72px)").concat(important, ";\n max-width: clamp(48px, 9vh, 72px)").concat(important, ";\n max-height: clamp(48px, 9vh, 72px)").concat(important, ";\n }\n \n .voice-control-btn.secondary:hover {\n background: #f8fafc").concat(important, ";\n transform: scale(1.05);\n }\n \n .voice-control-btn.secondary.muted {\n background: #f3f4f6").concat(important, ";\n }\n \n .voice-control-btn.secondary.muted .mute-icon {\n stroke: #9ca3af !important;\n }\n \n .voice-control-btn.secondary svg {\n width: 48%").concat(important, ";\n height: 48%").concat(important, ";\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n position: relative").concat(important, ";\n }\n \n .voice-timer {\n position: absolute;\n bottom: clamp(-18px, -3vh, -24px);\n font-size: clamp(9px, 1.6vh, 12px);\n color: #64748b;\n font-weight: 500;\n white-space: nowrap;\n }\n \n /* ===== DESKTOP VOICE SECTION - New Design ===== */\n .desktop-voice-section {\n padding: 16px 20px;\n background: linear-gradient(180deg, #ffffff 0%, rgba(168, 85, 247, 0.04) 100%);\n width: 100%;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n box-sizing: border-box;\n text-align: center;\n }\n \n /* Ensure all children are centered */\n .desktop-voice-section > * {\n margin-left: auto;\n margin-right: auto;\n }\n \n .desktop-timer {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 6px !important;\n padding: 5px 10px !important;\n background: rgba(0, 0, 0, 0.05) !important;\n border-radius: 20px !important;\n font-family: 'JetBrains Mono', 'Courier New', monospace;\n font-size: 11px !important;\n color: #64748b !important;\n margin: 0 auto !important;\n }\n \n .desktop-timer .timer-dot {\n width: 5px").concat(important, ";\n height: 5px").concat(important, ";\n background: #ef4444").concat(important, ";\n border-radius: 50%").concat(important, ";\n animation: timerPulse 1s ease-in-out infinite").concat(important, ";\n }\n \n @keyframes timerPulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n }\n \n .desktop-avatar-container {\n margin-bottom: 12px;\n }\n \n .desktop-avatar-large {\n width: 80px !important;\n height: 80px !important;\n border-radius: 20px !important;\n margin: 0 auto 12px !important;\n box-shadow: 0 8px 24px rgba(168, 85, 247, 0.35) !important;\n background: linear-gradient(135deg, ").concat(avatarBg, " 0%, ").concat(avatarActiveBg, " 100%) !important;\n }\n \n .desktop-waveform {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 4px !important;\n height: 36px !important;\n width: 100% !important;\n }\n \n .desktop-waveform-bar {\n width: 4px !important;\n background: rgba(255, 255, 255, 0.9) !important;\n border-radius: 2px !important;\n animation: waveformAnimation 0.8s ease-in-out infinite !important;\n }\n \n .desktop-waveform-bar[data-index=\"0\"] { height: 14px !important; animation-delay: 0s !important; }\n .desktop-waveform-bar[data-index=\"1\"] { height: 26px !important; animation-delay: 0.1s !important; }\n .desktop-waveform-bar[data-index=\"2\"] { height: 36px !important; animation-delay: 0.2s !important; }\n .desktop-waveform-bar[data-index=\"3\"] { height: 22px !important; animation-delay: 0.3s !important; }\n .desktop-waveform-bar[data-index=\"4\"] { height: 16px !important; animation-delay: 0.4s !important; }\n \n @keyframes waveformAnimation {\n 0%, 100% { transform: scaleY(0.5); }\n 50% { transform: scaleY(1); }\n }\n \n .desktop-waveform.paused .desktop-waveform-bar {\n animation-play-state: paused;\n }\n\n /* New main waveform (used in updated template) */\n .desktop-main-waveform {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 3px !important;\n height: 48px !important;\n width: 100% !important;\n max-width: 200px !important;\n margin: 0 auto !important;\n padding: 0 20px !important;\n }\n\n .desktop-main-waveform .waveform-bar {\n width: 3px !important;\n background: #a855f7 !important;\n border-radius: 2px !important;\n height: 8px !important;\n animation: waveformAnimation 0.8s ease-in-out infinite !important;\n }\n\n .desktop-main-waveform .waveform-bar:nth-child(1) { height: 12px !important; animation-delay: 0s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(2) { height: 20px !important; animation-delay: 0.05s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(3) { height: 28px !important; animation-delay: 0.1s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(4) { height: 36px !important; animation-delay: 0.15s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(5) { height: 44px !important; animation-delay: 0.2s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(6) { height: 50px !important; animation-delay: 0.25s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(7) { height: 54px !important; animation-delay: 0.3s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(8) { height: 56px !important; animation-delay: 0.35s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(9) { height: 54px !important; animation-delay: 0.4s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(10) { height: 50px !important; animation-delay: 0.45s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(11) { height: 44px !important; animation-delay: 0.5s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(12) { height: 36px !important; animation-delay: 0.55s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(13) { height: 28px !important; animation-delay: 0.6s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(14) { height: 20px !important; animation-delay: 0.65s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(15) { height: 12px !important; animation-delay: 0.7s !important; }\n\n .desktop-status {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 5px !important;\n font-size: 12px !important;\n color: ").concat(statusTitleColor, ";\n font-weight: 500;\n width: 100%;\n text-align: center;\n margin: 0 auto;\n }\n \n .desktop-status .status-dot {\n width: 5px !important;\n height: 5px !important;\n background: ").concat(statusDotColor, " !important;\n border-radius: 50% !important;\n animation: statusPulse 1.5s ease-in-out infinite !important;\n }\n \n @keyframes statusPulse {\n 0%, 100% { transform: scale(1); opacity: 1; }\n 50% { transform: scale(1.15); opacity: 0.8; }\n }\n \n .desktop-live-waveform {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n height: 48px;\n margin-bottom: 20px;\n }\n \n .desktop-live-bar {\n width: 3px;\n background: linear-gradient(180deg, ").concat(avatarBg, ", ").concat(avatarActiveBg, ");\n border-radius: 2px;\n transition: height 0.1s ease;\n height: 8px;\n }\n \n .desktop-controls {\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: center;\n width: 100%;\n margin: 0 auto;\n }\n \n .desktop-control-btn {\n width: 46px;\n height: 46px;\n border-radius: 50%;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .desktop-control-btn svg {\n width: 20px;\n height: 20px;\n }\n \n .desktop-mic-icon,\n .desktop-speaker-icon {\n width: 20px !important;\n height: 20px !important;\n display: block;\n flex-shrink: 0;\n }\n \n .desktop-control-btn.secondary.muted .desktop-mic-icon,\n .desktop-control-btn.secondary.muted .desktop-speaker-icon {\n width: 20px !important;\n height: 20px !important;\n }\n \n \n .desktop-control-btn.secondary:hover {\n background: rgba(0, 0, 0, 0.1);\n color: #1e293b;\n transform: scale(1.05);\n }\n .desktop-control-btn.secondary.muted {\n background: #f3f4f6;\n color: #9ca3af;\n }\n \n .desktop-control-btn.secondary.muted .desktop-mic-icon,\n .desktop-control-btn.secondary.muted .desktop-speaker-icon {\n stroke: #9ca3af;\n }\n \n .desktop-control-btn.secondary {\n position: relative;\n }\n \n \n /* Desktop microphone button background color */\n #desktopMuteBtn.desktop-control-btn.secondary,\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n /* Desktop speaker button background color */\n #desktopSpeakerBtn.desktop-control-btn.secondary,\n #desktopSpeakerBtnCompact.compact-control-btn.secondary {\n background: ").concat(speakerButtonColor).concat(important, ";\n }\n .desktop-mic-off-icon,\n .desktop-speaker-off-icon {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 46px;\n height: 46px;\n transform: translate(-50%, -50%);\n z-index: 10;\n }\n .desktop-control-btn.danger {\n width: 50px;\n height: 50px;\n background: ").concat(endCallBtnColor).concat(important, ";\n color: #ffffff;\n box-shadow: 0 4px 14px rgba(239, 68, 68, 0.4);\n overflow: visible;\n }\n \n .desktop-control-btn.danger svg {\n width: 20px;\n height: 20px;\n overflow: visible;\n }\n \n .desktop-control-btn.danger:hover {\n transform: scale(1.06);\n box-shadow: 0 6px 20px rgba(239, 68, 68, 0.5);\n }\n \n .desktop-control-btn.danger:hover {\n transform: scale(1.06);\n box-shadow: 0 6px 20px rgba(239, 68, 68, 0.5);\n }\n \n \n /* ===== COMPACT VOICE SECTION (Single-row layout) ===== */\n .compact-voice-section {\n padding: 10px 14px;\n background: linear-gradient(180deg, #ffffff, rgba(168, 85, 247, 0.04));\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.06);\n min-height: 62px;\n flex-shrink: 0;\n }\n \n .compact-left {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n \n .compact-avatar {\n width: 42px;\n height: 42px;\n min-width: 42px;\n min-height: 42px;\n border-radius: 12px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: visible;\n position: relative;\n }\n \n /* Waveform container in compact avatar - ensure it's visible */\n .compact-avatar .desktop-main-waveform {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 2px !important;\n height: 100% !important;\n width: 100% !important;\n padding: 4px !important;\n transform: scale(0.75) !important;\n transform-origin: center !important;\n }\n \n /* Ensure waveform bars are visible and animated in compact mode */\n .compact-avatar .desktop-main-waveform .waveform-bar {\n width: 2px !important;\n min-width: 2px !important;\n background: #a855f7 !important;\n border-radius: 1px !important;\n flex-shrink: 0 !important;\n animation: waveformAnimation 0.8s ease-in-out infinite !important;\n }\n \n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(1) { height: 6px !important; animation-delay: 0s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(2) { height: 10px !important; animation-delay: 0.05s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(3) { height: 14px !important; animation-delay: 0.1s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(4) { height: 18px !important; animation-delay: 0.15s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(5) { height: 22px !important; animation-delay: 0.2s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(6) { height: 26px !important; animation-delay: 0.25s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(7) { height: 28px !important; animation-delay: 0.3s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(8) { height: 30px !important; animation-delay: 0.35s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(9) { height: 28px !important; animation-delay: 0.4s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(10) { height: 26px !important; animation-delay: 0.45s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(11) { height: 22px !important; animation-delay: 0.5s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(12) { height: 18px !important; animation-delay: 0.55s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(13) { height: 14px !important; animation-delay: 0.6s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(14) { height: 10px !important; animation-delay: 0.65s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(15) { height: 6px !important; animation-delay: 0.7s !important; }\n\n }\n \n .compact-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n \n .compact-timer {\n display: flex;\n align-items: center;\n gap: 5px;\n font-family: 'JetBrains Mono', 'Courier New', monospace;\n font-size: 13px;\n font-weight: 600;\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n }\n \n .compact-timer .timer-dot {\n width: 6px").concat(important, ";\n height: 6px").concat(important, ";\n background: #ef4444").concat(important, ";\n border-radius: 50%").concat(important, ";\n animation: timerPulse 1s ease-in-out infinite").concat(important, ";\n }\n \n .compact-status {\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 4px").concat(important, ";\n font-size: 11px").concat(important, ";\n color: ").concat(statusTitleColor).concat(important, ";\n }\n \n .compact-status .status-dot {\n width: 5px").concat(important, ";\n height: 5px").concat(important, ";\n background: ").concat(statusDotColor).concat(important, ";\n border-radius: 50%").concat(important, ";\n animation: statusPulse 1.5s ease-in-out infinite").concat(important, ";\n }\n \n @keyframes statusPulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.7; transform: scale(1.1); }\n }\n \n .compact-controls {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n \n .compact-control-btn {\n width: 36px;\n height: 36px;\n min-width: 36px;\n min-height: 36px;\n border-radius: 50%;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n padding: 0;\n position: relative;\n }\n \n .compact-control-btn svg {\n width: 16px;\n height: 16px;\n }\n \n .compact-control-btn.secondary {\n background: #f1f5f9;\n color: #64748b;\n }\n \n \n /* Compact speaker button background color */\n #desktopSpeakerBtnCompact.compact-control-btn.secondary {\n background: ").concat(speakerButtonColor).concat(important, ";\n }\n /* Compact microphone button background color */\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n .compact-control-btn.secondary:hover {\n background: #e2e8f0;\n color: #475569;\n }\n \n .compact-control-btn.secondary.muted {\n background: rgba(239, 68, 68, 0.1);\n color: #ef4444;\n }\n \n \n .compact-control-btn.secondary.muted .desktop-mic-icon,\n .compact-control-btn.secondary.muted .desktop-speaker-icon {\n stroke: #ef4444;\n }\n \n .compact-control-btn.secondary.muted .desktop-mic-off-icon,\n .compact-control-btn.secondary.muted .desktop-speaker-off-icon {\n width: 46px;\n height: 46px;\n }\n\n .compact-control-btn.danger {\n width: 40px;\n height: 40px;\n min-width: 40px;\n min-height: 40px;\n background: ").concat(endCallBtnColor).concat(important, ";\n color: white;\n box-shadow: 0 3px 10px rgba(239, 68, 68, 0.35);\n }\n \n .compact-control-btn.danger:hover {\n transform: scale(1.05);\n box-shadow: 0 4px 14px rgba(239, 68, 68, 0.45);\n }\n \n .compact-control-btn.danger svg {\n width: 18px;\n height: 18px;\n overflow: visible;\n }\n \n/* ===== CONVERSATION PANEL ===== */\n .desktop-conversation-panel {\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n width: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n flex: 1;\n }\n \n .conversation-header {\n padding: 10px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: #fafafa;\n cursor: pointer;\n flex-shrink: 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.04);\n transition: background 0.2s ease;\n }\n \n .conversation-header:hover {\n background: #f5f5f5;\n }\n \n .conversation-label {\n font-size: 11px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n \n .conversation-toggle {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: #94a3b8;\n font-weight: 500;\n }\n \n .conversation-toggle svg {\n transition: transform 0.2s ease;\n }\n \n .conversation-header.expanded .conversation-toggle svg {\n transform: rotate(180deg);\n }\n \n /* ===== COLLAPSED: Live Transcript Only (2 lines) ===== */\n .live-transcript-collapsed {\n padding: 12px 16px;\n background: #fafafa;\n display: flex;\n flex-direction: column;\n gap: 6px;\n flex-shrink: 0;\n min-height: 50px;\n }\n \n .live-indicator {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 9px;\n font-weight: 700;\n color: ").concat(liveIndicatorTextColor).concat(important, ";\n text-transform: uppercase;\n letter-spacing: 0.08em;\n }\n \n .live-indicator .live-dot {\n height: 5px;\n width: 5px;\n background: ").concat(liveIndicatorDotColor).concat(important, ";\n border-radius: 50%;\n animation: statusPulse 1.5s ease-in-out infinite;\n }\n \n .live-text-collapsed {\n font-size: ").concat(liveTranscriptFontSize).concat(important, ";\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n \n .live-text-collapsed.muted {\n color: #94a3b8;\n font-style: italic;\n }\n \n .typing-cursor {\n display: inline-block;\n width: 2px;\n height: 14px;\n background: #a855f7;\n margin-left: 2px;\n animation: blink 1s step-end infinite;\n vertical-align: middle;\n }\n \n @keyframes blink {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0; }\n }\n \n /* ===== EXPANDED: Full Conversation History ===== */\n .conversation-history {\n flex: 1;\n flex-direction: column;\n gap: 10px;\n overflow-y: auto;\n padding: 14px 16px;\n min-height: 0;\n }\n .conversation-history.visible {\n display: flex;\n }\n\n .conversation-messages {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n /* Message Rows */\n .message-row {\n display: flex;\n gap: 8px;\n animation: msgIn 0.25s ease;\n }\n \n @keyframes msgIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n \n @keyframes slideOut {\n from { opacity: 1; transform: translateY(0); }\n to { opacity: 0; transform: translateY(-10px); }\n }\n \n .message-row.user {\n flex-direction: row-reverse;\n }\n \n .message-avatar {\n width: 28px;\n height: 28px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .message-avatar.assistant {\n background: linear-gradient(135deg, #c084fc, #a855f7);\n }\n\n .message-avatar.assistant .orb {\n width: 12px;\n height: 12px;\n background: rgba(255, 255, 255, 0.9);\n border-radius: 50%;\n }\n\n .message-avatar.user {\n background: linear-gradient(135deg, #64748b, #475569);\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n }\n\n .message-bubble {\n max-width: 80%;\n padding: 9px 13px;\n border-radius: 12px;\n font-size: 13px;\n line-height: 1.5;\n }\n \n .message-row.assistant .message-bubble {\n background: #fff;\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n border: 1px solid rgba(0, 0, 0, 0.06);\n border-bottom-left-radius: 4px;\n }\n \n .message-row.user .message-bubble {\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n color: #fff;\n border-bottom-right-radius: 4px;\n }\n \n /* Live message at bottom of history */\n .live-message-row {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px dashed rgba(0, 0, 0, 0.08);\n margin-top: auto;\n }\n \n .live-message-row .message-bubble {\n background: #fff;\n border: 1px solid rgba(16, 185, 129, 0.3);\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n position: relative;\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n }\n \n .live-message-row .live-badge {\n position: absolute;\n top: -8px;\n left: 10px;\n background: #10b981;\n color: #fff;\n font-size: 8px;\n font-weight: 700;\n padding: 2px 6px;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n \n /* Hide/show based on expanded state */\n .desktop-conversation-panel.collapsed .conversation-history {\n display: none;\n }\n \n .desktop-conversation-panel.collapsed .live-transcript-collapsed {\n display: flex;\n }\n \n .desktop-conversation-panel.expanded .conversation-history {\n display: flex;\n max-height: 400px;\n }\n \n .desktop-conversation-panel.expanded .live-transcript-collapsed {\n display: none;\n }\n \n /* ===== DARK MODE SUPPORT ===== */\n @media (prefers-color-scheme: dark) {\n .desktop-voice-section {\n background: linear-gradient(180deg, #1e1e2e 0%, rgba(168, 85, 247, 0.08) 100%);\n }\n\n .desktop-timer {\n color: #94a3b8;\n }\n\n .desktop-status {\n color: #34d399;\n }\n\n .desktop-status .status-dot {\n \n .desktop-control-btn.secondary.muted {\n background: rgba(255, 255, 255, 0.1);\n color: #9ca3af;\n \n .compact-voice-section {\n background: linear-gradient(180deg, #1e1e2e 0%, rgba(168, 85, 247, 0.08) 100%);\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n \n .compact-timer {\n color: #e2e8f0;\n }\n \n .compact-status {\n color: #34d399;\n }\n \n .compact-status .status-dot {\n background: #34d399;\n }\n \n .compact-control-btn.secondary {\n background: rgba(255, 255, 255, 0.08);\n color: #94a3b8;\n }\n \n .compact-control-btn.secondary:hover {\n background: rgba(255, 255, 255, 0.15);\n color: #e2e8f0;\n }\n \n .compact-control-btn.secondary.muted {\n background: rgba(239, 68, 68, 0.2);\n color: #f87171;\n }\n\n }\n \n .desktop-control-btn.secondary.muted svg {\n \n .desktop-control-btn.secondary {\n position: relative;\n }\n \n /* Desktop microphone button background color */\n #desktopMuteBtn.desktop-control-btn.secondary,\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n .desktop-mic-off-icon,\n .desktop-speaker-off-icon {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 20px;\n height: 20px;\n }\n \n .desktop-control-btn.secondary.muted {\n background: #f3f4f6;\n color: #9ca3af;\n }\n \n .desktop-control-btn.secondary.muted svg {\n \n .desktop-control-btn.secondary {\n position: relative;\n }\n \n /* Desktop microphone button background color */\n #desktopMuteBtn.desktop-control-btn.secondary,\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n .desktop-mic-off-icon,\n .desktop-speaker-off-icon {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 20px;\n height: 20px;\n }\n stroke: #9ca3af;\n }\n stroke: #9ca3af;\n }\n background: #34d399;\n }\n\n .desktop-control-btn.secondary {\n background: rgba(255, 255, 255, 0.08);\n color: #94a3b8;\n }\n\n .desktop-control-btn.secondary:hover {\n background: rgba(255, 255, 255, 0.15);\n color: #e2e8f0;\n }\n\n .desktop-conversation-panel {\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n }\n\n .conversation-header {\n background: #1a1a2e;\n }\n\n .conversation-header:hover {\n background: #252540;\n }\n\n .conversation-label {\n color: #94a3b8;\n }\n\n .conversation-toggle {\n color: #64748b;\n }\n\n .live-transcript-preview {\n background: #1a1a2e;\n }\n .live-indicator {\n color: ").concat(liveIndicatorTextColor).concat(important, ";\n }\n .live-indicator .live-dot {\n background: ").concat(liveIndicatorDotColor).concat(important, ";\n }\n\n .live-text {\n color: #e2e8f0;\n }\n\n .live-text.muted {\n color: #64748b;\n }\n\n .conversation-history {\n background: #1a1a2e;\n }\n\n .conversation-msg.assistant .conversation-msg-bubble {\n background: #252540;\n color: #e2e8f0;\n border: 1px solid rgba(255, 255, 255, 0.08);\n }\n\n .voice-text-input-area {\n background: #1a1a2e;\n }\n\n .voice-text-input {\n background: #252540 !important;\n color: #e2e8f0 !important;\n border-color: rgba(255, 255, 255, 0.1) !important;\n }\n\n .voice-text-input::placeholder {\n color: #64748b !important;\n }\n\n .voice-text-input:focus {\n border-color: ").concat(avatarBg, " !important;\n box-shadow: 0 0 0 3px rgba(168, 85, 247, 0.2) !important;\n }\n\n .voice-input-hint {\n color: #64748b !important;\n }\n\n .voice-send-btn {\n background: ").concat(voiceSendButtonColor, " !important;\n }\n\n .voice-send-btn:disabled {\n background: #374151 !important;\n color: #4b5563 !important;\n }\n }\n\n /* Mobile optimization */\n @media (max-width: 768px) {\n .voice-interface {\n padding: 6px 10px;\n }\n }\n \n @media (max-width: 480px) {\n .voice-interface {\n padding: 5px 8px;\n }\n }\n \n /* Mobile Voice Call UI - Shared styles (also used in generateMobileCSS) */\n ").concat(this._getSharedMobileCSS(important), "\n\n ");
27347
+ return "\n /* Voice Interface Styles - Ultra-compact for Wix iframes */\n .voice-interface { \n display: none".concat(important, "; \n flex: 1; \n flex-direction: column;\n align-items: stretch; \n justify-content: flex-start; \n padding: 0; \n background: linear-gradient(180deg, #f8fafc 0%, #e0e7ff 100%);\n overflow: hidden;\n min-height: 0;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n }\n .voice-interface.active { display: flex").concat(important, "; }\n \n /* Voice States - Better scaling gaps */\n #voiceIdleState {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n height: 100%;\n min-height: 0;\n justify-content: center;\n overflow: hidden;\n flex: 1;\n box-sizing: border-box;\n gap: clamp(6px, 1.5vh, 12px);\n }\n \n #voiceActiveState {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n width: 100%;\n height: 100%;\n min-height: 0;\n justify-content: flex-start;\n overflow: hidden;\n flex: 1;\n box-sizing: border-box;\n gap: 0;\n padding: 0;\n }\n \n #voiceActiveState[style*=\"display: none\"] {\n display: none !important;\n }\n \n /* Voice Avatar - Scales better from small to large */\n .voice-avatar,\n .voice-avatar-active {\n width: clamp(80px, 18vh, 160px);\n height: clamp(80px, 18vh, 160px);\n aspect-ratio: 1;\n border-radius: 50%;\n background: linear-gradient(135deg, ").concat(avatarBg, " 0%, ").concat(avatarActiveBg, " 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: clamp(40px, 9vh, 80px);\n margin: 0;\n box-shadow: 0 8px 30px rgba(102, 126, 234, 0.3);\n transition: all 0.3s ease;\n flex-shrink: 0;\n position: relative;\n }\n \n .voice-avatar-active {\n animation: avatarPulse 2s ease-in-out infinite;\n }\n \n @keyframes avatarPulse {\n 0%, 100% { \n transform: scale(1);\n }\n 50% { \n transform: scale(1.05);\n }\n }\n \n .voice-avatar-active.speaking {\n animation: avatarSpeak 0.5s ease-in-out infinite;\n }\n \n @keyframes avatarSpeak {\n 0%, 100% { transform: scale(1); }\n 50% { transform: scale(1.08); }\n }\n \n /* Voice Rings Animation */\n .voice-rings {\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n }\n \n .voice-ring {\ndisplay: block !important;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n border: 2px solid rgba(102, 126, 234, 0.3);\n border-radius: 50%;\n opacity: 0;\n animation: ringExpand 2s ease-out infinite;\n }\n \n .voice-ring:nth-child(2) { animation-delay: 0.5s; }\n .voice-ring:nth-child(3) { animation-delay: 1s; }\n \n @keyframes ringExpand {\n 0% {\n width: 100%;\n height: 100%;\n opacity: 0.6;\n }\n 100% {\n width: 160%;\n height: 160%;\n opacity: 0;\n }\n }\n \n /* Voice Status - Scales with container */\n .voice-status {\n text-align: center;\n margin: 0;\n flex-shrink: 0;\n min-height: 0;\n }\n \n .voice-status-title {\n font-size: clamp(12px, 3vh, 20px);\n font-weight: 600;\n color: ").concat(statusTitleColor, ";\n margin-bottom: clamp(2px, 0.5vh, 4px);\n line-height: 1.2;\n }\n \n .voice-status-subtitle {\n font-size: clamp(10px, 2vh, 14px);\n color: ").concat(statusSubtitleColor, ";\n line-height: 1.2;\n }\n \n /* Start Call Button - Scales with container */\n .start-call-btn {\n margin: 0;\n width: min(280px, 70vw)").concat(important, ";\n height: clamp(48px, 8vh, 64px)").concat(important, ";\n border-radius: clamp(24px, 4vh, 32px)").concat(important, ";\n border: none").concat(important, ";\n background: ").concat(startCallBtnColor).concat(important, ";\n color: ").concat(startCallBtnTextColor).concat(important, ";\n font-size: clamp(14px, 2.5vh, 18px)").concat(important, ";\n font-weight: 600").concat(important, ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n gap: clamp(8px, 1.5vh, 12px);\n box-shadow: 0 12px 30px rgba(102, 126, 234, 0.4);\n transition: all 0.3s ease;\n flex-shrink: 0;\n }\n \n .start-call-btn svg {\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n width: auto").concat(important, ";\n height: auto").concat(important, ";\n }\n \n .start-call-btn svg {\n width: clamp(22px, 4vh, 32px);\n height: clamp(22px, 4vh, 32px);\n }\n \n .start-call-btn:hover {\n transform: translateY(-2px);\n box-shadow: 0 12px 28px rgba(102, 126, 234, 0.5);\n }\n \n .start-call-btn:active {\n transform: translateY(-1px);\n }\n .start-call-btn:disabled {\n cursor: not-allowed").concat(important, ";\n opacity: 0.6").concat(important, ";\n }\n \n /* Connecting Spinner */\n .connecting-spinner {\n display: inline-block;\n width: 16px;\n height: 16px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-top-color: ").concat(startCallBtnTextColor, ";\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-right: 8px;\n vertical-align: middle;\n }\n \n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n \n /* Voice Transcript - Scales with container */\n .voice-transcript {\n background: ").concat(transcriptBg, ";\n padding: clamp(6px, 1.5vh, 12px);\n border-radius: 10px;\n width: min(360px, calc(100% - 40px));\n margin: 0;\n min-height: clamp(80px, 15vh, 120px);\n max-height: clamp(100px, 18vh, 140px);\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n flex-shrink: 1;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n }\n \n .transcript-label {\n font-size: clamp(8px, 1.4vh, 11px);\n color: ").concat(transcriptLabelColor, ";\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: clamp(3px, 0.6vh, 6px);\n flex-shrink: 0;\n word-wrap: break-word;\n }\n \n .transcript-text {\n font-size: clamp(11px, 2vh, 15px);\n color: ").concat(transcriptTextColor, ";\n line-height: 1.4;\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n word-wrap: break-word;\n overflow-wrap: break-word;\n }\n \n .transcript-text.empty {\n color: #cbd5e1;\n font-style: italic;\n }\n \n /* Voice Text Input Area - Type while on voice call */\n .voice-text-input-area {\n width: 100%;\n padding: 14px 16px;\n margin: 0;\n flex-shrink: 0;\n background: #ffffff;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n box-sizing: border-box;\n }\n \n .voice-input-wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n background: #f1f5f9;\n border-radius: 12px;\n padding: 4px 4px 4px 14px;\n border: 1px solid transparent;\n transition: all 0.2s ease;\n }\n \n .voice-input-wrapper:focus-within {\n background: #fff;\n border-color: #a855f7;\n box-shadow: 0 0 0 3px rgba(168, 85, 247, 0.1);\n }\n \n .voice-text-input {\n flex: 1;\n border: none;\n outline: none;\n font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 14px;\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n background: transparent;\n padding: 10px 0;\n }\n \n .voice-text-input::placeholder {\n color: #94a3b8;\n }\n \n .voice-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n border-radius: 10px;\n border: none;\n background: ").concat(voiceSendButtonColor).concat(important, ";\n color: #fff;\n cursor: pointer;\n transition: transform 0.2s ease;\n flex-shrink: 0;\n }\n \n .voice-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n }\n \n .voice-send-btn:active:not(:disabled) {\n transform: scale(0.95);\n }\n \n .voice-send-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n \n .voice-send-btn svg {\n width: 16px;\n height: 16px;\n }\n \n .voice-input-hint {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n margin-top: 10px;\n font-size: 11px;\n color: #64748b;\n transition: color 0.2s ease;\n }\n \n .voice-input-hint svg {\n width: 12px;\n height: 12px;\n color: #10b981;\n }\n \n /* Text input status states */\n .voice-input-hint--sending {\n color: #666;\n }\n \n .voice-input-hint--success {\n color: #28a745;\n }\n \n .voice-input-hint--queued {\n color: #ffc107;\n }\n \n .voice-input-hint--error {\n color: #dc3545;\n }\n \n /* Disabled input styling */\n .voice-text-input:disabled,\n #mobileTextInput:disabled {\n background-color: #f5f5f5;\n cursor: not-allowed;\n }\n \n .voice-send-btn:disabled,\n #mobileSendBtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n \n /* Voice Controls - Scales with container */\n .voice-controls {\n display: flex;\n gap: clamp(8px, 1.8vh, 14px);\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin: 0;\n padding-top: 0;\n }\n \n .voice-control-btn {\n width: clamp(48px, 9vh, 72px)").concat(important, ";\n height: clamp(48px, 9vh, 72px)").concat(important, ";\n min-width: clamp(48px, 9vh, 72px)").concat(important, ";\n min-height: clamp(48px, 9vh, 72px)").concat(important, ";\n max-width: clamp(48px, 9vh, 72px)").concat(important, ";\n max-height: clamp(48px, 9vh, 72px)").concat(important, ";\n aspect-ratio: 1").concat(important, ";\n border-radius: 50%").concat(important, ";\n border: none").concat(important, ";\n cursor: pointer").concat(important, ";\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n justify-content: center").concat(important, ";\n transition: all 0.2s;\n position: relative").concat(important, ";\n flex-shrink: 0;\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 .voice-control-btn svg {\n width: 48%").concat(important, ";\n height: 48%").concat(important, ";\n min-width: 48%").concat(important, ";\n min-height: 48%").concat(important, ";\n max-width: 48%").concat(important, ";\n max-height: 48%").concat(important, ";\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n position: relative").concat(important, ";\n flex-shrink: 0").concat(important, ";\n }\n \n .voice-control-btn.primary {\n width: clamp(54px, 10vh, 80px)").concat(important, ";\n height: clamp(54px, 10vh, 80px)").concat(important, ";\n min-width: clamp(54px, 10vh, 80px)").concat(important, ";\n min-height: clamp(54px, 10vh, 80px)").concat(important, ";\n max-width: clamp(54px, 10vh, 80px)").concat(important, ";\n max-height: clamp(54px, 10vh, 80px)").concat(important, ";\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)").concat(important, ";\n color: white").concat(important, ";\n box-shadow: 0 6px 18px rgba(102, 126, 234, 0.4);\n }\n \n .voice-control-btn.primary:hover {\n transform: scale(1.05);\n }\n \n .voice-control-btn.primary.active {\n background: ").concat(endCallBtnColor).concat(important, ";\n animation: recordingPulse 1.5s ease-in-out infinite;\n }\n .voice-control-btn.primary.active svg {\n fill: white").concat(important, ";\n }\n \n /* More specific selectors for WordPress compatibility */\n #endCallBtn.voice-control-btn.primary.active,\n #muteBtn.voice-control-btn.secondary,\n #speakerBtn.voice-control-btn.secondary {\n border-radius: 50% !important;\n width: clamp(48px, 9vh, 72px) !important;\n height: clamp(48px, 9vh, 72px) !important;\n min-width: clamp(48px, 9vh, 72px) !important;\n min-height: clamp(48px, 9vh, 72px) !important;\n max-width: clamp(48px, 9vh, 72px) !important;\n max-height: clamp(48px, 9vh, 72px) !important;\n aspect-ratio: 1 !important;\n overflow: hidden !important;\n }\n \n #endCallBtn.voice-control-btn.primary.active {\n width: clamp(54px, 10vh, 80px) !important;\n height: clamp(54px, 10vh, 80px) !important;\n min-width: clamp(54px, 10vh, 80px) !important;\n min-height: clamp(54px, 10vh, 80px) !important;\n max-width: clamp(54px, 10vh, 80px) !important;\n max-height: clamp(54px, 10vh, 80px) !important;\n }\n \n \n /* Microphone button specific background color */\n #muteBtn.voice-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n /* Speaker button specific background color */\n #speakerBtn.voice-control-btn.secondary {\n background: ").concat(speakerButtonColor).concat(important, ";\n }\n \n #endCallBtn.voice-control-btn.primary.active svg,\n #muteBtn.voice-control-btn.secondary svg,\n #speakerBtn.voice-control-btn.secondary svg {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 48% !important;\n height: 48% !important;\n margin: 0 !important;\n padding: 0 !important;\n position: relative !important;\n }\n \n @keyframes recordingPulse {\n 0%, 100% { \n box-shadow: 0 6px 16px rgba(239, 68, 68, 0.4);\n }\n 50% { \n box-shadow: 0 6px 24px rgba(239, 68, 68, 0.7);\n }\n }\n \n .voice-control-btn.secondary {\n background: ").concat(controlBtnColor).concat(important, ";\n color: ").concat(controlBtnSecondaryColor).concat(important, ";\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);\n width: clamp(48px, 9vh, 72px)").concat(important, ";\n height: clamp(48px, 9vh, 72px)").concat(important, ";\n min-width: clamp(48px, 9vh, 72px)").concat(important, ";\n min-height: clamp(48px, 9vh, 72px)").concat(important, ";\n max-width: clamp(48px, 9vh, 72px)").concat(important, ";\n max-height: clamp(48px, 9vh, 72px)").concat(important, ";\n }\n \n .voice-control-btn.secondary:hover {\n background: #f8fafc").concat(important, ";\n transform: scale(1.05);\n }\n \n .voice-control-btn.secondary.muted {\n background: #f3f4f6").concat(important, ";\n }\n \n .voice-control-btn.secondary.muted .mute-icon {\n stroke: #9ca3af !important;\n }\n \n .voice-control-btn.secondary svg {\n width: 48%").concat(important, ";\n height: 48%").concat(important, ";\n display: block").concat(important, ";\n visibility: visible").concat(important, ";\n opacity: 1").concat(important, ";\n margin: 0").concat(important, ";\n padding: 0").concat(important, ";\n position: relative").concat(important, ";\n }\n \n .voice-timer {\n position: absolute;\n bottom: clamp(-18px, -3vh, -24px);\n font-size: clamp(9px, 1.6vh, 12px);\n color: #64748b;\n font-weight: 500;\n white-space: nowrap;\n }\n \n /* ===== DESKTOP VOICE SECTION - New Design ===== */\n .desktop-voice-section {\n padding: 16px 20px;\n background: linear-gradient(180deg, #ffffff 0%, rgba(168, 85, 247, 0.04) 100%);\n width: 100%;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n box-sizing: border-box;\n text-align: center;\n }\n \n /* Ensure all children are centered */\n .desktop-voice-section > * {\n margin-left: auto;\n margin-right: auto;\n }\n \n .desktop-timer {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 6px !important;\n padding: 5px 10px !important;\n background: rgba(0, 0, 0, 0.05) !important;\n border-radius: 20px !important;\n font-family: 'JetBrains Mono', 'Courier New', monospace;\n font-size: 11px !important;\n color: #64748b !important;\n margin: 0 auto !important;\n }\n \n .desktop-timer .timer-dot {\n display: block !important;\n width: 5px").concat(important, ";\n height: 5px").concat(important, ";\n background: #ef4444").concat(important, ";\n border-radius: 50%").concat(important, ";\n animation: timerPulse 1s ease-in-out infinite").concat(important, ";\n }\n \n @keyframes timerPulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n }\n \n .desktop-avatar-container {\n margin-bottom: 12px;\n }\n \n .desktop-avatar-large {\n width: 80px !important;\n height: 80px !important;\n border-radius: 20px !important;\n margin: 0 auto 12px !important;\n box-shadow: 0 8px 24px rgba(168, 85, 247, 0.35) !important;\n background: linear-gradient(135deg, ").concat(avatarBg, " 0%, ").concat(avatarActiveBg, " 100%) !important;\n }\n \n .desktop-waveform {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 4px !important;\n height: 36px !important;\n width: 100% !important;\n }\n \n .desktop-waveform-bar {\n display: block !important;\n width: 4px !important;\n background: rgba(255, 255, 255, 0.9) !important;\n border-radius: 2px !important;\n animation: waveformAnimation 0.8s ease-in-out infinite !important;\n }\n \n .desktop-waveform-bar[data-index=\"0\"] { height: 14px !important; animation-delay: 0s !important; }\n .desktop-waveform-bar[data-index=\"1\"] { height: 26px !important; animation-delay: 0.1s !important; }\n .desktop-waveform-bar[data-index=\"2\"] { height: 36px !important; animation-delay: 0.2s !important; }\n .desktop-waveform-bar[data-index=\"3\"] { height: 22px !important; animation-delay: 0.3s !important; }\n .desktop-waveform-bar[data-index=\"4\"] { height: 16px !important; animation-delay: 0.4s !important; }\n \n @keyframes waveformAnimation {\n 0%, 100% { transform: scaleY(0.5); }\n 50% { transform: scaleY(1); }\n }\n \n .desktop-waveform.paused .desktop-waveform-bar {\n animation-play-state: paused;\n }\n\n /* New main waveform (used in updated template) */\n .desktop-main-waveform {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 3px !important;\n height: 48px !important;\n width: 100% !important;\n max-width: 200px !important;\n margin: 0 auto !important;\n padding: 0 20px !important;\n }\n\n .desktop-main-waveform .waveform-bar {\n display: block !important;\n width: 3px !important;\n background: #a855f7 !important;\n border-radius: 2px !important;\n height: 8px !important;\n animation: waveformAnimation 0.8s ease-in-out infinite !important;\n }\n\n .desktop-main-waveform .waveform-bar:nth-child(1) { height: 12px !important; animation-delay: 0s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(2) { height: 20px !important; animation-delay: 0.05s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(3) { height: 28px !important; animation-delay: 0.1s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(4) { height: 36px !important; animation-delay: 0.15s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(5) { height: 44px !important; animation-delay: 0.2s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(6) { height: 50px !important; animation-delay: 0.25s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(7) { height: 54px !important; animation-delay: 0.3s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(8) { height: 56px !important; animation-delay: 0.35s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(9) { height: 54px !important; animation-delay: 0.4s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(10) { height: 50px !important; animation-delay: 0.45s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(11) { height: 44px !important; animation-delay: 0.5s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(12) { height: 36px !important; animation-delay: 0.55s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(13) { height: 28px !important; animation-delay: 0.6s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(14) { height: 20px !important; animation-delay: 0.65s !important; }\n .desktop-main-waveform .waveform-bar:nth-child(15) { height: 12px !important; animation-delay: 0.7s !important; }\n\n .desktop-status {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 5px !important;\n font-size: 12px !important;\n color: ").concat(statusTitleColor, ";\n font-weight: 500;\n width: 100%;\n text-align: center;\n margin: 0 auto;\n }\n \n .desktop-status .status-dot {\n display: block !important;\n width: 5px !important;\n height: 5px !important;\n background: ").concat(statusDotColor, " !important;\n border-radius: 50% !important;\n animation: statusPulse 1.5s ease-in-out infinite !important;\n }\n \n @keyframes statusPulse {\n 0%, 100% { transform: scale(1); opacity: 1; }\n 50% { transform: scale(1.15); opacity: 0.8; }\n }\n \n .desktop-live-waveform {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n height: 48px;\n margin-bottom: 20px;\n }\n \n .desktop-live-bar {\ndisplay: block !important;\n width: 3px;\n background: linear-gradient(180deg, ").concat(avatarBg, ", ").concat(avatarActiveBg, ");\n border-radius: 2px;\n transition: height 0.1s ease;\n height: 8px;\n }\n \n .desktop-controls {\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: center;\n width: 100%;\n margin: 0 auto;\n }\n \n .desktop-control-btn {\n width: 46px;\n height: 46px;\n border-radius: 50%;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .desktop-control-btn svg {\n width: 20px;\n height: 20px;\n }\n \n .desktop-mic-icon,\n .desktop-speaker-icon {\n width: 20px !important;\n height: 20px !important;\n display: block;\n flex-shrink: 0;\n }\n \n .desktop-control-btn.secondary.muted .desktop-mic-icon,\n .desktop-control-btn.secondary.muted .desktop-speaker-icon {\n width: 20px !important;\n height: 20px !important;\n }\n \n \n .desktop-control-btn.secondary:hover {\n background: rgba(0, 0, 0, 0.1);\n color: #1e293b;\n transform: scale(1.05);\n }\n .desktop-control-btn.secondary.muted {\n background: #f3f4f6;\n color: #9ca3af;\n }\n \n .desktop-control-btn.secondary.muted .desktop-mic-icon,\n .desktop-control-btn.secondary.muted .desktop-speaker-icon {\n stroke: #9ca3af;\n }\n \n .desktop-control-btn.secondary {\n position: relative;\n }\n \n \n /* Desktop microphone button background color */\n #desktopMuteBtn.desktop-control-btn.secondary,\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n /* Desktop speaker button background color */\n #desktopSpeakerBtn.desktop-control-btn.secondary,\n #desktopSpeakerBtnCompact.compact-control-btn.secondary {\n background: ").concat(speakerButtonColor).concat(important, ";\n }\n .desktop-mic-off-icon,\n .desktop-speaker-off-icon {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 46px;\n height: 46px;\n transform: translate(-50%, -50%);\n z-index: 10;\n }\n .desktop-control-btn.danger {\n width: 50px;\n height: 50px;\n background: ").concat(endCallBtnColor).concat(important, ";\n color: #ffffff;\n box-shadow: 0 4px 14px rgba(239, 68, 68, 0.4);\n overflow: visible;\n }\n \n .desktop-control-btn.danger svg {\n width: 20px;\n height: 20px;\n overflow: visible;\n }\n \n .desktop-control-btn.danger:hover {\n transform: scale(1.06);\n box-shadow: 0 6px 20px rgba(239, 68, 68, 0.5);\n }\n \n .desktop-control-btn.danger:hover {\n transform: scale(1.06);\n box-shadow: 0 6px 20px rgba(239, 68, 68, 0.5);\n }\n \n \n /* ===== COMPACT VOICE SECTION (Single-row layout) ===== */\n .compact-voice-section {\n padding: 10px 14px;\n background: linear-gradient(180deg, #ffffff, rgba(168, 85, 247, 0.04));\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.06);\n min-height: 62px;\n flex-shrink: 0;\n }\n \n .compact-left {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n \n .compact-avatar {\n width: 42px;\n height: 42px;\n min-width: 42px;\n min-height: 42px;\n border-radius: 12px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: visible;\n position: relative;\n }\n \n /* Waveform container in compact avatar - ensure it's visible */\n .compact-avatar .desktop-main-waveform {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 2px !important;\n height: 100% !important;\n width: 100% !important;\n padding: 4px !important;\n transform: scale(0.75) !important;\n transform-origin: center !important;\n }\n \n /* Ensure waveform bars are visible and animated in compact mode */\n .compact-avatar .desktop-main-waveform .waveform-bar {\n display: block !important;\n width: 2px !important;\n min-width: 2px !important;\n background: #a855f7 !important;\n border-radius: 1px !important;\n flex-shrink: 0 !important;\n animation: waveformAnimation 0.8s ease-in-out infinite !important;\n }\n \n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(1) { height: 6px !important; animation-delay: 0s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(2) { height: 10px !important; animation-delay: 0.05s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(3) { height: 14px !important; animation-delay: 0.1s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(4) { height: 18px !important; animation-delay: 0.15s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(5) { height: 22px !important; animation-delay: 0.2s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(6) { height: 26px !important; animation-delay: 0.25s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(7) { height: 28px !important; animation-delay: 0.3s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(8) { height: 30px !important; animation-delay: 0.35s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(9) { height: 28px !important; animation-delay: 0.4s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(10) { height: 26px !important; animation-delay: 0.45s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(11) { height: 22px !important; animation-delay: 0.5s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(12) { height: 18px !important; animation-delay: 0.55s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(13) { height: 14px !important; animation-delay: 0.6s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(14) { height: 10px !important; animation-delay: 0.65s !important; }\n .compact-avatar .desktop-main-waveform .waveform-bar:nth-child(15) { height: 6px !important; animation-delay: 0.7s !important; }\n\n }\n \n .compact-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n \n .compact-timer {\n display: flex;\n align-items: center;\n gap: 5px;\n font-family: 'JetBrains Mono', 'Courier New', monospace;\n font-size: 13px;\n font-weight: 600;\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n }\n \n .compact-timer .timer-dot {\n display: block !important;\n width: 6px").concat(important, ";\n height: 6px").concat(important, ";\n background: #ef4444").concat(important, ";\n border-radius: 50%").concat(important, ";\n animation: timerPulse 1s ease-in-out infinite").concat(important, ";\n }\n \n .compact-status {\n display: flex").concat(important, ";\n align-items: center").concat(important, ";\n gap: 4px").concat(important, ";\n font-size: 11px").concat(important, ";\n color: ").concat(statusTitleColor).concat(important, ";\n }\n \n .compact-status .status-dot {\n display: block !important;\n width: 5px").concat(important, ";\n height: 5px").concat(important, ";\n background: ").concat(statusDotColor).concat(important, ";\n border-radius: 50%").concat(important, ";\n animation: statusPulse 1.5s ease-in-out infinite").concat(important, ";\n }\n \n @keyframes statusPulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.7; transform: scale(1.1); }\n }\n \n .compact-controls {\n display: flex;\n align-items: center;\n gap: 6px;\n }\n \n .compact-control-btn {\n width: 36px;\n height: 36px;\n min-width: 36px;\n min-height: 36px;\n border-radius: 50%;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n padding: 0;\n position: relative;\n overflow: hidden;\n }\n \n .compact-control-btn svg {\n width: 16px;\n height: 16px;\n }\n \n .compact-control-btn .desktop-mic-off-icon,\n .compact-control-btn .desktop-speaker-off-icon {\n width: 34px;\n height: 34px;\n }\n \n .compact-control-btn.secondary {\n background: #f1f5f9;\n color: #64748b;\n }\n \n \n /* Compact speaker button background color */\n #desktopSpeakerBtnCompact.compact-control-btn.secondary {\n background: ").concat(speakerButtonColor).concat(important, ";\n }\n /* Compact microphone button background color */\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n .compact-control-btn.secondary:hover {\n background: #e2e8f0;\n color: #475569;\n }\n \n .compact-control-btn.secondary.muted {\n background: rgba(239, 68, 68, 0.1);\n color: #ef4444;\n }\n \n \n .compact-control-btn.secondary.muted .desktop-mic-icon,\n .compact-control-btn.secondary.muted .desktop-speaker-icon {\n stroke: #ef4444;\n }\n \n .compact-control-btn.secondary.muted .desktop-mic-off-icon,\n .compact-control-btn.secondary.muted .desktop-speaker-off-icon {\n width: 34px;\n height: 34px;\n }\n\n .compact-control-btn.danger {\n width: 40px;\n height: 40px;\n min-width: 40px;\n min-height: 40px;\n background: ").concat(endCallBtnColor).concat(important, ";\n color: white;\n box-shadow: 0 3px 10px rgba(239, 68, 68, 0.35);\n }\n \n .compact-control-btn.danger:hover {\n transform: scale(1.05);\n box-shadow: 0 4px 14px rgba(239, 68, 68, 0.45);\n }\n \n .compact-control-btn.danger svg {\n width: 18px;\n height: 18px;\n overflow: visible;\n }\n \n/* ===== CONVERSATION PANEL ===== */\n .desktop-conversation-panel {\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n width: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n flex: 1;\n }\n \n .conversation-header {\n padding: 10px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: #fafafa;\n cursor: pointer;\n flex-shrink: 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.04);\n transition: background 0.2s ease;\n }\n \n .conversation-header:hover {\n background: #f5f5f5;\n }\n \n .conversation-label {\n font-size: 11px;\n font-weight: 600;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n \n .conversation-toggle {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n color: #94a3b8;\n font-weight: 500;\n }\n \n .conversation-toggle svg {\n transition: transform 0.2s ease;\n }\n \n .conversation-header.expanded .conversation-toggle svg {\n transform: rotate(180deg);\n }\n \n /* ===== COLLAPSED: Live Transcript Only (2 lines) ===== */\n .live-transcript-collapsed {\n padding: 12px 16px;\n background: #fafafa;\n display: flex;\n flex-direction: column;\n gap: 6px;\n flex-shrink: 0;\n min-height: 50px;\n }\n \n .live-indicator {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 9px;\n font-weight: 700;\n color: ").concat(liveIndicatorTextColor).concat(important, ";\n text-transform: uppercase;\n letter-spacing: 0.08em;\n }\n \n .live-indicator .live-dot {\ndisplay: block !important;\n height: 5px;\n width: 5px;\n background: ").concat(liveIndicatorDotColor).concat(important, ";\n border-radius: 50%;\n animation: statusPulse 1.5s ease-in-out infinite;\n }\n \n .live-text-collapsed {\n font-size: ").concat(liveTranscriptFontSize).concat(important, ";\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n line-height: 1.5;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n \n .live-text-collapsed.muted {\n color: #94a3b8;\n font-style: italic;\n }\n \n .typing-cursor {\n display: inline-block;\n width: 2px;\n height: 14px;\n background: #a855f7;\n margin-left: 2px;\n animation: blink 1s step-end infinite;\n vertical-align: middle;\n }\n \n @keyframes blink {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0; }\n }\n \n /* ===== EXPANDED: Full Conversation History ===== */\n .conversation-history {\n flex: 1;\n flex-direction: column;\n gap: 10px;\n overflow-y: auto;\n padding: 14px 16px;\n min-height: 0;\n }\n .conversation-history.visible {\n display: flex;\n }\n\n .conversation-messages {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n /* Message Rows */\n .message-row {\n display: flex;\n gap: 8px;\n animation: msgIn 0.25s ease;\n }\n \n @keyframes msgIn {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n \n @keyframes slideOut {\n from { opacity: 1; transform: translateY(0); }\n to { opacity: 0; transform: translateY(-10px); }\n }\n \n .message-row.user {\n flex-direction: row-reverse;\n }\n \n .message-avatar {\n width: 28px;\n height: 28px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .message-avatar.assistant {\n background: linear-gradient(135deg, #c084fc, #a855f7);\n }\n\n .message-avatar.assistant .orb {\n width: 12px;\n height: 12px;\n background: rgba(255, 255, 255, 0.9);\n border-radius: 50%;\n }\n\n .message-avatar.user {\n background: linear-gradient(135deg, #64748b, #475569);\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n }\n\n .message-bubble {\n max-width: 80%;\n padding: 9px 13px;\n border-radius: 12px;\n font-size: 13px;\n line-height: 1.5;\n }\n \n .message-row.assistant .message-bubble {\n background: #fff;\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n border: 1px solid rgba(0, 0, 0, 0.06);\n border-bottom-left-radius: 4px;\n }\n \n .message-row.user .message-bubble {\n background: linear-gradient(135deg, #7c3aed 0%, #a855f7 100%);\n color: #fff;\n border-bottom-right-radius: 4px;\n }\n \n /* Live message at bottom of history */\n .live-message-row {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px dashed rgba(0, 0, 0, 0.08);\n margin-top: auto;\n }\n \n .live-message-row .message-bubble {\n background: #fff;\n border: 1px solid rgba(16, 185, 129, 0.3);\n color: ").concat(liveTranscriptTextColor).concat(important, ";\n position: relative;\n border-radius: 14px;\n border-bottom-left-radius: 4px;\n }\n \n .live-message-row .live-badge {\ndisplay: block !important;\n position: absolute;\n top: -8px;\n left: 10px;\n background: #10b981;\n color: #fff;\n font-size: 8px;\n font-weight: 700;\n padding: 2px 6px;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n \n /* Hide/show based on expanded state */\n .desktop-conversation-panel.collapsed .conversation-history {\n display: none;\n }\n \n .desktop-conversation-panel.collapsed .live-transcript-collapsed {\n display: flex;\n }\n \n .desktop-conversation-panel.expanded .conversation-history {\n display: flex;\n max-height: 400px;\n }\n \n .desktop-conversation-panel.expanded .live-transcript-collapsed {\n display: none;\n }\n \n /* ===== DARK MODE SUPPORT ===== */\n @media (prefers-color-scheme: dark) {\n .desktop-voice-section {\n background: linear-gradient(180deg, #1e1e2e 0%, rgba(168, 85, 247, 0.08) 100%);\n }\n\n .desktop-timer {\n color: #94a3b8;\n }\n\n .desktop-status {\n color: #34d399;\n }\n\n .desktop-status .status-dot {\n \n .desktop-control-btn.secondary.muted {\n background: rgba(255, 255, 255, 0.1);\n color: #9ca3af;\n \n .compact-voice-section {\n background: linear-gradient(180deg, #1e1e2e 0%, rgba(168, 85, 247, 0.08) 100%);\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n \n .compact-timer {\n color: #e2e8f0;\n }\n \n .compact-status {\n color: #34d399;\n }\n \n .compact-status .status-dot {\n background: #34d399;\n }\n \n .compact-control-btn.secondary {\n background: rgba(255, 255, 255, 0.08);\n color: #94a3b8;\n }\n \n .compact-control-btn.secondary:hover {\n background: rgba(255, 255, 255, 0.15);\n color: #e2e8f0;\n }\n \n .compact-control-btn.secondary.muted {\n background: rgba(239, 68, 68, 0.2);\n color: #f87171;\n }\n\n }\n \n .desktop-control-btn.secondary.muted svg {\n \n .desktop-control-btn.secondary {\n position: relative;\n }\n \n /* Desktop microphone button background color */\n #desktopMuteBtn.desktop-control-btn.secondary,\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n .desktop-mic-off-icon,\n .desktop-speaker-off-icon {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 20px;\n height: 20px;\n }\n \n .desktop-control-btn.secondary.muted {\n background: #f3f4f6;\n color: #9ca3af;\n }\n \n .desktop-control-btn.secondary.muted svg {\n \n .desktop-control-btn.secondary {\n position: relative;\n }\n \n /* Desktop microphone button background color */\n #desktopMuteBtn.desktop-control-btn.secondary,\n #desktopMuteBtnCompact.compact-control-btn.secondary {\n background: ").concat(micButtonColor).concat(important, ";\n }\n \n .desktop-mic-off-icon,\n .desktop-speaker-off-icon {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 20px;\n height: 20px;\n }\n stroke: #9ca3af;\n }\n stroke: #9ca3af;\n }\n background: #34d399;\n }\n\n .desktop-control-btn.secondary {\n background: rgba(255, 255, 255, 0.08);\n color: #94a3b8;\n }\n\n .desktop-control-btn.secondary:hover {\n background: rgba(255, 255, 255, 0.15);\n color: #e2e8f0;\n }\n\n .desktop-conversation-panel {\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n }\n\n .conversation-header {\n background: #1a1a2e;\n }\n\n .conversation-header:hover {\n background: #252540;\n }\n\n .conversation-label {\n color: #94a3b8;\n }\n\n .conversation-toggle {\n color: #64748b;\n }\n\n .live-transcript-preview {\n background: #1a1a2e;\n }\n .live-indicator {\n color: ").concat(liveIndicatorTextColor).concat(important, ";\n }\n .live-indicator .live-dot {\n background: ").concat(liveIndicatorDotColor).concat(important, ";\n }\n\n .live-text {\n color: #e2e8f0;\n }\n\n .live-text.muted {\n color: #64748b;\n }\n\n .conversation-history {\n background: #1a1a2e;\n }\n\n .conversation-msg.assistant .conversation-msg-bubble {\n background: #252540;\n color: #e2e8f0;\n border: 1px solid rgba(255, 255, 255, 0.08);\n }\n\n .voice-text-input-area {\n background: #1a1a2e;\n }\n\n .voice-text-input {\n background: #252540 !important;\n color: #e2e8f0 !important;\n border-color: rgba(255, 255, 255, 0.1) !important;\n }\n\n .voice-text-input::placeholder {\n color: #64748b !important;\n }\n\n .voice-text-input:focus {\n border-color: ").concat(avatarBg, " !important;\n box-shadow: 0 0 0 3px rgba(168, 85, 247, 0.2) !important;\n }\n\n .voice-input-hint {\n color: #64748b !important;\n }\n\n .voice-send-btn {\n background: ").concat(voiceSendButtonColor, " !important;\n }\n\n .voice-send-btn:disabled {\n background: #374151 !important;\n color: #4b5563 !important;\n }\n }\n\n /* Mobile optimization */\n @media (max-width: 768px) {\n .voice-interface {\n padding: 6px 10px;\n }\n }\n \n @media (max-width: 480px) {\n .voice-interface {\n padding: 5px 8px;\n }\n }\n \n /* Mobile Voice Call UI - Shared styles (also used in generateMobileCSS) */\n ").concat(this._getSharedMobileCSS(important), "\n\n ");
27234
27348
  }
27235
27349
 
27236
27350
  /**
@@ -27240,7 +27354,7 @@ var Styles = /*#__PURE__*/function () {
27240
27354
  }, {
27241
27355
  key: "_getSharedMobileCSS",
27242
27356
  value: function _getSharedMobileCSS(important) {
27243
- 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 ");
27357
+ return "\n .mobile-duration-dot {\ndisplay: block !important;\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 {\ndisplay: block !important;\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 {\ndisplay: block !important;\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 {\ndisplay: block !important;\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 ");
27244
27358
  }
27245
27359
 
27246
27360
  /**