@sevenfold/setto-client 0.24.6 → 0.25.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.
@@ -1,6 +1,7 @@
1
+ export declare function nextWordBoundary(content: string, visibleLength: number): number;
1
2
  export declare function SiteChatMarkdown({ content, reveal }: {
2
3
  content: string;
3
4
  reveal?: boolean;
4
5
  }): import("react/jsx-runtime").JSX.Element;
5
- /** Full-viewport visitor conversation. Its drawer only contains this browser's site chats. */
6
+ /** Responsive visitor conversation. Its drawer only contains this browser's site chats. */
6
7
  export declare function SettoChat(): import("react/jsx-runtime").JSX.Element | null;
@@ -34655,9 +34655,12 @@ function remarkGfm(options) {
34655
34655
  toMarkdownExtensions.push(gfmToMarkdown(settings));
34656
34656
  }
34657
34657
  const VISITOR_KEY = "setto-chat-visitor";
34658
+ const ACTIVE_CONVERSATION_KEY = "setto-chat-active";
34659
+ const NAVIGATION_KEY = "setto-chat-navigation";
34658
34660
  const CLOSE_MS = 210;
34659
34661
  const MIN_COMPOSER_HEIGHT = 36;
34660
34662
  const MAX_COMPOSER_HEIGHT = 200;
34663
+ const DESKTOP_POPUP_QUERY = "(min-width: 701px)";
34661
34664
  function visitorId() {
34662
34665
  try {
34663
34666
  const stored = window.localStorage.getItem(VISITOR_KEY);
@@ -34669,6 +34672,69 @@ function visitorId() {
34669
34672
  return crypto.randomUUID();
34670
34673
  }
34671
34674
  }
34675
+ function activeConversationKey(siteId) {
34676
+ return `${ACTIVE_CONVERSATION_KEY}:${siteId}`;
34677
+ }
34678
+ function navigationKey(siteId) {
34679
+ return `${NAVIGATION_KEY}:${siteId}`;
34680
+ }
34681
+ function storedActiveConversation(siteId) {
34682
+ try {
34683
+ const value = window.sessionStorage.getItem(activeConversationKey(siteId));
34684
+ return value && /^[0-9a-f]{8}-[0-9a-f-]{27,}$/i.test(value) ? value : null;
34685
+ } catch {
34686
+ return null;
34687
+ }
34688
+ }
34689
+ function nextWordBoundary(content2, visibleLength) {
34690
+ if (visibleLength >= content2.length) return content2.length;
34691
+ const match = content2.slice(visibleLength).match(/^\s*\S+\s*/u);
34692
+ return Math.min(content2.length, visibleLength + (match?.[0].length ?? 1));
34693
+ }
34694
+ function createWordRevealer(onReveal) {
34695
+ let target = "";
34696
+ let visibleLength = 0;
34697
+ let timer = null;
34698
+ let finished = false;
34699
+ let settled = false;
34700
+ let resolveDrain = () => void 0;
34701
+ const drained = new Promise((resolve) => {
34702
+ resolveDrain = resolve;
34703
+ });
34704
+ const settle = () => {
34705
+ if (settled) return;
34706
+ settled = true;
34707
+ if (timer) clearTimeout(timer);
34708
+ timer = null;
34709
+ resolveDrain();
34710
+ };
34711
+ const tick = () => {
34712
+ timer = null;
34713
+ if (visibleLength < target.length) {
34714
+ visibleLength = nextWordBoundary(target, visibleLength);
34715
+ onReveal(target.slice(0, visibleLength));
34716
+ timer = setTimeout(tick, 28);
34717
+ return;
34718
+ }
34719
+ if (finished) settle();
34720
+ };
34721
+ const schedule = () => {
34722
+ if (!timer && !settled) timer = setTimeout(tick, 0);
34723
+ };
34724
+ return {
34725
+ push(next) {
34726
+ target = next;
34727
+ schedule();
34728
+ },
34729
+ finish(next) {
34730
+ if (next !== void 0) target = next;
34731
+ finished = true;
34732
+ schedule();
34733
+ return drained;
34734
+ },
34735
+ cancel: settle
34736
+ };
34737
+ }
34672
34738
  function norwegian(locale) {
34673
34739
  return locale.toLowerCase().startsWith("no");
34674
34740
  }
@@ -34761,19 +34827,9 @@ function PersonIcon() {
34761
34827
  function StaggeredText({ children }) {
34762
34828
  return Children.map(children, (child) => {
34763
34829
  if (typeof child !== "string") return child;
34764
- let wordIndex = 0;
34765
34830
  return child.split(/(\s+)/).map((part, index2) => {
34766
34831
  if (!part || /^\s+$/.test(part)) return part;
34767
- const delay = wordIndex++ % 9 * 24;
34768
- return /* @__PURE__ */ jsx(
34769
- "span",
34770
- {
34771
- className: "setto-chat__word",
34772
- style: { animationDelay: `${delay}ms` },
34773
- children: part
34774
- },
34775
- `${index2}-${part}`
34776
- );
34832
+ return /* @__PURE__ */ jsx("span", { className: "setto-chat__word", children: part }, `${index2}-${part}`);
34777
34833
  });
34778
34834
  });
34779
34835
  }
@@ -35053,6 +35109,17 @@ function useChatViewport(active, logRef, pinToBottomRef, programmaticScrollRef)
35053
35109
  };
35054
35110
  }, [active, logRef, pinToBottomRef, programmaticScrollRef]);
