@sevenfold/setto-client 0.25.1 → 0.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,32 @@
1
+ type Attachment = {
2
+ id: string;
3
+ url: string;
4
+ mimeType: string;
5
+ };
6
+ type Message = {
7
+ id?: string;
8
+ role: 'visitor' | 'assistant' | 'human' | 'system';
9
+ content: string;
10
+ reveal?: boolean;
11
+ avatarUrl?: string | null;
12
+ authorName?: string | null;
13
+ attachments?: Attachment[];
14
+ kind?: 'message' | 'navigation' | 'agent_joined';
15
+ action?: {
16
+ type: 'navigate';
17
+ url: string;
18
+ } | null;
19
+ };
1
20
  export declare function nextWordBoundary(content: string, visibleLength: number): number;
21
+ export declare function sineOut(progress: number): number;
22
+ export declare function isAtChatBottom(scrollHeight: number, scrollTop: number, clientHeight: number): boolean;
23
+ export declare function AgentJoinedEvent({ message }: {
24
+ message: Message;
25
+ }): import("react/jsx-runtime").JSX.Element;
2
26
  export declare function SiteChatMarkdown({ content, reveal }: {
3
27
  content: string;
4
28
  reveal?: boolean;
5
29
  }): import("react/jsx-runtime").JSX.Element;
6
30
  /** Responsive visitor conversation. Its drawer only contains this browser's site chats. */
7
31
  export declare function SettoChat(): import("react/jsx-runtime").JSX.Element | null;
32
+ export {};
@@ -34691,6 +34691,12 @@ function nextWordBoundary(content2, visibleLength) {
34691
34691
  const match = content2.slice(visibleLength).match(/^\s*\S+\s*/u);
34692
34692
  return Math.min(content2.length, visibleLength + (match?.[0].length ?? 1));
34693
34693
  }
34694
+ function sineOut(progress) {
34695
+ return Math.sin(Math.min(1, Math.max(0, progress)) * Math.PI / 2);
34696
+ }
34697
+ function isAtChatBottom(scrollHeight, scrollTop, clientHeight) {
34698
+ return scrollHeight - scrollTop - clientHeight <= 4;
34699
+ }
34694
34700
  function createWordRevealer(onReveal) {
34695
34701
  let target = "";
34696
34702
  let visibleLength = 0;
@@ -34824,6 +34830,19 @@ function PersonIcon() {
34824
34830
  }
34825
34831
  ) });
34826
34832
  }
34833
+ function AgentJoinedEvent({ message }) {
34834
+ return /* @__PURE__ */ jsxs("div", { className: "setto-chat__message setto-chat__message--system setto-chat__message--agent-joined", children: [
34835
+ /* @__PURE__ */ jsx(
34836
+ "span",
34837
+ {
34838
+ className: "setto-chat__avatar setto-chat__avatar--human setto-chat__avatar--joined",
34839
+ "aria-hidden": "true",
34840
+ children: message.avatarUrl ? /* @__PURE__ */ jsx("img", { src: message.avatarUrl, alt: "" }) : /* @__PURE__ */ jsx(PersonIcon, {})
34841
+ }
34842
+ ),
34843
+ /* @__PURE__ */ jsx("div", { className: "setto-chat__message-stack", children: /* @__PURE__ */ jsx("div", { className: "setto-chat__message-bubble", children: /* @__PURE__ */ jsx("span", { className: "setto-chat__message-copy", children: message.content }) }) })
34844
+ ] });
34845
+ }
34827
34846
  function StaggeredText({ children }) {
34828
34847
  return Children.map(children, (child) => {
34829
34848
  if (typeof child !== "string") return child;
@@ -35032,15 +35051,6 @@ function useChatViewport(active, logRef, pinToBottomRef, programmaticScrollRef)
35032
35051
  let scrollFrame = 0;
35033
35052
  let releaseScrollFrame = 0;
35034
35053
  const log = logRef.current;
35035
- const updatePinState = () => {
35036
- if (programmaticScrollRef.current) return;
35037
- if (!log) return;
35038
- pinToBottomRef.current = log.scrollHeight - log.scrollTop - log.clientHeight <= 96;
35039
- };
35040
- const stopFollowing = () => {
35041
- programmaticScrollRef.current = false;
35042
- pinToBottomRef.current = false;
35043
- };
35044
35054
  const update = () => {
35045
35055
  const height = Math.round(visualViewport?.height ?? window.innerHeight);
35046
35056
  const top = Math.round(visualViewport?.offsetTop ?? 0);
@@ -35076,10 +35086,6 @@ function useChatViewport(active, logRef, pinToBottomRef, programmaticScrollRef)
35076
35086
  });
35077
35087
  };
35078
35088
  update();
35079
- log?.addEventListener("scroll", updatePinState, { passive: true });
35080
- log?.addEventListener("pointerdown", stopFollowing, { passive: true });
35081
- log?.addEventListener("touchstart", stopFollowing, { passive: true });
35082
- log?.addEventListener("wheel", stopFollowing, { passive: true });
35083
35089
  visualViewport?.addEventListener("resize", update);
35084
35090
  visualViewport?.addEventListener("scroll", update);
35085
35091
  window.addEventListener("orientationchange", update);
@@ -35087,10 +35093,6 @@ function useChatViewport(active, logRef, pinToBottomRef, programmaticScrollRef)
35087
35093
  visualViewport?.removeEventListener("resize", update);
35088
35094
  visualViewport?.removeEventListener("scroll", update);
35089
35095
  window.removeEventListener("orientationchange", update);
35090
- log?.removeEventListener("scroll", updatePinState);
35091
- log?.removeEventListener("pointerdown", stopFollowing);
35092
- log?.removeEventListener("touchstart", stopFollowing);
35093
- log?.removeEventListener("wheel", stopFollowing);
35094
35096
  window.cancelAnimationFrame(scrollFrame);
35095
35097
  window.cancelAnimationFrame(releaseScrollFrame);
35096
35098
  programmaticScrollRef.current = false;
@@ -35109,6 +35111,35 @@ function useChatViewport(active, logRef, pinToBottomRef, programmaticScrollRef)
35109
35111
  };
