@helpai/elements 0.12.3 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,60 @@ 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
+ return toolName === ASK_USER_INPUT_TOOL;
1973
+ }
1974
+ var TRIGGER = {
1975
+ submitMessage: "submit-message",
1976
+ toolResult: "tool-result",
1977
+ toolApproval: "tool-approval"
1978
+ };
1979
+
1980
+ // src/stream/reducer.ts
1752
1981
  var log5 = logger.scope("reducer");
1753
1982
  var StreamReducer = class {
1754
1983
  constructor(messagesSig) {
@@ -1786,8 +2015,8 @@ var StreamReducer = class {
1786
2015
  ensureTextPart(m, "text", chunk.id);
1787
2016
  return;
1788
2017
  case "text-delta": {
1789
- const p29 = ensureTextPart(m, "text", chunk.id);
1790
- p29.textSig.value += chunk.delta;
2018
+ const p33 = ensureTextPart(m, "text", chunk.id);
2019
+ p33.textSig.value += chunk.delta;
1791
2020
  return;
1792
2021
  }
1793
2022
  case "text-end":
@@ -1797,8 +2026,8 @@ var StreamReducer = class {
1797
2026
  ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
1798
2027
  return;
1799
2028
  case "reasoning-delta": {
1800
- const p29 = ensureTextPart(m, "reasoning", chunk.id);
1801
- p29.textSig.value += chunk.delta;
2029
+ const p33 = ensureTextPart(m, "reasoning", chunk.id);
2030
+ p33.textSig.value += chunk.delta;
1802
2031
  return;
1803
2032
  }
1804
2033
  case "reasoning-end":
@@ -1809,6 +2038,7 @@ var StreamReducer = class {
1809
2038
  case "tool-input-available":
1810
2039
  case "tool-output-available":
1811
2040
  case "tool-output-error":
2041
+ case "tool-approval-request":
1812
2042
  applyTool(m, chunk);
1813
2043
  return;
1814
2044
  case "file":
@@ -1816,7 +2046,7 @@ var StreamReducer = class {
1816
2046
  return;
1817
2047
  case "source-url": {
1818
2048
  const parts = m.partsSig.value;
1819
- if (parts.some((p29) => p29.kind === "source" && p29.sourceId === chunk.sourceId)) return;
2049
+ if (parts.some((p33) => p33.kind === "source" && p33.sourceId === chunk.sourceId)) return;
1820
2050
  appendPart(m, { kind: "source", sourceId: chunk.sourceId, url: chunk.url, title: chunk.title });
1821
2051
  return;
1822
2052
  }
@@ -1840,14 +2070,14 @@ var StreamReducer = class {
1840
2070
  }
1841
2071
  };
1842
2072
  function ensureTextPart(m, kind, id) {
1843
- const existing = m.partsSig.value.find((p29) => p29.kind === kind && p29.id === id);
2073
+ const existing = m.partsSig.value.find((p33) => p33.kind === kind && p33.id === id);
1844
2074
  if (existing) return existing;
1845
2075
  const part = { kind, id, textSig: signal2(""), doneSig: signal2(false) };
1846
2076
  appendPart(m, part);
1847
2077
  return part;
1848
2078
  }
1849
2079
  function ensureToolPart(m, toolCallId, toolName) {
1850
- const existing = m.partsSig.value.find((p29) => p29.kind === "tool" && p29.toolCallId === toolCallId);
2080
+ const existing = m.partsSig.value.find((p33) => p33.kind === "tool" && p33.toolCallId === toolCallId);
1851
2081
  if (existing) return existing;
1852
2082
  const part = {
1853
2083
  kind: "tool",
@@ -1857,7 +2087,8 @@ function ensureToolPart(m, toolCallId, toolName) {
1857
2087
  inputSig: signal2(void 0),
1858
2088
  outputSig: signal2(void 0),
1859
2089
  errorSig: signal2(void 0),
1860
- stateSig: signal2("input")
2090
+ stateSig: signal2("input"),
2091
+ approvalSig: signal2(void 0)
1861
2092
  };
1862
2093
  appendPart(m, part);
1863
2094
  return part;
@@ -1871,26 +2102,32 @@ function applyTool(m, chunk) {
1871
2102
  ensureToolPart(m, chunk.toolCallId, chunk.toolName);
1872
2103
  return;
1873
2104
  case "tool-input-delta": {
1874
- const p29 = ensureToolPart(m, chunk.toolCallId);
1875
- p29.inputPartialSig.value += chunk.delta;
2105
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2106
+ p33.inputPartialSig.value += chunk.delta;
1876
2107
  return;
1877
2108
  }
1878
2109
  case "tool-input-available": {
1879
- const p29 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
1880
- p29.inputSig.value = chunk.input;
1881
- p29.stateSig.value = "awaiting";
2110
+ const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
2111
+ p33.inputSig.value = chunk.input;
2112
+ p33.stateSig.value = isAskUserInputTool(p33.toolName) ? "awaiting-input" : "awaiting";
2113
+ return;
2114
+ }
2115
+ case "tool-approval-request": {
2116
+ const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
2117
+ p33.approvalSig.value = { id: chunk.approvalId };
2118
+ p33.stateSig.value = "awaiting-approval";
1882
2119
  return;
1883
2120
  }
1884
2121
  case "tool-output-available": {
1885
- const p29 = ensureToolPart(m, chunk.toolCallId);
1886
- p29.outputSig.value = chunk.output;
1887
- p29.stateSig.value = "output";
2122
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2123
+ p33.outputSig.value = chunk.output;
2124
+ p33.stateSig.value = "output";
1888
2125
  return;
1889
2126
  }
1890
2127
  case "tool-output-error": {
1891
- const p29 = ensureToolPart(m, chunk.toolCallId);
1892
- p29.errorSig.value = chunk.errorText;
1893
- p29.stateSig.value = "error";
2128
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2129
+ p33.errorSig.value = chunk.errorText;
2130
+ p33.stateSig.value = "error";
1894
2131
  return;
1895
2132
  }
1896
2133
  default:
@@ -1910,6 +2147,7 @@ function createPersistence(widgetId, storage = defaultStorage) {
1910
2147
  const KEY_CALLOUT_DISMISSED = `${prefix}.calloutDismissed`;
1911
2148
  const KEY_SIDEBAR_COLLAPSED = `${prefix}.sidebarCollapsed`;
1912
2149
  const KEY_ACTIVE_MODULE = `${prefix}.activeModule`;
2150
+ const KEY_INTAKE = `${prefix}.intake`;
1913
2151
  const persistence = {
1914
2152
  getVisitorId() {
1915
2153
  const existing = storage.get(KEY_VISITOR);
@@ -1992,6 +2230,24 @@ function createPersistence(widgetId, storage = defaultStorage) {
1992
2230
  saveActiveModule(id) {
1993
2231
  storage.set(KEY_ACTIVE_MODULE, id);
1994
2232
  },
2233
+ loadIntake() {
2234
+ const raw = storage.get(KEY_INTAKE);
2235
+ if (!raw) return null;
2236
+ try {
2237
+ const parsed = JSON.parse(raw);
2238
+ return isPlainObject2(parsed) ? parsed : null;
2239
+ } catch (error) {
2240
+ log6.warn("loadIntake parse failed", { error });
2241
+ return null;
2242
+ }
2243
+ },
2244
+ saveIntake(values) {
2245
+ try {
2246
+ storage.set(KEY_INTAKE, JSON.stringify(values));
2247
+ } catch (error) {
2248
+ log6.warn("saveIntake serialise failed", { error });
2249
+ }
2250
+ },
1995
2251
  clearSession() {
1996
2252
  storage.remove(KEY_CHAT);
1997
2253
  }
@@ -2533,7 +2789,30 @@ var TID = {
2533
2789
  /** Help article row — suffix `-{id}`. */
2534
2790
  helpArticle: `${p2}-help-article`,
2535
2791
  /** News list item — suffix `-{id}`. */
2536
- newsItem: `${p2}-news-item`
2792
+ newsItem: `${p2}-news-item`,
2793
+ // ── Forms + human-in-the-loop (intake / ask-input / approval) ────
2794
+ /** Pre-chat intake form root (blocking gate). */
2795
+ intakeForm: `${p2}-intake-form`,
2796
+ /** Intake submit button. */
2797
+ intakeSubmit: `${p2}-intake-submit`,
2798
+ /** Intake skip button (only when `skippable`). */
2799
+ intakeSkip: `${p2}-intake-skip`,
2800
+ /** A single form field control — suffix `-{name}` at the JSX site. */
2801
+ formField: `${p2}-form-field`,
2802
+ /** Ask-input tool root (inline form in a message bubble). */
2803
+ toolAskInput: `${p2}-tool-ask-input`,
2804
+ /** Ask-input submit button. */
2805
+ toolInputSubmit: `${p2}-tool-input-submit`,
2806
+ /** Ask-input skip button. */
2807
+ toolInputSkip: `${p2}-tool-input-skip`,
2808
+ /** Tool-approval root (approve/reject prompt). */
2809
+ toolApproval: `${p2}-tool-approval`,
2810
+ /** Tool-approval approve button. */
2811
+ toolApprove: `${p2}-tool-approve`,
2812
+ /** Tool-approval reject button. */
2813
+ toolReject: `${p2}-tool-reject`,
2814
+ /** Recorded tool decision summary (after approve/reject/submit). */
2815
+ toolDecision: `${p2}-tool-decision`
2537
2816
  };
2538
2817
  function tid(base, suffix) {
2539
2818
  return `${base}-${suffix}`;
@@ -2644,24 +2923,24 @@ import { useCallback as useCallback2, useEffect as useEffect10, useRef as useRef
2644
2923
  import { useEffect as useEffect2, useRef } from "preact/hooks";
2645
2924
  import { jsx as jsx3 } from "preact/jsx-runtime";
2646
2925
  function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, strings }) {
2647
- const p29 = BRAND.cssPrefix;
2926
+ const p33 = BRAND.cssPrefix;
2648
2927
  const dragRef = useRef(null);
2649
2928
  useEffect2(() => {
2650
2929
  if (!panelEl) return;
2651
2930
  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);
2931
+ if (resize.minWidth) style.setProperty(`--${p33}-resize-min-w`, resize.minWidth);
2932
+ if (resize.maxWidth) style.setProperty(`--${p33}-resize-max-w`, resize.maxWidth);
2933
+ if (resize.minHeight) style.setProperty(`--${p33}-resize-min-h`, resize.minHeight);
2934
+ if (resize.maxHeight) style.setProperty(`--${p33}-resize-max-h`, resize.maxHeight);
2656
2935
  if (initialSize) {
2657
- style.setProperty(`--${p29}-widget-w`, `${initialSize.width}px`);
2658
- style.setProperty(`--${p29}-widget-h`, `${initialSize.height}px`);
2936
+ style.setProperty(`--${p33}-widget-w`, `${initialSize.width}px`);
2937
+ style.setProperty(`--${p33}-widget-h`, `${initialSize.height}px`);
2659
2938
  }
2660
- }, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p29, initialSize]);
2939
+ }, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p33, initialSize]);
2661
2940
  if (!panelEl) return null;
2662
2941
  const isTop = position.startsWith("top-");
2663
2942
  const isRight = position.endsWith("-right");
2664
- const cornerClass = `${p29}-resize-grip ${p29}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
2943
+ const cornerClass = `${p33}-resize-grip ${p33}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
2665
2944
  const onPointerDown = (e) => {
2666
2945
  if (!panelEl) return;
2667
2946
  const target = e.currentTarget;
@@ -2685,8 +2964,8 @@ function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, stri
2685
2964
  if (!d || e.pointerId !== d.pointerId || !panelEl) return;
2686
2965
  const dx = (e.clientX - d.startX) * d.dirX;
2687
2966
  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`);
2967
+ panelEl.style.setProperty(`--${p33}-widget-w`, `${d.startW + dx}px`);
2968
+ panelEl.style.setProperty(`--${p33}-widget-h`, `${d.startH + dy}px`);
2690
2969
  };
2691
2970
  const onPointerUp = (e) => {
2692
2971
  const d = dragRef.current;
@@ -2723,7 +3002,7 @@ var KEEP_VISIBLE = 56;
2723
3002
  function useDragMove(panelEl, enabled) {
2724
3003
  useEffect3(() => {
2725
3004
  if (!enabled || !panelEl) return;
2726
- const num = (v) => Number.parseFloat(v) || 0;
3005
+ const num2 = (v) => Number.parseFloat(v) || 0;
2727
3006
  const clamp = (v, max) => Math.min(max, Math.max(-max, v));
2728
3007
  let drag = null;
2729
3008
  const onDown = (e) => {
@@ -2734,8 +3013,8 @@ function useDragMove(panelEl, enabled) {
2734
3013
  id: e.pointerId,
2735
3014
  x: e.clientX,
2736
3015
  y: e.clientY,
2737
- dx: num(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
2738
- dy: num(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
3016
+ dx: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
3017
+ dy: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
2739
3018
  // Centred origin: |offset| ≤ (viewport + panel)/2 − keepVisible keeps a
2740
3019
  // strip of the dialog reachable so it can never be lost off-screen.
2741
3020
  maxX: (window.innerWidth + rect.width) / 2 - KEEP_VISIBLE,
@@ -3421,20 +3700,20 @@ function usePopoverMenu({ itemCount, initialFocusIndex }) {
3421
3700
  // src/ui/overflow-menu.tsx
3422
3701
  import { jsx as jsx8, jsxs as jsxs6 } from "preact/jsx-runtime";
3423
3702
  function OverflowMenu({ items, triggerLabel }) {
3424
- const p29 = BRAND.cssPrefix;
3703
+ const p33 = BRAND.cssPrefix;
3425
3704
  const menu = usePopoverMenu({ itemCount: items.length });
3426
3705
  const handleSelect = (item) => {
3427
3706
  if (item.disabled) return;
3428
3707
  item.onSelect();
3429
3708
  if (!item.keepOpen) menu.close();
3430
3709
  };
3431
- return /* @__PURE__ */ jsxs6("div", { class: `${p29}-menu-wrap`, children: [
3710
+ return /* @__PURE__ */ jsxs6("div", { class: `${p33}-menu-wrap`, children: [
3432
3711
  /* @__PURE__ */ jsx8(
3433
3712
  "button",
3434
3713
  {
3435
3714
  ref: menu.triggerRef,
3436
3715
  type: "button",
3437
- class: `${p29}-icon-btn`,
3716
+ class: `${p33}-icon-btn`,
3438
3717
  "aria-label": triggerLabel,
3439
3718
  "aria-haspopup": "menu",
3440
3719
  "aria-expanded": menu.open,
@@ -3448,7 +3727,7 @@ function OverflowMenu({ items, triggerLabel }) {
3448
3727
  "div",
3449
3728
  {
3450
3729
  ref: menu.menuRef,
3451
- class: `${p29}-menu`,
3730
+ class: `${p33}-menu`,
3452
3731
  role: "menu",
3453
3732
  "aria-label": triggerLabel,
3454
3733
  onKeyDown: menu.onMenuKey,
@@ -3458,15 +3737,15 @@ function OverflowMenu({ items, triggerLabel }) {
3458
3737
  {
3459
3738
  type: "button",
3460
3739
  role: "menuitem",
3461
- class: `${p29}-menu-item`,
3740
+ class: `${p33}-menu-item`,
3462
3741
  "aria-pressed": item.type === "switch" ? item.on : void 0,
3463
3742
  disabled: item.disabled,
3464
3743
  lang: item.lang,
3465
3744
  onClick: () => handleSelect(item),
3466
3745
  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
3746
+ item.icon ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-icon`, children: item.icon }) : null,
3747
+ /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-label`, children: item.label }),
3748
+ item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-check`, "aria-hidden": "true", children: /* @__PURE__ */ jsx8(CheckIcon, {}) }) : null
3470
3749
  ]
3471
3750
  },
3472
3751
  item.id
@@ -3588,18 +3867,360 @@ function HeaderActions({ panelProps, variant }) {
3588
3867
  ] });
3589
3868
  }
