@shaimaababiker/embed 0.1.3 → 0.1.4

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
@@ -56,6 +56,7 @@ import { useQuery } from "@apollo/client";
56
56
  import { z } from "zod";
57
57
  import { useForm } from "react-hook-form";
58
58
  import { zodResolver } from "@hookform/resolvers/zod";
59
+ import { Send, ShieldCheck, ArrowUpRight } from "lucide-react";
59
60
 
60
61
  // src/lib/startNewChat.ts
61
62
  async function startNewChat(origin, guestName, guestEmail, chatbotId) {
@@ -100,164 +101,12 @@ var GET_MESSEGES_BY_CHAT_SESSION_ID = gql`
100
101
  }
101
102
  `;
102
103
 
103
- // src/ui/Avatar.tsx
104
- import { rings } from "@dicebear/collection";
105
- import { createAvatar } from "@dicebear/core";
106
- import { jsx } from "react/jsx-runtime";
107
- function utf8ToBase64(input) {
108
- const bytes = new TextEncoder().encode(input);
109
- let binary = "";
110
- for (let i = 0; i < bytes.length; i++) {
111
- binary += String.fromCharCode(bytes[i]);
112
- }
113
- return btoa(binary);
114
- }
115
- function Avatar({ seed, className }) {
116
- const avatar = createAvatar(rings, { seed });
117
- const svg = avatar.toString();
118
- const dataUrl = `data:image/svg+xml;base64,${utf8ToBase64(svg)}`;
119
- return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("img", { src: dataUrl, alt: "Avatar", width: 80, height: 80, className }) });
120
- }
121
- var Avatar_default = Avatar;
122
-
123
104
  // src/ui/Messages.tsx
124
105
  import ReactMarkdown from "react-markdown";
125
106
  import remarkGfm from "remark-gfm";
126
107
  import { UserCircle } from "lucide-react";
127
108
  import { useEffect, useRef, useState } from "react";
