@cuekit-ai/react 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,8 +33,12 @@ __export(index_exports, {
33
33
  CuekitProvider: () => CuekitProvider,
34
34
  InitCuekit: () => InitCuekit,
35
35
  MicButton: () => MicButton,
36
+ navigate: () => navigate,
36
37
  onStateChange: () => onStateChange,
37
38
  processVoice: () => processVoice,
39
+ safeNavigate: () => safeNavigate,
40
+ setNavigationHandler: () => setNavigationHandler,
41
+ setNavigator: () => setNavigator,
38
42
  useAudioController: () => useAudioController,
39
43
  useVoiceRecognition: () => useVoiceRecognition
40
44
  });
@@ -216,10 +220,22 @@ var ttsManager = new TtsManager();
216
220
 
217
221
  // src/core/navigation.ts
218
222
  var navigation;
223
+ var navigationHandler = null;
219
224
  var setNavigator = (navigator2) => {
220
225
  navigation = navigator2;
221
226
  };
227
+ var setNavigationHandler = (handler) => {
228
+ navigationHandler = handler;
229
+ };
222
230
  var navigate = (path, params) => {
231
+ if (navigationHandler) {
232
+ try {
233
+ navigationHandler(path, params);
234
+ return;
235
+ } catch (error) {
236
+ console.error("[CueKit] navigation handler failed, falling back to default:", error);
237
+ }
238
+ }
223
239
  let fullPath = path;
224
240
  if (params) {
225
241
  const searchParams = new URLSearchParams(params).toString();
@@ -230,16 +246,17 @@ var navigate = (path, params) => {
230
246
  if (navigation) {
231
247
  navigation.push(fullPath);
232
248
  } else {
233
- window.location.href = fullPath;
249
+ if (typeof window !== "undefined") {
250
+ window.location.href = fullPath;
251
+ }
234
252
  }
235
253
  };
236
254
  var getCurrentPath = () => {
255
+ if (typeof window === "undefined") return "";
237
256
  return window.location.pathname;
238
257
  };
239
258
  var getSearchParams = () => {
240
- if (navigation) {
241
- return navigation.query;
242
- }
259
+ if (typeof window === "undefined") return new URLSearchParams();
243
260
  return new URLSearchParams(window.location.search);
244
261
  };
245
262
  var safeNavigate = (name, params = {}) => {
@@ -287,6 +304,7 @@ function onStateChange() {
287
304
  }
288
305
  var handleNavigationAndClick = (routeName, elementHash) => {
289
306
  safeNavigate(routeName);
307
+ if (typeof MutationObserver === "undefined" || typeof document === "undefined") return;
290
308
  const observer = new MutationObserver((mutationsList, observer2) => {
291
309
  const elements = flushCapturedElements();
292
310
  const elementToClick = elements.find((el) => el.elementId === elementHash);
@@ -334,17 +352,14 @@ var processVoice = async (transcript, apiKey, appId, deviceId) => {
334
352
  };
335
353
  console.log("body", body);
336
354
  try {
337
- const response = await fetch(
338
- `http://ec2-15-207-222-65.ap-south-1.compute.amazonaws.com/components/app/${appId}/app-intents`,
339
- {
340
- method: "POST",
341
- headers: {
342
- "Content-Type": "application/json",
343
- "X-API-Key": apiKey ?? ""
344
- },
345
- body: JSON.stringify(body)
346
- }
347
- );
355
+ const response = await fetch(`https://api.cuekit.ai/components/app/${appId}/app-intents`, {
356
+ method: "POST",
357
+ headers: {
358
+ "Content-Type": "application/json",
359
+ "X-API-Key": apiKey ?? ""
360
+ },
361
+ body: JSON.stringify(body)
362
+ });
348
363
  const data = await response.json();
349
364
  if (!response.ok) {
350
365
  console.log("Response Status:", response.status);
@@ -419,11 +434,8 @@ var _apiKey = "";
419
434
  var setApiKey = (key) => _apiKey = key;
420
435
 
421
436
  // src/core/init.ts
422
- function InitCuekit(apiKey, navigator2) {
437
+ function InitCuekit(apiKey) {
423
438
  setApiKey(apiKey);
424
- if (navigator2) {
425
- setNavigator(navigator2);
426
- }
427
439
  }
428
440
 
429
441
  // src/Provider/CuekitProvider.tsx
@@ -445,27 +457,40 @@ var QubeContext = (0, import_react.createContext)({
445
457
  appId: ""
446
458
  });
447
459
  var getUniqueId = () => {
448
- let id = localStorage.getItem("cuekit_device_id");
449
- if (!id) {
450
- id = Date.now().toString(36) + Math.random().toString(36).substring(2);
451
- localStorage.setItem("cuekit_device_id", id);
460
+ if (typeof window === "undefined") {
461
+ return "server-" + Date.now().toString(36);
462
+ }
463
+ try {
464
+ let id = localStorage.getItem("cuekit_device_id");
465
+ if (!id) {
466
+ id = Date.now().toString(36) + Math.random().toString(36).substring(2);
467
+ localStorage.setItem("cuekit_device_id", id);
468
+ }
469
+ return id;
470
+ } catch {
471
+ return "anon-" + Date.now().toString(36);
452
472
  }
453
- return id;
454
473
  };
455
474
  var CuekitProvider = ({
456
475
  apiKey,
457
476
  deviceId = "",
458
477
  appId,
459
478
  children,
460
- navigator: navigator2
479
+ navigationHandler: navigationHandler2
461
480
  }) => {
462
481
  const [internalDeviceId, setInternalDeviceId] = (0, import_react.useState)(deviceId);
463
482
  (0, import_react.useEffect)(() => {
464
- InitCuekit(apiKey, navigator2);
465
- }, [apiKey, navigator2]);
483
+ InitCuekit(apiKey);
484
+ }, [apiKey]);
485
+ (0, import_react.useEffect)(() => {
486
+ setNavigationHandler(navigationHandler2 ?? null);
487
+ return () => {
488
+ setNavigationHandler(null);
489
+ };
490
+ }, [navigationHandler2]);
466
491
  (0, import_react.useEffect)(() => {
467
492
  const updateGlobalStore = (id) => {
468
- if (globalThis.CuekitStore) {
493
+ if (typeof window !== "undefined" && globalThis.CuekitStore) {
469
494
  globalThis.CuekitStore.update({
470
495
  apiKey,
471
496
  appId,
@@ -496,16 +521,24 @@ var CuekitProvider = ({
496
521
  GlobalStore.clearData("transcript");
497
522
  }
498
523
  };
499
- window.addEventListener("popstate", handleRouteChange);
500
- const originalPushState = history.pushState;
501
- history.pushState = function(...args) {
502
- originalPushState.apply(this, args);
503
- handleRouteChange();
504
- };
524
+ if (typeof window !== "undefined") {
525
+ window.addEventListener("popstate", handleRouteChange);
526
+ }
527
+ const originalPushState = typeof history !== "undefined" ? history.pushState : void 0;
528
+ if (originalPushState) {
529
+ history.pushState = function(...args) {
530
+ originalPushState.apply(this, args);
531
+ handleRouteChange();
532
+ };
533
+ }
505
534
  handleRouteChange();
506
535
  return () => {
507
- window.removeEventListener("popstate", handleRouteChange);
508
- history.pushState = originalPushState;
536
+ if (typeof window !== "undefined") {
537
+ window.removeEventListener("popstate", handleRouteChange);
538
+ }
539
+ if (originalPushState) {
540
+ history.pushState = originalPushState;
541
+ }
509
542
  };
510
543
  }, [apiKey, appId, internalDeviceId]);
511
544
  return /* @__PURE__ */ import_react.default.createElement(
@@ -589,8 +622,8 @@ var import_react4 = require("react");
589
622
 
590
623
  // src/hook/useVoiceRecognition.ts
591
624
  var import_react3 = require("react");
592
- var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
593
- var recognition = SpeechRecognition ? new SpeechRecognition() : null;
625
+ var SpeechRecognitionCtor = typeof window !== "undefined" ? window.SpeechRecognition || window.webkitSpeechRecognition : null;
626
+ var recognition = SpeechRecognitionCtor ? new SpeechRecognitionCtor() : null;
594
627
  if (recognition) {
595
628
  recognition.continuous = true;
596
629
  recognition.interimResults = true;
@@ -697,10 +730,14 @@ var TtsManager2 = class {
697
730
  return;
698
731
  }
699
732
  console.log("\u{1F508} Speaking:", text);
700
- window.speechSynthesis.cancel();
733
+ if (typeof window !== "undefined") {
734
+ window.speechSynthesis.cancel();
735
+ }
701
736
  this.utterance.text = text;
702
737
  this.onEndCallback = onEnd || null;
703
- window.speechSynthesis.speak(this.utterance);
738
+ if (typeof window !== "undefined") {
739
+ window.speechSynthesis.speak(this.utterance);
740
+ }
704
741
  }
705
742
  stop() {
706
743
  if (typeof window !== "undefined" && "speechSynthesis" in window) {
@@ -761,7 +798,140 @@ var import_lucide_react = require("lucide-react");
761
798
  var import_react5 = __toESM(require("react"));
762
799
  var BorderGlow = ({ isActive }) => {
763
800
  if (!isActive) return null;
764
- return /* @__PURE__ */ import_react5.default.createElement("div", { className: "fixed inset-0 pointer-events-none z-[10000] overflow-hidden" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 right-0 bottom-0 w-1 bg-gradient-to-b from-cyan-500 via-primary to-blue-600 animate-pulse opacity-80" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 right-0 bottom-0 w-2 bg-gradient-to-b from-cyan-400 via-primary to-blue-500 blur-sm animate-pulse opacity-60" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 right-0 bottom-0 w-4 bg-gradient-to-b from-cyan-300 via-primary to-blue-400 blur-md animate-pulse opacity-40" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 bottom-0 left-0 w-1 bg-gradient-to-b from-accent via-primary to-blue-600 animate-pulse opacity-80" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 bottom-0 left-0 w-2 bg-gradient-to-b from-accent via-primary to-blue-500 blur-sm animate-pulse opacity-60" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 bottom-0 left-0 w-4 bg-gradient-to-b from-accent via-primary to-blue-400 blur-md animate-pulse opacity-40" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 left-0 w-8 h-8 bg-accent rounded-br-full blur-lg animate-pulse opacity-60" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute top-0 right-0 w-8 h-8 bg-cyan-500 rounded-bl-full blur-lg animate-pulse opacity-60" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute bottom-0 right-0 w-8 h-8 bg-primary rounded-tl-full blur-lg animate-pulse opacity-60" }), /* @__PURE__ */ import_react5.default.createElement("div", { className: "absolute bottom-0 left-0 w-8 h-8 bg-blue-600 rounded-tr-full blur-lg animate-pulse opacity-60" }));
801
+ const styles = {
802
+ container: {
803
+ position: "fixed",
804
+ top: 0,
805
+ left: 0,
806
+ right: 0,
807
+ bottom: 0,
808
+ pointerEvents: "none",
809
+ zIndex: 1e4,
810
+ overflow: "hidden"
811
+ },
812
+ rightBorder1: {
813
+ position: "absolute",
814
+ top: 0,
815
+ right: 0,
816
+ bottom: 0,
817
+ width: "4px",
818
+ background: "linear-gradient(to bottom, #06b6d4, #3b82f6, #2563eb)",
819
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
820
+ opacity: 0.8
821
+ },
822
+ rightBorder2: {
823
+ position: "absolute",
824
+ top: 0,
825
+ right: 0,
826
+ bottom: 0,
827
+ width: "8px",
828
+ background: "linear-gradient(to bottom, #22d3ee, #3b82f6, #3b82f6)",
829
+ filter: "blur(4px)",
830
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
831
+ opacity: 0.6
832
+ },
833
+ rightBorder3: {
834
+ position: "absolute",
835
+ top: 0,
836
+ right: 0,
837
+ bottom: 0,
838
+ width: "16px",
839
+ background: "linear-gradient(to bottom, #67e8f9, #3b82f6, #60a5fa)",
840
+ filter: "blur(12px)",
841
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
842
+ opacity: 0.4
843
+ },
844
+ leftBorder1: {
845
+ position: "absolute",
846
+ top: 0,
847
+ left: 0,
848
+ bottom: 0,
849
+ width: "4px",
850
+ background: "linear-gradient(to bottom, #f59e0b, #3b82f6, #2563eb)",
851
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
852
+ opacity: 0.8
853
+ },
854
+ leftBorder2: {
855
+ position: "absolute",
856
+ top: 0,
857
+ left: 0,
858
+ bottom: 0,
859
+ width: "8px",
860
+ background: "linear-gradient(to bottom, #f59e0b, #3b82f6, #3b82f6)",
861
+ filter: "blur(4px)",
862
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
863
+ opacity: 0.6
864
+ },
865
+ leftBorder3: {
866
+ position: "absolute",
867
+ top: 0,
868
+ left: 0,
869
+ bottom: 0,
870
+ width: "16px",
871
+ background: "linear-gradient(to bottom, #f59e0b, #3b82f6, #60a5fa)",
872
+ filter: "blur(12px)",
873
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
874
+ opacity: 0.4
875
+ },
876
+ cornerTopLeft: {
877
+ position: "absolute",
878
+ top: 0,
879
+ left: 0,
880
+ width: "32px",
881
+ height: "32px",
882
+ background: "#f59e0b",
883
+ borderBottomRightRadius: "50%",
884
+ filter: "blur(16px)",
885
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
886
+ opacity: 0.6
887
+ },
888
+ cornerTopRight: {
889
+ position: "absolute",
890
+ top: 0,
891
+ right: 0,
892
+ width: "32px",
893
+ height: "32px",
894
+ background: "#06b6d4",
895
+ borderBottomLeftRadius: "50%",
896
+ filter: "blur(16px)",
897
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
898
+ opacity: 0.6
899
+ },
900
+ cornerBottomRight: {
901
+ position: "absolute",
902
+ bottom: 0,
903
+ right: 0,
904
+ width: "32px",
905
+ height: "32px",
906
+ background: "#3b82f6",
907
+ borderTopLeftRadius: "50%",
908
+ filter: "blur(16px)",
909
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
910
+ opacity: 0.6
911
+ },
912
+ cornerBottomLeft: {
913
+ position: "absolute",
914
+ bottom: 0,
915
+ left: 0,
916
+ width: "32px",
917
+ height: "32px",
918
+ background: "#2563eb",
919
+ borderTopRightRadius: "50%",
920
+ filter: "blur(16px)",
921
+ animation: "borderPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
922
+ opacity: 0.6
923
+ }
924
+ };
925
+ return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("style", null, `
926
+ @keyframes borderPulse {
927
+ 0%, 100% {
928
+ opacity: 1;
929
+ }
930
+ 50% {
931
+ opacity: 0.5;
932
+ }
933
+ }
934
+ `), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.container }, /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ import_react5.default.createElement("div", { style: styles.cornerBottomLeft })));
765
935
  };
766
936
  var BorderGlow_default = BorderGlow;
767
937
 
@@ -788,6 +958,10 @@ if (typeof document !== "undefined") {
788
958
  0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8, 0, 1, 1); }
789
959
  50% { transform: none; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); }
790
960
  }
961
+ @keyframes spin {
962
+ from { transform: rotate(0deg); }
963
+ to { transform: rotate(360deg); }
964
+ }
791
965
  `;
792
966
  if (!document.head.querySelector("style[data-mic-button-animations]")) {
793
967
  style.setAttribute("data-mic-button-animations", "true");
@@ -795,34 +969,69 @@ if (typeof document !== "undefined") {
795
969
  }
796
970
  }
797
971
  var WaveAnimation = () => {
798
- return /* @__PURE__ */ import_react6.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "absolute inset-0 flex items-center justify-center" }, /* @__PURE__ */ import_react6.default.createElement(
799
- "div",
800
- {
801
- className: "absolute w-24 h-24 rounded-full border-2 border-blue-500 opacity-40",
802
- style: {
803
- animationDelay: "0s",
804
- animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
805
- }
806
- }
807
- ), /* @__PURE__ */ import_react6.default.createElement(
808
- "div",
809
- {
810
- className: "absolute w-32 h-32 rounded-full border-2 border-cyan-400 opacity-30",
811
- style: {
812
- animationDelay: "0.5s",
813
- animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
814
- }
815
- }
816
- ), /* @__PURE__ */ import_react6.default.createElement(
817
- "div",
818
- {
819
- className: "absolute w-40 h-40 rounded-full border-2 border-purple-400 opacity-20",
820
- style: {
821
- animationDelay: "1s",
822
- animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
823
- }
972
+ const waveStyles = {
973
+ container: {
974
+ position: "absolute",
975
+ top: 0,
976
+ left: 0,
977
+ right: 0,
978
+ bottom: 0,
979
+ display: "flex",
980
+ alignItems: "center",
981
+ justifyContent: "center",
982
+ pointerEvents: "none"
983
+ },
984
+ innerContainer: {
985
+ position: "absolute",
986
+ top: 0,
987
+ left: 0,
988
+ right: 0,
989
+ bottom: 0,
990
+ display: "flex",
991
+ alignItems: "center",
992
+ justifyContent: "center"
993
+ },
994
+ wave1: {
995
+ position: "absolute",
996
+ width: "96px",
997
+ // w-24
998
+ height: "96px",
999
+ // h-24
1000
+ borderRadius: "50%",
1001
+ border: "2px solid #3b82f6",
1002
+ // border-blue-500
1003
+ opacity: 0.4,
1004
+ animationDelay: "0s",
1005
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1006
+ },
1007
+ wave2: {
1008
+ position: "absolute",
1009
+ width: "128px",
1010
+ // w-32
1011
+ height: "128px",
1012
+ // h-32
1013
+ borderRadius: "50%",
1014
+ border: "2px solid #22d3ee",
1015
+ // border-cyan-400
1016
+ opacity: 0.3,
1017
+ animationDelay: "0.5s",
1018
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1019
+ },
1020
+ wave3: {
1021
+ position: "absolute",
1022
+ width: "160px",
1023
+ // w-40
1024
+ height: "160px",
1025
+ // h-40
1026
+ borderRadius: "50%",
1027
+ border: "2px solid #c084fc",
1028
+ // border-purple-400
1029
+ opacity: 0.2,
1030
+ animationDelay: "1s",
1031
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
824
1032
  }
825
- )));
1033
+ };
1034
+ return /* @__PURE__ */ import_react6.default.createElement("div", { style: waveStyles.container }, /* @__PURE__ */ import_react6.default.createElement("div", { style: waveStyles.innerContainer }, /* @__PURE__ */ import_react6.default.createElement("div", { style: waveStyles.wave1 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: waveStyles.wave2 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: waveStyles.wave3 })));
826
1035
  };
827
1036
  var UnifiedModal = ({
828
1037
  text,
@@ -868,87 +1077,318 @@ var UnifiedModal = ({
868
1077
  if (!isVisible) return null;
869
1078
  const isSpeechMode = mode === "speech";
870
1079
  const isComplete = currentWordIndex >= (text?.split(" ").length || 0) - 1;
871
- return /* @__PURE__ */ import_react6.default.createElement("div", { className: "fixed inset-x-0 bottom-0 z-[500000] flex items-end justify-center" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "fixed inset-0 bg-black/20", onClick: onClose }), /* @__PURE__ */ import_react6.default.createElement(
1080
+ const modalStyles = {
1081
+ container: {
1082
+ position: "fixed",
1083
+ left: 0,
1084
+ right: 0,
1085
+ bottom: 0,
1086
+ zIndex: 5e5,
1087
+ display: "flex",
1088
+ alignItems: "flex-end",
1089
+ justifyContent: "center"
1090
+ },
1091
+ overlay: {
1092
+ position: "fixed",
1093
+ top: 0,
1094
+ left: 0,
1095
+ right: 0,
1096
+ bottom: 0,
1097
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
1098
+ cursor: "pointer"
1099
+ },
1100
+ modalContainer: {
1101
+ position: "relative",
1102
+ width: "100%",
1103
+ maxWidth: "384px",
1104
+ // max-w-sm
1105
+ margin: "0 auto",
1106
+ height: "30vh",
1107
+ animation: "slideUp 0.3s ease-out forwards",
1108
+ transform: "translateY(100%)"
1109
+ },
1110
+ orbTop: {
1111
+ position: "absolute",
1112
+ top: "-16px",
1113
+ right: "-16px",
1114
+ width: "64px",
1115
+ // w-16
1116
+ height: "64px",
1117
+ // h-16
1118
+ background: "linear-gradient(to bottom right, rgba(59, 130, 246, 0.4), rgba(59, 130, 246, 0.2))",
1119
+ borderRadius: "50%",
1120
+ filter: "blur(24px)",
1121
+ // blur-xl
1122
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1123
+ },
1124
+ orbBottom: {
1125
+ position: "absolute",
1126
+ bottom: "-16px",
1127
+ left: "-16px",
1128
+ width: "48px",
1129
+ // w-12
1130
+ height: "48px",
1131
+ // h-12
1132
+ background: "linear-gradient(to bottom right, rgba(59, 130, 246, 0.3), rgba(59, 130, 246, 0.1))",
1133
+ borderRadius: "50%",
1134
+ filter: "blur(16px)",
1135
+ // blur-lg
1136
+ animationDelay: "1s",
1137
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1138
+ }
1139
+ };
1140
+ return /* @__PURE__ */ import_react6.default.createElement("div", { style: modalStyles.container }, /* @__PURE__ */ import_react6.default.createElement("div", { style: modalStyles.overlay, onClick: onClose }), /* @__PURE__ */ import_react6.default.createElement("div", { style: modalStyles.modalContainer }, /* @__PURE__ */ import_react6.default.createElement("div", { style: modalStyles.orbTop }), /* @__PURE__ */ import_react6.default.createElement("div", { style: modalStyles.orbBottom }), /* @__PURE__ */ import_react6.default.createElement(
872
1141
  "div",
873
1142
  {
874
- className: "relative w-full max-w-sm mx-auto",
875
1143
  style: {
876
- height: "30vh",
877
- animation: "slideUp 0.3s ease-out forwards",
878
- transform: "translateY(100%)"
1144
+ position: "relative",
1145
+ backgroundColor: "white",
1146
+ borderTopLeftRadius: "24px",
1147
+ borderTopRightRadius: "24px",
1148
+ borderTop: "1px solid rgba(59, 130, 246, 0.3)",
1149
+ borderLeft: "1px solid rgba(59, 130, 246, 0.3)",
1150
+ borderRight: "1px solid rgba(59, 130, 246, 0.3)",
1151
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
1152
+ height: "100%",
1153
+ display: "flex",
1154
+ flexDirection: "column",
1155
+ overflow: "hidden"
879
1156
  }
880
1157
  },
881
1158
  /* @__PURE__ */ import_react6.default.createElement(
882
1159
  "div",
883
1160
  {
884
- className: "absolute -top-4 -right-4 w-16 h-16 bg-gradient-to-br from-blue-500/40 to-blue-500/20 rounded-full blur-xl",
885
- style: { animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" }
886
- }
887
- ),
888
- /* @__PURE__ */ import_react6.default.createElement(
889
- "div",
890
- {
891
- className: "absolute -bottom-4 -left-4 w-12 h-12 bg-gradient-to-br from-blue-500/30 to-blue-500/10 rounded-full blur-lg",
892
1161
  style: {
893
- animationDelay: "1s",
894
- animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1162
+ position: "relative",
1163
+ background: "linear-gradient(to right, rgba(59, 130, 246, 0.1), rgba(59, 130, 246, 0.05), rgba(59, 130, 246, 0.1))",
1164
+ padding: "16px",
1165
+ borderBottom: "1px solid rgba(59, 130, 246, 0.2)",
1166
+ flexShrink: 0
895
1167
  }
896
- }
1168
+ },
1169
+ /* @__PURE__ */ import_react6.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" } }, /* @__PURE__ */ import_react6.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "12px" } }, /* @__PURE__ */ import_react6.default.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ import_react6.default.createElement(
1170
+ "div",
1171
+ {
1172
+ style: {
1173
+ width: "32px",
1174
+ height: "32px",
1175
+ background: "linear-gradient(to bottom right, #3b82f6, #3b82f6)",
1176
+ borderRadius: "12px",
1177
+ display: "flex",
1178
+ alignItems: "center",
1179
+ justifyContent: "center",
1180
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"
1181
+ }
1182
+ },
1183
+ isSpeechMode ? /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Mic, { style: { width: "16px", height: "16px", color: "white" } }) : /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Sparkles, { style: { width: "16px", height: "16px", color: "white" } })
1184
+ ), /* @__PURE__ */ import_react6.default.createElement(
1185
+ "div",
1186
+ {
1187
+ style: {
1188
+ position: "absolute",
1189
+ top: "-4px",
1190
+ left: "-4px",
1191
+ right: "-4px",
1192
+ bottom: "-4px",
1193
+ background: "linear-gradient(to bottom right, #3b82f6, #3b82f6)",
1194
+ borderRadius: "12px",
1195
+ opacity: 0.3,
1196
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1197
+ }
1198
+ }
1199
+ )), /* @__PURE__ */ import_react6.default.createElement("div", null, /* @__PURE__ */ import_react6.default.createElement(
1200
+ "h3",
1201
+ {
1202
+ style: {
1203
+ fontSize: "16px",
1204
+ fontWeight: "600",
1205
+ color: "#1f2937",
1206
+ margin: 0
1207
+ }
1208
+ },
1209
+ isSpeechMode ? "Voice Input" : "AI Assistant"
1210
+ ), /* @__PURE__ */ import_react6.default.createElement(
1211
+ "div",
1212
+ {
1213
+ style: { display: "flex", alignItems: "center", gap: "8px", marginTop: "2px" }
1214
+ },
1215
+ isSpeechMode ? /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("div", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ import_react6.default.createElement(
1216
+ "div",
1217
+ {
1218
+ style: {
1219
+ width: "4px",
1220
+ height: "4px",
1221
+ backgroundColor: "#3b82f6",
1222
+ borderRadius: "50%",
1223
+ animationDelay: "0ms",
1224
+ animation: "bounce 1s infinite"
1225
+ }
1226
+ }
1227
+ ), /* @__PURE__ */ import_react6.default.createElement(
1228
+ "div",
1229
+ {
1230
+ style: {
1231
+ width: "4px",
1232
+ height: "4px",
1233
+ backgroundColor: "#3b82f6",
1234
+ borderRadius: "50%",
1235
+ animationDelay: "150ms",
1236
+ animation: "bounce 1s infinite"
1237
+ }
1238
+ }
1239
+ ), /* @__PURE__ */ import_react6.default.createElement(
1240
+ "div",
1241
+ {
1242
+ style: {
1243
+ width: "4px",
1244
+ height: "4px",
1245
+ backgroundColor: "#3b82f6",
1246
+ borderRadius: "50%",
1247
+ animationDelay: "300ms",
1248
+ animation: "bounce 1s infinite"
1249
+ }
1250
+ }
1251
+ )), /* @__PURE__ */ import_react6.default.createElement("span", { style: { fontSize: "12px", color: "#4b5563" } }, "Listening...")) : /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Volume2, { style: { width: "12px", height: "12px", color: "#3b82f6" } }), /* @__PURE__ */ import_react6.default.createElement("span", { style: { fontSize: "12px", color: "#4b5563" } }, "Speaking..."))
1252
+ ))), /* @__PURE__ */ import_react6.default.createElement(
1253
+ "button",
1254
+ {
1255
+ onClick: onClose,
1256
+ style: {
1257
+ width: "32px",
1258
+ height: "32px",
1259
+ borderRadius: "12px",
1260
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
1261
+ border: "none",
1262
+ display: "flex",
1263
+ alignItems: "center",
1264
+ justifyContent: "center",
1265
+ transition: "all 0.2s",
1266
+ cursor: "pointer"
1267
+ },
1268
+ onMouseEnter: (e) => {
1269
+ e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
1270
+ e.currentTarget.style.transform = "scale(1.05)";
1271
+ },
1272
+ onMouseLeave: (e) => {
1273
+ e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.1)";
1274
+ e.currentTarget.style.transform = "scale(1)";
1275
+ }
1276
+ },
1277
+ /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.X, { style: { width: "16px", height: "16px", color: "#4b5563" } })
1278
+ ))
897
1279
  ),
898
- /* @__PURE__ */ import_react6.default.createElement("div", { className: "relative bg-white rounded-t-3xl border-t border-x border-blue-500/30 shadow-2xl h-full flex flex-col overflow-hidden" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "relative bg-gradient-to-r from-blue-500/10 via-blue-500/5 to-blue-500/10 p-4 border-b border-blue-500/20 flex-shrink-0" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-8 h-8 bg-gradient-to-br from-blue-500 to-blue-500 rounded-xl flex items-center justify-center shadow-lg" }, isSpeechMode ? /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Mic, { className: "w-4 h-4 text-white" }) : /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Sparkles, { className: "w-4 h-4 text-white" })), /* @__PURE__ */ import_react6.default.createElement(
899
- "div",
900
- {
901
- className: "absolute -inset-1 bg-gradient-to-br from-blue-500 to-blue-500 rounded-xl opacity-30",
902
- style: { animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" }
903
- }
904
- )), /* @__PURE__ */ import_react6.default.createElement("div", null, /* @__PURE__ */ import_react6.default.createElement("h3", { className: "text-base font-semibold text-gray-800" }, isSpeechMode ? "Voice Input" : "AI Assistant"), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-2 mt-0.5" }, isSpeechMode ? /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ import_react6.default.createElement(
1280
+ /* @__PURE__ */ import_react6.default.createElement(
905
1281
  "div",
906
1282
  {
907
- className: "w-1 h-1 bg-blue-500 rounded-full",
908
1283
  style: {
909
- animationDelay: "0ms",
910
- animation: "bounce 1s infinite"
1284
+ flex: 1,
1285
+ padding: "16px",
1286
+ overflowY: "auto"
911
1287
  }
912
- }
913
- ), /* @__PURE__ */ import_react6.default.createElement(
1288
+ },
1289
+ /* @__PURE__ */ import_react6.default.createElement(
1290
+ "div",
1291
+ {
1292
+ style: {
1293
+ minHeight: "80px",
1294
+ display: "flex",
1295
+ alignItems: "center",
1296
+ justifyContent: "center"
1297
+ }
1298
+ },
1299
+ displayedText ? /* @__PURE__ */ import_react6.default.createElement("div", { style: { width: "100%", textAlign: "center" } }, /* @__PURE__ */ import_react6.default.createElement(
1300
+ "p",
1301
+ {
1302
+ style: {
1303
+ fontSize: "14px",
1304
+ lineHeight: "1.625",
1305
+ fontWeight: "300",
1306
+ letterSpacing: "0.025em",
1307
+ color: "#1f2937",
1308
+ margin: 0
1309
+ }
1310
+ },
1311
+ displayedText,
1312
+ !isComplete && /* @__PURE__ */ import_react6.default.createElement(
1313
+ "span",
1314
+ {
1315
+ style: {
1316
+ display: "inline-block",
1317
+ width: "2px",
1318
+ height: "20px",
1319
+ background: "linear-gradient(to top, #3b82f6, #3b82f6)",
1320
+ marginLeft: "8px",
1321
+ verticalAlign: "text-bottom",
1322
+ borderRadius: "9999px",
1323
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1324
+ }
1325
+ }
1326
+ )
1327
+ )) : /* @__PURE__ */ import_react6.default.createElement("div", { style: { width: "100%", textAlign: "center" } }, /* @__PURE__ */ import_react6.default.createElement(
1328
+ "p",
1329
+ {
1330
+ style: {
1331
+ fontSize: "14px",
1332
+ color: "#4b5563",
1333
+ fontWeight: "300",
1334
+ fontStyle: "italic",
1335
+ margin: 0
1336
+ }
1337
+ },
1338
+ isSpeechMode ? "Start speaking..." : "Generating response..."
1339
+ ))
1340
+ )
1341
+ ),
1342
+ /* @__PURE__ */ import_react6.default.createElement(
914
1343
  "div",
915
1344
  {
916
- className: "w-1 h-1 bg-blue-500 rounded-full",
917
1345
  style: {
918
- animationDelay: "150ms",
919
- animation: "bounce 1s infinite"
1346
+ paddingLeft: "16px",
1347
+ paddingRight: "16px",
1348
+ paddingBottom: "16px",
1349
+ flexShrink: 0
920
1350
  }
921
- }
922
- ), /* @__PURE__ */ import_react6.default.createElement(
1351
+ },
1352
+ /* @__PURE__ */ import_react6.default.createElement(
1353
+ "div",
1354
+ {
1355
+ style: {
1356
+ display: "flex",
1357
+ alignItems: "center",
1358
+ justifyContent: "space-between",
1359
+ fontSize: "12px",
1360
+ color: "#6b7280"
1361
+ }
1362
+ },
1363
+ /* @__PURE__ */ import_react6.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ import_react6.default.createElement(
1364
+ "div",
1365
+ {
1366
+ style: {
1367
+ width: "8px",
1368
+ height: "8px",
1369
+ backgroundColor: "#3b82f6",
1370
+ borderRadius: "50%",
1371
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1372
+ }
1373
+ }
1374
+ ), /* @__PURE__ */ import_react6.default.createElement("span", null, isSpeechMode ? "Listening for input..." : "Response delivered")),
1375
+ /* @__PURE__ */ import_react6.default.createElement("span", null, (/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }))
1376
+ )
1377
+ ),
1378
+ /* @__PURE__ */ import_react6.default.createElement(
923
1379
  "div",
924
1380
  {
925
- className: "w-1 h-1 bg-blue-500 rounded-full",
926
1381
  style: {
927
- animationDelay: "300ms",
928
- animation: "bounce 1s infinite"
1382
+ position: "absolute",
1383
+ top: 0,
1384
+ left: 0,
1385
+ right: 0,
1386
+ height: "1px",
1387
+ background: "linear-gradient(to right, transparent, rgba(59, 130, 246, 0.5), transparent)"
929
1388
  }
930
1389
  }
931
- )), /* @__PURE__ */ import_react6.default.createElement("span", { className: "text-xs text-gray-600" }, "Listening...")) : /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Volume2, { className: "w-3 h-3 text-blue-500" }), /* @__PURE__ */ import_react6.default.createElement("span", { className: "text-xs text-gray-600" }, "Speaking..."))))), /* @__PURE__ */ import_react6.default.createElement(
932
- "button",
933
- {
934
- onClick: onClose,
935
- className: "w-8 h-8 rounded-xl bg-white/10 hover:bg-white/20 flex items-center justify-center transition-all duration-200 hover:scale-105"
936
- },
937
- /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.X, { className: "w-4 h-4 text-gray-600" })
938
- ))), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex-1 p-4 overflow-y-auto" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "min-h-[80px] flex items-center justify-center" }, displayedText ? /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-full text-center" }, /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-sm leading-relaxed font-light tracking-wide text-gray-800" }, displayedText, !isComplete && /* @__PURE__ */ import_react6.default.createElement(
939
- "span",
940
- {
941
- className: "inline-block w-0.5 h-5 bg-gradient-to-t from-blue-500 to-blue-500 ml-2 align-text-bottom rounded-full",
942
- style: { animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" }
943
- }
944
- ))) : /* @__PURE__ */ import_react6.default.createElement("div", { className: "w-full text-center" }, /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-sm text-gray-600 font-light italic" }, isSpeechMode ? "Start speaking..." : "Generating response...")))), /* @__PURE__ */ import_react6.default.createElement("div", { className: "px-4 pb-4 flex-shrink-0" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center justify-between text-xs text-gray-500" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react6.default.createElement(
945
- "div",
946
- {
947
- className: "w-2 h-2 bg-blue-500 rounded-full",
948
- style: { animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" }
949
- }
950
- ), /* @__PURE__ */ import_react6.default.createElement("span", null, isSpeechMode ? "Listening for input..." : "Response delivered")), /* @__PURE__ */ import_react6.default.createElement("span", null, (/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })))), /* @__PURE__ */ import_react6.default.createElement("div", { className: "absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-blue-500/50 to-transparent" }))
951
- ));
1390
+ )
1391
+ )));
952
1392
  };
953
1393
  var MicButton = ({
954
1394
  hasText = false,
@@ -958,7 +1398,8 @@ var MicButton = ({
958
1398
  imageStyle,
959
1399
  buttonStyle,
960
1400
  screenPosition = "bottom-right",
961
- buttonSize = 60
1401
+ bottomSpace = 20,
1402
+ buttonSize = 64
962
1403
  }) => {
963
1404
  const { isListening, start, stop, transcript } = useVoice();
964
1405
  const [micState, setMicState] = (0, import_react6.useState)("idle");
@@ -1040,27 +1481,36 @@ var MicButton = ({
1040
1481
  }
1041
1482
  }, [isListening, transcript]);
1042
1483
  const getIcon = () => {
1043
- switch (micState) {
1044
- case "listening":
1045
- return /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Mic, { className: "w-7 h-7 text-white drop-shadow-lg" });
1046
- case "thinking":
1047
- return /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Loader2, { className: "w-7 h-7 text-white drop-shadow-lg animate-spin" });
1048
- case "replying":
1049
- return /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Volume2, { className: "w-7 h-7 text-white drop-shadow-lg animate-pulse" });
1050
- default:
1051
- return /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Mic, { className: "w-7 h-7 text-white drop-shadow-lg" });
1484
+ if (imageSource) {
1485
+ const baseImageStyle = {
1486
+ width: `${buttonSize * 0.4375}px`,
1487
+ height: `${buttonSize * 0.4375}px`,
1488
+ objectFit: "contain",
1489
+ filter: "drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1))",
1490
+ ...imageStyle
1491
+ };
1492
+ const animatedImageStyle = micState === "thinking" ? { ...baseImageStyle, animation: "spin 1s linear infinite" } : micState === "replying" ? { ...baseImageStyle, animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" } : baseImageStyle;
1493
+ return /* @__PURE__ */ import_react6.default.createElement("img", { src: imageSource, alt: "Voice Assistant", style: animatedImageStyle });
1052
1494
  }
1053
- };
1054
- const getButtonClasses = () => {
1495
+ const iconStyle = {
1496
+ width: `${buttonSize * 0.4375}px`,
1497
+ height: `${buttonSize * 0.4375}px`,
1498
+ color: "white",
1499
+ filter: "drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1))"
1500
+ };
1055
1501
  switch (micState) {
1056
- case "listening":
1057
- return "scale-110 shadow-2xl shadow-blue-500/60";
1058
1502
  case "thinking":
1059
- return "scale-105 shadow-xl shadow-purple-400/40 animate-pulse";
1503
+ return /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Loader2, { style: { ...iconStyle, animation: "spin 1s linear infinite" } });
1060
1504
  case "replying":
1061
- return "scale-105 shadow-xl shadow-cyan-400/40";
1505
+ return /* @__PURE__ */ import_react6.default.createElement(
1506
+ import_lucide_react.Volume2,
1507
+ {
1508
+ style: { ...iconStyle, animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" }
1509
+ }
1510
+ );
1511
+ case "listening":
1062
1512
  default:
1063
- return "hover:scale-105 shadow-lg shadow-blue-500/30 hover:shadow-xl hover:shadow-blue-500/40";
1513
+ return /* @__PURE__ */ import_react6.default.createElement(import_lucide_react.Mic, { style: iconStyle });
1064
1514
  }
1065
1515
  };
1066
1516
  const shouldShowWaves = micState === "listening" || micState === "replying";
@@ -1068,7 +1518,7 @@ var MicButton = ({
1068
1518
  const positionStyles = {
1069
1519
  position: "fixed",
1070
1520
  // <-- Ensure button is fixed to the viewport
1071
- bottom: 20,
1521
+ bottom: bottomSpace,
1072
1522
  zIndex: 9999
1073
1523
  };
1074
1524
  switch (screenPosition) {
@@ -1091,32 +1541,134 @@ var MicButton = ({
1091
1541
  };
1092
1542
  }
1093
1543
  };
1094
- return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("div", { className: "relative flex items-center justify-center", style: getPositionStyle() }, shouldShowWaves && /* @__PURE__ */ import_react6.default.createElement(WaveAnimation, null), /* @__PURE__ */ import_react6.default.createElement(
1544
+ const buttonStyles = {
1545
+ container: {
1546
+ position: "relative",
1547
+ display: "flex",
1548
+ alignItems: "center",
1549
+ justifyContent: "center"
1550
+ },
1551
+ button: {
1552
+ position: "relative",
1553
+ display: "flex",
1554
+ alignItems: "center",
1555
+ justifyContent: "center",
1556
+ width: `${buttonSize}px`,
1557
+ height: `${buttonSize}px`,
1558
+ borderRadius: "50%",
1559
+ background: "linear-gradient(to bottom right, #3b82f6, #22d3ee, #c084fc)",
1560
+ // from-blue-500 via-cyan-400 to-purple-400
1561
+ transition: "all 0.5s",
1562
+ border: "none",
1563
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
1564
+ // shadow-2xl
1565
+ cursor: "pointer",
1566
+ transform: "scale(1)",
1567
+ ...buttonStyle
1568
+ },
1569
+ iconContainer: {
1570
+ position: "relative",
1571
+ zIndex: 10
1572
+ },
1573
+ listeningGlow: {
1574
+ position: "absolute",
1575
+ top: 0,
1576
+ left: 0,
1577
+ right: 0,
1578
+ bottom: 0,
1579
+ borderRadius: "50%",
1580
+ backgroundColor: "#3b82f6",
1581
+ opacity: 0.3,
1582
+ animation: "ping 1s cubic-bezier(0, 0, 0.2, 1) infinite"
1583
+ },
1584
+ thinkingRing: {
1585
+ position: "absolute",
1586
+ top: "-2px",
1587
+ left: "-2px",
1588
+ right: "-2px",
1589
+ bottom: "-2px",
1590
+ borderRadius: "50%",
1591
+ border: "2px solid rgba(59, 130, 246, 0.6)",
1592
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1593
+ },
1594
+ replyingGlow: {
1595
+ position: "absolute",
1596
+ top: 0,
1597
+ left: 0,
1598
+ right: 0,
1599
+ bottom: 0,
1600
+ borderRadius: "50%",
1601
+ backgroundColor: "#3b82f6",
1602
+ opacity: 0.25,
1603
+ animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
1604
+ }
1605
+ };
1606
+ const getDynamicButtonStyle = () => {
1607
+ const baseStyle = { ...buttonStyles.button };
1608
+ switch (micState) {
1609
+ case "listening":
1610
+ baseStyle.transform = "scale(1.1)";
1611
+ baseStyle.boxShadow = "0 25px 50px -12px rgba(59, 130, 246, 0.6)";
1612
+ break;
1613
+ case "thinking":
1614
+ baseStyle.transform = "scale(1.05)";
1615
+ baseStyle.boxShadow = "0 20px 25px -5px rgba(196, 132, 252, 0.4)";
1616
+ baseStyle.animation = "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite";
1617
+ break;
1618
+ case "replying":
1619
+ baseStyle.transform = "scale(1.05)";
1620
+ baseStyle.boxShadow = "0 20px 25px -5px rgba(34, 211, 238, 0.4)";
1621
+ break;
1622
+ default:
1623
+ baseStyle.boxShadow = "0 10px 15px -3px rgba(59, 130, 246, 0.3)";
1624
+ break;
1625
+ }
1626
+ return baseStyle;
1627
+ };
1628
+ return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("div", { style: { ...buttonStyles.container, ...getPositionStyle() } }, shouldShowWaves && /* @__PURE__ */ import_react6.default.createElement(WaveAnimation, null), /* @__PURE__ */ import_react6.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ import_react6.default.createElement(
1095
1629
  "button",
1096
1630
  {
1097
1631
  "data-testid": "ignore",
1098
1632
  onClick: handlePress,
1099
1633
  disabled: micState === "thinking" || micState === "replying",
1100
- className: `relative flex items-center justify-center w-16 h-16 rounded-full bg-gradient-to-br from-blue-500 via-cyan-400 to-purple-400 transition-all duration-500 border-0 shadow-2xl transform hover:scale-105 ${getButtonClasses()}`,
1101
- style: {
1102
- ...buttonStyle
1634
+ style: getDynamicButtonStyle(),
1635
+ onMouseEnter: (e) => {
1636
+ if (micState === "idle") {
1637
+ e.currentTarget.style.transform = "scale(1.05)";
1638
+ e.currentTarget.style.boxShadow = "0 20px 25px -5px rgba(59, 130, 246, 0.4)";
1639
+ }
1640
+ },
1641
+ onMouseLeave: (e) => {
1642
+ if (micState === "idle") {
1643
+ e.currentTarget.style.transform = "scale(1)";
1644
+ e.currentTarget.style.boxShadow = "0 10px 15px -3px rgba(59, 130, 246, 0.3)";
1645
+ }
1103
1646
  },
1104
1647
  "aria-label": micState === "thinking" ? "Processing..." : micState === "replying" ? "AI is responding..." : isListening ? "Stop listening" : "Start listening"
1105
1648
  },
1106
- /* @__PURE__ */ import_react6.default.createElement("div", { className: "relative z-10" }, getIcon()),
1107
- micState === "listening" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "absolute inset-0 rounded-full bg-blue-500 opacity-30 animate-ping" }),
1108
- micState === "thinking" && /* @__PURE__ */ import_react6.default.createElement(
1109
- "div",
1110
- {
1111
- className: "absolute inset-[-2px] rounded-full border-2 animate-pulse",
1112
- style: {
1113
- borderColor: "rgba(59, 130, 246, 0.6)",
1114
- animationDuration: "2s"
1115
- }
1649
+ /* @__PURE__ */ import_react6.default.createElement("div", { style: buttonStyles.iconContainer }, getIcon()),
1650
+ micState === "listening" && /* @__PURE__ */ import_react6.default.createElement("div", { style: buttonStyles.listeningGlow }),
1651
+ micState === "thinking" && /* @__PURE__ */ import_react6.default.createElement("div", { style: buttonStyles.thinkingRing }),
1652
+ micState === "replying" && /* @__PURE__ */ import_react6.default.createElement("div", { style: buttonStyles.replyingGlow })
1653
+ ), hasText && text && /* @__PURE__ */ import_react6.default.createElement(
1654
+ "div",
1655
+ {
1656
+ style: {
1657
+ fontSize: "12px",
1658
+ color: "#6b7280",
1659
+ fontWeight: "500",
1660
+ textAlign: "center",
1661
+ background: "rgba(255, 255, 255, 0.9)",
1662
+ padding: "4px 8px",
1663
+ borderRadius: "6px",
1664
+ backdropFilter: "blur(8px)",
1665
+ border: "1px solid rgba(59, 130, 246, 0.2)",
1666
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
1667
+ ...textStyle
1116
1668
  }
1117
- ),
1118
- micState === "replying" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "absolute inset-0 rounded-full bg-blue-500 opacity-25 animate-pulse" })
1119
- )), showModal && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
1669
+ },
1670
+ text
1671
+ ))), showModal && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
1120
1672
  /* @__PURE__ */ import_react6.default.createElement(
1121
1673
  UnifiedModal,
1122
1674
  {
@@ -1146,8 +1698,12 @@ MicButton.displayName = "MicButton";
1146
1698
  CuekitProvider,
1147
1699
  InitCuekit,
1148
1700
  MicButton,
1701
+ navigate,
1149
1702
  onStateChange,
1150
1703
  processVoice,
1704
+ safeNavigate,
1705
+ setNavigationHandler,
1706
+ setNavigator,
1151
1707
  useAudioController,
1152
1708
  useVoiceRecognition
1153
1709
  });