3590
3869
 
3870
+ // src/ui/form/dynamic-form.tsx
3871
+ import { useState as useState5 } from "preact/hooks";
3872
+
3873
+ // src/ui/form/validate.ts
3874
+ var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
3875
+ var URL_RE = /^https?:\/\/[^\s.]+\.[^\s]+$/i;
3876
+ var TEL_RE = /^[+]?[\d\s().-]{6,}$/;
3877
+ function fmt(template, vars) {
3878
+ return template.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? `{${k}}`));
3879
+ }
3880
+ function selectionCount(value) {
3881
+ if (Array.isArray(value)) return value.length;
3882
+ return value && value.trim() ? 1 : 0;
3883
+ }
3884
+ function validateField(field, value, strings) {
3885
+ const required = field.required ?? true;
3886
+ const v = field.validation;
3887
+ if (field.type === "multiselect") {
3888
+ const count = selectionCount(value);
3889
+ if (required && count === 0) return strings.formRequired;
3890
+ if (count === 0) return void 0;
3891
+ if (v?.minSelections != null && count < v.minSelections) {
3892
+ return fmt(strings.formChooseAtLeast, { min: v.minSelections });
3893
+ }
3894
+ if (v?.maxSelections != null && count > v.maxSelections) {
3895
+ return fmt(strings.formChooseAtMost, { max: v.maxSelections });
3896
+ }
3897
+ return void 0;
3898
+ }
3899
+ const text = typeof value === "string" ? value.trim() : "";
3900
+ if (!text) return required ? strings.formRequired : void 0;
3901
+ switch (field.type) {
3902
+ case "email":
3903
+ if (!EMAIL_RE2.test(text)) return strings.formInvalidEmail;
3904
+ break;
3905
+ case "url":
3906
+ if (!URL_RE.test(text)) return strings.formInvalidUrl;
3907
+ break;
3908
+ case "tel":
3909
+ if (!TEL_RE.test(text)) return strings.formInvalidTel;
3910
+ break;
3911
+ case "number": {
3912
+ const n = Number(text);
3913
+ if (!Number.isFinite(n)) return strings.formInvalidNumber;
3914
+ if (v?.min != null && n < v.min) return fmt(strings.formNumberTooSmall, { min: v.min });
3915
+ if (v?.max != null && n > v.max) return fmt(strings.formNumberTooLarge, { max: v.max });
3916
+ break;
3917
+ }
3918
+ default:
3919
+ break;
3920
+ }
3921
+ if (v?.minLength != null && text.length < v.minLength) return fmt(strings.formTooShort, { min: v.minLength });
3922
+ if (v?.maxLength != null && text.length > v.maxLength) return fmt(strings.formTooLong, { max: v.maxLength });
3923
+ if (v?.pattern) {
3924
+ try {
3925
+ if (!new RegExp(v.pattern).test(text)) return strings.formPatternMismatch;
3926
+ } catch {
3927
+ }
3928
+ }
3929
+ return void 0;
3930
+ }
3931
+ function validateForm(fields, values, strings) {
3932
+ const errors = {};
3933
+ for (const field of fields) {
3934
+ const err = validateField(field, values[field.name], strings);
3935
+ if (err) errors[field.name] = err;
3936
+ }
3937
+ return errors;
3938
+ }
3939
+ function flattenValues(values) {
3940
+ const out = {};
3941
+ for (const [k, v] of Object.entries(values)) {
3942
+ const flat = Array.isArray(v) ? v.join(", ") : v;
3943
+ if (flat && flat.trim()) out[k] = flat.trim();
3944
+ }
3945
+ return out;
3946
+ }
3947
+
3948
+ // src/ui/form/dynamic-form.tsx
3949
+ import { jsx as jsx10, jsxs as jsxs8 } from "preact/jsx-runtime";
3950
+ var p10 = BRAND.cssPrefix;
3951
+ var OTHER = "__other__";
3952
+ function DynamicForm({
3953
+ fields,
3954
+ strings,
3955
+ submitLabel,
3956
+ onSubmit,
3957
+ skipLabel,
3958
+ onSkip,
3959
+ disabled,
3960
+ rootTestId,
3961
+ submitTestId,
3962
+ skipTestId
3963
+ }) {
3964
+ const [values, setValues] = useState5(() => seedValues(fields));
3965
+ const [other, setOther] = useState5({});
3966
+ const [errors, setErrors] = useState5({});
3967
+ const clearError = (name) => {
3968
+ if (errors[name]) setErrors((prev) => ({ ...prev, [name]: "" }));
3969
+ };
3970
+ const setValue = (name, v) => {
3971
+ setValues((prev) => ({ ...prev, [name]: v }));
3972
+ clearError(name);
3973
+ };
3974
+ const setOtherText = (name, t) => {
3975
+ setOther((prev) => ({ ...prev, [name]: t }));
3976
+ clearError(name);
3977
+ };
3978
+ const submit = (e) => {
3979
+ e.preventDefault();
3980
+ if (disabled) return;
3981
+ const resolved = resolveValues(fields, values, other);
3982
+ const errs = validateForm(fields, resolved, strings);
3983
+ if (Object.keys(errs).length > 0) {
3984
+ setErrors(errs);
3985
+ return;
3986
+ }
3987
+ onSubmit(flattenValues(resolved));
3988
+ };
3989
+ return /* @__PURE__ */ jsxs8("form", { class: `${p10}-form`, onSubmit: submit, "data-testid": rootTestId, noValidate: true, children: [
3990
+ fields.map((field) => /* @__PURE__ */ jsx10(
3991
+ Field,
3992
+ {
3993
+ field,
3994
+ value: values[field.name],
3995
+ otherText: other[field.name] ?? "",
3996
+ error: errors[field.name],
3997
+ disabled,
3998
+ strings,
3999
+ onChange: (v) => setValue(field.name, v),
4000
+ onOtherChange: (t) => setOtherText(field.name, t)
4001
+ },
4002
+ field.name
4003
+ )),
4004
+ /* @__PURE__ */ jsxs8("div", { class: `${p10}-form-actions`, children: [
4005
+ skipLabel && onSkip ? /* @__PURE__ */ jsx10("button", { type: "button", class: `${p10}-form-skip`, onClick: onSkip, disabled, "data-testid": skipTestId, children: skipLabel }) : null,
4006
+ /* @__PURE__ */ jsx10("button", { type: "submit", class: `${p10}-form-submit`, disabled, "data-testid": submitTestId, children: submitLabel })
4007
+ ] })
4008
+ ] });
4009
+ }
4010
+ function Field({
4011
+ field,
4012
+ value,
4013
+ otherText,
4014
+ error,
4015
+ disabled,
4016
+ strings,
4017
+ onChange,
4018
+ onOtherChange
4019
+ }) {
4020
+ const fieldTid = tid(TID.formField, field.name);
4021
+ const control = renderControl({ field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid });
4022
+ return /* @__PURE__ */ jsxs8("label", { class: `${p10}-field`, "data-field": field.name, "data-invalid": error ? "true" : void 0, children: [
4023
+ /* @__PURE__ */ jsxs8("span", { class: `${p10}-field-label`, children: [
4024
+ field.label,
4025
+ field.required ?? true ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-req`, "aria-hidden": "true", children: " *" }) : null
4026
+ ] }),
4027
+ control,
4028
+ field.validationHint && !error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-hint`, children: field.validationHint }) : null,
4029
+ error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-error`, role: "alert", children: error }) : null
4030
+ ] });
4031
+ }
4032
+ function renderControl(args) {
4033
+ const { field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid } = args;
4034
+ const str2 = typeof value === "string" ? value : "";
4035
+ switch (field.type) {
4036
+ case "textarea":
4037
+ return /* @__PURE__ */ jsx10(
4038
+ "textarea",
4039
+ {
4040
+ class: `${p10}-field-input`,
4041
+ rows: 3,
4042
+ value: str2,
4043
+ placeholder: field.placeholder,
4044
+ disabled,
4045
+ onInput: (e) => onChange(e.target.value),
4046
+ "data-testid": fieldTid
4047
+ }
4048
+ );
4049
+ case "select":
4050
+ return /* @__PURE__ */ jsxs8(
4051
+ "select",
4052
+ {
4053
+ class: `${p10}-field-input`,
4054
+ value: str2,
4055
+ disabled,
4056
+ onChange: (e) => onChange(e.target.value),
4057
+ "data-testid": fieldTid,
4058
+ children: [
4059
+ /* @__PURE__ */ jsx10("option", { value: "", children: field.placeholder ?? "\u2014" }),
4060
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsx10("option", { value: o.value, children: o.label ?? o.value }, o.value))
4061
+ ]
4062
+ }
4063
+ );
4064
+ case "radio": {
4065
+ const isOther = field.allowOther && str2 === OTHER;
4066
+ return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, role: "radiogroup", "data-testid": fieldTid, children: [
4067
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4068
+ /* @__PURE__ */ jsx10(
4069
+ "input",
4070
+ {
4071
+ type: "radio",
4072
+ name: `${p10}-${field.name}`,
4073
+ checked: str2 === o.value,
4074
+ disabled,
4075
+ onChange: () => onChange(o.value)
4076
+ }
4077
+ ),
4078
+ /* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
4079
+ ] }, o.value)),
4080
+ field.allowOther ? /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4081
+ /* @__PURE__ */ jsx10(
4082
+ "input",
4083
+ {
4084
+ type: "radio",
4085
+ name: `${p10}-${field.name}`,
4086
+ checked: str2 === OTHER,
4087
+ disabled,
4088
+ onChange: () => onChange(OTHER)
4089
+ }
4090
+ ),
4091
+ /* @__PURE__ */ jsx10("span", { children: strings.formOther })
4092
+ ] }) : null,
4093
+ isOther ? /* @__PURE__ */ jsx10(
4094
+ "input",
4095
+ {
4096
+ class: `${p10}-field-input`,
4097
+ value: otherText,
4098
+ placeholder: field.placeholder ?? strings.formOtherPlaceholder,
4099
+ disabled,
4100
+ onInput: (e) => onOtherChange(e.target.value)
4101
+ }
4102
+ ) : null
4103
+ ] });
4104
+ }
4105
+ case "checkbox":
4106
+ return /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4107
+ /* @__PURE__ */ jsx10(
4108
+ "input",
4109
+ {
4110
+ type: "checkbox",
4111
+ checked: str2 === "true",
4112
+ disabled,
4113
+ onChange: (e) => onChange(e.target.checked ? "true" : ""),
4114
+ "data-testid": fieldTid
4115
+ }
4116
+ ),
4117
+ /* @__PURE__ */ jsx10("span", { children: field.placeholder ?? field.label })
4118
+ ] });
4119
+ case "multiselect": {
4120
+ const selected = Array.isArray(value) ? value : [];
4121
+ const toggle = (v, on) => onChange(on ? [...selected, v] : selected.filter((x) => x !== v));
4122
+ return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, "data-testid": fieldTid, children: [
4123
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4124
+ /* @__PURE__ */ jsx10(
4125
+ "input",
4126
+ {
4127
+ type: "checkbox",
4128
+ checked: selected.includes(o.value),
4129
+ disabled,
4130
+ onChange: (e) => toggle(o.value, e.target.checked)
4131
+ }
4132
+ ),
4133
+ /* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
4134
+ ] }, o.value)),
4135
+ field.allowOther || (field.options ?? []).length === 0 ? /* @__PURE__ */ jsx10(
4136
+ "textarea",
4137
+ {
4138
+ class: `${p10}-field-input`,
4139
+ rows: 2,
4140
+ value: otherText,
4141
+ placeholder: field.placeholder ?? strings.formOtherPlaceholder,
4142
+ disabled,
4143
+ onInput: (e) => onOtherChange(e.target.value)
4144
+ }
4145
+ ) : null
4146
+ ] });
4147
+ }
4148
+ default:
4149
+ return /* @__PURE__ */ jsx10(
4150
+ "input",
4151
+ {
4152
+ class: `${p10}-field-input`,
4153
+ type: inputType(field.type),
4154
+ value: str2,
4155
+ placeholder: field.placeholder,
4156
+ disabled,
4157
+ onInput: (e) => onChange(e.target.value),
4158
+ "data-testid": fieldTid
4159
+ }
4160
+ );
4161
+ }
4162
+ }
4163
+ function inputType(type) {
4164
+ return type === "number" || type === "email" || type === "tel" || type === "url" ? type : "text";
4165
+ }
4166
+ function seedValues(fields) {
4167
+ const out = {};
4168
+ for (const f of fields) {
4169
+ if (f.defaultValue == null) continue;
4170
+ out[f.name] = f.type === "multiselect" ? f.defaultValue.split(",").map((s) => s.trim()).filter(Boolean) : f.defaultValue;
4171
+ }
4172
+ return out;
4173
+ }
4174
+ function resolveValues(fields, values, other) {
4175
+ const out = { ...values };
4176
+ for (const f of fields) {
4177
+ const otherText = other[f.name]?.trim();
4178
+ if (f.type === "radio" && f.allowOther && values[f.name] === OTHER) {
4179
+ out[f.name] = otherText ?? "";
4180
+ } else if (f.type === "multiselect" && otherText) {
4181
+ const tokens = otherText.split(/[,\n;]+/).map((t) => t.trim()).filter(Boolean);
4182
+ const base = Array.isArray(values[f.name]) ? values[f.name] : [];
4183
+ out[f.name] = [...base, ...tokens];
4184
+ }
4185
+ }
4186
+ return out;
4187
+ }
4188
+
4189
+ // src/ui/intake-gate.tsx
4190
+ import { jsx as jsx11, jsxs as jsxs9 } from "preact/jsx-runtime";
4191
+ var p11 = BRAND.cssPrefix;
4192
+ function IntakeGate({ intake, strings, onComplete }) {
4193
+ return /* @__PURE__ */ jsxs9("div", { class: `${p11}-intake`, "data-testid": TID.intakeForm, children: [
4194
+ intake.title ? /* @__PURE__ */ jsx11("h3", { class: `${p11}-intake-title`, children: intake.title }) : null,
4195
+ intake.description ? /* @__PURE__ */ jsx11("p", { class: `${p11}-intake-desc`, children: intake.description }) : null,
4196
+ /* @__PURE__ */ jsx11(
4197
+ DynamicForm,
4198
+ {
4199
+ fields: intake.fields,
4200
+ strings,
4201
+ submitLabel: intake.submitLabel ?? strings.intakeSubmit,
4202
+ onSubmit: onComplete,
4203
+ skipLabel: intake.skippable ? strings.intakeSkip : void 0,
4204
+ onSkip: intake.skippable ? () => onComplete({}) : void 0,
4205
+ submitTestId: TID.intakeSubmit,
4206
+ skipTestId: TID.intakeSkip
4207
+ }
4208
+ )
4209
+ ] });
4210
+ }
4211
+
3591
4212
  // 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";
4213
+ import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as useState6 } from "preact/hooks";
4214
+ import { useComputed as useComputed5 } from "@preact/signals";
3594
4215
 
3595
4216
  // src/ui/message-bubble.tsx
3596
- import { useComputed as useComputed2 } from "@preact/signals";
4217
+ import { useComputed as useComputed4 } from "@preact/signals";
3597
4218
 
3598
4219
  // src/ui/markdown.tsx
3599
4220
  import { useEffect as useEffect7, useMemo, useRef as useRef4 } from "preact/hooks";
3600
4221
  import { effect, signal as signal4 } from "@preact/signals";
3601
4222
  import * as smd from "streaming-markdown";
3602
- import { jsx as jsx10 } from "preact/jsx-runtime";
4223
+ import { jsx as jsx12 } from "preact/jsx-runtime";
3603
4224
  function MarkdownView({ textSig, doneSig }) {
3604
4225
  const ref = useRef4(null);
3605
4226
  useEffect7(() => {
@@ -3649,12 +4270,12 @@ function MarkdownView({ textSig, doneSig }) {
3649
4270
  el.removeEventListener("click", onClick);
3650
4271
  };
3651
4272
  }, [textSig, doneSig]);
3652
- return /* @__PURE__ */ jsx10("div", { ref });
4273
+ return /* @__PURE__ */ jsx12("div", { ref });
3653
4274
  }
3654
4275
  function StaticMarkdown({ text }) {
3655
4276
  const textSig = useMemo(() => signal4(text), [text]);
3656
4277
  const doneSig = useMemo(() => signal4(true), []);
3657
- return /* @__PURE__ */ jsx10(MarkdownView, { textSig, doneSig });
4278
+ return /* @__PURE__ */ jsx12(MarkdownView, { textSig, doneSig });
3658
4279
  }
3659
4280
  function hardenLink(a) {
3660
4281
  const href = a.getAttribute("href") ?? "";
@@ -3666,29 +4287,248 @@ function hardenLink(a) {
3666
4287
  a.rel = [...tokens].join(" ");
3667
4288
  }
3668
4289
 
4290
+ // src/ui/tool-approval.tsx
4291
+ import { useComputed as useComputed2, useSignal } from "@preact/signals";
4292
+ import { Fragment, jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
4293
+ var p12 = BRAND.cssPrefix;
4294
+ function ToolApproval({ part, strings, active, onDecision }) {
4295
+ const approval = useComputed2(() => part.approvalSig.value);
4296
+ const input = useComputed2(() => part.inputSig.value);
4297
+ const reason = useSignal("");
4298
+ const decided = approval.value?.approved !== void 0;
4299
+ if (decided) {
4300
+ const ap = approval.value;
4301
+ return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval ${p12}-tool-decided`, "data-testid": TID.toolDecision, children: [
4302
+ /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-label`, "data-approved": ap?.approved ? "true" : "false", children: ap?.approved ? strings.approved : strings.rejected }),
4303
+ /* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName }),
4304
+ ap?.reason ? /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-value`, children: ap.reason }) : null
4305
+ ] });
4306
+ }
4307
+ const args = summarizeInput(input.value);
4308
+ return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval`, "data-testid": TID.toolApproval, children: [
4309
+ /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-head`, children: [
4310
+ /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-badge`, children: strings.approvalRequired }),
4311
+ /* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName })
4312
+ ] }),
4313
+ args ? /* @__PURE__ */ jsx13("pre", { class: `${p12}-tool-args`, children: args }) : null,
4314
+ active ? /* @__PURE__ */ jsxs10(Fragment, { children: [
4315
+ /* @__PURE__ */ jsx13(
4316
+ "input",
4317
+ {
4318
+ class: `${p12}-field-input`,
4319
+ value: reason.value,
4320
+ placeholder: strings.approvalReason,
4321
+ onInput: (e) => {
4322
+ reason.value = e.target.value;
4323
+ }
4324
+ }
4325
+ ),
4326
+ /* @__PURE__ */ jsxs10("div", { class: `${p12}-form-actions`, children: [
4327
+ /* @__PURE__ */ jsx13(
4328
+ "button",
4329
+ {
4330
+ type: "button",
4331
+ class: `${p12}-tool-reject`,
4332
+ onClick: () => onDecision(part.toolCallId, false, reason.value.trim() || void 0),
4333
+ "data-testid": TID.toolReject,
4334
+ children: strings.reject
4335
+ }
4336
+ ),
4337
+ /* @__PURE__ */ jsx13(
4338
+ "button",
4339
+ {
4340
+ type: "button",
4341
+ class: `${p12}-tool-approve`,
4342
+ onClick: () => onDecision(part.toolCallId, true, reason.value.trim() || void 0),
4343
+ "data-testid": TID.toolApprove,
4344
+ children: strings.approve
4345
+ }
4346
+ )
4347
+ ] })
4348
+ ] }) : /* @__PURE__ */ jsx13("p", { class: `${p12}-tool-stale-note`, children: strings.stepNoLongerActive })
4349
+ ] });
4350
+ }
4351
+ function summarizeInput(input) {
4352
+ if (input == null) return "";
4353
+ try {
4354
+ const json = typeof input === "string" ? input : JSON.stringify(input, null, 2);
4355
+ return json.length > 600 ? `${json.slice(0, 600)}\u2026` : json;
4356
+ } catch {
4357
+ return "";
4358
+ }
4359
+ }
4360
+
4361
+ // src/ui/tool-ask-input.tsx
4362
+ import { useComputed as useComputed3 } from "@preact/signals";
4363
+
4364
+ // src/ui/form/field.ts
4365
+ function parseAskUserInput(input) {
4366
+ const raw = input && typeof input === "object" ? input : {};
4367
+ const responseType = raw.responseType;
4368
+ return {
4369
+ title: str(raw.title),
4370
+ question: str(raw.question) ?? "Please provide the missing information.",
4371
+ description: str(raw.description),
4372
+ placeholder: str(raw.placeholder),
4373
+ responseType: responseType === "single-choice" || responseType === "multi-choice" || responseType === "confirmation" || responseType === "free-text" ? responseType : "free-text",
4374
+ choices: Array.isArray(raw.choices) ? raw.choices : void 0,
4375
+ allowOther: typeof raw.allowOther === "boolean" ? raw.allowOther : void 0,
4376
+ required: typeof raw.required === "boolean" ? raw.required : true,
4377
+ defaultValues: Array.isArray(raw.defaultValues) ? raw.defaultValues.filter((v) => typeof v === "string") : void 0,
4378
+ minSelections: num(raw.minSelections),
4379
+ maxSelections: num(raw.maxSelections),
4380
+ validationHint: str(raw.validationHint)
4381
+ };
4382
+ }
4383
+ function askInputToFields(req) {
4384
+ if (req.responseType === "confirmation") return [];
4385
+ const options = (req.choices ?? []).map(normalizeChoice).filter((c) => c !== null);
4386
+ let type = "textarea";
4387
+ if (req.responseType === "single-choice" && options.length > 0) type = "radio";
4388
+ else if (req.responseType === "multi-choice") type = "multiselect";
4389
+ const defaultValue = type === "multiselect" ? req.defaultValues?.join(", ") : req.defaultValues?.[0];
4390
+ return [
4391
+ {
4392
+ name: "answer",
4393
+ label: req.question,
4394
+ type,
4395
+ placeholder: req.placeholder,
4396
+ required: req.required ?? true,
4397
+ defaultValue,
4398
+ options: options.length > 0 ? options : void 0,
4399
+ allowOther: req.allowOther,
4400
+ validationHint: req.validationHint,
4401
+ validation: type === "multiselect" ? { minSelections: req.minSelections, maxSelections: req.maxSelections } : void 0
4402
+ }
4403
+ ];
4404
+ }
4405
+ function normalizeChoice(c) {
4406
+ if (typeof c === "string") return c ? { value: c, label: c } : null;
4407
+ if (c && typeof c.value === "string" && c.value)
4408
+ return { value: c.value, label: c.label ?? c.value, description: c.description };
4409
+ return null;
4410
+ }
4411
+ function str(v) {
4412
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
4413
+ }
4414
+ function num(v) {
4415
+ return typeof v === "number" && Number.isFinite(v) ? v : void 0;
4416
+ }
4417
+
4418
+ // src/ui/tool-ask-input.tsx
4419
+ import { jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
4420
+ var p13 = BRAND.cssPrefix;
4421
+ function ToolAskInput({ part, strings, active, onSubmit }) {
4422
+ const state = useComputed3(() => part.stateSig.value);
4423
+ const request = useComputed3(() => parseAskUserInput(part.inputSig.value));
4424
+ const decided = state.value === "output" || state.value === "error";
4425
+ if (decided) {
4426
+ return /* @__PURE__ */ jsx14(DecidedSummary, { part, strings });
4427
+ }
4428
+ if (!active) {
4429
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-stale`, "data-testid": TID.toolAskInput, children: [
4430
+ /* @__PURE__ */ jsx14(Header, { strings, title: request.value.title ?? request.value.question }),
4431
+ /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-stale-note`, children: strings.stepNoLongerActive })
4432
+ ] });
4433
+ }
4434
+ const req = request.value;
4435
+ const isConfirmation = req.responseType === "confirmation";
4436
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input`, "data-testid": TID.toolAskInput, children: [
4437
+ /* @__PURE__ */ jsx14(Header, { strings, title: req.title }),
4438
+ req.description ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-desc`, children: req.description }) : null,
4439
+ isConfirmation ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-question`, children: req.question }) : null,
4440
+ isConfirmation ? /* @__PURE__ */ jsxs11("div", { class: `${p13}-form-actions`, children: [
4441
+ /* @__PURE__ */ jsx14(
4442
+ "button",
4443
+ {
4444
+ type: "button",
4445
+ class: `${p13}-form-skip`,
4446
+ onClick: () => onSubmit(part.toolCallId, { confirmed: false }),
4447
+ "data-testid": TID.toolInputSkip,
4448
+ children: strings.reject
4449
+ }
4450
+ ),
4451
+ /* @__PURE__ */ jsx14(
4452
+ "button",
4453
+ {
4454
+ type: "button",
4455
+ class: `${p13}-form-submit`,
4456
+ onClick: () => onSubmit(part.toolCallId, { confirmed: true }),
4457
+ "data-testid": TID.toolInputSubmit,
4458
+ children: strings.approve
4459
+ }
4460
+ )
4461
+ ] }) : /* @__PURE__ */ jsx14(
4462
+ DynamicForm,
4463
+ {
4464
+ fields: askInputToFields(req),
4465
+ strings,
4466
+ submitLabel: strings.inputSubmit,
4467
+ onSubmit: (values) => onSubmit(part.toolCallId, values),
4468
+ skipLabel: req.required === false ? strings.inputSkip : void 0,
4469
+ onSkip: req.required === false ? () => onSubmit(part.toolCallId, {}) : void 0,
4470
+ submitTestId: TID.toolInputSubmit,
4471
+ skipTestId: TID.toolInputSkip
4472
+ }
4473
+ )
4474
+ ] });
4475
+ }
4476
+ function Header({ strings, title }) {
4477
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-head`, children: [
4478
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-badge`, children: strings.inputRequired }),
4479
+ title ? /* @__PURE__ */ jsx14("strong", { class: `${p13}-tool-title`, children: title }) : null
4480
+ ] });
4481
+ }
4482
+ function DecidedSummary({ part, strings }) {
4483
+ const output = useComputed3(() => part.outputSig.value);
4484
+ const text = summarizeOutput(output.value) || strings.inputSubmitted;
4485
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-decided`, "data-testid": TID.toolDecision, children: [
4486
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-label`, children: strings.inputSubmitted }),
4487
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-value`, children: text })
4488
+ ] });
4489
+ }
4490
+ function summarizeOutput(output) {
4491
+ if (output == null) return "";
4492
+ if (typeof output === "string") return output;
4493
+ if (typeof output === "object") {
4494
+ const rec = output;
4495
+ if ("confirmed" in rec) return rec.confirmed ? "Yes" : "No";
4496
+ return Object.values(rec).filter((v) => typeof v === "string" || typeof v === "number").join(", ");
4497
+ }
4498
+ return String(output);
4499
+ }
4500
+
3669
4501
  // src/ui/tool-chip.tsx
3670
- import { jsx as jsx11, jsxs as jsxs8 } from "preact/jsx-runtime";
4502
+ import { jsx as jsx15, jsxs as jsxs12 } from "preact/jsx-runtime";
3671
4503
  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: [
4504
+ const p33 = BRAND.cssPrefix;
4505
+ return /* @__PURE__ */ jsxs12("span", { class: `${p33}-tool-chip`, role: "status", children: [
4506
+ /* @__PURE__ */ jsxs12("span", { children: [
3675
4507
  strings.usedTool,
3676
4508
  ":"
3677
4509
  ] }),
3678
- /* @__PURE__ */ jsx11("strong", { children: part.toolName })
4510
+ /* @__PURE__ */ jsx15("strong", { children: part.toolName })
3679
4511
  ] });
3680
4512
  }
3681
4513
 
3682
4514
  // 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);
4515
+ import { jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
4516
+ var p14 = BRAND.cssPrefix;
4517
+ function MessageBubble({
4518
+ message,
4519
+ strings,
4520
+ responseMode,
4521
+ showReasoning,
4522
+ showToolCalls,
4523
+ interactive = false,
4524
+ tool
4525
+ }) {
4526
+ const parts = useComputed4(() => message.partsSig.value);
3687
4527
  const partList = parts.value;
3688
- const hasAnswerText = useComputed2(
4528
+ const hasAnswerText = useComputed4(
3689
4529
  () => message.partsSig.value.some((part) => part.kind === "text" && part.textSig.value.length > 0)
3690
4530
  );
3691
- const reasoningVisible = useComputed2(
4531
+ const reasoningVisible = useComputed4(
3692
4532
  () => showReasoning && message.partsSig.value.some((part) => part.kind === "reasoning")
3693
4533
  );
3694
4534
  const streaming = message.role === "assistant" && message.status === "streaming";
@@ -3696,23 +4536,25 @@ function MessageBubble({ message, strings, responseMode, showReasoning, showTool
3696
4536
  const working = streaming && !hasAnswerText.value;
3697
4537
  const showStreamDots = streaming && !bufferedHold && !(reasoningVisible.value && working);
3698
4538
  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(
4539
+ 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: [
4540
+ /* @__PURE__ */ jsxs13("div", { class: `${p14}-bubble`, children: [
4541
+ bufferedHold ? /* @__PURE__ */ jsx16(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx16(
3702
4542
  PartView,
3703
4543
  {
3704
4544
  part,
3705
4545
  active: working,
3706
4546
  strings,
3707
4547
  showReasoning,
3708
- showToolCalls
4548
+ showToolCalls,
4549
+ interactive,
4550
+ tool
3709
4551
  },
3710
4552
  partKey(part)
3711
4553
  )),
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
4554
+ showStreamDots && /* @__PURE__ */ jsx16(TypingDots, {}),
4555
+ message.status === "error" && message.errorText ? /* @__PURE__ */ jsx16("div", { class: `${p14}-error`, role: "alert", children: /* @__PURE__ */ jsx16("span", { children: message.errorText }) }) : null
3714
4556
  ] }),
3715
- stamp ? /* @__PURE__ */ jsx12("time", { class: `${p10}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
4557
+ stamp ? /* @__PURE__ */ jsx16("time", { class: `${p14}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
3716
4558
  ] }) });
3717
4559
  }
3718
4560
  function formatStamp(createdAt) {
@@ -3733,32 +4575,62 @@ function PartView({
3733
4575
  active,
3734
4576
  strings,
3735
4577
  showReasoning,
3736
- showToolCalls
4578
+ showToolCalls,
4579
+ interactive,
4580
+ tool
3737
4581
  }) {
3738
4582
  switch (part.kind) {
3739
4583
  case "text":
3740
- return /* @__PURE__ */ jsx12(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
4584
+ return /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
3741
4585
  case "reasoning":
3742
- return showReasoning ? /* @__PURE__ */ jsx12(ReasoningView, { part, active, strings }) : null;
4586
+ return showReasoning ? /* @__PURE__ */ jsx16(ReasoningView, { part, active, strings }) : null;
3743
4587
  case "tool":
3744
- return showToolCalls ? /* @__PURE__ */ jsx12(ToolChip, { part, strings }) : null;
4588
+ return /* @__PURE__ */ jsx16(
4589
+ ToolPartView,
4590
+ {
4591
+ part,
4592
+ strings,
4593
+ showToolCalls,
4594
+ interactive,
4595
+ tool
4596
+ }
4597
+ );
3745
4598
  case "file":
3746
4599
  if (part.mediaType.startsWith("image/")) {
3747
- return /* @__PURE__ */ jsx12("img", { src: part.url, alt: "", loading: "lazy" });
4600
+ return /* @__PURE__ */ jsx16("img", { src: part.url, alt: "", loading: "lazy" });
3748
4601
  }
3749
- return /* @__PURE__ */ jsx12("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
4602
+ return /* @__PURE__ */ jsx16("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
3750
4603
  case "source":
3751
4604
  return null;
3752
4605
  }
3753
4606
  }
4607
+ function ToolPartView({
4608
+ part,
4609
+ strings,
4610
+ showToolCalls,
4611
+ interactive,
4612
+ tool
4613
+ }) {
4614
+ const state = useComputed4(() => part.stateSig.value);
4615
+ const hasApproval = useComputed4(() => part.approvalSig.value !== void 0);
4616
+ if (tool?.humanInLoop) {
4617
+ if (hasApproval.value || state.value === "awaiting-approval") {
4618
+ return /* @__PURE__ */ jsx16(ToolApproval, { part, strings, active: interactive, onDecision: tool.onDecision });
4619
+ }
4620
+ if (isAskUserInputTool(part.toolName) || state.value === "awaiting-input") {
4621
+ return /* @__PURE__ */ jsx16(ToolAskInput, { part, strings, active: interactive, onSubmit: tool.onResult });
4622
+ }
4623
+ }
4624
+ return showToolCalls ? /* @__PURE__ */ jsx16(ToolChip, { part, strings }) : null;
4625
+ }
3754
4626
  function ReasoningView({
3755
4627
  part,
3756
4628
  active,
3757
4629
  strings
3758
4630
  }) {
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 }) })
4631
+ return /* @__PURE__ */ jsxs13("details", { class: `${p14}-reasoning`, open: active, "data-active": active ? "true" : void 0, children: [
4632
+ /* @__PURE__ */ jsx16("summary", { class: `${p14}-reasoning-summary`, children: /* @__PURE__ */ jsx16("span", { class: `${p14}-reasoning-label`, children: active ? strings.thinking : strings.thoughts }) }),
4633
+ /* @__PURE__ */ jsx16("div", { class: `${p14}-reasoning-body`, children: /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig }) })
3762
4634
  ] });
3763
4635
  }
3764
4636
  function partKey(part) {
@@ -3775,29 +4647,38 @@ function partKey(part) {
3775
4647
  }
3776
4648
  }
3777
4649
  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", {})
4650
+ return /* @__PURE__ */ jsxs13("span", { class: `${p14}-typing`, "aria-hidden": "true", children: [
4651
+ /* @__PURE__ */ jsx16("span", {}),
4652
+ /* @__PURE__ */ jsx16("span", {}),
4653
+ /* @__PURE__ */ jsx16("span", {})
3782
4654
  ] });
3783
4655
  }
3784
4656
  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 })
4657
+ return /* @__PURE__ */ jsxs13("span", { class: `${p14}-loading`, role: "status", children: [
4658
+ /* @__PURE__ */ jsx16("span", { class: `${p14}-loading-spinner`, "aria-hidden": "true" }),
4659
+ /* @__PURE__ */ jsx16("span", { class: `${p14}-loading-label`, children: label })
3788
4660
  ] });
3789
4661
  }
3790
4662
 
3791
4663
  // src/ui/message-list.tsx
3792
- import { jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
3793
- var p11 = BRAND.cssPrefix;
4664
+ import { jsx as jsx17, jsxs as jsxs14 } from "preact/jsx-runtime";
4665
+ var p15 = BRAND.cssPrefix;
3794
4666
  var STICK_THRESHOLD = 120;
3795
4667
  var DIVIDER_IDLE_MS = 1200;
3796
- function MessageList({ messagesSig, strings, responseMode, showReasoning, showToolCalls, loading }) {
4668
+ function MessageList({
4669
+ messagesSig,
4670
+ strings,
4671
+ responseMode,
4672
+ showReasoning,
4673
+ showToolCalls,
4674
+ loading,
4675
+ idle,
4676
+ tool
4677
+ }) {
3797
4678
  const ref = useRef5(null);
3798
- const messages = useComputed3(() => messagesSig.value);
3799
- const [showJump, setShowJump] = useState5(false);
3800
- const [scrolling, setScrolling] = useState5(false);
4679
+ const messages = useComputed5(() => messagesSig.value);
4680
+ const [showJump, setShowJump] = useState6(false);
4681
+ const [scrolling, setScrolling] = useState6(false);
3801
4682
  const hasHydratedRef = useRef5(false);
3802
4683
  const firstMessageId = messages.value[0]?.id;
3803
4684
  useLayoutEffect(() => {
@@ -3852,18 +4733,18 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
3852
4733
  const el = ref.current;
3853
4734
  if (!el) return;
3854
4735
  const syncJump = () => setShowJump(el.scrollHeight - el.scrollTop - el.clientHeight > STICK_THRESHOLD * 2);
3855
- let idle;
4736
+ let idleTimer;
3856
4737
  const onScroll = () => {
3857
4738
  syncJump();
3858
4739
  setScrolling(true);
3859
- clearTimeout(idle);
3860
- idle = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
4740
+ clearTimeout(idleTimer);
4741
+ idleTimer = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
3861
4742
  };
3862
4743
  el.addEventListener("scroll", onScroll, { passive: true });
3863
4744
  syncJump();
3864
4745
  return () => {
3865
4746
  el.removeEventListener("scroll", onScroll);
3866
- clearTimeout(idle);
4747
+ clearTimeout(idleTimer);
3867
4748
  };
3868
4749
  }, []);
3869
4750
  const jumpToBottom = () => {
@@ -3872,54 +4753,57 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
3872
4753
  };
3873
4754
  const rows = [];
3874
4755
  let prevDay = "";
4756
+ const lastId = messages.value.at(-1)?.id;
3875
4757
  for (const m of messages.value) {
3876
4758
  const day = dayKey(m.createdAt);
3877
4759
  if (day && day !== prevDay) {
3878
4760
  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}`)
4761
+ /* @__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
4762
  );
3881
4763
  prevDay = day;
3882
4764
  }
3883
4765
  rows.push(
3884
- /* @__PURE__ */ jsx13(
4766
+ /* @__PURE__ */ jsx17(
3885
4767
  MessageBubble,
3886
4768
  {
3887
4769
  message: m,
3888
4770
  strings,
3889
4771
  responseMode,
3890
4772
  showReasoning,
3891
- showToolCalls
4773
+ showToolCalls,
4774
+ interactive: Boolean(idle) && m.id === lastId,
4775
+ tool
3892
4776
  },
3893
4777
  m.id
3894
4778
  )
3895
4779
  );
3896
4780
  }