128
-
129
- // src/ui/ChatMotion.tsx
130
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
131
- function FourDotWave({ className = "" }) {
132
- const dots = [
133
- { color: "#8a2a2a", delay: "0s" },
134
- // oxblood
135
- { color: "#c89a5b", delay: "0.12s" },
136
- // brass
137
- { color: "#5a6b3b", delay: "0.24s" },
138
- // moss
139
- { color: "#2c5b5e", delay: "0.36s" }
140
- // teal
141
- ];
142
- return /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center gap-1.5 ${className}`, "aria-label": "Loading", children: [
143
- dots.map((d, i) => /* @__PURE__ */ jsx2(
144
- "span",
145
- {
146
- className: "dot-wave",
147
- style: { backgroundColor: d.color, animationDelay: d.delay }
148
- },
149
- i
150
- )),
151
- /* @__PURE__ */ jsx2("style", { children: `
152
- .dot-wave {
153
- display: inline-block;
154
- width: 7px;
155
- height: 7px;
156
- border-radius: 9999px;
157
- will-change: transform;
158
- animation: dotBounce 1.1s cubic-bezier(0.45, 0, 0.55, 1) infinite;
159
- }
160
- @keyframes dotBounce {
161
- 0%, 60%, 100% { transform: translate3d(0, 0, 0); }
162
- 30% { transform: translate3d(0, -6px, 0); }
163
- }
164
- ` })
165
- ] });
166
- }
167
- function AiBubble({
168
- children,
169
- className = "",
170
- springIn = true,
171
- style,
172
- typing = false
173
- }) {
174
- return /* @__PURE__ */ jsxs(
175
- "div",
176
- {
177
- className: `ai-bubble ${springIn ? "ai-bubble-in" : ""} ${typing ? "ai-typing" : ""} ${className}`,
178
- style,
179
- children: [
180
- children,
181
- /* @__PURE__ */ jsx2("style", { children: `
182
- .ai-bubble {
183
- position: relative;
184
- transform-origin: bottom left;
185
- color: #1e1e1e;
186
- background: linear-gradient(
187
- 135deg,
188
- #eef2ff 0%,
189
- #f5f3ff 35%,
190
- #ecfeff 70%,
191
- #eef2ff 100%
192
- );
193
- background-size: 250% 250%;
194
- will-change: transform, background-position, box-shadow;
195
- transition: box-shadow 220ms ease, background 220ms ease;
196
- }
197
- .ai-bubble-in {
198
- animation: aiSpring 620ms cubic-bezier(0.175, 0.885, 0.32, 1.275) both;
199
- }
200
- /* Typing state: vibrant purple gradient with glow */
201
- .ai-typing {
202
- background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 35%, #8b5cf6 70%, #7c3aed 100%);
203
- background-size: 200% 200%;
204
- animation: aiTypingShift 4.5s ease-in-out infinite;
205
- box-shadow: 0 12px 36px rgba(124,58,237,0.20), 0 1px 0 rgba(255,255,255,0.05) inset;
206
- color: #fff;
207
- border-color: rgba(255,255,255,0.08);
208
- }
209
- @keyframes aiSpring {
210
- 0% { transform: scale(0.4) translate3d(0, 12px, 0); opacity: 0; }
211
- 60% { transform: scale(1.04) translate3d(0, -2px, 0); opacity: 1; }
212
- 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 1; }
213
- }
214
- @keyframes aiTypingShift {
215
- 0% { background-position: 0% 50%; filter: drop-shadow(0 0 0 rgba(124,58,237,0)); }
216
- 50% { background-position: 100% 50%; filter: drop-shadow(0 18px 48px rgba(124,58,237,0.18)); }
217
- 100% { background-position: 0% 50%; filter: drop-shadow(0 0 0 rgba(124,58,237,0)); }
218
- }
219
- ` })
220
- ]
221
- }
222
- );
223
- }
224
- function UserBubble({
225
- children,
226
- className = "",
227
- springIn = true,
228
- style
229
- }) {
230
- return /* @__PURE__ */ jsxs(
231
- "div",
232
- {
233
- className: `user-bubble ${springIn ? "user-bubble-in" : ""} ${className}`,
234
- style,
235
- children: [
236
- children,
237
- /* @__PURE__ */ jsx2("style", { children: `
238
- .user-bubble {
239
- position: relative;
240
- transform-origin: bottom right;
241
- background: #111113;
242
- color: #ffffff;
243
- will-change: transform;
244
- }
245
- .user-bubble-in {
246
- animation: userSpring 520ms cubic-bezier(0.175, 0.885, 0.32, 1.275) both;
247
- }
248
- @keyframes userSpring {
249
- 0% { transform: scale(0.4) translate3d(0, 12px, 0); opacity: 0; }
250
- 60% { transform: scale(1.04) translate3d(0, -2px, 0); opacity: 1; }
251
- 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 1; }
252
- }
253
- ` })
254
- ]
255
- }
256
- );
257
- }
258
-
259
- // src/ui/Messages.tsx
260
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
109
+ import { jsx, jsxs } from "react/jsx-runtime";
261
110
  function formatTime(iso) {
262
111
  try {
263
112
  const d = new Date(iso);
@@ -266,7 +115,12 @@ function formatTime(iso) {
266
115
  return "";
267
116
  }
268
117
  }
269
- function TypewriterMarkdown({ text, isFresh, components, onType }) {
118
+ function TypewriterMarkdown({
119
+ text,
120
+ isFresh,
121
+ components,
122
+ onType
123
+ }) {
270
124
  const [displayedText, setDisplayedText] = useState("");
271
125
  const [index, setIndex] = useState(0);
272
126
  useEffect(() => {
@@ -279,22 +133,20 @@ function TypewriterMarkdown({ text, isFresh, components, onType }) {
279
133
  setDisplayedText((prev) => prev + text[index]);
280
134
  setIndex((prev) => prev + 1);
281
135
  if (onType) onType();
282
- }, 15);
136
+ }, 14);
283
137
  return () => clearTimeout(timeout);
284
138
  } else if (!isFresh) {
285
139
  setDisplayedText(text || "");
286
140
  }
287
141
  }, [index, text, isFresh]);
288
- return /* @__PURE__ */ jsx3(
289
- ReactMarkdown,
290
- {
291
- remarkPlugins: [remarkGfm],
292
- components,
293
- children: isFresh ? displayedText : text
294
- }
295
- );
142
+ const showCaret = isFresh && index < text.length;
143
+ return /* @__PURE__ */ jsx("span", { className: showCaret ? "assistly-caret" : void 0, children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components, children: isFresh ? displayedText : text }) });
296
144
  }
297
- function Messages({ messages, chatbotName, logoUrl, isReviewPage = false }) {
145
+ function Messages({
146
+ messages,
147
+ chatbotName,
148
+ isReviewPage = false
149
+ }) {
298
150
  const ref = useRef(null);
299
151
  const [hoveredId, setHoveredId] = useState(null);
300
152
  const scrollToBottom = (smooth = true) => {
@@ -305,111 +157,162 @@ function Messages({ messages, chatbotName, logoUrl, isReviewPage = false }) {
305
157
  useEffect(() => {
306
158
  scrollToBottom();
307
159
  }, [messages]);
308
- const [isClient, setIsClient] = useState(false);
309
- useEffect(() => {
310
- setIsClient(true);
311
- }, []);
312
160
  const markdownComponents = {
313
161
  ul: (_a) => {
314
162
  var _b = _a, { node } = _b, props = __objRest(_b, ["node"]);
315
- return /* @__PURE__ */ jsx3("ul", __spreadValues({ className: "list-disc list-inside ml-5 mb-3" }, props));
163
+ return /* @__PURE__ */ jsx("ul", __spreadValues({}, props));
316
164
  },
317
165
  ol: (_c) => {
318
166
  var _d = _c, { node } = _d, props = __objRest(_d, ["node"]);
319
- return /* @__PURE__ */ jsx3("ol", __spreadValues({ className: "list-decimal list-inside ml-5 mb-3" }, props));
167
+ return /* @__PURE__ */ jsx("ol", __spreadValues({}, props));
320
168
  },
321
- h1: (_e) => {
169
+ a: (_e) => {
322
170
  var _f = _e, { node } = _f, props = __objRest(_f, ["node"]);
323
- return /* @__PURE__ */ jsx3("h1", __spreadValues({ className: "text-2xl font-bold mb-3 font-display" }, props));
324
- },
325
- h2: (_g) => {
326
- var _h = _g, { node } = _h, props = __objRest(_h, ["node"]);
327
- return /* @__PURE__ */ jsx3("h2", __spreadValues({ className: "text-xl font-bold mb-3 font-display" }, props));
328
- },
329
- h3: (_i) => {
330
- var _j = _i, { node } = _j, props = __objRest(_j, ["node"]);
331
- return /* @__PURE__ */ jsx3("h3", __spreadValues({ className: "text-lg font-bold mb-3 font-display" }, props));
332
- },
333
- table: (_k) => {
334
- var _l = _k, { node } = _l, props = __objRest(_l, ["node"]);
335
- return /* @__PURE__ */ jsx3("table", __spreadValues({ className: "table-auto mb-3 w-full border-separate border-2 rounded-sm border-spacing-4", style: { borderColor: "rgba(26,20,15,0.18)" } }, props));
336
- },
337
- th: (_m) => {
338
- var _n = _m, { node } = _n, props = __objRest(_n, ["node"]);
339
- return /* @__PURE__ */ jsx3("th", __spreadValues({ className: "text-left underline" }, props));
340
- },
341
- p: (_o) => {
342
- var _p = _o, { node } = _p, props = __objRest(_p, ["node"]);
343
- return /* @__PURE__ */ jsx3("p", __spreadValues({ className: "whitespace-pre-wrap mb-3 last:mb-0 leading-relaxed" }, props));
344
- },
345
- a: (_q) => {
346
- var _r = _q, { node } = _r, props = __objRest(_r, ["node"]);
347
- return /* @__PURE__ */ jsx3("a", __spreadValues({ className: "hover:underline font-semibold", style: { color: "#c45d4f" }, rel: "noopener noreferrer", target: "_blank" }, props));
348
- },
349
- code: (_s) => {
350
- var _t = _s, { node } = _t, props = __objRest(_t, ["node"]);
351
- return /* @__PURE__ */ jsx3(
352
- "code",
353
- __spreadValues({
354
- className: "px-1.5 py-0.5 rounded font-mono text-[13px]",
355
- style: { background: "rgba(26,20,15,0.10)" }
356
- }, props)
357
- );
171
+ return /* @__PURE__ */ jsx("a", __spreadValues({ rel: "noopener noreferrer", target: "_blank" }, props));
358
172
  }
359
173
  };
360
- return /* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col space-y-7 py-8 px-5 md:px-10 bg-transparent rounded-lg scroll-smooth ", children: [
174
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 22 }, children: [
361
175
  messages.map((message, index) => {
362
176
  const isSender = message.sender !== "user";
363
177
  const isThinking = message.content === "" || message.content === "Thinking...";
364
178
  const isFresh = index === messages.length - 1;
365
179
  const showMeta = hoveredId === message.id || isReviewPage;
366
- return /* @__PURE__ */ jsxs2(
180
+ return /* @__PURE__ */ jsxs(
367
181
  "div",
368
182
  {
369
183
  onMouseEnter: () => setHoveredId(message.id),
370
184
  onMouseLeave: () => setHoveredId(null),
371
- className: `chat ${isSender ? "chat-start" : "chat-end"} relative group overflow-hidden`,
185
+ style: {
186
+ display: "flex",
187
+ flexDirection: "column",
188
+ alignItems: isSender ? "flex-start" : "flex-end",
189
+ maxWidth: "100%"
190
+ },
372
191
  children: [
373
- isReviewPage && /* @__PURE__ */ jsxs2("p", { className: "absolute -bottom-5 text-xs text-gray-300", children: [
374
- "sent ",
375
- new Date(message.created_at).toLocaleString()
376
- ] }),
377
- isFresh && /* @__PURE__ */ jsx3(
378
- "span",
192
+ /* @__PURE__ */ jsxs(
193
+ "div",
379
194
  {
380
- "aria-hidden": true,
381
- className: "ring-out pointer-events-none absolute -inset-2 rounded-[26px]"
195
+ style: {
196
+ display: "flex",
197
+ alignItems: "center",
198
+ gap: 10,
199
+ marginBottom: 8,
200
+ padding: isSender ? "0 4px" : "0 4px",
201
+ flexDirection: isSender ? "row" : "row-reverse"
202
+ },
203
+ children: [
204
+ /* @__PURE__ */ jsx(
205
+ "div",
206
+ {
207
+ style: {
208
+ width: 26,
209
+ height: 26,
210
+ borderRadius: "50%",
211
+ background: isSender ? "var(--assistly-paper-2)" : "var(--assistly-ink)",
212
+ color: isSender ? "var(--assistly-ink)" : "var(--assistly-paper)",
213
+ border: "1px solid var(--assistly-hairline-strong)",
214
+ display: "grid",
215
+ placeItems: "center",
216
+ flexShrink: 0
217
+ },
218
+ "aria-hidden": true,
219
+ children: isSender ? /* @__PURE__ */ jsx(
220
+ "span",
221
+ {
222
+ style: {
223
+ fontFamily: "Fraunces, Georgia, serif",
224
+ fontSize: 13,
225
+ fontWeight: 600,
226
+ lineHeight: 1
227
+ },
228
+ children: chatbotName.charAt(0).toUpperCase()
229
+ }
230
+ ) : /* @__PURE__ */ jsx(UserCircle, { size: 14, strokeWidth: 1.6 })
231
+ }
232
+ ),
233
+ /* @__PURE__ */ jsxs(
234
+ "div",
235
+ {
236
+ className: "assistly-font-mono",
237
+ style: {
238
+ display: "flex",
239
+ alignItems: "center",
240
+ gap: 8,
241
+ fontSize: 10,
242
+ letterSpacing: "0.18em",
243
+ textTransform: "uppercase",
244
+ color: "var(--assistly-ink-mute)"
245
+ },
246
+ children: [
247
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--assistly-ink-soft)", fontWeight: 500 }, children: isSender ? chatbotName || "assistant" : "you" }),
248
+ /* @__PURE__ */ jsx(
249
+ "span",
250
+ {
251
+ style: {
252
+ width: 3,
253
+ height: 3,
254
+ borderRadius: "50%",
255
+ background: "var(--assistly-ink-mute)",
256
+ opacity: showMeta ? 1 : 0,
257
+ transition: "opacity 200ms"
258
+ }
259
+ }
260
+ ),
261
+ /* @__PURE__ */ jsx("span", { style: { opacity: showMeta ? 1 : 0, transition: "opacity 200ms" }, children: formatTime(message.created_at) })
262
+ ]
263
+ }
264
+ )
265
+ ]
382
266
  }
383
267
  ),
384
- /* @__PURE__ */ jsx3("div", { className: `chat-image avatar w-10 ${!isSender && "mr-4"}`, children: logoUrl ? /* @__PURE__ */ jsx3(
385
- "img",
386
- {
387
- src: logoUrl,
388
- alt: chatbotName || "Chatbot logo",
389
- width: 48,
390
- height: 48,
391
- className: "h-12 w-12 rounded-full border object-cover",
392
- style: { borderColor: "var(--hairline)" }
393
- }
394
- ) : isSender ? /* @__PURE__ */ jsx3(
268
+ /* @__PURE__ */ jsx(
395
269
  "div",
396
270
  {
397
- className: "border h-12 w-12 rounded-full bg-white overflow-hidden",
398
- style: { borderColor: "var(--hairline)" },
399
- children: /* @__PURE__ */ jsx3(Avatar_default, { seed: chatbotName, className: "h-12 w-12" })
400
- }
401
- ) : /* @__PURE__ */ jsx3("div", { className: "h-12 w-12 rounded-full grid place-items-center", style: { background: "rgba(244,234,215,0.06)" }, children: /* @__PURE__ */ jsx3(UserCircle, { className: "text-[var(--brass-2)]" }) }) }),
402
- isSender ? /* @__PURE__ */ jsx3(
403
- AiBubble,
404
- {
405
- springIn: isFresh,
406
- typing: isThinking,
407
- className: "chat-bubble relative rounded-2xl px-4 py-3 max-w-[80%] font-body text-[15px] leading-relaxed",
408
- style: isThinking ? {} : { border: "1px solid rgba(224,176,112,0.18)" },
409
- children: isThinking ? /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3 py-1", style: { color: "#1e1e1e" }, children: [
410
- /* @__PURE__ */ jsx3(FourDotWave, {}),
411
- /* @__PURE__ */ jsx3("span", { className: "font-mono text-[10px] uppercase tracking-[0.25em] opacity-70", children: "Thinking..." })
412
- ] }) : /* @__PURE__ */ jsx3(
271
+ className: `${isSender ? "assistly-bubble-in" : ""}`,
272
+ style: {
273
+ position: "relative",
274
+ maxWidth: "min(82%, 640px)",
275
+ padding: "12px 16px",
276
+ borderRadius: isSender ? "4px 16px 16px 16px" : "16px 4px 16px 16px",
277
+ background: isSender ? "#fffefb" : "var(--assistly-ink)",
278
+ color: isSender ? "var(--assistly-ink)" : "var(--assistly-paper)",
279
+ border: isSender ? "1px solid var(--assistly-hairline-strong)" : "1px solid var(--assistly-ink)",
280
+ boxShadow: isSender ? "0 1px 0 rgba(26,20,15,0.02), 0 8px 24px rgba(26,20,15,0.05)" : "0 1px 0 rgba(255,255,255,0.04) inset, 0 8px 24px rgba(26,20,15,0.18)",
281
+ fontSize: 15,
282
+ lineHeight: 1.6
283
+ },
284
+ children: isThinking ? /* @__PURE__ */ jsxs(
285
+ "div",
286
+ {
287
+ style: {
288
+ display: "flex",
289
+ alignItems: "center",
290
+ gap: 12,
291
+ padding: "2px 0",
292
+ minHeight: 22
293
+ },
294
+ children: [
295
+ /* @__PURE__ */ jsx("span", { className: "assistly-dot" }),
296
+ /* @__PURE__ */ jsx("span", { className: "assistly-dot" }),
297
+ /* @__PURE__ */ jsx("span", { className: "assistly-dot" }),
298
+ /* @__PURE__ */ jsx("span", { className: "assistly-dot" }),
299
+ /* @__PURE__ */ jsx(
300
+ "span",
301
+ {
302
+ className: "assistly-font-mono",
303
+ style: {
304
+ marginLeft: 4,
305
+ fontSize: 10,
306
+ letterSpacing: "0.22em",
307
+ textTransform: "uppercase",
308
+ color: "var(--assistly-ink-mute)"
309
+ },
310
+ children: "Thinking\u2026"
311
+ }
312
+ )
313
+ ]
314
+ }
315
+ ) : isSender ? /* @__PURE__ */ jsx("div", { className: "assistly-prose", children: /* @__PURE__ */ jsx(
413
316
  TypewriterMarkdown,
414
317
  {
415
318
  text: message.content,
@@ -417,38 +320,7 @@ function Messages({ messages, chatbotName, logoUrl, isReviewPage = false }) {
417
320
  components: markdownComponents,
418
321
  onType: () => scrollToBottom(false)
419
322
  }
420
- )
421
- }
422
- ) : /* @__PURE__ */ jsx3(
423
- UserBubble,
424
- {
425
- springIn: isFresh,
426
- className: "chat-bubble relative rounded-2xl px-4 py-3 max-w-[80%] font-body text-[15px] leading-relaxed",
427
- style: {
428
- background: "#e9e3e3ff",
429
- color: "#1e1e1e",
430
- border: "1px solid rgba(231, 228, 224, 0.22)"
431
- },
432
- children: /* @__PURE__ */ jsx3(
433
- ReactMarkdown,
434
- {
435
- remarkPlugins: [remarkGfm],
436
- components: markdownComponents,
437
- children: message.content
438
- }
439
- )
440
- }
441
- ),
442
- /* @__PURE__ */ jsxs2(
443
- "div",
444
- {
445
- className: `mt-1.5 px-1 flex items-center gap-2 font-mono text-[10px] uppercase tracking-[0.2em] transition-opacity duration-200 ${showMeta ? "opacity-100" : "opacity-0"}`,
446
- style: { color: "var(--muted-2)" },
447
- children: [
448
- /* @__PURE__ */ jsx3("span", { children: isSender ? chatbotName || "assistant" : "you" }),
449
- /* @__PURE__ */ jsx3("span", { className: "w-1 h-1 rounded-full", style: { background: "var(--muted-2)" } }),
450
- /* @__PURE__ */ jsx3("span", { children: formatTime(message.created_at) })
451
- ]
323
+ ) }) : /* @__PURE__ */ jsx("div", { className: "assistly-prose", children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: message.content }) })
452
324
  }
453
325
  )
454
326
  ]
@@ -456,7 +328,7 @@ function Messages({ messages, chatbotName, logoUrl, isReviewPage = false }) {
456
328
  message.id || index
457
329
  );
458
330
  }),
459
- /* @__PURE__ */ jsx3("div", { ref })
331
+ /* @__PURE__ */ jsx("div", { ref })
460
332
  ] });
461
333
  }
462
334
  var Messages_default = Messages;
@@ -480,17 +352,17 @@ function cn(...inputs) {
480
352
 
481
353
  // src/ui/label.tsx
482
354
  import * as LabelPrimitive from "@radix-ui/react-label";
483
- import { jsx as jsx4 } from "react/jsx-runtime";
355
+ import { jsx as jsx2 } from "react/jsx-runtime";
484
356
 
485
357
  // src/ui/form.tsx
486
- import { jsx as jsx5 } from "react/jsx-runtime";
358
+ import { jsx as jsx3 } from "react/jsx-runtime";
487
359
  var Form = FormProvider;
488
360
  var FormFieldContext = React2.createContext(
489
361
  {}
490
362
  );
491
363
  var FormField = (_a) => {
492
364
  var props = __objRest(_a, []);
493
- return /* @__PURE__ */ jsx5(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx5(Controller, __spreadValues({}, props)) });
365
+ return /* @__PURE__ */ jsx3(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx3(Controller, __spreadValues({}, props)) });
494
366
  };
495
367
  var useFormField = () => {
496
368
  const fieldContext = React2.useContext(FormFieldContext);
@@ -516,7 +388,7 @@ var FormItemContext = React2.createContext(
516
388
  function FormItem(_a) {
517
389
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
518
390
  const id = React2.useId();
519
- return /* @__PURE__ */ jsx5(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx5(
391
+ return /* @__PURE__ */ jsx3(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx3(
520
392
  "div",
521
393
  __spreadValues({
522
394
  "data-slot": "form-item",
@@ -527,7 +399,7 @@ function FormItem(_a) {
527
399
  function FormControl(_a) {
528
400
  var props = __objRest(_a, []);
529
401
  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
530
- return /* @__PURE__ */ jsx5(
402
+ return /* @__PURE__ */ jsx3(
531
403
  Slot,
532
404
  __spreadValues({
533
405
  "data-slot": "form-control",
@@ -539,10 +411,10 @@ function FormControl(_a) {
539
411
  }
540
412
 
541
413
  // src/ui/input.tsx
542
- import { jsx as jsx6 } from "react/jsx-runtime";
414
+ import { jsx as jsx4 } from "react/jsx-runtime";
543
415
  function Input(_a) {
544
416
  var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
545
- return /* @__PURE__ */ jsx6(
417
+ return /* @__PURE__ */ jsx4(
546
418
  "input",
547
419
  __spreadValues({
548
420
  type,
@@ -557,59 +429,8 @@ function Input(_a) {
557
429
  );
558
430
  }
559
431
 
560
- // src/ui/button.tsx
561
- import { Slot as Slot2 } from "@radix-ui/react-slot";
562
- import { cva } from "class-variance-authority";
563
- import { jsx as jsx7 } from "react/jsx-runtime";
564
- var buttonVariants = cva(
565
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
566
- {
567
- variants: {
568
- variant: {
569
- default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
570
- destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
571
- outline: "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
572
- secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
573
- ghost: "hover:bg-accent hover:text-accent-foreground",
574
- link: "text-primary underline-offset-4 hover:underline"
575
- },
576
- size: {
577
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
578
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
579
- lg: "h-10 rounded-md px-6 has-[>svg]:px-3",
580
- icon: "size-9"
581
- }
582
- },
583
- defaultVariants: {
584
- variant: "default",
585
- size: "default"
586
- }
587
- }
588
- );
589
- function Button(_a) {
590
- var _b = _a, {
591
- className,
592
- variant,
593
- size,
594
- asChild = false
595
- } = _b, props = __objRest(_b, [
596
- "className",
597
- "variant",
598
- "size",
599
- "asChild"
600
- ]);
601
- const Comp = asChild ? Slot2 : "button";
602
- return /* @__PURE__ */ jsx7(
603
- Comp,
604
- __spreadValues({
605
- "data-slot": "button",
606
- className: cn(buttonVariants({ variant, size, className }))
607
- }, props)
608
- );
609
- }
610
-
611
432
  // src/ChatbotClient.tsx
612
- import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
433
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
613
434
  var formSchema = z.object({
614
435
  message: z.string().min(3, "Your Message is too short!")
615
436
  });
@@ -622,7 +443,7 @@ function ChatbotClient({ id, chatbotName, origin }) {
622
443
  const [message, setMessage] = useState2([
623
444
  {
624
445
  id: -1,
625
- content: `Hi there! I'm ${chatbotName}. I'd love to help you out, but first, could you tell me your name?`,
446
+ content: `Hi there \u2014 I'm ${chatbotName}. I'd love to help, but first, what's your name?`,
626
447
  sender: "ai",
