@smooai/chat-widget 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/chat-widget.global.js +1802 -0
- package/dist/chat-widget.global.js.map +1 -0
- package/dist/index.d.ts +278 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1296 -0
- package/dist/index.js.map +1 -0
- package/package.json +80 -0
- package/src/config.ts +160 -0
- package/src/conversation.ts +321 -0
- package/src/element.ts +563 -0
- package/src/index.ts +37 -0
- package/src/logo.ts +9 -0
- package/src/standalone.ts +33 -0
- package/src/styles.ts +518 -0
package/src/styles.ts
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import type { ChatWidgetMode, ResolvedTheme } from './config.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Render the widget's scoped stylesheet — the "Aurora Glass" design system.
|
|
5
|
+
*
|
|
6
|
+
* Every brand value is injected as a CSS custom property on `:host` so a host
|
|
7
|
+
* page can override colors per-instance and the rules below stay static. Two
|
|
8
|
+
* extra tokens are *derived in CSS* from the brand vars so they adapt to any
|
|
9
|
+
* theme (light or dark) without the caller supplying them:
|
|
10
|
+
*
|
|
11
|
+
* --sac-primary-2 a darker shade of `primary`, used as the second stop of the
|
|
12
|
+
* launcher / send / user-bubble gradients (depth without a
|
|
13
|
+
* second brand input).
|
|
14
|
+
* --sac-surface-2 a faint wash derived from `text`, used for inset chrome
|
|
15
|
+
* (composer field, close button, source cards). On a dark
|
|
16
|
+
* panel it reads as a light overlay; on a light panel, dark.
|
|
17
|
+
*
|
|
18
|
+
* Deliberately framework-light: no Tailwind, no runtime CSS-in-JS — just a string
|
|
19
|
+
* the web component drops into its shadow root. Modern color features
|
|
20
|
+
* (`color-mix`) are used intentionally; the widget targets evergreen browsers.
|
|
21
|
+
*
|
|
22
|
+
* `mode` switches host positioning + panel sizing between the floating popover
|
|
23
|
+
* (default) and the full-page layout (fills its container/viewport).
|
|
24
|
+
*/
|
|
25
|
+
export function buildStyles(theme: ResolvedTheme, mode: ChatWidgetMode = 'popover'): string {
|
|
26
|
+
return `
|
|
27
|
+
:host {
|
|
28
|
+
--sac-text: ${theme.text};
|
|
29
|
+
--sac-bg: ${theme.background};
|
|
30
|
+
--sac-primary: ${theme.primary};
|
|
31
|
+
--sac-primary-text: ${theme.primaryText};
|
|
32
|
+
--sac-assistant-bubble: ${theme.assistantBubble};
|
|
33
|
+
--sac-assistant-bubble-text: ${theme.assistantBubbleText};
|
|
34
|
+
--sac-user-bubble: ${theme.userBubble};
|
|
35
|
+
--sac-user-bubble-text: ${theme.userBubbleText};
|
|
36
|
+
--sac-border: ${theme.border};
|
|
37
|
+
|
|
38
|
+
/* Derived tokens — adapt to any brand color without a second input. */
|
|
39
|
+
--sac-primary-2: color-mix(in srgb, var(--sac-primary) 78%, #000 22%);
|
|
40
|
+
--sac-surface-2: color-mix(in srgb, var(--sac-text) 5%, transparent);
|
|
41
|
+
--sac-radius: 22px;
|
|
42
|
+
--sac-ease: cubic-bezier(.16, 1, .3, 1);
|
|
43
|
+
|
|
44
|
+
${
|
|
45
|
+
mode === 'fullpage'
|
|
46
|
+
? `/* Full-page: fill the host's box (sized by its container, else the viewport). */
|
|
47
|
+
display: block;
|
|
48
|
+
position: relative;
|
|
49
|
+
width: 100%;
|
|
50
|
+
height: 100%;
|
|
51
|
+
min-height: 100vh;`
|
|
52
|
+
: `/* Popover: float in the bottom-right corner. */
|
|
53
|
+
position: fixed;
|
|
54
|
+
bottom: 24px;
|
|
55
|
+
right: 24px;
|
|
56
|
+
z-index: 2147483000;`
|
|
57
|
+
}
|
|
58
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
59
|
+
-webkit-font-smoothing: antialiased;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
* { box-sizing: border-box; }
|
|
63
|
+
|
|
64
|
+
/* ───────────────────────────── Launcher ───────────────────────────── */
|
|
65
|
+
.launcher {
|
|
66
|
+
position: relative;
|
|
67
|
+
width: 62px;
|
|
68
|
+
height: 62px;
|
|
69
|
+
border-radius: 50%;
|
|
70
|
+
border: none;
|
|
71
|
+
cursor: pointer;
|
|
72
|
+
padding: 0;
|
|
73
|
+
background: radial-gradient(120% 120% at 30% 20%,
|
|
74
|
+
color-mix(in srgb, var(--sac-primary) 78%, #fff 22%) 0%,
|
|
75
|
+
var(--sac-primary) 42%,
|
|
76
|
+
var(--sac-primary-2) 130%);
|
|
77
|
+
color: var(--sac-primary-text);
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
justify-content: center;
|
|
81
|
+
box-shadow:
|
|
82
|
+
0 1px 0 rgba(255, 255, 255, .25) inset,
|
|
83
|
+
0 10px 24px -6px color-mix(in srgb, var(--sac-primary) 55%, transparent),
|
|
84
|
+
0 18px 50px -12px rgba(0, 0, 0, .6);
|
|
85
|
+
transition: transform .45s var(--sac-ease), box-shadow .45s var(--sac-ease), opacity .3s ease;
|
|
86
|
+
isolation: isolate;
|
|
87
|
+
}
|
|
88
|
+
/* Breathing presence ring. */
|
|
89
|
+
.launcher::before {
|
|
90
|
+
content: '';
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: -6px;
|
|
93
|
+
border-radius: 50%;
|
|
94
|
+
z-index: -1;
|
|
95
|
+
background: radial-gradient(closest-side, color-mix(in srgb, var(--sac-primary) 45%, transparent), transparent 75%);
|
|
96
|
+
animation: sac-breathe 3.4s ease-in-out infinite;
|
|
97
|
+
}
|
|
98
|
+
@keyframes sac-breathe { 0%, 100% { transform: scale(1); opacity: .55 } 50% { transform: scale(1.28); opacity: 0 } }
|
|
99
|
+
.launcher:hover {
|
|
100
|
+
transform: translateY(-3px) scale(1.06);
|
|
101
|
+
box-shadow:
|
|
102
|
+
0 1px 0 rgba(255, 255, 255, .3) inset,
|
|
103
|
+
0 16px 30px -6px color-mix(in srgb, var(--sac-primary) 60%, transparent),
|
|
104
|
+
0 26px 60px -14px rgba(0, 0, 0, .7);
|
|
105
|
+
}
|
|
106
|
+
.launcher:active { transform: translateY(-1px) scale(.98); }
|
|
107
|
+
.launcher .ico { width: 27px; height: 27px; display: block; transition: transform .4s var(--sac-ease); }
|
|
108
|
+
.launcher:hover .ico { transform: rotate(-6deg) scale(1.04); }
|
|
109
|
+
.launcher.hidden { opacity: 0; transform: scale(.4) translateY(10px); pointer-events: none; }
|
|
110
|
+
|
|
111
|
+
/* ─────────────────────────────── Panel ────────────────────────────── */
|
|
112
|
+
.panel {
|
|
113
|
+
width: 390px;
|
|
114
|
+
max-width: calc(100vw - 40px);
|
|
115
|
+
height: 600px;
|
|
116
|
+
max-height: calc(100vh - 56px);
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
overflow: hidden;
|
|
120
|
+
border-radius: var(--sac-radius);
|
|
121
|
+
background: linear-gradient(180deg, color-mix(in srgb, var(--sac-bg) 92%, #fff 8%) 0%, var(--sac-bg) 22%);
|
|
122
|
+
color: var(--sac-text);
|
|
123
|
+
border: 1px solid color-mix(in srgb, var(--sac-border) 80%, transparent);
|
|
124
|
+
box-shadow:
|
|
125
|
+
0 0 0 1px rgba(255, 255, 255, .03) inset,
|
|
126
|
+
0 40px 80px -24px rgba(0, 0, 0, .65),
|
|
127
|
+
0 16px 40px -20px rgba(0, 0, 0, .5);
|
|
128
|
+
transform-origin: bottom right;
|
|
129
|
+
animation: sac-panel-in .5s var(--sac-ease) both;
|
|
130
|
+
position: relative;
|
|
131
|
+
}
|
|
132
|
+
@keyframes sac-panel-in { from { opacity: 0; transform: translateY(16px) scale(.92) } to { opacity: 1; transform: none } }
|
|
133
|
+
.panel.hidden { display: none; }
|
|
134
|
+
/* Ambient brand glow bleeding from the top of the panel. */
|
|
135
|
+
.panel::before {
|
|
136
|
+
content: '';
|
|
137
|
+
position: absolute;
|
|
138
|
+
left: 0; right: 0; top: 0;
|
|
139
|
+
height: 140px;
|
|
140
|
+
pointer-events: none;
|
|
141
|
+
background: radial-gradient(120% 100% at 50% 0%, color-mix(in srgb, var(--sac-primary) 22%, transparent), transparent 70%);
|
|
142
|
+
}
|
|
143
|
+
/* Full-page: the panel becomes the whole surface. */
|
|
144
|
+
.panel.fullpage {
|
|
145
|
+
width: 100%;
|
|
146
|
+
height: 100%;
|
|
147
|
+
min-height: 100vh;
|
|
148
|
+
max-width: none;
|
|
149
|
+
max-height: none;
|
|
150
|
+
border: none;
|
|
151
|
+
border-radius: 0;
|
|
152
|
+
box-shadow: none;
|
|
153
|
+
animation: none;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* ─────────────────────────────── Header ───────────────────────────── */
|
|
157
|
+
.header {
|
|
158
|
+
position: relative;
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
gap: 12px;
|
|
162
|
+
padding: 16px 16px 14px;
|
|
163
|
+
}
|
|
164
|
+
.avatar {
|
|
165
|
+
width: 40px;
|
|
166
|
+
height: 40px;
|
|
167
|
+
border-radius: 13px;
|
|
168
|
+
flex: none;
|
|
169
|
+
background: linear-gradient(140deg, var(--sac-primary), var(--sac-primary-2));
|
|
170
|
+
display: flex;
|
|
171
|
+
align-items: center;
|
|
172
|
+
justify-content: center;
|
|
173
|
+
color: var(--sac-primary-text);
|
|
174
|
+
box-shadow:
|
|
175
|
+
0 6px 16px -6px color-mix(in srgb, var(--sac-primary) 60%, transparent),
|
|
176
|
+
0 1px 0 rgba(255, 255, 255, .25) inset;
|
|
177
|
+
}
|
|
178
|
+
.avatar svg { width: 22px; height: 22px; }
|
|
179
|
+
.avatar .logo-wrap { display: flex; }
|
|
180
|
+
.avatar .logo { height: 22px; width: auto; display: block; }
|
|
181
|
+
.meta { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
|
|
182
|
+
.title { font-weight: 650; font-size: 15.5px; letter-spacing: -.01em; line-height: 1.1; }
|
|
183
|
+
.status {
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
gap: 6px;
|
|
187
|
+
font-size: 12px;
|
|
188
|
+
color: color-mix(in srgb, var(--sac-text) 62%, transparent);
|
|
189
|
+
}
|
|
190
|
+
.dot {
|
|
191
|
+
width: 7px; height: 7px;
|
|
192
|
+
border-radius: 50%;
|
|
193
|
+
flex: none;
|
|
194
|
+
background: #34d399;
|
|
195
|
+
color: #34d399;
|
|
196
|
+
box-shadow: 0 0 0 0 rgba(52, 211, 153, .6);
|
|
197
|
+
animation: sac-pulse 2.4s ease-out infinite;
|
|
198
|
+
}
|
|
199
|
+
.dot.connecting { background: #fbbf24; color: #fbbf24; animation: sac-pulse 1.1s ease-out infinite; }
|
|
200
|
+
.dot.error { background: #f87171; color: #f87171; animation: none; }
|
|
201
|
+
.dot.off { background: #94a3b8; color: #94a3b8; animation: none; }
|
|
202
|
+
@keyframes sac-pulse {
|
|
203
|
+
0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent) }
|
|
204
|
+
70% { box-shadow: 0 0 0 6px transparent }
|
|
205
|
+
100% { box-shadow: 0 0 0 0 transparent }
|
|
206
|
+
}
|
|
207
|
+
.close {
|
|
208
|
+
margin-left: auto;
|
|
209
|
+
width: 32px; height: 32px;
|
|
210
|
+
border-radius: 10px;
|
|
211
|
+
border: none;
|
|
212
|
+
cursor: pointer;
|
|
213
|
+
background: var(--sac-surface-2);
|
|
214
|
+
color: inherit;
|
|
215
|
+
display: flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
justify-content: center;
|
|
218
|
+
transition: background .2s ease, transform .2s ease;
|
|
219
|
+
}
|
|
220
|
+
.close:hover { background: color-mix(in srgb, var(--sac-text) 12%, transparent); transform: translateY(1px); }
|
|
221
|
+
.close svg { width: 16px; height: 16px; opacity: .8; }
|
|
222
|
+
.powered { margin-left: auto; font-size: 10.5px; letter-spacing: .02em; opacity: .6; }
|
|
223
|
+
.header-sep { height: 1px; margin: 0 16px; background: linear-gradient(90deg, transparent, var(--sac-border), transparent); }
|
|
224
|
+
|
|
225
|
+
/* Full-page header: taller, logo-led, no close. */
|
|
226
|
+
.panel.fullpage .header { padding: 18px 22px; }
|
|
227
|
+
.panel.fullpage .avatar { width: 44px; height: 44px; }
|
|
228
|
+
.panel.fullpage .avatar .logo { height: 26px; }
|
|
229
|
+
|
|
230
|
+
/* ────────────────────────────── Messages ──────────────────────────── */
|
|
231
|
+
.messages {
|
|
232
|
+
flex: 1;
|
|
233
|
+
overflow-y: auto;
|
|
234
|
+
padding: 18px 16px 8px;
|
|
235
|
+
display: flex;
|
|
236
|
+
flex-direction: column;
|
|
237
|
+
gap: 12px;
|
|
238
|
+
scroll-behavior: smooth;
|
|
239
|
+
}
|
|
240
|
+
.messages::-webkit-scrollbar { width: 8px; }
|
|
241
|
+
.messages::-webkit-scrollbar-thumb {
|
|
242
|
+
background: color-mix(in srgb, var(--sac-text) 14%, transparent);
|
|
243
|
+
border-radius: 99px;
|
|
244
|
+
border: 2px solid transparent;
|
|
245
|
+
background-clip: padding-box;
|
|
246
|
+
}
|
|
247
|
+
.messages::-webkit-scrollbar-thumb:hover {
|
|
248
|
+
background: color-mix(in srgb, var(--sac-text) 24%, transparent);
|
|
249
|
+
background-clip: padding-box;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.row {
|
|
253
|
+
display: flex;
|
|
254
|
+
gap: 9px;
|
|
255
|
+
max-width: 88%;
|
|
256
|
+
animation: sac-msg-in .42s var(--sac-ease) both;
|
|
257
|
+
}
|
|
258
|
+
@keyframes sac-msg-in { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }
|
|
259
|
+
.row.user { align-self: flex-end; flex-direction: row-reverse; }
|
|
260
|
+
.row.assistant { align-self: flex-start; }
|
|
261
|
+
.mini {
|
|
262
|
+
width: 26px; height: 26px;
|
|
263
|
+
border-radius: 9px;
|
|
264
|
+
flex: none;
|
|
265
|
+
align-self: flex-end;
|
|
266
|
+
background: linear-gradient(140deg, var(--sac-primary), var(--sac-primary-2));
|
|
267
|
+
display: flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
justify-content: center;
|
|
270
|
+
color: var(--sac-primary-text);
|
|
271
|
+
}
|
|
272
|
+
.mini svg { width: 15px; height: 15px; }
|
|
273
|
+
|
|
274
|
+
.bubble {
|
|
275
|
+
padding: 11px 14px;
|
|
276
|
+
border-radius: 16px;
|
|
277
|
+
font-size: 14px;
|
|
278
|
+
line-height: 1.5;
|
|
279
|
+
white-space: pre-wrap;
|
|
280
|
+
word-break: break-word;
|
|
281
|
+
position: relative;
|
|
282
|
+
}
|
|
283
|
+
.bubble.assistant {
|
|
284
|
+
background: linear-gradient(180deg, color-mix(in srgb, var(--sac-assistant-bubble) 86%, #fff 5%), var(--sac-assistant-bubble));
|
|
285
|
+
color: var(--sac-assistant-bubble-text);
|
|
286
|
+
border: 1px solid color-mix(in srgb, var(--sac-text) 8%, transparent);
|
|
287
|
+
border-bottom-left-radius: 5px;
|
|
288
|
+
box-shadow: 0 2px 8px -4px rgba(0, 0, 0, .4);
|
|
289
|
+
}
|
|
290
|
+
.bubble.user {
|
|
291
|
+
background: linear-gradient(165deg,
|
|
292
|
+
color-mix(in srgb, var(--sac-user-bubble) 88%, #fff 12%),
|
|
293
|
+
var(--sac-user-bubble) 60%,
|
|
294
|
+
color-mix(in srgb, var(--sac-user-bubble) 80%, var(--sac-primary-2) 20%));
|
|
295
|
+
color: var(--sac-user-bubble-text);
|
|
296
|
+
border-bottom-right-radius: 5px;
|
|
297
|
+
box-shadow: 0 6px 16px -8px color-mix(in srgb, var(--sac-primary) 50%, transparent);
|
|
298
|
+
}
|
|
299
|
+
.bubble.greeting {
|
|
300
|
+
background: transparent;
|
|
301
|
+
border: 1px dashed color-mix(in srgb, var(--sac-text) 14%, transparent);
|
|
302
|
+
color: color-mix(in srgb, var(--sac-text) 80%, transparent);
|
|
303
|
+
box-shadow: none;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* Typing indicator (assistant bubble with no text yet). */
|
|
307
|
+
.bubble.typing { display: flex; gap: 4px; padding: 14px 15px; }
|
|
308
|
+
.bubble.typing i {
|
|
309
|
+
width: 7px; height: 7px;
|
|
310
|
+
border-radius: 50%;
|
|
311
|
+
background: color-mix(in srgb, var(--sac-assistant-bubble-text) 55%, transparent);
|
|
312
|
+
animation: sac-typing 1.3s ease-in-out infinite;
|
|
313
|
+
}
|
|
314
|
+
.bubble.typing i:nth-child(2) { animation-delay: .18s; }
|
|
315
|
+
.bubble.typing i:nth-child(3) { animation-delay: .36s; }
|
|
316
|
+
@keyframes sac-typing { 0%, 60%, 100% { transform: translateY(0); opacity: .4 } 30% { transform: translateY(-5px); opacity: 1 } }
|
|
317
|
+
|
|
318
|
+
.cursor::after {
|
|
319
|
+
content: '';
|
|
320
|
+
display: inline-block;
|
|
321
|
+
width: 2px; height: 1.05em;
|
|
322
|
+
margin-left: 2px;
|
|
323
|
+
vertical-align: -2px;
|
|
324
|
+
border-radius: 2px;
|
|
325
|
+
background: currentColor;
|
|
326
|
+
animation: sac-blink 1s steps(2, start) infinite;
|
|
327
|
+
}
|
|
328
|
+
@keyframes sac-blink { to { opacity: 0 } }
|
|
329
|
+
|
|
330
|
+
/* Full-page: center the conversation in a readable column. */
|
|
331
|
+
.panel.fullpage .messages { padding: 26px 20px; }
|
|
332
|
+
.panel.fullpage .row { max-width: 760px; width: 100%; margin-left: auto; margin-right: auto; }
|
|
333
|
+
.panel.fullpage .row.user { max-width: 80%; margin-right: 0; }
|
|
334
|
+
|
|
335
|
+
/* ───────────────── Sources (grounding citations) ──────────────────── */
|
|
336
|
+
.sources {
|
|
337
|
+
align-self: flex-start;
|
|
338
|
+
max-width: 88%;
|
|
339
|
+
margin: -4px 0 0 35px;
|
|
340
|
+
}
|
|
341
|
+
.panel.fullpage .sources { max-width: 760px; width: 100%; margin-left: auto; margin-right: auto; }
|
|
342
|
+
.sources summary {
|
|
343
|
+
cursor: pointer;
|
|
344
|
+
list-style: none;
|
|
345
|
+
display: inline-flex;
|
|
346
|
+
align-items: center;
|
|
347
|
+
gap: 7px;
|
|
348
|
+
font-size: 12px;
|
|
349
|
+
font-weight: 600;
|
|
350
|
+
color: color-mix(in srgb, var(--sac-text) 70%, transparent);
|
|
351
|
+
padding: 5px 0;
|
|
352
|
+
user-select: none;
|
|
353
|
+
}
|
|
354
|
+
.sources summary::-webkit-details-marker { display: none; }
|
|
355
|
+
.sources .chev { transition: transform .2s var(--sac-ease); flex: none; }
|
|
356
|
+
.sources details[open] .chev { transform: rotate(90deg); }
|
|
357
|
+
.sources .count {
|
|
358
|
+
background: color-mix(in srgb, var(--sac-primary) 18%, transparent);
|
|
359
|
+
color: color-mix(in srgb, var(--sac-primary) 92%, #fff);
|
|
360
|
+
font-size: 10.5px;
|
|
361
|
+
font-weight: 700;
|
|
362
|
+
padding: 1px 7px;
|
|
363
|
+
border-radius: 99px;
|
|
364
|
+
}
|
|
365
|
+
.sources ol { list-style: none; margin: 6px 0 2px; padding: 0; display: flex; flex-direction: column; gap: 7px; }
|
|
366
|
+
.sources li {
|
|
367
|
+
background: var(--sac-surface-2);
|
|
368
|
+
border: 1px solid color-mix(in srgb, var(--sac-border) 70%, transparent);
|
|
369
|
+
border-left: 2px solid var(--sac-primary);
|
|
370
|
+
border-radius: 9px;
|
|
371
|
+
padding: 8px 10px;
|
|
372
|
+
}
|
|
373
|
+
.sources .src-title {
|
|
374
|
+
color: color-mix(in srgb, var(--sac-primary) 92%, #fff);
|
|
375
|
+
font-weight: 600;
|
|
376
|
+
font-size: 12.5px;
|
|
377
|
+
text-decoration: none;
|
|
378
|
+
word-break: break-word;
|
|
379
|
+
}
|
|
380
|
+
.sources a.src-title:hover { text-decoration: underline; }
|
|
381
|
+
.sources span.src-title { color: var(--sac-text); opacity: .95; }
|
|
382
|
+
.sources .src-snippet {
|
|
383
|
+
display: block;
|
|
384
|
+
margin-top: 3px;
|
|
385
|
+
font-size: 11.5px;
|
|
386
|
+
line-height: 1.45;
|
|
387
|
+
color: color-mix(in srgb, var(--sac-text) 55%, transparent);
|
|
388
|
+
white-space: normal;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* ────────────────────────────── Composer ──────────────────────────── */
|
|
392
|
+
.composer-wrap { padding: 12px 14px calc(12px + env(safe-area-inset-bottom)); }
|
|
393
|
+
.composer {
|
|
394
|
+
display: flex;
|
|
395
|
+
align-items: flex-end;
|
|
396
|
+
gap: 8px;
|
|
397
|
+
padding: 7px 7px 7px 14px;
|
|
398
|
+
border-radius: 18px;
|
|
399
|
+
background: var(--sac-surface-2);
|
|
400
|
+
border: 1px solid color-mix(in srgb, var(--sac-border) 80%, transparent);
|
|
401
|
+
transition: border-color .25s ease, box-shadow .25s ease, background .25s ease;
|
|
402
|
+
}
|
|
403
|
+
.composer:focus-within {
|
|
404
|
+
border-color: color-mix(in srgb, var(--sac-primary) 60%, transparent);
|
|
405
|
+
box-shadow: 0 0 0 4px color-mix(in srgb, var(--sac-primary) 14%, transparent);
|
|
406
|
+
}
|
|
407
|
+
.composer textarea {
|
|
408
|
+
flex: 1;
|
|
409
|
+
resize: none;
|
|
410
|
+
border: none;
|
|
411
|
+
background: transparent;
|
|
412
|
+
color: var(--sac-text);
|
|
413
|
+
font-family: inherit;
|
|
414
|
+
font-size: 14px;
|
|
415
|
+
line-height: 1.45;
|
|
416
|
+
max-height: 120px;
|
|
417
|
+
padding: 6px 0;
|
|
418
|
+
outline: none;
|
|
419
|
+
}
|
|
420
|
+
.composer textarea::placeholder { color: color-mix(in srgb, var(--sac-text) 42%, transparent); }
|
|
421
|
+
.send {
|
|
422
|
+
width: 38px; height: 38px;
|
|
423
|
+
flex: none;
|
|
424
|
+
border: none;
|
|
425
|
+
border-radius: 13px;
|
|
426
|
+
cursor: pointer;
|
|
427
|
+
display: flex;
|
|
428
|
+
align-items: center;
|
|
429
|
+
justify-content: center;
|
|
430
|
+
background: linear-gradient(150deg, var(--sac-primary), var(--sac-primary-2));
|
|
431
|
+
color: var(--sac-primary-text);
|
|
432
|
+
box-shadow:
|
|
433
|
+
0 6px 14px -6px color-mix(in srgb, var(--sac-primary) 65%, transparent),
|
|
434
|
+
0 1px 0 rgba(255, 255, 255, .25) inset;
|
|
435
|
+
transition: transform .2s var(--sac-ease), box-shadow .2s var(--sac-ease), opacity .2s ease;
|
|
436
|
+
}
|
|
437
|
+
.send svg { width: 18px; height: 18px; }
|
|
438
|
+
.send:hover { transform: translateY(-1px) scale(1.05); }
|
|
439
|
+
.send:active { transform: scale(.94); }
|
|
440
|
+
.send:disabled { opacity: .4; cursor: default; transform: none; box-shadow: none; }
|
|
441
|
+
.footer {
|
|
442
|
+
text-align: center;
|
|
443
|
+
margin-top: 9px;
|
|
444
|
+
font-size: 10.5px;
|
|
445
|
+
letter-spacing: .04em;
|
|
446
|
+
color: color-mix(in srgb, var(--sac-text) 38%, transparent);
|
|
447
|
+
}
|
|
448
|
+
.footer b { font-weight: 600; color: color-mix(in srgb, var(--sac-text) 55%, transparent); }
|
|
449
|
+
|
|
450
|
+
/* ─────────────────── Pre-chat identity form ───────────────────────── */
|
|
451
|
+
.prechat { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 18px; padding: 22px 20px; }
|
|
452
|
+
.pc-head { text-align: center; }
|
|
453
|
+
.pc-title { font-size: 17px; font-weight: 650; letter-spacing: -.01em; }
|
|
454
|
+
.pc-sub { margin-top: 4px; font-size: 13px; color: color-mix(in srgb, var(--sac-text) 60%, transparent); }
|
|
455
|
+
.pc-form { display: flex; flex-direction: column; gap: 12px; }
|
|
456
|
+
.pc-field { display: flex; flex-direction: column; gap: 5px; }
|
|
457
|
+
.pc-field span { font-size: 12px; font-weight: 600; color: color-mix(in srgb, var(--sac-text) 70%, transparent); }
|
|
458
|
+
.pc-field input {
|
|
459
|
+
border: 1px solid color-mix(in srgb, var(--sac-border) 80%, transparent);
|
|
460
|
+
background: var(--sac-surface-2);
|
|
461
|
+
color: var(--sac-text);
|
|
462
|
+
border-radius: 12px;
|
|
463
|
+
padding: 11px 13px;
|
|
464
|
+
font-family: inherit;
|
|
465
|
+
font-size: 14px;
|
|
466
|
+
outline: none;
|
|
467
|
+
transition: border-color .2s ease, box-shadow .2s ease;
|
|
468
|
+
}
|
|
469
|
+
.pc-field input::placeholder { color: color-mix(in srgb, var(--sac-text) 42%, transparent); }
|
|
470
|
+
.pc-field input:focus {
|
|
471
|
+
border-color: color-mix(in srgb, var(--sac-primary) 60%, transparent);
|
|
472
|
+
box-shadow: 0 0 0 4px color-mix(in srgb, var(--sac-primary) 14%, transparent);
|
|
473
|
+
}
|
|
474
|
+
.pc-submit {
|
|
475
|
+
margin-top: 4px;
|
|
476
|
+
border: none;
|
|
477
|
+
border-radius: 13px;
|
|
478
|
+
padding: 12px;
|
|
479
|
+
cursor: pointer;
|
|
480
|
+
background: linear-gradient(150deg, var(--sac-primary), var(--sac-primary-2));
|
|
481
|
+
color: var(--sac-primary-text);
|
|
482
|
+
font-weight: 650;
|
|
483
|
+
font-size: 14px;
|
|
484
|
+
box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--sac-primary) 65%, transparent), 0 1px 0 rgba(255, 255, 255, .25) inset;
|
|
485
|
+
transition: transform .2s var(--sac-ease);
|
|
486
|
+
}
|
|
487
|
+
.pc-submit:hover { transform: translateY(-1px); }
|
|
488
|
+
.pc-submit:active { transform: scale(.98); }
|
|
489
|
+
|
|
490
|
+
/* ─────────────────── Starter-prompt chips ─────────────────────────── */
|
|
491
|
+
.prompts { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 2px 35px; }
|
|
492
|
+
.panel.fullpage .prompts { margin-left: auto; margin-right: auto; max-width: 760px; width: 100%; }
|
|
493
|
+
.chip {
|
|
494
|
+
border: 1px solid color-mix(in srgb, var(--sac-border) 80%, transparent);
|
|
495
|
+
background: var(--sac-surface-2);
|
|
496
|
+
color: var(--sac-text);
|
|
497
|
+
border-radius: 999px;
|
|
498
|
+
padding: 8px 13px;
|
|
499
|
+
font-family: inherit;
|
|
500
|
+
font-size: 12.5px;
|
|
501
|
+
cursor: pointer;
|
|
502
|
+
text-align: left;
|
|
503
|
+
transition: border-color .2s ease, background .2s ease, transform .2s ease;
|
|
504
|
+
}
|
|
505
|
+
.chip:hover {
|
|
506
|
+
border-color: color-mix(in srgb, var(--sac-primary) 50%, transparent);
|
|
507
|
+
background: color-mix(in srgb, var(--sac-primary) 10%, var(--sac-surface-2));
|
|
508
|
+
transform: translateY(-1px);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.hidden { display: none !important; }
|
|
512
|
+
|
|
513
|
+
@media (prefers-reduced-motion: reduce) {
|
|
514
|
+
.launcher::before, .dot, .bubble.typing i { animation: none !important; }
|
|
515
|
+
.panel, .row, .launcher, .send, .close { animation: none !important; transition: none !important; }
|
|
516
|
+
}
|
|
517
|
+
`;
|
|
518
|
+
}
|