@vanira/sdk-react-native 0.0.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.
Files changed (148) hide show
  1. package/README.md +239 -0
  2. package/package.json +53 -0
  3. package/src/__tests__/WebRTCClient.integration.test.ts +396 -0
  4. package/src/__tests__/adapters.test.ts +475 -0
  5. package/src/__tests__/httpResponse.test.ts +25 -0
  6. package/src/__tests__/mocks/react-native-incall-manager.ts +8 -0
  7. package/src/__tests__/mocks/react-native-permissions.ts +15 -0
  8. package/src/__tests__/mocks/react-native-webrtc.ts +6 -0
  9. package/src/__tests__/mocks/react-native.ts +28 -0
  10. package/src/__tests__/preset.test.ts +239 -0
  11. package/src/__tests__/resolveRuntimeConfig.test.ts +90 -0
  12. package/src/__tests__/storage.test.ts +211 -0
  13. package/src/__tests__/webrtcSignaling.test.ts +42 -0
  14. package/src/adapters/PeerConnectionAdapter.ts +101 -0
  15. package/src/adapters/browser/BrowserAudioAdapter.ts +43 -0
  16. package/src/adapters/browser/BrowserDataChannelAdapter.ts +69 -0
  17. package/src/adapters/browser/BrowserMediaAdapter.ts +15 -0
  18. package/src/adapters/browser/BrowserPeerAdapter.ts +14 -0
  19. package/src/adapters/browser/index.ts +4 -0
  20. package/src/adapters/interfaces.ts +84 -0
  21. package/src/adapters/react-native/RNAudioAdapter.ts +42 -0
  22. package/src/adapters/react-native/RNDataChannelAdapter.ts +79 -0
  23. package/src/adapters/react-native/RNMediaAdapter.ts +46 -0
  24. package/src/adapters/react-native/RNPeerAdapter.ts +28 -0
  25. package/src/adapters/react-native/callAudioRouting.ts +115 -0
  26. package/src/adapters/react-native/decodeUtf8.ts +72 -0
  27. package/src/adapters/react-native/index.ts +4 -0
  28. package/src/adapters/react-native/rnUploadFile.ts +76 -0
  29. package/src/adapters/storage/BrowserDualStorageAdapter.ts +71 -0
  30. package/src/adapters/storage/MemoryStorageAdapter.ts +50 -0
  31. package/src/adapters/storage/StorageAdapter.ts +21 -0
  32. package/src/adapters/storage/createSyncStorageAdapter.ts +40 -0
  33. package/src/adapters/storage/index.ts +7 -0
  34. package/src/api/services/ChatService.ts +304 -0
  35. package/src/api/services/ConfigService.ts +33 -0
  36. package/src/assets/icons.js +35 -0
  37. package/src/cdn.ts +68 -0
  38. package/src/core/CallSessionStore.ts +137 -0
  39. package/src/core/DraggableController.ts +83 -0
  40. package/src/core/SessionManager.ts +322 -0
  41. package/src/core/VaniraAI.ts +464 -0
  42. package/src/core/WebRTCClient.ts +1012 -0
  43. package/src/core/httpResponse.ts +22 -0
  44. package/src/core/iceServers.ts +18 -0
  45. package/src/core/toolCallNormalize.ts +80 -0
  46. package/src/core/voice-client.js +236 -0
  47. package/src/core/webrtcSignaling.ts +72 -0
  48. package/src/index.js +34 -0
  49. package/src/index.ts +6 -0
  50. package/src/platforms/browser.ts +67 -0
  51. package/src/platforms/react-native.ts +105 -0
  52. package/src/presets/BookingCalendarModal.tsx +457 -0
  53. package/src/presets/CameraModal.tsx +576 -0
  54. package/src/presets/DynamicFormModal.tsx +378 -0
  55. package/src/presets/NativePresetRenderer.tsx +350 -0
  56. package/src/presets/NavigateHandler.tsx +75 -0
  57. package/src/presets/PresetHost.tsx +155 -0
  58. package/src/presets/PresetShellModal.tsx +97 -0
  59. package/src/presets/UploadModal.tsx +321 -0
  60. package/src/presets/calendar/calendarUtils.ts +386 -0
  61. package/src/presets/call/CallSpeakerToggle.tsx +59 -0
  62. package/src/presets/call/callAudioRouting.ts +2 -0
  63. package/src/presets/call/useCallSpeaker.ts +31 -0
  64. package/src/presets/camera/cameraPermissions.ts +18 -0
  65. package/src/presets/camera/cameraStream.ts +19 -0
  66. package/src/presets/camera/cameraUtils.ts +21 -0
  67. package/src/presets/camera/useLivenessFlow.ts +95 -0
  68. package/src/presets/chalkboard/ChalkboardOverlay.tsx +156 -0
  69. package/src/presets/chalkboard/EraseTextHandler.tsx +95 -0
  70. package/src/presets/chalkboard/TypeTextHandler.tsx +107 -0
  71. package/src/presets/chalkboard/boardAbort.ts +36 -0
  72. package/src/presets/chalkboard/boardQueue.ts +620 -0
  73. package/src/presets/chalkboard/chalkboardSession.ts +75 -0
  74. package/src/presets/chalkboard/drawUtils.ts +123 -0
  75. package/src/presets/chalkboard/textUtils.ts +109 -0
  76. package/src/presets/clipRegion/ClipRegionModal.tsx +261 -0
  77. package/src/presets/clipRegion/clipRegionBridge.ts +19 -0
  78. package/src/presets/form/formValidation.ts +104 -0
  79. package/src/presets/form/parseFormFields.ts +171 -0
  80. package/src/presets/host/HostElementPresetHandler.tsx +155 -0
  81. package/src/presets/host/hostPresetBridge.ts +71 -0
  82. package/src/presets/index.ts +63 -0
  83. package/src/presets/liveScreen/CloseLiveScreenHandler.tsx +36 -0
  84. package/src/presets/liveScreen/LiveScreenCaptureHost.tsx +312 -0
  85. package/src/presets/liveScreen/LiveScreenHandler.tsx +25 -0
  86. package/src/presets/liveScreen/LiveScreenPipOverlay.tsx +6 -0
  87. package/src/presets/liveScreen/liveScreenSession.ts +73 -0
  88. package/src/presets/liveVision/CloseLiveVisionHandler.tsx +29 -0
  89. package/src/presets/liveVision/LiveVisionCameraHost.tsx +317 -0
  90. package/src/presets/liveVision/LiveVisionHandler.tsx +26 -0
  91. package/src/presets/liveVision/LiveVisionPipOverlay.tsx +7 -0
  92. package/src/presets/liveVision/liveVisionFrameLoop.ts +38 -0
  93. package/src/presets/liveVision/liveVisionSession.ts +75 -0
  94. package/src/presets/liveVision/liveVisionUpload.ts +62 -0
  95. package/src/presets/navigation/internalRouteRegistry.ts +25 -0
  96. package/src/presets/navigation/navigationBridge.ts +76 -0
  97. package/src/presets/navigation/navigationTypes.ts +12 -0
  98. package/src/presets/parseToolCall.ts +60 -0
  99. package/src/presets/presetClientAdapter.ts +29 -0
  100. package/src/presets/presetCompletion.ts +91 -0
  101. package/src/presets/presetEventHelpers.ts +45 -0
  102. package/src/presets/registry.ts +128 -0
  103. package/src/presets/streaming/mediaFrameUpload.ts +93 -0
  104. package/src/presets/types.ts +74 -0
  105. package/src/presets/upload/pickUploadFile.ts +256 -0
  106. package/src/presets/upload/uploadFormats.ts +163 -0
  107. package/src/presets/upload/uploadUtils.ts +68 -0
  108. package/src/react/PresetRenderer.tsx +144 -0
  109. package/src/react/index.ts +1 -0
  110. package/src/runtime/browserRuntime.ts +54 -0
  111. package/src/runtime/platform.ts +17 -0
  112. package/src/runtime/reactNativeRuntime.ts +68 -0
  113. package/src/runtime/resolveRuntimeConfig.ts +75 -0
  114. package/src/runtime/runtimeBundles.ts +74 -0
  115. package/src/runtime/types.ts +135 -0
  116. package/src/types/react-native-incall-manager.d.ts +17 -0
  117. package/src/types/react-native-webrtc.d.ts +47 -0
  118. package/src/types.ts +133 -0
  119. package/src/ui/VaniraWidget.ts +87 -0
  120. package/src/ui/abstraction/AbstractWidgetProvider.ts +18 -0
  121. package/src/ui/abstraction/interfaces.ts +12 -0
  122. package/src/ui/adapters/VaniraChatAdapter.ts +42 -0
  123. package/src/ui/components/AvatarView.ts +81 -0
  124. package/src/ui/components/ChatWindow.ts +263 -0
  125. package/src/ui/components/FloatingButton.ts +163 -0
  126. package/src/ui/components/FloatingWelcomeChips.ts +137 -0
  127. package/src/ui/components/Panel.ts +120 -0
  128. package/src/ui/components/VoiceOrb.ts +79 -0
  129. package/src/ui/components/VoiceOverlay.ts +497 -0
  130. package/src/ui/components/index.ts +7 -0
  131. package/src/ui/factory/WidgetFactory.ts +16 -0
  132. package/src/ui/icons_data.ts +2 -0
  133. package/src/ui/presets/WidgetPresetRenderer.ts +1802 -0
  134. package/src/ui/presets/types.ts +16 -0
  135. package/src/ui/providers/VaniraInternalProvider.ts +1066 -0
  136. package/src/ui/styles/index.ts +323 -0
  137. package/src/ui/styles/keyframes.ts +76 -0
  138. package/src/ui/styles/theme.ts +57 -0
  139. package/src/ui/styles/widget.css.ts +838 -0
  140. package/src/ui/utils.ts +37 -0
  141. package/src/ui/views/AbstractChatView.ts +93 -0
  142. package/src/ui/views/AbstractVoiceView.ts +57 -0
  143. package/src/ui/views/AvatarOnlyView.ts +78 -0
  144. package/src/ui/views/ChatAvatarView.ts +66 -0
  145. package/src/ui/views/ChatOnlyView.ts +28 -0
  146. package/src/ui/views/ChatVoiceView.ts +15 -0
  147. package/src/ui/views/VoiceOnlyView.ts +25 -0
  148. package/src/ui/views/index.ts +5 -0