627
448
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
628
449
  chat_session_id: 0
@@ -630,16 +451,12 @@ function ChatbotClient({ id, chatbotName, origin }) {
630
451
  ]);
631
452
  const form = useForm({
632
453
  resolver: zodResolver(formSchema),
633
- defaultValues: {
634
- message: ""
635
- }
454
+ defaultValues: { message: "" },
455
+ mode: "onChange"
636
456
  });
637
457
  const { data } = useQuery(
638
458
  GET_MESSEGES_BY_CHAT_SESSION_ID,
639
- {
640
- variables: { chat_session_id: chatId },
641
- skip: !chatId
642
- }
459
+ { variables: { chat_session_id: chatId }, skip: !chatId }
643
460
  );
644
461
  useEffect2(() => {
645
462
  if (data && onboardingStep === 3) {
@@ -666,7 +483,7 @@ function ChatbotClient({ id, chatbotName, origin }) {
666
483
  };
667
484
  const aiMsg = {
668
485
  id: Date.now() + 1,
669
- content: `It's a pleasure to meet you, ${formMessage}! Just one more thing\u2014what's your email address so we can stay connected?`,
486
+ content: `Lovely to meet you, ${formMessage}. One more thing \u2014 what's your email so we can stay in touch?`,
670
487
  chat_session_id: 0,
671
488
  sender: "ai",
672
489
  created_at: (/* @__PURE__ */ new Date()).toISOString()
@@ -678,15 +495,13 @@ function ChatbotClient({ id, chatbotName, origin }) {
678
495
  }
679
496
  if (onboardingStep === 2) {
680
497
  if (!formMessage.trim()) return;
681
- const isValidEmail = (email2) => {
682
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email2);
683
- };
498
+ const isValidEmail = (email2) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email2);
684
499
  if (!isValidEmail(formMessage.trim())) {
685
500
  setMessage((prev) => [
686
501
  ...prev,
687
502
  {
688
503
  id: Date.now() + 1,
689
- content: "Please enter a valid email address so we can continue.",
504
+ content: "That email doesn't look quite right \u2014 could you double-check it?",
690
505
  chat_session_id: 0,
691
506
  sender: "ai",
692
507
  created_at: (/* @__PURE__ */ new Date()).toISOString()
@@ -704,16 +519,15 @@ function ChatbotClient({ id, chatbotName, origin }) {
704
519
  setMessage((prev) => [...prev, userMsg]);
705
520
  setLoading(true);
706
521
  try {
707
- const finalEmail = formMessage;
708
- setEmail(finalEmail);
709
- const newChatId = await startNewChat_default(origin, name, finalEmail, Number(id));
522
+ const newChatId = await startNewChat_default(origin, name, formMessage, Number(id));
523
+ setEmail(formMessage);
710
524
  setChatId(newChatId);
711
525
  setOnboardingStep(3);
712
526
  } catch (error) {
713
527
  console.error("Error starting chat:", error);
714
528
  setMessage((prev) => [...prev, {
715
529
  id: Date.now() + 1,
716
- content: "Sorry, I had trouble setting up your session. Could you please try entering your email again?",
530
+ content: "Sorry \u2014 I had trouble setting up your session. Mind entering your email again?",
717
531
  chat_session_id: 0,
718
532
  sender: "ai",
719
533
  created_at: (/* @__PURE__ */ new Date()).toISOString()
@@ -762,68 +576,582 @@ function ChatbotClient({ id, chatbotName, origin }) {
762
576
  console.error("Error Sending Message:", error);
763
577
  }
764
578
  }
765
- return /* @__PURE__ */ jsx8("div", { className: "fixed inset-0 flex flex-col bg-gray-50 text-slate-900 md:p-6 md:pb-0", children: /* @__PURE__ */ jsxs3("div", { className: "flex flex-col w-full max-w-3xl mx-auto flex-1 overflow-hidden md:rounded-t-2xl border border-gray-200 bg-white relative", children: [
766
- /* @__PURE__ */ jsxs3("div", { className: "border-b border-gray-100 bg-white py-3 px-4 md:py-6 md:px-8 flex items-center justify-between shrink-0", children: [
767
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center space-x-3 md:space-x-4 min-w-0", children: [
768
- /* @__PURE__ */ jsxs3("div", { className: "relative shrink-0", children: [
769
- /* @__PURE__ */ jsx8(
770
- Avatar_default,
771
- {
772
- seed: chatbotName != null ? chatbotName : "default-seed",
773
- className: "w-9 h-9 md:w-10 md:h-10 bg-gray-100 rounded-full border border-gray-200"
774
- }
775
- ),
776
- /* @__PURE__ */ jsx8("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-emerald-500 border-2 border-white rounded-full" })
777
- ] }),
778
- /* @__PURE__ */ jsxs3("div", { className: "min-w-0", children: [
779
- /* @__PURE__ */ jsx8("h1", { className: "truncate text-sm md:text-base font-semibold text-slate-900", children: chatbotName || "Assistant" }),
780
- /* @__PURE__ */ jsxs3("p", { className: "text-xs text-slate-400 flex items-center gap-1.5", children: [
781
- /* @__PURE__ */ jsx8("span", { className: "w-2 h-2 bg-emerald-500 rounded-full" }),
782
- "Online"
783
- ] })
784
- ] })
785
- ] }),
786
- /* @__PURE__ */ jsx8("div", { className: "hidden sm:block text-[11px] font-medium text-slate-400 bg-gray-50 px-2 py-1 rounded-md border border-gray-100", children: "Secure Session" })
787
- ] }),
788
- /* @__PURE__ */ jsx8("div", { className: "flex-1 relative bg-white pb-32 md:pb-36 overflow-y-auto", children: /* @__PURE__ */ jsx8(Messages_default, { messages: message, chatbotName: chatbotName || "" }) }),
789
- /* @__PURE__ */ jsx8("div", { className: "absolute bottom-0 w-full bg-white p-3 md:p-6 border-t border-gray-100", children: /* @__PURE__ */ jsx8(Form, __spreadProps(__spreadValues({}, form), { children: /* @__PURE__ */ jsxs3(
790
- "form",
791
- {
792
- className: "relative flex items-center gap-2 md:gap-3 max-w-4xl mx-auto",
793
- onSubmit: form.handleSubmit(onsubmit),
794
- children: [
795
- /* @__PURE__ */ jsx8("div", { className: "relative flex-1", children: /* @__PURE__ */ jsx8(
796
- FormField,
797
- {
798
- control: form.control,
799
- name: "message",
800
- render: ({ field }) => /* @__PURE__ */ jsx8(FormItem, { className: "flex-1", children: /* @__PURE__ */ jsx8(FormControl, { children: /* @__PURE__ */ jsx8(
801
- Input,
802
- __spreadProps(__spreadValues({}, field), {
803
- placeholder: onboardingStep === 1 ? "Your name..." : onboardingStep === 2 ? "Your email..." : "Type a message...",
804
- className: "p-3 md:p-5 rounded-xl bg-gray-50 border-gray-200 text-slate-900 placeholder:text-slate-400 focus:ring-2 focus:ring-slate-200 focus:border-slate-300 transition-all"
805
- })
806
- ) }) })
807
- }
808
- ) }),
809
- /* @__PURE__ */ jsx8(
810
- Button,
811
- {
812
- type: "submit",
813
- disabled: form.formState.isSubmitting || !form.formState.isValid || loading,
814
- className: "h-12 w-12 md:h-16 md:w-16 rounded-xl bg-slate-900 text-white hover:bg-slate-800 transition-all shrink-0",
815
- children: loading ? /* @__PURE__ */ jsx8("div", { className: "h-6 w-6 md:h-8 md:w-8 border-2 border-white border-t-transparent rounded-full animate-spin" }) : /* @__PURE__ */ jsx8("p", { className: "cursor-pointer text-sm md:text-base", children: "Send" })
816
- }
817
- )
818
- ]
819
- }
820
- ) })) })
821
- ] }) });
579
+ return /* @__PURE__ */ jsxs2(
580
+ "div",
581
+ {
582
+ style: {
583
+ position: "relative",
584
+ display: "flex",
585
+ flexDirection: "column",
586
+ width: "100%",
587
+ height: "100%",
588
+ minHeight: 520,
589
+ background: "var(--assistly-paper)",
590
+ color: "var(--assistly-ink)",
591
+ overflow: "hidden"
592
+ },
593
+ children: [
594
+ /* @__PURE__ */ jsx5("div", { className: "assistly-grain" }),
595
+ /* @__PURE__ */ jsxs2(
596
+ "header",
597
+ {
598
+ style: {
599
+ position: "relative",
600
+ zIndex: 1,
601
+ display: "flex",
602
+ alignItems: "center",
603
+ justifyContent: "space-between",
604
+ padding: "18px 24px",
605
+ background: "var(--assistly-paper)",
606
+ borderBottom: "1px solid var(--assistly-hairline)"
607
+ },
608
+ children: [
609
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 14, minWidth: 0 }, children: [
610
+ /* @__PURE__ */ jsxs2(
611
+ "div",
612
+ {
613
+ style: {
614
+ position: "relative",
615
+ width: 44,
616
+ height: 44,
617
+ borderRadius: "50%",
618
+ background: "var(--assistly-paper-2)",
619
+ border: "1px solid var(--assistly-hairline-strong)",
620
+ display: "grid",
621
+ placeItems: "center",
622
+ flexShrink: 0
623
+ },
624
+ "aria-hidden": true,
625
+ children: [
626
+ /* @__PURE__ */ jsx5(
627
+ "span",
628
+ {
629
+ style: {
630
+ fontFamily: "Fraunces, Georgia, serif",
631
+ fontSize: 19,
632
+ fontWeight: 500,
633
+ color: "var(--assistly-ink)",
634
+ letterSpacing: "-0.02em"
635
+ },
636
+ children: chatbotName.charAt(0).toUpperCase()
637
+ }
638
+ ),
639
+ /* @__PURE__ */ jsx5(
640
+ "span",
641
+ {
642
+ style: {
643
+ position: "absolute",
644
+ right: -1,
645
+ bottom: -1,
646
+ width: 12,
647
+ height: 12,
648
+ borderRadius: "50%",
649
+ background: "#5a8c5a",
650
+ border: "2px solid var(--assistly-paper)"
651
+ }
652
+ }
653
+ )
654
+ ]
655
+ }
656
+ ),
657
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
658
+ /* @__PURE__ */ jsx5(
659
+ "span",
660
+ {
661
+ className: "assistly-font-display",
662
+ style: {
663
+ fontSize: 17,
664
+ lineHeight: 1.1,
665
+ color: "var(--assistly-ink)",
666
+ whiteSpace: "nowrap",
667
+ overflow: "hidden",
668
+ textOverflow: "ellipsis"
669
+ },
670
+ children: chatbotName
671
+ }
672
+ ),
673
+ /* @__PURE__ */ jsxs2(
674
+ "span",
675
+ {
676
+ className: "assistly-font-mono",
677
+ style: {
678
+ fontSize: 10,
679
+ marginTop: 4,
680
+ letterSpacing: "0.18em",
681
+ textTransform: "uppercase",
682
+ color: "var(--assistly-ink-mute)",
683
+ display: "flex",
684
+ alignItems: "center",
685
+ gap: 6
686
+ },
687
+ children: [
688
+ /* @__PURE__ */ jsx5(
689
+ "span",
690
+ {
691
+ style: {
692
+ width: 6,
693
+ height: 6,
694
+ borderRadius: "50%",
695
+ background: "#5a8c5a",
696
+ display: "inline-block"
697
+ }
698
+ }
699
+ ),
700
+ "Online \xB7 replies in seconds"
701
+ ]
702
+ }
703
+ )
704
+ ] })
705
+ ] }),
706
+ /* @__PURE__ */ jsxs2(
707
+ "div",
708
+ {
709
+ className: "assistly-font-mono",
710
+ style: {
711
+ display: "inline-flex",
712
+ alignItems: "center",
713
+ gap: 6,
714
+ padding: "6px 10px",
715
+ fontSize: 10,
716
+ letterSpacing: "0.16em",
717
+ textTransform: "uppercase",
718
+ color: "var(--assistly-ink-soft)",
719
+ background: "var(--assistly-paper-2)",
720
+ border: "1px solid var(--assistly-hairline)",
721
+ borderRadius: 999
722
+ },
723
+ children: [
724
+ /* @__PURE__ */ jsx5(ShieldCheck, { size: 12, strokeWidth: 1.6, style: { color: "var(--assistly-brass)" } }),
725
+ "Secure"
726
+ ]
727
+ }
728
+ )
729
+ ]
730
+ }
731
+ ),
732
+ /* @__PURE__ */ jsx5(
733
+ "main",
734
+ {
735
+ className: "assistly-scroll",
736
+ style: {
737
+ position: "relative",
738
+ zIndex: 1,
739
+ flex: 1,
740
+ overflowY: "auto",
741
+ padding: "28px 20px 24px",
742
+ background: "transparent"
743
+ },
744
+ children: /* @__PURE__ */ jsx5(
745
+ "div",
746
+ {
747
+ style: {
748
+ maxWidth: 760,
749
+ margin: "0 auto",
750
+ display: "flex",
751
+ flexDirection: "column",
752
+ gap: 18
753
+ },
754
+ children: /* @__PURE__ */ jsx5(Messages_default, { messages: message, chatbotName })
755
+ }
756
+ )
757
+ }
758
+ ),
759
+ /* @__PURE__ */ jsxs2(
760
+ "footer",
761
+ {
762
+ style: {
763
+ position: "relative",
764
+ zIndex: 1,
765
+ padding: "16px 20px 22px",
766
+ background: "linear-gradient(180deg, rgba(245,241,232,0) 0%, var(--assistly-paper) 30%)",
767
+ borderTop: "1px solid var(--assistly-hairline)"
768
+ },
769
+ children: [
770
+ /* @__PURE__ */ jsx5(Form, __spreadProps(__spreadValues({}, form), { children: /* @__PURE__ */ jsxs2(
771
+ "form",
772
+ {
773
+ onSubmit: form.handleSubmit(onsubmit),
774
+ style: {
775
+ maxWidth: 760,
776
+ margin: "0 auto",
777
+ display: "flex",
778
+ alignItems: "flex-end",
779
+ gap: 10
780
+ },
781
+ children: [
782
+ /* @__PURE__ */ jsx5(
783
+ FormField,
784
+ {
785
+ control: form.control,
786
+ name: "message",
787
+ render: ({ field }) => /* @__PURE__ */ jsx5(FormItem, { style: { flex: 1, margin: 0 }, children: /* @__PURE__ */ jsx5(FormControl, { children: /* @__PURE__ */ jsx5(
788
+ "div",
789
+ {
790
+ style: {
791
+ position: "relative",
792
+ background: "#fffefb",
793
+ border: "1px solid var(--assistly-hairline-strong)",
794
+ borderRadius: 14,
795
+ boxShadow: "0 1px 0 rgba(26,20,15,0.02), 0 6px 18px rgba(26,20,15,0.04)",
796
+ transition: "border-color 180ms ease, box-shadow 180ms ease"
797
+ },
798
+ children: /* @__PURE__ */ jsx5(
799
+ Input,
800
+ __spreadProps(__spreadValues({}, field), {
801
+ placeholder: onboardingStep === 1 ? "Your name\u2026" : onboardingStep === 2 ? "Your email\u2026" : "Write a message\u2026",
802
+ style: {
803
+ width: "100%",
804
+ padding: "14px 16px",
805
+ fontSize: 15,
806
+ lineHeight: 1.5,
807
+ color: "var(--assistly-ink)",
808
+ background: "transparent",
809
+ border: "none",
810
+ outline: "none",
811
+ fontFamily: "inherit",
812
+ borderRadius: 14
813
+ },
814
+ onFocus: (e) => {
815
+ const wrap = e.currentTarget.parentElement;
816
+ wrap.style.borderColor = "var(--assistly-brass)";
817
+ wrap.style.boxShadow = "0 0 0 3px rgba(184,137,58,0.18), 0 6px 18px rgba(26,20,15,0.04)";
818
+ },
819
+ onBlur: (e) => {
820
+ const wrap = e.currentTarget.parentElement;
821
+ wrap.style.borderColor = "var(--assistly-hairline-strong)";
822
+ wrap.style.boxShadow = "0 1px 0 rgba(26,20,15,0.02), 0 6px 18px rgba(26,20,15,0.04)";
823
+ }
824
+ })
825
+ )
826
+ }
827
+ ) }) })
828
+ }
829
+ ),
830
+ /* @__PURE__ */ jsx5(
831
+ "button",
832
+ {
833
+ type: "submit",
834
+ disabled: form.formState.isSubmitting || !form.formState.isValid || loading,
835
+ className: "assistly-send",
836
+ "aria-label": "Send message",
837
+ style: {
838
+ width: 52,
839
+ height: 52,
840
+ borderRadius: 14,
841
+ border: "none",
842
+ cursor: "pointer",
843
+ display: "grid",
844
+ placeItems: "center",
845
+ flexShrink: 0
846
+ },
847
+ children: loading ? /* @__PURE__ */ jsx5(
848
+ "span",
849
+ {
850
+ style: {
851
+ width: 18,
852
+ height: 18,
853
+ border: "2px solid rgba(245,241,232,0.35)",
854
+ borderTopColor: "var(--assistly-paper)",
855
+ borderRadius: "50%",
856
+ animation: "assistly-spin 0.9s linear infinite",
857
+ display: "inline-block"
858
+ }
859
+ }
860
+ ) : /* @__PURE__ */ jsx5(Send, { size: 18, strokeWidth: 2 })
861
+ }
862
+ )
863
+ ]
864
+ }
865
+ ) })),
866
+ /* @__PURE__ */ jsxs2(
867
+ "span",
868
+ {
869
+ className: "assistly-font-mono",
870
+ style: {
871
+ display: "block",
872
+ maxWidth: 760,
873
+ margin: "10px auto 0",
874
+ fontSize: 10,
875
+ letterSpacing: "0.16em",
876
+ textTransform: "uppercase",
877
+ color: "var(--assistly-ink-mute)",
878
+ textAlign: "center"
879
+ },
880
+ children: [
881
+ /* @__PURE__ */ jsx5(ArrowUpRight, { size: 10, strokeWidth: 1.8, style: { verticalAlign: "-1px", marginRight: 4 } }),
882
+ "Powered by Assistly"
883
+ ]
884
+ }
885
+ ),
886
+ /* @__PURE__ */ jsx5("style", { children: `@keyframes assistly-spin { to { transform: rotate(360deg); } }` })
887
+ ]
888
+ }
889
+ )
890
+ ]
891
+ }
892
+ );
822
893
  }
