@sevenfold/setto-client 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,71 @@
1
+ import { type CSSProperties } from 'react';
2
+ /**
3
+ * Barista in the site's own colours, light or dark as the page is now
4
+ * (Simon, 2026-09-25).
5
+ *
6
+ * It used to take the brand colours by position — the first was the soft
7
+ * surface, the fourth the text — which was setto.no's own order and nobody
8
+ * else's: one site got a purple canvas, and the many that write their brand
9
+ * colours as `hsl(var(--primary))` got setto.no's coffee instead. And it had
10
+ * no dark mode at all.
11
+ *
12
+ * So it reads the page, as the page is drawn right now:
13
+ *
14
+ * 1. A site with the shadcn tokens (every template since August) is read by
15
+ * role — `--background`, `--card`, `--muted`, `--foreground`,
16
+ * `--primary` and `--primary-foreground` — resolved on `<html>`,
17
+ * so `.dark` is already applied.
18
+ * 2. Otherwise the page's own ground and text: the computed background and
19
+ * colour of `<body>`, and the accent picked from the brand colours as the
20
+ * most colourful one that stands out from that ground.
21
+ * 3. Otherwise Setto's crema and terracotta.
22
+ *
23
+ * Read again whenever `<html>` or `<body>` changes class, style or data (a
24
+ * theme toggle, `data-sky`) and when the
25
+ * system switches light and dark.
26
+ */
27
+ export interface ChatPalette {
28
+ canvas: string;
29
+ raised: string;
30
+ crema: string;
31
+ ink: string;
32
+ accent: string;
33
+ onAccent: string;
34
+ dark: boolean;
35
+ }
36
+ type Rgba = [number, number, number, number];
37
+ export declare const FALLBACK: ChatPalette;
38
+ export declare function paletteStyle(p: ChatPalette): CSSProperties;
39
+ export declare function rgbString([r, g, b, a]: Rgba): string;
40
+ export declare function luminance([r, g, b]: Rgba): number;
41
+ export declare function contrast(a: Rgba, b: Rgba): number;
42
+ /** How colourful: the spread of the channels, 0 for a grey. */
43
+ export declare function chroma([r, g, b]: Rgba): number;
44
+ /** `a` over `b`, `amount` of the way. */
45
+ export declare function mix(a: Rgba, b: Rgba, amount: number): Rgba;
46
+ /** A shadcn token as a CSS colour: a bare `h s% l%` triplet (with or without `/ alpha`), or a colour already. */
47
+ export declare function tokenColor(raw: string): string | null;
48
+ /**
49
+ * The palette for a ground, a text colour, the site's tokens where it has
50
+ * them, and brand colours to take an accent from where it has not. Pure: the
51
+ * hook below does the reading.
52
+ */
53
+ export declare function buildPalette(input: {
54
+ background: Rgba | null;
55
+ foreground: Rgba | null;
56
+ card?: Rgba | null;
57
+ muted?: Rgba | null;
58
+ primary?: Rgba | null;
59
+ primaryForeground?: Rgba | null;
60
+ brand?: Rgba[];
61
+ }): ChatPalette;
62
+ /** Any CSS colour the browser understands, as sRGB: drawn on one pixel and read back. */
63
+ export declare function toRgba(color: string | null | undefined): Rgba | null;
64
+ export declare function readPalette(brandColors: Array<{
65
+ value: string;
66
+ }> | undefined): ChatPalette;
67
+ /** The palette, kept in step with the page's light and dark. */
68
+ export declare function useSitePalette(brandColors: Array<{
69
+ value: string;
70
+ }> | undefined): CSSProperties;
71
+ export {};
@@ -5869,8 +5869,8 @@ var Push = class {
5869
5869
  * @param {() => Record<string, unknown>} payload - The payload, for example `{user_id: 123}`
5870
5870
  * @param {number} timeout - The push timeout in milliseconds
5871
5871
  */
5872
- constructor(channel, event, payload, timeout) {
5873
- this.channel = channel;
5872
+ constructor(channel2, event, payload, timeout) {
5873
+ this.channel = channel2;
5874
5874
  this.event = event;
5875
5875
  this.payload = payload || function() {
5876
5876
  return {};
@@ -6590,12 +6590,12 @@ var Presence = class _Presence {
6590
6590
  * @param {Channel} channel - The Channel
6591
6591
  * @param {PresenceOptions} [opts] - The options, for example `{events: {state: "state", diff: "diff"}}`
6592
6592
  */
6593
- constructor(channel, opts = {}) {
6593
+ constructor(channel2, opts = {}) {
6594
6594
  let events = opts.events || /** @type {PresenceEvents} */
6595
6595
  { state: "presence_state", diff: "presence_diff" };
6596
6596
  this.state = {};
6597
6597
  this.pendingDiffs = [];
6598
- this.channel = channel;
6598
+ this.channel = channel2;
6599
6599
  this.joinRef = null;
6600
6600
  this.caller = {
6601
6601
  onJoin: function() {
@@ -7402,9 +7402,9 @@ var Socket = class {
7402
7402
  * @param {unknown} [reason] underlying close/error event forwarded to channel error listeners
7403
7403
  */
7404
7404
  triggerChanError(reason) {
7405
- this.channels.forEach((channel) => {
7406
- if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {
7407
- channel.trigger(CHANNEL_EVENTS.error, reason);
7405
+ this.channels.forEach((channel2) => {
7406
+ if (!(channel2.isErrored() || channel2.isLeaving() || channel2.isClosed())) {
7407
+ channel2.trigger(CHANNEL_EVENTS.error, reason);
7408
7408
  }
7409
7409
  });
7410
7410
  }
@@ -7433,9 +7433,9 @@ var Socket = class {
7433
7433
  *
7434
7434
  * @param {Channel} channel
7435
7435
  */
7436
- remove(channel) {
7437
- this.off(channel.stateChangeRefs);
7438
- this.channels = this.channels.filter((c) => c !== channel);
7436
+ remove(channel2) {
7437
+ this.off(channel2.stateChangeRefs);
7438
+ this.channels = this.channels.filter((c) => c !== channel2);
7439
7439
  }
7440
7440
  /**
7441
7441
  * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
@@ -7540,11 +7540,11 @@ var Socket = class {
7540
7540
  }
7541
7541
  if (this.hasLogger()) this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`.trim(), payload);
7542
7542
  for (let i = 0; i < this.channels.length; i++) {
7543
- const channel = this.channels[i];
7544
- if (!channel.isMember(topic, event, payload, join_ref)) {
7543
+ const channel2 = this.channels[i];
7544
+ if (!channel2.isMember(topic, event, payload, join_ref)) {
7545
7545
  continue;
7546
7546
  }
7547
- channel.trigger(event, payload, ref, join_ref);
7547
+ channel2.trigger(event, payload, ref, join_ref);
7548
7548
  }
7549
7549
  this.triggerStateCallbacks("message", msg);
7550
7550
  });
@@ -7578,19 +7578,19 @@ var Socket = class {
7578
7578
  }
7579
7579
  };
7580
7580
  class PresenceAdapter {
7581
- constructor(channel, opts) {
7581
+ constructor(channel2, opts) {
7582
7582
  const phoenixOptions = phoenixPresenceOptions(opts);
7583
- this.presence = new Presence(channel.getChannel(), phoenixOptions);
7583
+ this.presence = new Presence(channel2.getChannel(), phoenixOptions);
7584
7584
  this.presence.onJoin((key, currentPresence, newPresence) => {
7585
7585
  const onJoinPayload = PresenceAdapter.onJoinPayload(key, currentPresence, newPresence);
7586
- channel.getChannel().trigger("presence", onJoinPayload);
7586
+ channel2.getChannel().trigger("presence", onJoinPayload);
7587
7587
  });
7588
7588
  this.presence.onLeave((key, currentPresence, leftPresence) => {
7589
7589
  const onLeavePayload = PresenceAdapter.onLeavePayload(key, currentPresence, leftPresence);
7590
- channel.getChannel().trigger("presence", onLeavePayload);
7590
+ channel2.getChannel().trigger("presence", onLeavePayload);
7591
7591
  });
7592
7592
  this.presence.onSync(() => {
7593
- channel.getChannel().trigger("presence", { event: "sync" });
7593
+ channel2.getChannel().trigger("presence", { event: "sync" });
7594
7594
  });
7595
7595
  }
7596
7596
  get state() {
@@ -7692,8 +7692,8 @@ class RealtimePresence {
7692
7692
  * })
7693
7693
  * ```
7694
7694
  */
7695
- constructor(channel, opts) {
7696
- this.channel = channel;
7695
+ constructor(channel2, opts) {
7696
+ this.channel = channel2;
7697
7697
  this.presenceAdapter = new PresenceAdapter(this.channel.channelAdapter, opts);
7698
7698
  }
7699
7699
  }
@@ -8842,10 +8842,10 @@ Option 2: Install and provide the "ws" package:
8842
8842
  *
8843
8843
  * @category Realtime
8844
8844
  */
8845
- async removeChannel(channel) {
8846
- const status = await channel.unsubscribe();
8845
+ async removeChannel(channel2) {
8846
+ const status = await channel2.unsubscribe();
8847
8847
  if (status === "ok") {
8848
- channel.teardown();
8848
+ channel2.teardown();
8849
8849
  }
8850
8850
  return status;
8851
8851
  }
@@ -8855,9 +8855,9 @@ Option 2: Install and provide the "ws" package:
8855
8855
  * @category Realtime
8856
8856
  */
8857
8857
  async removeAllChannels() {
8858
- const promises = this.channels.map(async (channel) => {
8859
- const result2 = await channel.unsubscribe();
8860
- channel.teardown();
8858
+ const promises = this.channels.map(async (channel2) => {
8859
+ const result2 = await channel2.unsubscribe();
8860
+ channel2.teardown();
8861
8861
  return result2;
8862
8862
  });
8863
8863
  const result = await Promise.all(promises);
@@ -9007,8 +9007,8 @@ Option 2: Install and provide the "ws" package:
9007
9007
  *
9008
9008
  * @internal
9009
9009
  */
9010
- _remove(channel) {
9011
- this.channels = this.channels.filter((c) => c.topic !== channel.topic);
9010
+ _remove(channel2) {
9011
+ this.channels = this.channels.filter((c) => c.topic !== channel2.topic);
9012
9012
  if (this.channels.length === 0) {
9013
9013
  this.log("transport", "no channels remaining, scheduling disconnect");
9014
9014
  this._schedulePendingDisconnect();
@@ -9066,14 +9066,14 @@ Option 2: Install and provide the "ws" package:
9066
9066
  }
9067
9067
  if (this.accessTokenValue != tokenToSend) {
9068
9068
  this.accessTokenValue = tokenToSend;
9069
- this.channels.forEach((channel) => {
9069
+ this.channels.forEach((channel2) => {
9070
9070
  const payload = {
9071
9071
  access_token: tokenToSend,
9072
9072
  version: DEFAULT_VERSION
9073
9073
  };
9074
- tokenToSend && channel.updateJoinPayload(payload);
9075
- if (channel.joinedOnce && channel.channelAdapter.isJoined()) {
9076
- channel.channelAdapter.push(CHANNEL_EVENTS$1.access_token, {
9074
+ tokenToSend && channel2.updateJoinPayload(payload);
9075
+ if (channel2.joinedOnce && channel2.channelAdapter.isJoined()) {
9076
+ channel2.channelAdapter.push(CHANNEL_EVENTS$1.access_token, {
9077
9077
  access_token: tokenToSend
9078
9078
  });
9079
9079
  }
@@ -20680,8 +20680,8 @@ var SupabaseClient = class {
20680
20680
  * supabase.removeChannel(myChannel)
20681
20681
  * ```
20682
20682
  */
20683
- removeChannel(channel) {
20684
- return this.realtime.removeChannel(channel);
20683
+ removeChannel(channel2) {
20684
+ return this.realtime.removeChannel(channel2);
20685
20685
  }
20686
20686
  /**
20687
20687
  * Unsubscribes and removes all Realtime channels from Realtime client.
@@ -22320,6 +22320,184 @@ function EditModeShell({ children, themeStore, active, menu = active }) {
22320
22320
  active && sectionToolbarRoot && themeStore && SectionTools ? createPortal(/* @__PURE__ */ jsx(SectionTools, {}), sectionToolbarRoot) : null
22321
22321
  ] });
22322
22322
  }
22323
+ const FALLBACK = {
22324
+ canvas: "rgb(255 255 255)",
22325
+ raised: "rgb(250 246 238)",
22326
+ crema: "rgb(242 235 223)",
22327
+ ink: "rgb(33 23 17)",
22328
+ accent: "rgb(196 80 42)",
22329
+ onAccent: "rgb(250 246 238)",
22330
+ dark: false
22331
+ };
22332
+ function paletteStyle(p) {
22333
+ return {
22334
+ "--setto-chat-canvas": p.canvas,
22335
+ "--setto-chat-raised": p.raised,
22336
+ "--setto-chat-crema": p.crema,
22337
+ "--setto-chat-ink": p.ink,
22338
+ "--setto-chat-accent": p.accent,
22339
+ "--setto-chat-on-accent": p.onAccent,
22340
+ colorScheme: p.dark ? "dark" : "light"
22341
+ };
22342
+ }
22343
+ function rgbString([r, g, b, a]) {
22344
+ return a >= 1 ? `rgb(${r} ${g} ${b})` : `rgb(${r} ${g} ${b} / ${Math.round(a * 1e3) / 1e3})`;
22345
+ }
22346
+ function channel(v) {
22347
+ const c = v / 255;
22348
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
22349
+ }
22350
+ function luminance([r, g, b]) {
22351
+ return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
22352
+ }
22353
+ function contrast(a, b) {
22354
+ const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
22355
+ return (hi + 0.05) / (lo + 0.05);
22356
+ }
22357
+ function chroma([r, g, b]) {
22358
+ return (Math.max(r, g, b) - Math.min(r, g, b)) / 255;
22359
+ }
22360
+ function mix(a, b, amount) {
22361
+ const t = Math.max(0, Math.min(1, amount));
22362
+ return [0, 1, 2].map((i) => Math.round(a[i] * t + b[i] * (1 - t))).concat(1);
22363
+ }
22364
+ function tokenColor(raw) {
22365
+ const value = raw.trim();
22366
+ if (!value) return null;
22367
+ if (/^-?[\d.]+(deg)?\s+[\d.]+%\s+[\d.]+%(\s*\/\s*[\d.]+%?)?$/.test(value)) return `hsl(${value})`;
22368
+ return value;
22369
+ }
22370
+ function buildPalette(input) {
22371
+ const canvas = input.background && input.background[3] > 0.5 ? input.background : null;
22372
+ if (!canvas) return FALLBACK;
22373
+ const dark = luminance(canvas) < 0.2;
22374
+ const ink = input.foreground && contrast(input.foreground, canvas) >= 3 ? input.foreground : dark ? [245, 242, 236, 1] : [33, 23, 17, 1];
22375
+ const raised = input.card && input.card[3] > 0.5 ? input.card : mix(ink, canvas, dark ? 0.06 : 0.025);
22376
+ const crema = input.muted && input.muted[3] > 0.5 ? input.muted : mix(ink, canvas, dark ? 0.1 : 0.05);
22377
+ let accent = input.primary && input.primary[3] > 0.5 && contrast(input.primary, canvas) >= 1.8 ? input.primary : null;
22378
+ if (!accent) {
22379
+ const candidates = (input.brand ?? []).filter((c) => c[3] > 0.5 && contrast(c, canvas) >= 2.2 && chroma(c) > 0.18);
22380
+ accent = candidates.sort((a, b) => chroma(b) * contrast(b, canvas) - chroma(a) * contrast(a, canvas))[0] ?? null;
22381
+ }
22382
+ if (!accent) accent = dark ? [224, 122, 88, 1] : [196, 80, 42, 1];
22383
+ const white = [255, 255, 255, 1];
22384
+ const black = [17, 12, 9, 1];
22385
+ const onAccent = input.primaryForeground && accent === input.primary && contrast(input.primaryForeground, accent) >= 3 ? input.primaryForeground : contrast(white, accent) >= contrast(black, accent) ? white : black;
22386
+ return {
22387
+ canvas: rgbString(canvas),
22388
+ raised: rgbString(raised),
22389
+ crema: rgbString(crema),
22390
+ ink: rgbString(ink),
22391
+ accent: rgbString(accent),
22392
+ onAccent: rgbString(onAccent),
22393
+ dark
22394
+ };
22395
+ }
22396
+ let probe;
22397
+ function toRgba(color2) {
22398
+ if (!color2) return null;
22399
+ const value = color2.trim();
22400
+ if (!value || value === "transparent") return value === "transparent" ? [0, 0, 0, 0] : null;
22401
+ if (typeof CSS !== "undefined" && CSS.supports && !CSS.supports("color", value)) return null;
22402
+ if (probe === void 0) {
22403
+ try {
22404
+ const el = document.createElement("canvas");
22405
+ el.width = el.height = 1;
22406
+ probe = el.getContext("2d", { willReadFrequently: true });
22407
+ } catch {
22408
+ probe = null;
22409
+ }
22410
+ }
22411
+ if (!probe) return null;
22412
+ probe.clearRect(0, 0, 1, 1);
22413
+ probe.fillStyle = "#000";
22414
+ probe.fillStyle = value;
22415
+ probe.fillRect(0, 0, 1, 1);
22416
+ const [r, g, b, a] = probe.getImageData(0, 0, 1, 1).data;
22417
+ return [r, g, b, a / 255];
22418
+ }
22419
+ function readTokens() {
22420
+ const root2 = getComputedStyle(document.documentElement);
22421
+ const token = (name2) => toRgba(tokenColor(root2.getPropertyValue(name2)));
22422
+ const background = token("--background");
22423
+ const foreground = token("--foreground");
22424
+ if (!background || !foreground) return null;
22425
+ return {
22426
+ background,
22427
+ foreground,
22428
+ card: token("--card"),
22429
+ muted: token("--muted") ?? token("--secondary"),
22430
+ primary: token("--primary"),
22431
+ primaryForeground: token("--primary-foreground")
22432
+ };
22433
+ }
22434
+ function settled(el, property, now) {
22435
+ try {
22436
+ for (const animation of el.getAnimations?.() ?? []) {
22437
+ if (animation.transitionProperty !== property) continue;
22438
+ const frames = animation.effect?.getKeyframes() ?? [];
22439
+ const end = frames.at(-1)?.[property === "color" ? "color" : "backgroundColor"];
22440
+ if (typeof end === "string" && end) return end;
22441
+ }
22442
+ } catch {
22443
+ }
22444
+ return now;
22445
+ }
22446
+ function readGround() {
22447
+ const bodyEl = document.body;
22448
+ const htmlEl = document.documentElement;
22449
+ const body = getComputedStyle(bodyEl);
22450
+ const html2 = getComputedStyle(htmlEl);
22451
+ let background = toRgba(settled(bodyEl, "background-color", body.backgroundColor));
22452
+ if (!background || background[3] < 0.5) background = toRgba(settled(htmlEl, "background-color", html2.backgroundColor));
22453
+ if (!background || background[3] < 0.5) {
22454
+ background = /dark/.test(html2.colorScheme ?? "") ? [18, 18, 18, 1] : [255, 255, 255, 1];
22455
+ }
22456
+ return { background, foreground: toRgba(settled(bodyEl, "color", body.color)) };
22457
+ }
22458
+ function readPalette(brandColors) {
22459
+ try {
22460
+ const tokens = readTokens();
22461
+ if (tokens) return buildPalette(tokens);
22462
+ const brand = (brandColors ?? []).map((c) => toRgba(c.value)).filter((c) => c !== null);
22463
+ return buildPalette({ ...readGround(), brand });
22464
+ } catch {
22465
+ return FALLBACK;
22466
+ }
22467
+ }
22468
+ function useSitePalette(brandColors) {
22469
+ const [palette, setPalette] = useState(() => typeof document === "undefined" ? FALLBACK : readPalette(brandColors));
22470
+ useEffect(() => {
22471
+ let frame = 0;
22472
+ let last = "";
22473
+ const read = () => {
22474
+ cancelAnimationFrame(frame);
22475
+ frame = requestAnimationFrame(() => {
22476
+ const next = readPalette(brandColors);
22477
+ const key = JSON.stringify(next);
22478
+ if (key !== last) {
22479
+ last = key;
22480
+ setPalette(next);
22481
+ }
22482
+ });
22483
+ };
22484
+ read();
22485
+ const watch = new MutationObserver(read);
22486
+ const attributes = { attributes: true, attributeFilter: ["class", "style", "data-theme", "data-ground", "data-sky", "data-mode"] };
22487
+ watch.observe(document.documentElement, attributes);
22488
+ watch.observe(document.body, attributes);
22489
+ const system = window.matchMedia?.("(prefers-color-scheme: dark)");
22490
+ system?.addEventListener?.("change", read);
22491
+ window.addEventListener("load", read);
22492
+ return () => {
22493
+ cancelAnimationFrame(frame);
22494
+ watch.disconnect();
22495
+ system?.removeEventListener?.("change", read);
22496
+ window.removeEventListener("load", read);
22497
+ };
22498
+ }, [brandColors]);
22499
+ return paletteStyle(palette);
22500
+ }
22323
22501
  function ok$1() {
22324
22502
  }
22325
22503
  function unreachable() {
@@ -35125,14 +35303,14 @@ function createWordRevealer(onReveal) {
35125
35303
  let visibleLength = 0;
35126
35304
  let timer = null;
35127
35305
  let finished = false;
35128
- let settled = false;
35306
+ let settled2 = false;
35129
35307
  let resolveDrain = () => void 0;
35130
35308
  const drained = new Promise((resolve) => {
35131
35309
  resolveDrain = resolve;
35132
35310
  });
35133
35311
  const settle = () => {
35134
- if (settled) return;
35135
- settled = true;
35312
+ if (settled2) return;
35313
+ settled2 = true;
35136
35314
  if (timer) clearTimeout(timer);
35137
35315
  timer = null;
35138
35316
  resolveDrain();
@@ -35148,7 +35326,7 @@ function createWordRevealer(onReveal) {
35148
35326
  if (finished) settle();
35149
35327
  };
35150
35328
  const schedule = () => {
35151
- if (!timer && !settled) timer = setTimeout(tick, 0);
35329
+ if (!timer && !settled2) timer = setTimeout(tick, 0);
35152
35330
  };
35153
35331
  return {
35154
35332
  push(next) {
@@ -35170,19 +35348,6 @@ function norwegian(locale) {
35170
35348
  function intro(locale, name2, agent = "Barista") {
35171
35349
  return norwegian(locale) ? `Hei! Jeg er ${agent}, ${name2 ? `${name2}s` : "nettstedets"} AI-assistent. Jeg svarer ut fra det teamet har delt her, og hjelper deg videre til dem når det trengs.` : `Hello! I’m ${agent}, the AI assistant for ${name2 ?? "this website"}. I answer from what the team has shared here and help you reach them when needed.`;
35172
35350
  }
35173
- function validColor(value, fallback) {
35174
- return value && (/^#[0-9a-f]{3,8}$/i.test(value) || /^rgba?\(/i.test(value)) ? value : fallback;
35175
- }
35176
- function chatPalette(colors) {
35177
- const values = colors?.map((color2) => color2.value) ?? [];
35178
- return {
35179
- "--setto-chat-crema": validColor(values[0], "#F2EBDF"),
35180
- "--setto-chat-raised": validColor(values[1], "#FAF6EE"),
35181
- "--setto-chat-canvas": validColor(values[2], "#FFFFFF"),
35182
- "--setto-chat-ink": validColor(values[3], "#211711"),
35183
- "--setto-chat-accent": validColor(values.at(-2) ?? values.at(-1), "#C4502A")
35184
- };
35185
- }
35186
35351
  function MenuIcon() {
35187
35352
  return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
35188
35353
  "path",
@@ -35708,11 +35873,11 @@ function useConversationChannel(supabase, topic, handlers2) {
35708
35873
  useEffect(() => {
35709
35874
  if (!topic) return;
35710
35875
  let active = true;
35711
- let channel = null;
35876
+ let channel2 = null;
35712
35877
  let changedTimer = 0;
35713
35878
  const join2 = () => {
35714
35879
  if (!active) return;
35715
- channel = supabase.channel(topic).on("broadcast", { event: "changed" }, () => {
35880
+ channel2 = supabase.channel(topic).on("broadcast", { event: "changed" }, () => {
35716
35881
  window.clearTimeout(changedTimer);
35717
35882
  changedTimer = window.setTimeout(
35718
35883
  () => handlersRef.current.onChanged(),
@@ -35725,8 +35890,8 @@ function useConversationChannel(supabase, topic, handlers2) {
35725
35890
  const signal = parseTypingSignal(message.payload);
35726
35891
  if (signal) handlersRef.current.onTyping(signal);
35727
35892
  });
35728
- channelRef.current = channel;
35729
- channel.subscribe((status) => {
35893
+ channelRef.current = channel2;
35894
+ channel2.subscribe((status) => {
35730
35895
  if (active) handlersRef.current.onStatus(status === "SUBSCRIBED");
35731
35896
  });
35732
35897
  };
@@ -35736,11 +35901,11 @@ function useConversationChannel(supabase, topic, handlers2) {
35736
35901
  return () => {
35737
35902
  active = false;
35738
35903
  window.clearTimeout(changedTimer);
35739
- if (!channel) return;
35904
+ if (!channel2) return;
35740
35905
  handlersRef.current.onLeave();
35741
35906
  channelRef.current = null;
35742
35907
  handlersRef.current.onStatus(false);
35743
- const removal = supabase.removeChannel(channel).catch(() => void 0).finally(() => {
35908
+ const removal = supabase.removeChannel(channel2).catch(() => void 0).finally(() => {
35744
35909
  if (channelRemovals.get(topic) === removal) channelRemovals.delete(topic);
35745
35910
  });
35746
35911
  channelRemovals.set(topic, removal);
@@ -35807,7 +35972,7 @@ function SettoChat() {
35807
35972
  const refreshRef = useRef(async () => void 0);
35808
35973
  const typingSenderRef = useRef(null);
35809
35974
  const formId = useId();
35810
- const palette = useMemo(() => chatPalette(config.brandColors), [config.brandColors]);
35975
+ const palette = useSitePalette(config.brandColors);
35811
35976
  const desktopPopup = useDesktopPopup();
35812
35977
  const pageVisible = usePageVisible();
35813
35978
  const channelRef = useConversationChannel(supabase, mounted ? realtime?.topic ?? null : null, {
@@ -35835,9 +36000,9 @@ function SettoChat() {
35835
36000
  });
35836
36001
  function typingSender() {
35837
36002
  return typingSenderRef.current ??= createTypingSender((typing) => {
35838
- const channel = channelRef.current;
35839
- if (!channel || !subscribedRef.current || channel.state !== "joined") return false;
35840
- void channel.send({ type: "broadcast", event: "typing", payload: { side: "visitor", typing } }).catch(() => void 0);
36003
+ const channel2 = channelRef.current;
36004
+ if (!channel2 || !subscribedRef.current || channel2.state !== "joined") return false;
36005
+ void channel2.send({ type: "broadcast", event: "typing", payload: { side: "visitor", typing } }).catch(() => void 0);
35841
36006
  return true;
35842
36007
  });
35843
36008
  }
@@ -36528,11 +36693,11 @@ function useChatStyles() {
36528
36693
  .setto-chat{position:fixed;right:max(18px,env(safe-area-inset-right));bottom:max(18px,env(safe-area-inset-bottom));z-index:2147483000;overscroll-behavior:contain;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;overscroll-behavior:contain;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}
36529
36694
  .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)}
36530
36695
  .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}
36531
- .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 var(--setto-chat-composer-space,8rem);scroll-padding-bottom:var(--setto-chat-composer-space,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;min-width:1.8rem;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}
36696
+ .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 var(--setto-chat-composer-space,8rem);scroll-padding-bottom:var(--setto-chat-composer-space,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:var(--setto-chat-accent);justify-content:flex-end;color:var(--setto-chat-on-accent)}.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-on-accent)}.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;min-width:1.8rem;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}
36532
36697
  .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)}
36533
36698
  .setto-chat__receipt{display:block;margin:.26rem .45rem 0 0;color:color-mix(in srgb,var(--setto-chat-ink) 52%,transparent);font-size:.69rem;font-weight:500;line-height:1.2}.setto-chat__message--typing{animation:setto-chat-typing-in 180ms cubic-bezier(.2,.8,.2,1) both}.setto-chat__message--typing .setto-chat__message-bubble{min-width:3.25rem;text-align:center}.setto-chat__message--typing .setto-chat__typing{font-weight:700;letter-spacing:.06em}@keyframes setto-chat-typing-in{from{opacity:0;transform:translateY(4px)}}@media(prefers-reduced-motion:reduce){.setto-chat__message--typing{animation:none}}
36534
- .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:${MAX_COMPOSER_HEIGHT}px;overflow-y:auto;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 textarea::-webkit-scrollbar{width:6px}.setto-chat__composer textarea::-webkit-scrollbar-track{background:transparent}.setto-chat__composer textarea::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--setto-chat-ink) 24%,transparent)}.setto-chat__composer textarea::-webkit-scrollbar-button{display:none;height:0}@supports not selector(::-webkit-scrollbar){.setto-chat__composer textarea{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--setto-chat-ink) 24%,transparent) 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)}
36535
- .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 span{overflow:hidden}.setto-chat__launcher span img{width:100%;height:100%}.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}}
36699
+ .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:${MAX_COMPOSER_HEIGHT}px;overflow-y:auto;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 textarea::-webkit-scrollbar{width:6px}.setto-chat__composer textarea::-webkit-scrollbar-track{background:transparent}.setto-chat__composer textarea::-webkit-scrollbar-thumb{border-radius:999px;background:color-mix(in srgb,var(--setto-chat-ink) 24%,transparent)}.setto-chat__composer textarea::-webkit-scrollbar-button{display:none;height:0}@supports not selector(::-webkit-scrollbar){.setto-chat__composer textarea{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--setto-chat-ink) 24%,transparent) 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-on-accent);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:var(--setto-chat-canvas);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)}
36700
+ .setto-chat__launcher{width:58px;height:58px;padding:3px;border:1px solid color-mix(in srgb,var(--setto-chat-canvas) 54%,transparent);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-on-accent)}.setto-chat__launcher img{display:block;width:50px;height:50px;border-radius:50%;object-fit:cover}.setto-chat__launcher span{overflow:hidden}.setto-chat__launcher span img{width:100%;height:100%}.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}}
36536
36701
  @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}}
36537
36702
  `;
36538
36703
  style.textContent += "@media(prefers-reduced-motion:reduce){.setto-chat__markdown.is-revealing .setto-chat__word{opacity:1;transform:none;filter:none;animation:none}}";