3897
- return /* @__PURE__ */ jsxs10("div", { class: `${p11}-list-wrap`, children: [
3898
- /* @__PURE__ */ jsxs10(
4781
+ return /* @__PURE__ */ jsxs14("div", { class: `${p15}-list-wrap`, children: [
4782
+ /* @__PURE__ */ jsxs14(
3899
4783
  "div",
3900
4784
  {
3901
4785
  ref,
3902
- class: `${p11}-list`,
4786
+ class: `${p15}-list`,
3903
4787
  role: "log",
3904
4788
  "aria-live": "polite",
3905
4789
  "aria-relevant": "additions text",
3906
4790
  "data-scrolling": scrolling ? "true" : void 0,
3907
4791
  children: [
3908
- loading && messages.value.length === 0 ? /* @__PURE__ */ jsx13("div", { class: `${p11}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
4792
+ loading && messages.value.length === 0 ? /* @__PURE__ */ jsx17("div", { class: `${p15}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
3909
4793
  rows
3910
4794
  ]
3911
4795
  }
3912
4796
  ),
3913
- showJump ? /* @__PURE__ */ jsx13(
4797
+ showJump ? /* @__PURE__ */ jsx17(
3914
4798
  "button",
3915
4799
  {
3916
4800
  type: "button",
3917
- class: `${p11}-jump`,
4801
+ class: `${p15}-jump`,
3918
4802
  onClick: jumpToBottom,
3919
4803
  "aria-label": strings.scrollToBottom,
3920
4804
  title: strings.scrollToBottom,
3921
4805
  "data-testid": TID.scrollToBottom,
3922
- children: /* @__PURE__ */ jsx13(ChevronDownIcon, {})
4806
+ children: /* @__PURE__ */ jsx17(ChevronDownIcon, {})
3923
4807
  }
3924
4808
  ) : null
3925
4809
  ] });
@@ -3948,7 +4832,7 @@ function dayLabel(createdAt, strings) {
3948
4832
  }
3949
4833
 
3950
4834
  // src/ui/conversation-list.tsx
3951
- import { useEffect as useEffect9, useState as useState6 } from "preact/hooks";
4835
+ import { useEffect as useEffect9, useState as useState7 } from "preact/hooks";
3952
4836
 
3953
4837
  // src/ui/history-groups.ts
3954
4838
  var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
@@ -3978,7 +4862,7 @@ function startOfDay(ms) {
3978
4862
  }
3979
4863
 
3980
4864
  // src/ui/conversation-list.tsx
3981
- import { Fragment, jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
4865
+ import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs15 } from "preact/jsx-runtime";
3982
4866
  var log11 = logger.scope("history");
3983
4867
  var BUCKET_TO_STRING = {
3984
4868
  today: "dateToday",
@@ -3987,9 +4871,9 @@ var BUCKET_TO_STRING = {
3987
4871
  older: "dateOlder"
3988
4872
  };
3989
4873
  function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }) {
3990
- const p29 = BRAND.cssPrefix;
3991
- const [state, setState] = useState6("loading");
3992
- const [sessions, setChats] = useState6([]);
4874
+ const p33 = BRAND.cssPrefix;
4875
+ const [state, setState] = useState7("loading");
4876
+ const [sessions, setChats] = useState7([]);
3993
4877
  useEffect9(() => {
3994
4878
  let cancelled = false;
3995
4879
  transport.listSessions({ visitorId }).then((res) => {
@@ -4005,38 +4889,38 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
4005
4889
  cancelled = true;
4006
4890
  };
4007
4891
  }, [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, {}),
4892
+ 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: [
4893
+ /* @__PURE__ */ jsx18(PlusIcon, {}),
4010
4894
  strings.historyNewChat
4011
4895
  ] }) }) : null;
4012
4896
  if (state === "loading") {
4013
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
4014
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-empty`, children: strings.historyLoading }),
4897
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4898
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyLoading }),
4015
4899
  newChatButton
4016
4900
  ] });
4017
4901
  }
4018
4902
  if (state === "error" || sessions.length === 0) {
4019
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
4020
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-empty`, children: strings.historyEmpty }),
4903
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4904
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyEmpty }),
4021
4905
  newChatButton
4022
4906
  ] });