823
894
  var ChatbotClient_default = ChatbotClient;
824
895
 
896
+ // src/lib/injectStyles.ts
897
+ var injected = false;
898
+ var injectedHash = null;
899
+ function hashCss(css) {
900
+ let h = 5381;
901
+ for (let i = 0; i < css.length; i++) {
902
+ h = (h << 5) + h ^ css.charCodeAt(i);
903
+ }
904
+ return (h >>> 0).toString(36);
905
+ }
906
+ function ensureAssistlyStyles(css) {
907
+ if (typeof document === "undefined") return;
908
+ const h = hashCss(css);
909
+ if (injected && injectedHash === h) return;
910
+ injected = true;
911
+ injectedHash = h;
912
+ document.querySelectorAll("style[data-assistly-style]").forEach((el) => el.remove());
913
+ const style = document.createElement("style");
914
+ style.setAttribute("data-assistly-style", h);
915
+ style.textContent = css;
916
+ document.head.appendChild(style);
917
+ }
918
+ var fontsInjected = false;
919
+ var FONT_HREF = "https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap";
920
+ function ensureAssistlyFonts() {
921
+ if (typeof document === "undefined") return;
922
+ if (fontsInjected) return;
923
+ if (document.querySelector("link[data-assistly-fonts]")) {
924
+ fontsInjected = true;
925
+ return;
926
+ }
927
+ const link = document.createElement("link");
928
+ link.rel = "stylesheet";
929
+ link.href = FONT_HREF;
930
+ link.setAttribute("data-assistly-fonts", "true");
931
+ document.head.appendChild(link);
932
+ fontsInjected = true;
933
+ }
934
+
935
+ // src/styles.tokens
936
+ var styles_default = `/* Assistly embed \u2014 base styles
937
+ * ------------------------------------------------------------
938
+ * This file is compiled at build time and injected into the
939
+ * consumer page on mount. It defines the design tokens the
940
+ * React components reference (shadcn-style + custom palette)
941
+ * so the widget renders identically regardless of the host
942
+ * app's Tailwind/theme configuration.
943
+ */
944
+
945
+ :root {
946
+ /* --- Paper & ink palette --------------------------------- */
947
+ --assistly-paper: #f5f1e8; /* warm bone */
948
+ --assistly-paper-2: #efe9dc; /* slightly deeper bone */
949
+ --assistly-ink: #1a140f; /* near-black, warm */
950
+ --assistly-ink-soft: #3a322a; /* secondary text */
951
+ --assistly-ink-mute: #7a7166; /* tertiary / meta */
952
+ --assistly-hairline: rgba(26, 20, 15, 0.12);
953
+ --assistly-hairline-strong: rgba(26, 20, 15, 0.22);
954
+
955
+ /* --- Brass accent --------------------------------------- */
956
+ --assistly-brass: #b8893a;
957
+ --assistly-brass-soft: #d4ad6a;
958
+
959
+ /* --- shadcn aliases consumed by button/input ------------- */
960
+ --background: var(--assistly-paper);
961
+ --foreground: var(--assistly-ink);
962
+ --primary: var(--assistly-ink);
963
+ --primary-foreground: #f5f1e8;
964
+ --secondary: var(--assistly-paper-2);
965
+ --secondary-foreground: var(--assistly-ink);
966
+ --muted: var(--assistly-paper-2);
967
+ --muted-foreground: var(--assistly-ink-mute);
968
+ --accent: var(--assistly-brass-soft);
969
+ --accent-foreground: var(--assistly-ink);
970
+ --destructive: #8a2a2a;
971
+ --border: var(--assistly-hairline-strong);
972
+ --input: var(--assistly-hairline-strong);
973
+ --ring: var(--assistly-brass);
974
+
975
+ /* --- Component-specific aliases ------------------------- */
976
+ --hairline: var(--assistly-hairline);
977
+ --brass-2: var(--assistly-brass);
978
+ --muted-2: var(--assistly-ink-mute);
979
+ --assistly-primary: var(--assistly-ink);
980
+ }
981
+
982
+ /* --- Reset inside the widget ----------------------------- */
983
+ .assistly-root,
984
+ .assistly-root * {
985
+ box-sizing: border-box;
986
+ }
987
+
988
+ .assistly-root {
989
+ font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
990
+ color: var(--assistly-ink);
991
+ line-height: 1.55;
992
+ -webkit-font-smoothing: antialiased;
993
+ -moz-osx-font-smoothing: grayscale;
994
+ text-rendering: optimizeLegibility;
995
+ }
996
+
997
+ .assistly-font-display {
998
+ font-family: 'Fraunces', 'Cormorant Garamond', 'Playfair Display', Georgia, serif;
999
+ font-weight: 500;
1000
+ letter-spacing: -0.01em;
1001
+ font-feature-settings: "ss01", "ss02";
1002
+ }
1003
+
1004
+ .assistly-font-mono {
1005
+ font-family: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
1006
+ font-feature-settings: "ss01", "cv11";
1007
+ }
1008
+
1009
+ /* --- Paper grain overlay --------------------------------- */
1010
+ .assistly-grain {
1011
+ position: absolute;
1012
+ inset: 0;
1013
+ pointer-events: none;
1014
+ opacity: 0.35;
1015
+ mix-blend-mode: multiply;
1016
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.10 0 0 0 0 0.08 0 0 0 0 0.06 0 0 0 0.08 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
1017
+ }
1018
+
1019
+ /* --- Scrollbar ------------------------------------------- */
1020
+ .assistly-scroll::-webkit-scrollbar {
1021
+ width: 6px;
1022
+ }
1023
+ .assistly-scroll::-webkit-scrollbar-track {
1024
+ background: transparent;
1025
+ }
1026
+ .assistly-scroll::-webkit-scrollbar-thumb {
1027
+ background: var(--assistly-hairline-strong);
1028
+ border-radius: 999px;
1029
+ }
1030
+ .assistly-scroll::-webkit-scrollbar-thumb:hover {
1031
+ background: var(--assistly-ink-mute);
1032
+ }
1033
+
1034
+ /* --- Typing indicator ------------------------------------ */
1035
+ .assistly-dot {
1036
+ display: inline-block;
1037
+ width: 6px;
1038
+ height: 6px;
1039
+ border-radius: 999px;
1040
+ background: var(--assistly-brass);
1041
+ animation: assistly-bounce 1.1s cubic-bezier(0.45, 0, 0.55, 1) infinite;
1042
+ }
1043
+ .assistly-dot:nth-child(2) { animation-delay: 0.12s; background: var(--assistly-ink-soft); }
1044
+ .assistly-dot:nth-child(3) { animation-delay: 0.24s; background: var(--assistly-brass-soft); }
1045
+ .assistly-dot:nth-child(4) { animation-delay: 0.36s; background: var(--assistly-ink-mute); }
1046
+
1047
+ @keyframes assistly-bounce {
1048
+ 0%, 60%, 100% { transform: translate3d(0, 0, 0); }
1049
+ 30% { transform: translate3d(0, -5px, 0); }
1050
+ }
1051
+
1052
+ /* --- Bubble entrance ------------------------------------- */
1053
+ .assistly-bubble-in {
1054
+ animation: assistly-spring 520ms cubic-bezier(0.175, 0.885, 0.32, 1.275) both;
1055
+ }
1056
+ @keyframes assistly-spring {
1057
+ 0% { transform: scale(0.94) translate3d(0, 6px, 0); opacity: 0; }
1058
+ 60% { transform: scale(1.015) translate3d(0, -1px, 0); opacity: 1; }
1059
+ 100% { transform: scale(1) translate3d(0, 0, 0); opacity: 1; }
1060
+ }
1061
+
1062
+ /* --- Status pulse ---------------------------------------- */
1063
+ .assistly-pulse {
1064
+ position: relative;
1065
+ }
1066
+ .assistly-pulse::after {
1067
+ content: '';
1068
+ position: absolute;
1069
+ inset: -3px;
1070
+ border-radius: 999px;
1071
+ background: #5a8c5a;
1072
+ opacity: 0.35;
1073
+ animation: assistly-pulse 2.4s ease-out infinite;
1074
+ }
1075
+ @keyframes assistly-pulse {
1076
+ 0% { transform: scale(0.6); opacity: 0.45; }
1077
+ 100% { transform: scale(2.2); opacity: 0; }
1078
+ }
1079
+
1080
+ /* --- Send button hover ----------------------------------- */
1081
+ .assistly-send {
1082
+ position: relative;
1083
+ background: var(--assistly-ink);
1084
+ color: var(--assistly-paper);
1085
+ transition: transform 180ms ease, background 180ms ease, box-shadow 180ms ease;
1086
+ box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset, 0 4px 14px rgba(26,20,15,0.18);
1087
+ }
1088
+ .assistly-send:hover:not(:disabled) {
1089
+ background: var(--assistly-ink-soft);
1090
+ transform: translateY(-1px);
1091
+ box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset, 0 8px 22px rgba(26,20,15,0.24);
1092
+ }
1093
+ .assistly-send:active:not(:disabled) {
1094
+ transform: translateY(0);
1095
+ box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset, 0 2px 8px rgba(26,20,15,0.18);
1096
+ }
1097
+ .assistly-send:disabled {
1098
+ opacity: 0.4;
1099
+ cursor: not-allowed;
1100
+ }
1101
+
1102
+ /* --- Markdown content ------------------------------------ */
1103
+ .assistly-prose p {
1104
+ margin: 0 0 0.6em 0;
1105
+ white-space: pre-wrap;
1106
+ }
1107
+ .assistly-prose p:last-child { margin-bottom: 0; }
1108
+ .assistly-prose ul, .assistly-prose ol {
1109
+ margin: 0.4em 0 0.6em 1.1em;
1110
+ }
1111
+ .assistly-prose li { margin-bottom: 0.25em; }
1112
+ .assistly-prose code {
1113
+ font-family: 'JetBrains Mono', ui-monospace, monospace;
1114
+ font-size: 0.88em;
1115
+ padding: 0.1em 0.35em;
1116
+ background: rgba(26, 20, 15, 0.07);
1117
+ border-radius: 3px;
1118
+ }
1119
+ .assistly-prose a {
1120
+ color: var(--assistly-brass);
1121
+ text-decoration: underline;
1122
+ text-underline-offset: 2px;
1123
+ font-weight: 500;
1124
+ }
1125
+ .assistly-prose a:hover { color: var(--assistly-ink); }
1126
+ .assistly-prose h1, .assistly-prose h2, .assistly-prose h3 {
1127
+ font-family: 'Fraunces', Georgia, serif;
1128
+ font-weight: 600;
1129
+ margin: 0.6em 0 0.3em 0;
1130
+ letter-spacing: -0.01em;
1131
+ }
1132
+ .assistly-prose h1 { font-size: 1.25em; }
1133
+ .assistly-prose h2 { font-size: 1.1em; }
1134
+ .assistly-prose h3 { font-size: 1em; }
1135
+ .assistly-prose strong { font-weight: 600; }
1136
+
1137
+ /* --- Caret for streaming --------------------------------- */
1138
+ .assistly-caret::after {
1139
+ content: '\u258D';
1140
+ display: inline-block;
1141
+ margin-left: 1px;
1142
+ color: var(--assistly-brass);
1143
+ animation: assistly-blink 1s steps(1) infinite;
1144
+ }
1145
+ @keyframes assistly-blink {
1146
+ 50% { opacity: 0; }
1147
+ }
1148
+ `;
1149
+
1150
+ // src/lib/styles.ts
1151
+ var styles_default2 = styles_default;
1152
+
825
1153
  // src/widget.tsx