35110
35112
  }, [active, logRef, pinToBottomRef, programmaticScrollRef]);
35111
35113
  }
35114
+ function useChatPinTracking(active, logRef, pinToBottomRef, programmaticScrollRef) {
35115
+ useEffect(() => {
35116
+ if (!active) return;
35117
+ const log = logRef.current;
35118
+ if (!log) return;
35119
+ const updatePinState = () => {
35120
+ if (programmaticScrollRef.current) return;
35121
+ pinToBottomRef.current = isAtChatBottom(
35122
+ log.scrollHeight,
35123
+ log.scrollTop,
35124
+ log.clientHeight
35125
+ );
35126
+ };
35127
+ const stopFollowing = () => {
35128
+ programmaticScrollRef.current = false;
35129
+ pinToBottomRef.current = false;
35130
+ };
35131
+ log.addEventListener("scroll", updatePinState, { passive: true });
35132
+ log.addEventListener("pointerdown", stopFollowing, { passive: true });
35133
+ log.addEventListener("touchstart", stopFollowing, { passive: true });
35134
+ log.addEventListener("wheel", stopFollowing, { passive: true });
35135
+ return () => {
35136
+ log.removeEventListener("scroll", updatePinState);
35137
+ log.removeEventListener("pointerdown", stopFollowing);
35138
+ log.removeEventListener("touchstart", stopFollowing);
35139
+ log.removeEventListener("wheel", stopFollowing);
35140
+ };
35141
+ }, [active, logRef, pinToBottomRef, programmaticScrollRef]);
35142
+ }
35112
35143
  function useDesktopPopup() {
35113
35144
  const [desktop, setDesktop] = useState(false);
35114
35145
  useEffect(() => {
@@ -35127,31 +35158,41 @@ function useChatAutoScroll(active, logRef, pinToBottomRef, programmaticScrollRef
35127
35158
  const content2 = log?.firstElementChild;
35128
35159
  if (!log || !content2) return;
35129
35160
  let frame = 0;
35130
- let lastFrame = 0;
35161
+ let startedAt = 0;
35162
+ let startTop = 0;
35163
+ let targetTop = 0;
35131
35164
  const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
35165
+ const duration = 80;
35132
35166
  const follow = (now) => {
35133
35167
  frame = 0;
35134
35168
  if (!pinToBottomRef.current) {
35135
35169
  programmaticScrollRef.current = false;
35136
35170
  return;
35137
35171
  }
35138
- const target = Math.max(0, log.scrollHeight - log.clientHeight);
35139
- const distance = target - log.scrollTop;
35140
- if (reducedMotion || Math.abs(distance) < 0.75) {
35141
- log.scrollTop = target;
35172
+ const nextTarget = Math.max(0, log.scrollHeight - log.clientHeight);
35173
+ if (!startedAt || Math.abs(nextTarget - targetTop) > 0.5) {
35174
+ startedAt = now;
35175
+ startTop = log.scrollTop;
35176
+ targetTop = nextTarget;
35177
+ }
35178
+ const distance = targetTop - startTop;
35179
+ if (reducedMotion || Math.abs(targetTop - log.scrollTop) < 0.75) {
35180
+ log.scrollTop = targetTop;
35142
35181
  programmaticScrollRef.current = false;
35143
35182
  return;
35144
35183
  }
35145
- const elapsed = lastFrame ? Math.min(34, now - lastFrame) : 16;
35146
- lastFrame = now;
35147
- const easing = 1 - Math.exp(-elapsed / 82);
35184
+ const progress = Math.min(1, (now - startedAt) / duration);
35148
35185
  programmaticScrollRef.current = true;
35149
- log.scrollTop += distance * easing;
35150
- frame = window.requestAnimationFrame(follow);
35186
+ log.scrollTop = startTop + distance * sineOut(progress);
35187
+ if (progress < 1) {
35188
+ frame = window.requestAnimationFrame(follow);
35189
+ } else {
35190
+ programmaticScrollRef.current = false;
35191
+ }
35151
35192
  };
35152
35193
  const requestFollow = () => {
35153
35194
  if (!pinToBottomRef.current || frame) return;
35154
- lastFrame = 0;
35195
+ startedAt = 0;
35155
35196
  frame = window.requestAnimationFrame(follow);
35156
35197
  };
35157
35198
  const observer = new ResizeObserver(requestFollow);
@@ -35195,6 +35236,7 @@ function SettoChat() {
35195
35236
  const desktopPopup = useDesktopPopup();
35196
35237
  useChatStyles();
35197
35238
  useChatViewport(mounted && !desktopPopup, logRef, pinToBottomRef, programmaticScrollRef);
35239
+ useChatPinTracking(mounted, logRef, pinToBottomRef, programmaticScrollRef);
35198
35240
  useChatAutoScroll(mounted, logRef, pinToBottomRef, programmaticScrollRef);
35199
35241
  const locale = i18n.language || "no";
35200
35242
  const isNo = norwegian(locale);
@@ -35615,40 +35657,42 @@ function SettoChat() {
35615
35657
  ref: logRef,
35616
35658
  "aria-live": "polite",
35617
35659
  "aria-busy": loadingConversation,
35618
- children: /* @__PURE__ */ jsx("div", { className: "setto-chat__message-list", children: messages.map((item, index2) => /* @__PURE__ */ jsxs(
35619
- "div",
35620
- {
35621
- className: `setto-chat__message setto-chat__message--${item.role}`,
35622
- children: [
35623
- item.role === "assistant" || item.role === "human" ? /* @__PURE__ */ jsx(
35624
- "span",
35625
- {
35626
- className: `setto-chat__avatar setto-chat__avatar--${item.role}`,
35627
- "aria-hidden": "true",
35628
- children: item.role === "human" && item.avatarUrl ? /* @__PURE__ */ jsx("img", { src: item.avatarUrl, alt: "" }) : item.role === "human" ? /* @__PURE__ */ jsx(PersonIcon, {}) : /* @__PURE__ */ jsx(BaristaIcon, {})
35629
- }
35630
- ) : null,
35631
- /* @__PURE__ */ jsxs("div", { className: "setto-chat__message-stack", children: [
35632
- item.role === "assistant" || item.role === "human" ? /* @__PURE__ */ jsx("span", { className: "setto-chat__speaker", children: item.role === "human" ? labels.team : "Barista" }) : null,
35633
- /* @__PURE__ */ jsxs("div", { className: "setto-chat__message-bubble", children: [
35634
- /* @__PURE__ */ jsx("div", { className: "setto-chat__message-copy", children: item.content ? item.role === "assistant" ? /* @__PURE__ */ jsx(SiteChatMarkdown, { content: item.content, reveal: item.reveal }) : item.content : /* @__PURE__ */ jsx("span", { className: "setto-chat__typing", children: "···" }) }),
35635
- item.attachments?.map((attachment) => /* @__PURE__ */ jsx(
35636
- "a",
35637
- {
35638
- className: "setto-chat__image",
35639
- href: attachment.url,
35640
- target: "_blank",
35641
- rel: "noreferrer",
35642
- children: /* @__PURE__ */ jsx("img", { src: attachment.url, alt: labels.image })
35643
- },
35644
- attachment.id
35645
- ))
35660
+ children: /* @__PURE__ */ jsx("div", { className: "setto-chat__message-list", children: messages.map(
35661
+ (item, index2) => item.role === "system" && item.kind === "agent_joined" ? /* @__PURE__ */ jsx(AgentJoinedEvent, { message: item }, item.id ?? `agent-joined-${index2}`) : /* @__PURE__ */ jsxs(
35662
+ "div",
35663
+ {
35664
+ className: `setto-chat__message setto-chat__message--${item.role}`,
35665
+ children: [
35666
+ item.role === "assistant" || item.role === "human" ? /* @__PURE__ */ jsx(
35667
+ "span",
35668
+ {
35669
+ className: `setto-chat__avatar setto-chat__avatar--${item.role}`,
35670
+ "aria-hidden": "true",
35671
+ children: item.role === "human" && item.avatarUrl ? /* @__PURE__ */ jsx("img", { src: item.avatarUrl, alt: "" }) : item.role === "human" ? /* @__PURE__ */ jsx(PersonIcon, {}) : /* @__PURE__ */ jsx(BaristaIcon, {})
35672
+ }
35673
+ ) : null,
35674
+ /* @__PURE__ */ jsxs("div", { className: "setto-chat__message-stack", children: [
35675
+ item.role === "assistant" || item.role === "human" ? /* @__PURE__ */ jsx("span", { className: "setto-chat__speaker", children: item.role === "human" ? item.authorName || labels.team : "Barista" }) : null,
35676
+ /* @__PURE__ */ jsxs("div", { className: "setto-chat__message-bubble", children: [
35677
+ /* @__PURE__ */ jsx("div", { className: "setto-chat__message-copy", children: item.content ? item.role === "assistant" ? /* @__PURE__ */ jsx(SiteChatMarkdown, { content: item.content, reveal: item.reveal }) : item.content : /* @__PURE__ */ jsx("span", { className: "setto-chat__typing", children: "···" }) }),
35678
+ item.attachments?.map((attachment) => /* @__PURE__ */ jsx(
35679
+ "a",
35680
+ {
35681
+ className: "setto-chat__image",
35682
+ href: attachment.url,
35683
+ target: "_blank",
35684
+ rel: "noreferrer",
35685
+ children: /* @__PURE__ */ jsx("img", { src: attachment.url, alt: labels.image })
35686
+ },
35687
+ attachment.id
35688
+ ))
35689
+ ] })
35646
35690
  ] })
35647
- ] })
35648
- ]
35649
- },
35650
- item.id ?? `${item.role}-${index2}`
35651
- )) })
35691
+ ]
35692
+ },
35693
+ item.id ?? `${item.role}-${index2}`
35694
+ )
35695
+ ) })
35652
35696
  }
35653
35697
  ),
35654
35698
  /* @__PURE__ */ jsxs("div", { className: "setto-chat__composer-shell", children: [
@@ -35722,7 +35766,8 @@ function useChatStyles() {
35722
35766
  .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}
35723
35767
  .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)}
35724
35768
  .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}
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}
35769
+ .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:auto;-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}
35770
+ .setto-chat__message--agent-joined{justify-content:flex-start;align-items:center;gap:.55rem;padding:.1rem .4rem;color:color-mix(in srgb,var(--setto-chat-ink) 62%,transparent);font-size:.8rem;line-height:1.4;text-align:left}.setto-chat__message--agent-joined .setto-chat__message-stack{max-width:calc(100% - 38px);align-items:flex-start}.setto-chat__message--agent-joined .setto-chat__message-bubble{min-width:0;padding:.2rem 0;background:transparent;white-space:normal}.setto-chat__avatar--joined{flex-basis:30px;width:30px;height:30px;margin:0;border-width:1px;box-shadow:0 2px 7px color-mix(in srgb,var(--setto-chat-ink) 12%,transparent)}
35726
35771
  .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)}
35727
35772
  .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}}
35728
35773
  @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}}