4023
4907
  }
4024
4908
  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(
4909
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4910
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history`, role: "list", children: groups.map((group) => /* @__PURE__ */ jsxs15("div", { class: `${p33}-history-group`, children: [
4911
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-heading`, children: strings[BUCKET_TO_STRING[group.bucket]] }),
4912
+ group.sessions.map((chat) => /* @__PURE__ */ jsxs15(
4029
4913
  "button",
4030
4914
  {
4031
4915
  type: "button",
4032
4916
  role: "listitem",
4033
- class: `${p29}-history-item`,
4917
+ class: `${p33}-history-item`,
4034
4918
  onClick: () => onSelect(chat),
4035
4919
  "data-closed": chat.canContinue ? void 0 : "true",
4036
4920
  "data-testid": tid(TID.historyItem, chat.sessionId),
4037
4921
  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
4922
+ /* @__PURE__ */ jsx18("span", { class: `${p33}-history-title`, children: chat.title }),
4923
+ chat.preview ? /* @__PURE__ */ jsx18("span", { class: `${p33}-history-preview`, children: chat.preview }) : null
4040
4924
  ]
4041
4925
  },
4042
4926
  chat.sessionId
@@ -4047,21 +4931,21 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
4047
4931
  }
4048
4932
 
4049
4933
  // src/ui/chat-history-pane.tsx
4050
- import { jsx as jsx15 } from "preact/jsx-runtime";
4934
+ import { jsx as jsx19 } from "preact/jsx-runtime";
4051
4935
  function ChatHistoryPane(props2) {
4052
- return /* @__PURE__ */ jsx15(ConversationList, { ...props2 });
4936
+ return /* @__PURE__ */ jsx19(ConversationList, { ...props2 });
4053
4937
  }
4054
4938
 
4055
4939
  // src/ui/suggestions.tsx