35055
35111
  }
35112
+ function useDesktopPopup() {
35113
+ const [desktop, setDesktop] = useState(false);
35114
+ useEffect(() => {
35115
+ const query = window.matchMedia(DESKTOP_POPUP_QUERY);
35116
+ const update = () => setDesktop(query.matches);
35117
+ update();
35118
+ query.addEventListener("change", update);
35119
+ return () => query.removeEventListener("change", update);
35120
+ }, []);
35121
+ return desktop;
35122
+ }
35056
35123
  function useChatAutoScroll(active, logRef, pinToBottomRef, programmaticScrollRef) {
35057
35124
  useEffect(() => {
35058
35125
  if (!active) return;
@@ -35112,11 +35179,12 @@ function SettoChat() {
35112
35179
  const [sending, setSending] = useState(false);
35113
35180
  const [queued, setQueued] = useState(false);
35114
35181
  const [loadingConversation, setLoadingConversation] = useState(false);
35182
+ const [humanJoined, setHumanJoined] = useState(false);
35115
35183
  const [availability, setAvailability] = useState({
35116
35184
  humanAvailable: false,
35117
35185
  avatarUrl: null
35118
35186
  });
35119
- const conversationId = useRef(null);
35187
+ const conversationId = useRef(storedActiveConversation(config.siteId));
35120
35188
  const visitor = useRef(null);
35121
35189
  const logRef = useRef(null);
35122
35190
  const pinToBottomRef = useRef(true);
@@ -35124,8 +35192,9 @@ function SettoChat() {
35124
35192
  const filesRef = useRef([]);
35125
35193
  const formId = useId();
35126
35194
  const palette = useMemo(() => chatPalette(config.brandColors), [config.brandColors]);
35195
+ const desktopPopup = useDesktopPopup();
35127
35196
  useChatStyles();
35128
- useChatViewport(mounted, logRef, pinToBottomRef, programmaticScrollRef);
35197
+ useChatViewport(mounted && !desktopPopup, logRef, pinToBottomRef, programmaticScrollRef);
35129
35198
  useChatAutoScroll(mounted, logRef, pinToBottomRef, programmaticScrollRef);
35130
35199
  const locale = i18n.language || "no";
35131
35200
  const isNo = norwegian(locale);
@@ -35137,6 +35206,7 @@ function SettoChat() {
35137
35206
  chats: "Chats",
35138
35207
  newChat: "Ny chat",
35139
35208
  placeholder: "Hva vil du spørre om?",
35209
+ humanPlaceholder: "Skriv til teamet · bruk @barista for AI",
35140
35210
  send: "Send melding",
35141
35211
  sending: "Svarer …",
35142
35212
  attach: "Legg ved bilde",
@@ -35152,6 +35222,7 @@ function SettoChat() {
35152
35222
  chats: "Chats",
35153
35223
  newChat: "New chat",
35154
35224
  placeholder: "What would you like to ask?",
35225
+ humanPlaceholder: "Message the team · use @barista for AI",
35155
35226
  send: "Send message",
35156
35227
  sending: "Replying …",
35157
35228
  attach: "Attach image",
@@ -35164,6 +35235,29 @@ function SettoChat() {
35164
35235
  function ensureVisitor() {
35165
35236
  return visitor.current ??= visitorId();
35166
35237
  }
35238
+ function rememberConversation(id) {
35239
+ conversationId.current = id;
35240
+ try {
35241
+ if (id) window.sessionStorage.setItem(activeConversationKey(config.siteId), id);
35242
+ else window.sessionStorage.removeItem(activeConversationKey(config.siteId));
35243
+ } catch {
35244
+ }
35245
+ }
35246
+ function applyConversation(next) {
35247
+ rememberConversation(next.conversationId);
35248
+ setHumanJoined(next.humanJoined);
35249
+ setMessages(next.messages);
35250
+ const navigation = [...next.messages].reverse().find((message) => message.kind === "navigation" && message.action?.type === "navigate");
35251
+ if (!navigation?.id || !navigation.action?.url) return;
35252
+ try {
35253
+ if (window.sessionStorage.getItem(navigationKey(config.siteId)) === navigation.id) return;
35254
+ const target = new URL(navigation.action.url, window.location.href);
35255
+ if (target.origin !== window.location.origin || target.href === window.location.href) return;
35256
+ window.sessionStorage.setItem(navigationKey(config.siteId), navigation.id);
35257
+ window.location.assign(target.href);
35258
+ } catch {
35259
+ }
35260
+ }
35167
35261
  async function loadChats() {
35168
35262
  const id = visitor.current;
35169
35263
  if (!id) return;
@@ -35191,9 +35285,8 @@ function SettoChat() {
35191
35285
  );
35192
35286
  if (!response.ok) return;
35193
35287
  const next = await response.json();
35194
- conversationId.current = next.conversationId;
35195
35288
  pinToBottomRef.current = true;
35196
- setMessages(next.messages);
35289
+ applyConversation(next);
35197
35290
  setDrawer(false);
35198
35291
  } finally {
35199
35292
  setLoadingConversation(false);
@@ -35258,7 +35351,7 @@ function SettoChat() {
35258
35351
  );
35259
35352
  if (!response.ok || cancelled) return;
35260
35353
  const next = await response.json();
35261
- if (!cancelled) setMessages(next.messages);
35354
+ if (!cancelled) applyConversation(next);
35262
35355
  } catch {
35263
35356
  }
35264
35357
  };
@@ -35289,6 +35382,7 @@ function SettoChat() {
35289
35382
  window.requestAnimationFrame(() => setVisible(true));
35290
35383
  ensureVisitor();
35291
35384
  void loadChats();
35385
+ if (conversationId.current) void loadConversation(conversationId.current);
35292
35386
  }
35293
35387
  function hide() {
35294
35388
  if (document.activeElement instanceof HTMLElement) document.activeElement.blur();
@@ -35305,7 +35399,8 @@ function SettoChat() {
35305
35399
  });
35306
35400
  }
35307
35401
  function startNew() {
35308
- conversationId.current = null;
35402
+ rememberConversation(null);
35403
+ setHumanJoined(false);
35309
35404
  setMessages([{ role: "assistant", content: intro(locale, settings?.displayName ?? void 0) }]);
35310
35405
  setDraft("");
35311
35406
  setQueued(false);
@@ -35343,6 +35438,7 @@ function SettoChat() {
35343
35438
  setFiles([]);
35344
35439
  setSending(true);
35345
35440
  const visitorIdValue = ensureVisitor();
35441
+ let revealer = null;
35346
35442
  try {
35347
35443
  const uploaded = [];
35348
35444
  for (const image2 of turnFiles) {
@@ -35358,7 +35454,7 @@ function SettoChat() {
35358
35454
  );
35359
35455
  if (!response2.ok) throw new Error("image_upload_failed");
35360
35456
  const body = await response2.json();
35361
- conversationId.current = body.conversationId;
35457
+ rememberConversation(body.conversationId);
35362
35458
  uploaded.push(body.attachment);
35363
35459
  }
35364
35460
  setMessages((previous2) => [
@@ -35370,6 +35466,9 @@ function SettoChat() {
35370
35466
  },
35371
35467
  { role: "assistant", content: "", reveal: true }
35372
35468
  ]);
35469
+ revealer = createWordRevealer((answer) => {
35470
+ setMessages((previous2) => replaceLastAssistant(previous2, answer));
35471
+ });
35373
35472
  const response = await fetch(
35374
35473
  `${apiUrl}/sites/${encodeURIComponent(config.siteId)}/chat/messages`,
35375
35474
  {
@@ -35386,12 +35485,18 @@ function SettoChat() {
35386
35485
  }
35387
35486
  );
35388
35487
  const headerConversation = response.headers.get("X-Setto-Conversation");
35389
- if (headerConversation) conversationId.current = headerConversation;
35488
+ if (headerConversation) rememberConversation(headerConversation);
35390
35489
  if (!response.ok) throw new Error(`chat_failed_${response.status}`);
35391
35490
  if ((response.headers.get("content-type") ?? "").includes("application/json")) {
35392
35491
  const body = await response.json();
35393
- if (body.conversationId) conversationId.current = body.conversationId;
35394
- setMessages((previous2) => replaceLastAssistant(previous2, body.answer || labels.failed));
35492
+ if (body.conversationId) rememberConversation(body.conversationId);
35493
+ if (body.humanJoined) setHumanJoined(true);
35494
+ if (body.silent) {
35495
+ revealer.cancel();
35496
+ setMessages((previous2) => removeLastEmptyAssistant(previous2));
35497
+ } else {
35498
+ await revealer.finish(body.answer || labels.failed);
35499
+ }
35395
35500
  } else {
35396
35501
  const reader = response.body?.getReader();
35397
35502
  if (!reader) throw new Error("chat_missing_stream");
@@ -35401,15 +35506,14 @@ function SettoChat() {
35401
35506
  const { done, value } = await reader.read();
35402
35507
  if (done) break;
35403
35508
  answer += decoder.decode(value, { stream: true });
35404
- setMessages((previous2) => replaceLastAssistant(previous2, answer));
35509
+ revealer.push(answer);
35405
35510
  }
35406
35511
  answer += decoder.decode();
35407
- if (!answer.trim()) {
35408
- setMessages((previous2) => replaceLastAssistant(previous2, labels.failed));
35409
- }
35512
+ await revealer.finish(answer.trim() ? answer : labels.failed);
35410
35513
  }
35411
35514
  void loadChats();
35412
35515
  } catch {
35516
+ revealer?.cancel();
35413
35517
  setMessages((previous2) => replaceLastAssistant(previous2, labels.failed));
35414
35518
  } finally {
35415
35519
  for (const image2 of turnFiles) URL.revokeObjectURL(image2.preview);
@@ -35429,7 +35533,7 @@ function SettoChat() {
35429
35533
  {
35430
35534
  className: "setto-chat__shell",
35431
35535
  role: "dialog",
35432
- "aria-modal": "true",
35536
+ "aria-modal": desktopPopup ? void 0 : true,
35433
35537
  "aria-labelledby": `${formId}-title`,
35434
35538
  children: [
35435
35539
  /* @__PURE__ */ jsx(
@@ -35556,7 +35660,7 @@ function SettoChat() {
35556
35660
  onSubmit: queueOrSend,
35557
35661
  busy: sending,
35558
35662
  queued,
35559
- placeholder: labels.placeholder,
35663
+ placeholder: humanJoined ? labels.humanPlaceholder : labels.placeholder,
35560
35664
  attachLabel: labels.attach,
35561
35665
  sendLabel: labels.send,
35562
35666
  removeLabel: labels.remove,
@@ -35599,19 +35703,29 @@ function replaceLastAssistant(messages, content2) {
35599
35703
  }
35600
35704
  return [...messages, { role: "assistant", content: content2, reveal: true }];
35601
35705
  }
35706
+ function removeLastEmptyAssistant(messages) {
35707
+ for (let index2 = messages.length - 1; index2 >= 0; index2 -= 1) {
35708
+ const current = messages[index2];
35709
+ if (current?.role === "assistant" && !current.content) {
35710
+ return [...messages.slice(0, index2), ...messages.slice(index2 + 1)];
35711
+ }
35712
+ if (current?.role !== "system") break;
35713
+ }
35714
+ return messages;
35715
+ }
35602
35716
  function useChatStyles() {
35603
35717
  useInsertionEffect(() => {
35604
35718
  const style = document.createElement("style");
35605
35719
  style.dataset.settoChat = "";
35606
35720
  style.textContent = `
35607
- .setto-chat__markdown{display:block;min-width:0;white-space:normal}.setto-chat__markdown> :first-child{margin-top:0}.setto-chat__markdown> :last-child{margin-bottom:0}.setto-chat__markdown p{margin:0 0 .72em}.setto-chat__markdown h1,.setto-chat__markdown h2,.setto-chat__markdown h3{margin:.95em 0 .36em;font-size:1em;font-weight:680;line-height:1.28;letter-spacing:-.012em}.setto-chat__markdown h1{font-size:1.08em}.setto-chat__markdown ul,.setto-chat__markdown ol{margin:.12em 0 .72em;padding-left:1.25em}.setto-chat__markdown ul{list-style:disc}.setto-chat__markdown ol{list-style:decimal}.setto-chat__markdown li{margin:.2em 0;padding-left:.08em}.setto-chat__markdown li::marker{color:color-mix(in srgb,var(--setto-chat-accent) 78%,var(--setto-chat-ink))}.setto-chat__markdown strong{font-weight:700}.setto-chat__markdown a{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--setto-chat-accent) 70%,transparent);text-decoration-thickness:1px;text-underline-offset:.16em}.setto-chat__markdown blockquote{margin:.2em 0 .72em;padding:.08em 0 .08em .7em;border-left:2px solid color-mix(in srgb,var(--setto-chat-accent) 58%,transparent);color:color-mix(in srgb,var(--setto-chat-ink) 76%,transparent)}.setto-chat__markdown hr{height:1px;margin:.85em 0;border:0;background:color-mix(in srgb,var(--setto-chat-ink) 13%,transparent)}.setto-chat__markdown code{padding:.08em .28em;border-radius:.32em;background:color-mix(in srgb,var(--setto-chat-ink) 8%,transparent);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.88em}.setto-chat__markdown pre{max-width:100%;margin:.3em 0 .78em;padding:.7em;overflow-x:auto;border-radius:.7em;background:color-mix(in srgb,var(--setto-chat-ink) 8%,transparent);white-space:pre;-webkit-overflow-scrolling:touch}.setto-chat__markdown pre code{padding:0;background:transparent}.setto-chat__table-wrap{max-width:100%;margin:.25em 0 .75em;overflow-x:auto;-webkit-overflow-scrolling:touch}.setto-chat__markdown table{width:100%;border-collapse:collapse;font-size:.88em}.setto-chat__markdown th,.setto-chat__markdown td{padding:.38em .5em;border-bottom:1px solid color-mix(in srgb,var(--setto-chat-ink) 13%,transparent);text-align:left;vertical-align:top}.setto-chat__markdown th{font-weight:680}.setto-chat__markdown-image-label{font-style:italic;color:color-mix(in srgb,var(--setto-chat-ink) 62%,transparent)}.setto-chat__word{display:inline-block}.setto-chat__markdown.is-revealing .setto-chat__word{opacity:0;transform:translateY(.14em);filter:blur(.7px);animation:setto-chat-word-in 460ms cubic-bezier(.16,1,.3,1) forwards;will-change:opacity,transform,filter}@keyframes setto-chat-word-in{to{opacity:1;transform:none;filter:none}}
35721
+ .setto-chat__markdown{display:block;min-width:0;white-space:normal}.setto-chat__markdown> :first-child{margin-top:0}.setto-chat__markdown> :last-child{margin-bottom:0}.setto-chat__markdown p{margin:0 0 .72em}.setto-chat__markdown h1,.setto-chat__markdown h2,.setto-chat__markdown h3{margin:.95em 0 .36em;font-size:1em;font-weight:680;line-height:1.28;letter-spacing:-.012em}.setto-chat__markdown h1{font-size:1.08em}.setto-chat__markdown ul,.setto-chat__markdown ol{margin:.12em 0 .72em;padding-left:1.25em}.setto-chat__markdown ul{list-style:disc}.setto-chat__markdown ol{list-style:decimal}.setto-chat__markdown li{margin:.2em 0;padding-left:.08em}.setto-chat__markdown li::marker{color:color-mix(in srgb,var(--setto-chat-accent) 78%,var(--setto-chat-ink))}.setto-chat__markdown strong{font-weight:700}.setto-chat__markdown a{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--setto-chat-accent) 70%,transparent);text-decoration-thickness:1px;text-underline-offset:.16em}.setto-chat__markdown blockquote{margin:.2em 0 .72em;padding:.08em 0 .08em .7em;border-left:2px solid color-mix(in srgb,var(--setto-chat-accent) 58%,transparent);color:color-mix(in srgb,var(--setto-chat-ink) 76%,transparent)}.setto-chat__markdown hr{height:1px;margin:.85em 0;border:0;background:color-mix(in srgb,var(--setto-chat-ink) 13%,transparent)}.setto-chat__markdown code{padding:.08em .28em;border-radius:.32em;background:color-mix(in srgb,var(--setto-chat-ink) 8%,transparent);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.88em}.setto-chat__markdown pre{max-width:100%;margin:.3em 0 .78em;padding:.7em;overflow-x:auto;border-radius:.7em;background:color-mix(in srgb,var(--setto-chat-ink) 8%,transparent);white-space:pre;-webkit-overflow-scrolling:touch}.setto-chat__markdown pre code{padding:0;background:transparent}.setto-chat__table-wrap{max-width:100%;margin:.25em 0 .75em;overflow-x:auto;-webkit-overflow-scrolling:touch}.setto-chat__markdown table{width:100%;border-collapse:collapse;font-size:.88em}.setto-chat__markdown th,.setto-chat__markdown td{padding:.38em .5em;border-bottom:1px solid color-mix(in srgb,var(--setto-chat-ink) 13%,transparent);text-align:left;vertical-align:top}.setto-chat__markdown th{font-weight:680}.setto-chat__markdown-image-label{font-style:italic;color:color-mix(in srgb,var(--setto-chat-ink) 62%,transparent)}.setto-chat__word{display:inline-block}.setto-chat__markdown.is-revealing .setto-chat__word{opacity:0;transform:translateY(.08em);filter:blur(.35px);animation:setto-chat-word-in 180ms cubic-bezier(.2,.8,.2,1) forwards;will-change:opacity,transform,filter}@keyframes setto-chat-word-in{to{opacity:1;transform:none;filter:none}}
35608
35722
  .setto-chat{position:fixed;right:max(18px,env(safe-area-inset-right));bottom:max(18px,env(safe-area-inset-bottom));z-index:2147483000;color:var(--setto-chat-ink);font-family:"Archivo Variable",Archivo,system-ui,sans-serif;-webkit-font-smoothing:antialiased}.setto-chat *,.setto-chat *::before,.setto-chat *::after{box-sizing:border-box}.setto-chat button,.setto-chat input,.setto-chat textarea{font:inherit}.setto-chat--mounted{top:0;right:auto;bottom:auto;left:0;width:100vw;height:var(--setto-chat-layout-height,100lvh);overflow:hidden;background:var(--setto-chat-canvas);opacity:0;transition:opacity ${CLOSE_MS}ms ease}.setto-chat--visible{opacity:1}.setto-chat__shell{position:absolute;top:var(--setto-chat-top,0);left:0;width:100%;height:var(--setto-chat-height,100svh);display:flex;overflow:hidden;background:var(--setto-chat-canvas);opacity:0;transform:translateY(12px) scale(.994);transform-origin:center bottom;transition:opacity ${CLOSE_MS}ms ease,transform ${CLOSE_MS}ms cubic-bezier(.16,1,.3,1)}.setto-chat--visible .setto-chat__shell{opacity:1;transform:none}
35609
35723
  .setto-chat__scrim{position:absolute;inset:0;z-index:45;border:0;background:rgba(33,23,17,.32);opacity:0;pointer-events:none;transition:opacity 220ms ease}.setto-chat__scrim.is-open{opacity:1;pointer-events:auto}.setto-chat__chats{position:relative;z-index:50;width:min(84vw,280px);height:100%;flex:0 0 280px;padding:1rem .85rem calc(1rem + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:.9rem;background:color-mix(in srgb,var(--setto-chat-crema) 32%,var(--setto-chat-canvas));border-right:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);overflow:hidden}.setto-chat__chats-heading{display:flex;align-items:center;justify-content:space-between;gap:.5rem;min-height:34px;font-size:.66rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent)}.setto-chat__chats-heading button{width:34px;height:34px;padding:0;border:0;border-radius:8px;background:transparent;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.setto-chat__new{display:flex;align-items:center;gap:.55rem;width:100%;padding:.5rem .55rem;border:0;border-radius:8px;background:transparent;color:var(--setto-chat-ink);font-weight:600;font-size:.9rem;text-align:left;cursor:pointer;transition:background 140ms ease}.setto-chat__new:hover{background:color-mix(in srgb,var(--setto-chat-ink) 5%,transparent)}.setto-chat__chat-list{display:flex;flex-direction:column;gap:.1rem;flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;margin-right:-.85rem;padding-right:.3rem}.setto-chat__chat-list p{margin:.35rem .55rem;font-size:.85rem;line-height:1.5;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent)}.setto-chat__chat-row{width:100%;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.4rem;padding:.55rem;border:0;border-radius:8px;background:transparent;color:var(--setto-chat-ink);text-align:left;cursor:pointer}.setto-chat__chat-row:hover,.setto-chat__chat-row.is-active{background:color-mix(in srgb,var(--setto-chat-ink) 7.5%,transparent)}.setto-chat__chat-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.9rem;font-weight:600}.setto-chat__chat-row time{font-size:.72rem;color:color-mix(in srgb,var(--setto-chat-ink) 55%,transparent)}
35610
35724
  .setto-chat__main{position:relative;z-index:1;display:flex;flex:1;min-width:0;max-width:820px;height:100%;margin:0 auto;flex-direction:column;background:var(--setto-chat-canvas)}.setto-chat__header{position:absolute;inset:0 0 auto;z-index:30;min-height:58px;padding:.35rem .75rem;display:flex;align-items:center;gap:.5rem;background:linear-gradient(to bottom,color-mix(in srgb,var(--setto-chat-crema) 88%,transparent),color-mix(in srgb,var(--setto-chat-crema) 72%,transparent));border-bottom:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);backdrop-filter:blur(20px) saturate(150%);-webkit-backdrop-filter:blur(20px) saturate(150%);isolation:isolate}.setto-chat__round-button{flex:none;width:46px;height:46px;padding:0;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);border-radius:50%;background:var(--setto-chat-raised);color:var(--setto-chat-ink);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background 160ms ease,border-color 160ms ease,color 160ms ease}.setto-chat__round-button:hover{background:var(--setto-chat-crema);border-color:var(--setto-chat-accent);color:var(--setto-chat-accent)}.setto-chat__round-button:active{transform:scale(.96)}.setto-chat__brand{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;line-height:1.15;text-align:center}.setto-chat__brand h2{margin:0;color:var(--setto-chat-ink);font-size:1.02rem;font-weight:600;line-height:1.15}.setto-chat__brand p{max-width:100%;margin:2px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:color-mix(in srgb,var(--setto-chat-ink) 56%,transparent);font-size:.78rem;line-height:1.15}
35611
35725
  .setto-chat__body{position:relative;display:flex;flex:1 1 auto;min-height:0;height:100%;flex-direction:column}.setto-chat__log{display:flex;flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;flex-direction:column;padding:calc(58px + 1.3rem) .75rem 8rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.setto-chat__message-list{display:flex;flex-direction:column}.setto-chat__message{--setto-chat-bubble:color-mix(in srgb,var(--setto-chat-ink) 7%,var(--setto-chat-canvas));display:flex;align-items:flex-end;gap:.55rem;width:100%;margin-bottom:1rem;color:color-mix(in srgb,var(--setto-chat-ink) 92%,transparent);font-size:16px;line-height:1.5;overflow-wrap:anywhere}.setto-chat__message-stack{display:flex;min-width:0;max-width:min(78%,36rem);flex-direction:column;align-items:flex-start}.setto-chat__message-bubble{position:relative;min-width:2.5rem;padding:.58rem .82rem;border-radius:19px 19px 19px 5px;background:var(--setto-chat-bubble);white-space:pre-wrap}.setto-chat__message--assistant .setto-chat__message-bubble::before,.setto-chat__message--human .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;left:-7px;bottom:0;width:16px;height:17px;border-bottom-right-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--assistant .setto-chat__message-bubble::after,.setto-chat__message--human .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;left:-10px;bottom:0;width:10px;height:18px;border-bottom-right-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message-copy,.setto-chat__image{position:relative;z-index:2}.setto-chat__message--visitor{--setto-chat-bubble:#0a84ff;justify-content:flex-end;color:#fff}.setto-chat__message--visitor .setto-chat__message-stack{align-items:flex-end}.setto-chat__message--visitor .setto-chat__message-bubble{border-radius:19px 19px 5px 19px}.setto-chat__message--visitor .setto-chat__message-bubble::before{content:"";position:absolute;z-index:0;right:-7px;bottom:0;width:16px;height:17px;border-bottom-left-radius:14px;background:var(--setto-chat-bubble)}.setto-chat__message--visitor .setto-chat__message-bubble::after{content:"";position:absolute;z-index:1;right:-10px;bottom:0;width:10px;height:18px;border-bottom-left-radius:10px;background:var(--setto-chat-canvas)}.setto-chat__message--system{justify-content:center;color:color-mix(in srgb,var(--setto-chat-ink) 55%,transparent);font-size:.78rem;line-height:1.45;text-align:center}.setto-chat__message--system .setto-chat__message-stack{max-width:85%;align-items:center}.setto-chat__message--system .setto-chat__message-bubble{padding:.25rem .6rem;background:transparent}.setto-chat__avatar{position:relative;z-index:3;display:grid;place-items:center;flex:0 0 34px;width:34px;height:34px;margin-bottom:1px;overflow:hidden;border:2px solid var(--setto-chat-canvas);border-radius:50%;background:var(--setto-chat-crema);color:var(--setto-chat-ink);box-shadow:0 2px 8px color-mix(in srgb,var(--setto-chat-ink) 14%,transparent)}.setto-chat__avatar--assistant{background:var(--setto-chat-accent);color:var(--setto-chat-raised)}.setto-chat__avatar img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__speaker{display:block;margin:0 0 .2rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__typing{display:inline-block;animation:setto-chat-pulse 1s ease-in-out infinite}.setto-chat__image{display:block;width:max-content;max-width:100%;margin-top:.65rem;overflow:hidden;border-radius:13px}.setto-chat__image img{display:block;width:min(280px,100%);max-height:260px;object-fit:cover}
35612
35726
  .setto-chat__composer-shell{position:absolute;left:0;right:0;bottom:0;z-index:25;display:grid;grid-template-columns:minmax(0,1fr);padding:1.5rem .75rem 0;background:transparent;isolation:isolate}.setto-chat__composer-shell::before{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom,transparent 0%,color-mix(in srgb,var(--setto-chat-canvas) 82%,transparent) 46%,var(--setto-chat-canvas) 66%);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);-webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%);mask-image:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(0,0,0,.4) 34%,rgba(0,0,0,1) 66%)}.setto-chat__composer{position:relative;z-index:1;display:flex;flex-direction:column;gap:.15rem;width:100%;min-width:0;margin:0;padding:.35rem .4rem;border:2px solid color-mix(in srgb,var(--setto-chat-ink) 10%,transparent);border-radius:24px;background:var(--setto-chat-canvas);box-shadow:0 8px 24px -16px color-mix(in srgb,var(--setto-chat-ink) 28%,transparent);transition:padding 220ms cubic-bezier(.16,1,.3,1),border-color 200ms ease,box-shadow 360ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open{padding:.55rem .5rem}.setto-chat__composer:focus-within{border-color:var(--setto-chat-accent)}.setto-chat__composer textarea,.setto-chat__composer textarea:hover,.setto-chat__composer textarea:focus,.setto-chat__composer textarea:focus-visible{width:100%;min-height:36px;max-height:200px;padding:.45rem .25rem;resize:none;-webkit-appearance:none!important;appearance:none!important;border:0!important;border-radius:0!important;outline:0!important;box-shadow:none!important;background:transparent!important;color:var(--setto-chat-ink);font-family:"Archivo Variable",Archivo,system-ui,sans-serif;font-size:16px;line-height:1.35;transition:min-height 220ms cubic-bezier(.16,1,.3,1)}.setto-chat__composer.is-open textarea{min-height:40px}.setto-chat__composer textarea::placeholder{color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent)}.setto-chat__composer-tools{display:flex;align-items:center;gap:.4rem;width:100%;min-width:0}.setto-chat__attach{flex:none;width:34px;height:34px;padding:0;border:0;border-radius:50%;background:transparent;color:color-mix(in srgb,var(--setto-chat-ink) 58%,transparent);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background 160ms ease,color 160ms ease}.setto-chat__attach:hover:not(:disabled){background:color-mix(in srgb,var(--setto-chat-ink) 6%,transparent);color:var(--setto-chat-ink)}.setto-chat__attach:disabled{opacity:.4;cursor:default}.setto-chat__send{flex:none;width:36px;height:36px;margin-left:auto;padding:0;border:0;border-radius:50%;background:var(--setto-chat-accent);color:var(--setto-chat-raised);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform 360ms cubic-bezier(.16,1,.3,1),box-shadow 360ms cubic-bezier(.16,1,.3,1),background 200ms ease,opacity 200ms ease}.setto-chat__send:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 12px 24px -12px color-mix(in srgb,var(--setto-chat-ink) 45%,transparent)}.setto-chat__send:active:not(:disabled){transform:translateY(0);box-shadow:0 4px 10px -8px color-mix(in srgb,var(--setto-chat-ink) 40%,transparent);transition-duration:90ms}.setto-chat__send:disabled{opacity:.35;cursor:default}.setto-chat__send.is-queued{animation:setto-chat-queued 1.1s ease-in-out infinite}.setto-chat__attachments{display:flex;flex-wrap:wrap;gap:.4rem;list-style:none;margin:0;padding:.15rem .15rem 0}.setto-chat__attachments li{position:relative;width:56px;height:56px;border-radius:10px;overflow:hidden;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 12%,transparent);background:var(--setto-chat-crema)}.setto-chat__attachments img{display:block;width:100%;height:100%;object-fit:cover}.setto-chat__attachments button{position:absolute;top:2px;right:2px;width:18px;height:18px;padding:0;border:0;border-radius:50%;background:color-mix(in srgb,var(--setto-chat-ink) 72%,transparent);color:#fff;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.setto-chat__composer-floor{position:relative;z-index:1;width:calc(100% + 1.5rem);height:max(.35rem,env(safe-area-inset-bottom));margin-left:-.75rem;background:var(--setto-chat-canvas)}
35613
35727
  .setto-chat__launcher{width:58px;height:58px;padding:3px;border:1px solid rgba(255,255,255,.54);border-radius:50%;background:color-mix(in srgb,var(--setto-chat-raised) 35%,transparent);box-shadow:0 10px 30px color-mix(in srgb,var(--setto-chat-ink) 24%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--setto-chat-ink) 9%,transparent);backdrop-filter:blur(14px) saturate(115%);-webkit-backdrop-filter:blur(14px) saturate(115%);color:var(--setto-chat-ink);display:grid;place-items:center;cursor:pointer;transition:transform 180ms ease,box-shadow 180ms ease}.setto-chat__launcher:hover{transform:translateY(-2px);box-shadow:0 15px 35px color-mix(in srgb,var(--setto-chat-ink) 28%,transparent),inset 0 0 0 1px color-mix(in srgb,var(--setto-chat-ink) 9%,transparent)}.setto-chat__launcher span{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;background:var(--setto-chat-accent);color:var(--setto-chat-raised)}.setto-chat__launcher img{display:block;width:50px;height:50px;border-radius:50%;object-fit:cover}.setto-chat__launcher:focus-visible,.setto-chat button:focus-visible,.setto-chat input:focus-visible{outline:2px solid var(--setto-chat-accent);outline-offset:2px}@keyframes setto-chat-pulse{50%{opacity:.35}}@keyframes setto-chat-queued{50%{opacity:.55}}
35614
- @media(max-width:700px){.setto-chat__chats{position:absolute;inset:0 auto 0 0;transform:translateX(-100%);transition:transform 260ms cubic-bezier(.16,1,.3,1);box-shadow:14px 0 35px color-mix(in srgb,var(--setto-chat-ink) 16%,transparent)}.setto-chat__chats--open{transform:none}.setto-chat__main{width:100%;max-width:none;margin:0}.setto-chat__log{padding-left:.75rem;padding-right:.75rem}}@media(min-width:700px){.setto-chat__header,.setto-chat__log{padding-left:1.25rem;padding-right:1.25rem}.setto-chat__composer-shell{padding-left:1.25rem;padding-right:1.25rem}.setto-chat__composer-floor{width:calc(100% + 2.5rem);margin-left:-1.25rem}.setto-chat__message{font-size:16.5px}}@media(prefers-reduced-motion:reduce){.setto-chat,.setto-chat__shell,.setto-chat__chats,.setto-chat__launcher,.setto-chat__composer,.setto-chat__composer textarea,.setto-chat__send{transition:none!important}.setto-chat__typing,.setto-chat__send.is-queued{animation:none}}
35728
+ @media(max-width:700px){.setto-chat__chats{position:absolute;inset:0 auto 0 0;transform:translateX(-100%);transition:transform 260ms cubic-bezier(.16,1,.3,1);box-shadow:14px 0 35px color-mix(in srgb,var(--setto-chat-ink) 16%,transparent)}.setto-chat__chats--open{transform:none}.setto-chat__main{width:100%;max-width:none;margin:0}.setto-chat__log{padding-left:.75rem;padding-right:.75rem}}@media(min-width:701px){.setto-chat--mounted{top:auto;right:max(18px,env(safe-area-inset-right));bottom:max(18px,env(safe-area-inset-bottom));left:auto;width:min(440px,calc(100vw - 36px));height:min(720px,calc(100dvh - 36px));overflow:visible;background:transparent}.setto-chat__shell{position:relative;top:auto;left:auto;width:100%;height:100%;border:1px solid color-mix(in srgb,var(--setto-chat-ink) 14%,transparent);border-radius:26px;background:var(--setto-chat-canvas);box-shadow:0 28px 80px -24px color-mix(in srgb,var(--setto-chat-ink) 42%,transparent),0 8px 24px -12px color-mix(in srgb,var(--setto-chat-ink) 24%,transparent);transform:translateY(16px) scale(.975);transform-origin:right bottom}.setto-chat--visible .setto-chat__shell{transform:none}.setto-chat__chats{position:absolute;inset:0 auto 0 0;width:min(82%,280px);height:100%;transform:translateX(-100%);transition:transform 260ms cubic-bezier(.16,1,.3,1);box-shadow:14px 0 35px color-mix(in srgb,var(--setto-chat-ink) 16%,transparent)}.setto-chat__chats--open{transform:none}.setto-chat__main{width:100%;max-width:none;margin:0}.setto-chat__header,.setto-chat__log{padding-left:.9rem;padding-right:.9rem}.setto-chat__composer-shell{padding-left:.9rem;padding-right:.9rem}.setto-chat__composer-floor{width:calc(100% + 1.8rem);height:.45rem;margin-left:-.9rem}.setto-chat__message{font-size:15.5px}.setto-chat__message-stack{max-width:82%}}@media(prefers-reduced-motion:reduce){.setto-chat,.setto-chat__shell,.setto-chat__chats,.setto-chat__launcher,.setto-chat__composer,.setto-chat__composer textarea,.setto-chat__send{transition:none!important}.setto-chat__typing,.setto-chat__send.is-queued{animation:none}}
35615
35729
  `;
35616
35730
  style.textContent += "@media(prefers-reduced-motion:reduce){.setto-chat__markdown.is-revealing .setto-chat__word{opacity:1;transform:none;filter:none;animation:none}}";
35617
35731
  document.head.appendChild(style);