@thisispamela/react 1.0.0 → 1.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.
package/dist/index.js CHANGED
@@ -30,15 +30,15 @@ function styleInject(css, ref) {
30
30
  }
31
31
  }
32
32
 
33
- var css_248z = "/**\n * Pamela B2B React Component Library - Default Styles\n * \n * These styles match the Pamela B2C design system:\n * - Colors: Orange (#FA931C), Beige (#e7ab84), Blue (#4b4bea)\n * - Fonts: Poppins, Inter\n * - Dark mode support\n */\n\n/* Pulse animation for status indicators */\n@keyframes pamela-pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n\n/* Call Button - matches your gradient style */\n.pamela-call-button {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n background: linear-gradient(to right, #FA931C, #fd8b74);\n color: white;\n border: none;\n border-radius: 0.5rem;\n font-weight: 600;\n transition: opacity 0.2s;\n box-shadow: 0 2px 4px rgba(250, 147, 28, 0.2);\n}\n\n.pamela-call-button:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n.pamela-call-button:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n background: linear-gradient(to right, #ccc, #aaa);\n}\n\n/* Call Status - matches your card style */\n.pamela-call-status {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* Transcript Viewer - matches your message bubble style */\n.pamela-transcript-viewer {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .pamela-call-status {\n color: #ffffff;\n }\n \n .pamela-transcript-viewer {\n color: #ffffff;\n }\n}\n\n";
33
+ var css_248z = "/**\n * Pamela Enterprise React Component Library - Default Styles\n *\n * These styles align with the Pamela app design schema.\n * If the host app already defines these CSS variables, its values will win.\n */\n\n:root {\n --accent: #F27A1A;\n --accent-2: #F06C4F;\n --accent-3: #F3A84C;\n --accent-gradient: linear-gradient(90deg, var(--accent), var(--accent-2));\n --bg-gradient: linear-gradient(135deg, #F5F0E8 0%, #F3EEE8 45%, #EFE8DF 100%);\n --bg-glow: radial-gradient(1200px circle at 10% 20%, rgba(250, 147, 28, 0.1), transparent 58%),\n radial-gradient(900px circle at 80% 10%, rgba(253, 139, 116, 0.1), transparent 62%),\n radial-gradient(800px circle at 70% 80%, rgba(251, 193, 107, 0.08), transparent 60%);\n --surface: rgba(255, 255, 255, 0.5);\n --surface-strong: rgba(255, 255, 255, 0.78);\n --surface-border: rgba(231, 171, 132, 0.24);\n --surface-border-strong: rgba(255, 255, 255, 0.75);\n --surface-highlight: rgba(255, 255, 255, 0.68);\n --surface-liquid: linear-gradient(135deg, rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.38));\n --surface-liquid-strong: linear-gradient(140deg, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0.5));\n --liquid-highlight: linear-gradient(120deg, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0) 45%);\n --liquid-shadow: 0 18px 42px rgba(28, 25, 17, 0.14);\n --liquid-glow: 0 0 32px rgba(250, 147, 28, 0.2);\n --shadow-soft: 0 12px 26px rgba(28, 25, 17, 0.1);\n --shadow-hover: 0 24px 44px rgba(28, 25, 17, 0.18);\n --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.7);\n --cta-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.7), rgba(250, 147, 28, 0.32));\n --cta-border: 1px solid rgba(250, 147, 28, 0.4);\n --cta-glow: 0 0 18px rgba(250, 147, 28, 0.28);\n --cta-glow-hover: 0 0 22px rgba(250, 147, 28, 0.36);\n --danger-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.6), rgba(239, 68, 68, 0.3));\n --danger-border: 1px solid rgba(239, 68, 68, 0.45);\n --danger-glow: 0 0 16px rgba(239, 68, 68, 0.3);\n --danger-glow-hover: 0 0 20px rgba(239, 68, 68, 0.4);\n --badge-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.7), rgba(250, 147, 28, 0.28));\n --badge-border: 1px solid rgba(250, 147, 28, 0.4);\n --badge-glow: 0 0 14px rgba(250, 147, 28, 0.24);\n --avatar-bg: linear-gradient(135deg, rgba(255, 255, 255, 0.6), rgba(250, 147, 28, 0.38), rgba(253, 139, 116, 0.32));\n --avatar-border: 1px solid rgba(250, 147, 28, 0.35);\n --avatar-glow: 0 0 20px rgba(250, 147, 28, 0.28);\n --glass-blur: 24px;\n --glass-blur-strong: 32px;\n --noise-opacity: 0.05;\n --focus-ring: 0 0 0 3px rgba(250, 147, 28, 0.28);\n --radius-sm: 0.5rem;\n --radius-md: 0.75rem;\n --radius-lg: 1rem;\n --radius-xl: 1.5rem;\n --text-primary: #1C1917;\n --text-secondary: rgba(28, 25, 17, 0.78);\n --text-muted: rgba(28, 25, 17, 0.55);\n --status-success: #10b981;\n --status-warning: #eab308;\n --status-muted: #d1d5db;\n --status-error: #ef4444;\n --bubble-user: #FA931C;\n --bubble-pamela: #ffffff;\n --bubble-recipient: #4b4bea;\n --bubble-border: rgba(231, 171, 132, 0.3);\n}\n\n.dark {\n --bg-gradient: linear-gradient(135deg, #171513 0%, #14110f 45%, #0f0d0b 100%);\n --bg-glow: radial-gradient(1100px circle at 20% 10%, rgba(250, 147, 28, 0.18), transparent 60%),\n radial-gradient(900px circle at 80% 20%, rgba(253, 139, 116, 0.16), transparent 60%),\n radial-gradient(700px circle at 60% 80%, rgba(251, 193, 107, 0.12), transparent 55%);\n --surface: rgba(255, 255, 255, 0.08);\n --surface-strong: rgba(255, 255, 255, 0.16);\n --surface-border: rgba(255, 255, 255, 0.18);\n --surface-border-strong: rgba(255, 255, 255, 0.36);\n --surface-highlight: rgba(255, 255, 255, 0.2);\n --surface-liquid: linear-gradient(150deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.05));\n --surface-liquid-strong: linear-gradient(150deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.08));\n --liquid-highlight: linear-gradient(120deg, rgba(255, 255, 255, 0.24), rgba(255, 255, 255, 0) 45%);\n --liquid-shadow: 0 22px 48px rgba(0, 0, 0, 0.55);\n --liquid-glow: 0 0 30px rgba(250, 147, 28, 0.24);\n --shadow-soft: 0 16px 32px rgba(0, 0, 0, 0.5);\n --shadow-hover: 0 26px 44px rgba(0, 0, 0, 0.7);\n --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.12);\n --cta-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.22), rgba(250, 147, 28, 0.34));\n --cta-border: 1px solid rgba(250, 147, 28, 0.5);\n --cta-glow: 0 0 16px rgba(250, 147, 28, 0.26);\n --cta-glow-hover: 0 0 20px rgba(250, 147, 28, 0.32);\n --danger-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.18), rgba(239, 68, 68, 0.32));\n --danger-border: 1px solid rgba(248, 113, 113, 0.55);\n --danger-glow: 0 0 18px rgba(239, 68, 68, 0.32);\n --danger-glow-hover: 0 0 22px rgba(239, 68, 68, 0.4);\n --badge-bg: linear-gradient(120deg, rgba(255, 255, 255, 0.2), rgba(250, 147, 28, 0.32));\n --badge-border: 1px solid rgba(250, 147, 28, 0.5);\n --badge-glow: 0 0 14px rgba(250, 147, 28, 0.22);\n --avatar-bg: linear-gradient(135deg, rgba(255, 255, 255, 0.22), rgba(250, 147, 28, 0.26), rgba(253, 139, 116, 0.24));\n --avatar-border: 1px solid rgba(255, 255, 255, 0.18);\n --avatar-glow: 0 0 18px rgba(250, 147, 28, 0.22);\n --glass-blur: 24px;\n --glass-blur-strong: 32px;\n --noise-opacity: 0.08;\n --focus-ring: 0 0 0 3px rgba(250, 147, 28, 0.35);\n --text-primary: rgba(255, 255, 255, 0.95);\n --text-secondary: rgba(255, 255, 255, 0.72);\n --text-muted: rgba(255, 255, 255, 0.5);\n --bubble-pamela: rgba(255, 255, 255, 0.12);\n --bubble-border: rgba(255, 255, 255, 0.2);\n}\n\n/* Pulse animation for status indicators */\n@keyframes pamela-pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n\n/* VoiceOrb animations */\n@keyframes shimmer {\n 0% {\n transform: translateX(-100%) translateY(-100%) rotate(45deg);\n }\n 100% {\n transform: translateX(100%) translateY(100%) rotate(45deg);\n }\n}\n\n@keyframes ripple {\n 0% {\n transform: scale(1);\n opacity: 0.6;\n }\n 50% {\n transform: scale(2);\n opacity: 0;\n }\n 100% {\n transform: scale(1);\n opacity: 0.6;\n }\n}\n\n@keyframes float {\n 0%, 100% {\n transform: translateY(0px);\n }\n 50% {\n transform: translateY(-10px);\n }\n}\n\n/* Call Button - matches your gradient style */\n.pamela-call-button {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n background: var(--accent-gradient);\n color: var(--text-primary);\n border: var(--cta-border);\n border-radius: var(--radius-md);\n font-weight: 600;\n transition: opacity 0.2s;\n box-shadow: var(--shadow-soft), var(--cta-glow);\n padding: 10px 20px;\n font-size: 16px;\n cursor: pointer;\n}\n\n.pamela-call-button--primary {\n background: var(--accent-gradient);\n}\n\n.pamela-call-button--secondary {\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n box-shadow: var(--shadow-soft), var(--liquid-glow);\n}\n\n.pamela-call-button--danger {\n background: var(--danger-bg);\n border: var(--danger-border);\n color: #b91c1c;\n box-shadow: var(--shadow-soft), var(--danger-glow);\n}\n\n.pamela-call-button--sm {\n padding: 6px 12px;\n font-size: 14px;\n}\n\n.pamela-call-button--md {\n padding: 10px 20px;\n font-size: 16px;\n}\n\n.pamela-call-button--lg {\n padding: 12px 24px;\n font-size: 18px;\n}\n\n.pamela-call-button:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n.pamela-call-button:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n background: linear-gradient(to right, #cfcfcf, #b6b6b6);\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-shadow: none;\n}\n\n/* Call Status - matches your card style */\n.pamela-call-status {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* Transcript Viewer - matches your message bubble style */\n.pamela-transcript-viewer {\n font-family: 'Poppins', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n.pamela-card {\n background: var(--surface-liquid-strong);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-soft), var(--liquid-glow);\n}\n\n.pamela-panel {\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-xl);\n box-shadow: var(--liquid-shadow), var(--liquid-glow);\n}\n\n.pamela-chip {\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n border-radius: 999px;\n padding: 0.25rem 0.6rem;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--text-secondary);\n box-shadow: var(--shadow-inset);\n}\n\n.pamela-transcript-container {\n background: var(--surface);\n border-radius: var(--radius-md);\n padding: 16px;\n}\n\n.pamela-transcript-bubble {\n border-radius: var(--radius-md);\n padding: 12px 16px;\n}\n\n.pamela-transcript-bubble--pamela {\n background: var(--bubble-pamela);\n border: 1px solid var(--bubble-border);\n color: var(--text-primary);\n}\n\n.pamela-transcript-bubble--user {\n background: var(--bubble-user);\n color: #ffffff;\n}\n\n.pamela-transcript-bubble--recipient {\n background: var(--bubble-recipient);\n color: #ffffff;\n}\n\n/* Utility classes aligned with Pamela app design */\n.app-gradient {\n background: var(--bg-glow), var(--bg-gradient);\n}\n\n.surface-card {\n background: var(--surface-strong);\n border: 1px solid var(--surface-border);\n box-shadow: var(--shadow-soft);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n}\n\n.surface-card-hover {\n transition: box-shadow 180ms ease, transform 180ms ease;\n}\n\n.surface-card-hover:hover {\n box-shadow: var(--shadow-hover);\n}\n\n.accent-card {\n background: linear-gradient(90deg, rgba(250, 147, 28, 0.12), rgba(253, 139, 116, 0.12));\n border: 1px solid rgba(250, 147, 28, 0.3);\n box-shadow: var(--shadow-soft);\n}\n\n.dark .accent-card {\n background: linear-gradient(90deg, rgba(250, 147, 28, 0.22), rgba(253, 139, 116, 0.22));\n border-color: rgba(250, 147, 28, 0.35);\n}\n\n.send-button-idle {\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.78), rgba(255, 255, 255, 0.4));\n border: 1px solid rgba(231, 171, 132, 0.45);\n color: rgba(28, 25, 17, 0.5);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 0 14px rgba(250, 147, 28, 0.18);\n}\n\n.dark .send-button-idle {\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.04));\n border-color: rgba(255, 255, 255, 0.22);\n color: rgba(255, 255, 255, 0.6);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 0 16px rgba(250, 147, 28, 0.22);\n}\n\n.send-button-gradient {\n background: linear-gradient(120deg, rgba(250, 147, 28, 0.9), rgba(253, 139, 116, 0.9));\n border: 1px solid rgba(255, 255, 255, 0.45);\n box-shadow: 0 0 16px rgba(250, 147, 28, 0.32);\n}\n\n.send-button-gradient:hover,\n.send-button-gradient:focus-visible {\n box-shadow: 0 0 18px rgba(250, 147, 28, 0.36);\n}\n\n.transcript-bubble {\n box-shadow: 0 6px 14px rgba(15, 23, 42, 0.12), 0 0 10px rgba(250, 147, 28, 0.14);\n transition: box-shadow 180ms ease;\n}\n\n.transcript-bubble:hover,\n.transcript-bubble:focus-visible {\n box-shadow: 0 6px 14px rgba(15, 23, 42, 0.12), 0 0 10px rgba(250, 147, 28, 0.14);\n}\n\n.btn-primary {\n background: var(--cta-bg);\n border: var(--cta-border);\n color: var(--text-primary);\n font-weight: 600;\n border-radius: var(--radius-md);\n box-shadow: var(--shadow-soft), var(--cta-glow);\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n transition: transform 150ms ease, box-shadow 150ms ease, opacity 150ms ease;\n}\n\n.btn-primary:hover {\n box-shadow: var(--shadow-hover), var(--cta-glow-hover);\n opacity: 0.96;\n}\n\n.btn-primary:active {\n transform: scale(0.98);\n}\n\n.btn-danger {\n background: var(--danger-bg);\n border: var(--danger-border);\n color: #b91c1c;\n box-shadow: var(--shadow-soft), var(--danger-glow);\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n transition: box-shadow 180ms ease, transform 180ms ease, opacity 180ms ease;\n}\n\n.dark .btn-danger {\n color: #fca5a5;\n}\n\n.btn-danger:hover {\n box-shadow: var(--danger-glow-hover);\n}\n\n.badge-pill {\n background: var(--badge-bg);\n border: var(--badge-border);\n border-radius: 999px;\n padding: 0.25rem 0.6rem;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--text-secondary);\n box-shadow: var(--shadow-inset), var(--badge-glow);\n}\n\n.badge-accent {\n background: rgba(250, 147, 28, 0.15);\n color: rgba(250, 147, 28, 0.95);\n}\n\n.dark .badge-accent {\n background: rgba(250, 147, 28, 0.25);\n color: rgba(253, 139, 116, 0.95);\n}\n\n.h1 {\n font-size: 1.875rem;\n line-height: 2.25rem;\n font-weight: 700;\n}\n\n.h2 {\n font-size: 1.5rem;\n line-height: 2rem;\n font-weight: 600;\n}\n\n.h3 {\n font-size: 1.125rem;\n line-height: 1.75rem;\n font-weight: 600;\n}\n\n.body {\n font-size: 0.95rem;\n line-height: 1.5rem;\n}\n\n.meta {\n font-size: 0.75rem;\n line-height: 1.125rem;\n color: rgba(28, 25, 17, 0.6);\n}\n\n.dark .meta {\n color: rgba(255, 255, 255, 0.6);\n}\n\n.input-base {\n background: rgba(255, 255, 255, 0.86);\n border: 1px solid rgba(231, 171, 132, 0.28);\n border-radius: var(--radius-lg);\n padding: 0.75rem 1rem;\n color: #1C1917;\n transition: box-shadow 150ms ease, border-color 150ms ease;\n}\n\n.dark .input-base {\n background: rgba(255, 255, 255, 0.1);\n color: #ffffff;\n}\n\n.input-base:focus {\n outline: none;\n border-color: rgba(250, 147, 28, 0.6);\n box-shadow: var(--focus-ring);\n}\n\n.panel {\n position: relative;\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-xl);\n box-shadow: var(--liquid-shadow), var(--liquid-glow);\n backdrop-filter: blur(var(--glass-blur-strong));\n -webkit-backdrop-filter: blur(var(--glass-blur-strong));\n overflow: hidden;\n}\n\n.card {\n position: relative;\n background: var(--surface-liquid-strong);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-soft), var(--liquid-glow);\n backdrop-filter: blur(var(--glass-blur));\n -webkit-backdrop-filter: blur(var(--glass-blur));\n overflow: hidden;\n}\n\n.card-hover {\n transition: box-shadow 180ms ease, transform 180ms ease;\n}\n\n.card-hover:hover {\n box-shadow: var(--shadow-hover), var(--liquid-glow);\n transform: translateY(-2px);\n}\n\n.chip {\n background: var(--surface-liquid);\n border: 1px solid var(--surface-border-strong);\n border-radius: 999px;\n padding: 0.25rem 0.6rem;\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--text-secondary);\n box-shadow: var(--shadow-inset);\n}\n\n.input-field {\n position: relative;\n background: var(--surface-liquid-strong);\n border: 1px solid var(--surface-border-strong);\n border-radius: var(--radius-lg);\n padding: 0.75rem 1rem;\n color: var(--text-primary);\n box-shadow: var(--shadow-inset), var(--liquid-glow);\n transition: box-shadow 150ms ease, border-color 150ms ease, transform 150ms ease;\n}\n\n.input-field:focus {\n outline: none;\n border-color: rgba(250, 147, 28, 0.6);\n box-shadow: var(--focus-ring), var(--liquid-glow);\n transform: translateY(-1px);\n}\n\n.btn-secondary {\n border-radius: var(--radius-md);\n border: 1px solid var(--surface-border-strong);\n background: var(--surface-liquid);\n color: var(--text-primary);\n box-shadow: var(--shadow-soft), var(--liquid-glow);\n transition: transform 150ms ease, box-shadow 150ms ease, opacity 150ms ease;\n}\n\n.btn-secondary:hover {\n box-shadow: var(--shadow-hover), var(--liquid-glow);\n}\n\n.btn-secondary:active {\n transform: scale(0.98);\n}\n\n.tooltip-panel {\n background: var(--surface-liquid-strong);\n border: 1px solid var(--surface-border-strong);\n color: var(--text-primary);\n box-shadow: var(--shadow-soft), 0 12px 24px rgba(28, 25, 17, 0.16);\n backdrop-filter: blur(calc(var(--glass-blur) * 0.9));\n -webkit-backdrop-filter: blur(calc(var(--glass-blur) * 0.9));\n}\n\n.tooltip-arrow {\n background: var(--surface-liquid-strong);\n border: 1px solid var(--surface-border-strong);\n}\n\n::where(.panel, .card) {\n isolation: isolate;\n}\n\n::where(.panel, .card) > * {\n position: relative;\n z-index: 1;\n}\n\n::where(.panel, .card)::before {\n content: \"\";\n position: absolute;\n inset: 0;\n background: var(--liquid-highlight);\n opacity: 0.6;\n pointer-events: none;\n z-index: 0;\n}\n\n::where(.panel, .card)::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background-image: radial-gradient(rgba(255, 255, 255, 0.16) 0.5px, transparent 0.5px);\n background-size: 4px 4px;\n opacity: var(--noise-opacity);\n pointer-events: none;\n z-index: 0;\n}\n\n.avatar {\n background: var(--avatar-bg);\n border: var(--avatar-border);\n box-shadow: var(--shadow-soft), var(--avatar-glow);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n}\n\n.conversations-scroll::-webkit-scrollbar,\n.chat-scroll::-webkit-scrollbar {\n width: 6px;\n}\n\n.conversations-scroll::-webkit-scrollbar-track,\n.chat-scroll::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.conversations-scroll::-webkit-scrollbar-thumb,\n.chat-scroll::-webkit-scrollbar-thumb {\n background: rgba(230, 171, 132, 0.3);\n border-radius: 3px;\n}\n\n.conversations-scroll::-webkit-scrollbar-thumb:hover,\n.chat-scroll::-webkit-scrollbar-thumb:hover {\n background: rgba(230, 171, 132, 0.5);\n}\n\n.conversations-scroll,\n.chat-scroll {\n scrollbar-width: thin;\n scrollbar-color: rgba(230, 171, 132, 0.3) transparent;\n}\n\n.touch-manipulation {\n touch-action: manipulation;\n}\n\n/* Dark mode support */\n@media (prefers-color-scheme: dark) {\n .pamela-call-status {\n color: #ffffff;\n }\n \n .pamela-transcript-viewer {\n color: #ffffff;\n }\n}\n\n";
34
34
  styleInject(css_248z);