4056
- import { jsx as jsx16 } from "preact/jsx-runtime";
4057
- var p12 = BRAND.cssPrefix;
4940
+ import { jsx as jsx20 } from "preact/jsx-runtime";
4941
+ var p16 = BRAND.cssPrefix;
4058
4942
  function Suggestions({ suggestions, onPick }) {
4059
4943
  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(
4944
+ return /* @__PURE__ */ jsx20("div", { class: `${p16}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx20(
4061
4945
  "button",
4062
4946
  {
4063
4947
  type: "button",
4064
- class: `${p12}-suggestion`,
4948
+ class: `${p16}-suggestion`,
4065
4949
  onClick: () => onPick(s),
4066
4950
  "data-testid": tid(TID.suggestion, i),
4067
4951
  children: s.label
@@ -4071,8 +4955,8 @@ function Suggestions({ suggestions, onPick }) {
4071
4955
  }
4072
4956
 
4073
4957
  // src/ui/panel.tsx
4074
- import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs12 } from "preact/jsx-runtime";
4075
- var p13 = BRAND.cssPrefix;
4958
+ import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
4959
+ var p17 = BRAND.cssPrefix;
4076
4960
  function Panel(props2) {
4077
4961
  const { options, onClose } = props2;
4078
4962
  const s = options.strings;
@@ -4096,18 +4980,18 @@ function Panel(props2) {
4096
4980
  }, []);
4097
4981
  const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
4098
4982
  useDragMove(containerRef.current, options.mode === "modal");
4099
- return /* @__PURE__ */ jsxs12(
4983
+ return /* @__PURE__ */ jsxs16(
4100
4984
  "div",
4101
4985
  {
4102
4986
  ref: containerRef,
4103
- class: `${p13}-panel`,
4987
+ class: `${p17}-panel`,
4104
4988
  role: "dialog",
4105
4989
  "aria-modal": "false",
4106
4990
  "aria-label": s.panelTitle,
4107
4991
  style: { position: "relative" },
4108
4992
  "data-testid": TID.panel,
4109
4993
  children: [
4110
- /* @__PURE__ */ jsx17(
4994
+ /* @__PURE__ */ jsx21(
4111
4995
  PanelContent,
4112
4996
  {
4113
4997
  ...props2,
@@ -4116,7 +5000,7 @@ function Panel(props2) {
4116
5000
  composerAttachApiRef
4117
5001
  }
4118
5002
  ),
4119
- /* @__PURE__ */ jsx17(PoweredByBar, { poweredBy: props2.options.poweredBy })
5003
+ /* @__PURE__ */ jsx21(PoweredByBar, { poweredBy: props2.options.poweredBy })
4120
5004
  ]
4121
5005
  }
4122
5006
  );
@@ -4147,13 +5031,39 @@ function PanelContent(props2) {
4147
5031
  onSend,
4148
5032
  onStop,
4149
5033
  onSuggestion,
5034
+ intakePending,
5035
+ onIntakeComplete,
5036
+ tool,
4150
5037
  containerEl,
4151
5038
  dragOver,
4152
5039
  composerAttachApiRef
4153
5040
  } = props2;
4154
5041
  const s = options.strings;
4155
- return /* @__PURE__ */ jsxs12(Fragment2, { children: [
4156
- view === "history" ? /* @__PURE__ */ jsx17(
5042
+ let composerArea;
5043
+ if (intakePending) {
5044
+ composerArea = /* @__PURE__ */ jsx21(IntakeGate, { intake: options.intake, strings: s, onComplete: onIntakeComplete });
5045
+ } else if (canSend) {
5046
+ composerArea = /* @__PURE__ */ jsxs16(Fragment3, { children: [
5047
+ /* @__PURE__ */ jsx21(Suggestions, { suggestions, onPick: onSuggestion }),
5048
+ /* @__PURE__ */ jsx21(
5049
+ Composer,
5050
+ {
5051
+ options,
5052
+ transport,
5053
+ feedback,
5054
+ bus,
5055
+ isStreaming,
5056
+ onSend,
5057
+ onStop,
5058
+ attachApiRef: composerAttachApiRef
5059
+ }
5060
+ )
5061
+ ] });
5062
+ } else {
5063
+ composerArea = /* @__PURE__ */ jsx21(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear });
5064
+ }
5065
+ return /* @__PURE__ */ jsxs16(Fragment3, { children: [
5066
+ view === "history" ? /* @__PURE__ */ jsx21(
4157
5067
  HistoryHeader,
4158
5068
  {
4159
5069
  strings: s,
@@ -4161,22 +5071,22 @@ function PanelContent(props2) {
4161
5071
  onClose,
4162
5072
  showClose: canShowClose(options.mode, panelSize, options.actions)
4163
5073
  }
4164
- ) : /* @__PURE__ */ jsxs12("header", { class: `${p13}-header`, "data-testid": TID.panelHeader, children: [
4165
- onBack ? /* @__PURE__ */ jsx17(
5074
+ ) : /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, "data-testid": TID.panelHeader, children: [
5075
+ onBack ? /* @__PURE__ */ jsx21(
4166
5076
  "button",
4167
5077
  {
4168
5078
  type: "button",
4169
- class: `${p13}-icon-btn`,
5079
+ class: `${p17}-icon-btn`,
4170
5080
  onClick: onBack,
4171
5081
  "aria-label": s.moduleBack,
4172
5082
  title: s.moduleBack,
4173
- children: /* @__PURE__ */ jsx17(BackIcon, {})
5083
+ children: /* @__PURE__ */ jsx21(BackIcon, {})
4174
5084
  }
4175
5085
  ) : null,
4176
- agent ? /* @__PURE__ */ jsx17(AgentBadge, { agent }) : /* @__PURE__ */ jsx17("h1", { children: s.panelTitle }),
4177
- /* @__PURE__ */ jsx17(HeaderActions, { panelProps: props2, variant: "chat" })
5086
+ agent ? /* @__PURE__ */ jsx21(AgentBadge, { agent }) : /* @__PURE__ */ jsx21("h1", { children: s.panelTitle }),
5087
+ /* @__PURE__ */ jsx21(HeaderActions, { panelProps: props2, variant: "chat" })
4178
5088
  ] }),
4179
- view === "history" ? /* @__PURE__ */ jsx17(
5089
+ view === "history" ? /* @__PURE__ */ jsx21(
4180
5090
  ChatHistoryPane,
4181
5091
  {
4182
5092
  transport,
@@ -4185,9 +5095,9 @@ function PanelContent(props2) {
4185
5095
  onSelect: (chat) => onSelectHistoryChat(chat.sessionId),
4186
5096
  onNewChat
4187
5097
  }
4188
- ) : /* @__PURE__ */ jsxs12(Fragment2, { children: [
4189
- /* @__PURE__ */ jsx17(DropZone, { visible: dragOver, strings: s }),
4190
- /* @__PURE__ */ jsx17(
5098
+ ) : /* @__PURE__ */ jsxs16(Fragment3, { children: [
5099
+ /* @__PURE__ */ jsx21(DropZone, { visible: dragOver, strings: s }),
5100
+ /* @__PURE__ */ jsx21(
4191
5101
  MessageList,
4192
5102
  {
4193
5103
  messagesSig,
@@ -4195,28 +5105,15 @@ function PanelContent(props2) {
4195
5105
  responseMode: options.responseMode,
4196
5106
  showReasoning: options.showReasoning,
4197
5107
  showToolCalls: options.showToolCalls,
4198
- loading: loadingMessages
5108
+ loading: loadingMessages,
5109
+ idle: !isStreaming,
5110
+ tool
4199
5111
  }
4200
5112
  ),
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 })
5113
+ composerArea,
5114
+ /* @__PURE__ */ jsx21(ComposerFooter, { disclaimer: options.composerDisclaimer })
4218
5115
  ] }),
4219
- options.size.resize?.enabled ? /* @__PURE__ */ jsx17(
5116
+ options.size.resize?.enabled ? /* @__PURE__ */ jsx21(
4220
5117
  ResizeGrip,
4221
5118
  {
4222
5119
  panelEl: containerEl,
@@ -4235,86 +5132,86 @@ function HistoryHeader({
4235
5132
  onClose,
4236
5133
  showClose
4237
5134
  }) {
4238
- return /* @__PURE__ */ jsxs12("header", { class: `${p13}-header`, children: [
4239
- /* @__PURE__ */ jsx17(
5135
+ return /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, children: [
5136
+ /* @__PURE__ */ jsx21(
4240
5137
  "button",
4241
5138
  {
4242
5139
  type: "button",
4243
- class: `${p13}-icon-btn`,
5140
+ class: `${p17}-icon-btn`,
4244
5141
  onClick: onBack,
4245
5142
  "aria-label": strings.historyBack,
4246
5143
  title: strings.historyBack,
4247
- children: /* @__PURE__ */ jsx17(BackIcon, {})
5144
+ children: /* @__PURE__ */ jsx21(BackIcon, {})
4248
5145
  }
4249
5146
  ),
4250
- /* @__PURE__ */ jsx17("h1", { children: strings.historyTitle }),
4251
- showClose ? /* @__PURE__ */ jsx17(
5147
+ /* @__PURE__ */ jsx21("h1", { children: strings.historyTitle }),
5148
+ showClose ? /* @__PURE__ */ jsx21(
4252
5149
  "button",
4253
5150
  {
4254
5151
  type: "button",
4255
- class: `${p13}-icon-btn`,
5152
+ class: `${p17}-icon-btn`,
4256
5153
  onClick: onClose,
4257
5154
  "aria-label": strings.close,
4258
5155
  title: strings.close,
4259
- children: /* @__PURE__ */ jsx17(CloseIcon, {})
5156
+ children: /* @__PURE__ */ jsx21(CloseIcon, {})
4260
5157
  }
4261
5158
  ) : null
4262
5159
  ] });
4263
5160
  }
4264
5161
  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 })
5162
+ return /* @__PURE__ */ jsxs16("div", { class: `${p17}-readonly-banner`, role: "note", children: [
5163
+ /* @__PURE__ */ jsx21("span", { class: `${p17}-readonly-label`, children: label }),
5164
+ /* @__PURE__ */ jsx21("button", { type: "button", class: `${p17}-readonly-cta`, onClick: onNewChat, children: ctaLabel })
4268
5165
  ] });
4269
5166
  }
4270
5167
  function ComposerFooter({ disclaimer }) {
4271
5168
  if (!disclaimer) return null;
4272
- return /* @__PURE__ */ jsx17("div", { class: `${p13}-composer-footer`, children: /* @__PURE__ */ jsx17("div", { class: `${p13}-disclaimer`, children: disclaimer }) });
5169
+ return /* @__PURE__ */ jsx21("div", { class: `${p17}-composer-footer`, children: /* @__PURE__ */ jsx21("div", { class: `${p17}-disclaimer`, children: disclaimer }) });
4273
5170
  }
4274
5171
  function PoweredByBar({ poweredBy }) {
4275
5172
  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 }) });
5173
+ return /* @__PURE__ */ jsx21("div", { class: `${p17}-poweredby-bar`, children: /* @__PURE__ */ jsx21(PoweredBy, { logoUrl: poweredBy.logoUrl, text: poweredBy.text, href: poweredBy.href }) });
4277
5174
  }
4278
5175
  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
5176
+ const inner = /* @__PURE__ */ jsxs16(Fragment3, { children: [
5177
+ logoUrl ? /* @__PURE__ */ jsx21("img", { class: `${p17}-poweredby-logo`, src: logoUrl, alt: "", loading: "lazy" }) : null,
5178
+ text ? /* @__PURE__ */ jsx21("span", { children: text }) : null
4282
5179
  ] });
4283
5180
  if (href) {
4284
- return /* @__PURE__ */ jsx17("a", { class: `${p13}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
5181
+ return /* @__PURE__ */ jsx21("a", { class: `${p17}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
4285
5182
  }
4286
- return /* @__PURE__ */ jsx17("span", { class: `${p13}-poweredby`, children: inner });
5183
+ return /* @__PURE__ */ jsx21("span", { class: `${p17}-poweredby`, children: inner });
4287
5184
  }
4288
5185
 
4289
5186
  // src/ui/sidebar.tsx
4290
- import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs13 } from "preact/jsx-runtime";
5187
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
4291
5188
  function Sidebar(props2) {
4292
- const p29 = BRAND.cssPrefix;
5189
+ const p33 = BRAND.cssPrefix;
4293
5190
  const { site, blocks, strings, collapsed } = props2;
4294
5191
  const navigation = blocks?.navigation ?? [];
4295
5192
  const linkCards = blocks?.linkCards ?? [];
4296
5193
  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(
5194
+ return /* @__PURE__ */ jsxs17("aside", { class: `${p33}-sidebar`, "data-collapsed": collapsed ? "true" : "false", "data-testid": TID.sidebar, children: [
5195
+ /* @__PURE__ */ jsxs17("div", { class: `${p33}-sidebar-header`, children: [
5196
+ /* @__PURE__ */ jsx22(SidebarBrand, { site }),
5197
+ /* @__PURE__ */ jsx22(
4301
5198
  "button",
4302
5199
  {
4303
5200
  type: "button",
4304
- class: `${p29}-sidebar-toggle`,
5201
+ class: `${p33}-sidebar-toggle`,
4305
5202
  "aria-label": toggleLabel,
4306
5203
  "aria-expanded": collapsed ? "false" : "true",
4307
5204
  title: toggleLabel,
4308
5205
  onClick: props2.onToggleCollapsed,
4309
5206
  "data-testid": TID.sidebarToggle,
4310
- children: /* @__PURE__ */ jsx18(SidebarToggleIcon, { collapsed })
5207
+ children: /* @__PURE__ */ jsx22(SidebarToggleIcon, { collapsed })
4311
5208
  }
4312
5209
  )
4313
5210
  ] }),
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(
5211
+ collapsed ? null : /* @__PURE__ */ jsxs17(Fragment4, { children: [
5212
+ navigation.length > 0 ? /* @__PURE__ */ jsx22("nav", { class: `${p33}-sidebar-section`, "data-section": "navigation", children: /* @__PURE__ */ jsx22(SidebarNav, { items: navigation }) }) : null,
5213
+ linkCards.length > 0 ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-section`, "data-section": "link-cards", children: /* @__PURE__ */ jsx22(SidebarCards, { items: linkCards }) }) : null,
5214
+ props2.showConversations ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-conversations`, children: /* @__PURE__ */ jsx22(
4318
5215
  ConversationList,
4319
5216
  {
4320
5217
  transport: props2.transport,
@@ -4328,18 +5225,18 @@ function Sidebar(props2) {
4328
5225
  ] });
4329
5226
  }
4330
5227
  function SidebarBrand({ site }) {
4331
- const p29 = BRAND.cssPrefix;
5228
+ const p33 = BRAND.cssPrefix;
4332
5229
  if (site?.logo?.url) {
4333
5230
  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 })
5231
+ return /* @__PURE__ */ jsxs17("picture", { children: [
5232
+ site.logoDark?.url ? /* @__PURE__ */ jsx22("source", { srcset: site.logoDark.url, media: "(prefers-color-scheme: dark)" }) : null,
5233
+ /* @__PURE__ */ jsx22("img", { class: `${p33}-sidebar-logo`, src: site.logo.url, alt })
4337
5234
  ] });
4338
5235
  }
4339
- return /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-title`, children: site?.title ?? BRAND.name });
5236
+ return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-title`, children: site?.title ?? BRAND.name });
4340
5237
  }
4341
5238
  function SidebarToggleIcon({ collapsed }) {
4342
- return /* @__PURE__ */ jsx18(
5239
+ return /* @__PURE__ */ jsx22(
4343
5240
  "svg",
4344
5241
  {
4345
5242
  width: "16",
@@ -4349,38 +5246,38 @@ function SidebarToggleIcon({ collapsed }) {
4349
5246
  stroke: "currentColor",
4350
5247
  "stroke-width": "2",
4351
5248
  "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" })
5249
+ children: collapsed ? /* @__PURE__ */ jsx22("polyline", { points: "9 6 15 12 9 18" }) : /* @__PURE__ */ jsx22("polyline", { points: "15 6 9 12 15 18" })
4353
5250
  }
4354
5251
  );
4355
5252
  }
4356
5253
  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(
5254
+ const p33 = BRAND.cssPrefix;
5255
+ return /* @__PURE__ */ jsx22("ul", { class: `${p33}-sidebar-nav`, children: items.map((item) => /* @__PURE__ */ jsx22("li", { children: /* @__PURE__ */ jsxs17(
4359
5256
  "a",
4360
5257
  {
4361
- class: `${p29}-sidebar-nav-item`,
5258
+ class: `${p33}-sidebar-nav-item`,
4362
5259
  href: item.href,
4363
5260
  target: item.href ? "_blank" : void 0,
4364
5261
  rel: item.href ? "noreferrer" : void 0,
4365
5262
  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 })
5263
+ item.icon ? /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-icon`, "data-icon": item.icon }) : null,
5264
+ /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-label`, children: item.label })
4368
5265
  ]
4369
5266
  }
4370
5267
  ) }, item.id ?? item.label)) });
4371
5268
  }
4372
5269
  function SidebarCards({ items }) {
4373
- const p29 = BRAND.cssPrefix;
4374
- return /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs13(
5270
+ const p33 = BRAND.cssPrefix;
5271
+ return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs17(
4375
5272
  "a",
4376
5273
  {
4377
- class: `${p29}-sidebar-card`,
5274
+ class: `${p33}-sidebar-card`,
4378
5275
  href: item.href,
4379
5276
  target: item.href ? "_blank" : void 0,
4380
5277
  rel: item.href ? "noreferrer" : void 0,
4381
5278
  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
5279
+ /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-label`, children: item.label }),
5280
+ item.description ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-desc`, children: item.description }) : null
4384
5281
  ]
4385
5282
  },
4386
5283
  item.id ?? item.label
@@ -4388,11 +5285,11 @@ function SidebarCards({ items }) {
4388
5285
  }
4389
5286
 
4390
5287
  // src/ui/page-shell.tsx
4391
- import { jsx as jsx19, jsxs as jsxs14 } from "preact/jsx-runtime";
4392
- var p14 = BRAND.cssPrefix;
5288
+ import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
5289
+ var p18 = BRAND.cssPrefix;
4393
5290
  function PageShell(props2) {
4394
- return /* @__PURE__ */ jsxs14("main", { class: `${p14}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
4395
- /* @__PURE__ */ jsx19(
5291
+ return /* @__PURE__ */ jsxs18("main", { class: `${p18}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
5292
+ /* @__PURE__ */ jsx23(
4396
5293
  Sidebar,
4397
5294
  {
4398
5295
  site: props2.site,
@@ -4407,7 +5304,7 @@ function PageShell(props2) {
4407
5304
  onToggleCollapsed: props2.onToggleSidebarCollapsed
4408
5305
  }
4409
5306
  ),
4410
- /* @__PURE__ */ jsx19("section", { class: `${p14}-page-chat`, "aria-label": "Chat", children: props2.children })
5307
+ /* @__PURE__ */ jsx23("section", { class: `${p18}-page-chat`, "aria-label": "Chat", children: props2.children })
4411
5308
  ] });
4412
5309
  }
4413
5310
 
@@ -4445,7 +5342,7 @@ var atTabRoot = (s) => activeStack(s).length === 0;
4445
5342
 
4446
5343
  // src/ui/messenger-home.tsx
4447
5344
  import { useCallback as useCallback4, useEffect as useEffect15, useRef as useRef7 } from "preact/hooks";
4448
- import { useComputed as useComputed4 } from "@preact/signals";
5345
+ import { useComputed as useComputed6 } from "@preact/signals";
4449
5346
 
4450
5347
  // src/ui/modules/messages.tsx
4451
5348
  var chatLayout = {
@@ -4454,83 +5351,83 @@ var chatLayout = {
4454
5351
  };
4455
5352
 
4456
5353
  // src/ui/modules/help.tsx
4457
- import { useEffect as useEffect11, useMemo as useMemo2, useState as useState7 } from "preact/hooks";
5354
+ import { useEffect as useEffect11, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
4458
5355
 
4459
5356
  // src/ui/back-header.tsx
4460
- import { jsx as jsx20, jsxs as jsxs15 } from "preact/jsx-runtime";
4461
- var p15 = BRAND.cssPrefix;
5357
+ import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
5358
+ var p19 = BRAND.cssPrefix;
4462
5359
  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" })
5360
+ return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-variant": "title", children: [
5361
+ /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" }),
5362
+ /* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
5363
+ actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
4467
5364
  ] });
4468
5365
  }
4469
5366
  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" })
5367
+ return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-testid": testid, children: [
5368
+ /* @__PURE__ */ jsx24("button", { type: "button", class: `${p19}-icon-btn`, onClick: onBack, "aria-label": backLabel, title: backLabel, children: /* @__PURE__ */ jsx24(BackIcon, {}) }),
5369
+ /* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
5370
+ actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
4474
5371
  ] });
4475
5372
  }
4476
5373
 
4477
5374
  // src/ui/home-search.tsx
4478
- import { jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
4479
- var p16 = BRAND.cssPrefix;
5375
+ import { jsx as jsx25, jsxs as jsxs20 } from "preact/jsx-runtime";
5376
+ var p20 = BRAND.cssPrefix;
4480
5377
  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, {}) })
5378
+ return /* @__PURE__ */ jsxs20("button", { type: "button", class: `${p20}-home-search`, onClick: onActivate, "data-testid": TID.homeSearch, children: [
5379
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-text`, children: placeholder }),
5380
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
4484
5381
  ] });
