@arcai/chatbot 1.0.0-beta.1
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/LICENSE +21 -0
- package/README.md +128 -0
- package/dist/chatbot.min.js +455 -0
- package/dist/icons.d.ts +3 -0
- package/dist/icons.js +19 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +214 -0
- package/dist/styles.d.ts +1 -0
- package/dist/styles.js +434 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +1 -0
- package/package.json +48 -0
package/dist/index.js
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
2
|
+
import { defaultStyles } from './styles';
|
3
|
+
import { botIcon, sendIcon, closeIcon } from './icons';
|
4
|
+
export class Chatbot extends EventEmitter {
|
5
|
+
constructor(config) {
|
6
|
+
super();
|
7
|
+
this.messages = [];
|
8
|
+
this.isOpen = false;
|
9
|
+
this.config = {
|
10
|
+
...config,
|
11
|
+
position: config.position || 'bottom-right',
|
12
|
+
primaryColor: config.primaryColor || '#2563eb',
|
13
|
+
textColor: config.textColor || '#1e293b',
|
14
|
+
bgImage: config.bgImage || '',
|
15
|
+
opacity: config.opacity || 100,
|
16
|
+
glassmorphism: config.glassmorphism || false,
|
17
|
+
floatAnimation: config.floatAnimation || 'float-up-down',
|
18
|
+
showAvatar: config.showAvatar ?? true,
|
19
|
+
showThoughts: config.showThoughts ?? true,
|
20
|
+
thoughtInterval: config.thoughtInterval || 8,
|
21
|
+
customThoughts: config.customThoughts || [
|
22
|
+
"I'm here to help!",
|
23
|
+
"Have any questions?",
|
24
|
+
"Need assistance?",
|
25
|
+
],
|
26
|
+
onMessage: config.onMessage || this.defaultMessageHandler,
|
27
|
+
};
|
28
|
+
this.injectStyles();
|
29
|
+
this.container = this.createContainer();
|
30
|
+
this.chat = this.createChat();
|
31
|
+
document.body.appendChild(this.container);
|
32
|
+
if (this.config.showThoughts) {
|
33
|
+
this.startThoughtCycle();
|
34
|
+
}
|
35
|
+
}
|
36
|
+
injectStyles() {
|
37
|
+
const style = document.createElement('style');
|
38
|
+
style.textContent = defaultStyles;
|
39
|
+
document.head.appendChild(style);
|
40
|
+
// Inject custom CSS variables
|
41
|
+
const customStyles = document.createElement('style');
|
42
|
+
customStyles.textContent = `
|
43
|
+
:root {
|
44
|
+
--arcai-primary-color: ${this.config.primaryColor};
|
45
|
+
--arcai-primary-color-dark: ${this.adjustColor(this.config.primaryColor, -20)};
|
46
|
+
}
|
47
|
+
`;
|
48
|
+
document.head.appendChild(customStyles);
|
49
|
+
}
|
50
|
+
createContainer() {
|
51
|
+
const container = document.createElement('div');
|
52
|
+
container.className = `arcai-widget ${this.config.position}`;
|
53
|
+
const launcher = document.createElement('button');
|
54
|
+
launcher.className = `arcai-launcher ${this.config.floatAnimation}`;
|
55
|
+
launcher.innerHTML = botIcon;
|
56
|
+
launcher.onclick = () => this.toggle();
|
57
|
+
container.appendChild(launcher);
|
58
|
+
return container;
|
59
|
+
}
|
60
|
+
createChat() {
|
61
|
+
const chat = document.createElement('div');
|
62
|
+
chat.className = 'arcai-chat';
|
63
|
+
// Header
|
64
|
+
const header = document.createElement('div');
|
65
|
+
header.className = `arcai-header ${this.config.glassmorphism ? 'glassmorphism' : ''}`;
|
66
|
+
if (this.config.bgImage) {
|
67
|
+
header.style.backgroundImage = `url(${this.config.bgImage})`;
|
68
|
+
header.style.backgroundSize = 'cover';
|
69
|
+
header.style.backgroundPosition = 'center';
|
70
|
+
header.style.backgroundColor = `rgba(37, 99, 235, ${this.config.opacity / 100})`;
|
71
|
+
}
|
72
|
+
const title = document.createElement('div');
|
73
|
+
title.className = 'arcai-title';
|
74
|
+
title.innerHTML = `${botIcon} <span>Chat Assistant</span>`;
|
75
|
+
const closeBtn = document.createElement('button');
|
76
|
+
closeBtn.className = 'arcai-close';
|
77
|
+
closeBtn.innerHTML = closeIcon;
|
78
|
+
closeBtn.onclick = () => this.close();
|
79
|
+
header.appendChild(title);
|
80
|
+
header.appendChild(closeBtn);
|
81
|
+
// Messages
|
82
|
+
const messages = document.createElement('div');
|
83
|
+
messages.className = 'arcai-messages';
|
84
|
+
// Input
|
85
|
+
const input = document.createElement('div');
|
86
|
+
input.className = 'arcai-input';
|
87
|
+
const form = document.createElement('form');
|
88
|
+
form.className = 'arcai-input-form';
|
89
|
+
form.onsubmit = (e) => {
|
90
|
+
e.preventDefault();
|
91
|
+
const inputField = form.querySelector('input');
|
92
|
+
if (inputField?.value.trim()) {
|
93
|
+
this.sendMessage(inputField.value);
|
94
|
+
inputField.value = '';
|
95
|
+
}
|
96
|
+
};
|
97
|
+
const inputField = document.createElement('input');
|
98
|
+
inputField.className = 'arcai-input-field';
|
99
|
+
inputField.placeholder = 'Type your message...';
|
100
|
+
const sendBtn = document.createElement('button');
|
101
|
+
sendBtn.className = 'arcai-send';
|
102
|
+
sendBtn.type = 'submit';
|
103
|
+
sendBtn.innerHTML = sendIcon;
|
104
|
+
form.appendChild(inputField);
|
105
|
+
form.appendChild(sendBtn);
|
106
|
+
input.appendChild(form);
|
107
|
+
chat.appendChild(header);
|
108
|
+
chat.appendChild(messages);
|
109
|
+
chat.appendChild(input);
|
110
|
+
this.container.appendChild(chat);
|
111
|
+
return chat;
|
112
|
+
}
|
113
|
+
async sendMessage(content) {
|
114
|
+
const message = {
|
115
|
+
id: Math.random().toString(36).substr(2, 9),
|
116
|
+
role: 'user',
|
117
|
+
content,
|
118
|
+
timestamp: new Date(),
|
119
|
+
};
|
120
|
+
this.messages.push(message);
|
121
|
+
this.renderMessage(message);
|
122
|
+
try {
|
123
|
+
const response = await this.config.onMessage(content);
|
124
|
+
const botMessage = {
|
125
|
+
id: Math.random().toString(36).substr(2, 9),
|
126
|
+
role: 'bot',
|
127
|
+
content: response,
|
128
|
+
timestamp: new Date(),
|
129
|
+
};
|
130
|
+
this.messages.push(botMessage);
|
131
|
+
this.renderMessage(botMessage);
|
132
|
+
}
|
133
|
+
catch (error) {
|
134
|
+
console.error('Error sending message:', error);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
renderMessage(message) {
|
138
|
+
const messagesContainer = this.chat.querySelector('.arcai-messages');
|
139
|
+
if (!messagesContainer)
|
140
|
+
return;
|
141
|
+
const messageEl = document.createElement('div');
|
142
|
+
messageEl.className = `arcai-message ${message.role}`;
|
143
|
+
if (this.config.showAvatar) {
|
144
|
+
const avatar = document.createElement('div');
|
145
|
+
avatar.className = 'arcai-avatar';
|
146
|
+
avatar.innerHTML = botIcon;
|
147
|
+
messageEl.appendChild(avatar);
|
148
|
+
}
|
149
|
+
const bubble = document.createElement('div');
|
150
|
+
bubble.className = 'arcai-bubble';
|
151
|
+
bubble.textContent = message.content;
|
152
|
+
messageEl.appendChild(bubble);
|
153
|
+
messagesContainer.appendChild(messageEl);
|
154
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
155
|
+
}
|
156
|
+
showThought() {
|
157
|
+
const thought = this.config.customThoughts[Math.floor(Math.random() * this.config.customThoughts.length)];
|
158
|
+
const thoughtEl = document.createElement('div');
|
159
|
+
thoughtEl.className = 'arcai-thought';
|
160
|
+
thoughtEl.textContent = thought;
|
161
|
+
const launcher = this.container.querySelector('.arcai-launcher');
|
162
|
+
if (launcher) {
|
163
|
+
launcher.appendChild(thoughtEl);
|
164
|
+
setTimeout(() => {
|
165
|
+
thoughtEl.remove();
|
166
|
+
}, 4000);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
startThoughtCycle() {
|
170
|
+
if (this.thoughtTimeout) {
|
171
|
+
clearTimeout(this.thoughtTimeout);
|
172
|
+
}
|
173
|
+
const showNextThought = () => {
|
174
|
+
if (!this.isOpen) {
|
175
|
+
this.showThought();
|
176
|
+
}
|
177
|
+
this.thoughtTimeout = setTimeout(showNextThought, this.config.thoughtInterval * 1000);
|
178
|
+
};
|
179
|
+
setTimeout(showNextThought, 2000);
|
180
|
+
}
|
181
|
+
adjustColor(color, amount) {
|
182
|
+
const hex = color.replace('#', '');
|
183
|
+
const num = parseInt(hex, 16);
|
184
|
+
const r = Math.min(255, Math.max(0, (num >> 16) + amount));
|
185
|
+
const g = Math.min(255, Math.max(0, ((num >> 8) & 0x00ff) + amount));
|
186
|
+
const b = Math.min(255, Math.max(0, (num & 0x0000ff) + amount));
|
187
|
+
return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0')}`;
|
188
|
+
}
|
189
|
+
async defaultMessageHandler(message) {
|
190
|
+
return `I received your message: "${message}". This is a default response. Please configure a custom message handler for more meaningful interactions.`;
|
191
|
+
}
|
192
|
+
open() {
|
193
|
+
this.isOpen = true;
|
194
|
+
this.chat.classList.add('open');
|
195
|
+
}
|
196
|
+
close() {
|
197
|
+
this.isOpen = false;
|
198
|
+
this.chat.classList.remove('open');
|
199
|
+
}
|
200
|
+
toggle() {
|
201
|
+
if (this.isOpen) {
|
202
|
+
this.close();
|
203
|
+
}
|
204
|
+
else {
|
205
|
+
this.open();
|
206
|
+
}
|
207
|
+
}
|
208
|
+
destroy() {
|
209
|
+
if (this.thoughtTimeout) {
|
210
|
+
clearTimeout(this.thoughtTimeout);
|
211
|
+
}
|
212
|
+
this.container.remove();
|
213
|
+
}
|
214
|
+
}
|
package/dist/styles.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export declare const defaultStyles = "\n/* Dark mode support */\n.arcai-widget[data-theme=\"dark\"] {\n --arcai-bg: #1a1a1a;\n --arcai-text: #ffffff;\n --arcai-border: #333333;\n}\n\n.arcai-widget[data-theme=\"light\"] {\n --arcai-bg: #ffffff;\n --arcai-text: #1a1a1a;\n --arcai-border: #e5e5e5;\n}\n\n.arcai-widget {\n position: fixed;\n z-index: 9999;\n transform: none;\n font-family: system-ui, -apple-system, sans-serif;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.arcai-widget.bottom-right {\n bottom: 20px;\n right: 20px;\n transform-origin: bottom right;\n}\n\n.arcai-widget.bottom-left {\n bottom: 20px;\n left: 20px;\n transform-origin: bottom left;\n}\n\n.arcai-widget.top-right {\n top: 20px;\n right: 20px;\n transform-origin: top right;\n}\n\n.arcai-widget.top-left {\n top: 20px;\n left: 20px;\n transform-origin: top left;\n}\n\n.arcai-widget.outside-left {\n left: -28px; /* Half of launcher width */\n top: 50%;\n transform: translateY(-50%);\n transform-origin: center left;\n}\n\n.arcai-widget.outside-left:hover {\n left: 20px;\n}\n\n.arcai-widget.outside-left .arcai-chat {\n left: 80px;\n bottom: auto;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.arcai-widget.outside-right {\n right: -28px;\n top: 50%;\n transform: translateY(-50%);\n transform-origin: center right;\n}\n\n.arcai-widget.outside-right:hover {\n right: 20px;\n}\n\n.arcai-widget.outside-right .arcai-chat {\n right: 80px;\n bottom: auto;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.arcai-launcher {\n width: 56px;\n height: 56px;\n border-radius: 50%;\n background: var(--arcai-primary-color, #2563eb);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s, box-shadow 0.2s;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n position: relative;\n z-index: 2;\n}\n\n.arcai-launcher:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);\n}\n\n.arcai-launcher.float-up-down {\n animation: arcaiFloatUpDown 3s ease-in-out infinite;\n}\n\n.arcai-launcher.float-left-right {\n animation: arcaiFloatLeftRight 3s ease-in-out infinite;\n}\n\n.arcai-launcher.float-diagonal {\n animation: arcaiFloatDiagonal 4s ease-in-out infinite;\n}\n\n.arcai-launcher.float-circle {\n animation: arcaiFloatCircle 5s ease-in-out infinite;\n}\n\n/* Sound effect animations */\n@keyframes arcaiSoundWave {\n 0% { transform: scale(1); opacity: 0.8; }\n 100% { transform: scale(2); opacity: 0; }\n}\n\n.arcai-sound-wave {\n position: absolute;\n border: 2px solid var(--arcai-primary-color);\n width: 100%;\n height: 100%;\n border-radius: 50%;\n animation: arcaiSoundWave 1s ease-out infinite;\n}\n\n/* Typing indicator */\n.arcai-typing {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px;\n background: var(--arcai-bg);\n border-radius: 12px;\n margin-bottom: 8px;\n}\n\n.arcai-typing-dot {\n width: 6px;\n height: 6px;\n background: var(--arcai-primary-color);\n border-radius: 50%;\n animation: arcaiDotPulse 1.4s infinite;\n}\n\n.arcai-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n.arcai-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n\n@keyframes arcaiDotPulse {\n 0%, 60%, 100% { transform: scale(1); opacity: 1; }\n 30% { transform: scale(1.2); opacity: 0.4; }\n}\n\n/* Suggested messages */\n.arcai-suggestions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 12px;\n}\n\n.arcai-suggestion {\n padding: 6px 12px;\n background: var(--arcai-primary-color);\n color: white;\n border-radius: 16px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s;\n border: none;\n}\n\n.arcai-suggestion:hover {\n transform: translateY(-1px);\n filter: brightness(1.1);\n}\n\n/* Attachment handling */\n.arcai-attachments {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 8px;\n}\n\n.arcai-attachment {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n background: var(--arcai-bg);\n border-radius: 4px;\n font-size: 12px;\n}\n\n.arcai-attachment-remove {\n cursor: pointer;\n opacity: 0.6;\n transition: opacity 0.2s;\n}\n\n.arcai-attachment-remove:hover {\n opacity: 1;\n}\n\n.arcai-chat {\n position: fixed;\n width: 380px;\n height: 600px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n opacity: 0;\n transform: translateY(20px);\n transition: opacity 0.3s, transform 0.3s;\n z-index: 1;\n}\n\n.arcai-chat.open {\n opacity: 1;\n transform: translateY(0);\n}\n\n.arcai-header {\n padding: 16px;\n background: var(--arcai-primary-color, #2563eb);\n color: white;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n.arcai-header.glassmorphism {\n backdrop-filter: blur(8px);\n background: rgba(37, 99, 235, 0.8);\n}\n\n.arcai-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 500;\n}\n\n.arcai-close {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 4px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.arcai-close:hover {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.arcai-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: #f8fafc;\n}\n\n.arcai-message {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-bottom: 16px;\n opacity: 0;\n transform: translateY(10px);\n animation: arcaiMessageSlideUp 0.3s forwards;\n}\n\n.arcai-message.user {\n flex-direction: row-reverse;\n}\n\n.arcai-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #e2e8f0;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.arcai-bubble {\n background: white;\n padding: 12px 16px;\n border-radius: 12px;\n max-width: 70%;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n}\n\n.arcai-message.user .arcai-bubble {\n background: var(--arcai-primary-color, #2563eb);\n color: white;\n}\n\n.arcai-input {\n padding: 16px;\n background: white;\n border-top: 1px solid #e2e8f0;\n}\n\n.arcai-input-form {\n display: flex;\n gap: 8px;\n}\n\n.arcai-input-field {\n flex: 1;\n padding: 8px 16px;\n border: 1px solid #e2e8f0;\n border-radius: 24px;\n outline: none;\n font-size: 14px;\n}\n\n.arcai-input-field:focus {\n border-color: var(--arcai-primary-color, #2563eb);\n box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);\n}\n\n.arcai-send {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--arcai-primary-color, #2563eb);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n}\n\n.arcai-send:hover {\n background: var(--arcai-primary-color-dark, #1d4ed8);\n}\n\n.arcai-thought {\n position: absolute;\n bottom: 100%;\n right: 0;\n margin-bottom: 12px;\n background: white;\n padding: 12px 16px;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n max-width: 240px;\n opacity: 0;\n transform: translateY(10px);\n animation: arcaiThoughtBubble 4s ease-in-out forwards;\n}\n\n.arcai-thought::after {\n content: '';\n position: absolute;\n bottom: -6px;\n right: 24px;\n width: 12px;\n height: 12px;\n background: white;\n transform: rotate(45deg);\n}\n\n@keyframes arcaiFloatUpDown {\n 0%, 100% { transform: translateY(0); }\n 50% { transform: translateY(-10px); }\n}\n\n@keyframes arcaiFloatLeftRight {\n 0%, 100% { transform: translateX(0); }\n 50% { transform: translateX(10px); }\n}\n\n@keyframes arcaiFloatDiagonal {\n 0%, 100% { transform: translate(0, 0); }\n 50% { transform: translate(5px, -5px); }\n}\n\n@keyframes arcaiFloatCircle {\n 0% { transform: translate(0, 0); }\n 25% { transform: translate(5px, -5px); }\n 50% { transform: translate(10px, 0); }\n 75% { transform: translate(5px, 5px); }\n 100% { transform: translate(0, 0); }\n}\n\n@keyframes arcaiMessageSlideUp {\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes arcaiThoughtBubble {\n 0% {\n opacity: 0;\n transform: scale(0.8) translateY(10px);\n }\n 10% {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n 90% {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n 100% {\n opacity: 0;\n transform: scale(0.8) translateY(-10px);\n }\n}";
|
package/dist/styles.js
ADDED
@@ -0,0 +1,434 @@
|
|
1
|
+
export const defaultStyles = `
|
2
|
+
/* Dark mode support */
|
3
|
+
.arcai-widget[data-theme="dark"] {
|
4
|
+
--arcai-bg: #1a1a1a;
|
5
|
+
--arcai-text: #ffffff;
|
6
|
+
--arcai-border: #333333;
|
7
|
+
}
|
8
|
+
|
9
|
+
.arcai-widget[data-theme="light"] {
|
10
|
+
--arcai-bg: #ffffff;
|
11
|
+
--arcai-text: #1a1a1a;
|
12
|
+
--arcai-border: #e5e5e5;
|
13
|
+
}
|
14
|
+
|
15
|
+
.arcai-widget {
|
16
|
+
position: fixed;
|
17
|
+
z-index: 9999;
|
18
|
+
transform: none;
|
19
|
+
font-family: system-ui, -apple-system, sans-serif;
|
20
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
21
|
+
}
|
22
|
+
|
23
|
+
.arcai-widget.bottom-right {
|
24
|
+
bottom: 20px;
|
25
|
+
right: 20px;
|
26
|
+
transform-origin: bottom right;
|
27
|
+
}
|
28
|
+
|
29
|
+
.arcai-widget.bottom-left {
|
30
|
+
bottom: 20px;
|
31
|
+
left: 20px;
|
32
|
+
transform-origin: bottom left;
|
33
|
+
}
|
34
|
+
|
35
|
+
.arcai-widget.top-right {
|
36
|
+
top: 20px;
|
37
|
+
right: 20px;
|
38
|
+
transform-origin: top right;
|
39
|
+
}
|
40
|
+
|
41
|
+
.arcai-widget.top-left {
|
42
|
+
top: 20px;
|
43
|
+
left: 20px;
|
44
|
+
transform-origin: top left;
|
45
|
+
}
|
46
|
+
|
47
|
+
.arcai-widget.outside-left {
|
48
|
+
left: -28px; /* Half of launcher width */
|
49
|
+
top: 50%;
|
50
|
+
transform: translateY(-50%);
|
51
|
+
transform-origin: center left;
|
52
|
+
}
|
53
|
+
|
54
|
+
.arcai-widget.outside-left:hover {
|
55
|
+
left: 20px;
|
56
|
+
}
|
57
|
+
|
58
|
+
.arcai-widget.outside-left .arcai-chat {
|
59
|
+
left: 80px;
|
60
|
+
bottom: auto;
|
61
|
+
top: 50%;
|
62
|
+
transform: translateY(-50%);
|
63
|
+
}
|
64
|
+
|
65
|
+
.arcai-widget.outside-right {
|
66
|
+
right: -28px;
|
67
|
+
top: 50%;
|
68
|
+
transform: translateY(-50%);
|
69
|
+
transform-origin: center right;
|
70
|
+
}
|
71
|
+
|
72
|
+
.arcai-widget.outside-right:hover {
|
73
|
+
right: 20px;
|
74
|
+
}
|
75
|
+
|
76
|
+
.arcai-widget.outside-right .arcai-chat {
|
77
|
+
right: 80px;
|
78
|
+
bottom: auto;
|
79
|
+
top: 50%;
|
80
|
+
transform: translateY(-50%);
|
81
|
+
}
|
82
|
+
|
83
|
+
.arcai-launcher {
|
84
|
+
width: 56px;
|
85
|
+
height: 56px;
|
86
|
+
border-radius: 50%;
|
87
|
+
background: var(--arcai-primary-color, #2563eb);
|
88
|
+
color: white;
|
89
|
+
border: none;
|
90
|
+
cursor: pointer;
|
91
|
+
display: flex;
|
92
|
+
align-items: center;
|
93
|
+
justify-content: center;
|
94
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
95
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
96
|
+
position: relative;
|
97
|
+
z-index: 2;
|
98
|
+
}
|
99
|
+
|
100
|
+
.arcai-launcher:hover {
|
101
|
+
transform: translateY(-2px);
|
102
|
+
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
|
103
|
+
}
|
104
|
+
|
105
|
+
.arcai-launcher.float-up-down {
|
106
|
+
animation: arcaiFloatUpDown 3s ease-in-out infinite;
|
107
|
+
}
|
108
|
+
|
109
|
+
.arcai-launcher.float-left-right {
|
110
|
+
animation: arcaiFloatLeftRight 3s ease-in-out infinite;
|
111
|
+
}
|
112
|
+
|
113
|
+
.arcai-launcher.float-diagonal {
|
114
|
+
animation: arcaiFloatDiagonal 4s ease-in-out infinite;
|
115
|
+
}
|
116
|
+
|
117
|
+
.arcai-launcher.float-circle {
|
118
|
+
animation: arcaiFloatCircle 5s ease-in-out infinite;
|
119
|
+
}
|
120
|
+
|
121
|
+
/* Sound effect animations */
|
122
|
+
@keyframes arcaiSoundWave {
|
123
|
+
0% { transform: scale(1); opacity: 0.8; }
|
124
|
+
100% { transform: scale(2); opacity: 0; }
|
125
|
+
}
|
126
|
+
|
127
|
+
.arcai-sound-wave {
|
128
|
+
position: absolute;
|
129
|
+
border: 2px solid var(--arcai-primary-color);
|
130
|
+
width: 100%;
|
131
|
+
height: 100%;
|
132
|
+
border-radius: 50%;
|
133
|
+
animation: arcaiSoundWave 1s ease-out infinite;
|
134
|
+
}
|
135
|
+
|
136
|
+
/* Typing indicator */
|
137
|
+
.arcai-typing {
|
138
|
+
display: flex;
|
139
|
+
align-items: center;
|
140
|
+
gap: 4px;
|
141
|
+
padding: 8px;
|
142
|
+
background: var(--arcai-bg);
|
143
|
+
border-radius: 12px;
|
144
|
+
margin-bottom: 8px;
|
145
|
+
}
|
146
|
+
|
147
|
+
.arcai-typing-dot {
|
148
|
+
width: 6px;
|
149
|
+
height: 6px;
|
150
|
+
background: var(--arcai-primary-color);
|
151
|
+
border-radius: 50%;
|
152
|
+
animation: arcaiDotPulse 1.4s infinite;
|
153
|
+
}
|
154
|
+
|
155
|
+
.arcai-typing-dot:nth-child(2) { animation-delay: 0.2s; }
|
156
|
+
.arcai-typing-dot:nth-child(3) { animation-delay: 0.4s; }
|
157
|
+
|
158
|
+
@keyframes arcaiDotPulse {
|
159
|
+
0%, 60%, 100% { transform: scale(1); opacity: 1; }
|
160
|
+
30% { transform: scale(1.2); opacity: 0.4; }
|
161
|
+
}
|
162
|
+
|
163
|
+
/* Suggested messages */
|
164
|
+
.arcai-suggestions {
|
165
|
+
display: flex;
|
166
|
+
flex-wrap: wrap;
|
167
|
+
gap: 8px;
|
168
|
+
margin-top: 12px;
|
169
|
+
}
|
170
|
+
|
171
|
+
.arcai-suggestion {
|
172
|
+
padding: 6px 12px;
|
173
|
+
background: var(--arcai-primary-color);
|
174
|
+
color: white;
|
175
|
+
border-radius: 16px;
|
176
|
+
font-size: 14px;
|
177
|
+
cursor: pointer;
|
178
|
+
transition: all 0.2s;
|
179
|
+
border: none;
|
180
|
+
}
|
181
|
+
|
182
|
+
.arcai-suggestion:hover {
|
183
|
+
transform: translateY(-1px);
|
184
|
+
filter: brightness(1.1);
|
185
|
+
}
|
186
|
+
|
187
|
+
/* Attachment handling */
|
188
|
+
.arcai-attachments {
|
189
|
+
display: flex;
|
190
|
+
flex-wrap: wrap;
|
191
|
+
gap: 8px;
|
192
|
+
margin-top: 8px;
|
193
|
+
}
|
194
|
+
|
195
|
+
.arcai-attachment {
|
196
|
+
display: flex;
|
197
|
+
align-items: center;
|
198
|
+
gap: 4px;
|
199
|
+
padding: 4px 8px;
|
200
|
+
background: var(--arcai-bg);
|
201
|
+
border-radius: 4px;
|
202
|
+
font-size: 12px;
|
203
|
+
}
|
204
|
+
|
205
|
+
.arcai-attachment-remove {
|
206
|
+
cursor: pointer;
|
207
|
+
opacity: 0.6;
|
208
|
+
transition: opacity 0.2s;
|
209
|
+
}
|
210
|
+
|
211
|
+
.arcai-attachment-remove:hover {
|
212
|
+
opacity: 1;
|
213
|
+
}
|
214
|
+
|
215
|
+
.arcai-chat {
|
216
|
+
position: fixed;
|
217
|
+
width: 380px;
|
218
|
+
height: 600px;
|
219
|
+
background: white;
|
220
|
+
border-radius: 12px;
|
221
|
+
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
222
|
+
display: flex;
|
223
|
+
flex-direction: column;
|
224
|
+
overflow: hidden;
|
225
|
+
opacity: 0;
|
226
|
+
transform: translateY(20px);
|
227
|
+
transition: opacity 0.3s, transform 0.3s;
|
228
|
+
z-index: 1;
|
229
|
+
}
|
230
|
+
|
231
|
+
.arcai-chat.open {
|
232
|
+
opacity: 1;
|
233
|
+
transform: translateY(0);
|
234
|
+
}
|
235
|
+
|
236
|
+
.arcai-header {
|
237
|
+
padding: 16px;
|
238
|
+
background: var(--arcai-primary-color, #2563eb);
|
239
|
+
color: white;
|
240
|
+
display: flex;
|
241
|
+
align-items: center;
|
242
|
+
justify-content: space-between;
|
243
|
+
}
|
244
|
+
|
245
|
+
.arcai-header.glassmorphism {
|
246
|
+
backdrop-filter: blur(8px);
|
247
|
+
background: rgba(37, 99, 235, 0.8);
|
248
|
+
}
|
249
|
+
|
250
|
+
.arcai-title {
|
251
|
+
display: flex;
|
252
|
+
align-items: center;
|
253
|
+
gap: 8px;
|
254
|
+
font-weight: 500;
|
255
|
+
}
|
256
|
+
|
257
|
+
.arcai-close {
|
258
|
+
background: none;
|
259
|
+
border: none;
|
260
|
+
color: white;
|
261
|
+
cursor: pointer;
|
262
|
+
padding: 4px;
|
263
|
+
border-radius: 4px;
|
264
|
+
display: flex;
|
265
|
+
align-items: center;
|
266
|
+
justify-content: center;
|
267
|
+
}
|
268
|
+
|
269
|
+
.arcai-close:hover {
|
270
|
+
background: rgba(255, 255, 255, 0.1);
|
271
|
+
}
|
272
|
+
|
273
|
+
.arcai-messages {
|
274
|
+
flex: 1;
|
275
|
+
overflow-y: auto;
|
276
|
+
padding: 16px;
|
277
|
+
background: #f8fafc;
|
278
|
+
}
|
279
|
+
|
280
|
+
.arcai-message {
|
281
|
+
display: flex;
|
282
|
+
align-items: flex-start;
|
283
|
+
gap: 8px;
|
284
|
+
margin-bottom: 16px;
|
285
|
+
opacity: 0;
|
286
|
+
transform: translateY(10px);
|
287
|
+
animation: arcaiMessageSlideUp 0.3s forwards;
|
288
|
+
}
|
289
|
+
|
290
|
+
.arcai-message.user {
|
291
|
+
flex-direction: row-reverse;
|
292
|
+
}
|
293
|
+
|
294
|
+
.arcai-avatar {
|
295
|
+
width: 32px;
|
296
|
+
height: 32px;
|
297
|
+
border-radius: 50%;
|
298
|
+
background: #e2e8f0;
|
299
|
+
display: flex;
|
300
|
+
align-items: center;
|
301
|
+
justify-content: center;
|
302
|
+
flex-shrink: 0;
|
303
|
+
}
|
304
|
+
|
305
|
+
.arcai-bubble {
|
306
|
+
background: white;
|
307
|
+
padding: 12px 16px;
|
308
|
+
border-radius: 12px;
|
309
|
+
max-width: 70%;
|
310
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
311
|
+
}
|
312
|
+
|
313
|
+
.arcai-message.user .arcai-bubble {
|
314
|
+
background: var(--arcai-primary-color, #2563eb);
|
315
|
+
color: white;
|
316
|
+
}
|
317
|
+
|
318
|
+
.arcai-input {
|
319
|
+
padding: 16px;
|
320
|
+
background: white;
|
321
|
+
border-top: 1px solid #e2e8f0;
|
322
|
+
}
|
323
|
+
|
324
|
+
.arcai-input-form {
|
325
|
+
display: flex;
|
326
|
+
gap: 8px;
|
327
|
+
}
|
328
|
+
|
329
|
+
.arcai-input-field {
|
330
|
+
flex: 1;
|
331
|
+
padding: 8px 16px;
|
332
|
+
border: 1px solid #e2e8f0;
|
333
|
+
border-radius: 24px;
|
334
|
+
outline: none;
|
335
|
+
font-size: 14px;
|
336
|
+
}
|
337
|
+
|
338
|
+
.arcai-input-field:focus {
|
339
|
+
border-color: var(--arcai-primary-color, #2563eb);
|
340
|
+
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
|
341
|
+
}
|
342
|
+
|
343
|
+
.arcai-send {
|
344
|
+
width: 36px;
|
345
|
+
height: 36px;
|
346
|
+
border-radius: 50%;
|
347
|
+
background: var(--arcai-primary-color, #2563eb);
|
348
|
+
color: white;
|
349
|
+
border: none;
|
350
|
+
cursor: pointer;
|
351
|
+
display: flex;
|
352
|
+
align-items: center;
|
353
|
+
justify-content: center;
|
354
|
+
transition: background-color 0.2s;
|
355
|
+
}
|
356
|
+
|
357
|
+
.arcai-send:hover {
|
358
|
+
background: var(--arcai-primary-color-dark, #1d4ed8);
|
359
|
+
}
|
360
|
+
|
361
|
+
.arcai-thought {
|
362
|
+
position: absolute;
|
363
|
+
bottom: 100%;
|
364
|
+
right: 0;
|
365
|
+
margin-bottom: 12px;
|
366
|
+
background: white;
|
367
|
+
padding: 12px 16px;
|
368
|
+
border-radius: 12px;
|
369
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
370
|
+
max-width: 240px;
|
371
|
+
opacity: 0;
|
372
|
+
transform: translateY(10px);
|
373
|
+
animation: arcaiThoughtBubble 4s ease-in-out forwards;
|
374
|
+
}
|
375
|
+
|
376
|
+
.arcai-thought::after {
|
377
|
+
content: '';
|
378
|
+
position: absolute;
|
379
|
+
bottom: -6px;
|
380
|
+
right: 24px;
|
381
|
+
width: 12px;
|
382
|
+
height: 12px;
|
383
|
+
background: white;
|
384
|
+
transform: rotate(45deg);
|
385
|
+
}
|
386
|
+
|
387
|
+
@keyframes arcaiFloatUpDown {
|
388
|
+
0%, 100% { transform: translateY(0); }
|
389
|
+
50% { transform: translateY(-10px); }
|
390
|
+
}
|
391
|
+
|
392
|
+
@keyframes arcaiFloatLeftRight {
|
393
|
+
0%, 100% { transform: translateX(0); }
|
394
|
+
50% { transform: translateX(10px); }
|
395
|
+
}
|
396
|
+
|
397
|
+
@keyframes arcaiFloatDiagonal {
|
398
|
+
0%, 100% { transform: translate(0, 0); }
|
399
|
+
50% { transform: translate(5px, -5px); }
|
400
|
+
}
|
401
|
+
|
402
|
+
@keyframes arcaiFloatCircle {
|
403
|
+
0% { transform: translate(0, 0); }
|
404
|
+
25% { transform: translate(5px, -5px); }
|
405
|
+
50% { transform: translate(10px, 0); }
|
406
|
+
75% { transform: translate(5px, 5px); }
|
407
|
+
100% { transform: translate(0, 0); }
|
408
|
+
}
|
409
|
+
|
410
|
+
@keyframes arcaiMessageSlideUp {
|
411
|
+
to {
|
412
|
+
opacity: 1;
|
413
|
+
transform: translateY(0);
|
414
|
+
}
|
415
|
+
}
|
416
|
+
|
417
|
+
@keyframes arcaiThoughtBubble {
|
418
|
+
0% {
|
419
|
+
opacity: 0;
|
420
|
+
transform: scale(0.8) translateY(10px);
|
421
|
+
}
|
422
|
+
10% {
|
423
|
+
opacity: 1;
|
424
|
+
transform: scale(1) translateY(0);
|
425
|
+
}
|
426
|
+
90% {
|
427
|
+
opacity: 1;
|
428
|
+
transform: scale(1) translateY(0);
|
429
|
+
}
|
430
|
+
100% {
|
431
|
+
opacity: 0;
|
432
|
+
transform: scale(0.8) translateY(-10px);
|
433
|
+
}
|
434
|
+
}`;
|