35
35
 
36
36
  const PamelaContext = React.createContext(null);
37
37
  function PamelaProvider({ config, children }) {
38
- const client = new sdk.PamelaClient({
38
+ const client = React.useMemo(() => new sdk.PamelaClient({
39
39
  apiKey: config.apiKey,
40
40
  baseUrl: config.baseUrl,
41
- });
41
+ }), [config.apiKey, config.baseUrl]);
42
42
  return (React.createElement(PamelaContext.Provider, { value: { client } }, children));
43
43
  }
44
44
  function usePamela() {
@@ -49,13 +49,37 @@ function usePamela() {
49
49
  return context;
50
50
  }
51
51
 
52
- function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, onCallStart, onCallComplete, onError, disabled = false, className = '', children, }) {
52
+ function CallButton({ to, task, country, locale, instructions, end_user_id, metadata, tools, webhooks, onCallStart, onCallComplete, onError, variant = 'primary', size = 'md', pollInterval = 2000, pollTimeout = 5 * 60 * 1000, disabled = false, className = '', children, }) {
53
53
  const { client } = usePamela();
54
54
  const [loading, setLoading] = React.useState(false);
55
55
  const [callId, setCallId] = React.useState(null);
56
+ const pollIntervalRef = React.useRef(null);
57
+ const timeoutRef = React.useRef(null);
58
+ // Cleanup on unmount
59
+ React.useEffect(() => {
60
+ return () => {
61
+ if (pollIntervalRef.current) {
62
+ clearInterval(pollIntervalRef.current);
63
+ pollIntervalRef.current = null;
64
+ }
65
+ if (timeoutRef.current) {
66
+ clearTimeout(timeoutRef.current);
67
+ timeoutRef.current = null;
68
+ }
69
+ };
70
+ }, []);
56
71
  const handleClick = async () => {
57
72
  if (loading || disabled)
58
73
  return;
74
+ // Clear any existing intervals/timeouts
75
+ if (pollIntervalRef.current) {
76
+ clearInterval(pollIntervalRef.current);
77
+ pollIntervalRef.current = null;
78
+ }
79
+ if (timeoutRef.current) {
80
+ clearTimeout(timeoutRef.current);
81
+ timeoutRef.current = null;
82
+ }
59
83
  setLoading(true);
60
84
  try {
61
85
  const call = await client.createCall({
@@ -66,78 +90,101 @@ function CallButton({ to, task, country, locale, instructions, end_user_id, meta
66
90
  instructions,
67
91
  end_user_id,
68
92
  metadata,
93
+ tools,
94
+ webhooks,
69
95
  });
70
96
  setCallId(call.id);
71
97
  onCallStart?.(call.id);
72
98
  // Poll for call completion
73
- const pollInterval = setInterval(async () => {
99
+ pollIntervalRef.current = setInterval(async () => {
74
100
  try {
75
101
  const status = await client.getCall(call.id);
76
102
  if (status.status === 'completed' || status.status === 'failed' || status.status === 'cancelled') {
77
- clearInterval(pollInterval);
103
+ if (pollIntervalRef.current) {
104
+ clearInterval(pollIntervalRef.current);
105
+ pollIntervalRef.current = null;
106
+ }
107
+ if (timeoutRef.current) {
108
+ clearTimeout(timeoutRef.current);
109
+ timeoutRef.current = null;
110
+ }
78
111
  setLoading(false);
79
112
  onCallComplete?.(status);
80
113
  }
81
114
  }
82
115
  catch (error) {
83
- clearInterval(pollInterval);
116
+ if (pollIntervalRef.current) {
117
+ clearInterval(pollIntervalRef.current);
118
+ pollIntervalRef.current = null;
119
+ }
120
+ if (timeoutRef.current) {
121
+ clearTimeout(timeoutRef.current);
122
+ timeoutRef.current = null;
123
+ }
84
124
  setLoading(false);
85
125
  onError?.(error);
86
126
  }
87
- }, 2000);
127
+ }, pollInterval);
88
128
  // Timeout after 5 minutes
89
- setTimeout(() => {
90
- clearInterval(pollInterval);
129
+ timeoutRef.current = setTimeout(() => {
130
+ if (pollIntervalRef.current) {
131
+ clearInterval(pollIntervalRef.current);
132
+ pollIntervalRef.current = null;
133
+ }
91
134
  setLoading(false);
92
- }, 5 * 60 * 1000);
135
+ }, pollTimeout);
93
136
  }
94
137
  catch (error) {
95
138
  setLoading(false);
96
139
  onError?.(error);
97
140
  }
98
141
  };
99
- return (React.createElement("button", { onClick: handleClick, disabled: loading || disabled, className: `pamela-call-button ${className}`, style: {
100
- padding: '10px 20px',
101
- background: loading
102
- ? 'linear-gradient(to right, #ccc, #aaa)'
103
- : 'linear-gradient(to right, #FA931C, #fd8b74)',
104
- color: 'white',
105
- border: 'none',
106
- borderRadius: '0.5rem',
107
- cursor: loading || disabled ? 'not-allowed' : 'pointer',
108
- fontSize: '16px',
109
- fontWeight: '600',
110
- fontFamily: 'Poppins, Inter, -apple-system, BlinkMacSystemFont, sans-serif',
111
- transition: 'opacity 0.2s',
112
- opacity: loading || disabled ? 0.7 : 1,
113
- boxShadow: loading || disabled ? 'none' : '0 2px 4px rgba(250, 147, 28, 0.2)',
114
- } }, loading ? 'Calling...' : children || 'Call Now'));
142
+ const variantClass = variant === 'secondary'
143
+ ? 'pamela-call-button--secondary'
144
+ : variant === 'danger'
145
+ ? 'pamela-call-button--danger'
146
+ : 'pamela-call-button--primary';
147
+ const sizeClass = size === 'sm'
148
+ ? 'pamela-call-button--sm'
149
+ : size === 'lg'
150
+ ? 'pamela-call-button--lg'
151
+ : 'pamela-call-button--md';
152
+ return (React.createElement("button", { onClick: handleClick, disabled: loading || disabled, className: `pamela-call-button ${variantClass} ${sizeClass} ${className}` }, loading ? 'Calling...' : children || 'Call Now'));
115
153
  }
116
154
 
117
- function TranscriptViewer({ transcript, className = '' }) {
155
+ function TranscriptViewer({ transcript, maxHeight = 400, autoScroll = true, className = '', }) {
156
+ const containerRef = React.useRef(null);
157
+ React.useEffect(() => {
158
+ if (!autoScroll || !containerRef.current)
159
+ return;
160
+ containerRef.current.scrollTop = containerRef.current.scrollHeight;
161
+ }, [autoScroll, transcript]);
118
162
  const getMessageStyle = (speaker) => {
119
163
  if (speaker === 'pamela' || speaker === 'agent') {
120
164
  // Pamela messages: white background with beige border
121
165
  return {
122
- backgroundColor: '#ffffff',
123
- border: '1px solid rgba(231, 171, 132, 0.3)',
124
- color: '#1f2937',
166
+ backgroundColor: 'var(--bubble-pamela, #ffffff)',
167
+ border: '1px solid var(--bubble-border, rgba(231, 171, 132, 0.3))',
168
+ color: 'var(--text-primary, #1f2937)',
169
+ className: 'pamela-transcript-bubble pamela-transcript-bubble--pamela',
125
170
  };
126
171
  }
127
172
  else if (speaker === 'user' || speaker === 'caller') {
128
173
  // User messages: orange background
129
174
  return {
130
- backgroundColor: '#FA931C',
175
+ backgroundColor: 'var(--bubble-user, #FA931C)',
131
176
  border: 'none',
132
177
  color: '#ffffff',
178
+ className: 'pamela-transcript-bubble pamela-transcript-bubble--user',
133
179
  };
134
180
  }
135
181
  else {
136
182
  // Call recipient: blue background
137
183
  return {
138
- backgroundColor: '#4b4bea',
184
+ backgroundColor: 'var(--bubble-recipient, #4b4bea)',
139
185
  border: 'none',
140
186
  color: '#ffffff',
187
+ className: 'pamela-transcript-bubble pamela-transcript-bubble--recipient',
141
188
  };
142
189
  }
143
190
  };
@@ -148,21 +195,21 @@ function TranscriptViewer({ transcript, className = '' }) {
148
195
  marginBottom: '16px',
149
196
  fontSize: '18px',
150
197
  fontWeight: '600',
151
- color: '#1f2937',
198
+ color: 'var(--text-primary, #1f2937)',
152
199
  } }, "Transcript"),
153
- React.createElement("div", { style: {
154
- maxHeight: '400px',
200
+ React.createElement("div", { className: "pamela-transcript-container", style: {
201
+ maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight,
155
202
  overflowY: 'auto',
156
- borderRadius: '0.5rem',
203
+ borderRadius: 'var(--radius-sm, 0.5rem)',
157
204
  padding: '16px',
158
- backgroundColor: '#F7F4ED',
159
- } }, transcript.map((entry, index) => {
205
+ background: 'var(--surface, #F7F4ED)',
206
+ }, ref: containerRef }, transcript.map((entry, index) => {
160
207
  const style = getMessageStyle(entry.speaker);
161
- return (React.createElement("div", { key: index, style: {
208
+ const { className: bubbleClassName, ...bubbleStyle } = style;
209
+ return (React.createElement("div", { key: index, className: bubbleClassName, style: {
162
210
  marginBottom: '12px',
163
- padding: '12px 16px',
164
- ...style,
165
- borderRadius: '0.75rem',
211
+ ...bubbleStyle,
212
+ borderRadius: 'var(--radius-md, 0.75rem)',
166
213
  maxWidth: '75%',
167
214
  marginLeft: entry.speaker === 'pamela' || entry.speaker === 'agent' ? '0' : 'auto',
168
215
  marginRight: entry.speaker === 'pamela' || entry.speaker === 'agent' ? 'auto' : '0',
@@ -170,7 +217,7 @@ function TranscriptViewer({ transcript, className = '' }) {
170
217
  React.createElement("div", { style: {
171
218
  fontSize: '12px',
172
219
  fontWeight: '600',
173
- color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.9)' : '#6b7280',
220
+ color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.9)' : 'var(--text-muted, #6b7280)',
174
221
  marginBottom: '6px',
175
222
  textTransform: 'capitalize',
176
223
  } }, entry.speaker === 'pamela' || entry.speaker === 'agent'
@@ -187,7 +234,7 @@ function TranscriptViewer({ transcript, className = '' }) {
187
234
  } }, entry.text),
188
235
  entry.timestamp && (React.createElement("div", { style: {
189
236
  fontSize: '11px',
190
- color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.7)' : '#9ca3af',
237
+ color: style.color === '#ffffff' ? 'rgba(255, 255, 255, 0.7)' : 'var(--text-muted, #9ca3af)',
191
238
  marginTop: '6px',
192
239
  } }, new Date(entry.timestamp).toLocaleTimeString()))));
193
240
  }))));
@@ -197,45 +244,63 @@ function TranscriptViewer({ transcript, className = '' }) {
197
244
  function StatusIndicator({ status }) {
198
245
  const getStatusConfig = () => {
199
246
  switch (status) {
247
+ case 'queued':
248
+ case 'initiating':
249
+ return {
250
+ dots: [
251
+ { color: 'var(--status-warning, #eab308)', pulse: true },
252
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
253
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
254
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
255
+ ],
256
+ text: 'Queued...',
257
+ textColor: 'var(--status-warning, #eab308)',
258
+ };
200
259
  case 'ringing':
201
260
  return {
202
261
  dots: [
203
- { color: '#10b981', pulse: true }, // green-500 (first dot)
204
- { color: '#eab308', pulse: true }, // yellow-500 (second dot)
205
- { color: '#d1d5db', pulse: false }, // gray-300 (third dot)
206
- { color: '#d1d5db', pulse: false }, // gray-300 (fourth dot)
262
+ { color: 'var(--status-success, #10b981)', pulse: true },
263
+ { color: 'var(--status-warning, #eab308)', pulse: true },
264
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
265
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
207
266
  ],
208
267
  text: 'Ringing...',
209
- textColor: '#eab308', // yellow-600
268
+ textColor: 'var(--status-warning, #eab308)',
210
269
  };
211
270
  case 'in_progress':
212
271
  case 'in-progress':
213
272
  return {
214
273
  dots: [
215
- { color: '#10b981', pulse: false }, // green-500
216
- { color: '#10b981', pulse: false },
217
- { color: '#10b981', pulse: true }, // third dot pulses
218
- { color: '#d1d5db', pulse: false }, // gray-300
274
+ { color: 'var(--status-success, #10b981)', pulse: false },
275
+ { color: 'var(--status-success, #10b981)', pulse: false },
276
+ { color: 'var(--status-success, #10b981)', pulse: true },
277
+ { color: 'var(--status-muted, #d1d5db)', pulse: false },
219
278
  ],
220
279
  text: 'In progress',
221
- textColor: '#10b981', // green-600
280
+ textColor: 'var(--status-success, #10b981)',
222
281
  };
223
282
  case 'completed':
224
283
  return {
225
284
  dots: [
226
- { color: '#10b981', pulse: false },
227
- { color: '#10b981', pulse: false },
228
- { color: '#10b981', pulse: false },
229
- { color: '#10b981', pulse: false, icon: true },
285
+ { color: 'var(--status-success, #10b981)', pulse: false },
286
+ { color: 'var(--status-success, #10b981)', pulse: false },
287
+ { color: 'var(--status-success, #10b981)', pulse: false },
288
+ { color: 'var(--status-success, #10b981)', pulse: false, icon: true },
230
289
  ],
231
290
  text: 'Completed',
232
- textColor: '#10b981',
291
+ textColor: 'var(--status-success, #10b981)',
233
292
  };
234
293
  case 'failed':
235
294
  return {
236
295
  dots: [],
237
296
  text: 'Failed',
238
- textColor: '#ef4444', // red-500
297
+ textColor: 'var(--status-error, #ef4444)',
298
+ };
299
+ case 'cancelled':
300
+ return {
301
+ dots: [],
302
+ text: 'Cancelled',
303
+ textColor: 'var(--status-error, #ef4444)',
239
304
  };
240
305
  default:
241
306
  return {
@@ -253,16 +318,17 @@ function StatusIndicator({ status }) {
253
318
  height: '8px',
254
319
  borderRadius: '50%',
255
320
  backgroundColor: dot.color,
256
- animation: dot.pulse ? 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite' : 'none',
321
+ animation: dot.pulse ? 'pamela-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite' : 'none',
257
322
  } }))))))),
258
323
  React.createElement("span", { style: {
259
324
  fontSize: '12px',
260
325
  fontWeight: '500',
261
326
  color: config.textColor,
327
+ fontStyle: 'italic',
262
328
  fontFamily: 'Poppins, Inter, sans-serif',
263
329
  } }, config.text)));
264
330
  }
265
- function CallStatus({ callId, pollInterval = 5000, onStatusChange, showTranscript = true, className = '', }) {
331
+ function CallStatus({ callId, pollInterval = 5000, onStatusChange, showTranscript = true, showSummary = true, compact = false, className = '', }) {
266
332
  const { client } = usePamela();
267
333
  const [status, setStatus] = React.useState(null);
268
334
  const [loading, setLoading] = React.useState(true);
@@ -288,74 +354,64 @@ function CallStatus({ callId, pollInterval = 5000, onStatusChange, showTranscrip
288
354
  }, [callId, pollInterval, client, onStatusChange]);
289
355
  if (loading) {
290
356
  return (React.createElement("div", { className: `pamela-call-status ${className}` },
291
- React.createElement("div", { style: { color: '#6b7280', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call status...")));
357
+ React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call status...")));
292
358
  }
293
359
  if (error) {
294
360
  return (React.createElement("div", { className: `pamela-call-status ${className}` },
295
- React.createElement("div", { style: { color: '#ef4444', fontFamily: 'Poppins, Inter, sans-serif' } },
361
+ React.createElement("div", { style: { color: 'var(--status-error, #ef4444)', fontFamily: 'Poppins, Inter, sans-serif' } },
296
362
  "Error: ",
297
363
  error.message)));
298
364
  }
299
365
  if (!status) {
300
366
  return (React.createElement("div", { className: `pamela-call-status ${className}` },
301
- React.createElement("div", { style: { color: '#6b7280', fontFamily: 'Poppins, Inter, sans-serif' } }, "Call not found")));
367
+ React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontFamily: 'Poppins, Inter, sans-serif' } }, "Call not found")));
302
368
  }
303
369
  return (React.createElement("div", { className: `pamela-call-status ${className}`, style: {
304
370
  fontFamily: 'Poppins, Inter, -apple-system, BlinkMacSystemFont, sans-serif',
305
371
  } },
306
372
  React.createElement("div", { style: {
307
- marginBottom: '16px',
308
- padding: '16px',
309
- backgroundColor: '#ffffff',
310
- borderRadius: '0.75rem',
311
- border: '1px solid rgba(231, 171, 132, 0.3)',
312
- boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1)',
373
+ marginBottom: compact ? '8px' : '16px',
374
+ padding: compact ? '12px' : '16px',
375
+ background: 'var(--surface-liquid-strong, #ffffff)',
376
+ borderRadius: 'var(--radius-md, 0.75rem)',
377
+ border: '1px solid var(--surface-border-strong, rgba(231, 171, 132, 0.3))',
378
+ boxShadow: 'var(--shadow-soft, 0 1px 3px rgba(0, 0, 0, 0.1))',
313
379
  } },
314
380
  React.createElement("div", { style: { marginBottom: '12px' } },
315
381
  React.createElement(StatusIndicator, { status: status.status })),
316
- React.createElement("div", { style: { fontSize: '14px', color: '#1f2937', lineHeight: '1.6' } },
317
- React.createElement("div", { style: { marginBottom: '8px' } },
318
- React.createElement("span", { style: { fontWeight: '600', color: '#6b7280' } }, "To:"),
382
+ React.createElement("div", { style: { fontSize: compact ? '12px' : '14px', color: 'var(--text-primary, #1f2937)', lineHeight: '1.6' } },
383
+ React.createElement("div", { style: { marginBottom: compact ? '6px' : '8px' } },
384
+ React.createElement("span", { style: { fontWeight: '600', color: 'var(--text-secondary, #6b7280)' } }, "To:"),
319
385
  ' ',
320
- React.createElement("span", { style: { color: '#1f2937' } }, status.to)),
321
- React.createElement("div", { style: { marginBottom: '8px' } },
322
- React.createElement("span", { style: { fontWeight: '600', color: '#6b7280' } }, "From:"),
386
+ React.createElement("span", { style: { color: 'var(--text-primary, #1f2937)' } }, status.to)),
387
+ React.createElement("div", { style: { marginBottom: compact ? '6px' : '8px' } },
388
+ React.createElement("span", { style: { fontWeight: '600', color: 'var(--text-secondary, #6b7280)' } }, "From:"),
323
389
  ' ',
324
- React.createElement("span", { style: { color: '#1f2937' } }, status.from_)),
325
- status.duration_seconds && (React.createElement("div", { style: { marginBottom: '8px' } },
326
- React.createElement("span", { style: { fontWeight: '600', color: '#6b7280' } }, "Duration:"),
390
+ React.createElement("span", { style: { color: 'var(--text-primary, #1f2937)' } }, status.from_)),
391
+ status.duration_seconds && !compact && (React.createElement("div", { style: { marginBottom: '8px' } },
392
+ React.createElement("span", { style: { fontWeight: '600', color: 'var(--text-secondary, #6b7280)' } }, "Duration:"),
327
393
  ' ',
328
- React.createElement("span", { style: { color: '#1f2937' } },
394
+ React.createElement("span", { style: { color: 'var(--text-primary, #1f2937)' } },
329
395
  status.duration_seconds,
330
396
  "s")))),
331
- status.summary && (React.createElement("div", { style: {
332
- marginTop: '16px',
333
- padding: '16px',
334
- background: 'linear-gradient(to right, rgba(250, 147, 28, 0.1), rgba(253, 139, 116, 0.1))',
335
- border: '1px solid rgba(250, 147, 28, 0.3)',
336
- borderRadius: '0.75rem',
397
+ showSummary && status.summary && (React.createElement("div", { style: {
398
+ marginTop: compact ? '12px' : '16px',
399
+ padding: compact ? '12px' : '16px',
400
+ background: 'var(--cta-bg, linear-gradient(to right, rgba(250, 147, 28, 0.1), rgba(253, 139, 116, 0.1)))',
401
+ border: 'var(--cta-border, 1px solid rgba(250, 147, 28, 0.3))',
402
+ borderRadius: 'var(--radius-md, 0.75rem)',
337
403
  } },
338
404
  React.createElement("div", { style: {
339
405
  display: 'flex',
340
406
  alignItems: 'center',
341
407
  gap: '8px',
342
- marginBottom: '8px',
408
+ marginBottom: compact ? '6px' : '8px',
343
409
  } },
344
- React.createElement("svg", { style: { width: '20px', height: '20px', color: '#FA931C' }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
410
+ React.createElement("svg", { style: { width: '20px', height: '20px', color: 'var(--accent, #FA931C)' }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
345
411
  React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" })),
346
- React.createElement("h4", { style: { fontWeight: '600', color: '#1f2937', fontSize: '14px' } }, "Call Summary")),
347
- React.createElement("p", { style: { fontSize: '14px', color: '#1f2937', lineHeight: '1.6' } }, status.summary)))),
348
- showTranscript && status.transcript && status.transcript.length > 0 && (React.createElement(TranscriptViewer, { transcript: status.transcript })),
349
- React.createElement("style", null, `
350
- @keyframes pulse {
351
- 0%, 100% {
352
- opacity: 1;
353
- }
354
- 50% {
355
- opacity: 0.5;
356
- }
357
- }
358
- `)));
412
+ React.createElement("h4", { style: { fontWeight: '600', color: 'var(--text-primary, #1f2937)', fontSize: compact ? '12px' : '14px' } }, "Call Summary")),
413
+ React.createElement("p", { style: { fontSize: compact ? '12px' : '14px', color: 'var(--text-primary, #1f2937)', lineHeight: '1.6' } }, status.summary)))),
414
+ showTranscript && status.transcript && status.transcript.length > 0 && (React.createElement(TranscriptViewer, { transcript: status.transcript }))));
359
415
  }
360
416
 
361
417
  function CallHistory({ limit = 10, onCallSelect, className = '', }) {
@@ -363,19 +419,37 @@ function CallHistory({ limit = 10, onCallSelect, className = '', }) {
363
419
  const [calls, setCalls] = React.useState([]);
364
420
  const [loading, setLoading] = React.useState(true);
365
421
  const [error, setError] = React.useState(null);
366
- // Note: This requires a list endpoint in the API
367
- // For now, this is a placeholder that shows the structure
368
422
  React.useEffect(() => {
369
- // TODO: Implement when /api/b2b/v1/calls list endpoint is available
370
- setLoading(false);
371
- }, [client]);
423
+ let isMounted = true;
424
+ const fetchCalls = async () => {
425
+ try {
426
+ const response = await client.listCalls({ limit });
427
+ if (!isMounted) {
428
+ return;
429
+ }
430
+ setCalls(response.items || []);
431
+ setLoading(false);
432
+ }
433
+ catch (err) {
434
+ if (!isMounted) {
435
+ return;
436
+ }
437
+ setError(err);
438
+ setLoading(false);
439
+ }
440
+ };
441
+ fetchCalls();
442
+ return () => {
443
+ isMounted = false;
444
+ };
445
+ }, [client, limit]);
372
446
  if (loading) {
373
447
  return (React.createElement("div", { className: `pamela-call-history ${className}` },
374
- React.createElement("div", { style: { color: '#6b7280', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call history...")));
448
+ React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontFamily: 'Poppins, Inter, sans-serif' } }, "Loading call history...")));
375
449
  }
376
450
  if (error) {
377
451
  return (React.createElement("div", { className: `pamela-call-history ${className}` },
378
- React.createElement("div", { style: { color: '#ef4444', fontFamily: 'Poppins, Inter, sans-serif' } },
452
+ React.createElement("div", { style: { color: 'var(--status-error, #ef4444)', fontFamily: 'Poppins, Inter, sans-serif' } },
379
453
  "Error: ",
380
454
  error.message)));
381
455
  }
@@ -386,39 +460,244 @@ function CallHistory({ limit = 10, onCallSelect, className = '', }) {
386
460
  marginBottom: '16px',
387
461
  fontSize: '18px',
388
462
  fontWeight: '600',
389
- color: '#1f2937',
463
+ color: 'var(--text-primary, #1f2937)',
390
464
  } }, "Call History"),
391
- calls.length === 0 ? (React.createElement("div", { style: { color: '#6b7280', fontSize: '14px' } }, "No calls yet")) : (React.createElement("div", null, calls.map((call) => (React.createElement("div", { key: call.id, onClick: () => onCallSelect?.(call.id), style: {
465
+ calls.length === 0 ? (React.createElement("div", { style: { color: 'var(--text-muted, #6b7280)', fontSize: '14px' } }, "No calls yet")) : (React.createElement("div", null, calls.map((call) => (React.createElement("div", { key: call.id, onClick: () => onCallSelect?.(call.id), style: {
392
466
  padding: '12px',
393
467
  marginBottom: '8px',
394
- border: '1px solid rgba(231, 171, 132, 0.3)',
395
- borderRadius: '0.5rem',
468
+ border: '1px solid var(--surface-border-strong, rgba(231, 171, 132, 0.3))',
469
+ borderRadius: 'var(--radius-sm, 0.5rem)',
396
470
  cursor: onCallSelect ? 'pointer' : 'default',
397
- backgroundColor: '#ffffff',
471
+ background: 'var(--surface-liquid-strong, #ffffff)',
398
472
  transition: 'background-color 0.2s',
399
473
  ...(onCallSelect && {
400
474
  ':hover': {
401
- backgroundColor: '#F7F4ED',
475
+ backgroundColor: 'var(--surface, #F7F4ED)',
402
476
  },
403
477
  }),
404
478
  }, onMouseEnter: (e) => {
405
479
  if (onCallSelect) {
406
- e.currentTarget.style.backgroundColor = '#F7F4ED';
480
+ e.currentTarget.style.backgroundColor = 'var(--surface, #F7F4ED)';
407
481
  }
408
482
  }, onMouseLeave: (e) => {
409
- e.currentTarget.style.backgroundColor = '#ffffff';
483
+ e.currentTarget.style.backgroundColor = 'var(--surface-liquid-strong, #ffffff)';
410
484
  } },
411
- React.createElement("div", { style: { fontWeight: '600', color: '#1f2937', marginBottom: '4px' } }, call.to),
412
- React.createElement("div", { style: { fontSize: '14px', color: '#6b7280' } },
485
+ React.createElement("div", { style: { fontWeight: '600', color: 'var(--text-primary, #1f2937)', marginBottom: '4px' } }, call.to),
486
+ React.createElement("div", { style: { fontSize: '14px', color: 'var(--text-secondary, #6b7280)' } },
413
487
  call.status,
414
488
  " \u2022 ",
415
489
  new Date(call.created_at).toLocaleString()))))))));
416
490
  }
417
491
 
492
+ const sizeMap = {
493
+ small: 'var(--pamela-orb-size-small, 96px)',
494
+ medium: 'var(--pamela-orb-size-medium, 128px)',
495
+ large: 'var(--pamela-orb-size-large, 192px)',
496
+ };
497
+ function VoiceOrb({ isActive = false, size = 'large', className = '' }) {
498
+ const [pulsePhase, setPulsePhase] = React.useState(0);
499
+ const [idlePhase, setIdlePhase] = React.useState(Math.floor(Math.random() * 720)); // Random initial phase to avoid sync
500
+ // Continuous animation for idle mode - runs once on mount
501
+ // Remove modulo to allow continuous rotation (can go beyond 360 degrees for seamless loop)
502
+ React.useEffect(() => {
503
+ const interval = setInterval(() => {
504
+ setIdlePhase(prev => prev + 1); // Continuous growth - no reset for fluid animation
505
+ }, 16); // ~60fps
506
+ return () => clearInterval(interval);
507
+ }, []); // Empty deps - only run once
508
+ // Fast animation for active mode
509
+ React.useEffect(() => {
510
+ if (!isActive)
511
+ return;
512
+ const interval = setInterval(() => {
513
+ setPulsePhase(prev => (prev + 1) % 360);
514
+ }, 16); // ~60fps
515
+ return () => clearInterval(interval);
516
+ }, [isActive]);
517
+ const orbSize = sizeMap[size];
518
+ // Multiple breathing layers for idle mode (more organic) - reduced by 10%
519
+ const baseTime = idlePhase * 0.05;
520
+ const idleBreath1 = Math.sin(baseTime) * 0.072; // 7.2% primary breath (was 8%)
521
+ const idleBreath2 = Math.sin(baseTime * 1.3) * 0.045; // 4.5% secondary breath (was 5%)
522
+ const idleBreath3 = Math.sin(baseTime * 0.7) * 0.027; // 2.7% tertiary breath (was 3%)
523
+ // Calculate pulse scale - multi-layer breathing when idle, faster pulse when active - reduced by 10%
524
+ const pulseScale = isActive
525
+ ? 1 + Math.sin((pulsePhase * Math.PI) / 180) * 0.135 // 13.5% pulse variation (was 15%)
526
+ : 1 + idleBreath1 + idleBreath2 + idleBreath3; // Layered breathing when idle
527
+ // Floating/levitation effect (idle only) - reduced by 10%
528
+ const floatY = isActive ? 0 : Math.sin(baseTime * 0.4) * 7.2; // 7.2px float movement (was 8px)
529
+ // Continuous gradient rotation - slower when idle, faster when active
530
+ const gradientRotation = isActive
531
+ ? pulsePhase * 0.5
532
+ : idlePhase * 0.15; // Slow, continuous rotation when idle
533
+ // Subtle color shift for idle mode - reduced by 10%
534
+ const colorShift = isActive ? 0 : Math.sin(baseTime * 0.3) * 9; // 9deg color shift (was 10deg)
535
+ const orbSizeStyle = {
536
+ width: orbSize,
537
+ height: orbSize,
538
+ };
539
+ return (React.createElement("div", { className: className, style: {
540
+ position: 'relative',
541
+ display: 'flex',
542
+ alignItems: 'center',
543
+ justifyContent: 'center',
544
+ transform: `translateY(${floatY}px)`,
545
+ transition: isActive ? 'transform 0.3s ease-out' : 'none',
546
+ } },
547
+ React.createElement("div", { style: {
548
+ ...orbSizeStyle,
549
+ position: 'absolute',
550
+ borderRadius: '50%',
551
+ filter: 'blur(24px)', // blur-xl
552
+ background: `radial-gradient(circle,
553
+ hsla(${25 + colorShift}, 75%, 55%, 0.54),
554
+ hsla(${11 + colorShift}, 97%, 72%, 0.54))`,
555
+ transform: `scale(${pulseScale * 1.125})`,
556
+ opacity: isActive ? 0.315 : 0.225,
557
+ transition: 'opacity 0.3s ease-out',
558
+ } }),
559
+ React.createElement("div", { style: {
560
+ ...orbSizeStyle,
561
+ position: 'absolute',
562
+ borderRadius: '50%',
563
+ filter: 'blur(16px)', // blur-lg
564
+ background: `radial-gradient(circle,
565
+ hsla(${25 + colorShift * 0.7}, 75%, 55%, 0.45),
566
+ hsla(${11 + colorShift * 0.7}, 97%, 72%, 0.45))`,
567
+ transform: `scale(${pulseScale * 1.035}) rotate(${gradientRotation * 0.3}deg)`,
568
+ opacity: isActive ? 0.405 : 0.315,
569
+ transition: 'opacity 0.3s ease-out',
570
+ } }),
571
+ !isActive && (React.createElement("div", { style: {
572
+ ...orbSizeStyle,
573
+ position: 'absolute',
574
+ borderRadius: '50%',
575
+ filter: 'blur(40px)', // blur-2xl
576
+ background: `radial-gradient(circle,
577
+ hsla(${25 + colorShift * 0.5}, 70%, 50%, 0.27),
578
+ hsla(${11 + colorShift * 0.5}, 97%, 72%, 0.27))`,
579
+ transform: `scale(${(1 + idleBreath1) * 1.26})`,
580
+ opacity: 0.18,
581
+ } })),
582
+ React.createElement("div", { style: {
583
+ ...orbSizeStyle,
584
+ position: 'relative',
585
+ borderRadius: '50%',
586
+ background: `linear-gradient(${gradientRotation + colorShift}deg,
587
+ hsl(${25 + colorShift}, 75%, 55%),
588
+ hsl(${11 + colorShift}, 97%, 72%),
589
+ hsl(${25 + colorShift}, 75%, 55%))`,
590
+ backgroundSize: '200% 200%',
591
+ transform: `scale(${pulseScale}) rotate(${gradientRotation * 0.1}deg)`,
592
+ boxShadow: isActive
593
+ ? '0 0 54px rgba(250,147,28,0.45), 0 0 90px rgba(253,139,116,0.27), inset 0 0 36px rgba(255,255,255,0.09)'
594
+ : `0 0 72px hsla(${25 + colorShift}, 60%, 50%, 0.36),
595
+ 0 0 108px hsla(${11 + colorShift}, 97%, 72%, 0.225),
596
+ inset 0 0 45px rgba(255,255,255,0.135)`,
597
+ transition: 'box-shadow 0.3s ease-out',
598
+ } },
599
+ React.createElement("div", { style: {
600
+ position: 'absolute',
601
+ inset: 0,
602
+ borderRadius: '50%',
603
+ background: `radial-gradient(circle at ${30 + Math.sin(baseTime * 0.2) * 5}% ${30 + Math.cos(baseTime * 0.2) * 5}%,
604
+ rgba(255,255,255,${isActive ? 0.36 : 0.315}), transparent 60%)`,
605
+ opacity: isActive ? 0.54 : 0.63,
606
+ transition: 'opacity 0.3s ease-out',
607
+ } }),
608
+ React.createElement("div", { style: {
609
+ position: 'absolute',
610
+ inset: 0,
611
+ borderRadius: '50%',
612
+ background: `linear-gradient(${45 + gradientRotation * 0.2}deg,
613
+ transparent 30%,
614
+ rgba(255,255,255,${isActive ? 0.45 : 0.225}) 50%,
615
+ transparent 70%)`,
616
+ animation: isActive ? 'shimmer 3s infinite' : 'shimmer 6s infinite',
617
+ opacity: isActive ? 0.27 : 0.18,
618
+ transition: 'opacity 0.3s ease-out',
619
+ } }),
620
+ !isActive && (React.createElement(React.Fragment, null,
621
+ React.createElement("div", { style: {
622
+ position: 'absolute',
623
+ borderRadius: '50%',
624
+ backgroundColor: 'white',
625
+ width: '8px',
626
+ height: '8px',
627
+ top: `${25 + Math.sin(baseTime * 0.5) * 15}%`,
628
+ left: `${35 + Math.cos(baseTime * 0.5) * 15}%`,
629
+ opacity: 0.36 + Math.sin(baseTime * 0.8) * 0.18,
630
+ filter: 'blur(2px)',
631
+ transform: `scale(${0.8 + Math.sin(baseTime * 1.2) * 0.36})`,
632
+ } }),
633
+ React.createElement("div", { style: {
634
+ position: 'absolute',
635
+ borderRadius: '50%',
636
+ backgroundColor: 'white',
637
+ width: '6px',
638
+ height: '6px',
639
+ top: `${60 + Math.sin(baseTime * 0.7 + 2) * 12}%`,
640
+ left: `${65 + Math.cos(baseTime * 0.7 + 2) * 12}%`,
641
+ opacity: 0.27 + Math.sin(baseTime * 0.9) * 0.135,
642
+ filter: 'blur(1.5px)',
643
+ transform: `scale(${0.7 + Math.sin(baseTime * 1.4) * 0.27})`,
644
+ } })))),
645
+ isActive && (React.createElement(React.Fragment, null,
646
+ React.createElement("div", { style: {
647
+ ...orbSizeStyle,
648
+ position: 'absolute',
649
+ borderRadius: '50%',
650
+ border: '2px solid #FA931C',
651
+ opacity: 0,
652
+ animation: 'ripple 2s infinite ease-in-out',
653
+ animationDelay: '0s',
654
+ } }),
655
+ React.createElement("div", { style: {
656
+ ...orbSizeStyle,
657
+ position: 'absolute',
658
+ borderRadius: '50%',
659
+ border: '2px solid #fd8b74',
660
+ opacity: 0,
661
+ animation: 'ripple 2s infinite ease-in-out',
662
+ animationDelay: '0.7s',
663
+ } }),
664
+ React.createElement("div", { style: {
665
+ ...orbSizeStyle,
666
+ position: 'absolute',
667
+ borderRadius: '50%',
668
+ border: '2px solid #FA931C',
669
+ opacity: 0,
670
+ animation: 'ripple 2s infinite ease-in-out',
671
+ animationDelay: '1.4s',
672
+ } }))),
673
+ !isActive && (React.createElement(React.Fragment, null,
674
+ React.createElement("div", { style: {
675
+ ...orbSizeStyle,
676
+ position: 'absolute',
677
+ borderRadius: '50%',
678
+ border: '1px solid #FA931C',
679
+ opacity: 0.135 + Math.sin(baseTime * 0.25) * 0.045,
680
+ transform: `scale(${1 + Math.sin(baseTime * 0.25) * 0.27})`,
681
+ animation: 'ripple 8s infinite ease-in-out',
682
+ animationDelay: '0s',
683
+ } }),
684
+ React.createElement("div", { style: {
685
+ ...orbSizeStyle,
686
+ position: 'absolute',
687
+ borderRadius: '50%',
688
+ border: '1px solid #fd8b74',
689
+ opacity: 0.09 + Math.sin(baseTime * 0.25 + 3) * 0.027,
690
+ transform: `scale(${1 + Math.sin(baseTime * 0.25 + 3) * 0.225})`,
691
+ animation: 'ripple 8s infinite ease-in-out',
692
+ animationDelay: '2.5s',
693
+ } })))));
694
+ }
695
+
418
696
  exports.CallButton = CallButton;
419
697
  exports.CallHistory = CallHistory;
420
698
  exports.CallStatus = CallStatus;
421
699
  exports.PamelaProvider = PamelaProvider;
422
700
  exports.TranscriptViewer = TranscriptViewer;
701
+ exports.VoiceOrb = VoiceOrb;
423
702
  exports.usePamela = usePamela;
424
703
  //# sourceMappingURL=index.js.map