4485
5382
  }
4486
5383
  function HelpSearchInput({ placeholder, value, onInput }) {
4487
- return /* @__PURE__ */ jsxs16("div", { class: `${p16}-home-search`, "data-input": "true", children: [
4488
- /* @__PURE__ */ jsx21(
5384
+ return /* @__PURE__ */ jsxs20("div", { class: `${p20}-home-search`, "data-input": "true", children: [
5385
+ /* @__PURE__ */ jsx25(
4489
5386
  "input",
4490
5387
  {
4491
5388
  type: "search",
4492
- class: `${p16}-home-search-input`,
5389
+ class: `${p20}-home-search-input`,
4493
5390
  placeholder,
4494
5391
  value,
4495
5392
  onInput: (e) => onInput(e.currentTarget.value),
4496
5393
  "data-testid": TID.helpSearch
4497
5394
  }
4498
5395
  ),
4499
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx21(SearchIcon, {}) })
5396
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
4500
5397
  ] });
4501
5398
  }
4502
5399
 
4503
5400
  // src/ui/list-row.tsx
4504
- import { jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
4505
- var p17 = BRAND.cssPrefix;
5401
+ import { jsx as jsx26, jsxs as jsxs21 } from "preact/jsx-runtime";
5402
+ var p21 = BRAND.cssPrefix;
4506
5403
  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
5404
+ return /* @__PURE__ */ jsxs21("button", { type: "button", class: `${p21}-list-row`, onClick, "data-testid": testid, children: [
5405
+ /* @__PURE__ */ jsxs21("span", { class: `${p21}-list-row-body`, children: [
5406
+ /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-title`, children: title }),
5407
+ subtitle ? /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-sub`, children: subtitle }) : null
4511
5408
  ] }),
4512
- /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx22(ChevronRightIcon, {}) })
5409
+ /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(ChevronRightIcon, {}) })
4513
5410
  ] });
4514
5411
  }
4515
5412
 
4516
5413
  // src/ui/module-state.tsx
4517
- import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
4518
- var p18 = BRAND.cssPrefix;
5414
+ import { jsx as jsx27, jsxs as jsxs22 } from "preact/jsx-runtime";
5415
+ var p22 = BRAND.cssPrefix;
4519
5416
  function ModuleState({
4520
5417
  tone = "info",
4521
5418
  message,
4522
5419
  onRetry,
4523
5420
  strings
4524
5421
  }) {
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
5422
+ return /* @__PURE__ */ jsxs22("div", { class: `${p22}-module-empty`, role: tone === "error" ? "alert" : "status", "aria-live": "polite", children: [
5423
+ /* @__PURE__ */ jsx27("span", { children: message }),
5424
+ onRetry ? /* @__PURE__ */ jsx27("button", { type: "button", class: `${p22}-module-retry`, onClick: onRetry, children: strings.errorRetry }) : null
4528
5425
  ] });
4529
5426
  }
4530
5427
 
4531
5428
  // src/ui/modules/help.tsx
4532
- import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
4533
- var p19 = BRAND.cssPrefix;
5429
+ import { jsx as jsx28, jsxs as jsxs23 } from "preact/jsx-runtime";
5430
+ var p23 = BRAND.cssPrefix;
4534
5431
  var log12 = logger.scope("help");
4535
5432
  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
5433
  function groupByCategory(items) {
@@ -4559,7 +5456,7 @@ function fuzzySearch(items, query) {
4559
5456
  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
5457
  }
4561
5458
  function ArticleRow({ article, nav }) {
4562
- return /* @__PURE__ */ jsx24(
5459
+ return /* @__PURE__ */ jsx28(
4563
5460
  ListRow,
4564
5461
  {
4565
5462
  title: article.title,
@@ -4571,11 +5468,11 @@ function ArticleRow({ article, nav }) {
4571
5468
  }
4572
5469
  function HelpRoot({ transport, strings, config, nav, panelProps }) {
4573
5470
  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);
5471
+ const [state, setState] = useState8("loading");
5472
+ const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
5473
+ const [items, setItems] = useState8([]);
5474
+ const [query, setQuery] = useState8("");
5475
+ const [reloadKey, setReloadKey] = useState8(0);
4579
5476
  useEffect11(() => {
4580
5477
  let cancelled = false;
4581
5478
  setState("loading");
@@ -4596,46 +5493,46 @@ function HelpRoot({ transport, strings, config, nav, panelProps }) {
4596
5493
  const results = useMemo2(() => fuzzySearch(items, query), [items, query]);
4597
5494
  function renderBody() {
4598
5495
  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)) });
5496
+ if (results.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpSearchEmpty, strings });
5497
+ return /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: results.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) });
4601
5498
  }
4602
- if (state === "loading") return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpLoading, strings });
5499
+ if (state === "loading") return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpLoading, strings });
4603
5500
  if (state === "error") {
4604
- return /* @__PURE__ */ jsx24(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
5501
+ return /* @__PURE__ */ jsx28(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
4605
5502
  }
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)) })
5503
+ if (items.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpEmpty, strings });
5504
+ return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */ jsxs23("section", { class: `${p23}-help-group`, children: [
5505
+ category ? /* @__PURE__ */ jsx28("h2", { class: `${p23}-help-section-title`, children: category }) : null,
5506
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: rows.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) })
4610
5507
  ] }, category));
4611
5508
  }
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() })
5509
+ return /* @__PURE__ */ jsxs23("div", { class: `${p23}-module`, children: [
5510
+ /* @__PURE__ */ jsx28(TitleBar, { title: strings.helpTitle, actions: /* @__PURE__ */ jsx28(HeaderActions, { panelProps, variant: "plain" }) }),
5511
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-module-pad`, children: /* @__PURE__ */ jsx28(HelpSearchInput, { placeholder: strings.helpSearchPlaceholder, value: query, onInput: setQuery }) }),
5512
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-help-list`, children: renderBody() })
4616
5513
  ] });
4617
5514
  }
4618
5515
  var helpLayout = {
4619
5516
  Icon: HelpIcon,
4620
- Root: (props2) => /* @__PURE__ */ jsx24(HelpRoot, { ...props2 })
5517
+ Root: (props2) => /* @__PURE__ */ jsx28(HelpRoot, { ...props2 })
4621
5518
  };
4622
5519
 
4623
5520
  // src/ui/modules/home.tsx
4624
- import { useEffect as useEffect12, useState as useState8 } from "preact/hooks";
5521
+ import { useEffect as useEffect12, useState as useState9 } from "preact/hooks";
4625
5522
 
4626
5523
  // src/ui/home-card.tsx
4627
- import { jsx as jsx25 } from "preact/jsx-runtime";
4628
- var p20 = BRAND.cssPrefix;
5524
+ import { jsx as jsx29 } from "preact/jsx-runtime";
5525
+ var p24 = BRAND.cssPrefix;
4629
5526
  function HomeCard({ onClick, children, testid }) {
4630
5527
  if (onClick) {
4631
- return /* @__PURE__ */ jsx25("button", { type: "button", class: `${p20}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
5528
+ return /* @__PURE__ */ jsx29("button", { type: "button", class: `${p24}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
4632
5529
  }
4633
- return /* @__PURE__ */ jsx25("div", { class: `${p20}-home-card`, "data-testid": testid, children });
5530
+ return /* @__PURE__ */ jsx29("div", { class: `${p24}-home-card`, "data-testid": testid, children });
4634
5531
  }
4635
5532
 
4636
5533
  // 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;
5534
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs24 } from "preact/jsx-runtime";
5535
+ var p25 = BRAND.cssPrefix;
4639
5536
  var log13 = logger.scope("home");
4640
5537
  function resolveGreeting(props2) {
4641
5538
  const name = props2.options.userContext?.name;
@@ -4649,8 +5546,8 @@ function resolveGreeting(props2) {
4649
5546
  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
5547
  function HomeRoot(props2) {
4651
5548
  const { transport, strings, config, nav, panelProps } = props2;
4652
- const [recent, setRecent] = useState8(null);
4653
- const [content, setContent] = useState8([]);
5549
+ const [recent, setRecent] = useState9(null);
5550
+ const [content, setContent] = useState9([]);
4654
5551
  const tagsKey = config.contentTags?.join(",");
4655
5552
  useEffect12(() => {
4656
5553
  if (!config.showRecentMessages) return;
@@ -4672,49 +5569,49 @@ function HomeRoot(props2) {
4672
5569
  const avatars = config.userAvatars ?? [];
4673
5570
  const status = config.status;
4674
5571
  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" })
5572
+ return /* @__PURE__ */ jsx30("div", { class: `${p25}-module ${p25}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-scroll`, children: [
5573
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero`, children: [
5574
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-top`, children: [
5575
+ 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" }),
5576
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-actions`, children: [
5577
+ 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,
5578
+ /* @__PURE__ */ jsx30(HeaderActions, { panelProps, variant: "plain" })
4682
5579
  ] })
4683
5580
  ] }),
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
5581
+ config.showGreeting !== false ? /* @__PURE__ */ jsxs24(Fragment5, { children: [
5582
+ /* @__PURE__ */ jsx30("h1", { class: `${p25}-home-greeting`, "data-testid": TID.homeGreeting, children: greeting.title }),
5583
+ greeting.subtitle ? /* @__PURE__ */ jsx30("p", { class: `${p25}-home-lead`, children: greeting.subtitle }) : null
4687
5584
  ] }) : null
4688
5585
  ] }),
4689
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-cards`, children: [
4690
- config.showSearchBar !== false ? /* @__PURE__ */ jsx26(
5586
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-cards`, children: [
5587
+ config.showSearchBar !== false ? /* @__PURE__ */ jsx30(
4691
5588
  HomeSearchButton,
4692
5589
  {
4693
5590
  placeholder: strings.homeSearchPlaceholder,
4694
5591
  onActivate: () => nav.switchToLayout("help")
4695
5592
  }
4696
5593
  ) : 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
5594
+ 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: [
5595
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-avatar`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(BubblesIcon, {}) }),
5596
+ /* @__PURE__ */ jsxs24("span", { class: `${p25}-home-recent-body`, children: [
5597
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-title`, children: recent.title }),
5598
+ recent.preview ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-preview`, children: recent.preview }) : null
4702
5599
  ] }),
4703
- (recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-dot`, "aria-label": "Unread" }) : null
5600
+ (recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-dot`, "aria-label": "Unread" }) : null
4704
5601
  ] }) }) : null,
4705
- status ? /* @__PURE__ */ jsx26(
5602
+ status ? /* @__PURE__ */ jsx30(
4706
5603
  HomeCard,
4707
5604
  {
4708
5605
  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 })
5606
+ children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-status`, "data-level": status.level ?? "operational", children: [
5607
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(StatusOkIcon, {}) }),
5608
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-text`, children: status.text })
4712
5609
  ] })
4713
5610
  }