@@ -0,0 +1,838 @@
1
+
2
+ import { keyframes } from './keyframes';
3
+
4
+ export const widgetStyles = `
5
+ :host(.vanira-portal) {
6
+ position: fixed !important;
7
+ bottom: 0 !important;
8
+ right: 0 !important;
9
+ top: auto !important;
10
+ left: auto !important;
11
+ width: 0 !important;
12
+ height: 0 !important;
13
+ pointer-events: none !important;
14
+ z-index: 2147483647;
15
+ overflow: visible !important;
16
+ contain: none !important;
17
+ }
18
+
19
+ :host {
20
+ display: block;
21
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
22
+ box-sizing: border-box;
23
+
24
+ /* Default Theme Variables */
25
+ --primary: #000000;
26
+ --primary-hover: #111111;
27
+ --primary-rgb: 0, 0, 0;
28
+ --secondary: #111111;
29
+ --secondary-rgb: 17, 17, 17;
30
+ --bg: #ffffff;
31
+ --text: #1f2937;
32
+ --text-muted: #6b7280;
33
+ --border: #e5e7eb;
34
+ --shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
35
+ --shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.15);
36
+ }
37
+
38
+ :host * {
39
+ box-sizing: border-box;
40
+ }
41
+
42
+ ${keyframes}
43
+
44
+ .widget-fab {
45
+ position: fixed;
46
+ z-index: 2147483647;
47
+ pointer-events: auto !important;
48
+ width: 64px;
49
+ height: 64px;
50
+ border-radius: 50%;
51
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
52
+ border: none;
53
+ cursor: pointer;
54
+ display: flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ box-shadow: var(--shadow);
58
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
59
+ animation: fadeInScale 0.4s ease-out;
60
+ }
61
+
62
+ .widget-fab:hover {
63
+ transform: scale(1.1);
64
+ box-shadow: var(--shadow-lg);
65
+ }
66
+
67
+ .widget-fab:active {
68
+ transform: scale(0.95);
69
+ }
70
+
71
+ .widget-fab svg {
72
+ width: 28px;
73
+ height: 28px;
74
+ color: white;
75
+ }
76
+
77
+ .widget-panel {
78
+ position: fixed;
79
+ z-index: 2147483647;
80
+ pointer-events: auto;
81
+ background: rgba(255, 255, 255, 0.98);
82
+ backdrop-filter: blur(20px);
83
+ -webkit-backdrop-filter: blur(20px);
84
+ border: 1px solid #d1d5db;
85
+ border-radius: 28px;
86
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.08);
87
+ overflow: hidden;
88
+ display: flex;
89
+ flex-direction: column;
90
+ transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1);
91
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
92
+
93
+ /* Default Dimensions */
94
+ width: 400px;
95
+ height: 600px;
96
+ max-height: 90vh;
97
+ max-width: 95vw;
98
+ }
99
+
100
+ .widget-panel.maximized {
101
+ width: 90vw !important;
102
+ height: 90vh !important;
103
+ top: 5vh !important;
104
+ left: 5vw !important;
105
+ right: 5vw !important;
106
+ bottom: 5vh !important;
107
+ margin: auto;
108
+ }
109
+
110
+ .widget-body {
111
+ padding: 0;
112
+ flex: 1;
113
+ display: flex;
114
+ flex-direction: column;
115
+ overflow: hidden;
116
+ min-height: 0;
117
+ }
118
+
119
+ .widget-panel.hidden {
120
+ opacity: 0;
121
+ pointer-events: none !important;
122
+ transform: translateY(20px) scale(0.95);
123
+ }
124
+
125
+ .widget-header {
126
+ background: #1f2937;
127
+ color: white;
128
+ padding: 14px 20px;
129
+ display: flex;
130
+ justify-content: space-between;
131
+ align-items: center;
132
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
133
+ }
134
+
135
+ .widget-title {
136
+ font-size: 18px;
137
+ font-weight: 600;
138
+ margin: 0;
139
+ letter-spacing: 0.3px;
140
+ }
141
+
142
+ .close-btn {
143
+ background: rgba(255, 255, 255, 0.15);
144
+ border: none;
145
+ width: 36px;
146
+ height: 36px;
147
+ border-radius: 50%;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ cursor: pointer;
152
+ transition: all 0.2s;
153
+ backdrop-filter: blur(10px);
154
+ }
155
+
156
+ .close-btn:hover {
157
+ background: rgba(255, 255, 255, 0.25);
158
+ transform: scale(1.1);
159
+ }
160
+
161
+ .close-btn.maximize-btn {
162
+ display: flex;
163
+ }
164
+
165
+ .close-btn svg {
166
+ width: 18px;
167
+ height: 18px;
168
+ color: white;
169
+ flex-shrink: 0;
170
+ }
171
+
172
+ .status-indicator {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 12px;
176
+ padding: 16px;
177
+ background: #f9fafb;
178
+ border-radius: 12px;
179
+ margin-bottom: 20px;
180
+ }
181
+
182
+ .status-dot {
183
+ width: 10px;
184
+ height: 10px;
185
+ border-radius: 50%;
186
+ background: #10b981;
187
+ animation: pulse 2s infinite;
188
+ }
189
+
190
+ .status-text {
191
+ font-size: 14px;
192
+ color: var(--text-muted);
193
+ margin: 0;
194
+ }
195
+
196
+ .controls {
197
+ display: flex;
198
+ gap: 12px;
199
+ justify-content: center;
200
+ }
201
+
202
+ .control-btn {
203
+ flex: 1;
204
+ padding: 14px 20px;
205
+ border: none;
206
+ border-radius: 12px;
207
+ font-size: 14px;
208
+ font-weight: 600;
209
+ cursor: pointer;
210
+ transition: all 0.2s;
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ gap: 8px;
215
+ }
216
+
217
+ .control-btn svg {
218
+ width: 18px;
219
+ height: 18px;
220
+ }
221
+
222
+ .control-btn.primary {
223
+ background: #1f2937;
224
+ color: white;
225
+ }
226
+
227
+ .control-btn.primary:hover {
228
+ background: #374151;
229
+ }
230
+
231
+ .control-btn.danger {
232
+ background: #ef4444;
233
+ color: white;
234
+ }
235
+
236
+ .control-btn.danger:hover {
237
+ background: #dc2626;
238
+ }
239
+
240
+ .voice-mode-container {
241
+ display: flex;
242
+ flex-direction: column;
243
+ align-items: center;
244
+ justify-content: center;
245
+ height: 100%;
246
+ padding-bottom: 0;
247
+ }
248
+
249
+ .central-orb-container {
250
+ position: relative;
251
+ width: 120px;
252
+ height: 120px;
253
+ margin-bottom: 32px;
254
+ cursor: pointer;
255
+ }
256
+
257
+ .central-orb {
258
+ width: 100%;
259
+ height: 100%;
260
+ border-radius: 50%;
261
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
262
+ display: flex;
263
+ align-items: center;
264
+ justify-content: center;
265
+ color: white;
266
+ position: relative;
267
+ z-index: 10;
268
+ box-shadow: 0 10px 30px rgba(var(--primary-rgb), 0.3);
269
+ transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
270
+ }
271
+
272
+ .central-orb.active {
273
+ animation: pulse 2s infinite;
274
+ }
275
+
276
+ .central-orb.idle {
277
+ animation: floatOrb 4s ease-in-out infinite;
278
+ cursor: pointer;
279
+ }
280
+
281
+ .central-orb.idle:hover {
282
+ transform: scale(1.05);
283
+ }
284
+
285
+ .central-orb-glow {
286
+ position: absolute;
287
+ top: 50%;
288
+ left: 50%;
289
+ transform: translate(-50%, -50%);
290
+ width: 140%;
291
+ height: 140%;
292
+ background: radial-gradient(circle, rgba(var(--primary-rgb), 0.2) 0%, transparent 70%);
293
+ animation: pulseGlowIdle 4s ease-in-out infinite;
294
+ z-index: -1;
295
+ pointer-events: none;
296
+ }
297
+
298
+ .central-orb svg {
299
+ width: 24px;
300
+ height: 24px;
301
+ }
302
+
303
+ .voice-status-text {
304
+ font-size: 20px;
305
+ font-weight: 600;
306
+ color: var(--text);
307
+ margin-bottom: 8px;
308
+ text-align: center;
309
+ }
310
+
311
+ .voice-status-subtext {
312
+ font-size: 14px;
313
+ color: var(--text-muted);
314
+ text-align: center;
315
+ }
316
+
317
+ /* Chat Mode Styles */
318
+ .chat-messages {
319
+ flex: 1;
320
+ min-height: 0;
321
+ overflow-y: auto;
322
+ padding: 16px;
323
+ display: flex;
324
+ flex-direction: column;
325
+ gap: 12px;
326
+ background: #f9fafb;
327
+
328
+ scrollbar-width: thin;
329
+ scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
330
+ }
331
+
332
+ .chat-messages::-webkit-scrollbar {
333
+ width: 6px;
334
+ }
335
+
336
+ .chat-messages::-webkit-scrollbar-track {
337
+ background: transparent;
338
+ }
339
+
340
+ .chat-messages::-webkit-scrollbar-thumb {
341
+ background-color: rgba(156, 163, 175, 0.5);
342
+ border-radius: 3px;
343
+ }
344
+
345
+ .chat-message {
346
+ max-width: 85%;
347
+ padding: 12px 16px;
348
+ border-radius: 16px;
349
+ font-size: 14px;
350
+ line-height: 1.5;
351
+ word-wrap: break-word;
352
+ white-space: pre-wrap;
353
+ }
354
+
355
+ .chat-message.user {
356
+ align-self: flex-end;
357
+ background: #000000;
358
+ color: white;
359
+ border-bottom-right-radius: 4px;
360
+ }
361
+
362
+ .chat-message.assistant {
363
+ align-self: flex-start;
364
+ background: #ffffff;
365
+ border: 1px solid #e5e7eb;
366
+ color: var(--text);
367
+ border-bottom-left-radius: 4px;
368
+ box-shadow: 0 1px 2px rgba(0,0,0,0.05);
369
+ }
370
+
371
+ .chat-input-area {
372
+ padding: 20px;
373
+ border-top: 1px solid rgba(0, 0, 0, 0.05);
374
+ display: flex;
375
+ gap: 10px;
376
+ align-items: center;
377
+ background: white;
378
+ z-index: 30;
379
+ position: relative;
380
+ border-bottom-left-radius: 28px;
381
+ border-bottom-right-radius: 28px;
382
+ }
383
+
384
+ .chat-input {
385
+ flex: 1;
386
+ padding: 14px 20px;
387
+ border: 1px solid #e5e7eb;
388
+ border-radius: 28px;
389
+ font-size: 15px;
390
+ outline: none;
391
+ transition: all 0.3s;
392
+ background: #f3f4f6;
393
+ color: #1f2937;
394
+ }
395
+
396
+ .chat-input:focus {
397
+ border-color: var(--primary);
398
+ background: white;
399
+ box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);
400
+ }
401
+
402
+ .chat-send-btn {
403
+ width: 48px;
404
+ height: 48px;
405
+ border-radius: 50%;
406
+ background: var(--primary);
407
+ border: none;
408
+ cursor: pointer;
409
+ display: flex;
410
+ align-items: center;
411
+ justify-content: center;
412
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
413
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
414
+ flex-shrink: 0;
415
+ }
416
+
417
+ .chat-send-btn:hover {
418
+ transform: scale(1.05) rotate(-10deg);
419
+ background: var(--primary-hover);
420
+ box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);
421
+ }
422
+
423
+ .chat-send-btn:active {
424
+ transform: scale(0.95);
425
+ }
426
+
427
+ .chat-send-btn svg {
428
+ width: 22px;
429
+ height: 22px;
430
+ color: white;
431
+ margin-left: 2px;
432
+ }
433
+
434
+ .avatar-container {
435
+ background: transparent;
436
+ flex: 1;
437
+ display: flex;
438
+ align-items: center;
439
+ justify-content: center;
440
+ position: relative;
441
+ overflow: hidden;
442
+ }
443
+
444
+ .avatar-video {
445
+ width: 100%;
446
+ height: 100%;
447
+ object-fit: cover;
448
+ }
449
+
450
+ .voice-btn-simple {
451
+ position: relative;
452
+ width: 44px;
453
+ height: 44px;
454
+ border-radius: 50%;
455
+ border: 1.5px solid #e5e7eb;
456
+ cursor: pointer;
457
+ display: flex;
458
+ align-items: center;
459
+ justify-content: center;
460
+ transition: all 0.3s;
461
+ overflow: visible;
462
+ background: white;
463
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
464
+ }
465
+
466
+ .voice-btn-simple:hover {
467
+ transform: scale(1.05);
468
+ background: #f9fafb;
469
+ border-color: #9ca3af;
470
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
471
+ }
472
+
473
+ .voice-btn-icon {
474
+ width: 100%;
475
+ height: 100%;
476
+ display: flex;
477
+ align-items: center;
478
+ justify-content: center;
479
+ color: #4b5563;
480
+ }
481
+
482
+ .voice-btn-icon svg {
483
+ width: 20px;
484
+ height: 20px;
485
+ stroke-width: 2px;
486
+ }
487
+
488
+ .absolute { position: absolute; }
489
+ .relative { position: relative; }
490
+ .rounded-full { border-radius: 9999px; }
491
+ .flex { display: flex; }
492
+ .items-center { align-items: center; }
493
+ .justify-center { justify-content: center; }
494
+ .w-full { width: 100%; }
495
+ .h-full { height: 100%; }
496
+ .z-50 { z-index: 50; }
497
+
498
+ .branding-footer {
499
+ display: flex;
500
+ justify-content: center;
501
+ padding: 4px 0 8px 0;
502
+ background-color: #f9fafb;
503
+ font-size: 10px;
504
+ color: #9ca3af;
505
+ font-weight: 500;
506
+ letter-spacing: 0.025em;
507
+ }
508
+
509
+ .branding-footer b {
510
+ color: #3b82f6;
511
+ font-weight: 700;
512
+ margin-left: 4px;
513
+ }
514
+
515
+ @media (max-width: 640px) {
516
+ .widget-panel {
517
+ width: 75vw !important;
518
+ height: 50vh !important;
519
+ max-width: 75vw !important;
520
+ max-height: 50vh !important;
521
+ top: auto !important;
522
+ left: auto !important;
523
+ right: 16px !important;
524
+ bottom: 16px !important;
525
+ border-radius: 20px !important;
526
+ margin: 0 !important;
527
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15) !important;
528
+ }
529
+
530
+ .widget-panel.maximized {
531
+ width: 100vw !important;
532
+ height: 100vh !important;
533
+ max-width: 100vw !important;
534
+ max-height: 100vh !important;
535
+ top: 0 !important;
536
+ left: 0 !important;
537
+ right: 0 !important;
538
+ bottom: 0 !important;
539
+ border-radius: 0 !important;
540
+ margin: 0 !important;
541
+ }
542
+
543
+ .widget-fab {
544
+ width: 56px;
545
+ height: 56px;
546
+ bottom: 16px !important;
547
+ right: 16px !important;
548
+ }
549
+
550
+ :host(.vanira-panel-open) .widget-fab {
551
+ display: none !important;
552
+ }
553
+
554
+ .close-btn.maximize-btn {
555
+ display: flex !important;
556
+ }
557
+
558
+ .widget-header {
559
+ padding: 12px 16px;
560
+ }
561
+
562
+ .widget-title {
563
+ font-size: 16px;
564
+ }
565
+
566
+ .chat-input-area {
567
+ padding: 12px;
568
+ padding-bottom: env(safe-area-inset-bottom, 12px);
569
+ }
570
+
571
+ /* Voice overlay mobile default view adjustments */
572
+ .widget-panel:not(.maximized) .voice-content-container {
573
+ padding: 12px 16px 8px !important;
574
+ min-height: 0 !important;
575
+ flex: 1 !important;
576
+ }
577
+
578
+ .widget-panel:not(.maximized) .voice-orb-wrapper {
579
+ width: 140px !important;
580
+ height: 140px !important;
581
+ transform: scale(0.65) !important;
582
+ transform-origin: center !important;
583
+ margin: 4px 0 !important;
584
+ }
585
+
586
+ .widget-panel:not(.maximized) .voice-video-container {
587
+ max-width: 140px !important;
588
+ margin-bottom: 8px !important;
589
+ }
590
+
591
+ .widget-panel:not(.maximized) .voice-status-area {
592
+ margin-top: 4px !important;
593
+ gap: 4px !important;
594
+ }
595
+
596
+ .widget-panel:not(.maximized) .voice-status-area p {
597
+ margin: 0 !important;
598
+ }
599
+
600
+ .widget-panel:not(.maximized) .voice-transcription {
601
+ margin-top: 4px !important;
602
+ font-size: 11px !important;
603
+ min-height: 24px !important;
604
+ max-height: 40px !important;
605
+ }
606
+
607
+ .widget-panel:not(.maximized) .voice-footer {
608
+ padding: 0 12px 12px !important;
609
+ }
610
+
611
+ .widget-panel:not(.maximized) .voice-hangup-btn {
612
+ padding: 8px 20px !important;
613
+ font-size: 12px !important;
614
+ }
615
+ }
616
+
617
+ /* Premium Session Behavior Selector */
618
+ .session-selector-container {
619
+ display: flex;
620
+ gap: 8px;
621
+ background: #f1f5f9;
622
+ padding: 4px;
623
+ border-radius: 12px;
624
+ margin-top: 24px;
625
+ width: 280px;
626
+ box-sizing: border-box;
627
+ border: 1px solid #e2e8f0;
628
+ pointer-events: auto !important;
629
+ }
630
+
631
+ .session-option {
632
+ flex: 1;
633
+ display: flex;
634
+ flex-direction: column;
635
+ align-items: center;
636
+ padding: 8px 10px;
637
+ background: transparent;
638
+ border-radius: 8px;
639
+ cursor: pointer;
640
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
641
+ border: 1.5px solid transparent;
642
+ }
643
+
644
+ .session-option:hover {
645
+ background: rgba(255, 255, 255, 0.5);
646
+ }
647
+
648
+ .session-option.active {
649
+ background: #ffffff;
650
+ border-color: var(--primary);
651
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
652
+ }
653
+
654
+ .session-option .session-title {
655
+ font-size: 11px;
656
+ font-weight: 700;
657
+ color: #1e293b;
658
+ margin-bottom: 2px;
659
+ letter-spacing: 0.2px;
660
+ text-transform: uppercase;
661
+ }
662
+
663
+ .session-option .session-desc {
664
+ font-size: 8.5px;
665
+ font-weight: 500;
666
+ color: #64748b;
667
+ text-align: center;
668
+ line-height: 1.2;
669
+ }
670
+
671
+ /* Selector styling for clean card launcher */
672
+ .clean-card-launcher .session-selector-container {
673
+ width: 100%;
674
+ margin-top: 10px;
675
+ margin-bottom: 6px;
676
+ gap: 4px;
677
+ padding: 3px;
678
+ border-radius: 8px;
679
+ }
680
+
681
+ .clean-card-launcher .session-option {
682
+ padding: 5px 6px;
683
+ border-radius: 6px;
684
+ }
685
+
686
+ .clean-card-launcher .session-option .session-title {
687
+ font-size: 9px;
688
+ margin-bottom: 0;
689
+ }
690
+
691
+ .clean-card-launcher .session-option .session-desc {
692
+ display: none;
693
+ }
694
+
695
+ /* Thin Resolve Bar & Link above text input */
696
+ .chat-resolve-bar {
697
+ padding: 8px 16px;
698
+ border-top: 1px solid rgba(0, 0, 0, 0.05);
699
+ border-bottom: 1px solid rgba(0, 0, 0, 0.03);
700
+ background: #ffffff;
701
+ display: flex;
702
+ justify-content: center;
703
+ align-items: center;
704
+ z-index: 25;
705
+ }
706
+
707
+ .chat-resolve-link {
708
+ background: none;
709
+ border: none;
710
+ font-size: 11px;
711
+ font-weight: 500;
712
+ color: var(--primary);
713
+ cursor: pointer;
714
+ transition: all 0.2s;
715
+ text-decoration: underline;
716
+ opacity: 0.8;
717
+ }
718
+
719
+ .chat-resolve-link:hover {
720
+ opacity: 1;
721
+ color: var(--primary-hover);
722
+ }
723
+
724
+ /* Audio-only Mode Sizing Override (Half Width and Height of 400x600) */
725
+ .widget-panel.voice-only-panel {
726
+ width: 200px !important;
727
+ height: 300px !important;
728
+ border-radius: 20px !important;
729
+ }
730
+
731
+ .widget-panel.voice-only-panel .widget-header {
732
+ padding: 8px 12px !important;
733
+ }
734
+
735
+ .widget-panel.voice-only-panel .widget-title {
736
+ font-size: 13px !important;
737
+ }
738
+
739
+ .widget-panel.voice-only-panel .close-btn {
740
+ width: 26px !important;
741
+ height: 26px !important;
742
+ }
743
+
744
+ .widget-panel.voice-only-panel .close-btn svg {
745
+ width: 14px !important;
746
+ height: 14px !important;
747
+ }
748
+
749
+ .widget-panel.voice-only-panel .central-orb-container {
750
+ width: 64px !important;
751
+ height: 64px !important;
752
+ margin-bottom: 12px !important;
753
+ }
754
+
755
+ .widget-panel.voice-only-panel .voice-status-text {
756
+ font-size: 13px !important;
757
+ font-weight: 600 !important;
758
+ margin-bottom: 2px !important;
759
+ }
760
+
761
+ .widget-panel.voice-only-panel .voice-status-subtext {
762
+ font-size: 10px !important;
763
+ }
764
+
765
+ .widget-panel.voice-only-panel .session-selector-container {
766
+ width: 184px !important;
767
+ margin-top: 14px !important;
768
+ gap: 4px !important;
769
+ padding: 3px !important;
770
+ border-radius: 8px !important;
771
+ }
772
+
773
+ .widget-panel.voice-only-panel .session-option {
774
+ padding: 6px 2px !important;
775
+ border-radius: 6px !important;
776
+ }
777
+
778
+ .widget-panel.voice-only-panel .session-option .session-title {
779
+ font-size: 10px !important;
780
+ font-weight: 600 !important;
781
+ text-transform: none !important;
782
+ margin-bottom: 4px !important;
783
+ letter-spacing: 0px !important;
784
+ text-align: center;
785
+ }
786
+
787
+ .widget-panel.voice-only-panel .session-option .session-desc {
788
+ font-size: 8px !important;
789
+ text-transform: none !important;
790
+ line-height: 1.1 !important;
791
+ letter-spacing: 0px !important;
792
+ }
793
+
794
+ /* Scale VoiceOverlay inside voice-only-panel */
795
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-content-container {
796
+ padding: 12px 8px 8px !important;
797
+ }
798
+
799
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-orb-wrapper {
800
+ transform: scale(0.5) !important;
801
+ margin: -40px 0 !important;
802
+ }
803
+
804
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-status-area {
805
+ margin-top: 0px !important;
806
+ gap: 4px !important;
807
+ }
808
+
809
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-status-area p {
810
+ font-size: 9px !important;
811
+ }
812
+
813
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-status-area > div {
814
+ padding: 3px 10px !important;
815
+ }
816
+
817
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-status-area span {
818
+ font-size: 9px !important;
819
+ }
820
+
821
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-transcription {
822
+ margin-top: 2px !important;
823
+ font-size: 10px !important;
824
+ min-height: 16px !important;
825
+ max-height: 36px !important;
826
+ padding: 0 10px !important;
827
+ line-height: 1.3 !important;
828
+ }
829
+
830
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-footer {
831
+ padding: 0 12px 12px !important;
832
+ }
833
+
834
+ .widget-panel.voice-only-panel #voice-active-overlay .voice-hangup-btn {
835
+ padding: 6px 16px !important;
836
+ font-size: 11px !important;
837
+ }
838
+ `;