@helpai/elements 0.12.3 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web-component.mjs CHANGED
@@ -6,8 +6,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6
6
  import { h as h2, render as render2 } from "preact";
7
7
 
8
8
  // src/ui/app.tsx
9
- import { useCallback as useCallback6, useEffect as useEffect17, useMemo as useMemo3, useRef as useRef8, useState as useState12 } from "preact/hooks";
10
- import { useSignal } from "@preact/signals";
9
+ import { useCallback as useCallback6, useEffect as useEffect17, useMemo as useMemo3, useRef as useRef8, useState as useState13 } from "preact/hooks";
10
+ import { useSignal as useSignal2 } from "@preact/signals";
11
11
 
12
12
  // src/core/brand.ts
13
13
  var BRAND = {
@@ -105,15 +105,154 @@ var STRINGS_EN = {
105
105
  newsEmpty: "No news yet",
106
106
  newsLoading: "Loading news\u2026",
107
107
  newsBack: "Back to news",
108
- newsPublishedAt: "Published {date}"
108
+ newsPublishedAt: "Published {date}",
109
+ // ── Forms + human-in-the-loop (intake / ask-input / approval) ───
110
+ intakeSubmit: "Start chat",
111
+ intakeSkip: "Skip for now",
112
+ formRequired: "This field is required",
113
+ formInvalidEmail: "Enter a valid email address",
114
+ formInvalidTel: "Enter a valid phone number",
115
+ formInvalidUrl: "Enter a valid URL",
116
+ formInvalidNumber: "Enter a valid number",
117
+ formTooShort: "Too short (min {min} characters)",
118
+ formTooLong: "Too long (max {max} characters)",
119
+ formNumberTooSmall: "Must be at least {min}",
120
+ formNumberTooLarge: "Must be at most {max}",
121
+ formPatternMismatch: "Please match the requested format",
122
+ formChooseAtLeast: "Choose at least {min}",
123
+ formChooseAtMost: "Choose at most {max}",
124
+ formOther: "Other",
125
+ formOtherPlaceholder: "Type your answer\u2026",
126
+ inputRequired: "Input required",
127
+ inputSubmit: "Submit",
128
+ inputSkip: "Skip",
129
+ inputSubmitted: "Answer submitted",
130
+ approvalRequired: "Approval required",
131
+ approve: "Approve",
132
+ reject: "Reject",
133
+ approved: "Approved",
134
+ rejected: "Rejected",
135
+ approvalReason: "Add a reason (optional)",
136
+ stepNoLongerActive: "This request is no longer active."
137
+ };
138
+ var STRINGS_FR = {
139
+ attach: "Joindre des fichiers",
140
+ attachmentMimeRejected: "Type de fichier non pris en charge",
141
+ attachmentTooLarge: "Le fichier est trop volumineux",
142
+ attachmentTooMany: "Limite de pi\xE8ces jointes atteinte",
143
+ chatClosed: "Cette conversation est ferm\xE9e",
144
+ close: "Fermer",
145
+ collapse: "R\xE9duire",
146
+ collapseSidebar: "R\xE9duire la barre lat\xE9rale",
147
+ composerPlaceholder: "\xC9crivez un message\u2026",
148
+ dateLastWeek: "7 derniers jours",
149
+ dateOlder: "Plus ancien",
150
+ dateToday: "Aujourd'hui",
151
+ dateYesterday: "Hier",
152
+ dropZone: "D\xE9posez les fichiers \xE0 joindre",
153
+ errorGeneric: "Une erreur s'est produite",
154
+ errorRateLimited: "Trop de requ\xEAtes \u2014 veuillez r\xE9essayer dans un instant.",
155
+ errorRetry: "R\xE9essayer",
156
+ expand: "Agrandir",
157
+ expandSidebar: "D\xE9velopper la barre lat\xE9rale",
158
+ exitFullscreen: "Quitter le plein \xE9cran",
159
+ fullscreen: "Plein \xE9cran",
160
+ history: "Historique",
161
+ historyBack: "Retour au chat",
162
+ historyEmpty: "Aucune conversation pour le moment",
163
+ historyLoading: "Chargement de vos conversations\u2026",
164
+ historyNewChat: "Nouvelle conversation",
165
+ historyTitle: "Historique des conversations",
166
+ language: "Langue",
167
+ launcherOpen: "Ouvrir le chat",
168
+ messagesLoading: "Chargement de la conversation\u2026",
169
+ micStart: "D\xE9marrer la saisie vocale",
170
+ micStop: "Arr\xEAter la saisie vocale",
171
+ micUnsupported: "La saisie vocale n'est pas prise en charge par ce navigateur",
172
+ moreActions: "Plus d'actions",
173
+ newConversation: "Nouvelle conversation",
174
+ panelTitle: "Chat",
175
+ popOut: "Ouvrir dans un nouvel onglet",
176
+ resizeHandle: "Glisser pour redimensionner",
177
+ scrollToBottom: "Aller au plus r\xE9cent",
178
+ send: "Envoyer",
179
+ soundOff: "Son d\xE9sactiv\xE9",
180
+ soundOn: "Son activ\xE9",
181
+ startNewConversation: "D\xE9marrer une nouvelle conversation",
182
+ stop: "Arr\xEAter",
183
+ theme: "Th\xE8me",
184
+ themeAuto: "Auto (syst\xE8me)",
185
+ themeDark: "Sombre",
186
+ themeLight: "Clair",
187
+ loading: "Chargement\u2026",
188
+ thinking: "R\xE9flexion\u2026",
189
+ thoughts: "R\xE9flexions",
190
+ usedTool: "Outil utilis\xE9",
191
+ // ── Messenger modules ──────────────────────────────────────────
192
+ tabHome: "Accueil",
193
+ tabMessages: "Messages",
194
+ tabHelp: "Aide",
195
+ tabNews: "Actualit\xE9s",
196
+ modulesEmpty: "Rien pour le moment",
197
+ moduleBack: "Retour",
198
+ contentLoading: "Chargement\u2026",
199
+ homeGreeting: "Comment pouvons-nous vous aider ?",
200
+ homeGreetingNamed: "Bonjour {name} \u{1F44B}",
201
+ homeGreetingLead: "Comment pouvons-nous vous aider ?",
202
+ homeSearchPlaceholder: "Rechercher de l'aide",
203
+ homeContentTitle: "Articles populaires",
204
+ helpTitle: "Aide",
205
+ helpSearchPlaceholder: "Rechercher de l'aide",
206
+ helpEmpty: "Aucun article d'aide pour le moment",
207
+ helpLoading: "Chargement de l'aide\u2026",
208
+ helpSearchEmpty: "Aucun r\xE9sultat trouv\xE9",
209
+ newsTitle: "Actualit\xE9s",
210
+ newsEmpty: "Aucune actualit\xE9 pour le moment",
211
+ newsLoading: "Chargement des actualit\xE9s\u2026",
212
+ newsBack: "Retour aux actualit\xE9s",
213
+ newsPublishedAt: "Publi\xE9 le {date}",
214
+ // ── Forms + human-in-the-loop (intake / ask-input / approval) ───
215
+ intakeSubmit: "D\xE9marrer le chat",
216
+ intakeSkip: "Ignorer pour l'instant",
217
+ formRequired: "Ce champ est obligatoire",
218
+ formInvalidEmail: "Saisissez une adresse e-mail valide",
219
+ formInvalidTel: "Saisissez un num\xE9ro de t\xE9l\xE9phone valide",
220
+ formInvalidUrl: "Saisissez une URL valide",
221
+ formInvalidNumber: "Saisissez un nombre valide",
222
+ formTooShort: "Trop court (min. {min} caract\xE8res)",
223
+ formTooLong: "Trop long (max. {max} caract\xE8res)",
224
+ formNumberTooSmall: "Doit \xEAtre au moins {min}",
225
+ formNumberTooLarge: "Doit \xEAtre au plus {max}",
226
+ formPatternMismatch: "Veuillez respecter le format demand\xE9",
227
+ formChooseAtLeast: "Choisissez au moins {min}",
228
+ formChooseAtMost: "Choisissez au plus {max}",
229
+ formOther: "Autre",
230
+ formOtherPlaceholder: "Saisissez votre r\xE9ponse\u2026",
231
+ inputRequired: "Saisie requise",
232
+ inputSubmit: "Envoyer",
233
+ inputSkip: "Ignorer",
234
+ inputSubmitted: "R\xE9ponse envoy\xE9e",
235
+ approvalRequired: "Approbation requise",
236
+ approve: "Approuver",
237
+ reject: "Refuser",
238
+ approved: "Approuv\xE9",
239
+ rejected: "Refus\xE9",
240
+ approvalReason: "Ajouter une raison (facultatif)",
241
+ stepNoLongerActive: "Cette demande n'est plus active."
242
+ };
243
+ var BUILTIN_STRINGS = {
244
+ en: STRINGS_EN,
245
+ fr: STRINGS_FR
109
246
  };
110
247
  function resolveStrings(locale, override) {
111
248
  const tag = primaryTag(locale);
112
249
  const isNested = isNestedShape(override);
250
+ const builtinLocale = tag === "en" ? {} : BUILTIN_STRINGS[tag] ?? {};
113
251
  const localeOverride = isNested ? override[tag] ?? {} : override ?? {};
114
252
  const enOverride = isNested ? override.en ?? {} : {};
115
253
  return {
116
254
  ...STRINGS_EN,
255
+ ...builtinLocale,
117
256
  ...enOverride,
118
257
  ...localeOverride
119
258
  };
@@ -293,11 +432,14 @@ var DEFAULT_ATTACHMENTS = {
293
432
  var DEFAULT_WELCOME = { animation: "typewriter", speed: 60 };
294
433
  var DEFAULT_FEATURES = {
295
434
  files: true,
296
- voice: "local"
435
+ voice: "local",
436
+ humanInLoop: true
297
437
  };
438
+ var DEFAULT_INTAKE = { enabled: false, fields: [], skippable: false };
298
439
  var DEFAULT_ENDPOINTS = {
299
440
  upload: "/ai/agent/upload-file",
300
- transcribe: "/ai/agent/transcribe-audio"
441
+ transcribe: "/ai/agent/transcribe-audio",
442
+ intake: "/ai/agent/intake"
301
443
  };
302
444
  var DEFAULT_LAUNCHER = {
303
445
  variant: "circle",
@@ -359,11 +501,14 @@ function resolveOptions(rawOpts) {
359
501
  features: {
360
502
  files: opts.features?.files ?? DEFAULT_FEATURES.files,
361
503
  voice: opts.features?.voice ?? DEFAULT_FEATURES.voice,
504
+ humanInLoop: opts.features?.humanInLoop ?? DEFAULT_FEATURES.humanInLoop,
362
505
  tools: opts.features?.tools
363
506
  },
507
+ intake: resolveIntake(opts.intake),
364
508
  endpoints: {
365
509
  upload: opts.endpoints?.upload ?? DEFAULT_ENDPOINTS.upload,
366
- transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe
510
+ transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe,
511
+ intake: opts.endpoints?.intake ?? DEFAULT_ENDPOINTS.intake
367
512
  },
368
513
  attachments: {
369
514
  accept: opts.composer?.attachments?.accept ?? DEFAULT_ATTACHMENTS.accept,
@@ -462,6 +607,18 @@ function resolveModules(overrides) {
462
607
  const byId = Object.fromEntries(list.map((m) => [m.id, m]));
463
608
  return { list, byId };
464
609
  }
610
+ function resolveIntake(overrides) {
611
+ const fields = (overrides?.fields ?? []).filter((f) => Boolean(f && f.name && f.label && f.type));
612
+ if (fields.length === 0) return DEFAULT_INTAKE;
613
+ return {
614
+ enabled: overrides?.enabled ?? false,
615
+ title: overrides?.title,
616
+ description: overrides?.description,
617
+ fields,
618
+ submitLabel: overrides?.submitLabel,
619
+ skippable: overrides?.skippable ?? false
620
+ };
621
+ }
465
622
  function resolveLauncher(overrides) {
466
623
  const callout = overrides?.callout?.text ? {
467
624
  shape: "pill",
@@ -507,6 +664,7 @@ var SECTION_KEYS = [
507
664
  "i18n",
508
665
  "footer",
509
666
  "features",
667
+ "intake",
510
668
  "endpoints"
511
669
  ];
512
670
  function mergeServerConfig(user, server) {
@@ -658,55 +816,55 @@ var REACTIVE_ATTRS = [
658
816
  ];
659
817
  function parseAttributes(get) {
660
818
  const opts = {};
661
- const str = (name) => {
819
+ const str2 = (name) => {
662
820
  const v = get(name);
663
821
  return v === null || v === "" ? void 0 : v;
664
822
  };
665
823
  for (const [attr, key, cast] of EMBED_SCALAR_ATTRS) {
666
- const raw = str(attr);
824
+ const raw = str2(attr);
667
825
  if (raw === void 0) continue;
668
826
  opts[key] = cast ? cast(raw) : raw;
669
827
  }
670
- const presentationFlat = collectSubset(str, PRESENTATION_ATTRS);
671
- const size = collectSubset(str, PRESENTATION_SIZE_ATTRS);
828
+ const presentationFlat = collectSubset(str2, PRESENTATION_ATTRS);
829
+ const size = collectSubset(str2, PRESENTATION_SIZE_ATTRS);
672
830
  if (presentationFlat || size) {
673
831
  opts.presentation = { ...presentationFlat, ...size ? { size } : {} };
674
832
  }
675
- const behavior = collectSubset(str, BEHAVIOR_ATTRS);
833
+ const behavior = collectSubset(str2, BEHAVIOR_ATTRS);
676
834
  if (behavior) opts.behavior = behavior;
677
- const i18n = collectSubset(str, I18N_ATTRS);
835
+ const i18n = collectSubset(str2, I18N_ATTRS);
678
836
  if (i18n) opts.i18n = i18n;
679
- const launcher = parseLauncher(get, str);
837
+ const launcher = parseLauncher(get, str2);
680
838
  if (launcher) opts.launcher = launcher;
681
- const features = collectSubset(str, FEATURE_ATTRS);
839
+ const features = collectSubset(str2, FEATURE_ATTRS);
682
840
  if (features) opts.features = features;
683
- const endpoints = collectSubset(str, ENDPOINT_ATTRS);
841
+ const endpoints = collectSubset(str2, ENDPOINT_ATTRS);
684
842
  if (endpoints) opts.endpoints = endpoints;
685
- const userContext = collectContext(str, USER_CONTEXT_ATTRS, "user-context");
843
+ const userContext = collectContext(str2, USER_CONTEXT_ATTRS, "user-context");
686
844
  if (userContext) opts.userContext = userContext;
687
- const pageContext = collectContext(str, PAGE_CONTEXT_ATTRS, "page-context");
845
+ const pageContext = collectContext(str2, PAGE_CONTEXT_ATTRS, "page-context");
688
846
  if (pageContext) opts.pageContext = pageContext;
689
- const actionsRaw = str("actions");
847
+ const actionsRaw = str2("actions");
690
848
  if (actionsRaw !== void 0) opts.header = { actions: onlyValidActions(actionsRaw) };
691
849
  return opts;
692
850
  }
693
- function collectSubset(str, table) {
851
+ function collectSubset(str2, table) {
694
852
  const out = {};
695
853
  for (const [attr, key, cast] of table) {
696
- const raw = str(attr);
854
+ const raw = str2(attr);
697
855
  if (raw === void 0) continue;
698
856
  out[key] = cast ? cast(raw) : raw;
699
857
  }
700
858
  return Object.keys(out).length > 0 ? out : null;
701
859
  }
702
- function collectContext(str, table, jsonAttr) {
860
+ function collectContext(str2, table, jsonAttr) {
703
861
  const scalars = {};
704
862
  for (const [attr, key] of table) {
705
- const raw = str(attr);
863
+ const raw = str2(attr);
706
864
  if (raw !== void 0) scalars[key] = raw;
707
865
  }
708
866
  let fromJson = {};
709
- const jsonRaw = str(jsonAttr);
867
+ const jsonRaw = str2(jsonAttr);
710
868
  if (jsonRaw) {
711
869
  try {
712
870
  const parsed = JSON.parse(jsonRaw);
@@ -717,13 +875,13 @@ function collectContext(str, table, jsonAttr) {
717
875
  const out = { ...fromJson, ...scalars };
718
876
  return Object.keys(out).length > 0 ? out : null;
719
877
  }
720
- function parseLauncher(get, str) {
721
- const base = collectSubset(str, LAUNCHER_ATTRS) ?? {};
878
+ function parseLauncher(get, str2) {
879
+ const base = collectSubset(str2, LAUNCHER_ATTRS) ?? {};
722
880
  const label = get("launcher-label");
723
881
  if (label !== null) base.label = label;
724
- const text = str("callout-text");
882
+ const text = str2("callout-text");
725
883
  if (text) {
726
- const delay = Number.parseInt(str("callout-delay") ?? "", 10);
884
+ const delay = Number.parseInt(str2("callout-delay") ?? "", 10);
727
885
  base.callout = { text, ...Number.isFinite(delay) ? { delayMs: delay } : {} };
728
886
  }
729
887
  return Object.keys(base).length > 0 ? base : null;
@@ -767,7 +925,7 @@ var tokens_default = ':host{--__P__-accent: __BRAND_ACCENT__;--__P__-accent-text
767
925
  var reset_default = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;border:0}button{font:inherit;color:inherit;background:none;cursor:pointer;-webkit-appearance:none;appearance:none;line-height:1}button:focus-visible,[tabindex]:focus-visible,textarea:focus-visible,input:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px}textarea,input{font:inherit;color:inherit;background:none;border:0;outline:0;resize:none}a{color:var(--__P__-accent);text-decoration:underline;text-underline-offset:2px}img,svg{display:block;max-width:100%}ul,ol{list-style:none}.__P__-app{display:block;width:100%;height:100%;font-family:var(--__P__-font);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:"cv11","ss01","ss03"}.__P__-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n';
768
926
 
769
927
  // src/styles/panel.css
770
- var panel_default = '.__P__-anchor{right:16px;bottom:16px}:host([data-position="bottom-left"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{right:auto;left:16px}:host([data-position="top-right"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{bottom:auto;top:16px}.__P__-anchor{position:fixed;display:flex;flex-direction:column;align-items:flex-end;gap:var(--__P__-space-3);pointer-events:none}.__P__-anchor{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=sm]{--__P__-fab-size: 44px}.__P__-anchor[data-launcher-size=md]{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=lg]{--__P__-fab-size: 68px}.__P__-anchor>*{pointer-events:auto}.__P__-fab[data-size=sm]{--__P__-fab-size: 44px;font-size:var(--__P__-text-sm)}.__P__-fab[data-size=md]{--__P__-fab-size: 56px;font-size:14px}.__P__-fab[data-size=lg]{--__P__-fab-size: 68px;font-size:var(--__P__-text-base)}.__P__-fab{display:inline-flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);color:var(--__P__-accent-text);background:var(--__P__-accent);box-shadow:var(--__P__-shadow-fab);font-weight:600;line-height:1;transform-origin:bottom right;animation:__P__-fab-in var(--__P__-dur-base) var(--__P__-ease) both;transition:transform var(--__P__-dur-base) var(--__P__-ease),opacity var(--__P__-dur-base) var(--__P__-ease),box-shadow var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab:hover{transform:translateY(-2px)}.__P__-fab:active{transform:translateY(0)}.__P__-fab:focus-visible{outline:2px solid var(--__P__-on-accent);outline-offset:3px}.__P__-fab svg{width:24px;height:24px;flex-shrink:0}@keyframes __P__-fab-in{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:none}}.__P__-fab[data-leaving]{position:absolute;right:0;bottom:0;animation:__P__-fab-out var(--__P__-dur-quick) var(--__P__-ease) forwards;pointer-events:none}:host([data-position^="top-"]) .__P__-fab[data-leaving]{bottom:auto;top:0}:host([data-position$="-left"]) .__P__-fab[data-leaving]{right:auto;left:0}@keyframes __P__-fab-out{0%{opacity:1;transform:none}to{opacity:0;transform:scale(.85)}}.__P__-fab[data-variant=circle]{width:var(--__P__-fab-size);height:var(--__P__-fab-size);border-radius:999px}.__P__-fab[data-variant=circle] .__P__-fab-label{display:none}.__P__-fab[data-variant=pill]{height:var(--__P__-fab-size);padding:0 18px 0 16px;border-radius:999px}.__P__-fab[data-variant=bar]{height:var(--__P__-fab-size);padding:0 22px;border-radius:var(--__P__-radius)}.__P__-fab[data-variant=minimal]{height:var(--__P__-fab-size);padding:0 var(--__P__-space-4);border-radius:999px;background:transparent;color:var(--__P__-accent);box-shadow:none;border:1px solid currentColor}.__P__-fab[data-variant=minimal]:hover{background:color-mix(in srgb,var(--__P__-accent) 12%,transparent)}.__P__-callout{--__P__-callout-fab-h: var(--__P__-fab-size, 56px);--__P__-callout-gap: clamp(12px, calc(var(--__P__-callout-fab-h) * .25), 22px);--__P__-callout-nudge-direction: -1;position:absolute;display:inline-flex;align-items:center;gap:var(--__P__-space-2);padding:10px 14px;background:var(--__P__-fg);color:var(--__P__-bg);border-radius:999px;font-size:var(--__P__-text-sm);font-weight:600;line-height:1.2;box-shadow:0 10px 30px -8px #00000059;pointer-events:auto;animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease);z-index:1;max-width:240px;white-space:nowrap}.__P__-callout[data-position=left]{right:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%)}.__P__-callout[data-position=right]{left:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%);--__P__-callout-nudge-direction: 1}.__P__-callout[data-position=top]{bottom:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-position=bottom]{top:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}:host([data-position$="-left"]) .__P__-callout[data-position=top],:host([data-position$="-left"]) .__P__-callout[data-position=bottom]{right:auto;left:0}.__P__-callout[data-shape=bubble]{border-radius:var(--__P__-radius-md);white-space:normal;width:max-content;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-shape=callout]{padding:12px 18px;font-size:14px;background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-callout:after{content:"";position:absolute;width:12px;height:12px;background:inherit;border-radius:2px;transform:rotate(45deg)}.__P__-callout[data-position=left]:after{right:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=right]:after{left:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=top]:after{bottom:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-position=bottom]:after{top:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}:host([data-position$="-left"]) .__P__-callout[data-position=top]:after,:host([data-position$="-left"]) .__P__-callout[data-position=bottom]:after{right:auto;left:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-animated]{animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease),__P__-callout-nudge 1.6s var(--__P__-ease-in-out) var(--__P__-dur-slow) infinite}@keyframes __P__-callout-in{0%{opacity:0}to{opacity:1}}@keyframes __P__-callout-nudge{0%,to{margin-left:0;margin-right:0}50%{margin-left:calc(6px * var(--__P__-callout-nudge-direction));margin-right:calc(-6px * var(--__P__-callout-nudge-direction))}}@media(prefers-reduced-motion:reduce){.__P__-callout[data-animated]{animation:__P__-callout-in 1ms var(--__P__-ease)}.__P__-icon-btn[data-recording=true],.__P__-typing span{animation:none}}.__P__-callout-close{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:inherit;opacity:.7;cursor:pointer}.__P__-callout-close:hover{opacity:1;background:#ffffff26}.__P__-callout-close svg{width:12px;height:12px}.__P__-panel{width:var(--__P__-panel-w);height:var(--__P__-panel-h);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);background:var(--__P__-bg);color:var(--__P__-fg);border-radius:var(--__P__-radius-lg);box-shadow:var(--__P__-shadow-panel);display:flex;flex-direction:column;overflow:hidden;transform-origin:bottom right;animation:__P__-panel-in var(--__P__-dur-slow) var(--__P__-ease);border:1px solid var(--__P__-border)}:host([data-mode="open"]) .__P__-panel{width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));min-width:var(--__P__-resize-min-w, auto);min-height:var(--__P__-resize-min-h, auto);max-width:var(--__P__-resize-max-w, calc(100vw - 32px) );max-height:var(--__P__-resize-max-h, calc(100dvh - 32px) )}@keyframes __P__-panel-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}:host([data-mode="expanded"]) .__P__-panel{width:var(--__P__-expanded-w, 640px);height:var(--__P__-expanded-h, 820px);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px)}:host([data-mode="fullscreen"]){z-index:var(--__P__-z-panel)!important}:host([data-mode="fullscreen"]) .__P__-anchor{inset:0;align-items:stretch;padding:0}:host([data-mode="fullscreen"]) .__P__-panel{width:100vw;height:100dvh;max-width:none;max-height:none;border-radius:0;border:0}:host([data-mode="fullscreen"]) .__P__-fab{display:none}:host([data-mode="inline"]) .__P__-anchor,:host([data-mode="standalone"]) .__P__-anchor{position:static;inset:auto;padding:0;align-items:stretch;width:100%;height:100%;min-height:0}:host([data-mode="inline"]) .__P__-panel,:host([data-mode="standalone"]) .__P__-panel{width:100%;height:100%;min-width:0;min-height:0;max-width:none;max-height:none;animation:none}:host([data-mode="inline"]) .__P__-fab,:host([data-mode="standalone"]) .__P__-fab{display:none}:host([data-mode="inline"]){min-height:320px}:host([data-mode="inline"]) .__P__-panel{border-radius:var(--__P__-radius)}:host([data-mode="standalone"]) .__P__-panel{border-radius:0;border:0;box-shadow:none}:host([data-mode="modal"]){position:fixed!important;inset:0!important;z-index:var(--__P__-z-panel)!important;display:block!important;width:100vw;height:100dvh;background:var(--__P__-modal-backdrop, var(--__P__-backdrop));animation:__P__-backdrop-in var(--__P__-dur-base) var(--__P__-ease) both;--__P__-panel-w: min(960px, 92vw);--__P__-panel-h: min(720px, 88dvh)}:host([data-mode="modal"]) .__P__-anchor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:var(--__P__-space-6);pointer-events:none}:host([data-mode="modal"]) .__P__-panel{pointer-events:auto;width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));max-width:calc(100vw - 48px);max-height:calc(100dvh - 48px);min-width:0;min-height:0;border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-panel);animation:__P__-modal-in var(--__P__-dur-base) var(--__P__-ease);translate:var(--__P__-modal-dx, 0px) var(--__P__-modal-dy, 0px)}:host([data-mode="modal"]) .__P__-header,:host([data-mode="modal"]) .__P__-back-header,:host([data-mode="modal"]) .__P__-home-hero{cursor:grab;touch-action:none}:host([data-mode="modal"]) .__P__-panel[data-dragging]{cursor:grabbing;user-select:none}:host([data-mode="modal"]) .__P__-panel[data-dragging] *{cursor:grabbing}:host([data-mode="modal"]) .__P__-fab{display:none}@keyframes __P__-backdrop-in{0%{background:#0000}to{background:var(--__P__-modal-backdrop, var(--__P__-backdrop))}}@keyframes __P__-modal-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}:host([data-mode="drawer"]){--__P__-panel-w: min(440px, calc(100vw - 32px) );--__P__-panel-h: 100dvh}:host([data-mode="drawer"]) .__P__-anchor{position:fixed;--__P__-inset-x: var(--__P__-panel-inset, 12px);--__P__-inset-y: var(--__P__-panel-inset, 3dvh);top:var(--__P__-inset-y);bottom:auto;right:var(--__P__-inset-x);left:auto;width:min(var(--__P__-widget-w, var(--__P__-panel-w)),calc(100vw - var(--__P__-inset-x) * 2));height:min(var(--__P__-widget-h, var(--__P__-panel-h)),calc(100dvh - var(--__P__-inset-y) * 2));padding:0;display:block;pointer-events:auto}:host([data-mode="drawer"][data-position$="-left"]) .__P__-anchor{right:auto;left:var(--__P__-inset-x)}:host([data-mode="drawer"][data-position^="bottom-"]) .__P__-anchor{top:auto;bottom:var(--__P__-inset-y)}:host([data-mode="drawer"]) .__P__-panel{width:100%;height:100%;max-width:none;max-height:none;min-width:0;min-height:0;border-radius:var(--__P__-radius, 12px);border:1px solid var(--__P__-border);box-shadow:-8px 16px 32px -12px #00000038;animation:__P__-drawer-in var(--__P__-dur-base) var(--__P__-ease)}:host([data-mode="drawer"][data-position$="-left"]) .__P__-panel{box-shadow:8px 16px 32px -12px #00000038;animation:__P__-drawer-in-left var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab[data-edge-tab]{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-2);position:fixed;top:50%;height:140px;width:auto;min-width:0;padding:10px 8px;writing-mode:vertical-rl;text-orientation:mixed;transform:translateY(-50%);transform-origin:center;animation:__P__-edge-tab-in var(--__P__-dur-base) var(--__P__-ease) both}.__P__-fab[data-edge-tab] svg{writing-mode:horizontal-tb}.__P__-fab[data-edge-tab]:hover{transform:translateY(-50%) scale(1.03)}.__P__-fab[data-edge-tab]:active{transform:translateY(-50%) scale(.97)}:host([data-position$="-right"]) .__P__-fab[data-edge-tab]{right:0;left:auto;border-radius:12px 0 0 12px;box-shadow:-6px 0 18px -8px #0000004d}:host([data-position$="-left"]) .__P__-fab[data-edge-tab]{left:0;right:auto;border-radius:0 12px 12px 0;box-shadow:6px 0 18px -8px #0000004d}.__P__-fab[data-edge-tab][data-leaving]{position:fixed;top:50%;bottom:auto;animation:__P__-edge-tab-out var(--__P__-dur-quick) var(--__P__-ease) forwards}@keyframes __P__-edge-tab-in{0%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:1;transform:translateY(-50%) scale(1)}}@keyframes __P__-edge-tab-out{0%{opacity:1;transform:translateY(-50%) scale(1)}to{opacity:0;transform:translateY(-50%) scale(.85)}}@keyframes __P__-drawer-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes __P__-drawer-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}@media(prefers-reduced-motion:reduce){:host([data-mode="drawer"]) .__P__-panel,.__P__-fab[data-edge-tab]{animation:none}}.__P__-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);background:var(--__P__-bg)}.__P__-header h1{font-size:14px;font-weight:600;flex:1;letter-spacing:-.01em}.__P__-header-actions{margin-left:auto;display:flex;align-items:center;gap:var(--__P__-space-1);flex-shrink:0}.__P__-agent{flex:1;display:inline-flex;align-items:center;gap:10px;min-width:0}.__P__-agent-avatar{position:relative;width:32px;height:32px;border-radius:999px;background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--__P__-text-xs);overflow:hidden;flex-shrink:0}.__P__-agent-avatar img{width:100%;height:100%;object-fit:cover}.__P__-agent-avatar:after{content:"";position:absolute;right:-1px;bottom:-1px;width:10px;height:10px;border-radius:999px;border:2px solid var(--__P__-bg);background:var(--__P__-neutral)}.__P__-agent-avatar[data-status=online]:after{background:var(--__P__-success)}.__P__-agent-avatar[data-status=away]:after{background:var(--__P__-warning)}.__P__-agent-avatar[data-status=offline]:after{background:var(--__P__-neutral)}.__P__-agent-meta{display:flex;flex-direction:column;line-height:1.15;min-width:0}.__P__-agent-meta strong{font-size:14px;font-weight:600;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-agent-meta span{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-suggestions{display:flex;flex-wrap:nowrap;gap:var(--__P__-space-2);padding:6px 14px 10px;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scroll-snap-type:x proximity;scrollbar-width:none;-ms-overflow-style:none;min-width:0}.__P__-suggestions::-webkit-scrollbar{display:none}.__P__-suggestions:before,.__P__-suggestions:after{content:"";flex:1 1 0;min-width:0}.__P__-suggestion{flex:0 0 auto;scroll-snap-align:center;padding:7px 14px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg);font-size:var(--__P__-text-sm);font-weight:500;white-space:nowrap;transition:background var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-suggestion:hover{border-color:var(--__P__-accent);color:var(--__P__-accent);transform:translateY(-1px)}.__P__-suggestion:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px;border-color:var(--__P__-accent)}.__P__-suggestion:active{transform:translateY(0)}.__P__-icon-btn{width:32px;height:32px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);transition:background var(--__P__-dur-quick) var(--__P__-ease),color var(--__P__-dur-quick) var(--__P__-ease)}.__P__-icon-btn:hover{background:var(--__P__-bg-elevated);color:var(--__P__-fg)}.__P__-icon-btn:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-icon-btn:active{background:var(--__P__-border)}.__P__-icon-btn:disabled{opacity:.45;cursor:not-allowed}.__P__-icon-btn:before{content:"";position:absolute;inset:-6px}.__P__-icon-btn{position:relative}.__P__-icon-btn svg{width:18px;height:18px}.__P__-icon-btn[data-recording=true]{color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);animation:__P__-pulse 1.2s var(--__P__-ease) infinite}@keyframes __P__-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--__P__-accent) 40%,transparent)}50%{box-shadow:0 0 0 6px color-mix(in srgb,var(--__P__-accent) 0%,transparent)}}.__P__-list-wrap{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}.__P__-jump{position:absolute;right:14px;bottom:14px;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:999px;border:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);color:var(--__P__-fg);box-shadow:var(--__P__-shadow-panel);cursor:pointer;opacity:.85;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease);animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-jump:hover{opacity:1}.__P__-jump:active{transform:translateY(1px)}.__P__-jump svg{width:18px;height:18px}.__P__-list{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-4);padding-bottom:var(--__P__-space-8);display:flex;flex-direction:column;gap:14px;scrollbar-width:thin;scrollbar-color:var(--__P__-border-strong) transparent;scrollbar-gutter:stable}.__P__-list::-webkit-scrollbar{width:8px}.__P__-list::-webkit-scrollbar-thumb{background:var(--__P__-border-strong);border-radius:8px}.__P__-date-divider{position:sticky;top:var(--__P__-space-2);z-index:2;display:flex;justify-content:center;margin:var(--__P__-space-1) 0;pointer-events:none}.__P__-date-pill{padding:3px 10px;border-radius:999px;font-size:11px;font-weight:600;color:var(--__P__-fg-muted);background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);box-shadow:var(--__P__-shadow-card);opacity:0;pointer-events:none;transition:opacity var(--__P__-dur-base) var(--__P__-ease)}.__P__-list[data-scrolling=true] .__P__-date-pill{opacity:1;pointer-events:auto}@media(prefers-reduced-motion:reduce){.__P__-date-pill{transition:none}}.__P__-bubble-row{display:flex}.__P__-bubble-row[data-role=user]{justify-content:flex-end}.__P__-bubble-row[data-role=assistant]{justify-content:flex-start}.__P__-bubble{max-width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);line-height:1.6;font-size:14px;word-wrap:break-word;overflow-wrap:anywhere;box-shadow:0 1px 2px #0000000a,0 1px 8px -4px #0000000f;animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-bubble ::selection{background:color-mix(in srgb,var(--__P__-accent) 30%,transparent)}.__P__-bubble-row[data-role=user] .__P__-bubble ::selection{background:#fff6;color:var(--__P__-bubble-user-text)}@keyframes __P__-bubble-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.__P__-bubble-row[data-role=user] .__P__-bubble{background:var(--__P__-bubble-user);color:var(--__P__-bubble-user-text);border-bottom-right-radius:5px}.__P__-bubble-row[data-role=assistant] .__P__-bubble{background:var(--__P__-bubble-assistant);color:var(--__P__-bubble-assistant-text);border-bottom-left-radius:5px}.__P__-bubble-col{display:flex;flex-direction:column;max-width:85%;min-width:0}.__P__-bubble-row[data-role=user] .__P__-bubble-col{align-items:flex-end}.__P__-bubble-row[data-role=assistant] .__P__-bubble-col{align-items:flex-start}.__P__-bubble-time{margin-top:3px;padding:0 4px;font-size:11px;line-height:1;color:var(--__P__-fg-muted);user-select:none}.__P__-md>*:first-child{margin-top:0}.__P__-md>*:last-child{margin-bottom:0}.__P__-md p{margin:10px 0}.__P__-md h1,.__P__-md h2,.__P__-md h3,.__P__-md h4,.__P__-md h5,.__P__-md h6{margin:18px 0 8px;line-height:1.3;letter-spacing:-.01em;font-weight:700}.__P__-md h1{font-size:1.4em}.__P__-md h2{font-size:1.22em}.__P__-md h3{font-size:1.08em}.__P__-md h4,.__P__-md h5,.__P__-md h6{font-size:1em}.__P__-md>h1:first-child,.__P__-md>h2:first-child,.__P__-md>h3:first-child,.__P__-md>h4:first-child,.__P__-md>h5:first-child,.__P__-md>h6:first-child{margin-top:0}.__P__-md ul,.__P__-md ol{padding-left:1.5em;margin:10px 0}.__P__-md ul{list-style:disc}.__P__-md ol{list-style:decimal}.__P__-md li{margin:6px 0;padding-left:2px}.__P__-md li::marker{color:var(--__P__-fg-muted)}.__P__-md li>p{margin:6px 0}.__P__-md li>ul,.__P__-md li>ol{margin:6px 0}.__P__-md strong,.__P__-md b{font-weight:650;letter-spacing:-.005em}.__P__-md em,.__P__-md i{font-style:italic}.__P__-md code{font-family:var(--__P__-font-mono);font-size:.86em;padding:1px 6px;border-radius:5px;background:color-mix(in srgb,var(--__P__-accent) 10%,transparent);color:var(--__P__-fg);border:1px solid color-mix(in srgb,var(--__P__-accent) 16%,transparent)}.__P__-md pre{font-family:var(--__P__-font-mono);font-size:12.5px;padding:12px 14px;border-radius:var(--__P__-radius-sm);background:#7f7f7f1f;overflow-x:auto;margin:var(--__P__-space-3) 0;line-height:1.5}.__P__-md pre code{padding:0;background:none}.__P__-md a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}.__P__-md a:hover{text-decoration-thickness:2px}.__P__-md blockquote{margin:14px 0;padding:6px 14px;border-left:3px solid color-mix(in srgb,var(--__P__-accent) 50%,transparent);background:color-mix(in srgb,var(--__P__-accent) 5%,transparent);border-radius:0 var(--__P__-radius-sm) var(--__P__-radius-sm) 0;color:var(--__P__-fg-muted)}.__P__-md blockquote>:first-child{margin-top:0}.__P__-md blockquote>:last-child{margin-bottom:0}.__P__-md hr{border:0;height:1px;background:color-mix(in srgb,currentColor 18%,transparent);margin:var(--__P__-space-4) 0}.__P__-md table{border-collapse:collapse;margin:var(--__P__-space-3) 0;font-size:.95em;display:block;overflow-x:auto;max-width:100%;font-variant-numeric:tabular-nums}.__P__-md th,.__P__-md td{padding:6px 10px;border-bottom:1px solid color-mix(in srgb,currentColor 12%,transparent);text-align:left}.__P__-md th{font-weight:700;background:color-mix(in srgb,currentColor 6%,transparent)}.__P__-md h1+ul,.__P__-md h1+ol,.__P__-md h2+ul,.__P__-md h2+ol,.__P__-md h3+ul,.__P__-md h3+ol,.__P__-md h4+ul,.__P__-md h4+ol{margin-top:var(--__P__-space-1)}.__P__-loading{display:inline-flex;align-items:center;gap:var(--__P__-space-2);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-loading-spinner{width:14px;height:14px;border-radius:999px;border:2px solid currentColor;border-top-color:transparent;animation:__P__-spin .8s linear infinite}@keyframes __P__-spin{to{transform:rotate(1turn)}}.__P__-typing{display:inline-flex;gap:var(--__P__-space-1);padding:var(--__P__-space-1) 0}.__P__-typing span{width:5px;height:5px;border-radius:999px;background:currentColor;opacity:.4;animation:__P__-blink 1.2s var(--__P__-ease) infinite}.__P__-typing span:nth-child(2){animation-delay:.2s}.__P__-typing span:nth-child(3){animation-delay:.4s}@keyframes __P__-blink{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}.__P__-reasoning{margin:var(--__P__-space-1) 0 var(--__P__-space-2);padding-left:var(--__P__-space-3);border-left:2px solid var(--__P__-border-strong)}.__P__-reasoning-summary{display:inline-flex;align-items:center;gap:var(--__P__-space-1);cursor:pointer;list-style:none;user-select:none;color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600}.__P__-reasoning-summary::-webkit-details-marker{display:none}.__P__-reasoning-summary:before{content:"";width:5px;height:5px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);opacity:.7;transition:transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-reasoning[open] .__P__-reasoning-summary:before{transform:rotate(45deg)}.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:__P__-reasoning-pulse 1.4s var(--__P__-ease) infinite}@keyframes __P__-reasoning-pulse{0%,to{opacity:.5}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:none}}.__P__-reasoning-body{margin-top:var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-reasoning-body>:first-child{margin-top:0}.__P__-reasoning-body>:last-child{margin-bottom:0}.__P__-tool-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2);margin-top:6px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs)}.__P__-composer{border-top:1px solid var(--__P__-border);padding:10px 12px;background:var(--__P__-bg);display:flex;flex-direction:column;gap:var(--__P__-space-2)}.__P__-composer-row{display:flex;align-items:flex-end;gap:6px}.__P__-textarea{flex:1;height:40px;max-height:160px;padding:10px 12px;border-radius:var(--__P__-radius);background:var(--__P__-bg-elevated);border:1px solid transparent;font-size:14px;line-height:1.4;transition:height var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),box-shadow var(--__P__-dur-quick) var(--__P__-ease)}.__P__-textarea:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:1px;border-color:var(--__P__-focus)}@media(pointer:coarse){.__P__-textarea,.__P__-home-search-input{font-size:16px}.__P__-textarea{height:44px}}.__P__-send{width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease),background var(--__P__-dur-quick) var(--__P__-ease)}.__P__-send[data-shape=circle]{border-radius:999px}.__P__-send[data-shape=square]{border-radius:var(--__P__-radius-sm)}.__P__-send[data-shape=pill]{width:auto;padding:0 18px;border-radius:999px}.__P__-send[data-variant=filled]{background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-send[data-variant=outline]{background:transparent;color:var(--__P__-accent);border-color:var(--__P__-accent)}.__P__-send[data-variant=outline]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 10%,transparent)}.__P__-send[data-variant=ghost]{background:transparent;color:var(--__P__-accent)}.__P__-send[data-variant=ghost]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 8%,transparent)}.__P__-send:disabled{opacity:.4;cursor:not-allowed}.__P__-send:not(:disabled):hover{transform:translateY(-1px)}.__P__-send:not(:disabled):active{transform:translateY(0)}.__P__-send:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-send svg{width:18px;height:18px}.__P__-composer-actions{display:flex;gap:var(--__P__-space-1);flex-wrap:wrap}.__P__-attachments{display:flex;flex-wrap:wrap;gap:6px}.__P__-attachment-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-1);border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);font-size:var(--__P__-text-xs);max-width:200px}.__P__-attachment-thumb{width:24px;height:24px;border-radius:999px;object-fit:cover;background:var(--__P__-border)}.__P__-attachment-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-attachment-remove{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted)}.__P__-attachment-remove:hover{background:var(--__P__-border);color:var(--__P__-fg)}.__P__-dropzone{position:absolute;inset:8px;border:2px dashed var(--__P__-accent);border-radius:var(--__P__-radius);background:color-mix(in srgb,var(--__P__-accent) 8%,transparent);display:flex;align-items:center;justify-content:center;font-weight:600;color:var(--__P__-accent);pointer-events:none;z-index:10;animation:__P__-fade-in var(--__P__-dur-quick) var(--__P__-ease)}@keyframes __P__-fade-in{0%{opacity:0}to{opacity:1}}.__P__-error{margin-top:var(--__P__-space-1);padding:8px 10px;border-radius:var(--__P__-radius-sm);background:var(--__P__-danger-bg);color:var(--__P__-danger-text);font-size:var(--__P__-text-sm);display:flex;align-items:center;gap:var(--__P__-space-2)}.__P__-error button{color:inherit;text-decoration:underline;font-size:var(--__P__-text-sm)}.__P__-history{flex:1;overflow-y:auto;padding:var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-3)}.__P__-history-footer{flex:none;padding:var(--__P__-space-2) var(--__P__-space-3) var(--__P__-space-3);border-top:1px solid var(--__P__-border);background:var(--__P__-surface)}.__P__-history-new{width:100%;display:flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);padding:var(--__P__-space-2) var(--__P__-space-3);border:none;border-radius:var(--__P__-radius-md);background:var(--__P__-accent);color:var(--__P__-on-accent);cursor:pointer;font-size:var(--__P__-text-sm);font-weight:600;transition:filter var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-history-new svg{width:16px;height:16px}.__P__-history-new:hover{filter:brightness(1.08)}.__P__-history-new:active{transform:translateY(1px)}.__P__-history-new:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-history-empty{flex:1;display:flex;align-items:center;justify-content:center;padding:40px 16px;color:var(--__P__-fg-muted);font-size:14px;text-align:center}.__P__-history-group{display:flex;flex-direction:column;padding:0 var(--__P__-space-2)}.__P__-history-heading{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-fg-muted);padding:12px 8px 6px;text-transform:uppercase;letter-spacing:.04em}.__P__-history-item{all:unset;display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:var(--__P__-radius-md);cursor:pointer;transition:background var(--__P__-dur-base) var(--__P__-ease)}.__P__-history-item:hover{background:var(--__P__-bg-elevated)}.__P__-history-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-history-title{font-size:14px;font-weight:500;color:var(--__P__-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-preview{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-item[data-closed=true] .__P__-history-title:after{content:"\\2022";margin-left:var(--__P__-space-2);opacity:.5}.__P__-list-loading{margin:auto;padding:var(--__P__-space-6) var(--__P__-space-4);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);text-align:center}.__P__-readonly-banner{display:flex;flex-direction:column;align-items:center;gap:10px;padding:14px 12px;margin:0 var(--__P__-space-3) var(--__P__-space-3);border-radius:var(--__P__-radius-md);background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);text-align:center;font-size:var(--__P__-text-sm)}.__P__-readonly-label{line-height:1.4}.__P__-readonly-cta{appearance:none;border:0;cursor:pointer;padding:var(--__P__-space-2) var(--__P__-space-4);border-radius:999px;background:var(--__P__-accent);color:var(--__P__-accent-text, #fff);font:inherit;font-weight:600;font-size:var(--__P__-text-sm);transition:filter var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-readonly-cta:hover,.__P__-readonly-cta:focus-visible{filter:brightness(1.1)}.__P__-readonly-cta:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px}.__P__-composer-footer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:10px 16px;margin:0 var(--__P__-space-3);border-top:1px solid var(--__P__-border);text-align:center;font-size:11px;line-height:1.4;color:var(--__P__-fg-muted)}.__P__-disclaimer{max-width:320px;margin:0 auto;opacity:.9;letter-spacing:.01em}.__P__-poweredby{display:inline-flex;align-items:center;justify-content:center;gap:6px;color:inherit;text-decoration:none;opacity:.7;transition:opacity var(--__P__-dur-base) var(--__P__-ease);font-size:11px;letter-spacing:.02em}.__P__-poweredby:hover{opacity:1}.__P__-poweredby-logo{height:12px;width:auto;display:inline-block;vertical-align:middle}.__P__-poweredby-bar{flex:none;display:flex;align-items:center;justify-content:center;padding:6px 16px;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated)}.__P__-menu-wrap{position:relative;display:inline-flex}.__P__-menu{position:absolute;top:100%;right:0;margin-top:6px;min-width:200px;padding:6px;background:var(--__P__-bg);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);box-shadow:var(--__P__-shadow-panel);z-index:10;display:flex;flex-direction:column;gap:2px;animation:__P__-menu-in var(--__P__-dur-base) var(--__P__-ease)}@media(prefers-reduced-motion:reduce){.__P__-menu{animation:none}}@keyframes __P__-menu-in{0%{opacity:0;transform:translateY(-4px) scale(.98);transform-origin:top right}to{opacity:1;transform:none}}.__P__-menu-item{all:unset;display:flex;align-items:center;gap:10px;padding:8px 10px;font-size:var(--__P__-text-sm);color:var(--__P__-fg);border-radius:var(--__P__-radius-sm);cursor:pointer;user-select:none}.__P__-menu-item:hover{background:var(--__P__-bg-elevated)}.__P__-menu-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-menu-item[disabled]{opacity:.45;cursor:not-allowed}.__P__-menu-icon{display:inline-flex;width:16px;height:16px;color:var(--__P__-fg-muted)}.__P__-menu-icon svg{width:16px;height:16px}.__P__-menu-label{flex:1}.__P__-menu-check{display:inline-flex;color:var(--__P__-accent)}.__P__-menu-check svg{width:14px;height:14px}.__P__-resize-grip{position:absolute;width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);opacity:.45;transition:opacity var(--__P__-dur-base) var(--__P__-ease);z-index:2;touch-action:none;user-select:none}.__P__-resize-grip:hover,.__P__-resize-grip:focus-visible{opacity:1}.__P__-resize-grip svg{width:10px;height:10px}.__P__-resize-grip--bottom-left{bottom:2px;left:2px;cursor:nesw-resize;transform:scaleX(-1)}.__P__-resize-grip--bottom-right{bottom:2px;right:2px;cursor:nwse-resize}.__P__-resize-grip--top-left{top:2px;left:2px;cursor:nwse-resize;transform:rotate(180deg)}.__P__-resize-grip--top-right{top:2px;right:2px;cursor:nesw-resize;transform:scaleY(-1)}:host(:not([data-mode="open"])) .__P__-resize-grip{display:none}.__P__-messenger{display:flex;flex-direction:column;overflow:hidden}.__P__-messenger-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}.__P__-module{display:flex;flex-direction:column;height:100%;min-height:0}.__P__-module-scroll{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-3);display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-home{background:radial-gradient(125% 65% at 88% 0%,color-mix(in srgb,#fff 16%,transparent),transparent 55%),linear-gradient(180deg,var(--__P__-accent) 0%,var(--__P__-accent) 22%,color-mix(in srgb,var(--__P__-accent) 28%,var(--__P__-surface)) 44%,var(--__P__-surface) 70%);border-radius:var(--__P__-radius-lg) var(--__P__-radius-lg) 0 0}.__P__-home-scroll{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;background:transparent}.__P__-home-cards{display:flex;flex-direction:column;gap:var(--__P__-space-3);padding:4px 14px 16px}.__P__-module-pad{padding:var(--__P__-space-3) var(--__P__-space-3) 0}.__P__-module-empty{display:flex;flex-direction:column;align-items:center;gap:var(--__P__-space-3);padding:var(--__P__-space-8) var(--__P__-space-4);text-align:center;color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}.__P__-module-retry{padding:var(--__P__-space-2) var(--__P__-space-4);border:1px solid var(--__P__-border-strong);border-radius:var(--__P__-radius-sm);color:var(--__P__-fg);font-weight:600;cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),border-color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-module-retry:hover{background:var(--__P__-hover);border-color:var(--__P__-accent)}.__P__-module-retry:active{background:var(--__P__-border)}.__P__-module-retry:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-help-list{flex:1;min-height:0;overflow-y:auto;padding-bottom:var(--__P__-space-3)}.__P__-help-group{display:flex;flex-direction:column}.__P__-help-section-title{position:sticky;top:0;z-index:1;margin:0;padding:var(--__P__-space-3) var(--__P__-space-5) var(--__P__-space-2);font-size:var(--__P__-text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--__P__-fg-muted);background:var(--__P__-bg)}.__P__-help-card{margin:0 var(--__P__-space-3) var(--__P__-space-3);background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden}.__P__-help-card .__P__-list-row{border-bottom:0;border-radius:0}.__P__-help-card .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-help-card .__P__-list-row:hover{background:var(--__P__-hover)}.__P__-module-cta{padding:var(--__P__-space-3);border-top:1px solid var(--__P__-border)}.__P__-tabbar{display:flex;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);flex-shrink:0}.__P__-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-1);min-height:48px;padding:var(--__P__-space-2) var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600;transition:color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-tab:hover{color:var(--__P__-fg)}.__P__-tab[aria-selected=true]{color:var(--__P__-accent)}.__P__-tab:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-tab:active{background:var(--__P__-hover)}.__P__-tab-icon{position:relative;display:inline-flex}.__P__-tab-icon svg{width:22px;height:22px}.__P__-tab-badge{position:absolute;top:-4px;left:calc(50% + 6px);min-width:16px;height:16px;padding:0 4px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:var(--__P__-accent);color:var(--__P__-on-accent);font-size:10px;font-weight:600;line-height:1}.__P__-home-hero{flex-shrink:0;padding:var(--__P__-space-5) var(--__P__-space-5) var(--__P__-space-3);color:var(--__P__-on-accent);--__P__-focus: var(--__P__-on-accent)}.__P__-home-hero-top{display:flex;align-items:center;justify-content:space-between;gap:var(--__P__-space-3);min-height:32px}.__P__-home-brand{font-size:14px;font-weight:600;letter-spacing:.01em;color:color-mix(in srgb,#fff 82%,transparent);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.__P__-home-brand-spacer{flex:1}.__P__-home-hero-actions{display:flex;align-items:center;gap:var(--__P__-space-2);flex-shrink:0}.__P__-home-hero-actions .__P__-icon-btn{color:#fff}.__P__-home-greeting{margin:28px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;overflow-wrap:anywhere}.__P__-home-lead{margin:2px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;color:color-mix(in srgb,var(--__P__-on-accent) 88%,transparent);overflow-wrap:anywhere}.__P__-home-avatars{display:flex}.__P__-home-avatar{width:30px;height:30px;border-radius:999px;overflow:hidden;margin-left:-10px;border:2px solid color-mix(in srgb,#fff 92%,transparent);box-shadow:0 1px 3px #0000002e;background:var(--__P__-surface);display:inline-flex;align-items:center;justify-content:center;font-size:var(--__P__-text-xs);font-weight:700;color:var(--__P__-fg)}.__P__-home-avatar:first-child{margin-left:0}.__P__-home-avatar img{width:100%;height:100%;object-fit:cover}.__P__-home-content{background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-card);overflow:hidden}.__P__-home-content-title{padding:var(--__P__-space-4) var(--__P__-space-4) var(--__P__-space-3);font-size:var(--__P__-text-sm);font-weight:700}.__P__-home-content-list{display:flex;flex-direction:column;padding:0 var(--__P__-space-2) var(--__P__-space-2)}.__P__-home-content-list .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-home-card{display:block;width:100%;text-align:left;background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);padding:var(--__P__-space-4);box-shadow:var(--__P__-shadow-card)}.__P__-home-card[data-interactive=true]{cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-home-card[data-interactive=true]:hover{background:var(--__P__-bg-elevated)}.__P__-home-card[data-interactive=true]:active{transform:translateY(1px)}.__P__-home-card[data-interactive=true]:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-recent-row{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-recent-avatar{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;flex-shrink:0;border-radius:999px;background:color-mix(in oklch,var(--__P__-accent) 14%,transparent);color:var(--__P__-accent)}.__P__-home-recent-avatar svg{width:20px;height:20px}.__P__-home-recent-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.__P__-home-recent-title{font-weight:600;font-size:14px}.__P__-home-recent-preview{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-home-recent-at{color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);flex-shrink:0}.__P__-home-recent-dot{width:8px;height:8px;border-radius:999px;background:var(--__P__-accent);flex-shrink:0}.__P__-home-recent-row[data-unread=true] .__P__-home-recent-title{font-weight:700}.__P__-home-status{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-status-icon svg{width:22px;height:22px;color:var(--__P__-success)}.__P__-home-status[data-level=degraded] .__P__-home-status-icon svg{color:var(--__P__-warning)}.__P__-home-status[data-level=down] .__P__-home-status-icon svg{color:var(--__P__-danger)}.__P__-home-status-text{font-weight:600;font-size:14px}.__P__-home-search{display:flex;align-items:center;gap:var(--__P__-space-2);width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);border:1px solid var(--__P__-border);background:var(--__P__-surface);text-align:left}.__P__-home-search[data-input=true]{background:var(--__P__-bg-elevated)}.__P__-home-search:hover{border-color:var(--__P__-border-strong)}.__P__-home-search:focus-visible,.__P__-home-search:focus-within{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-search-text{flex:1;color:var(--__P__-fg-muted);font-size:14px}.__P__-home-search-input{flex:1;border:0;background:transparent;font-size:14px;color:var(--__P__-fg);outline:none}.__P__-home-search-icon svg{width:18px;height:18px;color:var(--__P__-accent)}.__P__-list-row{display:flex;align-items:center;gap:var(--__P__-space-3);width:100%;min-height:44px;text-align:left;padding:var(--__P__-space-3) var(--__P__-space-2);border-radius:var(--__P__-radius-sm)}.__P__-list-row:hover{background:var(--__P__-bg-elevated)}.__P__-list-row:active{background:var(--__P__-border)}.__P__-list-row:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-list-row-body{display:flex;flex-direction:column;min-width:0;flex:1}.__P__-list-row-title{font-weight:600;font-size:var(--__P__-text-md);line-height:1.35}.__P__-list-row-sub{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);margin-top:var(--__P__-space-1);line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-list-row-chevron svg{width:18px;height:18px;color:var(--__P__-accent);flex-shrink:0}.__P__-back-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);flex-shrink:0}.__P__-back-title{flex:1;text-align:center;font-size:var(--__P__-text-md);font-weight:700;margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-back-spacer{width:32px;height:1px}.__P__-content{display:flex;flex-direction:column;gap:14px;width:100%;max-width:68ch;margin:0 auto}.__P__-content-hero{width:100%;border-radius:var(--__P__-radius)}.__P__-content-subtitle{color:var(--__P__-fg-muted);margin:0}.__P__-content-frame{flex:1;min-height:0;width:100%;border:0;background:#fff}.__P__-news-list{display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-news-card{display:block;width:100%;text-align:left;border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden;background:var(--__P__-surface)}.__P__-news-card{transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-news-card:hover{background:var(--__P__-bg-elevated)}.__P__-news-card:active{transform:translateY(1px)}.__P__-news-card:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-news-hero{width:100%;display:block}.__P__-news-body{display:flex;flex-direction:column;gap:6px;padding:14px 16px}.__P__-news-tags{display:flex;gap:6px;flex-wrap:wrap}.__P__-news-tag{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);padding:2px 8px;border-radius:999px}.__P__-news-title{font-weight:700;font-size:var(--__P__-text-md)}.__P__-news-summary{color:var(--__P__-fg-muted);font-size:14px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-modules-empty{display:flex;align-items:center;justify-content:center;position:relative}.__P__-modules-empty-close{position:absolute;top:12px;right:12px}.__P__-modules-empty-text{color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}\n';
928
+ var panel_default = '.__P__-anchor{right:16px;bottom:16px}:host([data-position="bottom-left"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{right:auto;left:16px}:host([data-position="top-right"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{bottom:auto;top:16px}.__P__-anchor{position:fixed;display:flex;flex-direction:column;align-items:flex-end;gap:var(--__P__-space-3);pointer-events:none}.__P__-anchor{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=sm]{--__P__-fab-size: 44px}.__P__-anchor[data-launcher-size=md]{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=lg]{--__P__-fab-size: 68px}.__P__-anchor>*{pointer-events:auto}.__P__-fab[data-size=sm]{--__P__-fab-size: 44px;font-size:var(--__P__-text-sm)}.__P__-fab[data-size=md]{--__P__-fab-size: 56px;font-size:14px}.__P__-fab[data-size=lg]{--__P__-fab-size: 68px;font-size:var(--__P__-text-base)}.__P__-fab{display:inline-flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);color:var(--__P__-accent-text);background:var(--__P__-accent);box-shadow:var(--__P__-shadow-fab);font-weight:600;line-height:1;transform-origin:bottom right;animation:__P__-fab-in var(--__P__-dur-base) var(--__P__-ease) both;transition:transform var(--__P__-dur-base) var(--__P__-ease),opacity var(--__P__-dur-base) var(--__P__-ease),box-shadow var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab:hover{transform:translateY(-2px)}.__P__-fab:active{transform:translateY(0)}.__P__-fab:focus-visible{outline:2px solid var(--__P__-on-accent);outline-offset:3px}.__P__-fab svg{width:24px;height:24px;flex-shrink:0}@keyframes __P__-fab-in{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:none}}.__P__-fab[data-leaving]{position:absolute;right:0;bottom:0;animation:__P__-fab-out var(--__P__-dur-quick) var(--__P__-ease) forwards;pointer-events:none}:host([data-position^="top-"]) .__P__-fab[data-leaving]{bottom:auto;top:0}:host([data-position$="-left"]) .__P__-fab[data-leaving]{right:auto;left:0}@keyframes __P__-fab-out{0%{opacity:1;transform:none}to{opacity:0;transform:scale(.85)}}.__P__-fab[data-variant=circle]{width:var(--__P__-fab-size);height:var(--__P__-fab-size);border-radius:999px}.__P__-fab[data-variant=circle] .__P__-fab-label{display:none}.__P__-fab[data-variant=pill]{height:var(--__P__-fab-size);padding:0 18px 0 16px;border-radius:999px}.__P__-fab[data-variant=bar]{height:var(--__P__-fab-size);padding:0 22px;border-radius:var(--__P__-radius)}.__P__-fab[data-variant=minimal]{height:var(--__P__-fab-size);padding:0 var(--__P__-space-4);border-radius:999px;background:transparent;color:var(--__P__-accent);box-shadow:none;border:1px solid currentColor}.__P__-fab[data-variant=minimal]:hover{background:color-mix(in srgb,var(--__P__-accent) 12%,transparent)}.__P__-callout{--__P__-callout-fab-h: var(--__P__-fab-size, 56px);--__P__-callout-gap: clamp(12px, calc(var(--__P__-callout-fab-h) * .25), 22px);--__P__-callout-nudge-direction: -1;position:absolute;display:inline-flex;align-items:center;gap:var(--__P__-space-2);padding:10px 14px;background:var(--__P__-fg);color:var(--__P__-bg);border-radius:999px;font-size:var(--__P__-text-sm);font-weight:600;line-height:1.2;box-shadow:0 10px 30px -8px #00000059;pointer-events:auto;animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease);z-index:1;max-width:240px;white-space:nowrap}.__P__-callout[data-position=left]{right:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%)}.__P__-callout[data-position=right]{left:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%);--__P__-callout-nudge-direction: 1}.__P__-callout[data-position=top]{bottom:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-position=bottom]{top:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}:host([data-position$="-left"]) .__P__-callout[data-position=top],:host([data-position$="-left"]) .__P__-callout[data-position=bottom]{right:auto;left:0}.__P__-callout[data-shape=bubble]{border-radius:var(--__P__-radius-md);white-space:normal;width:max-content;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-shape=callout]{padding:12px 18px;font-size:14px;background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-callout:after{content:"";position:absolute;width:12px;height:12px;background:inherit;border-radius:2px;transform:rotate(45deg)}.__P__-callout[data-position=left]:after{right:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=right]:after{left:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=top]:after{bottom:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-position=bottom]:after{top:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}:host([data-position$="-left"]) .__P__-callout[data-position=top]:after,:host([data-position$="-left"]) .__P__-callout[data-position=bottom]:after{right:auto;left:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-animated]{animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease),__P__-callout-nudge 1.6s var(--__P__-ease-in-out) var(--__P__-dur-slow) infinite}@keyframes __P__-callout-in{0%{opacity:0}to{opacity:1}}@keyframes __P__-callout-nudge{0%,to{margin-left:0;margin-right:0}50%{margin-left:calc(6px * var(--__P__-callout-nudge-direction));margin-right:calc(-6px * var(--__P__-callout-nudge-direction))}}@media(prefers-reduced-motion:reduce){.__P__-callout[data-animated]{animation:__P__-callout-in 1ms var(--__P__-ease)}.__P__-icon-btn[data-recording=true],.__P__-typing span{animation:none}}.__P__-callout-close{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:inherit;opacity:.7;cursor:pointer}.__P__-callout-close:hover{opacity:1;background:#ffffff26}.__P__-callout-close svg{width:12px;height:12px}.__P__-panel{width:var(--__P__-panel-w);height:var(--__P__-panel-h);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);background:var(--__P__-bg);color:var(--__P__-fg);border-radius:var(--__P__-radius-lg);box-shadow:var(--__P__-shadow-panel);display:flex;flex-direction:column;overflow:hidden;transform-origin:bottom right;animation:__P__-panel-in var(--__P__-dur-slow) var(--__P__-ease);border:1px solid var(--__P__-border)}:host([data-mode="open"]) .__P__-panel{width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));min-width:var(--__P__-resize-min-w, auto);min-height:var(--__P__-resize-min-h, auto);max-width:var(--__P__-resize-max-w, calc(100vw - 32px) );max-height:var(--__P__-resize-max-h, calc(100dvh - 32px) )}@keyframes __P__-panel-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}:host([data-mode="expanded"]) .__P__-panel{width:var(--__P__-expanded-w, 640px);height:var(--__P__-expanded-h, 820px);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px)}:host([data-mode="fullscreen"]){z-index:var(--__P__-z-panel)!important}:host([data-mode="fullscreen"]) .__P__-anchor{inset:0;align-items:stretch;padding:0}:host([data-mode="fullscreen"]) .__P__-panel{width:100vw;height:100dvh;max-width:none;max-height:none;border-radius:0;border:0}:host([data-mode="fullscreen"]) .__P__-fab{display:none}:host([data-mode="inline"]) .__P__-anchor,:host([data-mode="standalone"]) .__P__-anchor{position:static;inset:auto;padding:0;align-items:stretch;width:100%;height:100%;min-height:0}:host([data-mode="inline"]) .__P__-panel,:host([data-mode="standalone"]) .__P__-panel{width:100%;height:100%;min-width:0;min-height:0;max-width:none;max-height:none;animation:none}:host([data-mode="inline"]) .__P__-fab,:host([data-mode="standalone"]) .__P__-fab{display:none}:host([data-mode="inline"]){min-height:320px}:host([data-mode="inline"]) .__P__-panel{border-radius:var(--__P__-radius)}:host([data-mode="standalone"]) .__P__-panel{border-radius:0;border:0;box-shadow:none}:host([data-mode="modal"]){position:fixed!important;inset:0!important;z-index:var(--__P__-z-panel)!important;display:block!important;width:100vw;height:100dvh;background:var(--__P__-modal-backdrop, var(--__P__-backdrop));animation:__P__-backdrop-in var(--__P__-dur-base) var(--__P__-ease) both;--__P__-panel-w: min(960px, 92vw);--__P__-panel-h: min(720px, 88dvh)}:host([data-mode="modal"]) .__P__-anchor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:var(--__P__-space-6);pointer-events:none}:host([data-mode="modal"]) .__P__-panel{pointer-events:auto;width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));max-width:calc(100vw - 48px);max-height:calc(100dvh - 48px);min-width:0;min-height:0;border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-panel);animation:__P__-modal-in var(--__P__-dur-base) var(--__P__-ease);translate:var(--__P__-modal-dx, 0px) var(--__P__-modal-dy, 0px)}:host([data-mode="modal"]) .__P__-header,:host([data-mode="modal"]) .__P__-back-header,:host([data-mode="modal"]) .__P__-home-hero{cursor:grab;touch-action:none}:host([data-mode="modal"]) .__P__-panel[data-dragging]{cursor:grabbing;user-select:none}:host([data-mode="modal"]) .__P__-panel[data-dragging] *{cursor:grabbing}:host([data-mode="modal"]) .__P__-fab{display:none}@keyframes __P__-backdrop-in{0%{background:#0000}to{background:var(--__P__-modal-backdrop, var(--__P__-backdrop))}}@keyframes __P__-modal-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}:host([data-mode="drawer"]){--__P__-panel-w: min(440px, calc(100vw - 32px) );--__P__-panel-h: 100dvh}:host([data-mode="drawer"]) .__P__-anchor{position:fixed;--__P__-inset-x: var(--__P__-panel-inset, 12px);--__P__-inset-y: var(--__P__-panel-inset, 3dvh);top:var(--__P__-inset-y);bottom:auto;right:var(--__P__-inset-x);left:auto;width:min(var(--__P__-widget-w, var(--__P__-panel-w)),calc(100vw - var(--__P__-inset-x) * 2));height:min(var(--__P__-widget-h, var(--__P__-panel-h)),calc(100dvh - var(--__P__-inset-y) * 2));padding:0;display:block;pointer-events:auto}:host([data-mode="drawer"][data-position$="-left"]) .__P__-anchor{right:auto;left:var(--__P__-inset-x)}:host([data-mode="drawer"][data-position^="bottom-"]) .__P__-anchor{top:auto;bottom:var(--__P__-inset-y)}:host([data-mode="drawer"]) .__P__-panel{width:100%;height:100%;max-width:none;max-height:none;min-width:0;min-height:0;border-radius:var(--__P__-radius, 12px);border:1px solid var(--__P__-border);box-shadow:-8px 16px 32px -12px #00000038;animation:__P__-drawer-in var(--__P__-dur-base) var(--__P__-ease)}:host([data-mode="drawer"][data-position$="-left"]) .__P__-panel{box-shadow:8px 16px 32px -12px #00000038;animation:__P__-drawer-in-left var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab[data-edge-tab]{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-2);position:fixed;top:50%;height:140px;width:auto;min-width:0;padding:10px 8px;writing-mode:vertical-rl;text-orientation:mixed;transform:translateY(-50%);transform-origin:center;animation:__P__-edge-tab-in var(--__P__-dur-base) var(--__P__-ease) both}.__P__-fab[data-edge-tab] svg{writing-mode:horizontal-tb}.__P__-fab[data-edge-tab]:hover{transform:translateY(-50%) scale(1.03)}.__P__-fab[data-edge-tab]:active{transform:translateY(-50%) scale(.97)}:host([data-position$="-right"]) .__P__-fab[data-edge-tab]{right:0;left:auto;border-radius:12px 0 0 12px;box-shadow:-6px 0 18px -8px #0000004d}:host([data-position$="-left"]) .__P__-fab[data-edge-tab]{left:0;right:auto;border-radius:0 12px 12px 0;box-shadow:6px 0 18px -8px #0000004d}.__P__-fab[data-edge-tab][data-leaving]{position:fixed;top:50%;bottom:auto;animation:__P__-edge-tab-out var(--__P__-dur-quick) var(--__P__-ease) forwards}@keyframes __P__-edge-tab-in{0%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:1;transform:translateY(-50%) scale(1)}}@keyframes __P__-edge-tab-out{0%{opacity:1;transform:translateY(-50%) scale(1)}to{opacity:0;transform:translateY(-50%) scale(.85)}}@keyframes __P__-drawer-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes __P__-drawer-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}@media(prefers-reduced-motion:reduce){:host([data-mode="drawer"]) .__P__-panel,.__P__-fab[data-edge-tab]{animation:none}}.__P__-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);background:var(--__P__-bg)}.__P__-header h1{font-size:14px;font-weight:600;flex:1;letter-spacing:-.01em}.__P__-header-actions{margin-left:auto;display:flex;align-items:center;gap:var(--__P__-space-1);flex-shrink:0}.__P__-agent{flex:1;display:inline-flex;align-items:center;gap:10px;min-width:0}.__P__-agent-avatar{position:relative;width:32px;height:32px;border-radius:999px;background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--__P__-text-xs);overflow:hidden;flex-shrink:0}.__P__-agent-avatar img{width:100%;height:100%;object-fit:cover}.__P__-agent-avatar:after{content:"";position:absolute;right:-1px;bottom:-1px;width:10px;height:10px;border-radius:999px;border:2px solid var(--__P__-bg);background:var(--__P__-neutral)}.__P__-agent-avatar[data-status=online]:after{background:var(--__P__-success)}.__P__-agent-avatar[data-status=away]:after{background:var(--__P__-warning)}.__P__-agent-avatar[data-status=offline]:after{background:var(--__P__-neutral)}.__P__-agent-meta{display:flex;flex-direction:column;line-height:1.15;min-width:0}.__P__-agent-meta strong{font-size:14px;font-weight:600;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-agent-meta span{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-suggestions{display:flex;flex-wrap:nowrap;gap:var(--__P__-space-2);padding:6px 14px 10px;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scroll-snap-type:x proximity;scrollbar-width:none;-ms-overflow-style:none;min-width:0}.__P__-suggestions::-webkit-scrollbar{display:none}.__P__-suggestions:before,.__P__-suggestions:after{content:"";flex:1 1 0;min-width:0}.__P__-suggestion{flex:0 0 auto;scroll-snap-align:center;padding:7px 14px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg);font-size:var(--__P__-text-sm);font-weight:500;white-space:nowrap;transition:background var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-suggestion:hover{border-color:var(--__P__-accent);color:var(--__P__-accent);transform:translateY(-1px)}.__P__-suggestion:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px;border-color:var(--__P__-accent)}.__P__-suggestion:active{transform:translateY(0)}.__P__-icon-btn{width:32px;height:32px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);transition:background var(--__P__-dur-quick) var(--__P__-ease),color var(--__P__-dur-quick) var(--__P__-ease)}.__P__-icon-btn:hover{background:var(--__P__-bg-elevated);color:var(--__P__-fg)}.__P__-icon-btn:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-icon-btn:active{background:var(--__P__-border)}.__P__-icon-btn:disabled{opacity:.45;cursor:not-allowed}.__P__-icon-btn:before{content:"";position:absolute;inset:-6px}.__P__-icon-btn{position:relative}.__P__-icon-btn svg{width:18px;height:18px}.__P__-icon-btn[data-recording=true]{color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);animation:__P__-pulse 1.2s var(--__P__-ease) infinite}@keyframes __P__-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--__P__-accent) 40%,transparent)}50%{box-shadow:0 0 0 6px color-mix(in srgb,var(--__P__-accent) 0%,transparent)}}.__P__-list-wrap{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}.__P__-jump{position:absolute;right:14px;bottom:14px;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:999px;border:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);color:var(--__P__-fg);box-shadow:var(--__P__-shadow-panel);cursor:pointer;opacity:.85;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease);animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-jump:hover{opacity:1}.__P__-jump:active{transform:translateY(1px)}.__P__-jump svg{width:18px;height:18px}.__P__-list{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-4);padding-bottom:var(--__P__-space-8);display:flex;flex-direction:column;gap:14px;scrollbar-width:thin;scrollbar-color:var(--__P__-border-strong) transparent;scrollbar-gutter:stable}.__P__-list::-webkit-scrollbar{width:8px}.__P__-list::-webkit-scrollbar-thumb{background:var(--__P__-border-strong);border-radius:8px}.__P__-date-divider{position:sticky;top:var(--__P__-space-2);z-index:2;display:flex;justify-content:center;margin:var(--__P__-space-1) 0;pointer-events:none}.__P__-date-pill{padding:3px 10px;border-radius:999px;font-size:11px;font-weight:600;color:var(--__P__-fg-muted);background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);box-shadow:var(--__P__-shadow-card);opacity:0;pointer-events:none;transition:opacity var(--__P__-dur-base) var(--__P__-ease)}.__P__-list[data-scrolling=true] .__P__-date-pill{opacity:1;pointer-events:auto}@media(prefers-reduced-motion:reduce){.__P__-date-pill{transition:none}}.__P__-bubble-row{display:flex}.__P__-bubble-row[data-role=user]{justify-content:flex-end}.__P__-bubble-row[data-role=assistant]{justify-content:flex-start}.__P__-bubble{max-width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);line-height:1.6;font-size:14px;word-wrap:break-word;overflow-wrap:anywhere;box-shadow:0 1px 2px #0000000a,0 1px 8px -4px #0000000f;animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-bubble ::selection{background:color-mix(in srgb,var(--__P__-accent) 30%,transparent)}.__P__-bubble-row[data-role=user] .__P__-bubble ::selection{background:#fff6;color:var(--__P__-bubble-user-text)}@keyframes __P__-bubble-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.__P__-bubble-row[data-role=user] .__P__-bubble{background:var(--__P__-bubble-user);color:var(--__P__-bubble-user-text);border-bottom-right-radius:5px}.__P__-bubble-row[data-role=assistant] .__P__-bubble{background:var(--__P__-bubble-assistant);color:var(--__P__-bubble-assistant-text);border-bottom-left-radius:5px}.__P__-bubble-col{display:flex;flex-direction:column;max-width:85%;min-width:0}.__P__-bubble-row[data-role=user] .__P__-bubble-col{align-items:flex-end}.__P__-bubble-row[data-role=assistant] .__P__-bubble-col{align-items:flex-start}.__P__-bubble-time{margin-top:3px;padding:0 4px;font-size:11px;line-height:1;color:var(--__P__-fg-muted);user-select:none}.__P__-md>*:first-child{margin-top:0}.__P__-md>*:last-child{margin-bottom:0}.__P__-md p{margin:10px 0}.__P__-md h1,.__P__-md h2,.__P__-md h3,.__P__-md h4,.__P__-md h5,.__P__-md h6{margin:18px 0 8px;line-height:1.3;letter-spacing:-.01em;font-weight:700}.__P__-md h1{font-size:1.4em}.__P__-md h2{font-size:1.22em}.__P__-md h3{font-size:1.08em}.__P__-md h4,.__P__-md h5,.__P__-md h6{font-size:1em}.__P__-md>h1:first-child,.__P__-md>h2:first-child,.__P__-md>h3:first-child,.__P__-md>h4:first-child,.__P__-md>h5:first-child,.__P__-md>h6:first-child{margin-top:0}.__P__-md ul,.__P__-md ol{padding-left:1.5em;margin:10px 0}.__P__-md ul{list-style:disc}.__P__-md ol{list-style:decimal}.__P__-md li{margin:6px 0;padding-left:2px}.__P__-md li::marker{color:var(--__P__-fg-muted)}.__P__-md li>p{margin:6px 0}.__P__-md li>ul,.__P__-md li>ol{margin:6px 0}.__P__-md strong,.__P__-md b{font-weight:650;letter-spacing:-.005em}.__P__-md em,.__P__-md i{font-style:italic}.__P__-md code{font-family:var(--__P__-font-mono);font-size:.86em;padding:1px 6px;border-radius:5px;background:color-mix(in srgb,var(--__P__-accent) 10%,transparent);color:var(--__P__-fg);border:1px solid color-mix(in srgb,var(--__P__-accent) 16%,transparent)}.__P__-md pre{font-family:var(--__P__-font-mono);font-size:12.5px;padding:12px 14px;border-radius:var(--__P__-radius-sm);background:#7f7f7f1f;overflow-x:auto;margin:var(--__P__-space-3) 0;line-height:1.5}.__P__-md pre code{padding:0;background:none}.__P__-md a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}.__P__-md a:hover{text-decoration-thickness:2px}.__P__-md blockquote{margin:14px 0;padding:6px 14px;border-left:3px solid color-mix(in srgb,var(--__P__-accent) 50%,transparent);background:color-mix(in srgb,var(--__P__-accent) 5%,transparent);border-radius:0 var(--__P__-radius-sm) var(--__P__-radius-sm) 0;color:var(--__P__-fg-muted)}.__P__-md blockquote>:first-child{margin-top:0}.__P__-md blockquote>:last-child{margin-bottom:0}.__P__-md hr{border:0;height:1px;background:color-mix(in srgb,currentColor 18%,transparent);margin:var(--__P__-space-4) 0}.__P__-md table{border-collapse:collapse;margin:var(--__P__-space-3) 0;font-size:.95em;display:block;overflow-x:auto;max-width:100%;font-variant-numeric:tabular-nums}.__P__-md th,.__P__-md td{padding:6px 10px;border-bottom:1px solid color-mix(in srgb,currentColor 12%,transparent);text-align:left}.__P__-md th{font-weight:700;background:color-mix(in srgb,currentColor 6%,transparent)}.__P__-md h1+ul,.__P__-md h1+ol,.__P__-md h2+ul,.__P__-md h2+ol,.__P__-md h3+ul,.__P__-md h3+ol,.__P__-md h4+ul,.__P__-md h4+ol{margin-top:var(--__P__-space-1)}.__P__-loading{display:inline-flex;align-items:center;gap:var(--__P__-space-2);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-loading-spinner{width:14px;height:14px;border-radius:999px;border:2px solid currentColor;border-top-color:transparent;animation:__P__-spin .8s linear infinite}@keyframes __P__-spin{to{transform:rotate(1turn)}}.__P__-typing{display:inline-flex;gap:var(--__P__-space-1);padding:var(--__P__-space-1) 0}.__P__-typing span{width:5px;height:5px;border-radius:999px;background:currentColor;opacity:.4;animation:__P__-blink 1.2s var(--__P__-ease) infinite}.__P__-typing span:nth-child(2){animation-delay:.2s}.__P__-typing span:nth-child(3){animation-delay:.4s}@keyframes __P__-blink{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}.__P__-reasoning{margin:var(--__P__-space-1) 0 var(--__P__-space-2);padding-left:var(--__P__-space-3);border-left:2px solid var(--__P__-border-strong)}.__P__-reasoning-summary{display:inline-flex;align-items:center;gap:var(--__P__-space-1);cursor:pointer;list-style:none;user-select:none;color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600}.__P__-reasoning-summary::-webkit-details-marker{display:none}.__P__-reasoning-summary:before{content:"";width:5px;height:5px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);opacity:.7;transition:transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-reasoning[open] .__P__-reasoning-summary:before{transform:rotate(45deg)}.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:__P__-reasoning-pulse 1.4s var(--__P__-ease) infinite}@keyframes __P__-reasoning-pulse{0%,to{opacity:.5}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:none}}.__P__-reasoning-body{margin-top:var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-reasoning-body>:first-child{margin-top:0}.__P__-reasoning-body>:last-child{margin-bottom:0}.__P__-tool-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2);margin-top:6px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs)}.__P__-composer{border-top:1px solid var(--__P__-border);padding:10px 12px;background:var(--__P__-bg);display:flex;flex-direction:column;gap:var(--__P__-space-2)}.__P__-composer-row{display:flex;align-items:flex-end;gap:6px}.__P__-textarea{flex:1;height:40px;max-height:160px;padding:10px 12px;border-radius:var(--__P__-radius);background:var(--__P__-bg-elevated);border:1px solid transparent;font-size:14px;line-height:1.4;transition:height var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),box-shadow var(--__P__-dur-quick) var(--__P__-ease)}.__P__-textarea:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:1px;border-color:var(--__P__-focus)}@media(pointer:coarse){.__P__-textarea,.__P__-home-search-input{font-size:16px}.__P__-textarea{height:44px}}.__P__-send{width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease),background var(--__P__-dur-quick) var(--__P__-ease)}.__P__-send[data-shape=circle]{border-radius:999px}.__P__-send[data-shape=square]{border-radius:var(--__P__-radius-sm)}.__P__-send[data-shape=pill]{width:auto;padding:0 18px;border-radius:999px}.__P__-send[data-variant=filled]{background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-send[data-variant=outline]{background:transparent;color:var(--__P__-accent);border-color:var(--__P__-accent)}.__P__-send[data-variant=outline]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 10%,transparent)}.__P__-send[data-variant=ghost]{background:transparent;color:var(--__P__-accent)}.__P__-send[data-variant=ghost]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 8%,transparent)}.__P__-send:disabled{opacity:.4;cursor:not-allowed}.__P__-send:not(:disabled):hover{transform:translateY(-1px)}.__P__-send:not(:disabled):active{transform:translateY(0)}.__P__-send:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-send svg{width:18px;height:18px}.__P__-composer-actions{display:flex;gap:var(--__P__-space-1);flex-wrap:wrap}.__P__-attachments{display:flex;flex-wrap:wrap;gap:6px}.__P__-attachment-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-1);border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);font-size:var(--__P__-text-xs);max-width:200px}.__P__-attachment-thumb{width:24px;height:24px;border-radius:999px;object-fit:cover;background:var(--__P__-border)}.__P__-attachment-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-attachment-remove{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted)}.__P__-attachment-remove:hover{background:var(--__P__-border);color:var(--__P__-fg)}.__P__-dropzone{position:absolute;inset:8px;border:2px dashed var(--__P__-accent);border-radius:var(--__P__-radius);background:color-mix(in srgb,var(--__P__-accent) 8%,transparent);display:flex;align-items:center;justify-content:center;font-weight:600;color:var(--__P__-accent);pointer-events:none;z-index:10;animation:__P__-fade-in var(--__P__-dur-quick) var(--__P__-ease)}@keyframes __P__-fade-in{0%{opacity:0}to{opacity:1}}.__P__-error{margin-top:var(--__P__-space-1);padding:8px 10px;border-radius:var(--__P__-radius-sm);background:var(--__P__-danger-bg);color:var(--__P__-danger-text);font-size:var(--__P__-text-sm);display:flex;align-items:center;gap:var(--__P__-space-2)}.__P__-error button{color:inherit;text-decoration:underline;font-size:var(--__P__-text-sm)}.__P__-history{flex:1;overflow-y:auto;padding:var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-3)}.__P__-history-footer{flex:none;padding:var(--__P__-space-2) var(--__P__-space-3) var(--__P__-space-3);border-top:1px solid var(--__P__-border);background:var(--__P__-surface)}.__P__-history-new{width:100%;display:flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);padding:var(--__P__-space-2) var(--__P__-space-3);border:none;border-radius:var(--__P__-radius-md);background:var(--__P__-accent);color:var(--__P__-on-accent);cursor:pointer;font-size:var(--__P__-text-sm);font-weight:600;transition:filter var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-history-new svg{width:16px;height:16px}.__P__-history-new:hover{filter:brightness(1.08)}.__P__-history-new:active{transform:translateY(1px)}.__P__-history-new:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-history-empty{flex:1;display:flex;align-items:center;justify-content:center;padding:40px 16px;color:var(--__P__-fg-muted);font-size:14px;text-align:center}.__P__-history-group{display:flex;flex-direction:column;padding:0 var(--__P__-space-2)}.__P__-history-heading{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-fg-muted);padding:12px 8px 6px;text-transform:uppercase;letter-spacing:.04em}.__P__-history-item{all:unset;display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:var(--__P__-radius-md);cursor:pointer;transition:background var(--__P__-dur-base) var(--__P__-ease)}.__P__-history-item:hover{background:var(--__P__-bg-elevated)}.__P__-history-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-history-title{font-size:14px;font-weight:500;color:var(--__P__-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-preview{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-item[data-closed=true] .__P__-history-title:after{content:"\\2022";margin-left:var(--__P__-space-2);opacity:.5}.__P__-list-loading{margin:auto;padding:var(--__P__-space-6) var(--__P__-space-4);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);text-align:center}.__P__-readonly-banner{display:flex;flex-direction:column;align-items:center;gap:10px;padding:14px 12px;margin:0 var(--__P__-space-3) var(--__P__-space-3);border-radius:var(--__P__-radius-md);background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);text-align:center;font-size:var(--__P__-text-sm)}.__P__-readonly-label{line-height:1.4}.__P__-readonly-cta{appearance:none;border:0;cursor:pointer;padding:var(--__P__-space-2) var(--__P__-space-4);border-radius:999px;background:var(--__P__-accent);color:var(--__P__-accent-text, #fff);font:inherit;font-weight:600;font-size:var(--__P__-text-sm);transition:filter var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-readonly-cta:hover,.__P__-readonly-cta:focus-visible{filter:brightness(1.1)}.__P__-readonly-cta:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px}.__P__-composer-footer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:10px 16px;margin:0 var(--__P__-space-3);border-top:1px solid var(--__P__-border);text-align:center;font-size:11px;line-height:1.4;color:var(--__P__-fg-muted)}.__P__-disclaimer{max-width:320px;margin:0 auto;opacity:.9;letter-spacing:.01em}.__P__-poweredby{display:inline-flex;align-items:center;justify-content:center;gap:6px;color:inherit;text-decoration:none;opacity:.7;transition:opacity var(--__P__-dur-base) var(--__P__-ease);font-size:11px;letter-spacing:.02em}.__P__-poweredby:hover{opacity:1}.__P__-poweredby-logo{height:12px;width:auto;display:inline-block;vertical-align:middle}.__P__-poweredby-bar{flex:none;display:flex;align-items:center;justify-content:center;padding:6px 16px;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated)}.__P__-menu-wrap{position:relative;display:inline-flex}.__P__-menu{position:absolute;top:100%;right:0;margin-top:6px;min-width:200px;padding:6px;background:var(--__P__-bg);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);box-shadow:var(--__P__-shadow-panel);z-index:10;display:flex;flex-direction:column;gap:2px;animation:__P__-menu-in var(--__P__-dur-base) var(--__P__-ease)}@media(prefers-reduced-motion:reduce){.__P__-menu{animation:none}}@keyframes __P__-menu-in{0%{opacity:0;transform:translateY(-4px) scale(.98);transform-origin:top right}to{opacity:1;transform:none}}.__P__-menu-item{all:unset;display:flex;align-items:center;gap:10px;padding:8px 10px;font-size:var(--__P__-text-sm);color:var(--__P__-fg);border-radius:var(--__P__-radius-sm);cursor:pointer;user-select:none}.__P__-menu-item:hover{background:var(--__P__-bg-elevated)}.__P__-menu-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-menu-item[disabled]{opacity:.45;cursor:not-allowed}.__P__-menu-icon{display:inline-flex;width:16px;height:16px;color:var(--__P__-fg-muted)}.__P__-menu-icon svg{width:16px;height:16px}.__P__-menu-label{flex:1}.__P__-menu-check{display:inline-flex;color:var(--__P__-accent)}.__P__-menu-check svg{width:14px;height:14px}.__P__-resize-grip{position:absolute;width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);opacity:.45;transition:opacity var(--__P__-dur-base) var(--__P__-ease);z-index:2;touch-action:none;user-select:none}.__P__-resize-grip:hover,.__P__-resize-grip:focus-visible{opacity:1}.__P__-resize-grip svg{width:10px;height:10px}.__P__-resize-grip--bottom-left{bottom:2px;left:2px;cursor:nesw-resize;transform:scaleX(-1)}.__P__-resize-grip--bottom-right{bottom:2px;right:2px;cursor:nwse-resize}.__P__-resize-grip--top-left{top:2px;left:2px;cursor:nwse-resize;transform:rotate(180deg)}.__P__-resize-grip--top-right{top:2px;right:2px;cursor:nesw-resize;transform:scaleY(-1)}:host(:not([data-mode="open"])) .__P__-resize-grip{display:none}.__P__-messenger{display:flex;flex-direction:column;overflow:hidden}.__P__-messenger-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}.__P__-module{display:flex;flex-direction:column;height:100%;min-height:0}.__P__-module-scroll{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-3);display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-home{background:radial-gradient(125% 65% at 88% 0%,color-mix(in srgb,#fff 16%,transparent),transparent 55%),linear-gradient(180deg,var(--__P__-accent) 0%,var(--__P__-accent) 22%,color-mix(in srgb,var(--__P__-accent) 28%,var(--__P__-surface)) 44%,var(--__P__-surface) 70%);border-radius:var(--__P__-radius-lg) var(--__P__-radius-lg) 0 0}.__P__-home-scroll{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;background:transparent}.__P__-home-cards{display:flex;flex-direction:column;gap:var(--__P__-space-3);padding:4px 14px 16px}.__P__-module-pad{padding:var(--__P__-space-3) var(--__P__-space-3) 0}.__P__-module-empty{display:flex;flex-direction:column;align-items:center;gap:var(--__P__-space-3);padding:var(--__P__-space-8) var(--__P__-space-4);text-align:center;color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}.__P__-module-retry{padding:var(--__P__-space-2) var(--__P__-space-4);border:1px solid var(--__P__-border-strong);border-radius:var(--__P__-radius-sm);color:var(--__P__-fg);font-weight:600;cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),border-color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-module-retry:hover{background:var(--__P__-hover);border-color:var(--__P__-accent)}.__P__-module-retry:active{background:var(--__P__-border)}.__P__-module-retry:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-help-list{flex:1;min-height:0;overflow-y:auto;padding-bottom:var(--__P__-space-3)}.__P__-help-group{display:flex;flex-direction:column}.__P__-help-section-title{position:sticky;top:0;z-index:1;margin:0;padding:var(--__P__-space-3) var(--__P__-space-5) var(--__P__-space-2);font-size:var(--__P__-text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--__P__-fg-muted);background:var(--__P__-bg)}.__P__-help-card{margin:0 var(--__P__-space-3) var(--__P__-space-3);background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden}.__P__-help-card .__P__-list-row{border-bottom:0;border-radius:0}.__P__-help-card .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-help-card .__P__-list-row:hover{background:var(--__P__-hover)}.__P__-module-cta{padding:var(--__P__-space-3);border-top:1px solid var(--__P__-border)}.__P__-tabbar{display:flex;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);flex-shrink:0}.__P__-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-1);min-height:48px;padding:var(--__P__-space-2) var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600;transition:color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-tab:hover{color:var(--__P__-fg)}.__P__-tab[aria-selected=true]{color:var(--__P__-accent)}.__P__-tab:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-tab:active{background:var(--__P__-hover)}.__P__-tab-icon{position:relative;display:inline-flex}.__P__-tab-icon svg{width:22px;height:22px}.__P__-tab-badge{position:absolute;top:-4px;left:calc(50% + 6px);min-width:16px;height:16px;padding:0 4px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:var(--__P__-accent);color:var(--__P__-on-accent);font-size:10px;font-weight:600;line-height:1}.__P__-home-hero{flex-shrink:0;padding:var(--__P__-space-5) var(--__P__-space-5) var(--__P__-space-3);color:var(--__P__-on-accent);--__P__-focus: var(--__P__-on-accent)}.__P__-home-hero-top{display:flex;align-items:center;justify-content:space-between;gap:var(--__P__-space-3);min-height:32px}.__P__-home-brand{font-size:14px;font-weight:600;letter-spacing:.01em;color:color-mix(in srgb,#fff 82%,transparent);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.__P__-home-brand-spacer{flex:1}.__P__-home-hero-actions{display:flex;align-items:center;gap:var(--__P__-space-2);flex-shrink:0}.__P__-home-hero-actions .__P__-icon-btn{color:#fff}.__P__-home-greeting{margin:28px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;overflow-wrap:anywhere}.__P__-home-lead{margin:2px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;color:color-mix(in srgb,var(--__P__-on-accent) 88%,transparent);overflow-wrap:anywhere}.__P__-home-avatars{display:flex}.__P__-home-avatar{width:30px;height:30px;border-radius:999px;overflow:hidden;margin-left:-10px;border:2px solid color-mix(in srgb,#fff 92%,transparent);box-shadow:0 1px 3px #0000002e;background:var(--__P__-surface);display:inline-flex;align-items:center;justify-content:center;font-size:var(--__P__-text-xs);font-weight:700;color:var(--__P__-fg)}.__P__-home-avatar:first-child{margin-left:0}.__P__-home-avatar img{width:100%;height:100%;object-fit:cover}.__P__-home-content{background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-card);overflow:hidden}.__P__-home-content-title{padding:var(--__P__-space-4) var(--__P__-space-4) var(--__P__-space-3);font-size:var(--__P__-text-sm);font-weight:700}.__P__-home-content-list{display:flex;flex-direction:column;padding:0 var(--__P__-space-2) var(--__P__-space-2)}.__P__-home-content-list .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-home-card{display:block;width:100%;text-align:left;background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);padding:var(--__P__-space-4);box-shadow:var(--__P__-shadow-card)}.__P__-home-card[data-interactive=true]{cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-home-card[data-interactive=true]:hover{background:var(--__P__-bg-elevated)}.__P__-home-card[data-interactive=true]:active{transform:translateY(1px)}.__P__-home-card[data-interactive=true]:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-recent-row{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-recent-avatar{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;flex-shrink:0;border-radius:999px;background:color-mix(in oklch,var(--__P__-accent) 14%,transparent);color:var(--__P__-accent)}.__P__-home-recent-avatar svg{width:20px;height:20px}.__P__-home-recent-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.__P__-home-recent-title{font-weight:600;font-size:14px}.__P__-home-recent-preview{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-home-recent-at{color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);flex-shrink:0}.__P__-home-recent-dot{width:8px;height:8px;border-radius:999px;background:var(--__P__-accent);flex-shrink:0}.__P__-home-recent-row[data-unread=true] .__P__-home-recent-title{font-weight:700}.__P__-home-status{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-status-icon svg{width:22px;height:22px;color:var(--__P__-success)}.__P__-home-status[data-level=degraded] .__P__-home-status-icon svg{color:var(--__P__-warning)}.__P__-home-status[data-level=down] .__P__-home-status-icon svg{color:var(--__P__-danger)}.__P__-home-status-text{font-weight:600;font-size:14px}.__P__-home-search{display:flex;align-items:center;gap:var(--__P__-space-2);width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);border:1px solid var(--__P__-border);background:var(--__P__-surface);text-align:left}.__P__-home-search[data-input=true]{background:var(--__P__-bg-elevated)}.__P__-home-search:hover{border-color:var(--__P__-border-strong)}.__P__-home-search:focus-visible,.__P__-home-search:focus-within{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-search-text{flex:1;color:var(--__P__-fg-muted);font-size:14px}.__P__-home-search-input{flex:1;border:0;background:transparent;font-size:14px;color:var(--__P__-fg);outline:none}.__P__-home-search-icon svg{width:18px;height:18px;color:var(--__P__-accent)}.__P__-list-row{display:flex;align-items:center;gap:var(--__P__-space-3);width:100%;min-height:44px;text-align:left;padding:var(--__P__-space-3) var(--__P__-space-2);border-radius:var(--__P__-radius-sm)}.__P__-list-row:hover{background:var(--__P__-bg-elevated)}.__P__-list-row:active{background:var(--__P__-border)}.__P__-list-row:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-list-row-body{display:flex;flex-direction:column;min-width:0;flex:1}.__P__-list-row-title{font-weight:600;font-size:var(--__P__-text-md);line-height:1.35}.__P__-list-row-sub{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);margin-top:var(--__P__-space-1);line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-list-row-chevron svg{width:18px;height:18px;color:var(--__P__-accent);flex-shrink:0}.__P__-back-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);flex-shrink:0}.__P__-back-title{flex:1;text-align:center;font-size:var(--__P__-text-md);font-weight:700;margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-back-spacer{width:32px;height:1px}.__P__-content{display:flex;flex-direction:column;gap:14px;width:100%;max-width:68ch;margin:0 auto}.__P__-content-hero{width:100%;border-radius:var(--__P__-radius)}.__P__-content-subtitle{color:var(--__P__-fg-muted);margin:0}.__P__-content-frame{flex:1;min-height:0;width:100%;border:0;background:#fff}.__P__-news-list{display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-news-card{display:block;width:100%;text-align:left;border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden;background:var(--__P__-surface)}.__P__-news-card{transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-news-card:hover{background:var(--__P__-bg-elevated)}.__P__-news-card:active{transform:translateY(1px)}.__P__-news-card:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-news-hero{width:100%;display:block}.__P__-news-body{display:flex;flex-direction:column;gap:6px;padding:14px 16px}.__P__-news-tags{display:flex;gap:6px;flex-wrap:wrap}.__P__-news-tag{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);padding:2px 8px;border-radius:999px}.__P__-news-title{font-weight:700;font-size:var(--__P__-text-md)}.__P__-news-summary{color:var(--__P__-fg-muted);font-size:14px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-modules-empty{display:flex;align-items:center;justify-content:center;position:relative}.__P__-modules-empty-close{position:absolute;top:12px;right:12px}.__P__-modules-empty-text{color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}.__P__-form{display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-field{display:flex;flex-direction:column;gap:4px}.__P__-field-label{font-size:var(--__P__-text-sm);font-weight:600;color:var(--__P__-fg)}.__P__-field-req{color:var(--__P__-danger)}.__P__-field-input{width:100%;box-sizing:border-box;padding:var(--__P__-space-2) var(--__P__-space-3);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);background:var(--__P__-bg);color:var(--__P__-fg);font:inherit;font-size:var(--__P__-text-sm);resize:vertical;transition:border-color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-field-input:focus-visible{outline:none;border-color:var(--__P__-accent)}.__P__-field[data-invalid=true] .__P__-field-input{border-color:var(--__P__-danger)}.__P__-field-hint{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted)}.__P__-field-error{font-size:var(--__P__-text-xs);color:var(--__P__-danger)}.__P__-field-choices{display:flex;flex-direction:column;gap:6px}.__P__-choice{display:flex;align-items:flex-start;gap:8px;font-size:var(--__P__-text-sm);color:var(--__P__-fg);cursor:pointer}.__P__-choice input{margin-top:2px;accent-color:var(--__P__-accent)}.__P__-form-actions{display:flex;justify-content:flex-end;gap:var(--__P__-space-2);margin-top:2px}.__P__-form-submit,.__P__-tool-approve{padding:var(--__P__-space-2) var(--__P__-space-4);border:none;border-radius:var(--__P__-radius-md);background:var(--__P__-accent);color:var(--__P__-accent-text, #fff);font:inherit;font-weight:600;font-size:var(--__P__-text-sm);cursor:pointer;transition:filter var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-form-submit:hover:not(:disabled),.__P__-tool-approve:hover:not(:disabled){filter:brightness(1.06)}.__P__-form-submit:disabled{opacity:.6;cursor:default}.__P__-form-skip,.__P__-tool-reject{padding:var(--__P__-space-2) var(--__P__-space-4);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);background:transparent;color:var(--__P__-fg-muted);font:inherit;font-size:var(--__P__-text-sm);cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-form-skip:hover:not(:disabled),.__P__-tool-reject:hover:not(:disabled){background:var(--__P__-bg-elevated)}.__P__-intake{display:flex;flex-direction:column;gap:var(--__P__-space-2);padding:var(--__P__-space-3) var(--__P__-space-4) var(--__P__-space-4);border-top:1px solid var(--__P__-border);overflow-y:auto}.__P__-intake-title{margin:0;font-size:var(--__P__-text-base);font-weight:700;color:var(--__P__-fg)}.__P__-intake-desc{margin:0 0 var(--__P__-space-1);font-size:var(--__P__-text-sm);color:var(--__P__-fg-muted)}.__P__-tool-ask-input,.__P__-tool-approval{display:flex;flex-direction:column;gap:var(--__P__-space-2);margin-top:6px;padding:var(--__P__-space-3);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);background:var(--__P__-bg-elevated)}.__P__-tool-head{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.__P__-tool-badge{padding:2px 8px;border-radius:999px;background:var(--__P__-warning, #f59e0b);color:#1a1206;font-size:var(--__P__-text-xs);font-weight:600}.__P__-tool-title{font-size:var(--__P__-text-sm);color:var(--__P__-fg)}.__P__-tool-question{margin:0;font-size:var(--__P__-text-sm);font-weight:600;color:var(--__P__-fg)}.__P__-tool-desc{margin:0;font-size:var(--__P__-text-sm);color:var(--__P__-fg-muted)}.__P__-tool-args{margin:0;padding:var(--__P__-space-2);max-height:160px;overflow:auto;border-radius:var(--__P__-radius-sm);background:var(--__P__-bg);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);white-space:pre-wrap;word-break:break-word}.__P__-tool-stale-note{margin:0;font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted)}.__P__-tool-decided{flex-direction:row;align-items:center;flex-wrap:wrap;gap:8px}.__P__-tool-decided-label{padding:2px 8px;border-radius:999px;background:var(--__P__-bg);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600}.__P__-tool-decided-label[data-approved=true]{color:var(--__P__-success, #16a34a);border-color:var(--__P__-success, #16a34a)}.__P__-tool-decided-label[data-approved=false]{color:var(--__P__-danger);border-color:var(--__P__-danger)}.__P__-tool-decided-value{font-size:var(--__P__-text-sm);color:var(--__P__-fg)}\n';
771
929
 
772
930
  // src/styles/standalone.css
773
931
  var standalone_default = ".__P__-standalone-page{margin:0;height:100vh;background:var(--__P__-bg, #fff);display:grid;place-items:stretch}\n";
@@ -855,22 +1013,22 @@ function attachAdoptedSheet(shadow, doc) {
855
1013
  }
856
1014
  }
857
1015
  function applyThemeOverrides(host, overrides) {
858
- const p29 = BRAND.cssPrefix;
859
- if (overrides.accent) host.style.setProperty(`--${p29}-accent`, overrides.accent);
860
- if (overrides.accentText) host.style.setProperty(`--${p29}-accent-text`, overrides.accentText);
861
- if (overrides.radius) host.style.setProperty(`--${p29}-radius`, overrides.radius);
862
- if (overrides.fontFamily) host.style.setProperty(`--${p29}-font`, overrides.fontFamily);
1016
+ const p33 = BRAND.cssPrefix;
1017
+ if (overrides.accent) host.style.setProperty(`--${p33}-accent`, overrides.accent);
1018
+ if (overrides.accentText) host.style.setProperty(`--${p33}-accent-text`, overrides.accentText);
1019
+ if (overrides.radius) host.style.setProperty(`--${p33}-radius`, overrides.radius);
1020
+ if (overrides.fontFamily) host.style.setProperty(`--${p33}-font`, overrides.fontFamily);
863
1021
  }
864
1022
  function applyThemeMode(host, mode) {
865
1023
  host.dataset.theme = mode;
866
1024
  }
867
1025
  function applySize(host, size) {
868
- const p29 = BRAND.cssPrefix;
869
- if (size.width !== void 0) host.style.setProperty(`--${p29}-panel-w`, size.width);
870
- if (size.height !== void 0) host.style.setProperty(`--${p29}-panel-h`, size.height);
871
- if (size.expanded?.width !== void 0) host.style.setProperty(`--${p29}-expanded-w`, size.expanded.width);
872
- if (size.expanded?.height !== void 0) host.style.setProperty(`--${p29}-expanded-h`, size.expanded.height);
873
- if (size.inset !== void 0) host.style.setProperty(`--${p29}-panel-inset`, size.inset);
1026
+ const p33 = BRAND.cssPrefix;
1027
+ if (size.width !== void 0) host.style.setProperty(`--${p33}-panel-w`, size.width);
1028
+ if (size.height !== void 0) host.style.setProperty(`--${p33}-panel-h`, size.height);
1029
+ if (size.expanded?.width !== void 0) host.style.setProperty(`--${p33}-expanded-w`, size.expanded.width);
1030
+ if (size.expanded?.height !== void 0) host.style.setProperty(`--${p33}-expanded-h`, size.expanded.height);
1031
+ if (size.inset !== void 0) host.style.setProperty(`--${p33}-panel-inset`, size.inset);
874
1032
  }
875
1033
  function applyPosition(host, pos) {
876
1034
  host.dataset.position = pos;
@@ -1041,11 +1199,11 @@ function toBase64Url(json) {
1041
1199
  var nonEmpty = (ctx) => ctx && Object.keys(ctx).length > 0 ? ctx : void 0;
1042
1200
  function encodeContext(user, page) {
1043
1201
  const u = nonEmpty(user);
1044
- const p29 = nonEmpty(page);
1045
- if (!u && !p29) return void 0;
1202
+ const p33 = nonEmpty(page);
1203
+ if (!u && !p33) return void 0;
1046
1204
  const envelope = {};
1047
1205
  if (u) envelope.user = u;
1048
- if (p29) envelope.page = p29;
1206
+ if (p33) envelope.page = p33;
1049
1207
  return toBase64Url(JSON.stringify(envelope));
1050
1208
  }
1051
1209
 
@@ -1084,7 +1242,15 @@ var DEFAULT_PATHS = {
1084
1242
  markRead: "/ai/agent/mark-read",
1085
1243
  // ── CMS content (unified — Home / Help / News / docs) ─────────────
1086
1244
  /** All widget content via one filtered endpoint. `GET /ai/agent/content?tags=…`. */
1087
- content: "/ai/agent/content"
1245
+ content: "/ai/agent/content",
1246
+ /**
1247
+ * Optional pre-chat intake submission. POST `{ visitorId, sessionId, values,
1248
+ * skipped? }` → record the lead immediately (before/independent of the first
1249
+ * message), keyed by the same visitor + session as the conversation.
1250
+ * Overridable via `endpoints.intake`. Fire-and-forget; 404 on older backends
1251
+ * is ignored.
1252
+ */
1253
+ intake: "/ai/agent/intake"
1088
1254
  };
1089
1255
  var CONTEXT_PARAM = "context";
1090
1256
  function buildSendMessageRequest(params) {
@@ -1108,18 +1274,34 @@ function buildSendMessageRequest(params) {
1108
1274
  if (Object.keys(data).length > 0) body.data = data;
1109
1275
  return body;
1110
1276
  }
1277
+ function isResolvedToolPart(p33) {
1278
+ return p33.state === "output" || p33.state === "error" || p33.approval?.approved !== void 0;
1279
+ }
1111
1280
  function normalizeToolRef(ref) {
1112
1281
  if (typeof ref === "string") return ref ? { code: ref } : null;
1113
1282
  return ref?.code ? ref : null;
1114
1283
  }
1115
1284
  function messageToWireParts(m) {
1116
1285
  const out = [];
1117
- for (const p29 of m.parts) {
1118
- if (p29.kind === "text" && p29.text) {
1119
- out.push({ text: p29.text, type: "text" });
1286
+ for (const p33 of m.parts) {
1287
+ if (p33.kind === "text" && p33.text) {
1288
+ out.push({ text: p33.text, type: "text" });
1120
1289
  }
1121
- if (p29.kind === "file" && p29.url) {
1122
- out.push({ mediaType: p29.mediaType, type: "file", url: p29.url });
1290
+ if (p33.kind === "file" && p33.url) {
1291
+ out.push({ mediaType: p33.mediaType, type: "file", url: p33.url });
1292
+ }
1293
+ if (p33.kind === "tool" && isResolvedToolPart(p33)) {
1294
+ const part = {
1295
+ type: "tool",
1296
+ toolCallId: p33.toolCallId,
1297
+ toolName: p33.toolName,
1298
+ state: p33.state
1299
+ };
1300
+ if (p33.input !== void 0) part.input = p33.input;
1301
+ if (p33.output !== void 0) part.output = p33.output;
1302
+ if (p33.error !== void 0) part.errorText = p33.error;
1303
+ if (p33.approval && p33.approval.approved !== void 0) part.approval = p33.approval;
1304
+ out.push(part);
1123
1305
  }
1124
1306
  }
1125
1307
  for (const a of m.attachments ?? []) {
@@ -1366,6 +1548,25 @@ var AgentTransport = class {
1366
1548
  get transcribePath() {
1367
1549
  return this.opts.endpoints?.transcribe ?? "/ai/agent/transcribe-audio";
1368
1550
  }
1551
+ get intakePath() {
1552
+ return this.opts.endpoints?.intake ?? DEFAULT_PATHS.intake;
1553
+ }
1554
+ /**
1555
+ * Record a completed pre-chat intake form. Fire-and-forget — the lead is
1556
+ * captured even if the visitor never sends a message. `sessionId` is explicit
1557
+ * so the record ties to the conversation that follows; `visitorId` + context
1558
+ * ride the envelope. A failure (e.g. 404 on a backend that doesn't implement
1559
+ * the endpoint) is non-fatal — the values still reach the agent as
1560
+ * `userContext` on the next message, so callers don't await this.
1561
+ */
1562
+ async submitIntake(sessionId, values, skipped = false) {
1563
+ log4.debug("submitIntake \u2192", { sessionId, fields: Object.keys(values).length, skipped });
1564
+ try {
1565
+ await this.postJson(this.intakePath, { sessionId, values, skipped }, "submitIntake");
1566
+ } catch (err) {
1567
+ log4.debug("submitIntake failed (non-fatal)", { err });
1568
+ }
1569
+ }
1369
1570
  sendMessage(body) {
1370
1571
  log4.debug("message \u2192", {
1371
1572
  sessionId: body.sessionId,
@@ -1679,8 +1880,21 @@ function fromWireMessage(w) {
1679
1880
  if (part.type === "file") {
1680
1881
  return { kind: "file", url: part.url, mediaType: part.mediaType };
1681
1882
  }
1883
+ if (part.type === "tool") {
1884
+ return {
1885
+ kind: "tool",
1886
+ toolCallId: part.toolCallId,
1887
+ toolName: part.toolName,
1888
+ inputPartialSig: signal(""),
1889
+ inputSig: signal(part.input),
1890
+ outputSig: signal(part.output),
1891
+ errorSig: signal(part.errorText),
1892
+ stateSig: signal(part.state),
1893
+ approvalSig: signal(part.approval)
1894
+ };
1895
+ }
1682
1896
  return null;
1683
- }).filter((p29) => p29 !== null);
1897
+ }).filter((p33) => p33 !== null);
1684
1898
  return {
1685
1899
  id: w.id,
1686
1900
  role: w.role,
@@ -1710,45 +1924,62 @@ function assistantText(m) {
1710
1924
  }
1711
1925
  return out;
1712
1926
  }
1713
- function partToReactive(p29) {
1714
- if (p29.kind === "text" || p29.kind === "reasoning") {
1715
- return { kind: p29.kind, id: p29.id, textSig: signal(p29.text), doneSig: signal(p29.done) };
1927
+ function partToReactive(p33) {
1928
+ if (p33.kind === "text" || p33.kind === "reasoning") {
1929
+ return { kind: p33.kind, id: p33.id, textSig: signal(p33.text), doneSig: signal(p33.done) };
1716
1930
  }
1717
- if (p29.kind === "tool") {
1931
+ if (p33.kind === "tool") {
1718
1932
  return {
1719
1933
  kind: "tool",
1720
- toolCallId: p29.toolCallId,
1721
- toolName: p29.toolName,
1722
- inputPartialSig: signal(p29.inputPartial),
1723
- inputSig: signal(p29.input),
1724
- outputSig: signal(p29.output),
1725
- errorSig: signal(p29.error),
1726
- stateSig: signal(p29.state)
1934
+ toolCallId: p33.toolCallId,
1935
+ toolName: p33.toolName,
1936
+ inputPartialSig: signal(p33.inputPartial),
1937
+ inputSig: signal(p33.input),
1938
+ outputSig: signal(p33.output),
1939
+ errorSig: signal(p33.error),
1940
+ stateSig: signal(p33.state),
1941
+ approvalSig: signal(p33.approval)
1727
1942
  };
1728
1943
  }
1729
- return p29;
1944
+ return p33;
1730
1945
  }
1731
- function partFromReactive(p29) {
1732
- if (p29.kind === "text" || p29.kind === "reasoning") {
1733
- return { kind: p29.kind, id: p29.id, text: p29.textSig.value, done: p29.doneSig.value };
1946
+ function partFromReactive(p33) {
1947
+ if (p33.kind === "text" || p33.kind === "reasoning") {
1948
+ return { kind: p33.kind, id: p33.id, text: p33.textSig.value, done: p33.doneSig.value };
1734
1949
  }
1735
- if (p29.kind === "tool") {
1950
+ if (p33.kind === "tool") {
1736
1951
  return {
1737
1952
  kind: "tool",
1738
- toolCallId: p29.toolCallId,
1739
- toolName: p29.toolName,
1740
- inputPartial: p29.inputPartialSig.value,
1741
- input: p29.inputSig.value,
1742
- output: p29.outputSig.value,
1743
- error: p29.errorSig.value,
1744
- state: p29.stateSig.value
1953
+ toolCallId: p33.toolCallId,
1954
+ toolName: p33.toolName,
1955
+ inputPartial: p33.inputPartialSig.value,
1956
+ input: p33.inputSig.value,
1957
+ output: p33.outputSig.value,
1958
+ error: p33.errorSig.value,
1959
+ state: p33.stateSig.value,
1960
+ approval: p33.approvalSig.value
1745
1961
  };
1746
1962
  }
1747
- return p29;
1963
+ return p33;
1748
1964
  }
1749
1965
 
1750
1966
  // src/stream/reducer.ts
1751
1967
  import { signal as signal2 } from "@preact/signals";
1968
+
1969
+ // src/stream/constants.ts
1970
+ var ASK_USER_INPUT_TOOL = "tool:ask-user-input";
1971
+ function isAskUserInputTool(toolName) {
1972
+ if (!toolName) return false;
1973
+ const t = toolName.toLowerCase();
1974
+ return t === ASK_USER_INPUT_TOOL || t === "ask-user-input" || t === "ask_user_input";
1975
+ }
1976
+ var TRIGGER = {
1977
+ submitMessage: "submit-message",
1978
+ toolResult: "tool-result",
1979
+ toolApproval: "tool-approval"
1980
+ };
1981
+
1982
+ // src/stream/reducer.ts
1752
1983
  var log5 = logger.scope("reducer");
1753
1984
  var StreamReducer = class {
1754
1985
  constructor(messagesSig) {
@@ -1786,8 +2017,8 @@ var StreamReducer = class {
1786
2017
  ensureTextPart(m, "text", chunk.id);
1787
2018
  return;
1788
2019
  case "text-delta": {
1789
- const p29 = ensureTextPart(m, "text", chunk.id);
1790
- p29.textSig.value += chunk.delta;
2020
+ const p33 = ensureTextPart(m, "text", chunk.id);
2021
+ p33.textSig.value += chunk.delta;
1791
2022
  return;
1792
2023
  }
1793
2024
  case "text-end":
@@ -1797,8 +2028,8 @@ var StreamReducer = class {
1797
2028
  ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
1798
2029
  return;
1799
2030
  case "reasoning-delta": {
1800
- const p29 = ensureTextPart(m, "reasoning", chunk.id);
1801
- p29.textSig.value += chunk.delta;
2031
+ const p33 = ensureTextPart(m, "reasoning", chunk.id);
2032
+ p33.textSig.value += chunk.delta;
1802
2033
  return;
1803
2034
  }
1804
2035
  case "reasoning-end":
@@ -1809,6 +2040,7 @@ var StreamReducer = class {
1809
2040
  case "tool-input-available":
1810
2041
  case "tool-output-available":
1811
2042
  case "tool-output-error":
2043
+ case "tool-approval-request":
1812
2044
  applyTool(m, chunk);
1813
2045
  return;
1814
2046
  case "file":
@@ -1816,7 +2048,7 @@ var StreamReducer = class {
1816
2048
  return;
1817
2049
  case "source-url": {
1818
2050
  const parts = m.partsSig.value;
1819
- if (parts.some((p29) => p29.kind === "source" && p29.sourceId === chunk.sourceId)) return;
2051
+ if (parts.some((p33) => p33.kind === "source" && p33.sourceId === chunk.sourceId)) return;
1820
2052
  appendPart(m, { kind: "source", sourceId: chunk.sourceId, url: chunk.url, title: chunk.title });
1821
2053
  return;
1822
2054
  }
@@ -1840,14 +2072,14 @@ var StreamReducer = class {
1840
2072
  }
1841
2073
  };
1842
2074
  function ensureTextPart(m, kind, id) {
1843
- const existing = m.partsSig.value.find((p29) => p29.kind === kind && p29.id === id);
2075
+ const existing = m.partsSig.value.find((p33) => p33.kind === kind && p33.id === id);
1844
2076
  if (existing) return existing;
1845
2077
  const part = { kind, id, textSig: signal2(""), doneSig: signal2(false) };
1846
2078
  appendPart(m, part);
1847
2079
  return part;
1848
2080
  }
1849
2081
  function ensureToolPart(m, toolCallId, toolName) {
1850
- const existing = m.partsSig.value.find((p29) => p29.kind === "tool" && p29.toolCallId === toolCallId);
2082
+ const existing = m.partsSig.value.find((p33) => p33.kind === "tool" && p33.toolCallId === toolCallId);
1851
2083
  if (existing) return existing;
1852
2084
  const part = {
1853
2085
  kind: "tool",
@@ -1857,7 +2089,8 @@ function ensureToolPart(m, toolCallId, toolName) {
1857
2089
  inputSig: signal2(void 0),
1858
2090
  outputSig: signal2(void 0),
1859
2091
  errorSig: signal2(void 0),
1860
- stateSig: signal2("input")
2092
+ stateSig: signal2("input"),
2093
+ approvalSig: signal2(void 0)
1861
2094
  };
1862
2095
  appendPart(m, part);
1863
2096
  return part;
@@ -1871,26 +2104,32 @@ function applyTool(m, chunk) {
1871
2104
  ensureToolPart(m, chunk.toolCallId, chunk.toolName);
1872
2105
  return;
1873
2106
  case "tool-input-delta": {
1874
- const p29 = ensureToolPart(m, chunk.toolCallId);
1875
- p29.inputPartialSig.value += chunk.delta;
2107
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2108
+ p33.inputPartialSig.value += chunk.delta;
1876
2109
  return;
1877
2110
  }
1878
2111
  case "tool-input-available": {
1879
- const p29 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
1880
- p29.inputSig.value = chunk.input;
1881
- p29.stateSig.value = "awaiting";
2112
+ const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
2113
+ p33.inputSig.value = chunk.input;
2114
+ p33.stateSig.value = isAskUserInputTool(p33.toolName) ? "awaiting-input" : "awaiting";
2115
+ return;
2116
+ }
2117
+ case "tool-approval-request": {
2118
+ const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
2119
+ p33.approvalSig.value = { id: chunk.approvalId };
2120
+ p33.stateSig.value = "awaiting-approval";
1882
2121
  return;
1883
2122
  }
1884
2123
  case "tool-output-available": {
1885
- const p29 = ensureToolPart(m, chunk.toolCallId);
1886
- p29.outputSig.value = chunk.output;
1887
- p29.stateSig.value = "output";
2124
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2125
+ p33.outputSig.value = chunk.output;
2126
+ p33.stateSig.value = "output";
1888
2127
  return;
1889
2128
  }
1890
2129
  case "tool-output-error": {
1891
- const p29 = ensureToolPart(m, chunk.toolCallId);
1892
- p29.errorSig.value = chunk.errorText;
1893
- p29.stateSig.value = "error";
2130
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2131
+ p33.errorSig.value = chunk.errorText;
2132
+ p33.stateSig.value = "error";
1894
2133
  return;
1895
2134
  }
1896
2135
  default:
@@ -1910,6 +2149,7 @@ function createPersistence(widgetId, storage = defaultStorage) {
1910
2149
  const KEY_CALLOUT_DISMISSED = `${prefix}.calloutDismissed`;
1911
2150
  const KEY_SIDEBAR_COLLAPSED = `${prefix}.sidebarCollapsed`;
1912
2151
  const KEY_ACTIVE_MODULE = `${prefix}.activeModule`;
2152
+ const KEY_INTAKE = `${prefix}.intake`;
1913
2153
  const persistence = {
1914
2154
  getVisitorId() {
1915
2155
  const existing = storage.get(KEY_VISITOR);
@@ -1992,6 +2232,24 @@ function createPersistence(widgetId, storage = defaultStorage) {
1992
2232
  saveActiveModule(id) {
1993
2233
  storage.set(KEY_ACTIVE_MODULE, id);
1994
2234
  },
2235
+ loadIntake() {
2236
+ const raw = storage.get(KEY_INTAKE);
2237
+ if (!raw) return null;
2238
+ try {
2239
+ const parsed = JSON.parse(raw);
2240
+ return isPlainObject2(parsed) ? parsed : null;
2241
+ } catch (error) {
2242
+ log6.warn("loadIntake parse failed", { error });
2243
+ return null;
2244
+ }
2245
+ },
2246
+ saveIntake(values) {
2247
+ try {
2248
+ storage.set(KEY_INTAKE, JSON.stringify(values));
2249
+ } catch (error) {
2250
+ log6.warn("saveIntake serialise failed", { error });
2251
+ }
2252
+ },
1995
2253
  clearSession() {
1996
2254
  storage.remove(KEY_CHAT);
1997
2255
  }
@@ -2533,7 +2791,30 @@ var TID = {
2533
2791
  /** Help article row — suffix `-{id}`. */
2534
2792
  helpArticle: `${p2}-help-article`,
2535
2793
  /** News list item — suffix `-{id}`. */
2536
- newsItem: `${p2}-news-item`
2794
+ newsItem: `${p2}-news-item`,
2795
+ // ── Forms + human-in-the-loop (intake / ask-input / approval) ────
2796
+ /** Pre-chat intake form root (blocking gate). */
2797
+ intakeForm: `${p2}-intake-form`,
2798
+ /** Intake submit button. */
2799
+ intakeSubmit: `${p2}-intake-submit`,
2800
+ /** Intake skip button (only when `skippable`). */
2801
+ intakeSkip: `${p2}-intake-skip`,
2802
+ /** A single form field control — suffix `-{name}` at the JSX site. */
2803
+ formField: `${p2}-form-field`,
2804
+ /** Ask-input tool root (inline form in a message bubble). */
2805
+ toolAskInput: `${p2}-tool-ask-input`,
2806
+ /** Ask-input submit button. */
2807
+ toolInputSubmit: `${p2}-tool-input-submit`,
2808
+ /** Ask-input skip button. */
2809
+ toolInputSkip: `${p2}-tool-input-skip`,
2810
+ /** Tool-approval root (approve/reject prompt). */
2811
+ toolApproval: `${p2}-tool-approval`,
2812
+ /** Tool-approval approve button. */
2813
+ toolApprove: `${p2}-tool-approve`,
2814
+ /** Tool-approval reject button. */
2815
+ toolReject: `${p2}-tool-reject`,
2816
+ /** Recorded tool decision summary (after approve/reject/submit). */
2817
+ toolDecision: `${p2}-tool-decision`
2537
2818
  };
2538
2819
  function tid(base, suffix) {
2539
2820
  return `${base}-${suffix}`;
@@ -2644,24 +2925,24 @@ import { useCallback as useCallback2, useEffect as useEffect10, useRef as useRef
2644
2925
  import { useEffect as useEffect2, useRef } from "preact/hooks";
2645
2926
  import { jsx as jsx3 } from "preact/jsx-runtime";
2646
2927
  function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, strings }) {
2647
- const p29 = BRAND.cssPrefix;
2928
+ const p33 = BRAND.cssPrefix;
2648
2929
  const dragRef = useRef(null);
2649
2930
  useEffect2(() => {
2650
2931
  if (!panelEl) return;
2651
2932
  const style = panelEl.style;
2652
- if (resize.minWidth) style.setProperty(`--${p29}-resize-min-w`, resize.minWidth);
2653
- if (resize.maxWidth) style.setProperty(`--${p29}-resize-max-w`, resize.maxWidth);
2654
- if (resize.minHeight) style.setProperty(`--${p29}-resize-min-h`, resize.minHeight);
2655
- if (resize.maxHeight) style.setProperty(`--${p29}-resize-max-h`, resize.maxHeight);
2933
+ if (resize.minWidth) style.setProperty(`--${p33}-resize-min-w`, resize.minWidth);
2934
+ if (resize.maxWidth) style.setProperty(`--${p33}-resize-max-w`, resize.maxWidth);
2935
+ if (resize.minHeight) style.setProperty(`--${p33}-resize-min-h`, resize.minHeight);
2936
+ if (resize.maxHeight) style.setProperty(`--${p33}-resize-max-h`, resize.maxHeight);
2656
2937
  if (initialSize) {
2657
- style.setProperty(`--${p29}-widget-w`, `${initialSize.width}px`);
2658
- style.setProperty(`--${p29}-widget-h`, `${initialSize.height}px`);
2938
+ style.setProperty(`--${p33}-widget-w`, `${initialSize.width}px`);
2939
+ style.setProperty(`--${p33}-widget-h`, `${initialSize.height}px`);
2659
2940
  }
2660
- }, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p29, initialSize]);
2941
+ }, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p33, initialSize]);
2661
2942
  if (!panelEl) return null;
2662
2943
  const isTop = position.startsWith("top-");
2663
2944
  const isRight = position.endsWith("-right");
2664
- const cornerClass = `${p29}-resize-grip ${p29}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
2945
+ const cornerClass = `${p33}-resize-grip ${p33}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
2665
2946
  const onPointerDown = (e) => {
2666
2947
  if (!panelEl) return;
2667
2948
  const target = e.currentTarget;
@@ -2685,8 +2966,8 @@ function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, stri
2685
2966
  if (!d || e.pointerId !== d.pointerId || !panelEl) return;
2686
2967
  const dx = (e.clientX - d.startX) * d.dirX;
2687
2968
  const dy = (e.clientY - d.startY) * d.dirY;
2688
- panelEl.style.setProperty(`--${p29}-widget-w`, `${d.startW + dx}px`);
2689
- panelEl.style.setProperty(`--${p29}-widget-h`, `${d.startH + dy}px`);
2969
+ panelEl.style.setProperty(`--${p33}-widget-w`, `${d.startW + dx}px`);
2970
+ panelEl.style.setProperty(`--${p33}-widget-h`, `${d.startH + dy}px`);
2690
2971
  };
2691
2972
  const onPointerUp = (e) => {
2692
2973
  const d = dragRef.current;
@@ -2723,7 +3004,7 @@ var KEEP_VISIBLE = 56;
2723
3004
  function useDragMove(panelEl, enabled) {
2724
3005
  useEffect3(() => {
2725
3006
  if (!enabled || !panelEl) return;
2726
- const num = (v) => Number.parseFloat(v) || 0;
3007
+ const num2 = (v) => Number.parseFloat(v) || 0;
2727
3008
  const clamp = (v, max) => Math.min(max, Math.max(-max, v));
2728
3009
  let drag = null;
2729
3010
  const onDown = (e) => {
@@ -2734,8 +3015,8 @@ function useDragMove(panelEl, enabled) {
2734
3015
  id: e.pointerId,
2735
3016
  x: e.clientX,
2736
3017
  y: e.clientY,
2737
- dx: num(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
2738
- dy: num(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
3018
+ dx: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
3019
+ dy: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
2739
3020
  // Centred origin: |offset| ≤ (viewport + panel)/2 − keepVisible keeps a
2740
3021
  // strip of the dialog reachable so it can never be lost off-screen.
2741
3022
  maxX: (window.innerWidth + rect.width) / 2 - KEEP_VISIBLE,
@@ -3421,20 +3702,20 @@ function usePopoverMenu({ itemCount, initialFocusIndex }) {
3421
3702
  // src/ui/overflow-menu.tsx
3422
3703
  import { jsx as jsx8, jsxs as jsxs6 } from "preact/jsx-runtime";
3423
3704
  function OverflowMenu({ items, triggerLabel }) {
3424
- const p29 = BRAND.cssPrefix;
3705
+ const p33 = BRAND.cssPrefix;
3425
3706
  const menu = usePopoverMenu({ itemCount: items.length });
3426
3707
  const handleSelect = (item) => {
3427
3708
  if (item.disabled) return;
3428
3709
  item.onSelect();
3429
3710
  if (!item.keepOpen) menu.close();
3430
3711
  };
3431
- return /* @__PURE__ */ jsxs6("div", { class: `${p29}-menu-wrap`, children: [
3712
+ return /* @__PURE__ */ jsxs6("div", { class: `${p33}-menu-wrap`, children: [
3432
3713
  /* @__PURE__ */ jsx8(
3433
3714
  "button",
3434
3715
  {
3435
3716
  ref: menu.triggerRef,
3436
3717
  type: "button",
3437
- class: `${p29}-icon-btn`,
3718
+ class: `${p33}-icon-btn`,
3438
3719
  "aria-label": triggerLabel,
3439
3720
  "aria-haspopup": "menu",
3440
3721
  "aria-expanded": menu.open,
@@ -3448,7 +3729,7 @@ function OverflowMenu({ items, triggerLabel }) {
3448
3729
  "div",
3449
3730
  {
3450
3731
  ref: menu.menuRef,
3451
- class: `${p29}-menu`,
3732
+ class: `${p33}-menu`,
3452
3733
  role: "menu",
3453
3734
  "aria-label": triggerLabel,
3454
3735
  onKeyDown: menu.onMenuKey,
@@ -3458,15 +3739,15 @@ function OverflowMenu({ items, triggerLabel }) {
3458
3739
  {
3459
3740
  type: "button",
3460
3741
  role: "menuitem",
3461
- class: `${p29}-menu-item`,
3742
+ class: `${p33}-menu-item`,
3462
3743
  "aria-pressed": item.type === "switch" ? item.on : void 0,
3463
3744
  disabled: item.disabled,
3464
3745
  lang: item.lang,
3465
3746
  onClick: () => handleSelect(item),
3466
3747
  children: [
3467
- item.icon ? /* @__PURE__ */ jsx8("span", { class: `${p29}-menu-icon`, children: item.icon }) : null,
3468
- /* @__PURE__ */ jsx8("span", { class: `${p29}-menu-label`, children: item.label }),
3469
- item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${p29}-menu-check`, "aria-hidden": "true", children: /* @__PURE__ */ jsx8(CheckIcon, {}) }) : null
3748
+ item.icon ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-icon`, children: item.icon }) : null,
3749
+ /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-label`, children: item.label }),
3750
+ item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-check`, "aria-hidden": "true", children: /* @__PURE__ */ jsx8(CheckIcon, {}) }) : null
3470
3751
  ]
3471
3752
  },
3472
3753
  item.id
@@ -3588,18 +3869,360 @@ function HeaderActions({ panelProps, variant }) {
3588
3869
  ] });
3589
3870
  }
3590
3871
 
3872
+ // src/ui/form/dynamic-form.tsx
3873
+ import { useState as useState5 } from "preact/hooks";
3874
+
3875
+ // src/ui/form/validate.ts
3876
+ var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
3877
+ var URL_RE = /^https?:\/\/[^\s.]+\.[^\s]+$/i;
3878
+ var TEL_RE = /^[+]?[\d\s().-]{6,}$/;
3879
+ function fmt(template, vars) {
3880
+ return template.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? `{${k}}`));
3881
+ }
3882
+ function selectionCount(value) {
3883
+ if (Array.isArray(value)) return value.length;
3884
+ return value && value.trim() ? 1 : 0;
3885
+ }
3886
+ function validateField(field, value, strings) {
3887
+ const required = field.required ?? true;
3888
+ const v = field.validation;
3889
+ if (field.type === "multiselect") {
3890
+ const count = selectionCount(value);
3891
+ if (required && count === 0) return strings.formRequired;
3892
+ if (count === 0) return void 0;
3893
+ if (v?.minSelections != null && count < v.minSelections) {
3894
+ return fmt(strings.formChooseAtLeast, { min: v.minSelections });
3895
+ }
3896
+ if (v?.maxSelections != null && count > v.maxSelections) {
3897
+ return fmt(strings.formChooseAtMost, { max: v.maxSelections });
3898
+ }
3899
+ return void 0;
3900
+ }
3901
+ const text = typeof value === "string" ? value.trim() : "";
3902
+ if (!text) return required ? strings.formRequired : void 0;
3903
+ switch (field.type) {
3904
+ case "email":
3905
+ if (!EMAIL_RE2.test(text)) return strings.formInvalidEmail;
3906
+ break;
3907
+ case "url":
3908
+ if (!URL_RE.test(text)) return strings.formInvalidUrl;
3909
+ break;
3910
+ case "tel":
3911
+ if (!TEL_RE.test(text)) return strings.formInvalidTel;
3912
+ break;
3913
+ case "number": {
3914
+ const n = Number(text);
3915
+ if (!Number.isFinite(n)) return strings.formInvalidNumber;
3916
+ if (v?.min != null && n < v.min) return fmt(strings.formNumberTooSmall, { min: v.min });
3917
+ if (v?.max != null && n > v.max) return fmt(strings.formNumberTooLarge, { max: v.max });
3918
+ break;
3919
+ }
3920
+ default:
3921
+ break;
3922
+ }
3923
+ if (v?.minLength != null && text.length < v.minLength) return fmt(strings.formTooShort, { min: v.minLength });
3924
+ if (v?.maxLength != null && text.length > v.maxLength) return fmt(strings.formTooLong, { max: v.maxLength });
3925
+ if (v?.pattern) {
3926
+ try {
3927
+ if (!new RegExp(v.pattern).test(text)) return strings.formPatternMismatch;
3928
+ } catch {
3929
+ }
3930
+ }
3931
+ return void 0;
3932
+ }
3933
+ function validateForm(fields, values, strings) {
3934
+ const errors = {};
3935
+ for (const field of fields) {
3936
+ const err = validateField(field, values[field.name], strings);
3937
+ if (err) errors[field.name] = err;
3938
+ }
3939
+ return errors;
3940
+ }
3941
+ function flattenValues(values) {
3942
+ const out = {};
3943
+ for (const [k, v] of Object.entries(values)) {
3944
+ const flat = Array.isArray(v) ? v.join(", ") : v;
3945
+ if (flat && flat.trim()) out[k] = flat.trim();
3946
+ }
3947
+ return out;
3948
+ }
3949
+
3950
+ // src/ui/form/dynamic-form.tsx
3951
+ import { jsx as jsx10, jsxs as jsxs8 } from "preact/jsx-runtime";
3952
+ var p10 = BRAND.cssPrefix;
3953
+ var OTHER = "__other__";
3954
+ function DynamicForm({
3955
+ fields,
3956
+ strings,
3957
+ submitLabel,
3958
+ onSubmit,
3959
+ skipLabel,
3960
+ onSkip,
3961
+ disabled,
3962
+ rootTestId,
3963
+ submitTestId,
3964
+ skipTestId
3965
+ }) {
3966
+ const [values, setValues] = useState5(() => seedValues(fields));
3967
+ const [other, setOther] = useState5({});
3968
+ const [errors, setErrors] = useState5({});
3969
+ const clearError = (name) => {
3970
+ if (errors[name]) setErrors((prev) => ({ ...prev, [name]: "" }));
3971
+ };
3972
+ const setValue = (name, v) => {
3973
+ setValues((prev) => ({ ...prev, [name]: v }));
3974
+ clearError(name);
3975
+ };
3976
+ const setOtherText = (name, t) => {
3977
+ setOther((prev) => ({ ...prev, [name]: t }));
3978
+ clearError(name);
3979
+ };
3980
+ const submit = (e) => {
3981
+ e.preventDefault();
3982
+ if (disabled) return;
3983
+ const resolved = resolveValues(fields, values, other);
3984
+ const errs = validateForm(fields, resolved, strings);
3985
+ if (Object.keys(errs).length > 0) {
3986
+ setErrors(errs);
3987
+ return;
3988
+ }
3989
+ onSubmit(flattenValues(resolved));
3990
+ };
3991
+ return /* @__PURE__ */ jsxs8("form", { class: `${p10}-form`, onSubmit: submit, "data-testid": rootTestId, noValidate: true, children: [
3992
+ fields.map((field) => /* @__PURE__ */ jsx10(
3993
+ Field,
3994
+ {
3995
+ field,
3996
+ value: values[field.name],
3997
+ otherText: other[field.name] ?? "",
3998
+ error: errors[field.name],
3999
+ disabled,
4000
+ strings,
4001
+ onChange: (v) => setValue(field.name, v),
4002
+ onOtherChange: (t) => setOtherText(field.name, t)
4003
+ },
4004
+ field.name
4005
+ )),
4006
+ /* @__PURE__ */ jsxs8("div", { class: `${p10}-form-actions`, children: [
4007
+ skipLabel && onSkip ? /* @__PURE__ */ jsx10("button", { type: "button", class: `${p10}-form-skip`, onClick: onSkip, disabled, "data-testid": skipTestId, children: skipLabel }) : null,
4008
+ /* @__PURE__ */ jsx10("button", { type: "submit", class: `${p10}-form-submit`, disabled, "data-testid": submitTestId, children: submitLabel })
4009
+ ] })
4010
+ ] });
4011
+ }
4012
+ function Field({
4013
+ field,
4014
+ value,
4015
+ otherText,
4016
+ error,
4017
+ disabled,
4018
+ strings,
4019
+ onChange,
4020
+ onOtherChange
4021
+ }) {
4022
+ const fieldTid = tid(TID.formField, field.name);
4023
+ const control = renderControl({ field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid });
4024
+ return /* @__PURE__ */ jsxs8("label", { class: `${p10}-field`, "data-field": field.name, "data-invalid": error ? "true" : void 0, children: [
4025
+ /* @__PURE__ */ jsxs8("span", { class: `${p10}-field-label`, children: [
4026
+ field.label,
4027
+ field.required ?? true ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-req`, "aria-hidden": "true", children: " *" }) : null
4028
+ ] }),
4029
+ control,
4030
+ field.validationHint && !error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-hint`, children: field.validationHint }) : null,
4031
+ error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-error`, role: "alert", children: error }) : null
4032
+ ] });
4033
+ }
4034
+ function renderControl(args) {
4035
+ const { field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid } = args;
4036
+ const str2 = typeof value === "string" ? value : "";
4037
+ switch (field.type) {
4038
+ case "textarea":
4039
+ return /* @__PURE__ */ jsx10(
4040
+ "textarea",
4041
+ {
4042
+ class: `${p10}-field-input`,
4043
+ rows: 3,
4044
+ value: str2,
4045
+ placeholder: field.placeholder,
4046
+ disabled,
4047
+ onInput: (e) => onChange(e.target.value),
4048
+ "data-testid": fieldTid
4049
+ }
4050
+ );
4051
+ case "select":
4052
+ return /* @__PURE__ */ jsxs8(
4053
+ "select",
4054
+ {
4055
+ class: `${p10}-field-input`,
4056
+ value: str2,
4057
+ disabled,
4058
+ onChange: (e) => onChange(e.target.value),
4059
+ "data-testid": fieldTid,
4060
+ children: [
4061
+ /* @__PURE__ */ jsx10("option", { value: "", children: field.placeholder ?? "\u2014" }),
4062
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsx10("option", { value: o.value, children: o.label ?? o.value }, o.value))
4063
+ ]
4064
+ }
4065
+ );
4066
+ case "radio": {
4067
+ const isOther = field.allowOther && str2 === OTHER;
4068
+ return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, role: "radiogroup", "data-testid": fieldTid, children: [
4069
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4070
+ /* @__PURE__ */ jsx10(
4071
+ "input",
4072
+ {
4073
+ type: "radio",
4074
+ name: `${p10}-${field.name}`,
4075
+ checked: str2 === o.value,
4076
+ disabled,
4077
+ onChange: () => onChange(o.value)
4078
+ }
4079
+ ),
4080
+ /* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
4081
+ ] }, o.value)),
4082
+ field.allowOther ? /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4083
+ /* @__PURE__ */ jsx10(
4084
+ "input",
4085
+ {
4086
+ type: "radio",
4087
+ name: `${p10}-${field.name}`,
4088
+ checked: str2 === OTHER,
4089
+ disabled,
4090
+ onChange: () => onChange(OTHER)
4091
+ }
4092
+ ),
4093
+ /* @__PURE__ */ jsx10("span", { children: strings.formOther })
4094
+ ] }) : null,
4095
+ isOther ? /* @__PURE__ */ jsx10(
4096
+ "input",
4097
+ {
4098
+ class: `${p10}-field-input`,
4099
+ value: otherText,
4100
+ placeholder: field.placeholder ?? strings.formOtherPlaceholder,
4101
+ disabled,
4102
+ onInput: (e) => onOtherChange(e.target.value)
4103
+ }
4104
+ ) : null
4105
+ ] });
4106
+ }
4107
+ case "checkbox":
4108
+ return /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4109
+ /* @__PURE__ */ jsx10(
4110
+ "input",
4111
+ {
4112
+ type: "checkbox",
4113
+ checked: str2 === "true",
4114
+ disabled,
4115
+ onChange: (e) => onChange(e.target.checked ? "true" : ""),
4116
+ "data-testid": fieldTid
4117
+ }
4118
+ ),
4119
+ /* @__PURE__ */ jsx10("span", { children: field.placeholder ?? field.label })
4120
+ ] });
4121
+ case "multiselect": {
4122
+ const selected = Array.isArray(value) ? value : [];
4123
+ const toggle = (v, on) => onChange(on ? [...selected, v] : selected.filter((x) => x !== v));
4124
+ return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, "data-testid": fieldTid, children: [
4125
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4126
+ /* @__PURE__ */ jsx10(
4127
+ "input",
4128
+ {
4129
+ type: "checkbox",
4130
+ checked: selected.includes(o.value),
4131
+ disabled,
4132
+ onChange: (e) => toggle(o.value, e.target.checked)
4133
+ }
4134
+ ),
4135
+ /* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
4136
+ ] }, o.value)),
4137
+ field.allowOther || (field.options ?? []).length === 0 ? /* @__PURE__ */ jsx10(
4138
+ "textarea",
4139
+ {
4140
+ class: `${p10}-field-input`,
4141
+ rows: 2,
4142
+ value: otherText,
4143
+ placeholder: field.placeholder ?? strings.formOtherPlaceholder,
4144
+ disabled,
4145
+ onInput: (e) => onOtherChange(e.target.value)
4146
+ }
4147
+ ) : null
4148
+ ] });
4149
+ }
4150
+ default:
4151
+ return /* @__PURE__ */ jsx10(
4152
+ "input",
4153
+ {
4154
+ class: `${p10}-field-input`,
4155
+ type: inputType(field.type),
4156
+ value: str2,
4157
+ placeholder: field.placeholder,
4158
+ disabled,
4159
+ onInput: (e) => onChange(e.target.value),
4160
+ "data-testid": fieldTid
4161
+ }
4162
+ );
4163
+ }
4164
+ }
4165
+ function inputType(type) {
4166
+ return type === "number" || type === "email" || type === "tel" || type === "url" ? type : "text";
4167
+ }
4168
+ function seedValues(fields) {
4169
+ const out = {};
4170
+ for (const f of fields) {
4171
+ if (f.defaultValue == null) continue;
4172
+ out[f.name] = f.type === "multiselect" ? f.defaultValue.split(",").map((s) => s.trim()).filter(Boolean) : f.defaultValue;
4173
+ }
4174
+ return out;
4175
+ }
4176
+ function resolveValues(fields, values, other) {
4177
+ const out = { ...values };
4178
+ for (const f of fields) {
4179
+ const otherText = other[f.name]?.trim();
4180
+ if (f.type === "radio" && f.allowOther && values[f.name] === OTHER) {
4181
+ out[f.name] = otherText ?? "";
4182
+ } else if (f.type === "multiselect" && otherText) {
4183
+ const tokens = otherText.split(/[,\n;]+/).map((t) => t.trim()).filter(Boolean);
4184
+ const base = Array.isArray(values[f.name]) ? values[f.name] : [];
4185
+ out[f.name] = [...base, ...tokens];
4186
+ }
4187
+ }
4188
+ return out;
4189
+ }
4190
+
4191
+ // src/ui/intake-gate.tsx
4192
+ import { jsx as jsx11, jsxs as jsxs9 } from "preact/jsx-runtime";
4193
+ var p11 = BRAND.cssPrefix;
4194
+ function IntakeGate({ intake, strings, onComplete }) {
4195
+ return /* @__PURE__ */ jsxs9("div", { class: `${p11}-intake`, "data-testid": TID.intakeForm, children: [
4196
+ intake.title ? /* @__PURE__ */ jsx11("h3", { class: `${p11}-intake-title`, children: intake.title }) : null,
4197
+ intake.description ? /* @__PURE__ */ jsx11("p", { class: `${p11}-intake-desc`, children: intake.description }) : null,
4198
+ /* @__PURE__ */ jsx11(
4199
+ DynamicForm,
4200
+ {
4201
+ fields: intake.fields,
4202
+ strings,
4203
+ submitLabel: intake.submitLabel ?? strings.intakeSubmit,
4204
+ onSubmit: onComplete,
4205
+ skipLabel: intake.skippable ? strings.intakeSkip : void 0,
4206
+ onSkip: intake.skippable ? () => onComplete({}) : void 0,
4207
+ submitTestId: TID.intakeSubmit,
4208
+ skipTestId: TID.intakeSkip
4209
+ }
4210
+ )
4211
+ ] });
4212
+ }
4213
+
3591
4214
  // src/ui/message-list.tsx
3592
- import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as useState5 } from "preact/hooks";
3593
- import { useComputed as useComputed3 } from "@preact/signals";
4215
+ import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as useState6 } from "preact/hooks";
4216
+ import { useComputed as useComputed5 } from "@preact/signals";
3594
4217
 
3595
4218
  // src/ui/message-bubble.tsx
3596
- import { useComputed as useComputed2 } from "@preact/signals";
4219
+ import { useComputed as useComputed4 } from "@preact/signals";
3597
4220
 
3598
4221
  // src/ui/markdown.tsx
3599
4222
  import { useEffect as useEffect7, useMemo, useRef as useRef4 } from "preact/hooks";
3600
4223
  import { effect, signal as signal4 } from "@preact/signals";
3601
4224
  import * as smd from "streaming-markdown";
3602
- import { jsx as jsx10 } from "preact/jsx-runtime";
4225
+ import { jsx as jsx12 } from "preact/jsx-runtime";
3603
4226
  function MarkdownView({ textSig, doneSig }) {
3604
4227
  const ref = useRef4(null);
3605
4228
  useEffect7(() => {
@@ -3649,12 +4272,12 @@ function MarkdownView({ textSig, doneSig }) {
3649
4272
  el.removeEventListener("click", onClick);
3650
4273
  };
3651
4274
  }, [textSig, doneSig]);
3652
- return /* @__PURE__ */ jsx10("div", { ref });
4275
+ return /* @__PURE__ */ jsx12("div", { ref });
3653
4276
  }
3654
4277
  function StaticMarkdown({ text }) {
3655
4278
  const textSig = useMemo(() => signal4(text), [text]);
3656
4279
  const doneSig = useMemo(() => signal4(true), []);
3657
- return /* @__PURE__ */ jsx10(MarkdownView, { textSig, doneSig });
4280
+ return /* @__PURE__ */ jsx12(MarkdownView, { textSig, doneSig });
3658
4281
  }
3659
4282
  function hardenLink(a) {
3660
4283
  const href = a.getAttribute("href") ?? "";
@@ -3666,29 +4289,247 @@ function hardenLink(a) {
3666
4289
  a.rel = [...tokens].join(" ");
3667
4290
  }
3668
4291
 
4292
+ // src/ui/tool-approval.tsx
4293
+ import { useComputed as useComputed2, useSignal } from "@preact/signals";
4294
+ import { Fragment, jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
4295
+ var p12 = BRAND.cssPrefix;
4296
+ function ToolApproval({ part, strings, active, onDecision }) {
4297
+ const approval = useComputed2(() => part.approvalSig.value);
4298
+ const input = useComputed2(() => part.inputSig.value);
4299
+ const reason = useSignal("");
4300
+ const decided = approval.value?.approved !== void 0;
4301
+ if (decided) {
4302
+ const ap = approval.value;
4303
+ return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval ${p12}-tool-decided`, "data-testid": TID.toolDecision, children: [
4304
+ /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-label`, "data-approved": ap?.approved ? "true" : "false", children: ap?.approved ? strings.approved : strings.rejected }),
4305
+ /* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName }),
4306
+ ap?.reason ? /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-value`, children: ap.reason }) : null
4307
+ ] });
4308
+ }
4309
+ return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval`, "data-testid": TID.toolApproval, children: [
4310
+ /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-head`, children: [
4311
+ /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-badge`, children: strings.approvalRequired }),
4312
+ /* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName })
4313
+ ] }),
4314
+ summarizeInput(input.value) ? /* @__PURE__ */ jsx13("pre", { class: `${p12}-tool-args`, children: summarizeInput(input.value) }) : null,
4315
+ active ? /* @__PURE__ */ jsxs10(Fragment, { children: [
4316
+ /* @__PURE__ */ jsx13(
4317
+ "input",
4318
+ {
4319
+ class: `${p12}-field-input`,
4320
+ value: reason.value,
4321
+ placeholder: strings.approvalReason,
4322
+ onInput: (e) => {
4323
+ reason.value = e.target.value;
4324
+ }
4325
+ }
4326
+ ),
4327
+ /* @__PURE__ */ jsxs10("div", { class: `${p12}-form-actions`, children: [
4328
+ /* @__PURE__ */ jsx13(
4329
+ "button",
4330
+ {
4331
+ type: "button",
4332
+ class: `${p12}-tool-reject`,
4333
+ onClick: () => onDecision(part.toolCallId, false, reason.value.trim() || void 0),
4334
+ "data-testid": TID.toolReject,
4335
+ children: strings.reject
4336
+ }
4337
+ ),
4338
+ /* @__PURE__ */ jsx13(
4339
+ "button",
4340
+ {
4341
+ type: "button",
4342
+ class: `${p12}-tool-approve`,
4343
+ onClick: () => onDecision(part.toolCallId, true, reason.value.trim() || void 0),
4344
+ "data-testid": TID.toolApprove,
4345
+ children: strings.approve
4346
+ }
4347
+ )
4348
+ ] })
4349
+ ] }) : /* @__PURE__ */ jsx13("p", { class: `${p12}-tool-stale-note`, children: strings.stepNoLongerActive })
4350
+ ] });
4351
+ }
4352
+ function summarizeInput(input) {
4353
+ if (input == null) return "";
4354
+ try {
4355
+ const json = typeof input === "string" ? input : JSON.stringify(input, null, 2);
4356
+ return json.length > 600 ? `${json.slice(0, 600)}\u2026` : json;
4357
+ } catch {
4358
+ return "";
4359
+ }
4360
+ }
4361
+
4362
+ // src/ui/tool-ask-input.tsx
4363
+ import { useComputed as useComputed3 } from "@preact/signals";
4364
+
4365
+ // src/ui/form/field.ts
4366
+ function parseAskUserInput(input) {
4367
+ const raw = input && typeof input === "object" ? input : {};
4368
+ const responseType = raw.responseType;
4369
+ return {
4370
+ title: str(raw.title),
4371
+ question: str(raw.question) ?? "Please provide the missing information.",
4372
+ description: str(raw.description),
4373
+ placeholder: str(raw.placeholder),
4374
+ responseType: responseType === "single-choice" || responseType === "multi-choice" || responseType === "confirmation" || responseType === "free-text" ? responseType : "free-text",
4375
+ choices: Array.isArray(raw.choices) ? raw.choices : void 0,
4376
+ allowOther: typeof raw.allowOther === "boolean" ? raw.allowOther : void 0,
4377
+ required: typeof raw.required === "boolean" ? raw.required : true,
4378
+ defaultValues: Array.isArray(raw.defaultValues) ? raw.defaultValues.filter((v) => typeof v === "string") : void 0,
4379
+ minSelections: num(raw.minSelections),
4380
+ maxSelections: num(raw.maxSelections),
4381
+ validationHint: str(raw.validationHint)
4382
+ };
4383
+ }
4384
+ function askInputToFields(req) {
4385
+ if (req.responseType === "confirmation") return [];
4386
+ const options = (req.choices ?? []).map(normalizeChoice).filter((c) => c !== null);
4387
+ let type = "textarea";
4388
+ if (req.responseType === "single-choice" && options.length > 0) type = "radio";
4389
+ else if (req.responseType === "multi-choice") type = "multiselect";
4390
+ const defaultValue = type === "multiselect" ? req.defaultValues?.join(", ") : req.defaultValues?.[0];
4391
+ return [
4392
+ {
4393
+ name: "answer",
4394
+ label: req.question,
4395
+ type,
4396
+ placeholder: req.placeholder,
4397
+ required: req.required ?? true,
4398
+ defaultValue,
4399
+ options: options.length > 0 ? options : void 0,
4400
+ allowOther: req.allowOther,
4401
+ validationHint: req.validationHint,
4402
+ validation: type === "multiselect" ? { minSelections: req.minSelections, maxSelections: req.maxSelections } : void 0
4403
+ }
4404
+ ];
4405
+ }
4406
+ function normalizeChoice(c) {
4407
+ if (typeof c === "string") return c ? { value: c, label: c } : null;
4408
+ if (c && typeof c.value === "string" && c.value)
4409
+ return { value: c.value, label: c.label ?? c.value, description: c.description };
4410
+ return null;
4411
+ }
4412
+ function str(v) {
4413
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
4414
+ }
4415
+ function num(v) {
4416
+ return typeof v === "number" && Number.isFinite(v) ? v : void 0;
4417
+ }
4418
+
4419
+ // src/ui/tool-ask-input.tsx
4420
+ import { jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
4421
+ var p13 = BRAND.cssPrefix;
4422
+ function ToolAskInput({ part, strings, active, onSubmit }) {
4423
+ const state = useComputed3(() => part.stateSig.value);
4424
+ const request = useComputed3(() => parseAskUserInput(part.inputSig.value));
4425
+ const decided = state.value === "output" || state.value === "error";
4426
+ if (decided) {
4427
+ return /* @__PURE__ */ jsx14(DecidedSummary, { part, strings });
4428
+ }
4429
+ if (!active) {
4430
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-stale`, "data-testid": TID.toolAskInput, children: [
4431
+ /* @__PURE__ */ jsx14(Header, { strings, title: request.value.title ?? request.value.question }),
4432
+ /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-stale-note`, children: strings.stepNoLongerActive })
4433
+ ] });
4434
+ }
4435
+ const req = request.value;
4436
+ const fields = askInputToFields(req);
4437
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input`, "data-testid": TID.toolAskInput, children: [
4438
+ /* @__PURE__ */ jsx14(Header, { strings, title: req.title }),
4439
+ req.description ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-desc`, children: req.description }) : null,
4440
+ req.responseType === "confirmation" ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-question`, children: req.question }) : null,
4441
+ req.responseType === "confirmation" ? /* @__PURE__ */ jsxs11("div", { class: `${p13}-form-actions`, children: [
4442
+ /* @__PURE__ */ jsx14(
4443
+ "button",
4444
+ {
4445
+ type: "button",
4446
+ class: `${p13}-form-skip`,
4447
+ onClick: () => onSubmit(part.toolCallId, { confirmed: false }),
4448
+ "data-testid": TID.toolInputSkip,
4449
+ children: strings.reject
4450
+ }
4451
+ ),
4452
+ /* @__PURE__ */ jsx14(
4453
+ "button",
4454
+ {
4455
+ type: "button",
4456
+ class: `${p13}-form-submit`,
4457
+ onClick: () => onSubmit(part.toolCallId, { confirmed: true }),
4458
+ "data-testid": TID.toolInputSubmit,
4459
+ children: strings.approve
4460
+ }
4461
+ )
4462
+ ] }) : /* @__PURE__ */ jsx14(
4463
+ DynamicForm,
4464
+ {
4465
+ fields,
4466
+ strings,
4467
+ submitLabel: strings.inputSubmit,
4468
+ onSubmit: (values) => onSubmit(part.toolCallId, values),
4469
+ skipLabel: req.required === false ? strings.inputSkip : void 0,
4470
+ onSkip: req.required === false ? () => onSubmit(part.toolCallId, {}) : void 0,
4471
+ submitTestId: TID.toolInputSubmit,
4472
+ skipTestId: TID.toolInputSkip
4473
+ }
4474
+ )
4475
+ ] });
4476
+ }
4477
+ function Header({ strings, title }) {
4478
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-head`, children: [
4479
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-badge`, children: strings.inputRequired }),
4480
+ title ? /* @__PURE__ */ jsx14("strong", { class: `${p13}-tool-title`, children: title }) : null
4481
+ ] });
4482
+ }
4483
+ function DecidedSummary({ part, strings }) {
4484
+ const output = useComputed3(() => part.outputSig.value);
4485
+ const text = summarizeOutput(output.value) || strings.inputSubmitted;
4486
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-decided`, "data-testid": TID.toolDecision, children: [
4487
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-label`, children: strings.inputSubmitted }),
4488
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-value`, children: text })
4489
+ ] });
4490
+ }
4491
+ function summarizeOutput(output) {
4492
+ if (output == null) return "";
4493
+ if (typeof output === "string") return output;
4494
+ if (typeof output === "object") {
4495
+ const rec = output;
4496
+ if ("confirmed" in rec) return rec.confirmed ? "Yes" : "No";
4497
+ return Object.values(rec).filter((v) => typeof v === "string" || typeof v === "number").join(", ");
4498
+ }
4499
+ return String(output);
4500
+ }
4501
+
3669
4502
  // src/ui/tool-chip.tsx
3670
- import { jsx as jsx11, jsxs as jsxs8 } from "preact/jsx-runtime";
4503
+ import { jsx as jsx15, jsxs as jsxs12 } from "preact/jsx-runtime";
3671
4504
  function ToolChip({ part, strings }) {
3672
- const p29 = BRAND.cssPrefix;
3673
- return /* @__PURE__ */ jsxs8("span", { class: `${p29}-tool-chip`, role: "status", children: [
3674
- /* @__PURE__ */ jsxs8("span", { children: [
4505
+ const p33 = BRAND.cssPrefix;
4506
+ return /* @__PURE__ */ jsxs12("span", { class: `${p33}-tool-chip`, role: "status", children: [
4507
+ /* @__PURE__ */ jsxs12("span", { children: [
3675
4508
  strings.usedTool,
3676
4509
  ":"
3677
4510
  ] }),
3678
- /* @__PURE__ */ jsx11("strong", { children: part.toolName })
4511
+ /* @__PURE__ */ jsx15("strong", { children: part.toolName })
3679
4512
  ] });
3680
4513
  }
3681
4514
 
3682
4515
  // src/ui/message-bubble.tsx
3683
- import { jsx as jsx12, jsxs as jsxs9 } from "preact/jsx-runtime";
3684
- var p10 = BRAND.cssPrefix;
3685
- function MessageBubble({ message, strings, responseMode, showReasoning, showToolCalls }) {
3686
- const parts = useComputed2(() => message.partsSig.value);
4516
+ import { jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
4517
+ var p14 = BRAND.cssPrefix;
4518
+ function MessageBubble({
4519
+ message,
4520
+ strings,
4521
+ responseMode,
4522
+ showReasoning,
4523
+ showToolCalls,
4524
+ interactive = false,
4525
+ tool
4526
+ }) {
4527
+ const parts = useComputed4(() => message.partsSig.value);
3687
4528
  const partList = parts.value;
3688
- const hasAnswerText = useComputed2(
4529
+ const hasAnswerText = useComputed4(
3689
4530
  () => message.partsSig.value.some((part) => part.kind === "text" && part.textSig.value.length > 0)
3690
4531
  );
3691
- const reasoningVisible = useComputed2(
4532
+ const reasoningVisible = useComputed4(
3692
4533
  () => showReasoning && message.partsSig.value.some((part) => part.kind === "reasoning")
3693
4534
  );
3694
4535
  const streaming = message.role === "assistant" && message.status === "streaming";
@@ -3696,23 +4537,25 @@ function MessageBubble({ message, strings, responseMode, showReasoning, showTool
3696
4537
  const working = streaming && !hasAnswerText.value;
3697
4538
  const showStreamDots = streaming && !bufferedHold && !(reasoningVisible.value && working);
3698
4539
  const stamp = formatStamp(message.createdAt);
3699
- return /* @__PURE__ */ jsx12("div", { class: `${p10}-bubble-row`, "data-role": message.role, "data-testid": tid(TID.messageBubble, message.id), children: /* @__PURE__ */ jsxs9("div", { class: `${p10}-bubble-col`, children: [
3700
- /* @__PURE__ */ jsxs9("div", { class: `${p10}-bubble`, children: [
3701
- bufferedHold ? /* @__PURE__ */ jsx12(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx12(
4540
+ return /* @__PURE__ */ jsx16("div", { class: `${p14}-bubble-row`, "data-role": message.role, "data-testid": tid(TID.messageBubble, message.id), children: /* @__PURE__ */ jsxs13("div", { class: `${p14}-bubble-col`, children: [
4541
+ /* @__PURE__ */ jsxs13("div", { class: `${p14}-bubble`, children: [
4542
+ bufferedHold ? /* @__PURE__ */ jsx16(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx16(
3702
4543
  PartView,
3703
4544
  {
3704
4545
  part,
3705
4546
  active: working,
3706
4547
  strings,
3707
4548
  showReasoning,
3708
- showToolCalls
4549
+ showToolCalls,
4550
+ interactive,
4551
+ tool
3709
4552
  },
3710
4553
  partKey(part)
3711
4554
  )),
3712
- showStreamDots && /* @__PURE__ */ jsx12(TypingDots, {}),
3713
- message.status === "error" && message.errorText ? /* @__PURE__ */ jsx12("div", { class: `${p10}-error`, role: "alert", children: /* @__PURE__ */ jsx12("span", { children: message.errorText }) }) : null
4555
+ showStreamDots && /* @__PURE__ */ jsx16(TypingDots, {}),
4556
+ message.status === "error" && message.errorText ? /* @__PURE__ */ jsx16("div", { class: `${p14}-error`, role: "alert", children: /* @__PURE__ */ jsx16("span", { children: message.errorText }) }) : null
3714
4557
  ] }),
3715
- stamp ? /* @__PURE__ */ jsx12("time", { class: `${p10}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
4558
+ stamp ? /* @__PURE__ */ jsx16("time", { class: `${p14}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
3716
4559
  ] }) });
3717
4560
  }
3718
4561
  function formatStamp(createdAt) {
@@ -3733,32 +4576,62 @@ function PartView({
3733
4576
  active,
3734
4577
  strings,
3735
4578
  showReasoning,
3736
- showToolCalls
4579
+ showToolCalls,
4580
+ interactive,
4581
+ tool
3737
4582
  }) {
3738
4583
  switch (part.kind) {
3739
4584
  case "text":
3740
- return /* @__PURE__ */ jsx12(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
4585
+ return /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
3741
4586
  case "reasoning":
3742
- return showReasoning ? /* @__PURE__ */ jsx12(ReasoningView, { part, active, strings }) : null;
4587
+ return showReasoning ? /* @__PURE__ */ jsx16(ReasoningView, { part, active, strings }) : null;
3743
4588
  case "tool":
3744
- return showToolCalls ? /* @__PURE__ */ jsx12(ToolChip, { part, strings }) : null;
4589
+ return /* @__PURE__ */ jsx16(
4590
+ ToolPartView,
4591
+ {
4592
+ part,
4593
+ strings,
4594
+ showToolCalls,
4595
+ interactive,
4596
+ tool
4597
+ }
4598
+ );
3745
4599
  case "file":
3746
4600
  if (part.mediaType.startsWith("image/")) {
3747
- return /* @__PURE__ */ jsx12("img", { src: part.url, alt: "", loading: "lazy" });
4601
+ return /* @__PURE__ */ jsx16("img", { src: part.url, alt: "", loading: "lazy" });
3748
4602
  }
3749
- return /* @__PURE__ */ jsx12("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
4603
+ return /* @__PURE__ */ jsx16("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
3750
4604
  case "source":
3751
4605
  return null;
3752
4606
  }
3753
4607
  }
4608
+ function ToolPartView({
4609
+ part,
4610
+ strings,
4611
+ showToolCalls,
4612
+ interactive,
4613
+ tool
4614
+ }) {
4615
+ const state = useComputed4(() => part.stateSig.value);
4616
+ const hasApproval = useComputed4(() => part.approvalSig.value !== void 0);
4617
+ if (tool?.humanInLoop) {
4618
+ if (hasApproval.value || state.value === "awaiting-approval") {
4619
+ return /* @__PURE__ */ jsx16(ToolApproval, { part, strings, active: interactive, onDecision: tool.onDecision });
4620
+ }
4621
+ if (isAskUserInputTool(part.toolName) || state.value === "awaiting-input") {
4622
+ return /* @__PURE__ */ jsx16(ToolAskInput, { part, strings, active: interactive, onSubmit: tool.onResult });
4623
+ }
4624
+ }
4625
+ return showToolCalls ? /* @__PURE__ */ jsx16(ToolChip, { part, strings }) : null;
4626
+ }
3754
4627
  function ReasoningView({
3755
4628
  part,
3756
4629
  active,
3757
4630
  strings
3758
4631
  }) {
3759
- return /* @__PURE__ */ jsxs9("details", { class: `${p10}-reasoning`, open: active, "data-active": active ? "true" : void 0, children: [
3760
- /* @__PURE__ */ jsx12("summary", { class: `${p10}-reasoning-summary`, children: /* @__PURE__ */ jsx12("span", { class: `${p10}-reasoning-label`, children: active ? strings.thinking : strings.thoughts }) }),
3761
- /* @__PURE__ */ jsx12("div", { class: `${p10}-reasoning-body`, children: /* @__PURE__ */ jsx12(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig }) })
4632
+ return /* @__PURE__ */ jsxs13("details", { class: `${p14}-reasoning`, open: active, "data-active": active ? "true" : void 0, children: [
4633
+ /* @__PURE__ */ jsx16("summary", { class: `${p14}-reasoning-summary`, children: /* @__PURE__ */ jsx16("span", { class: `${p14}-reasoning-label`, children: active ? strings.thinking : strings.thoughts }) }),
4634
+ /* @__PURE__ */ jsx16("div", { class: `${p14}-reasoning-body`, children: /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig }) })
3762
4635
  ] });
3763
4636
  }
3764
4637
  function partKey(part) {
@@ -3775,29 +4648,38 @@ function partKey(part) {
3775
4648
  }
3776
4649
  }
3777
4650
  function TypingDots() {
3778
- return /* @__PURE__ */ jsxs9("span", { class: `${p10}-typing`, "aria-hidden": "true", children: [
3779
- /* @__PURE__ */ jsx12("span", {}),
3780
- /* @__PURE__ */ jsx12("span", {}),
3781
- /* @__PURE__ */ jsx12("span", {})
4651
+ return /* @__PURE__ */ jsxs13("span", { class: `${p14}-typing`, "aria-hidden": "true", children: [
4652
+ /* @__PURE__ */ jsx16("span", {}),
4653
+ /* @__PURE__ */ jsx16("span", {}),
4654
+ /* @__PURE__ */ jsx16("span", {})
3782
4655
  ] });
3783
4656
  }
3784
4657
  function LoadingSpinner({ label }) {
3785
- return /* @__PURE__ */ jsxs9("span", { class: `${p10}-loading`, role: "status", children: [
3786
- /* @__PURE__ */ jsx12("span", { class: `${p10}-loading-spinner`, "aria-hidden": "true" }),
3787
- /* @__PURE__ */ jsx12("span", { class: `${p10}-loading-label`, children: label })
4658
+ return /* @__PURE__ */ jsxs13("span", { class: `${p14}-loading`, role: "status", children: [
4659
+ /* @__PURE__ */ jsx16("span", { class: `${p14}-loading-spinner`, "aria-hidden": "true" }),
4660
+ /* @__PURE__ */ jsx16("span", { class: `${p14}-loading-label`, children: label })
3788
4661
  ] });
3789
4662
  }
3790
4663
 
3791
4664
  // src/ui/message-list.tsx
3792
- import { jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
3793
- var p11 = BRAND.cssPrefix;
4665
+ import { jsx as jsx17, jsxs as jsxs14 } from "preact/jsx-runtime";
4666
+ var p15 = BRAND.cssPrefix;
3794
4667
  var STICK_THRESHOLD = 120;
3795
4668
  var DIVIDER_IDLE_MS = 1200;
3796
- function MessageList({ messagesSig, strings, responseMode, showReasoning, showToolCalls, loading }) {
4669
+ function MessageList({
4670
+ messagesSig,
4671
+ strings,
4672
+ responseMode,
4673
+ showReasoning,
4674
+ showToolCalls,
4675
+ loading,
4676
+ idle,
4677
+ tool
4678
+ }) {
3797
4679
  const ref = useRef5(null);
3798
- const messages = useComputed3(() => messagesSig.value);
3799
- const [showJump, setShowJump] = useState5(false);
3800
- const [scrolling, setScrolling] = useState5(false);
4680
+ const messages = useComputed5(() => messagesSig.value);
4681
+ const [showJump, setShowJump] = useState6(false);
4682
+ const [scrolling, setScrolling] = useState6(false);
3801
4683
  const hasHydratedRef = useRef5(false);
3802
4684
  const firstMessageId = messages.value[0]?.id;
3803
4685
  useLayoutEffect(() => {
@@ -3852,18 +4734,18 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
3852
4734
  const el = ref.current;
3853
4735
  if (!el) return;
3854
4736
  const syncJump = () => setShowJump(el.scrollHeight - el.scrollTop - el.clientHeight > STICK_THRESHOLD * 2);
3855
- let idle;
4737
+ let idleTimer;
3856
4738
  const onScroll = () => {
3857
4739
  syncJump();
3858
4740
  setScrolling(true);
3859
- clearTimeout(idle);
3860
- idle = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
4741
+ clearTimeout(idleTimer);
4742
+ idleTimer = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
3861
4743
  };
3862
4744
  el.addEventListener("scroll", onScroll, { passive: true });
3863
4745
  syncJump();
3864
4746
  return () => {
3865
4747
  el.removeEventListener("scroll", onScroll);
3866
- clearTimeout(idle);
4748
+ clearTimeout(idleTimer);
3867
4749
  };
3868
4750
  }, []);
3869
4751
  const jumpToBottom = () => {
@@ -3872,54 +4754,57 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
3872
4754
  };
3873
4755
  const rows = [];
3874
4756
  let prevDay = "";
4757
+ const lastId = messages.value.at(-1)?.id;
3875
4758
  for (const m of messages.value) {
3876
4759
  const day = dayKey(m.createdAt);
3877
4760
  if (day && day !== prevDay) {
3878
4761
  rows.push(
3879
- /* @__PURE__ */ jsx13("div", { class: `${p11}-date-divider`, children: /* @__PURE__ */ jsx13("span", { class: `${p11}-date-pill`, title: fullDate(m.createdAt), children: dayLabel(m.createdAt, strings) }) }, `day:${day}`)
4762
+ /* @__PURE__ */ jsx17("div", { class: `${p15}-date-divider`, children: /* @__PURE__ */ jsx17("span", { class: `${p15}-date-pill`, title: fullDate(m.createdAt), children: dayLabel(m.createdAt, strings) }) }, `day:${day}`)
3880
4763
  );
3881
4764
  prevDay = day;
3882
4765
  }
3883
4766
  rows.push(
3884
- /* @__PURE__ */ jsx13(
4767
+ /* @__PURE__ */ jsx17(
3885
4768
  MessageBubble,
3886
4769
  {
3887
4770
  message: m,
3888
4771
  strings,
3889
4772
  responseMode,
3890
4773
  showReasoning,
3891
- showToolCalls
4774
+ showToolCalls,
4775
+ interactive: Boolean(idle) && m.id === lastId,
4776
+ tool
3892
4777
  },
3893
4778
  m.id
3894
4779
  )
3895
4780
  );
3896
4781
  }
3897
- return /* @__PURE__ */ jsxs10("div", { class: `${p11}-list-wrap`, children: [
3898
- /* @__PURE__ */ jsxs10(
4782
+ return /* @__PURE__ */ jsxs14("div", { class: `${p15}-list-wrap`, children: [
4783
+ /* @__PURE__ */ jsxs14(
3899
4784
  "div",
3900
4785
  {
3901
4786
  ref,
3902
- class: `${p11}-list`,
4787
+ class: `${p15}-list`,
3903
4788
  role: "log",
3904
4789
  "aria-live": "polite",
3905
4790
  "aria-relevant": "additions text",
3906
4791
  "data-scrolling": scrolling ? "true" : void 0,
3907
4792
  children: [
3908
- loading && messages.value.length === 0 ? /* @__PURE__ */ jsx13("div", { class: `${p11}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
4793
+ loading && messages.value.length === 0 ? /* @__PURE__ */ jsx17("div", { class: `${p15}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
3909
4794
  rows
3910
4795
  ]
3911
4796
  }
3912
4797
  ),
3913
- showJump ? /* @__PURE__ */ jsx13(
4798
+ showJump ? /* @__PURE__ */ jsx17(
3914
4799
  "button",
3915
4800
  {
3916
4801
  type: "button",
3917
- class: `${p11}-jump`,
4802
+ class: `${p15}-jump`,
3918
4803
  onClick: jumpToBottom,
3919
4804
  "aria-label": strings.scrollToBottom,
3920
4805
  title: strings.scrollToBottom,
3921
4806
  "data-testid": TID.scrollToBottom,
3922
- children: /* @__PURE__ */ jsx13(ChevronDownIcon, {})
4807
+ children: /* @__PURE__ */ jsx17(ChevronDownIcon, {})
3923
4808
  }
3924
4809
  ) : null
3925
4810
  ] });
@@ -3948,7 +4833,7 @@ function dayLabel(createdAt, strings) {
3948
4833
  }
3949
4834
 
3950
4835
  // src/ui/conversation-list.tsx
3951
- import { useEffect as useEffect9, useState as useState6 } from "preact/hooks";
4836
+ import { useEffect as useEffect9, useState as useState7 } from "preact/hooks";
3952
4837
 
3953
4838
  // src/ui/history-groups.ts
3954
4839
  var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
@@ -3978,7 +4863,7 @@ function startOfDay(ms) {
3978
4863
  }
3979
4864
 
3980
4865
  // src/ui/conversation-list.tsx
3981
- import { Fragment, jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
4866
+ import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs15 } from "preact/jsx-runtime";
3982
4867
  var log11 = logger.scope("history");
3983
4868
  var BUCKET_TO_STRING = {
3984
4869
  today: "dateToday",
@@ -3987,9 +4872,9 @@ var BUCKET_TO_STRING = {
3987
4872
  older: "dateOlder"
3988
4873
  };
3989
4874
  function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }) {
3990
- const p29 = BRAND.cssPrefix;
3991
- const [state, setState] = useState6("loading");
3992
- const [sessions, setChats] = useState6([]);
4875
+ const p33 = BRAND.cssPrefix;
4876
+ const [state, setState] = useState7("loading");
4877
+ const [sessions, setChats] = useState7([]);
3993
4878
  useEffect9(() => {
3994
4879
  let cancelled = false;
3995
4880
  transport.listSessions({ visitorId }).then((res) => {
@@ -4005,38 +4890,38 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
4005
4890
  cancelled = true;
4006
4891
  };
4007
4892
  }, [transport, visitorId]);
4008
- const newChatButton = onNewChat ? /* @__PURE__ */ jsx14("div", { class: `${p29}-history-footer`, children: /* @__PURE__ */ jsxs11("button", { type: "button", class: `${p29}-history-new`, onClick: onNewChat, "data-testid": TID.sidebarNewChat, children: [
4009
- /* @__PURE__ */ jsx14(PlusIcon, {}),
4893
+ const newChatButton = onNewChat ? /* @__PURE__ */ jsx18("div", { class: `${p33}-history-footer`, children: /* @__PURE__ */ jsxs15("button", { type: "button", class: `${p33}-history-new`, onClick: onNewChat, "data-testid": TID.sidebarNewChat, children: [
4894
+ /* @__PURE__ */ jsx18(PlusIcon, {}),
4010
4895
  strings.historyNewChat
4011
4896
  ] }) }) : null;
4012
4897
  if (state === "loading") {
4013
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
4014
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-empty`, children: strings.historyLoading }),
4898
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4899
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyLoading }),
4015
4900
  newChatButton
4016
4901
  ] });
4017
4902
  }
4018
4903
  if (state === "error" || sessions.length === 0) {
4019
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
4020
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-empty`, children: strings.historyEmpty }),
4904
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4905
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyEmpty }),
4021
4906
  newChatButton
4022
4907
  ] });
4023
4908
  }
4024
4909
  const groups = groupByBucket(Date.now(), sessions);
4025
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
4026
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history`, role: "list", children: groups.map((group) => /* @__PURE__ */ jsxs11("div", { class: `${p29}-history-group`, children: [
4027
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-heading`, children: strings[BUCKET_TO_STRING[group.bucket]] }),
4028
- group.sessions.map((chat) => /* @__PURE__ */ jsxs11(
4910
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4911
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history`, role: "list", children: groups.map((group) => /* @__PURE__ */ jsxs15("div", { class: `${p33}-history-group`, children: [
4912
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-heading`, children: strings[BUCKET_TO_STRING[group.bucket]] }),
4913
+ group.sessions.map((chat) => /* @__PURE__ */ jsxs15(
4029
4914
  "button",
4030
4915
  {
4031
4916
  type: "button",
4032
4917
  role: "listitem",
4033
- class: `${p29}-history-item`,
4918
+ class: `${p33}-history-item`,
4034
4919
  onClick: () => onSelect(chat),
4035
4920
  "data-closed": chat.canContinue ? void 0 : "true",
4036
4921
  "data-testid": tid(TID.historyItem, chat.sessionId),
4037
4922
  children: [
4038
- /* @__PURE__ */ jsx14("span", { class: `${p29}-history-title`, children: chat.title }),
4039
- chat.preview ? /* @__PURE__ */ jsx14("span", { class: `${p29}-history-preview`, children: chat.preview }) : null
4923
+ /* @__PURE__ */ jsx18("span", { class: `${p33}-history-title`, children: chat.title }),
4924
+ chat.preview ? /* @__PURE__ */ jsx18("span", { class: `${p33}-history-preview`, children: chat.preview }) : null
4040
4925
  ]
4041
4926
  },
4042
4927
  chat.sessionId
@@ -4047,21 +4932,21 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
4047
4932
  }
4048
4933
 
4049
4934
  // src/ui/chat-history-pane.tsx
4050
- import { jsx as jsx15 } from "preact/jsx-runtime";
4935
+ import { jsx as jsx19 } from "preact/jsx-runtime";
4051
4936
  function ChatHistoryPane(props2) {
4052
- return /* @__PURE__ */ jsx15(ConversationList, { ...props2 });
4937
+ return /* @__PURE__ */ jsx19(ConversationList, { ...props2 });
4053
4938
  }
4054
4939
 
4055
4940
  // src/ui/suggestions.tsx
4056
- import { jsx as jsx16 } from "preact/jsx-runtime";
4057
- var p12 = BRAND.cssPrefix;
4941
+ import { jsx as jsx20 } from "preact/jsx-runtime";
4942
+ var p16 = BRAND.cssPrefix;
4058
4943
  function Suggestions({ suggestions, onPick }) {
4059
4944
  if (suggestions.length === 0) return null;
4060
- return /* @__PURE__ */ jsx16("div", { class: `${p12}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx16(
4945
+ return /* @__PURE__ */ jsx20("div", { class: `${p16}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx20(
4061
4946
  "button",
4062
4947
  {
4063
4948
  type: "button",
4064
- class: `${p12}-suggestion`,
4949
+ class: `${p16}-suggestion`,
4065
4950
  onClick: () => onPick(s),
4066
4951
  "data-testid": tid(TID.suggestion, i),
4067
4952
  children: s.label
@@ -4071,8 +4956,8 @@ function Suggestions({ suggestions, onPick }) {
4071
4956
  }
4072
4957
 
4073
4958
  // src/ui/panel.tsx
4074
- import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs12 } from "preact/jsx-runtime";
4075
- var p13 = BRAND.cssPrefix;
4959
+ import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
4960
+ var p17 = BRAND.cssPrefix;
4076
4961
  function Panel(props2) {
4077
4962
  const { options, onClose } = props2;
4078
4963
  const s = options.strings;
@@ -4096,18 +4981,18 @@ function Panel(props2) {
4096
4981
  }, []);
4097
4982
  const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
4098
4983
  useDragMove(containerRef.current, options.mode === "modal");
4099
- return /* @__PURE__ */ jsxs12(
4984
+ return /* @__PURE__ */ jsxs16(
4100
4985
  "div",
4101
4986
  {
4102
4987
  ref: containerRef,
4103
- class: `${p13}-panel`,
4988
+ class: `${p17}-panel`,
4104
4989
  role: "dialog",
4105
4990
  "aria-modal": "false",
4106
4991
  "aria-label": s.panelTitle,
4107
4992
  style: { position: "relative" },
4108
4993
  "data-testid": TID.panel,
4109
4994
  children: [
4110
- /* @__PURE__ */ jsx17(
4995
+ /* @__PURE__ */ jsx21(
4111
4996
  PanelContent,
4112
4997
  {
4113
4998
  ...props2,
@@ -4116,7 +5001,7 @@ function Panel(props2) {
4116
5001
  composerAttachApiRef
4117
5002
  }
4118
5003
  ),
4119
- /* @__PURE__ */ jsx17(PoweredByBar, { poweredBy: props2.options.poweredBy })
5004
+ /* @__PURE__ */ jsx21(PoweredByBar, { poweredBy: props2.options.poweredBy })
4120
5005
  ]
4121
5006
  }
4122
5007
  );
@@ -4147,13 +5032,39 @@ function PanelContent(props2) {
4147
5032
  onSend,
4148
5033
  onStop,
4149
5034
  onSuggestion,
5035
+ intakePending,
5036
+ onIntakeComplete,
5037
+ tool,
4150
5038
  containerEl,
4151
5039
  dragOver,
4152
5040
  composerAttachApiRef
4153
5041
  } = props2;
4154
5042
  const s = options.strings;
4155
- return /* @__PURE__ */ jsxs12(Fragment2, { children: [
4156
- view === "history" ? /* @__PURE__ */ jsx17(
5043
+ let composerArea;
5044
+ if (intakePending) {
5045
+ composerArea = /* @__PURE__ */ jsx21(IntakeGate, { intake: options.intake, strings: s, onComplete: onIntakeComplete });
5046
+ } else if (canSend) {
5047
+ composerArea = /* @__PURE__ */ jsxs16(Fragment3, { children: [
5048
+ /* @__PURE__ */ jsx21(Suggestions, { suggestions, onPick: onSuggestion }),
5049
+ /* @__PURE__ */ jsx21(
5050
+ Composer,
5051
+ {
5052
+ options,
5053
+ transport,
5054
+ feedback,
5055
+ bus,
5056
+ isStreaming,
5057
+ onSend,
5058
+ onStop,
5059
+ attachApiRef: composerAttachApiRef
5060
+ }
5061
+ )
5062
+ ] });
5063
+ } else {
5064
+ composerArea = /* @__PURE__ */ jsx21(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear });
5065
+ }
5066
+ return /* @__PURE__ */ jsxs16(Fragment3, { children: [
5067
+ view === "history" ? /* @__PURE__ */ jsx21(
4157
5068
  HistoryHeader,
4158
5069
  {
4159
5070
  strings: s,
@@ -4161,22 +5072,22 @@ function PanelContent(props2) {
4161
5072
  onClose,
4162
5073
  showClose: canShowClose(options.mode, panelSize, options.actions)
4163
5074
  }
4164
- ) : /* @__PURE__ */ jsxs12("header", { class: `${p13}-header`, "data-testid": TID.panelHeader, children: [
4165
- onBack ? /* @__PURE__ */ jsx17(
5075
+ ) : /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, "data-testid": TID.panelHeader, children: [
5076
+ onBack ? /* @__PURE__ */ jsx21(
4166
5077
  "button",
4167
5078
  {
4168
5079
  type: "button",
4169
- class: `${p13}-icon-btn`,
5080
+ class: `${p17}-icon-btn`,
4170
5081
  onClick: onBack,
4171
5082
  "aria-label": s.moduleBack,
4172
5083
  title: s.moduleBack,
4173
- children: /* @__PURE__ */ jsx17(BackIcon, {})
5084
+ children: /* @__PURE__ */ jsx21(BackIcon, {})
4174
5085
  }
4175
5086
  ) : null,
4176
- agent ? /* @__PURE__ */ jsx17(AgentBadge, { agent }) : /* @__PURE__ */ jsx17("h1", { children: s.panelTitle }),
4177
- /* @__PURE__ */ jsx17(HeaderActions, { panelProps: props2, variant: "chat" })
5087
+ agent ? /* @__PURE__ */ jsx21(AgentBadge, { agent }) : /* @__PURE__ */ jsx21("h1", { children: s.panelTitle }),
5088
+ /* @__PURE__ */ jsx21(HeaderActions, { panelProps: props2, variant: "chat" })
4178
5089
  ] }),
4179
- view === "history" ? /* @__PURE__ */ jsx17(
5090
+ view === "history" ? /* @__PURE__ */ jsx21(
4180
5091
  ChatHistoryPane,
4181
5092
  {
4182
5093
  transport,
@@ -4185,9 +5096,9 @@ function PanelContent(props2) {
4185
5096
  onSelect: (chat) => onSelectHistoryChat(chat.sessionId),
4186
5097
  onNewChat
4187
5098
  }
4188
- ) : /* @__PURE__ */ jsxs12(Fragment2, { children: [
4189
- /* @__PURE__ */ jsx17(DropZone, { visible: dragOver, strings: s }),
4190
- /* @__PURE__ */ jsx17(
5099
+ ) : /* @__PURE__ */ jsxs16(Fragment3, { children: [
5100
+ /* @__PURE__ */ jsx21(DropZone, { visible: dragOver, strings: s }),
5101
+ /* @__PURE__ */ jsx21(
4191
5102
  MessageList,
4192
5103
  {
4193
5104
  messagesSig,
@@ -4195,28 +5106,15 @@ function PanelContent(props2) {
4195
5106
  responseMode: options.responseMode,
4196
5107
  showReasoning: options.showReasoning,
4197
5108
  showToolCalls: options.showToolCalls,
4198
- loading: loadingMessages
5109
+ loading: loadingMessages,
5110
+ idle: !isStreaming,
5111
+ tool
4199
5112
  }
4200
5113
  ),
4201
- canSend ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
4202
- /* @__PURE__ */ jsx17(Suggestions, { suggestions, onPick: onSuggestion }),
4203
- /* @__PURE__ */ jsx17(
4204
- Composer,
4205
- {
4206
- options,
4207
- transport,
4208
- feedback,
4209
- bus,
4210
- isStreaming,
4211
- onSend,
4212
- onStop,
4213
- attachApiRef: composerAttachApiRef
4214
- }
4215
- )
4216
- ] }) : /* @__PURE__ */ jsx17(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear }),
4217
- /* @__PURE__ */ jsx17(ComposerFooter, { disclaimer: options.composerDisclaimer })
5114
+ composerArea,
5115
+ /* @__PURE__ */ jsx21(ComposerFooter, { disclaimer: options.composerDisclaimer })
4218
5116
  ] }),
4219
- options.size.resize?.enabled ? /* @__PURE__ */ jsx17(
5117
+ options.size.resize?.enabled ? /* @__PURE__ */ jsx21(
4220
5118
  ResizeGrip,
4221
5119
  {
4222
5120
  panelEl: containerEl,
@@ -4235,86 +5133,86 @@ function HistoryHeader({
4235
5133
  onClose,
4236
5134
  showClose
4237
5135
  }) {
4238
- return /* @__PURE__ */ jsxs12("header", { class: `${p13}-header`, children: [
4239
- /* @__PURE__ */ jsx17(
5136
+ return /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, children: [
5137
+ /* @__PURE__ */ jsx21(
4240
5138
  "button",
4241
5139
  {
4242
5140
  type: "button",
4243
- class: `${p13}-icon-btn`,
5141
+ class: `${p17}-icon-btn`,
4244
5142
  onClick: onBack,
4245
5143
  "aria-label": strings.historyBack,
4246
5144
  title: strings.historyBack,
4247
- children: /* @__PURE__ */ jsx17(BackIcon, {})
5145
+ children: /* @__PURE__ */ jsx21(BackIcon, {})
4248
5146
  }
4249
5147
  ),
4250
- /* @__PURE__ */ jsx17("h1", { children: strings.historyTitle }),
4251
- showClose ? /* @__PURE__ */ jsx17(
5148
+ /* @__PURE__ */ jsx21("h1", { children: strings.historyTitle }),
5149
+ showClose ? /* @__PURE__ */ jsx21(
4252
5150
  "button",
4253
5151
  {
4254
5152
  type: "button",
4255
- class: `${p13}-icon-btn`,
5153
+ class: `${p17}-icon-btn`,
4256
5154
  onClick: onClose,
4257
5155
  "aria-label": strings.close,
4258
5156
  title: strings.close,
4259
- children: /* @__PURE__ */ jsx17(CloseIcon, {})
5157
+ children: /* @__PURE__ */ jsx21(CloseIcon, {})
4260
5158
  }
4261
5159
  ) : null
4262
5160
  ] });
4263
5161
  }
4264
5162
  function ReadOnlyBanner({ label, ctaLabel, onNewChat }) {
4265
- return /* @__PURE__ */ jsxs12("div", { class: `${p13}-readonly-banner`, role: "note", children: [
4266
- /* @__PURE__ */ jsx17("span", { class: `${p13}-readonly-label`, children: label }),
4267
- /* @__PURE__ */ jsx17("button", { type: "button", class: `${p13}-readonly-cta`, onClick: onNewChat, children: ctaLabel })
5163
+ return /* @__PURE__ */ jsxs16("div", { class: `${p17}-readonly-banner`, role: "note", children: [
5164
+ /* @__PURE__ */ jsx21("span", { class: `${p17}-readonly-label`, children: label }),
5165
+ /* @__PURE__ */ jsx21("button", { type: "button", class: `${p17}-readonly-cta`, onClick: onNewChat, children: ctaLabel })
4268
5166
  ] });
4269
5167
  }
4270
5168
  function ComposerFooter({ disclaimer }) {
4271
5169
  if (!disclaimer) return null;
4272
- return /* @__PURE__ */ jsx17("div", { class: `${p13}-composer-footer`, children: /* @__PURE__ */ jsx17("div", { class: `${p13}-disclaimer`, children: disclaimer }) });
5170
+ return /* @__PURE__ */ jsx21("div", { class: `${p17}-composer-footer`, children: /* @__PURE__ */ jsx21("div", { class: `${p17}-disclaimer`, children: disclaimer }) });
4273
5171
  }
4274
5172
  function PoweredByBar({ poweredBy }) {
4275
5173
  if (!poweredBy) return null;
4276
- return /* @__PURE__ */ jsx17("div", { class: `${p13}-poweredby-bar`, children: /* @__PURE__ */ jsx17(PoweredBy, { logoUrl: poweredBy.logoUrl, text: poweredBy.text, href: poweredBy.href }) });
5174
+ return /* @__PURE__ */ jsx21("div", { class: `${p17}-poweredby-bar`, children: /* @__PURE__ */ jsx21(PoweredBy, { logoUrl: poweredBy.logoUrl, text: poweredBy.text, href: poweredBy.href }) });
4277
5175
  }
4278
5176
  function PoweredBy({ logoUrl, text, href }) {
4279
- const inner = /* @__PURE__ */ jsxs12(Fragment2, { children: [
4280
- logoUrl ? /* @__PURE__ */ jsx17("img", { class: `${p13}-poweredby-logo`, src: logoUrl, alt: "", loading: "lazy" }) : null,
4281
- text ? /* @__PURE__ */ jsx17("span", { children: text }) : null
5177
+ const inner = /* @__PURE__ */ jsxs16(Fragment3, { children: [
5178
+ logoUrl ? /* @__PURE__ */ jsx21("img", { class: `${p17}-poweredby-logo`, src: logoUrl, alt: "", loading: "lazy" }) : null,
5179
+ text ? /* @__PURE__ */ jsx21("span", { children: text }) : null
4282
5180
  ] });
4283
5181
  if (href) {
4284
- return /* @__PURE__ */ jsx17("a", { class: `${p13}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
5182
+ return /* @__PURE__ */ jsx21("a", { class: `${p17}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
4285
5183
  }
4286
- return /* @__PURE__ */ jsx17("span", { class: `${p13}-poweredby`, children: inner });
5184
+ return /* @__PURE__ */ jsx21("span", { class: `${p17}-poweredby`, children: inner });
4287
5185
  }
4288
5186
 
4289
5187
  // src/ui/sidebar.tsx
4290
- import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs13 } from "preact/jsx-runtime";
5188
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
4291
5189
  function Sidebar(props2) {
4292
- const p29 = BRAND.cssPrefix;
5190
+ const p33 = BRAND.cssPrefix;
4293
5191
  const { site, blocks, strings, collapsed } = props2;
4294
5192
  const navigation = blocks?.navigation ?? [];
4295
5193
  const linkCards = blocks?.linkCards ?? [];
4296
5194
  const toggleLabel = collapsed ? strings.expandSidebar : strings.collapseSidebar;
4297
- return /* @__PURE__ */ jsxs13("aside", { class: `${p29}-sidebar`, "data-collapsed": collapsed ? "true" : "false", "data-testid": TID.sidebar, children: [
4298
- /* @__PURE__ */ jsxs13("div", { class: `${p29}-sidebar-header`, children: [
4299
- /* @__PURE__ */ jsx18(SidebarBrand, { site }),
4300
- /* @__PURE__ */ jsx18(
5195
+ return /* @__PURE__ */ jsxs17("aside", { class: `${p33}-sidebar`, "data-collapsed": collapsed ? "true" : "false", "data-testid": TID.sidebar, children: [
5196
+ /* @__PURE__ */ jsxs17("div", { class: `${p33}-sidebar-header`, children: [
5197
+ /* @__PURE__ */ jsx22(SidebarBrand, { site }),
5198
+ /* @__PURE__ */ jsx22(
4301
5199
  "button",
4302
5200
  {
4303
5201
  type: "button",
4304
- class: `${p29}-sidebar-toggle`,
5202
+ class: `${p33}-sidebar-toggle`,
4305
5203
  "aria-label": toggleLabel,
4306
5204
  "aria-expanded": collapsed ? "false" : "true",
4307
5205
  title: toggleLabel,
4308
5206
  onClick: props2.onToggleCollapsed,
4309
5207
  "data-testid": TID.sidebarToggle,
4310
- children: /* @__PURE__ */ jsx18(SidebarToggleIcon, { collapsed })
5208
+ children: /* @__PURE__ */ jsx22(SidebarToggleIcon, { collapsed })
4311
5209
  }
4312
5210
  )
4313
5211
  ] }),
4314
- collapsed ? null : /* @__PURE__ */ jsxs13(Fragment3, { children: [
4315
- navigation.length > 0 ? /* @__PURE__ */ jsx18("nav", { class: `${p29}-sidebar-section`, "data-section": "navigation", children: /* @__PURE__ */ jsx18(SidebarNav, { items: navigation }) }) : null,
4316
- linkCards.length > 0 ? /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-section`, "data-section": "link-cards", children: /* @__PURE__ */ jsx18(SidebarCards, { items: linkCards }) }) : null,
4317
- props2.showConversations ? /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-conversations`, children: /* @__PURE__ */ jsx18(
5212
+ collapsed ? null : /* @__PURE__ */ jsxs17(Fragment4, { children: [
5213
+ navigation.length > 0 ? /* @__PURE__ */ jsx22("nav", { class: `${p33}-sidebar-section`, "data-section": "navigation", children: /* @__PURE__ */ jsx22(SidebarNav, { items: navigation }) }) : null,
5214
+ linkCards.length > 0 ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-section`, "data-section": "link-cards", children: /* @__PURE__ */ jsx22(SidebarCards, { items: linkCards }) }) : null,
5215
+ props2.showConversations ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-conversations`, children: /* @__PURE__ */ jsx22(
4318
5216
  ConversationList,
4319
5217
  {
4320
5218
  transport: props2.transport,
@@ -4328,18 +5226,18 @@ function Sidebar(props2) {
4328
5226
  ] });
4329
5227
  }
4330
5228
  function SidebarBrand({ site }) {
4331
- const p29 = BRAND.cssPrefix;
5229
+ const p33 = BRAND.cssPrefix;
4332
5230
  if (site?.logo?.url) {
4333
5231
  const alt = site.logo.alt ?? site.title ?? "Logo";
4334
- return /* @__PURE__ */ jsxs13("picture", { children: [
4335
- site.logoDark?.url ? /* @__PURE__ */ jsx18("source", { srcset: site.logoDark.url, media: "(prefers-color-scheme: dark)" }) : null,
4336
- /* @__PURE__ */ jsx18("img", { class: `${p29}-sidebar-logo`, src: site.logo.url, alt })
5232
+ return /* @__PURE__ */ jsxs17("picture", { children: [
5233
+ site.logoDark?.url ? /* @__PURE__ */ jsx22("source", { srcset: site.logoDark.url, media: "(prefers-color-scheme: dark)" }) : null,
5234
+ /* @__PURE__ */ jsx22("img", { class: `${p33}-sidebar-logo`, src: site.logo.url, alt })
4337
5235
  ] });
4338
5236
  }
4339
- return /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-title`, children: site?.title ?? BRAND.name });
5237
+ return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-title`, children: site?.title ?? BRAND.name });
4340
5238
  }
4341
5239
  function SidebarToggleIcon({ collapsed }) {
4342
- return /* @__PURE__ */ jsx18(
5240
+ return /* @__PURE__ */ jsx22(
4343
5241
  "svg",
4344
5242
  {
4345
5243
  width: "16",
@@ -4349,38 +5247,38 @@ function SidebarToggleIcon({ collapsed }) {
4349
5247
  stroke: "currentColor",
4350
5248
  "stroke-width": "2",
4351
5249
  "aria-hidden": "true",
4352
- children: collapsed ? /* @__PURE__ */ jsx18("polyline", { points: "9 6 15 12 9 18" }) : /* @__PURE__ */ jsx18("polyline", { points: "15 6 9 12 15 18" })
5250
+ children: collapsed ? /* @__PURE__ */ jsx22("polyline", { points: "9 6 15 12 9 18" }) : /* @__PURE__ */ jsx22("polyline", { points: "15 6 9 12 15 18" })
4353
5251
  }
4354
5252
  );
4355
5253
  }
4356
5254
  function SidebarNav({ items }) {
4357
- const p29 = BRAND.cssPrefix;
4358
- return /* @__PURE__ */ jsx18("ul", { class: `${p29}-sidebar-nav`, children: items.map((item) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsxs13(
5255
+ const p33 = BRAND.cssPrefix;
5256
+ return /* @__PURE__ */ jsx22("ul", { class: `${p33}-sidebar-nav`, children: items.map((item) => /* @__PURE__ */ jsx22("li", { children: /* @__PURE__ */ jsxs17(
4359
5257
  "a",
4360
5258
  {
4361
- class: `${p29}-sidebar-nav-item`,
5259
+ class: `${p33}-sidebar-nav-item`,
4362
5260
  href: item.href,
4363
5261
  target: item.href ? "_blank" : void 0,
4364
5262
  rel: item.href ? "noreferrer" : void 0,
4365
5263
  children: [
4366
- item.icon ? /* @__PURE__ */ jsx18("span", { class: `${p29}-sidebar-nav-icon`, "data-icon": item.icon }) : null,
4367
- /* @__PURE__ */ jsx18("span", { class: `${p29}-sidebar-nav-label`, children: item.label })
5264
+ item.icon ? /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-icon`, "data-icon": item.icon }) : null,
5265
+ /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-label`, children: item.label })
4368
5266
  ]
4369
5267
  }
4370
5268
  ) }, item.id ?? item.label)) });
4371
5269
  }
4372
5270
  function SidebarCards({ items }) {
4373
- const p29 = BRAND.cssPrefix;
4374
- return /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs13(
5271
+ const p33 = BRAND.cssPrefix;
5272
+ return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs17(
4375
5273
  "a",
4376
5274
  {
4377
- class: `${p29}-sidebar-card`,
5275
+ class: `${p33}-sidebar-card`,
4378
5276
  href: item.href,
4379
5277
  target: item.href ? "_blank" : void 0,
4380
5278
  rel: item.href ? "noreferrer" : void 0,
4381
5279
  children: [
4382
- /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-card-label`, children: item.label }),
4383
- item.description ? /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-card-desc`, children: item.description }) : null
5280
+ /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-label`, children: item.label }),
5281
+ item.description ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-desc`, children: item.description }) : null
4384
5282
  ]
4385
5283
  },
4386
5284
  item.id ?? item.label
@@ -4388,11 +5286,11 @@ function SidebarCards({ items }) {
4388
5286
  }
4389
5287
 
4390
5288
  // src/ui/page-shell.tsx
4391
- import { jsx as jsx19, jsxs as jsxs14 } from "preact/jsx-runtime";
4392
- var p14 = BRAND.cssPrefix;
5289
+ import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
5290
+ var p18 = BRAND.cssPrefix;
4393
5291
  function PageShell(props2) {
4394
- return /* @__PURE__ */ jsxs14("main", { class: `${p14}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
4395
- /* @__PURE__ */ jsx19(
5292
+ return /* @__PURE__ */ jsxs18("main", { class: `${p18}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
5293
+ /* @__PURE__ */ jsx23(
4396
5294
  Sidebar,
4397
5295
  {
4398
5296
  site: props2.site,
@@ -4407,7 +5305,7 @@ function PageShell(props2) {
4407
5305
  onToggleCollapsed: props2.onToggleSidebarCollapsed
4408
5306
  }
4409
5307
  ),
4410
- /* @__PURE__ */ jsx19("section", { class: `${p14}-page-chat`, "aria-label": "Chat", children: props2.children })
5308
+ /* @__PURE__ */ jsx23("section", { class: `${p18}-page-chat`, "aria-label": "Chat", children: props2.children })
4411
5309
  ] });
4412
5310
  }
4413
5311
 
@@ -4445,7 +5343,7 @@ var atTabRoot = (s) => activeStack(s).length === 0;
4445
5343
 
4446
5344
  // src/ui/messenger-home.tsx
4447
5345
  import { useCallback as useCallback4, useEffect as useEffect15, useRef as useRef7 } from "preact/hooks";
4448
- import { useComputed as useComputed4 } from "@preact/signals";
5346
+ import { useComputed as useComputed6 } from "@preact/signals";
4449
5347
 
4450
5348
  // src/ui/modules/messages.tsx
4451
5349
  var chatLayout = {
@@ -4454,83 +5352,83 @@ var chatLayout = {
4454
5352
  };
4455
5353
 
4456
5354
  // src/ui/modules/help.tsx
4457
- import { useEffect as useEffect11, useMemo as useMemo2, useState as useState7 } from "preact/hooks";
5355
+ import { useEffect as useEffect11, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
4458
5356
 
4459
5357
  // src/ui/back-header.tsx
4460
- import { jsx as jsx20, jsxs as jsxs15 } from "preact/jsx-runtime";
4461
- var p15 = BRAND.cssPrefix;
5358
+ import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
5359
+ var p19 = BRAND.cssPrefix;
4462
5360
  function TitleBar({ title, actions }) {
4463
- return /* @__PURE__ */ jsxs15("header", { class: `${p15}-back-header`, "data-variant": "title", children: [
4464
- /* @__PURE__ */ jsx20("span", { class: `${p15}-back-spacer`, "aria-hidden": "true" }),
4465
- /* @__PURE__ */ jsx20("h1", { class: `${p15}-back-title`, children: title }),
4466
- actions ?? /* @__PURE__ */ jsx20("span", { class: `${p15}-back-spacer`, "aria-hidden": "true" })
5361
+ return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-variant": "title", children: [
5362
+ /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" }),
5363
+ /* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
5364
+ actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
4467
5365
  ] });
4468
5366
  }
4469
5367
  function BackHeader({ title, backLabel, onBack, actions, testid }) {
4470
- return /* @__PURE__ */ jsxs15("header", { class: `${p15}-back-header`, "data-testid": testid, children: [
4471
- /* @__PURE__ */ jsx20("button", { type: "button", class: `${p15}-icon-btn`, onClick: onBack, "aria-label": backLabel, title: backLabel, children: /* @__PURE__ */ jsx20(BackIcon, {}) }),
4472
- /* @__PURE__ */ jsx20("h1", { class: `${p15}-back-title`, children: title }),
4473
- actions ?? /* @__PURE__ */ jsx20("span", { class: `${p15}-back-spacer`, "aria-hidden": "true" })
5368
+ return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-testid": testid, children: [
5369
+ /* @__PURE__ */ jsx24("button", { type: "button", class: `${p19}-icon-btn`, onClick: onBack, "aria-label": backLabel, title: backLabel, children: /* @__PURE__ */ jsx24(BackIcon, {}) }),
5370
+ /* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
5371
+ actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
4474
5372
  ] });
4475
5373
  }
4476
5374
 
4477
5375
  // src/ui/home-search.tsx
4478
- import { jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
4479
- var p16 = BRAND.cssPrefix;
5376
+ import { jsx as jsx25, jsxs as jsxs20 } from "preact/jsx-runtime";
5377
+ var p20 = BRAND.cssPrefix;
4480
5378
  function HomeSearchButton({ placeholder, onActivate }) {
4481
- return /* @__PURE__ */ jsxs16("button", { type: "button", class: `${p16}-home-search`, onClick: onActivate, "data-testid": TID.homeSearch, children: [
4482
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-text`, children: placeholder }),
4483
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx21(SearchIcon, {}) })
5379
+ return /* @__PURE__ */ jsxs20("button", { type: "button", class: `${p20}-home-search`, onClick: onActivate, "data-testid": TID.homeSearch, children: [
5380
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-text`, children: placeholder }),
5381
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
4484
5382
  ] });
4485
5383
  }
4486
5384
  function HelpSearchInput({ placeholder, value, onInput }) {
4487
- return /* @__PURE__ */ jsxs16("div", { class: `${p16}-home-search`, "data-input": "true", children: [
4488
- /* @__PURE__ */ jsx21(
5385
+ return /* @__PURE__ */ jsxs20("div", { class: `${p20}-home-search`, "data-input": "true", children: [
5386
+ /* @__PURE__ */ jsx25(
4489
5387
  "input",
4490
5388
  {
4491
5389
  type: "search",
4492
- class: `${p16}-home-search-input`,
5390
+ class: `${p20}-home-search-input`,
4493
5391
  placeholder,
4494
5392
  value,
4495
5393
  onInput: (e) => onInput(e.currentTarget.value),
4496
5394
  "data-testid": TID.helpSearch
4497
5395
  }
4498
5396
  ),
4499
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx21(SearchIcon, {}) })
5397
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
4500
5398
  ] });
4501
5399
  }
4502
5400
 
4503
5401
  // src/ui/list-row.tsx
4504
- import { jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
4505
- var p17 = BRAND.cssPrefix;
5402
+ import { jsx as jsx26, jsxs as jsxs21 } from "preact/jsx-runtime";
5403
+ var p21 = BRAND.cssPrefix;
4506
5404
  function ListRow({ title, subtitle, onClick, testid }) {
4507
- return /* @__PURE__ */ jsxs17("button", { type: "button", class: `${p17}-list-row`, onClick, "data-testid": testid, children: [
4508
- /* @__PURE__ */ jsxs17("span", { class: `${p17}-list-row-body`, children: [
4509
- /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-title`, children: title }),
4510
- subtitle ? /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-sub`, children: subtitle }) : null
5405
+ return /* @__PURE__ */ jsxs21("button", { type: "button", class: `${p21}-list-row`, onClick, "data-testid": testid, children: [
5406
+ /* @__PURE__ */ jsxs21("span", { class: `${p21}-list-row-body`, children: [
5407
+ /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-title`, children: title }),
5408
+ subtitle ? /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-sub`, children: subtitle }) : null
4511
5409
  ] }),
4512
- /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx22(ChevronRightIcon, {}) })
5410
+ /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(ChevronRightIcon, {}) })
4513
5411
  ] });
4514
5412
  }
4515
5413
 
4516
5414
  // src/ui/module-state.tsx
4517
- import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
4518
- var p18 = BRAND.cssPrefix;
5415
+ import { jsx as jsx27, jsxs as jsxs22 } from "preact/jsx-runtime";
5416
+ var p22 = BRAND.cssPrefix;
4519
5417
  function ModuleState({
4520
5418
  tone = "info",
4521
5419
  message,
4522
5420
  onRetry,
4523
5421
  strings
4524
5422
  }) {
4525
- return /* @__PURE__ */ jsxs18("div", { class: `${p18}-module-empty`, role: tone === "error" ? "alert" : "status", "aria-live": "polite", children: [
4526
- /* @__PURE__ */ jsx23("span", { children: message }),
4527
- onRetry ? /* @__PURE__ */ jsx23("button", { type: "button", class: `${p18}-module-retry`, onClick: onRetry, children: strings.errorRetry }) : null
5423
+ return /* @__PURE__ */ jsxs22("div", { class: `${p22}-module-empty`, role: tone === "error" ? "alert" : "status", "aria-live": "polite", children: [
5424
+ /* @__PURE__ */ jsx27("span", { children: message }),
5425
+ onRetry ? /* @__PURE__ */ jsx27("button", { type: "button", class: `${p22}-module-retry`, onClick: onRetry, children: strings.errorRetry }) : null
4528
5426
  ] });
4529
5427
  }
4530
5428
 
4531
5429
  // src/ui/modules/help.tsx
4532
- import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
4533
- var p19 = BRAND.cssPrefix;
5430
+ import { jsx as jsx28, jsxs as jsxs23 } from "preact/jsx-runtime";
5431
+ var p23 = BRAND.cssPrefix;
4534
5432
  var log12 = logger.scope("help");
4535
5433
  var openArticle = (nav, a) => a.url ? nav.push({ kind: "iframe", url: a.url, title: a.title }) : nav.push({ kind: "content", id: a.id, title: a.title });
4536
5434
  function groupByCategory(items) {
@@ -4559,7 +5457,7 @@ function fuzzySearch(items, query) {
4559
5457
  return items.map((item) => ({ item, score: Math.max(fuzzyScore(q, item.title) * 2, fuzzyScore(q, item.description ?? "")) })).filter((r) => r.score > 0).toSorted((a, b) => b.score - a.score).map((r) => r.item);
4560
5458
  }
4561
5459
  function ArticleRow({ article, nav }) {
4562
- return /* @__PURE__ */ jsx24(
5460
+ return /* @__PURE__ */ jsx28(
4563
5461
  ListRow,
4564
5462
  {
4565
5463
  title: article.title,
@@ -4571,11 +5469,11 @@ function ArticleRow({ article, nav }) {
4571
5469
  }
4572
5470
  function HelpRoot({ transport, strings, config, nav, panelProps }) {
4573
5471
  const tags = config.contentTags;
4574
- const [state, setState] = useState7("loading");
4575
- const [errorMsg, setErrorMsg] = useState7(strings.errorGeneric);
4576
- const [items, setItems] = useState7([]);
4577
- const [query, setQuery] = useState7("");
4578
- const [reloadKey, setReloadKey] = useState7(0);
5472
+ const [state, setState] = useState8("loading");
5473
+ const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
5474
+ const [items, setItems] = useState8([]);
5475
+ const [query, setQuery] = useState8("");
5476
+ const [reloadKey, setReloadKey] = useState8(0);
4579
5477
  useEffect11(() => {
4580
5478
  let cancelled = false;
4581
5479
  setState("loading");
@@ -4596,46 +5494,46 @@ function HelpRoot({ transport, strings, config, nav, panelProps }) {
4596
5494
  const results = useMemo2(() => fuzzySearch(items, query), [items, query]);
4597
5495
  function renderBody() {
4598
5496
  if (query.trim().length > 0) {
4599
- if (results.length === 0) return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpSearchEmpty, strings });
4600
- return /* @__PURE__ */ jsx24("div", { class: `${p19}-help-card`, children: results.map((a) => /* @__PURE__ */ jsx24(ArticleRow, { article: a, nav }, a.id)) });
5497
+ if (results.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpSearchEmpty, strings });
5498
+ return /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: results.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) });
4601
5499
  }
4602
- if (state === "loading") return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpLoading, strings });
5500
+ if (state === "loading") return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpLoading, strings });
4603
5501
  if (state === "error") {
4604
- return /* @__PURE__ */ jsx24(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
5502
+ return /* @__PURE__ */ jsx28(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
4605
5503
  }
4606
- if (items.length === 0) return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpEmpty, strings });
4607
- return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */ jsxs19("section", { class: `${p19}-help-group`, children: [
4608
- category ? /* @__PURE__ */ jsx24("h2", { class: `${p19}-help-section-title`, children: category }) : null,
4609
- /* @__PURE__ */ jsx24("div", { class: `${p19}-help-card`, children: rows.map((a) => /* @__PURE__ */ jsx24(ArticleRow, { article: a, nav }, a.id)) })
5504
+ if (items.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpEmpty, strings });
5505
+ return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */ jsxs23("section", { class: `${p23}-help-group`, children: [
5506
+ category ? /* @__PURE__ */ jsx28("h2", { class: `${p23}-help-section-title`, children: category }) : null,
5507
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: rows.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) })
4610
5508
  ] }, category));
4611
5509
  }
4612
- return /* @__PURE__ */ jsxs19("div", { class: `${p19}-module`, children: [
4613
- /* @__PURE__ */ jsx24(TitleBar, { title: strings.helpTitle, actions: /* @__PURE__ */ jsx24(HeaderActions, { panelProps, variant: "plain" }) }),
4614
- /* @__PURE__ */ jsx24("div", { class: `${p19}-module-pad`, children: /* @__PURE__ */ jsx24(HelpSearchInput, { placeholder: strings.helpSearchPlaceholder, value: query, onInput: setQuery }) }),
4615
- /* @__PURE__ */ jsx24("div", { class: `${p19}-help-list`, children: renderBody() })
5510
+ return /* @__PURE__ */ jsxs23("div", { class: `${p23}-module`, children: [
5511
+ /* @__PURE__ */ jsx28(TitleBar, { title: strings.helpTitle, actions: /* @__PURE__ */ jsx28(HeaderActions, { panelProps, variant: "plain" }) }),
5512
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-module-pad`, children: /* @__PURE__ */ jsx28(HelpSearchInput, { placeholder: strings.helpSearchPlaceholder, value: query, onInput: setQuery }) }),
5513
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-help-list`, children: renderBody() })
4616
5514
  ] });
4617
5515
  }
4618
5516
  var helpLayout = {
4619
5517
  Icon: HelpIcon,
4620
- Root: (props2) => /* @__PURE__ */ jsx24(HelpRoot, { ...props2 })
5518
+ Root: (props2) => /* @__PURE__ */ jsx28(HelpRoot, { ...props2 })
4621
5519
  };
4622
5520
 
4623
5521
  // src/ui/modules/home.tsx
4624
- import { useEffect as useEffect12, useState as useState8 } from "preact/hooks";
5522
+ import { useEffect as useEffect12, useState as useState9 } from "preact/hooks";
4625
5523
 
4626
5524
  // src/ui/home-card.tsx
4627
- import { jsx as jsx25 } from "preact/jsx-runtime";
4628
- var p20 = BRAND.cssPrefix;
5525
+ import { jsx as jsx29 } from "preact/jsx-runtime";
5526
+ var p24 = BRAND.cssPrefix;
4629
5527
  function HomeCard({ onClick, children, testid }) {
4630
5528
  if (onClick) {
4631
- return /* @__PURE__ */ jsx25("button", { type: "button", class: `${p20}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
5529
+ return /* @__PURE__ */ jsx29("button", { type: "button", class: `${p24}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
4632
5530
  }
4633
- return /* @__PURE__ */ jsx25("div", { class: `${p20}-home-card`, "data-testid": testid, children });
5531
+ return /* @__PURE__ */ jsx29("div", { class: `${p24}-home-card`, "data-testid": testid, children });
4634
5532
  }
4635
5533
 
4636
5534
  // src/ui/modules/home.tsx
4637
- import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs20 } from "preact/jsx-runtime";
4638
- var p21 = BRAND.cssPrefix;
5535
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs24 } from "preact/jsx-runtime";
5536
+ var p25 = BRAND.cssPrefix;
4639
5537
  var log13 = logger.scope("home");
4640
5538
  function resolveGreeting(props2) {
4641
5539
  const name = props2.options.userContext?.name;
@@ -4649,8 +5547,8 @@ function resolveGreeting(props2) {
4649
5547
  var openContent = (nav, item) => item.url ? nav.push({ kind: "iframe", url: item.url, title: item.title }) : nav.push({ kind: "content", id: item.id, title: item.title });
4650
5548
  function HomeRoot(props2) {
4651
5549
  const { transport, strings, config, nav, panelProps } = props2;
4652
- const [recent, setRecent] = useState8(null);
4653
- const [content, setContent] = useState8([]);
5550
+ const [recent, setRecent] = useState9(null);
5551
+ const [content, setContent] = useState9([]);
4654
5552
  const tagsKey = config.contentTags?.join(",");
4655
5553
  useEffect12(() => {
4656
5554
  if (!config.showRecentMessages) return;
@@ -4672,49 +5570,49 @@ function HomeRoot(props2) {
4672
5570
  const avatars = config.userAvatars ?? [];
4673
5571
  const status = config.status;
4674
5572
  const contentTitle = config.contentBlockTitle ? moduleLabel(strings, config.contentBlockTitle) : strings.homeContentTitle;
4675
- return /* @__PURE__ */ jsx26("div", { class: `${p21}-module ${p21}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-scroll`, children: [
4676
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-hero`, children: [
4677
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-hero-top`, children: [
4678
- config.brandName ? /* @__PURE__ */ jsx26("span", { class: `${p21}-home-brand`, "data-testid": TID.homeBrand, children: config.brandName }) : /* @__PURE__ */ jsx26("span", { class: `${p21}-home-brand-spacer`, "aria-hidden": "true" }),
4679
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-hero-actions`, children: [
4680
- avatars.length > 0 ? /* @__PURE__ */ jsx26("div", { class: `${p21}-home-avatars`, children: avatars.map((a) => /* @__PURE__ */ jsx26("span", { class: `${p21}-home-avatar`, title: a.role ? `${a.name} \xB7 ${a.role}` : a.name, children: a.avatar ? /* @__PURE__ */ jsx26("img", { src: a.avatar, alt: "", loading: "lazy" }) : /* @__PURE__ */ jsx26("span", { children: initials(a.name) }) }, a.name)) }) : null,
4681
- /* @__PURE__ */ jsx26(HeaderActions, { panelProps, variant: "plain" })
5573
+ return /* @__PURE__ */ jsx30("div", { class: `${p25}-module ${p25}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-scroll`, children: [
5574
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero`, children: [
5575
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-top`, children: [
5576
+ config.brandName ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-brand`, "data-testid": TID.homeBrand, children: config.brandName }) : /* @__PURE__ */ jsx30("span", { class: `${p25}-home-brand-spacer`, "aria-hidden": "true" }),
5577
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-actions`, children: [
5578
+ avatars.length > 0 ? /* @__PURE__ */ jsx30("div", { class: `${p25}-home-avatars`, children: avatars.map((a) => /* @__PURE__ */ jsx30("span", { class: `${p25}-home-avatar`, title: a.role ? `${a.name} \xB7 ${a.role}` : a.name, children: a.avatar ? /* @__PURE__ */ jsx30("img", { src: a.avatar, alt: "", loading: "lazy" }) : /* @__PURE__ */ jsx30("span", { children: initials(a.name) }) }, a.name)) }) : null,
5579
+ /* @__PURE__ */ jsx30(HeaderActions, { panelProps, variant: "plain" })
4682
5580
  ] })
4683
5581
  ] }),
4684
- config.showGreeting !== false ? /* @__PURE__ */ jsxs20(Fragment4, { children: [
4685
- /* @__PURE__ */ jsx26("h1", { class: `${p21}-home-greeting`, "data-testid": TID.homeGreeting, children: greeting.title }),
4686
- greeting.subtitle ? /* @__PURE__ */ jsx26("p", { class: `${p21}-home-lead`, children: greeting.subtitle }) : null
5582
+ config.showGreeting !== false ? /* @__PURE__ */ jsxs24(Fragment5, { children: [
5583
+ /* @__PURE__ */ jsx30("h1", { class: `${p25}-home-greeting`, "data-testid": TID.homeGreeting, children: greeting.title }),
5584
+ greeting.subtitle ? /* @__PURE__ */ jsx30("p", { class: `${p25}-home-lead`, children: greeting.subtitle }) : null
4687
5585
  ] }) : null
4688
5586
  ] }),
4689
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-cards`, children: [
4690
- config.showSearchBar !== false ? /* @__PURE__ */ jsx26(
5587
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-cards`, children: [
5588
+ config.showSearchBar !== false ? /* @__PURE__ */ jsx30(
4691
5589
  HomeSearchButton,
4692
5590
  {
4693
5591
  placeholder: strings.homeSearchPlaceholder,
4694
5592
  onActivate: () => nav.switchToLayout("help")
4695
5593
  }
4696
5594
  ) : null,
4697
- recent ? /* @__PURE__ */ jsx26(HomeCard, { onClick: () => nav.selectSession(recent.sessionId), testid: TID.homeRecent, children: /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-recent-row`, "data-unread": (recent.unreadCount ?? 0) > 0 ? "true" : void 0, children: [
4698
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-avatar`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(BubblesIcon, {}) }),
4699
- /* @__PURE__ */ jsxs20("span", { class: `${p21}-home-recent-body`, children: [
4700
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-title`, children: recent.title }),
4701
- recent.preview ? /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-preview`, children: recent.preview }) : null
5595
+ recent ? /* @__PURE__ */ jsx30(HomeCard, { onClick: () => nav.selectSession(recent.sessionId), testid: TID.homeRecent, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-recent-row`, "data-unread": (recent.unreadCount ?? 0) > 0 ? "true" : void 0, children: [
5596
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-avatar`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(BubblesIcon, {}) }),
5597
+ /* @__PURE__ */ jsxs24("span", { class: `${p25}-home-recent-body`, children: [
5598
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-title`, children: recent.title }),
5599
+ recent.preview ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-preview`, children: recent.preview }) : null
4702
5600
  ] }),
4703
- (recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-dot`, "aria-label": "Unread" }) : null
5601
+ (recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-dot`, "aria-label": "Unread" }) : null
4704
5602
  ] }) }) : null,
4705
- status ? /* @__PURE__ */ jsx26(
5603
+ status ? /* @__PURE__ */ jsx30(
4706
5604
  HomeCard,
4707
5605
  {
4708
5606
  onClick: status.url ? () => nav.push({ kind: "iframe", url: status.url, title: status.text }) : void 0,
4709
- children: /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-status`, "data-level": status.level ?? "operational", children: [
4710
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-status-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(StatusOkIcon, {}) }),
4711
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-status-text`, children: status.text })
5607
+ children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-status`, "data-level": status.level ?? "operational", children: [
5608
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(StatusOkIcon, {}) }),
5609
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-text`, children: status.text })
4712
5610
  ] })
4713
5611
  }
4714
5612
  ) : null,
4715
- content.length > 0 ? /* @__PURE__ */ jsxs20("section", { class: `${p21}-home-content`, children: [
4716
- /* @__PURE__ */ jsx26("div", { class: `${p21}-home-content-title`, children: contentTitle }),
4717
- /* @__PURE__ */ jsx26("div", { class: `${p21}-home-content-list`, children: content.map((item) => /* @__PURE__ */ jsx26(
5613
+ content.length > 0 ? /* @__PURE__ */ jsxs24("section", { class: `${p25}-home-content`, children: [
5614
+ /* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-title`, children: contentTitle }),
5615
+ /* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-list`, children: content.map((item) => /* @__PURE__ */ jsx30(
4718
5616
  ListRow,
4719
5617
  {
4720
5618
  title: item.title,
@@ -4730,20 +5628,20 @@ function HomeRoot(props2) {
4730
5628
  }
4731
5629
  var homeLayout = {
4732
5630
  Icon: HomeIcon,
4733
- Root: (props2) => /* @__PURE__ */ jsx26(HomeRoot, { ...props2 })
5631
+ Root: (props2) => /* @__PURE__ */ jsx30(HomeRoot, { ...props2 })
4734
5632
  };
4735
5633
 
4736
5634
  // src/ui/modules/news.tsx
4737
- import { useEffect as useEffect13, useState as useState9 } from "preact/hooks";
4738
- import { jsx as jsx27, jsxs as jsxs21 } from "preact/jsx-runtime";
4739
- var p22 = BRAND.cssPrefix;
5635
+ import { useEffect as useEffect13, useState as useState10 } from "preact/hooks";
5636
+ import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
5637
+ var p26 = BRAND.cssPrefix;
4740
5638
  var log14 = logger.scope("news");
4741
5639
  function NewsRoot({ transport, strings, config, nav, panelProps }) {
4742
5640
  const tags = config.contentTags;
4743
- const [state, setState] = useState9("loading");
4744
- const [errorMsg, setErrorMsg] = useState9(strings.errorGeneric);
4745
- const [items, setItems] = useState9([]);
4746
- const [reloadKey, setReloadKey] = useState9(0);
5641
+ const [state, setState] = useState10("loading");
5642
+ const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
5643
+ const [items, setItems] = useState10([]);
5644
+ const [reloadKey, setReloadKey] = useState10(0);
4747
5645
  useEffect13(() => {
4748
5646
  let cancelled = false;
4749
5647
  setState("loading");
@@ -4762,38 +5660,38 @@ function NewsRoot({ transport, strings, config, nav, panelProps }) {
4762
5660
  };
4763
5661
  }, [transport, tags, reloadKey]);
4764
5662
  function renderBody() {
4765
- if (state === "loading") return /* @__PURE__ */ jsx27(ModuleState, { message: strings.newsLoading, strings });
5663
+ if (state === "loading") return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsLoading, strings });
4766
5664
  if (state === "error") {
4767
- return /* @__PURE__ */ jsx27(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
5665
+ return /* @__PURE__ */ jsx31(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
4768
5666
  }
4769
- if (items.length === 0) return /* @__PURE__ */ jsx27(ModuleState, { message: strings.newsEmpty, strings });
4770
- return /* @__PURE__ */ jsx27("div", { class: `${p22}-news-list`, children: items.map((item) => /* @__PURE__ */ jsxs21(
5667
+ if (items.length === 0) return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsEmpty, strings });
5668
+ return /* @__PURE__ */ jsx31("div", { class: `${p26}-news-list`, children: items.map((item) => /* @__PURE__ */ jsxs25(
4771
5669
  "button",
4772
5670
  {
4773
5671
  type: "button",
4774
- class: `${p22}-news-card`,
5672
+ class: `${p26}-news-card`,
4775
5673
  onClick: () => nav.push({ kind: "content", id: item.id, title: item.title }),
4776
5674
  "data-testid": tid(TID.newsItem, item.id),
4777
5675
  children: [
4778
- item.image ? /* @__PURE__ */ jsx27("img", { class: `${p22}-news-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
4779
- /* @__PURE__ */ jsxs21("span", { class: `${p22}-news-body`, children: [
4780
- item.tags && item.tags.length > 0 ? /* @__PURE__ */ jsx27("span", { class: `${p22}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx27("span", { class: `${p22}-news-tag`, children: t }, t)) }) : null,
4781
- /* @__PURE__ */ jsx27("span", { class: `${p22}-news-title`, children: item.title }),
4782
- item.description ? /* @__PURE__ */ jsx27("span", { class: `${p22}-news-summary`, children: item.description }) : null
5676
+ item.image ? /* @__PURE__ */ jsx31("img", { class: `${p26}-news-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
5677
+ /* @__PURE__ */ jsxs25("span", { class: `${p26}-news-body`, children: [
5678
+ item.tags && item.tags.length > 0 ? /* @__PURE__ */ jsx31("span", { class: `${p26}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx31("span", { class: `${p26}-news-tag`, children: t }, t)) }) : null,
5679
+ /* @__PURE__ */ jsx31("span", { class: `${p26}-news-title`, children: item.title }),
5680
+ item.description ? /* @__PURE__ */ jsx31("span", { class: `${p26}-news-summary`, children: item.description }) : null
4783
5681
  ] })
4784
5682
  ]
4785
5683
  },
4786
5684
  item.id
4787
5685
  )) });
4788
5686
  }
4789
- return /* @__PURE__ */ jsxs21("div", { class: `${p22}-module`, children: [
4790
- /* @__PURE__ */ jsx27(TitleBar, { title: strings.newsTitle, actions: /* @__PURE__ */ jsx27(HeaderActions, { panelProps, variant: "plain" }) }),
4791
- /* @__PURE__ */ jsx27("div", { class: `${p22}-module-scroll`, children: renderBody() })
5687
+ return /* @__PURE__ */ jsxs25("div", { class: `${p26}-module`, children: [
5688
+ /* @__PURE__ */ jsx31(TitleBar, { title: strings.newsTitle, actions: /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" }) }),
5689
+ /* @__PURE__ */ jsx31("div", { class: `${p26}-module-scroll`, children: renderBody() })
4792
5690
  ] });
4793
5691
  }
4794
5692
  var newsLayout = {
4795
5693
  Icon: NewsIcon,
4796
- Root: (props2) => /* @__PURE__ */ jsx27(NewsRoot, { ...props2 })
5694
+ Root: (props2) => /* @__PURE__ */ jsx31(NewsRoot, { ...props2 })
4797
5695
  };
4798
5696
 
4799
5697
  // src/ui/modules/registry.ts
@@ -4805,28 +5703,28 @@ var LAYOUTS = {
4805
5703
  };
4806
5704
 
4807
5705
  // src/ui/home-tab-bar.tsx
4808
- import { jsx as jsx28, jsxs as jsxs22 } from "preact/jsx-runtime";
4809
- var p23 = BRAND.cssPrefix;
5706
+ import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
5707
+ var p27 = BRAND.cssPrefix;
4810
5708
  function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
4811
- return /* @__PURE__ */ jsx28("nav", { class: `${p23}-tabbar`, role: "tablist", "aria-label": strings.panelTitle, children: modules.map((m) => {
5709
+ return /* @__PURE__ */ jsx32("nav", { class: `${p27}-tabbar`, role: "tablist", "aria-label": strings.panelTitle, children: modules.map((m) => {
4812
5710
  const Icon = LAYOUTS[m.layout].Icon;
4813
5711
  const selected = m.id === activeTab;
4814
5712
  const badge = m.layout === "chat" && unreadCount > 0 ? unreadCount > 9 ? "9+" : String(unreadCount) : null;
4815
- return /* @__PURE__ */ jsxs22(
5713
+ return /* @__PURE__ */ jsxs26(
4816
5714
  "button",
4817
5715
  {
4818
5716
  type: "button",
4819
5717
  role: "tab",
4820
5718
  "aria-selected": selected,
4821
- class: `${p23}-tab`,
5719
+ class: `${p27}-tab`,
4822
5720
  onClick: () => onSelect(m.id),
4823
5721
  "data-testid": tid(TID.tab, m.id),
4824
5722
  children: [
4825
- /* @__PURE__ */ jsxs22("span", { class: `${p23}-tab-icon`, "aria-hidden": "true", children: [
4826
- /* @__PURE__ */ jsx28(Icon, {}),
4827
- badge ? /* @__PURE__ */ jsx28("span", { class: `${p23}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
5723
+ /* @__PURE__ */ jsxs26("span", { class: `${p27}-tab-icon`, "aria-hidden": "true", children: [
5724
+ /* @__PURE__ */ jsx32(Icon, {}),
5725
+ badge ? /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
4828
5726
  ] }),
4829
- /* @__PURE__ */ jsx28("span", { class: `${p23}-tab-label`, children: moduleLabel(strings, m.label) })
5727
+ /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-label`, children: moduleLabel(strings, m.label) })
4830
5728
  ]
4831
5729
  },
4832
5730
  m.id
@@ -4835,12 +5733,12 @@ function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
4835
5733
  }
4836
5734
 
4837
5735
  // src/ui/iframe-view.tsx
4838
- import { jsx as jsx29, jsxs as jsxs23 } from "preact/jsx-runtime";
4839
- var p24 = BRAND.cssPrefix;
5736
+ import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
5737
+ var p28 = BRAND.cssPrefix;
4840
5738
  var SANDBOX = "allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads";
4841
5739
  function IframeView({ url, title, strings, onBack, actions }) {
4842
- return /* @__PURE__ */ jsxs23("div", { class: `${p24}-module`, children: [
4843
- /* @__PURE__ */ jsx29(
5740
+ return /* @__PURE__ */ jsxs27("div", { class: `${p28}-module`, children: [
5741
+ /* @__PURE__ */ jsx33(
4844
5742
  BackHeader,
4845
5743
  {
4846
5744
  title: title || strings.moduleBack,
@@ -4849,10 +5747,10 @@ function IframeView({ url, title, strings, onBack, actions }) {
4849
5747
  actions
4850
5748
  }
4851
5749
  ),
4852
- /* @__PURE__ */ jsx29(
5750
+ /* @__PURE__ */ jsx33(
4853
5751
  "iframe",
4854
5752
  {
4855
- class: `${p24}-content-frame`,
5753
+ class: `${p28}-content-frame`,
4856
5754
  src: url,
4857
5755
  title: title || "content",
4858
5756
  sandbox: SANDBOX,
@@ -4865,14 +5763,14 @@ function IframeView({ url, title, strings, onBack, actions }) {
4865
5763
  }
4866
5764
 
4867
5765
  // src/ui/content-view.tsx
4868
- import { useCallback as useCallback3, useEffect as useEffect14, useState as useState10 } from "preact/hooks";
4869
- import { jsx as jsx30, jsxs as jsxs24 } from "preact/jsx-runtime";
4870
- var p25 = BRAND.cssPrefix;
5766
+ import { useCallback as useCallback3, useEffect as useEffect14, useState as useState11 } from "preact/hooks";
5767
+ import { jsx as jsx34, jsxs as jsxs28 } from "preact/jsx-runtime";
5768
+ var p29 = BRAND.cssPrefix;
4871
5769
  var log15 = logger.scope("content");
4872
5770
  function ContentView({ id, title, transport, strings, onBack, actions }) {
4873
- const [item, setItem] = useState10(null);
4874
- const [failed, setFailed] = useState10(false);
4875
- const [reloadKey, setReloadKey] = useState10(0);
5771
+ const [item, setItem] = useState11(null);
5772
+ const [failed, setFailed] = useState11(false);
5773
+ const [reloadKey, setReloadKey] = useState11(0);
4876
5774
  const retry = useCallback3(() => {
4877
5775
  setFailed(false);
4878
5776
  setItem(null);
@@ -4895,17 +5793,17 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
4895
5793
  };
4896
5794
  }, [transport, id, reloadKey]);
4897
5795
  function renderBody() {
4898
- if (failed) return /* @__PURE__ */ jsx30(ModuleState, { tone: "error", message: strings.errorGeneric, onRetry: retry, strings });
4899
- if (item === null) return /* @__PURE__ */ jsx30(ModuleState, { message: strings.contentLoading, strings });
4900
- return /* @__PURE__ */ jsxs24("article", { class: `${p25}-content`, "data-testid": TID.contentView, children: [
4901
- item.image ? /* @__PURE__ */ jsx30("img", { class: `${p25}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
4902
- item.description ? /* @__PURE__ */ jsx30("p", { class: `${p25}-content-subtitle`, children: item.description }) : null,
4903
- item.tags && item.tags.length > 0 ? /* @__PURE__ */ jsx30("span", { class: `${p25}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx30("span", { class: `${p25}-news-tag`, children: t }, t)) }) : null,
4904
- /* @__PURE__ */ jsx30(StaticMarkdown, { text: item.content ?? "" })
5796
+ if (failed) return /* @__PURE__ */ jsx34(ModuleState, { tone: "error", message: strings.errorGeneric, onRetry: retry, strings });
5797
+ if (item === null) return /* @__PURE__ */ jsx34(ModuleState, { message: strings.contentLoading, strings });
5798
+ return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
5799
+ item.image ? /* @__PURE__ */ jsx34("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
5800
+ item.description ? /* @__PURE__ */ jsx34("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
5801
+ item.tags && item.tags.length > 0 ? /* @__PURE__ */ jsx34("span", { class: `${p29}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx34("span", { class: `${p29}-news-tag`, children: t }, t)) }) : null,
5802
+ /* @__PURE__ */ jsx34(StaticMarkdown, { text: item.content ?? "" })
4905
5803
  ] });
4906
5804
  }
4907
- return /* @__PURE__ */ jsxs24("div", { class: `${p25}-module`, children: [
4908
- /* @__PURE__ */ jsx30(
5805
+ return /* @__PURE__ */ jsxs28("div", { class: `${p29}-module`, children: [
5806
+ /* @__PURE__ */ jsx34(
4909
5807
  BackHeader,
4910
5808
  {
4911
5809
  title: item?.title || title || strings.moduleBack,
@@ -4915,13 +5813,13 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
4915
5813
  testid: TID.backHeader
4916
5814
  }
4917
5815
  ),
4918
- /* @__PURE__ */ jsx30("div", { class: `${p25}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
5816
+ /* @__PURE__ */ jsx34("div", { class: `${p29}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
4919
5817
  ] });
4920
5818
  }
4921
5819
 
4922
5820
  // src/ui/messenger-home.tsx
4923
- import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
4924
- var p26 = BRAND.cssPrefix;
5821
+ import { jsx as jsx35, jsxs as jsxs29 } from "preact/jsx-runtime";
5822
+ var p30 = BRAND.cssPrefix;
4925
5823
  function MessengerHome({
4926
5824
  panelProps,
4927
5825
  enabledModules,
@@ -4953,7 +5851,7 @@ function MessengerHome({
4953
5851
  }, []);
4954
5852
  const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
4955
5853
  useDragMove(containerRef.current, options.mode === "modal");
4956
- const navState = useComputed4(() => nav.sig.value).value;
5854
+ const navState = useComputed6(() => nav.sig.value).value;
4957
5855
  const top = topScreen(navState);
4958
5856
  const activeModule = options.modules.byId[navState.activeTab];
4959
5857
  const isReader = top?.kind === "iframe" || top?.kind === "content";
@@ -4989,12 +5887,12 @@ function MessengerHome({
4989
5887
  nav: moduleNav,
4990
5888
  panelProps
4991
5889
  });
4992
- const plainActions = /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" });
5890
+ const plainActions = /* @__PURE__ */ jsx35(HeaderActions, { panelProps, variant: "plain" });
4993
5891
  let body;
4994
5892
  if (top?.kind === "iframe") {
4995
- body = /* @__PURE__ */ jsx31(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
5893
+ body = /* @__PURE__ */ jsx35(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
4996
5894
  } else if (top?.kind === "content") {
4997
- body = /* @__PURE__ */ jsx31(
5895
+ body = /* @__PURE__ */ jsx35(
4998
5896
  ContentView,
4999
5897
  {
5000
5898
  id: top.id,
@@ -5006,7 +5904,7 @@ function MessengerHome({
5006
5904
  }
5007
5905
  );
5008
5906
  } else if (activeModule?.layout === "chat") {
5009
- body = /* @__PURE__ */ jsx31(
5907
+ body = /* @__PURE__ */ jsx35(
5010
5908
  PanelContent,
5011
5909
  {
5012
5910
  ...panelProps,
@@ -5017,23 +5915,23 @@ function MessengerHome({
5017
5915
  );
5018
5916
  } else if (activeModule) {
5019
5917
  const Root = LAYOUTS[activeModule.layout].Root;
5020
- body = Root ? /* @__PURE__ */ jsx31(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
5918
+ body = Root ? /* @__PURE__ */ jsx35(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
5021
5919
  } else {
5022
5920
  body = null;
5023
5921
  }
5024
- return /* @__PURE__ */ jsxs25(
5922
+ return /* @__PURE__ */ jsxs29(
5025
5923
  "div",
5026
5924
  {
5027
5925
  ref: containerRef,
5028
- class: `${p26}-panel ${p26}-messenger`,
5926
+ class: `${p30}-panel ${p30}-messenger`,
5029
5927
  role: "dialog",
5030
5928
  "aria-modal": "false",
5031
5929
  "aria-label": strings.panelTitle,
5032
5930
  style: { position: "relative" },
5033
5931
  "data-testid": TID.messengerHome,
5034
5932
  children: [
5035
- /* @__PURE__ */ jsx31("div", { class: `${p26}-messenger-body`, children: body }),
5036
- showTabBar ? /* @__PURE__ */ jsx31(
5933
+ /* @__PURE__ */ jsx35("div", { class: `${p30}-messenger-body`, children: body }),
5934
+ showTabBar ? /* @__PURE__ */ jsx35(
5037
5935
  HomeTabBar,
5038
5936
  {
5039
5937
  modules: enabledModules,
@@ -5043,8 +5941,8 @@ function MessengerHome({
5043
5941
  onSelect: nav.switchTab
5044
5942
  }
5045
5943
  ) : null,
5046
- /* @__PURE__ */ jsx31(PoweredByBar, { poweredBy: options.poweredBy }),
5047
- options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx31(
5944
+ /* @__PURE__ */ jsx35(PoweredByBar, { poweredBy: options.poweredBy }),
5945
+ options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx35(
5048
5946
  ResizeGrip,
5049
5947
  {
5050
5948
  panelEl: containerRef.current,
@@ -5061,29 +5959,29 @@ function MessengerHome({
5061
5959
  }
5062
5960
 
5063
5961
  // src/ui/modules-empty.tsx
5064
- import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
5065
- var p27 = BRAND.cssPrefix;
5962
+ import { jsx as jsx36, jsxs as jsxs30 } from "preact/jsx-runtime";
5963
+ var p31 = BRAND.cssPrefix;
5066
5964
  function ModulesEmpty({ strings, onClose }) {
5067
- return /* @__PURE__ */ jsxs26(
5965
+ return /* @__PURE__ */ jsxs30(
5068
5966
  "div",
5069
5967
  {
5070
- class: `${p27}-panel ${p27}-modules-empty`,
5968
+ class: `${p31}-panel ${p31}-modules-empty`,
5071
5969
  role: "dialog",
5072
5970
  "aria-label": strings.panelTitle,
5073
5971
  "data-testid": TID.modulesEmpty,
5074
5972
  children: [
5075
- onClose ? /* @__PURE__ */ jsx32(
5973
+ onClose ? /* @__PURE__ */ jsx36(
5076
5974
  "button",
5077
5975
  {
5078
5976
  type: "button",
5079
- class: `${p27}-icon-btn ${p27}-modules-empty-close`,
5977
+ class: `${p31}-icon-btn ${p31}-modules-empty-close`,
5080
5978
  onClick: onClose,
5081
5979
  "aria-label": strings.close,
5082
5980
  title: strings.close,
5083
- children: /* @__PURE__ */ jsx32(CloseIcon, {})
5981
+ children: /* @__PURE__ */ jsx36(CloseIcon, {})
5084
5982
  }
5085
5983
  ) : null,
5086
- /* @__PURE__ */ jsx32("p", { class: `${p27}-modules-empty-text`, children: strings.modulesEmpty })
5984
+ /* @__PURE__ */ jsx36("p", { class: `${p31}-modules-empty-text`, children: strings.modulesEmpty })
5087
5985
  ]
5088
5986
  }
5089
5987
  );
@@ -5138,11 +6036,11 @@ function animateTypewriter(msg, text, charsPerSecond, abort) {
5138
6036
  }
5139
6037
 
5140
6038
  // src/ui/use-launcher-callout.ts
5141
- import { useCallback as useCallback5, useEffect as useEffect16, useState as useState11 } from "preact/hooks";
6039
+ import { useCallback as useCallback5, useEffect as useEffect16, useState as useState12 } from "preact/hooks";
5142
6040
  function useLauncherCallout({ callout, persistence }) {
5143
6041
  const textKey = callout?.text ?? "";
5144
6042
  const persistent = callout?.persistent ?? true;
5145
- const [dismissed, setDismissed] = useState11(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
6043
+ const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
5146
6044
  useEffect16(() => {
5147
6045
  setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
5148
6046
  }, [textKey, persistent, persistence]);
@@ -5154,21 +6052,21 @@ function useLauncherCallout({ callout, persistence }) {
5154
6052
  }
5155
6053
 
5156
6054
  // src/ui/app.tsx
5157
- import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
6055
+ import { jsx as jsx37, jsxs as jsxs31 } from "preact/jsx-runtime";
5158
6056
  var log16 = logger.scope("app");
5159
- var p28 = BRAND.cssPrefix;
6057
+ var p32 = BRAND.cssPrefix;
5160
6058
  function App({ options, hostElement, bus }) {
5161
- const [persistence] = useState12(() => createPersistence(options.widgetId, options.storage));
5162
- const [visitorId, setVisitorId] = useState12(() => persistence.getVisitorId());
6059
+ const [persistence] = useState13(() => createPersistence(options.widgetId, options.storage));
6060
+ const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
5163
6061
  const initialSettings = persistence.loadUserPrefs();
5164
- const [activeLocale, setActiveLocale] = useState12(() => initialSettings.locale ?? options.locale);
5165
- const [activeThemeMode, setActiveThemeMode] = useState12(
6062
+ const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
6063
+ const [activeThemeMode, setActiveThemeMode] = useState13(
5166
6064
  () => initialSettings.themeMode ?? options.themeMode
5167
6065
  );
5168
- const sessionIdSig = useSignal(persistence.loadSessionId());
5169
- const messagesSig = useSignal([]);
5170
- const unreadCountSig = useSignal(0);
5171
- const [loadingMessages, setLoadingMessages] = useState12(false);
6066
+ const sessionIdSig = useSignal2(persistence.loadSessionId());
6067
+ const messagesSig = useSignal2([]);
6068
+ const unreadCountSig = useSignal2(0);
6069
+ const [loadingMessages, setLoadingMessages] = useState13(false);
5172
6070
  function landingTab() {
5173
6071
  const list = options.modules.list;
5174
6072
  const ids = new Set(list.map((m) => m.id));
@@ -5187,14 +6085,14 @@ function App({ options, hostElement, bus }) {
5187
6085
  const homeNav = homeNavRef.current;
5188
6086
  const chatTabIdRef = useRef8(void 0);
5189
6087
  chatTabIdRef.current = chatTabId();
5190
- const [sessionReady, setSessionReady] = useState12(false);
6088
+ const [sessionReady, setSessionReady] = useState13(false);
5191
6089
  const isInlineLike = options.mode === "standalone" || options.mode === "inline";
5192
6090
  const initialPanelRef = useRef8(
5193
6091
  resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
5194
6092
  );
5195
- const [isOpen, setIsOpen] = useState12(initialPanelRef.current.panelOpen);
6093
+ const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
5196
6094
  const initialPanelApplied = useRef8(false);
5197
- const [launcherLeaving, setLauncherLeaving] = useState12(false);
6095
+ const [launcherLeaving, setLauncherLeaving] = useState13(false);
5198
6096
  const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
5199
6097
  callout: options.launcher.callout,
5200
6098
  persistence
@@ -5205,19 +6103,20 @@ function App({ options, hostElement, bus }) {
5205
6103
  bus.emit("calloutDismiss", void 0);
5206
6104
  dismissCalloutRaw();
5207
6105
  }, [bus, dismissCalloutRaw]);
5208
- const [panelSize, setPanelSize] = useState12(initialPanelRef.current.panelSize);
6106
+ const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
5209
6107
  const initialSizeApplied = useRef8(false);
5210
- const [view, setView] = useState12("chat");
5211
- const [canSend, setCanSend] = useState12(true);
5212
- const [streaming, setStreaming] = useState12(false);
5213
- const [agent, setAgent] = useState12(null);
5214
- const [suggestions, setSuggestions] = useState12([]);
5215
- const [activeCancel, setActiveCancel] = useState12(null);
6108
+ const [view, setView] = useState13("chat");
6109
+ const [canSend, setCanSend] = useState13(true);
6110
+ const [streaming, setStreaming] = useState13(false);
6111
+ const [agent, setAgent] = useState13(null);
6112
+ const [suggestions, setSuggestions] = useState13([]);
6113
+ const [activeCancel, setActiveCancel] = useState13(null);
5216
6114
  const welcomeAbortRef = useRef8(null);
5217
- const [parsedSite, setParsedSite] = useState12(void 0);
5218
- const [parsedBlocks, setParsedBlocks] = useState12(void 0);
5219
- const [sidebarCollapsed, setSidebarCollapsed] = useState12(() => persistence.loadSidebarCollapsed() ?? false);
5220
- const [transport] = useState12(
6115
+ const [parsedSite, setParsedSite] = useState13(void 0);
6116
+ const [parsedBlocks, setParsedBlocks] = useState13(void 0);
6117
+ const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
6118
+ const [intakeValues, setIntakeValues] = useState13(() => persistence.loadIntake());
6119
+ const [transport] = useState13(
5221
6120
  () => new AgentTransport({
5222
6121
  baseUrl: options.baseUrl,
5223
6122
  auth: createAuth({
@@ -5228,8 +6127,8 @@ function App({ options, hostElement, bus }) {
5228
6127
  endpoints: options.endpoints
5229
6128
  })
5230
6129
  );
5231
- const [reducer] = useState12(() => new StreamReducer(messagesSig));
5232
- const [feedback] = useState12(() => new FeedbackBus(options.sound, options.haptics));
6130
+ const [reducer] = useState13(() => new StreamReducer(messagesSig));
6131
+ const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
5233
6132
  const patchAndSync = useCallback6(
5234
6133
  (patch) => {
5235
6134
  persistence.patchUserPrefs(patch);
@@ -5399,9 +6298,11 @@ function App({ options, hostElement, bus }) {
5399
6298
  );
5400
6299
  const userSig = JSON.stringify(options.userContext ?? null);
5401
6300
  const pageSig = JSON.stringify(options.pageContext ?? null);
6301
+ const intakeSig = JSON.stringify(intakeValues ?? null);
5402
6302
  useEffect17(() => {
5403
- transport.setContext(options.userContext, toWirePageContext(options.pageContext));
5404
- }, [transport, userSig, pageSig]);
6303
+ const merged = intakeValues ? { ...intakeValues, ...options.userContext } : options.userContext;
6304
+ transport.setContext(merged, toWirePageContext(options.pageContext));
6305
+ }, [transport, userSig, pageSig, intakeSig]);
5405
6306
  const runResume = useCallback6(
5406
6307
  async (handle) => {
5407
6308
  let bubble = null;
@@ -5489,24 +6390,8 @@ function App({ options, hostElement, bus }) {
5489
6390
  document.addEventListener("keydown", onKey);
5490
6391
  return () => document.removeEventListener("keydown", onKey);
5491
6392
  }, [isOpen, options.mode]);
5492
- const handleSend = useCallback6(
5493
- async (text, attachments) => {
5494
- log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
5495
- if (streaming) return;
5496
- bus.emit("send", { text, attachmentCount: attachments.length });
5497
- if (suggestions.length > 0) setSuggestions([]);
5498
- const uploaded = await uploadAttachments(transport, attachments, (err) => {
5499
- log16.warn("upload failed", { err });
5500
- bus.emit("error", err);
5501
- options.onError?.(err);
5502
- });
5503
- feedback.unlock();
5504
- feedback.play("messageSent");
5505
- const userMsg = makeUserMessage(text, uploaded);
5506
- const assistantMsg = makeAssistantMessage();
5507
- messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
5508
- reducer.attach(assistantMsg);
5509
- emitMessage(bus, options, "user", text);
6393
+ const streamAssistant = useCallback6(
6394
+ async (assistantMsg, trigger) => {
5510
6395
  const activeSessionId = sessionIdSig.value ?? uuid7();
5511
6396
  if (!sessionIdSig.value) {
5512
6397
  sessionIdSig.value = activeSessionId;
@@ -5515,10 +6400,10 @@ function App({ options, hostElement, bus }) {
5515
6400
  const body = buildSendMessageRequest({
5516
6401
  messages: messagesSig.value.slice(0, -1).map(fromReactive),
5517
6402
  sessionId: activeSessionId,
5518
- // textModel + imageModel are backend-only — selected per
5519
- // deployment in the dashboard, never passed up by the widget.
6403
+ // textModel + imageModel are backend-only — selected per deployment.
5520
6404
  tools: options.features.tools,
5521
6405
  responseMode: options.responseMode,
6406
+ trigger,
5522
6407
  // Identity + preferences ride on every message — server may need
5523
6408
  // them to route, persist, or reconcile in-flight.
5524
6409
  visitorId,
@@ -5550,19 +6435,95 @@ function App({ options, hostElement, bus }) {
5550
6435
  messagesSig.value = [...messagesSig.value];
5551
6436
  }
5552
6437
  },
5553
- [
5554
- streaming,
5555
- transport,
5556
- reducer,
5557
- messagesSig,
5558
- sessionIdSig,
5559
- options,
5560
- bus,
5561
- suggestions.length,
5562
- feedback,
5563
- persistence,
5564
- visitorId
5565
- ]
6438
+ [transport, reducer, messagesSig, sessionIdSig, options, bus, feedback, persistence, visitorId]
6439
+ );
6440
+ const resolveTool = useCallback6(
6441
+ (toolCallId, trigger, mutate) => {
6442
+ if (streaming) return;
6443
+ const last = messagesSig.value.at(-1);
6444
+ const part = last?.partsSig.value.find(
6445
+ (pt) => pt.kind === "tool" && pt.toolCallId === toolCallId
6446
+ );
6447
+ if (!part) {
6448
+ log16.warn("resolveTool: tool part not found", { toolCallId });
6449
+ return;
6450
+ }
6451
+ mutate(part);
6452
+ if (last) last.partsSig.value = [...last.partsSig.value];
6453
+ const assistantMsg = makeAssistantMessage();
6454
+ messagesSig.value = [...messagesSig.value, assistantMsg];
6455
+ reducer.attach(assistantMsg);
6456
+ void streamAssistant(assistantMsg, trigger);
6457
+ },
6458
+ [streaming, messagesSig, reducer, streamAssistant]
6459
+ );
6460
+ const handleToolResult = useCallback6(
6461
+ (toolCallId, output) => {
6462
+ log16.info("toolResult", { toolCallId });
6463
+ bus.emit("toolResult", { toolCallId });
6464
+ resolveTool(toolCallId, TRIGGER.toolResult, (part) => {
6465
+ part.outputSig.value = output;
6466
+ part.stateSig.value = "output";
6467
+ });
6468
+ },
6469
+ [bus, resolveTool]
6470
+ );
6471
+ const handleToolDecision = useCallback6(
6472
+ (toolCallId, approved, reason) => {
6473
+ log16.info("toolDecision", { toolCallId, approved });
6474
+ bus.emit("toolDecision", { toolCallId, approved });
6475
+ resolveTool(toolCallId, TRIGGER.toolApproval, (part) => {
6476
+ const id = part.approvalSig.value?.id ?? toolCallId;
6477
+ part.approvalSig.value = { id, approved, reason };
6478
+ part.stateSig.value = "output";
6479
+ });
6480
+ },
6481
+ [bus, resolveTool]
6482
+ );
6483
+ const toolInteraction = useMemo3(
6484
+ () => ({ humanInLoop: options.features.humanInLoop, onResult: handleToolResult, onDecision: handleToolDecision }),
6485
+ [options.features.humanInLoop, handleToolResult, handleToolDecision]
6486
+ );
6487
+ const intakePending = options.intake.enabled && intakeValues === null;
6488
+ const handleIntakeComplete = useCallback6(
6489
+ (values) => {
6490
+ const hasValues = Object.keys(values).length > 0;
6491
+ log16.info("intakeComplete", { fields: Object.keys(values).length, skipped: !hasValues });
6492
+ persistence.saveIntake(values);
6493
+ setIntakeValues(values);
6494
+ bus.emit("intakeSubmit", values);
6495
+ if (!hasValues) return;
6496
+ const activeSessionId = sessionIdSig.value ?? uuid7();
6497
+ if (!sessionIdSig.value) {
6498
+ sessionIdSig.value = activeSessionId;
6499
+ persistence.saveSessionId(activeSessionId);
6500
+ transport.primeIdentity(void 0, activeSessionId);
6501
+ }
6502
+ void transport.submitIntake(activeSessionId, values);
6503
+ },
6504
+ [persistence, bus, sessionIdSig, transport]
6505
+ );
6506
+ const handleSend = useCallback6(
6507
+ async (text, attachments) => {
6508
+ log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
6509
+ if (streaming) return;
6510
+ bus.emit("send", { text, attachmentCount: attachments.length });
6511
+ if (suggestions.length > 0) setSuggestions([]);
6512
+ const uploaded = await uploadAttachments(transport, attachments, (err) => {
6513
+ log16.warn("upload failed", { err });
6514
+ bus.emit("error", err);
6515
+ options.onError?.(err);
6516
+ });
6517
+ feedback.unlock();
6518
+ feedback.play("messageSent");
6519
+ const userMsg = makeUserMessage(text, uploaded);
6520
+ const assistantMsg = makeAssistantMessage();
6521
+ messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
6522
+ reducer.attach(assistantMsg);
6523
+ emitMessage(bus, options, "user", text);
6524
+ await streamAssistant(assistantMsg, TRIGGER.submitMessage);
6525
+ },
6526
+ [streaming, transport, bus, options, suggestions.length, messagesSig, reducer, streamAssistant]
5566
6527
  );
5567
6528
  const handleStop = useCallback6(() => {
5568
6529
  log16.info("stop");
@@ -5766,7 +6727,10 @@ function App({ options, hostElement, bus }) {
5766
6727
  log16.info("suggestion", { text });
5767
6728
  bus.emit("suggestion", { text });
5768
6729
  void handleSend(text, []);
5769
- }
6730
+ },
6731
+ intakePending,
6732
+ onIntakeComplete: handleIntakeComplete,
6733
+ tool: toolInteraction
5770
6734
  };
5771
6735
  const onSelectSession = (sessionId) => {
5772
6736
  void handleSelectHistoryChat(sessionId);
@@ -5778,12 +6742,12 @@ function App({ options, hostElement, bus }) {
5778
6742
  const renderSurface = (size) => {
5779
6743
  const closeable = isActionVisible("close", effectiveOptions.mode, size);
5780
6744
  if (enabledModules.length === 0) {
5781
- return /* @__PURE__ */ jsx33(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
6745
+ return /* @__PURE__ */ jsx37(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
5782
6746
  }
5783
6747
  if (enabledModules.length === 1 && enabledModules[0]?.layout === "chat") {
5784
- return /* @__PURE__ */ jsx33(Panel, { ...panelProps, panelSize: size });
6748
+ return /* @__PURE__ */ jsx37(Panel, { ...panelProps, panelSize: size });
5785
6749
  }
5786
- return /* @__PURE__ */ jsx33(
6750
+ return /* @__PURE__ */ jsx37(
5787
6751
  MessengerHome,
5788
6752
  {
5789
6753
  panelProps: { ...panelProps, panelSize: size, onClose: closeable ? handleClose : void 0 },
@@ -5801,7 +6765,7 @@ function App({ options, hostElement, bus }) {
5801
6765
  void handleSelectHistoryChat(chat.sessionId);
5802
6766
  };
5803
6767
  const messagesEnabled = enabledModules.some((m) => m.layout === "chat");
5804
- return /* @__PURE__ */ jsx33("div", { class: `${p28}-anchor`, children: /* @__PURE__ */ jsx33(
6768
+ return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: /* @__PURE__ */ jsx37(
5805
6769
  PageShell,
5806
6770
  {
5807
6771
  site: parsedSite,
@@ -5820,15 +6784,15 @@ function App({ options, hostElement, bus }) {
5820
6784
  }
5821
6785
  if (isInlineLike) {
5822
6786
  const inlineSize = options.mode === "standalone" ? "fullscreen" : panelSize;
5823
- return /* @__PURE__ */ jsx33("div", { class: `${p28}-anchor`, children: renderSurface(inlineSize) });
6787
+ return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: renderSurface(inlineSize) });
5824
6788
  }
5825
6789
  const drawerEdgeTab = options.mode === "drawer";
5826
6790
  const triggerOwnedByPage = options.mode === "modal";
5827
6791
  const launcherVisible = !triggerOwnedByPage && !options.launcher.hidden && (!isOpen || launcherLeaving);
5828
6792
  const calloutToRender = launcherVisible && !launcherLeaving && !calloutDismissed && !drawerEdgeTab ? effectiveOptions.launcher.callout : null;
5829
- return /* @__PURE__ */ jsxs27("div", { class: `${p28}-anchor`, "data-launcher-size": effectiveOptions.launcher.size, children: [
6793
+ return /* @__PURE__ */ jsxs31("div", { class: `${p32}-anchor`, "data-launcher-size": effectiveOptions.launcher.size, children: [
5830
6794
  isOpen ? renderSurface(panelSize) : null,
5831
- launcherVisible ? /* @__PURE__ */ jsx33(
6795
+ launcherVisible ? /* @__PURE__ */ jsx37(
5832
6796
  Launcher,
5833
6797
  {
5834
6798
  onToggle: handleOpen,
@@ -5838,7 +6802,7 @@ function App({ options, hostElement, bus }) {
5838
6802
  edgeTab: drawerEdgeTab
5839
6803
  }
5840
6804
  ) : null,
5841
- calloutToRender ? /* @__PURE__ */ jsx33(
6805
+ calloutToRender ? /* @__PURE__ */ jsx37(
5842
6806
  LauncherCallout,
5843
6807
  {
5844
6808
  callout: calloutToRender,