4714
5611
  ) : 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(
5612
+ content.length > 0 ? /* @__PURE__ */ jsxs24("section", { class: `${p25}-home-content`, children: [
5613
+ /* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-title`, children: contentTitle }),
5614
+ /* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-list`, children: content.map((item) => /* @__PURE__ */ jsx30(
4718
5615
  ListRow,
4719
5616
  {
4720
5617
  title: item.title,
@@ -4730,20 +5627,20 @@ function HomeRoot(props2) {
4730
5627
  }
4731
5628
  var homeLayout = {
4732
5629
  Icon: HomeIcon,
4733
- Root: (props2) => /* @__PURE__ */ jsx26(HomeRoot, { ...props2 })
5630
+ Root: (props2) => /* @__PURE__ */ jsx30(HomeRoot, { ...props2 })
4734
5631
  };
4735
5632
 
4736
5633
  // 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;
5634
+ import { useEffect as useEffect13, useState as useState10 } from "preact/hooks";
5635
+ import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
5636
+ var p26 = BRAND.cssPrefix;
4740
5637
  var log14 = logger.scope("news");
4741
5638
  function NewsRoot({ transport, strings, config, nav, panelProps }) {
4742
5639
  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);
5640
+ const [state, setState] = useState10("loading");
5641
+ const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
5642
+ const [items, setItems] = useState10([]);
5643
+ const [reloadKey, setReloadKey] = useState10(0);
4747
5644
  useEffect13(() => {
4748
5645
  let cancelled = false;
4749
5646
  setState("loading");
@@ -4762,38 +5659,38 @@ function NewsRoot({ transport, strings, config, nav, panelProps }) {
4762
5659
  };
4763
5660
  }, [transport, tags, reloadKey]);
4764
5661
  function renderBody() {
4765
- if (state === "loading") return /* @__PURE__ */ jsx27(ModuleState, { message: strings.newsLoading, strings });
5662
+ if (state === "loading") return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsLoading, strings });
4766
5663
  if (state === "error") {
4767
- return /* @__PURE__ */ jsx27(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
5664
+ return /* @__PURE__ */ jsx31(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
4768
5665
  }
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(
5666
+ if (items.length === 0) return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsEmpty, strings });
5667
+ return /* @__PURE__ */ jsx31("div", { class: `${p26}-news-list`, children: items.map((item) => /* @__PURE__ */ jsxs25(
4771
5668
  "button",
4772
5669
  {
4773
5670
  type: "button",
4774
- class: `${p22}-news-card`,
5671
+ class: `${p26}-news-card`,
4775
5672
  onClick: () => nav.push({ kind: "content", id: item.id, title: item.title }),
4776
5673
  "data-testid": tid(TID.newsItem, item.id),
4777
5674
  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
5675
+ item.image ? /* @__PURE__ */ jsx31("img", { class: `${p26}-news-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
5676
+ /* @__PURE__ */ jsxs25("span", { class: `${p26}-news-body`, children: [
5677
+ 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,
5678
+ /* @__PURE__ */ jsx31("span", { class: `${p26}-news-title`, children: item.title }),
5679
+ item.description ? /* @__PURE__ */ jsx31("span", { class: `${p26}-news-summary`, children: item.description }) : null
4783
5680
  ] })
4784
5681
  ]
4785
5682
  },
4786
5683
  item.id
4787
5684
  )) });
4788
5685
  }
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() })
5686
+ return /* @__PURE__ */ jsxs25("div", { class: `${p26}-module`, children: [
5687
+ /* @__PURE__ */ jsx31(TitleBar, { title: strings.newsTitle, actions: /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" }) }),
5688
+ /* @__PURE__ */ jsx31("div", { class: `${p26}-module-scroll`, children: renderBody() })
4792
5689
  ] });
4793
5690
  }
4794
5691
  var newsLayout = {
4795
5692
  Icon: NewsIcon,
4796
- Root: (props2) => /* @__PURE__ */ jsx27(NewsRoot, { ...props2 })
5693
+ Root: (props2) => /* @__PURE__ */ jsx31(NewsRoot, { ...props2 })
4797
5694
  };
4798
5695
 
4799
5696
  // src/ui/modules/registry.ts
@@ -4805,28 +5702,28 @@ var LAYOUTS = {
4805
5702
  };
4806
5703
 
4807
5704
  // src/ui/home-tab-bar.tsx
4808
- import { jsx as jsx28, jsxs as jsxs22 } from "preact/jsx-runtime";
4809
- var p23 = BRAND.cssPrefix;
5705
+ import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
5706
+ var p27 = BRAND.cssPrefix;
4810
5707
  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) => {
5708
+ return /* @__PURE__ */ jsx32("nav", { class: `${p27}-tabbar`, role: "tablist", "aria-label": strings.panelTitle, children: modules.map((m) => {
4812
5709
  const Icon = LAYOUTS[m.layout].Icon;
4813
5710
  const selected = m.id === activeTab;
4814
5711
  const badge = m.layout === "chat" && unreadCount > 0 ? unreadCount > 9 ? "9+" : String(unreadCount) : null;
4815
- return /* @__PURE__ */ jsxs22(
5712
+ return /* @__PURE__ */ jsxs26(
4816
5713
  "button",
4817
5714
  {
4818
5715
  type: "button",
4819
5716
  role: "tab",
4820
5717
  "aria-selected": selected,
4821
- class: `${p23}-tab`,
5718
+ class: `${p27}-tab`,
4822
5719
  onClick: () => onSelect(m.id),
4823
5720
  "data-testid": tid(TID.tab, m.id),
4824
5721
  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
5722
+ /* @__PURE__ */ jsxs26("span", { class: `${p27}-tab-icon`, "aria-hidden": "true", children: [
5723
+ /* @__PURE__ */ jsx32(Icon, {}),
5724
+ badge ? /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
4828
5725
  ] }),
4829
- /* @__PURE__ */ jsx28("span", { class: `${p23}-tab-label`, children: moduleLabel(strings, m.label) })
5726
+ /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-label`, children: moduleLabel(strings, m.label) })
4830
5727
  ]
4831
5728
  },
4832
5729
  m.id
@@ -4835,12 +5732,12 @@ function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
4835
5732
  }
4836
5733
 
4837
5734
  // src/ui/iframe-view.tsx
4838
- import { jsx as jsx29, jsxs as jsxs23 } from "preact/jsx-runtime";
4839
- var p24 = BRAND.cssPrefix;
5735
+ import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
5736
+ var p28 = BRAND.cssPrefix;
4840
5737
  var SANDBOX = "allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads";
4841
5738
  function IframeView({ url, title, strings, onBack, actions }) {
4842
- return /* @__PURE__ */ jsxs23("div", { class: `${p24}-module`, children: [
4843
- /* @__PURE__ */ jsx29(
5739
+ return /* @__PURE__ */ jsxs27("div", { class: `${p28}-module`, children: [
5740
+ /* @__PURE__ */ jsx33(
4844
5741
  BackHeader,
4845
5742
  {
4846
5743
  title: title || strings.moduleBack,
@@ -4849,10 +5746,10 @@ function IframeView({ url, title, strings, onBack, actions }) {
4849
5746
  actions
4850
5747
  }
4851
5748
  ),
4852
- /* @__PURE__ */ jsx29(
5749
+ /* @__PURE__ */ jsx33(
4853
5750
  "iframe",
4854
5751
  {
4855
- class: `${p24}-content-frame`,
5752
+ class: `${p28}-content-frame`,
4856
5753
  src: url,
4857
5754
  title: title || "content",
4858
5755
  sandbox: SANDBOX,
@@ -4865,14 +5762,14 @@ function IframeView({ url, title, strings, onBack, actions }) {
4865
5762
  }
4866
5763
 
4867
5764
  // 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;
5765
+ import { useCallback as useCallback3, useEffect as useEffect14, useState as useState11 } from "preact/hooks";
5766
+ import { jsx as jsx34, jsxs as jsxs28 } from "preact/jsx-runtime";
5767
+ var p29 = BRAND.cssPrefix;
4871
5768
  var log15 = logger.scope("content");
4872
5769
  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);
5770
+ const [item, setItem] = useState11(null);
5771
+ const [failed, setFailed] = useState11(false);
5772
+ const [reloadKey, setReloadKey] = useState11(0);
4876
5773
  const retry = useCallback3(() => {
4877
5774
  setFailed(false);
4878
5775
  setItem(null);
@@ -4895,17 +5792,17 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
4895
5792
  };
4896
5793
  }, [transport, id, reloadKey]);
4897
5794
  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 ?? "" })
5795
+ if (failed) return /* @__PURE__ */ jsx34(ModuleState, { tone: "error", message: strings.errorGeneric, onRetry: retry, strings });
5796
+ if (item === null) return /* @__PURE__ */ jsx34(ModuleState, { message: strings.contentLoading, strings });
5797
+ return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
5798
+ item.image ? /* @__PURE__ */ jsx34("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
5799
+ item.description ? /* @__PURE__ */ jsx34("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
5800
+ 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,
5801
+ /* @__PURE__ */ jsx34(StaticMarkdown, { text: item.content ?? "" })
4905
5802
  ] });
4906
5803
  }
4907
- return /* @__PURE__ */ jsxs24("div", { class: `${p25}-module`, children: [
4908
- /* @__PURE__ */ jsx30(
5804
+ return /* @__PURE__ */ jsxs28("div", { class: `${p29}-module`, children: [
5805
+ /* @__PURE__ */ jsx34(
4909
5806
  BackHeader,
4910
5807
  {
4911
5808
  title: item?.title || title || strings.moduleBack,
@@ -4915,13 +5812,13 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
4915
5812
  testid: TID.backHeader
4916
5813
  }
4917
5814
  ),
4918
- /* @__PURE__ */ jsx30("div", { class: `${p25}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
5815
+ /* @__PURE__ */ jsx34("div", { class: `${p29}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
4919
5816
  ] });
4920
5817
  }
4921
5818
 
4922
5819
  // src/ui/messenger-home.tsx
4923
- import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
4924
- var p26 = BRAND.cssPrefix;
5820
+ import { jsx as jsx35, jsxs as jsxs29 } from "preact/jsx-runtime";
5821
+ var p30 = BRAND.cssPrefix;
4925
5822
  function MessengerHome({
4926
5823
  panelProps,
4927
5824
  enabledModules,
@@ -4953,7 +5850,7 @@ function MessengerHome({
4953
5850
  }, []);
4954
5851
  const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
4955
5852
  useDragMove(containerRef.current, options.mode === "modal");
4956
- const navState = useComputed4(() => nav.sig.value).value;
5853
+ const navState = useComputed6(() => nav.sig.value).value;
4957
5854
  const top = topScreen(navState);
4958
5855
  const activeModule = options.modules.byId[navState.activeTab];
4959
5856
  const isReader = top?.kind === "iframe" || top?.kind === "content";
@@ -4989,12 +5886,12 @@ function MessengerHome({
4989
5886
  nav: moduleNav,
4990
5887
  panelProps
4991
5888
  });
4992
- const plainActions = /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" });
5889
+ const plainActions = /* @__PURE__ */ jsx35(HeaderActions, { panelProps, variant: "plain" });
4993
5890
  let body;
4994
5891
  if (top?.kind === "iframe") {
4995
- body = /* @__PURE__ */ jsx31(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
5892
+ body = /* @__PURE__ */ jsx35(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
4996
5893
  } else if (top?.kind === "content") {
4997
- body = /* @__PURE__ */ jsx31(
5894
+ body = /* @__PURE__ */ jsx35(
4998
5895
  ContentView,
4999
5896
  {
5000
5897
  id: top.id,
@@ -5006,7 +5903,7 @@ function MessengerHome({
5006
5903
  }
5007
5904
  );
5008
5905
  } else if (activeModule?.layout === "chat") {
5009
- body = /* @__PURE__ */ jsx31(
5906
+ body = /* @__PURE__ */ jsx35(
5010
5907
  PanelContent,
5011
5908
  {
5012
5909
  ...panelProps,
@@ -5017,23 +5914,23 @@ function MessengerHome({
5017
5914
  );
5018
5915
  } else if (activeModule) {
5019
5916
  const Root = LAYOUTS[activeModule.layout].Root;
5020
- body = Root ? /* @__PURE__ */ jsx31(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
5917
+ body = Root ? /* @__PURE__ */ jsx35(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
5021
5918
  } else {
5022
5919
  body = null;
5023
5920
  }
5024
- return /* @__PURE__ */ jsxs25(
5921
+ return /* @__PURE__ */ jsxs29(
5025
5922
  "div",
5026
5923
  {
5027
5924
  ref: containerRef,
5028
- class: `${p26}-panel ${p26}-messenger`,
5925
+ class: `${p30}-panel ${p30}-messenger`,
5029
5926
  role: "dialog",
5030
5927
  "aria-modal": "false",
5031
5928
  "aria-label": strings.panelTitle,
5032
5929
  style: { position: "relative" },
5033
5930
  "data-testid": TID.messengerHome,
5034
5931
  children: [
5035
- /* @__PURE__ */ jsx31("div", { class: `${p26}-messenger-body`, children: body }),
5036
- showTabBar ? /* @__PURE__ */ jsx31(
5932
+ /* @__PURE__ */ jsx35("div", { class: `${p30}-messenger-body`, children: body }),
5933
+ showTabBar ? /* @__PURE__ */ jsx35(
5037
5934
  HomeTabBar,
5038
5935
  {
5039
5936
  modules: enabledModules,
@@ -5043,8 +5940,8 @@ function MessengerHome({
5043
5940
  onSelect: nav.switchTab
5044
5941
  }
5045
5942
  ) : null,
5046
- /* @__PURE__ */ jsx31(PoweredByBar, { poweredBy: options.poweredBy }),
5047
- options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx31(
5943
+ /* @__PURE__ */ jsx35(PoweredByBar, { poweredBy: options.poweredBy }),
5944
+ options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx35(
5048
5945
  ResizeGrip,
5049
5946
  {
5050
5947
  panelEl: containerRef.current,
@@ -5061,29 +5958,29 @@ function MessengerHome({
5061
5958
  }
5062
5959
 
5063
5960
  // src/ui/modules-empty.tsx
5064
- import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
5065
- var p27 = BRAND.cssPrefix;
5961
+ import { jsx as jsx36, jsxs as jsxs30 } from "preact/jsx-runtime";
5962
+ var p31 = BRAND.cssPrefix;
5066
5963
  function ModulesEmpty({ strings, onClose }) {
5067
- return /* @__PURE__ */ jsxs26(
5964
+ return /* @__PURE__ */ jsxs30(
5068
5965
  "div",
5069
5966
  {
5070
- class: `${p27}-panel ${p27}-modules-empty`,
5967
+ class: `${p31}-panel ${p31}-modules-empty`,
5071
5968
  role: "dialog",
5072
5969
  "aria-label": strings.panelTitle,
5073
5970
  "data-testid": TID.modulesEmpty,
5074
5971
  children: [
5075
- onClose ? /* @__PURE__ */ jsx32(
5972
+ onClose ? /* @__PURE__ */ jsx36(
5076
5973
  "button",
5077
5974
  {
5078
5975
  type: "button",
5079
- class: `${p27}-icon-btn ${p27}-modules-empty-close`,
5976
+ class: `${p31}-icon-btn ${p31}-modules-empty-close`,
5080
5977
  onClick: onClose,
5081
5978
  "aria-label": strings.close,
5082
5979
  title: strings.close,
5083
- children: /* @__PURE__ */ jsx32(CloseIcon, {})
5980
+ children: /* @__PURE__ */ jsx36(CloseIcon, {})
5084
5981
  }
5085
5982
  ) : null,
5086
- /* @__PURE__ */ jsx32("p", { class: `${p27}-modules-empty-text`, children: strings.modulesEmpty })
5983
+ /* @__PURE__ */ jsx36("p", { class: `${p31}-modules-empty-text`, children: strings.modulesEmpty })
5087
5984
  ]
5088
5985
  }
5089
5986
  );
@@ -5138,11 +6035,11 @@ function animateTypewriter(msg, text, charsPerSecond, abort) {
5138
6035
  }
5139
6036
 
5140
6037
  // src/ui/use-launcher-callout.ts
5141
- import { useCallback as useCallback5, useEffect as useEffect16, useState as useState11 } from "preact/hooks";
6038
+ import { useCallback as useCallback5, useEffect as useEffect16, useState as useState12 } from "preact/hooks";
5142
6039
  function useLauncherCallout({ callout, persistence }) {
5143
6040
  const textKey = callout?.text ?? "";
5144
6041
  const persistent = callout?.persistent ?? true;
5145
- const [dismissed, setDismissed] = useState11(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
6042
+ const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
5146
6043
  useEffect16(() => {
5147
6044
  setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
5148
6045
  }, [textKey, persistent, persistence]);
@@ -5154,21 +6051,21 @@ function useLauncherCallout({ callout, persistence }) {
5154
6051
  }
5155
6052
 
5156
6053
  // src/ui/app.tsx
5157
- import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
6054
+ import { jsx as jsx37, jsxs as jsxs31 } from "preact/jsx-runtime";
5158
6055
  var log16 = logger.scope("app");
5159
- var p28 = BRAND.cssPrefix;
6056
+ var p32 = BRAND.cssPrefix;
5160
6057
  function App({ options, hostElement, bus }) {
5161
- const [persistence] = useState12(() => createPersistence(options.widgetId, options.storage));
5162
- const [visitorId, setVisitorId] = useState12(() => persistence.getVisitorId());
6058
+ const [persistence] = useState13(() => createPersistence(options.widgetId, options.storage));
6059
+ const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
5163
6060
  const initialSettings = persistence.loadUserPrefs();
5164
- const [activeLocale, setActiveLocale] = useState12(() => initialSettings.locale ?? options.locale);
5165
- const [activeThemeMode, setActiveThemeMode] = useState12(
6061
+ const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
6062
+ const [activeThemeMode, setActiveThemeMode] = useState13(
5166
6063
  () => initialSettings.themeMode ?? options.themeMode
5167
6064
  );
5168
- const sessionIdSig = useSignal(persistence.loadSessionId());
5169
- const messagesSig = useSignal([]);
5170
- const unreadCountSig = useSignal(0);
5171
- const [loadingMessages, setLoadingMessages] = useState12(false);
6065
+ const sessionIdSig = useSignal2(persistence.loadSessionId());
6066
+ const messagesSig = useSignal2([]);
6067
+ const unreadCountSig = useSignal2(0);
6068
+ const [loadingMessages, setLoadingMessages] = useState13(false);
5172
6069
  function landingTab() {
5173
6070
  const list = options.modules.list;
5174
6071
  const ids = new Set(list.map((m) => m.id));
@@ -5187,14 +6084,14 @@ function App({ options, hostElement, bus }) {
5187
6084
  const homeNav = homeNavRef.current;
5188
6085
  const chatTabIdRef = useRef8(void 0);
5189
6086
  chatTabIdRef.current = chatTabId();
5190
- const [sessionReady, setSessionReady] = useState12(false);
6087
+ const [sessionReady, setSessionReady] = useState13(false);
5191
6088
  const isInlineLike = options.mode === "standalone" || options.mode === "inline";
5192
6089
  const initialPanelRef = useRef8(
5193
6090
  resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
5194
6091
  );
5195
- const [isOpen, setIsOpen] = useState12(initialPanelRef.current.panelOpen);
6092
+ const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
5196
6093
  const initialPanelApplied = useRef8(false);
5197
- const [launcherLeaving, setLauncherLeaving] = useState12(false);
6094
+ const [launcherLeaving, setLauncherLeaving] = useState13(false);
5198
6095
  const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
5199
6096
  callout: options.launcher.callout,
5200
6097
  persistence
@@ -5205,19 +6102,20 @@ function App({ options, hostElement, bus }) {
5205
6102
  bus.emit("calloutDismiss", void 0);
5206
6103
  dismissCalloutRaw();
5207
6104
  }, [bus, dismissCalloutRaw]);
5208
- const [panelSize, setPanelSize] = useState12(initialPanelRef.current.panelSize);
6105
+ const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
5209
6106
  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);
6107
+ const [view, setView] = useState13("chat");
6108
+ const [canSend, setCanSend] = useState13(true);
6109
+ const [streaming, setStreaming] = useState13(false);
6110
+ const [agent, setAgent] = useState13(null);
6111
+ const [suggestions, setSuggestions] = useState13([]);
6112
+ const [activeCancel, setActiveCancel] = useState13(null);
5216
6113
  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(
6114
+ const [parsedSite, setParsedSite] = useState13(void 0);
6115
+ const [parsedBlocks, setParsedBlocks] = useState13(void 0);
6116
+ const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
6117
+ const [intakeValues, setIntakeValues] = useState13(() => persistence.loadIntake());
6118
+ const [transport] = useState13(
5221
6119
  () => new AgentTransport({
5222
6120
  baseUrl: options.baseUrl,
5223
6121
  auth: createAuth({
@@ -5228,8 +6126,8 @@ function App({ options, hostElement, bus }) {
5228
6126
  endpoints: options.endpoints
5229
6127
  })
5230
6128
  );
5231
- const [reducer] = useState12(() => new StreamReducer(messagesSig));
5232
- const [feedback] = useState12(() => new FeedbackBus(options.sound, options.haptics));
6129
+ const [reducer] = useState13(() => new StreamReducer(messagesSig));
6130
+ const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
5233
6131
  const patchAndSync = useCallback6(
5234
6132
  (patch) => {
5235
6133
  persistence.patchUserPrefs(patch);
@@ -5399,9 +6297,11 @@ function App({ options, hostElement, bus }) {
5399
6297
  );
5400
6298
  const userSig = JSON.stringify(options.userContext ?? null);
5401
6299
  const pageSig = JSON.stringify(options.pageContext ?? null);
6300
+ const intakeSig = JSON.stringify(intakeValues ?? null);
5402
6301
  useEffect17(() => {
5403
- transport.setContext(options.userContext, toWirePageContext(options.pageContext));
5404
- }, [transport, userSig, pageSig]);
6302
+ const merged = intakeValues ? { ...intakeValues, ...options.userContext } : options.userContext;
6303
+ transport.setContext(merged, toWirePageContext(options.pageContext));
6304
+ }, [transport, userSig, pageSig, intakeSig]);
5405
6305
  const runResume = useCallback6(
5406
6306
  async (handle) => {
5407
6307
  let bubble = null;
@@ -5489,24 +6389,8 @@ function App({ options, hostElement, bus }) {
5489
6389
  document.addEventListener("keydown", onKey);
5490
6390
  return () => document.removeEventListener("keydown", onKey);
5491
6391
  }, [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);
6392
+ const streamAssistant = useCallback6(
6393
+ async (assistantMsg, trigger) => {
5510
6394
  const activeSessionId = sessionIdSig.value ?? uuid7();
5511
6395
  if (!sessionIdSig.value) {
5512
6396
  sessionIdSig.value = activeSessionId;
@@ -5515,10 +6399,10 @@ function App({ options, hostElement, bus }) {
5515
6399
  const body = buildSendMessageRequest({
5516
6400
  messages: messagesSig.value.slice(0, -1).map(fromReactive),
5517
6401
  sessionId: activeSessionId,
5518
- // textModel + imageModel are backend-only — selected per
5519
- // deployment in the dashboard, never passed up by the widget.
6402
+ // textModel + imageModel are backend-only — selected per deployment.
5520
6403
  tools: options.features.tools,
5521
6404
  responseMode: options.responseMode,
6405
+ trigger,
5522
6406
  // Identity + preferences ride on every message — server may need
5523
6407
  // them to route, persist, or reconcile in-flight.
5524
6408
  visitorId,
@@ -5550,19 +6434,95 @@ function App({ options, hostElement, bus }) {
5550
6434
  messagesSig.value = [...messagesSig.value];
5551
6435
  }
5552
6436
  },
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
- ]
6437
+ [transport, reducer, messagesSig, sessionIdSig, options, bus, feedback, persistence, visitorId]
6438
+ );
6439
+ const resolveTool = useCallback6(
6440
+ (toolCallId, trigger, mutate) => {
6441
+ if (streaming) return;
6442
+ const last = messagesSig.value.at(-1);
6443
+ const part = last?.partsSig.value.find(
6444
+ (pt) => pt.kind === "tool" && pt.toolCallId === toolCallId
6445
+ );
6446
+ if (!part) {
6447
+ log16.warn("resolveTool: tool part not found", { toolCallId });
6448
+ return;
6449
+ }
6450
+ mutate(part);
6451
+ if (last) last.partsSig.value = [...last.partsSig.value];
6452
+ const assistantMsg = makeAssistantMessage();
6453
+ messagesSig.value = [...messagesSig.value, assistantMsg];
6454
+ reducer.attach(assistantMsg);
6455
+ void streamAssistant(assistantMsg, trigger);
6456
+ },
6457
+ [streaming, messagesSig, reducer, streamAssistant]
6458
+ );
6459
+ const handleToolResult = useCallback6(
6460
+ (toolCallId, output) => {
6461
+ log16.info("toolResult", { toolCallId });
6462
+ bus.emit("toolResult", { toolCallId });
6463
+ resolveTool(toolCallId, TRIGGER.toolResult, (part) => {
6464
+ part.outputSig.value = output;
6465
+ part.stateSig.value = "output";
6466
+ });
6467
+ },
6468
+ [bus, resolveTool]
6469
+ );
6470
+ const handleToolDecision = useCallback6(
6471
+ (toolCallId, approved, reason) => {
6472
+ log16.info("toolDecision", { toolCallId, approved });
6473
+ bus.emit("toolDecision", { toolCallId, approved });
6474
+ resolveTool(toolCallId, TRIGGER.toolApproval, (part) => {
6475
+ const id = part.approvalSig.value?.id ?? toolCallId;
6476
+ part.approvalSig.value = { id, approved, reason };
6477
+ part.stateSig.value = "output";
6478
+ });
6479
+ },
6480
+ [bus, resolveTool]
6481
+ );
6482
+ const toolInteraction = useMemo3(
6483
+ () => ({ humanInLoop: options.features.humanInLoop, onResult: handleToolResult, onDecision: handleToolDecision }),
6484
+ [options.features.humanInLoop, handleToolResult, handleToolDecision]
6485
+ );
6486
+ const intakePending = options.intake.enabled && intakeValues === null;
6487
+ const handleIntakeComplete = useCallback6(
6488
+ (values) => {
6489
+ const hasValues = Object.keys(values).length > 0;
6490
+ log16.info("intakeComplete", { fields: Object.keys(values).length, skipped: !hasValues });
6491
+ persistence.saveIntake(values);
6492
+ setIntakeValues(values);
6493
+ bus.emit("intakeSubmit", values);
6494
+ if (!hasValues) return;
6495
+ const activeSessionId = sessionIdSig.value ?? uuid7();
6496
+ if (!sessionIdSig.value) {
6497
+ sessionIdSig.value = activeSessionId;
6498
+ persistence.saveSessionId(activeSessionId);
6499
+ transport.primeIdentity(void 0, activeSessionId);
6500
+ }
6501
+ void transport.submitIntake(activeSessionId, values);
6502
+ },
6503
+ [persistence, bus, sessionIdSig, transport]
6504
+ );
6505
+ const handleSend = useCallback6(
6506
+ async (text, attachments) => {
6507
+ log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
6508
+ if (streaming) return;
6509
+ bus.emit("send", { text, attachmentCount: attachments.length });
6510
+ if (suggestions.length > 0) setSuggestions([]);
6511
+ const uploaded = await uploadAttachments(transport, attachments, (err) => {
6512
+ log16.warn("upload failed", { err });
6513
+ bus.emit("error", err);
6514
+ options.onError?.(err);
6515
+ });
6516
+ feedback.unlock();
6517
+ feedback.play("messageSent");
6518
+ const userMsg = makeUserMessage(text, uploaded);
6519
+ const assistantMsg = makeAssistantMessage();
6520
+ messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
6521
+ reducer.attach(assistantMsg);
6522
+ emitMessage(bus, options, "user", text);
6523
+ await streamAssistant(assistantMsg, TRIGGER.submitMessage);
6524
+ },
6525
+ [streaming, transport, bus, options, suggestions.length, messagesSig, reducer, streamAssistant]
5566
6526
  );
5567
6527
  const handleStop = useCallback6(() => {
5568
6528
  log16.info("stop");
@@ -5766,7 +6726,10 @@ function App({ options, hostElement, bus }) {
5766
6726
  log16.info("suggestion", { text });
5767
6727
  bus.emit("suggestion", { text });
5768
6728
  void handleSend(text, []);
5769
- }
6729
+ },
6730
+ intakePending,
6731
+ onIntakeComplete: handleIntakeComplete,
6732
+ tool: toolInteraction
5770
6733
  };
5771
6734
  const onSelectSession = (sessionId) => {
5772
6735
  void handleSelectHistoryChat(sessionId);
@@ -5778,12 +6741,12 @@ function App({ options, hostElement, bus }) {
5778
6741
  const renderSurface = (size) => {
5779
6742
  const closeable = isActionVisible("close", effectiveOptions.mode, size);
5780
6743
  if (enabledModules.length === 0) {
5781
- return /* @__PURE__ */ jsx33(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
6744
+ return /* @__PURE__ */ jsx37(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
5782
6745
  }
5783
6746
  if (enabledModules.length === 1 && enabledModules[0]?.layout === "chat") {
5784
- return /* @__PURE__ */ jsx33(Panel, { ...panelProps, panelSize: size });
6747
+ return /* @__PURE__ */ jsx37(Panel, { ...panelProps, panelSize: size });
5785
6748
  }
5786
- return /* @__PURE__ */ jsx33(
6749
+ return /* @__PURE__ */ jsx37(
5787
6750
  MessengerHome,
5788
6751
  {
5789
6752
  panelProps: { ...panelProps, panelSize: size, onClose: closeable ? handleClose : void 0 },
@@ -5801,7 +6764,7 @@ function App({ options, hostElement, bus }) {
5801
6764
  void handleSelectHistoryChat(chat.sessionId);
5802
6765
  };
5803
6766
  const messagesEnabled = enabledModules.some((m) => m.layout === "chat");
5804
- return /* @__PURE__ */ jsx33("div", { class: `${p28}-anchor`, children: /* @__PURE__ */ jsx33(
6767
+ return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: /* @__PURE__ */ jsx37(
5805
6768
  PageShell,
5806
6769
  {
5807
6770
  site: parsedSite,
@@ -5820,15 +6783,15 @@ function App({ options, hostElement, bus }) {
5820
6783
  }
5821
6784
  if (isInlineLike) {
5822
6785
  const inlineSize = options.mode === "standalone" ? "fullscreen" : panelSize;
5823
- return /* @__PURE__ */ jsx33("div", { class: `${p28}-anchor`, children: renderSurface(inlineSize) });
6786
+ return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: renderSurface(inlineSize) });
5824
6787
  }
5825
6788
  const drawerEdgeTab = options.mode === "drawer";
5826
6789
  const triggerOwnedByPage = options.mode === "modal";
5827
6790
  const launcherVisible = !triggerOwnedByPage && !options.launcher.hidden && (!isOpen || launcherLeaving);
5828
6791
  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: [
6792
+ return /* @__PURE__ */ jsxs31("div", { class: `${p32}-anchor`, "data-launcher-size": effectiveOptions.launcher.size, children: [
5830
6793
  isOpen ? renderSurface(panelSize) : null,
5831
- launcherVisible ? /* @__PURE__ */ jsx33(
6794
+ launcherVisible ? /* @__PURE__ */ jsx37(
5832
6795
  Launcher,
5833
6796
  {
5834
6797
  onToggle: handleOpen,
@@ -5838,7 +6801,7 @@ function App({ options, hostElement, bus }) {
5838
6801
  edgeTab: drawerEdgeTab
5839
6802
  }
5840
6803
  ) : null,
5841
- calloutToRender ? /* @__PURE__ */ jsx33(
6804
+ calloutToRender ? /* @__PURE__ */ jsx37(
5842
6805
  LauncherCallout,
5843
6806
  {
5844
6807
  callout: calloutToRender,