826
- import { jsx as jsx9 } from "react/jsx-runtime";
1154
+ import { jsx as jsx6 } from "react/jsx-runtime";
827
1155
  function AssistlyChat({
828
1156
  chatbotId,
829
1157
  origin,
@@ -834,25 +1162,35 @@ function AssistlyChat({
834
1162
  const client = useMemo(() => createApolloClient(origin), [origin]);
835
1163
  const [mounted, setMounted] = useState3(false);
836
1164
  useEffect3(() => {
837
- setMounted(true);
838
- onReady == null ? void 0 : onReady();
839
1165
  try {
1166
+ ensureAssistlyStyles(styles_default2);
1167
+ ensureAssistlyFonts();
1168
+ setMounted(true);
1169
+ onReady == null ? void 0 : onReady();
840
1170
  } catch (err) {
841
1171
  onError == null ? void 0 : onError(err);
842
1172
  }
843
1173
  }, [onReady, onError]);
844
1174
  if (!mounted) return null;
845
- return /* @__PURE__ */ jsx9(ApolloProvider, { client, children: /* @__PURE__ */ jsx9(
1175
+ const themeVars = primaryColor ? {
1176
+ ["--assistly-brass"]: primaryColor,
1177
+ ["--assistly-primary"]: primaryColor
1178
+ } : {};
1179
+ return /* @__PURE__ */ jsx6(ApolloProvider, { client, children: /* @__PURE__ */ jsx6(
846
1180
  "div",
847
1181
  {
1182
+ className: "assistly-root",
848
1183
  style: __spreadValues({
849
1184
  width: "100%",
850
1185
  height: "100%",
851
- minHeight: 400,
1186
+ minHeight: 520,
852
1187
  display: "flex",
853
- flexDirection: "column"
854
- }, primaryColor ? { "--assistly-primary": primaryColor } : null),
855
- children: /* @__PURE__ */ jsx9(ChatbotClient_default, { id: String(chatbotId), chatbotName: "Assistant", origin })
1188
+ flexDirection: "column",
1189
+ position: "relative",
1190
+ background: "var(--assistly-paper)",
1191
+ color: "var(--assistly-ink)"
1192
+ }, themeVars),
1193
+ children: /* @__PURE__ */ jsx6(ChatbotClient_default, { id: String(chatbotId), chatbotName: "Assistant", origin })
856
1194
  }
857
1195
  ) });
858
1196
  }