@helpai/elements 0.12.3 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.mjs CHANGED
@@ -6,8 +6,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6
6
  import { h, render } 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
  };
@@ -308,11 +447,14 @@ var DEFAULT_ATTACHMENTS = {
308
447
  var DEFAULT_WELCOME = { animation: "typewriter", speed: 60 };
309
448
  var DEFAULT_FEATURES = {
310
449
  files: true,
311
- voice: "local"
450
+ voice: "local",
451
+ humanInLoop: true
312
452
  };
453
+ var DEFAULT_INTAKE = { enabled: false, fields: [], skippable: false };
313
454
  var DEFAULT_ENDPOINTS = {
314
455
  upload: "/ai/agent/upload-file",
315
- transcribe: "/ai/agent/transcribe-audio"
456
+ transcribe: "/ai/agent/transcribe-audio",
457
+ intake: "/ai/agent/intake"
316
458
  };
317
459
  var DEFAULT_LAUNCHER = {
318
460
  variant: "circle",
@@ -374,11 +516,14 @@ function resolveOptions(rawOpts) {
374
516
  features: {
375
517
  files: opts.features?.files ?? DEFAULT_FEATURES.files,
376
518
  voice: opts.features?.voice ?? DEFAULT_FEATURES.voice,
519
+ humanInLoop: opts.features?.humanInLoop ?? DEFAULT_FEATURES.humanInLoop,
377
520
  tools: opts.features?.tools
378
521
  },
522
+ intake: resolveIntake(opts.intake),
379
523
  endpoints: {
380
524
  upload: opts.endpoints?.upload ?? DEFAULT_ENDPOINTS.upload,
381
- transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe
525
+ transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe,
526
+ intake: opts.endpoints?.intake ?? DEFAULT_ENDPOINTS.intake
382
527
  },
383
528
  attachments: {
384
529
  accept: opts.composer?.attachments?.accept ?? DEFAULT_ATTACHMENTS.accept,
@@ -477,6 +622,18 @@ function resolveModules(overrides) {
477
622
  const byId = Object.fromEntries(list.map((m) => [m.id, m]));
478
623
  return { list, byId };
479
624
  }
625
+ function resolveIntake(overrides) {
626
+ const fields = (overrides?.fields ?? []).filter((f) => Boolean(f && f.name && f.label && f.type));
627
+ if (fields.length === 0) return DEFAULT_INTAKE;
628
+ return {
629
+ enabled: overrides?.enabled ?? false,
630
+ title: overrides?.title,
631
+ description: overrides?.description,
632
+ fields,
633
+ submitLabel: overrides?.submitLabel,
634
+ skippable: overrides?.skippable ?? false
635
+ };
636
+ }
480
637
  function resolveLauncher(overrides) {
481
638
  const callout = overrides?.callout?.text ? {
482
639
  shape: "pill",
@@ -522,6 +679,7 @@ var SECTION_KEYS = [
522
679
  "i18n",
523
680
  "footer",
524
681
  "features",
682
+ "intake",
525
683
  "endpoints"
526
684
  ];
527
685
  function mergeServerConfig(user, server) {
@@ -712,7 +870,7 @@ var tokens_default = ':host{--__P__-accent: __BRAND_ACCENT__;--__P__-accent-text
712
870
  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';
713
871
 
714
872
  // src/styles/panel.css
715
- 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';
873
+ 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';
716
874
 
717
875
  // src/styles/standalone.css
718
876
  var standalone_default = ".__P__-standalone-page{margin:0;height:100vh;background:var(--__P__-bg, #fff);display:grid;place-items:stretch}\n";
@@ -800,22 +958,22 @@ function attachAdoptedSheet(shadow, doc) {
800
958
  }
801
959
  }
802
960
  function applyThemeOverrides(host, overrides) {
803
- const p29 = BRAND.cssPrefix;
804
- if (overrides.accent) host.style.setProperty(`--${p29}-accent`, overrides.accent);
805
- if (overrides.accentText) host.style.setProperty(`--${p29}-accent-text`, overrides.accentText);
806
- if (overrides.radius) host.style.setProperty(`--${p29}-radius`, overrides.radius);
807
- if (overrides.fontFamily) host.style.setProperty(`--${p29}-font`, overrides.fontFamily);
961
+ const p33 = BRAND.cssPrefix;
962
+ if (overrides.accent) host.style.setProperty(`--${p33}-accent`, overrides.accent);
963
+ if (overrides.accentText) host.style.setProperty(`--${p33}-accent-text`, overrides.accentText);
964
+ if (overrides.radius) host.style.setProperty(`--${p33}-radius`, overrides.radius);
965
+ if (overrides.fontFamily) host.style.setProperty(`--${p33}-font`, overrides.fontFamily);
808
966
  }
809
967
  function applyThemeMode(host, mode) {
810
968
  host.dataset.theme = mode;
811
969
  }
812
970
  function applySize(host, size) {
813
- const p29 = BRAND.cssPrefix;
814
- if (size.width !== void 0) host.style.setProperty(`--${p29}-panel-w`, size.width);
815
- if (size.height !== void 0) host.style.setProperty(`--${p29}-panel-h`, size.height);
816
- if (size.expanded?.width !== void 0) host.style.setProperty(`--${p29}-expanded-w`, size.expanded.width);
817
- if (size.expanded?.height !== void 0) host.style.setProperty(`--${p29}-expanded-h`, size.expanded.height);
818
- if (size.inset !== void 0) host.style.setProperty(`--${p29}-panel-inset`, size.inset);
971
+ const p33 = BRAND.cssPrefix;
972
+ if (size.width !== void 0) host.style.setProperty(`--${p33}-panel-w`, size.width);
973
+ if (size.height !== void 0) host.style.setProperty(`--${p33}-panel-h`, size.height);
974
+ if (size.expanded?.width !== void 0) host.style.setProperty(`--${p33}-expanded-w`, size.expanded.width);
975
+ if (size.expanded?.height !== void 0) host.style.setProperty(`--${p33}-expanded-h`, size.expanded.height);
976
+ if (size.inset !== void 0) host.style.setProperty(`--${p33}-panel-inset`, size.inset);
819
977
  }
820
978
  function applyPosition(host, pos) {
821
979
  host.dataset.position = pos;
@@ -986,11 +1144,11 @@ function toBase64Url(json) {
986
1144
  var nonEmpty = (ctx) => ctx && Object.keys(ctx).length > 0 ? ctx : void 0;
987
1145
  function encodeContext(user, page) {
988
1146
  const u = nonEmpty(user);
989
- const p29 = nonEmpty(page);
990
- if (!u && !p29) return void 0;
1147
+ const p33 = nonEmpty(page);
1148
+ if (!u && !p33) return void 0;
991
1149
  const envelope = {};
992
1150
  if (u) envelope.user = u;
993
- if (p29) envelope.page = p29;
1151
+ if (p33) envelope.page = p33;
994
1152
  return toBase64Url(JSON.stringify(envelope));
995
1153
  }
996
1154
 
@@ -1029,7 +1187,15 @@ var DEFAULT_PATHS = {
1029
1187
  markRead: "/ai/agent/mark-read",
1030
1188
  // ── CMS content (unified — Home / Help / News / docs) ─────────────
1031
1189
  /** All widget content via one filtered endpoint. `GET /ai/agent/content?tags=…`. */
1032
- content: "/ai/agent/content"
1190
+ content: "/ai/agent/content",
1191
+ /**
1192
+ * Optional pre-chat intake submission. POST `{ visitorId, sessionId, values,
1193
+ * skipped? }` → record the lead immediately (before/independent of the first
1194
+ * message), keyed by the same visitor + session as the conversation.
1195
+ * Overridable via `endpoints.intake`. Fire-and-forget; 404 on older backends
1196
+ * is ignored.
1197
+ */
1198
+ intake: "/ai/agent/intake"
1033
1199
  };
1034
1200
  var CONTEXT_PARAM = "context";
1035
1201
  function buildSendMessageRequest(params) {
@@ -1053,18 +1219,34 @@ function buildSendMessageRequest(params) {
1053
1219
  if (Object.keys(data).length > 0) body.data = data;
1054
1220
  return body;
1055
1221
  }
1222
+ function isResolvedToolPart(p33) {
1223
+ return p33.state === "output" || p33.state === "error" || p33.approval?.approved !== void 0;
1224
+ }
1056
1225
  function normalizeToolRef(ref) {
1057
1226
  if (typeof ref === "string") return ref ? { code: ref } : null;
1058
1227
  return ref?.code ? ref : null;
1059
1228
  }
1060
1229
  function messageToWireParts(m) {
1061
1230
  const out = [];
1062
- for (const p29 of m.parts) {
1063
- if (p29.kind === "text" && p29.text) {
1064
- out.push({ text: p29.text, type: "text" });
1231
+ for (const p33 of m.parts) {
1232
+ if (p33.kind === "text" && p33.text) {
1233
+ out.push({ text: p33.text, type: "text" });
1065
1234
  }
1066
- if (p29.kind === "file" && p29.url) {
1067
- out.push({ mediaType: p29.mediaType, type: "file", url: p29.url });
1235
+ if (p33.kind === "file" && p33.url) {
1236
+ out.push({ mediaType: p33.mediaType, type: "file", url: p33.url });
1237
+ }
1238
+ if (p33.kind === "tool" && isResolvedToolPart(p33)) {
1239
+ const part = {
1240
+ type: "tool",
1241
+ toolCallId: p33.toolCallId,
1242
+ toolName: p33.toolName,
1243
+ state: p33.state
1244
+ };
1245
+ if (p33.input !== void 0) part.input = p33.input;
1246
+ if (p33.output !== void 0) part.output = p33.output;
1247
+ if (p33.error !== void 0) part.errorText = p33.error;
1248
+ if (p33.approval && p33.approval.approved !== void 0) part.approval = p33.approval;
1249
+ out.push(part);
1068
1250
  }
1069
1251
  }
1070
1252
  for (const a of m.attachments ?? []) {
@@ -1311,6 +1493,25 @@ var AgentTransport = class {
1311
1493
  get transcribePath() {
1312
1494
  return this.opts.endpoints?.transcribe ?? "/ai/agent/transcribe-audio";
1313
1495
  }
1496
+ get intakePath() {
1497
+ return this.opts.endpoints?.intake ?? DEFAULT_PATHS.intake;
1498
+ }
1499
+ /**
1500
+ * Record a completed pre-chat intake form. Fire-and-forget — the lead is
1501
+ * captured even if the visitor never sends a message. `sessionId` is explicit
1502
+ * so the record ties to the conversation that follows; `visitorId` + context
1503
+ * ride the envelope. A failure (e.g. 404 on a backend that doesn't implement
1504
+ * the endpoint) is non-fatal — the values still reach the agent as
1505
+ * `userContext` on the next message, so callers don't await this.
1506
+ */
1507
+ async submitIntake(sessionId, values, skipped = false) {
1508
+ log4.debug("submitIntake \u2192", { sessionId, fields: Object.keys(values).length, skipped });
1509
+ try {
1510
+ await this.postJson(this.intakePath, { sessionId, values, skipped }, "submitIntake");
1511
+ } catch (err) {
1512
+ log4.debug("submitIntake failed (non-fatal)", { err });
1513
+ }
1514
+ }
1314
1515
  sendMessage(body) {
1315
1516
  log4.debug("message \u2192", {
1316
1517
  sessionId: body.sessionId,
@@ -1624,8 +1825,21 @@ function fromWireMessage(w) {
1624
1825
  if (part.type === "file") {
1625
1826
  return { kind: "file", url: part.url, mediaType: part.mediaType };
1626
1827
  }
1828
+ if (part.type === "tool") {
1829
+ return {
1830
+ kind: "tool",
1831
+ toolCallId: part.toolCallId,
1832
+ toolName: part.toolName,
1833
+ inputPartialSig: signal(""),
1834
+ inputSig: signal(part.input),
1835
+ outputSig: signal(part.output),
1836
+ errorSig: signal(part.errorText),
1837
+ stateSig: signal(part.state),
1838
+ approvalSig: signal(part.approval)
1839
+ };
1840
+ }
1627
1841
  return null;
1628
- }).filter((p29) => p29 !== null);
1842
+ }).filter((p33) => p33 !== null);
1629
1843
  return {
1630
1844
  id: w.id,
1631
1845
  role: w.role,
@@ -1655,45 +1869,62 @@ function assistantText(m) {
1655
1869
  }
1656
1870
  return out;
1657
1871
  }
1658
- function partToReactive(p29) {
1659
- if (p29.kind === "text" || p29.kind === "reasoning") {
1660
- return { kind: p29.kind, id: p29.id, textSig: signal(p29.text), doneSig: signal(p29.done) };
1872
+ function partToReactive(p33) {
1873
+ if (p33.kind === "text" || p33.kind === "reasoning") {
1874
+ return { kind: p33.kind, id: p33.id, textSig: signal(p33.text), doneSig: signal(p33.done) };
1661
1875
  }
1662
- if (p29.kind === "tool") {
1876
+ if (p33.kind === "tool") {
1663
1877
  return {
1664
1878
  kind: "tool",
1665
- toolCallId: p29.toolCallId,
1666
- toolName: p29.toolName,
1667
- inputPartialSig: signal(p29.inputPartial),
1668
- inputSig: signal(p29.input),
1669
- outputSig: signal(p29.output),
1670
- errorSig: signal(p29.error),
1671
- stateSig: signal(p29.state)
1879
+ toolCallId: p33.toolCallId,
1880
+ toolName: p33.toolName,
1881
+ inputPartialSig: signal(p33.inputPartial),
1882
+ inputSig: signal(p33.input),
1883
+ outputSig: signal(p33.output),
1884
+ errorSig: signal(p33.error),
1885
+ stateSig: signal(p33.state),
1886
+ approvalSig: signal(p33.approval)
1672
1887
  };
1673
1888
  }
1674
- return p29;
1889
+ return p33;
1675
1890
  }
1676
- function partFromReactive(p29) {
1677
- if (p29.kind === "text" || p29.kind === "reasoning") {
1678
- return { kind: p29.kind, id: p29.id, text: p29.textSig.value, done: p29.doneSig.value };
1891
+ function partFromReactive(p33) {
1892
+ if (p33.kind === "text" || p33.kind === "reasoning") {
1893
+ return { kind: p33.kind, id: p33.id, text: p33.textSig.value, done: p33.doneSig.value };
1679
1894
  }
1680
- if (p29.kind === "tool") {
1895
+ if (p33.kind === "tool") {
1681
1896
  return {
1682
1897
  kind: "tool",
1683
- toolCallId: p29.toolCallId,
1684
- toolName: p29.toolName,
1685
- inputPartial: p29.inputPartialSig.value,
1686
- input: p29.inputSig.value,
1687
- output: p29.outputSig.value,
1688
- error: p29.errorSig.value,
1689
- state: p29.stateSig.value
1898
+ toolCallId: p33.toolCallId,
1899
+ toolName: p33.toolName,
1900
+ inputPartial: p33.inputPartialSig.value,
1901
+ input: p33.inputSig.value,
1902
+ output: p33.outputSig.value,
1903
+ error: p33.errorSig.value,
1904
+ state: p33.stateSig.value,
1905
+ approval: p33.approvalSig.value
1690
1906
  };
1691
1907
  }
1692
- return p29;
1908
+ return p33;
1693
1909
  }
1694
1910
 
1695
1911
  // src/stream/reducer.ts
1696
1912
  import { signal as signal2 } from "@preact/signals";
1913
+
1914
+ // src/stream/constants.ts
1915
+ var ASK_USER_INPUT_TOOL = "tool:ask-user-input";
1916
+ function isAskUserInputTool(toolName) {
1917
+ if (!toolName) return false;
1918
+ const t = toolName.toLowerCase();
1919
+ return t === ASK_USER_INPUT_TOOL || t === "ask-user-input" || t === "ask_user_input";
1920
+ }
1921
+ var TRIGGER = {
1922
+ submitMessage: "submit-message",
1923
+ toolResult: "tool-result",
1924
+ toolApproval: "tool-approval"
1925
+ };
1926
+
1927
+ // src/stream/reducer.ts
1697
1928
  var log5 = logger.scope("reducer");
1698
1929
  var StreamReducer = class {
1699
1930
  constructor(messagesSig) {
@@ -1731,8 +1962,8 @@ var StreamReducer = class {
1731
1962
  ensureTextPart(m, "text", chunk.id);
1732
1963
  return;
1733
1964
  case "text-delta": {
1734
- const p29 = ensureTextPart(m, "text", chunk.id);
1735
- p29.textSig.value += chunk.delta;
1965
+ const p33 = ensureTextPart(m, "text", chunk.id);
1966
+ p33.textSig.value += chunk.delta;
1736
1967
  return;
1737
1968
  }
1738
1969
  case "text-end":
@@ -1742,8 +1973,8 @@ var StreamReducer = class {
1742
1973
  ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
1743
1974
  return;
1744
1975
  case "reasoning-delta": {
1745
- const p29 = ensureTextPart(m, "reasoning", chunk.id);
1746
- p29.textSig.value += chunk.delta;
1976
+ const p33 = ensureTextPart(m, "reasoning", chunk.id);
1977
+ p33.textSig.value += chunk.delta;
1747
1978
  return;
1748
1979
  }
1749
1980
  case "reasoning-end":
@@ -1754,6 +1985,7 @@ var StreamReducer = class {
1754
1985
  case "tool-input-available":
1755
1986
  case "tool-output-available":
1756
1987
  case "tool-output-error":
1988
+ case "tool-approval-request":
1757
1989
  applyTool(m, chunk);
1758
1990
  return;
1759
1991
  case "file":
@@ -1761,7 +1993,7 @@ var StreamReducer = class {
1761
1993
  return;
1762
1994
  case "source-url": {
1763
1995
  const parts = m.partsSig.value;
1764
- if (parts.some((p29) => p29.kind === "source" && p29.sourceId === chunk.sourceId)) return;
1996
+ if (parts.some((p33) => p33.kind === "source" && p33.sourceId === chunk.sourceId)) return;
1765
1997
  appendPart(m, { kind: "source", sourceId: chunk.sourceId, url: chunk.url, title: chunk.title });
1766
1998
  return;
1767
1999
  }
@@ -1785,14 +2017,14 @@ var StreamReducer = class {
1785
2017
  }
1786
2018
  };
1787
2019
  function ensureTextPart(m, kind, id) {
1788
- const existing = m.partsSig.value.find((p29) => p29.kind === kind && p29.id === id);
2020
+ const existing = m.partsSig.value.find((p33) => p33.kind === kind && p33.id === id);
1789
2021
  if (existing) return existing;
1790
2022
  const part = { kind, id, textSig: signal2(""), doneSig: signal2(false) };
1791
2023
  appendPart(m, part);
1792
2024
  return part;
1793
2025
  }
1794
2026
  function ensureToolPart(m, toolCallId, toolName) {
1795
- const existing = m.partsSig.value.find((p29) => p29.kind === "tool" && p29.toolCallId === toolCallId);
2027
+ const existing = m.partsSig.value.find((p33) => p33.kind === "tool" && p33.toolCallId === toolCallId);
1796
2028
  if (existing) return existing;
1797
2029
  const part = {
1798
2030
  kind: "tool",
@@ -1802,7 +2034,8 @@ function ensureToolPart(m, toolCallId, toolName) {
1802
2034
  inputSig: signal2(void 0),
1803
2035
  outputSig: signal2(void 0),
1804
2036
  errorSig: signal2(void 0),
1805
- stateSig: signal2("input")
2037
+ stateSig: signal2("input"),
2038
+ approvalSig: signal2(void 0)
1806
2039
  };
1807
2040
  appendPart(m, part);
1808
2041
  return part;
@@ -1816,26 +2049,32 @@ function applyTool(m, chunk) {
1816
2049
  ensureToolPart(m, chunk.toolCallId, chunk.toolName);
1817
2050
  return;
1818
2051
  case "tool-input-delta": {
1819
- const p29 = ensureToolPart(m, chunk.toolCallId);
1820
- p29.inputPartialSig.value += chunk.delta;
2052
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2053
+ p33.inputPartialSig.value += chunk.delta;
1821
2054
  return;
1822
2055
  }
1823
2056
  case "tool-input-available": {
1824
- const p29 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
1825
- p29.inputSig.value = chunk.input;
1826
- p29.stateSig.value = "awaiting";
2057
+ const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
2058
+ p33.inputSig.value = chunk.input;
2059
+ p33.stateSig.value = isAskUserInputTool(p33.toolName) ? "awaiting-input" : "awaiting";
2060
+ return;
2061
+ }
2062
+ case "tool-approval-request": {
2063
+ const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
2064
+ p33.approvalSig.value = { id: chunk.approvalId };
2065
+ p33.stateSig.value = "awaiting-approval";
1827
2066
  return;
1828
2067
  }
1829
2068
  case "tool-output-available": {
1830
- const p29 = ensureToolPart(m, chunk.toolCallId);
1831
- p29.outputSig.value = chunk.output;
1832
- p29.stateSig.value = "output";
2069
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2070
+ p33.outputSig.value = chunk.output;
2071
+ p33.stateSig.value = "output";
1833
2072
  return;
1834
2073
  }
1835
2074
  case "tool-output-error": {
1836
- const p29 = ensureToolPart(m, chunk.toolCallId);
1837
- p29.errorSig.value = chunk.errorText;
1838
- p29.stateSig.value = "error";
2075
+ const p33 = ensureToolPart(m, chunk.toolCallId);
2076
+ p33.errorSig.value = chunk.errorText;
2077
+ p33.stateSig.value = "error";
1839
2078
  return;
1840
2079
  }
1841
2080
  default:
@@ -1855,6 +2094,7 @@ function createPersistence(widgetId, storage = defaultStorage) {
1855
2094
  const KEY_CALLOUT_DISMISSED = `${prefix}.calloutDismissed`;
1856
2095
  const KEY_SIDEBAR_COLLAPSED = `${prefix}.sidebarCollapsed`;
1857
2096
  const KEY_ACTIVE_MODULE = `${prefix}.activeModule`;
2097
+ const KEY_INTAKE = `${prefix}.intake`;
1858
2098
  const persistence = {
1859
2099
  getVisitorId() {
1860
2100
  const existing = storage.get(KEY_VISITOR);
@@ -1937,6 +2177,24 @@ function createPersistence(widgetId, storage = defaultStorage) {
1937
2177
  saveActiveModule(id) {
1938
2178
  storage.set(KEY_ACTIVE_MODULE, id);
1939
2179
  },
2180
+ loadIntake() {
2181
+ const raw = storage.get(KEY_INTAKE);
2182
+ if (!raw) return null;
2183
+ try {
2184
+ const parsed = JSON.parse(raw);
2185
+ return isPlainObject2(parsed) ? parsed : null;
2186
+ } catch (error) {
2187
+ log6.warn("loadIntake parse failed", { error });
2188
+ return null;
2189
+ }
2190
+ },
2191
+ saveIntake(values) {
2192
+ try {
2193
+ storage.set(KEY_INTAKE, JSON.stringify(values));
2194
+ } catch (error) {
2195
+ log6.warn("saveIntake serialise failed", { error });
2196
+ }
2197
+ },
1940
2198
  clearSession() {
1941
2199
  storage.remove(KEY_CHAT);
1942
2200
  }
@@ -2478,7 +2736,30 @@ var TID = {
2478
2736
  /** Help article row — suffix `-{id}`. */
2479
2737
  helpArticle: `${p2}-help-article`,
2480
2738
  /** News list item — suffix `-{id}`. */
2481
- newsItem: `${p2}-news-item`
2739
+ newsItem: `${p2}-news-item`,
2740
+ // ── Forms + human-in-the-loop (intake / ask-input / approval) ────
2741
+ /** Pre-chat intake form root (blocking gate). */
2742
+ intakeForm: `${p2}-intake-form`,
2743
+ /** Intake submit button. */
2744
+ intakeSubmit: `${p2}-intake-submit`,
2745
+ /** Intake skip button (only when `skippable`). */
2746
+ intakeSkip: `${p2}-intake-skip`,
2747
+ /** A single form field control — suffix `-{name}` at the JSX site. */
2748
+ formField: `${p2}-form-field`,
2749
+ /** Ask-input tool root (inline form in a message bubble). */
2750
+ toolAskInput: `${p2}-tool-ask-input`,
2751
+ /** Ask-input submit button. */
2752
+ toolInputSubmit: `${p2}-tool-input-submit`,
2753
+ /** Ask-input skip button. */
2754
+ toolInputSkip: `${p2}-tool-input-skip`,
2755
+ /** Tool-approval root (approve/reject prompt). */
2756
+ toolApproval: `${p2}-tool-approval`,
2757
+ /** Tool-approval approve button. */
2758
+ toolApprove: `${p2}-tool-approve`,
2759
+ /** Tool-approval reject button. */
2760
+ toolReject: `${p2}-tool-reject`,
2761
+ /** Recorded tool decision summary (after approve/reject/submit). */
2762
+ toolDecision: `${p2}-tool-decision`
2482
2763
  };
2483
2764
  function tid(base, suffix) {
2484
2765
  return `${base}-${suffix}`;
@@ -2589,24 +2870,24 @@ import { useCallback as useCallback2, useEffect as useEffect10, useRef as useRef
2589
2870
  import { useEffect as useEffect2, useRef } from "preact/hooks";
2590
2871
  import { jsx as jsx3 } from "preact/jsx-runtime";
2591
2872
  function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, strings }) {
2592
- const p29 = BRAND.cssPrefix;
2873
+ const p33 = BRAND.cssPrefix;
2593
2874
  const dragRef = useRef(null);
2594
2875
  useEffect2(() => {
2595
2876
  if (!panelEl) return;
2596
2877
  const style = panelEl.style;
2597
- if (resize.minWidth) style.setProperty(`--${p29}-resize-min-w`, resize.minWidth);
2598
- if (resize.maxWidth) style.setProperty(`--${p29}-resize-max-w`, resize.maxWidth);
2599
- if (resize.minHeight) style.setProperty(`--${p29}-resize-min-h`, resize.minHeight);
2600
- if (resize.maxHeight) style.setProperty(`--${p29}-resize-max-h`, resize.maxHeight);
2878
+ if (resize.minWidth) style.setProperty(`--${p33}-resize-min-w`, resize.minWidth);
2879
+ if (resize.maxWidth) style.setProperty(`--${p33}-resize-max-w`, resize.maxWidth);
2880
+ if (resize.minHeight) style.setProperty(`--${p33}-resize-min-h`, resize.minHeight);
2881
+ if (resize.maxHeight) style.setProperty(`--${p33}-resize-max-h`, resize.maxHeight);
2601
2882
  if (initialSize) {
2602
- style.setProperty(`--${p29}-widget-w`, `${initialSize.width}px`);
2603
- style.setProperty(`--${p29}-widget-h`, `${initialSize.height}px`);
2883
+ style.setProperty(`--${p33}-widget-w`, `${initialSize.width}px`);
2884
+ style.setProperty(`--${p33}-widget-h`, `${initialSize.height}px`);
2604
2885
  }
2605
- }, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p29, initialSize]);
2886
+ }, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p33, initialSize]);
2606
2887
  if (!panelEl) return null;
2607
2888
  const isTop = position.startsWith("top-");
2608
2889
  const isRight = position.endsWith("-right");
2609
- const cornerClass = `${p29}-resize-grip ${p29}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
2890
+ const cornerClass = `${p33}-resize-grip ${p33}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
2610
2891
  const onPointerDown = (e) => {
2611
2892
  if (!panelEl) return;
2612
2893
  const target = e.currentTarget;
@@ -2630,8 +2911,8 @@ function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, stri
2630
2911
  if (!d || e.pointerId !== d.pointerId || !panelEl) return;
2631
2912
  const dx = (e.clientX - d.startX) * d.dirX;
2632
2913
  const dy = (e.clientY - d.startY) * d.dirY;
2633
- panelEl.style.setProperty(`--${p29}-widget-w`, `${d.startW + dx}px`);
2634
- panelEl.style.setProperty(`--${p29}-widget-h`, `${d.startH + dy}px`);
2914
+ panelEl.style.setProperty(`--${p33}-widget-w`, `${d.startW + dx}px`);
2915
+ panelEl.style.setProperty(`--${p33}-widget-h`, `${d.startH + dy}px`);
2635
2916
  };
2636
2917
  const onPointerUp = (e) => {
2637
2918
  const d = dragRef.current;
@@ -2668,7 +2949,7 @@ var KEEP_VISIBLE = 56;
2668
2949
  function useDragMove(panelEl, enabled) {
2669
2950
  useEffect3(() => {
2670
2951
  if (!enabled || !panelEl) return;
2671
- const num = (v) => Number.parseFloat(v) || 0;
2952
+ const num2 = (v) => Number.parseFloat(v) || 0;
2672
2953
  const clamp = (v, max) => Math.min(max, Math.max(-max, v));
2673
2954
  let drag = null;
2674
2955
  const onDown = (e) => {
@@ -2679,8 +2960,8 @@ function useDragMove(panelEl, enabled) {
2679
2960
  id: e.pointerId,
2680
2961
  x: e.clientX,
2681
2962
  y: e.clientY,
2682
- dx: num(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
2683
- dy: num(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
2963
+ dx: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
2964
+ dy: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
2684
2965
  // Centred origin: |offset| ≤ (viewport + panel)/2 − keepVisible keeps a
2685
2966
  // strip of the dialog reachable so it can never be lost off-screen.
2686
2967
  maxX: (window.innerWidth + rect.width) / 2 - KEEP_VISIBLE,
@@ -3366,20 +3647,20 @@ function usePopoverMenu({ itemCount, initialFocusIndex }) {
3366
3647
  // src/ui/overflow-menu.tsx
3367
3648
  import { jsx as jsx8, jsxs as jsxs6 } from "preact/jsx-runtime";
3368
3649
  function OverflowMenu({ items, triggerLabel }) {
3369
- const p29 = BRAND.cssPrefix;
3650
+ const p33 = BRAND.cssPrefix;
3370
3651
  const menu = usePopoverMenu({ itemCount: items.length });
3371
3652
  const handleSelect = (item) => {
3372
3653
  if (item.disabled) return;
3373
3654
  item.onSelect();
3374
3655
  if (!item.keepOpen) menu.close();
3375
3656
  };
3376
- return /* @__PURE__ */ jsxs6("div", { class: `${p29}-menu-wrap`, children: [
3657
+ return /* @__PURE__ */ jsxs6("div", { class: `${p33}-menu-wrap`, children: [
3377
3658
  /* @__PURE__ */ jsx8(
3378
3659
  "button",
3379
3660
  {
3380
3661
  ref: menu.triggerRef,
3381
3662
  type: "button",
3382
- class: `${p29}-icon-btn`,
3663
+ class: `${p33}-icon-btn`,
3383
3664
  "aria-label": triggerLabel,
3384
3665
  "aria-haspopup": "menu",
3385
3666
  "aria-expanded": menu.open,
@@ -3393,7 +3674,7 @@ function OverflowMenu({ items, triggerLabel }) {
3393
3674
  "div",
3394
3675
  {
3395
3676
  ref: menu.menuRef,
3396
- class: `${p29}-menu`,
3677
+ class: `${p33}-menu`,
3397
3678
  role: "menu",
3398
3679
  "aria-label": triggerLabel,
3399
3680
  onKeyDown: menu.onMenuKey,
@@ -3403,15 +3684,15 @@ function OverflowMenu({ items, triggerLabel }) {
3403
3684
  {
3404
3685
  type: "button",
3405
3686
  role: "menuitem",
3406
- class: `${p29}-menu-item`,
3687
+ class: `${p33}-menu-item`,
3407
3688
  "aria-pressed": item.type === "switch" ? item.on : void 0,
3408
3689
  disabled: item.disabled,
3409
3690
  lang: item.lang,
3410
3691
  onClick: () => handleSelect(item),
3411
3692
  children: [
3412
- item.icon ? /* @__PURE__ */ jsx8("span", { class: `${p29}-menu-icon`, children: item.icon }) : null,
3413
- /* @__PURE__ */ jsx8("span", { class: `${p29}-menu-label`, children: item.label }),
3414
- item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${p29}-menu-check`, "aria-hidden": "true", children: /* @__PURE__ */ jsx8(CheckIcon, {}) }) : null
3693
+ item.icon ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-icon`, children: item.icon }) : null,
3694
+ /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-label`, children: item.label }),
3695
+ item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-check`, "aria-hidden": "true", children: /* @__PURE__ */ jsx8(CheckIcon, {}) }) : null
3415
3696
  ]
3416
3697
  },
3417
3698
  item.id
@@ -3533,18 +3814,360 @@ function HeaderActions({ panelProps, variant }) {
3533
3814
  ] });
3534
3815
  }
3535
3816
 
3817
+ // src/ui/form/dynamic-form.tsx
3818
+ import { useState as useState5 } from "preact/hooks";
3819
+
3820
+ // src/ui/form/validate.ts
3821
+ var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
3822
+ var URL_RE = /^https?:\/\/[^\s.]+\.[^\s]+$/i;
3823
+ var TEL_RE = /^[+]?[\d\s().-]{6,}$/;
3824
+ function fmt(template, vars) {
3825
+ return template.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? `{${k}}`));
3826
+ }
3827
+ function selectionCount(value) {
3828
+ if (Array.isArray(value)) return value.length;
3829
+ return value && value.trim() ? 1 : 0;
3830
+ }
3831
+ function validateField(field, value, strings) {
3832
+ const required = field.required ?? true;
3833
+ const v = field.validation;
3834
+ if (field.type === "multiselect") {
3835
+ const count = selectionCount(value);
3836
+ if (required && count === 0) return strings.formRequired;
3837
+ if (count === 0) return void 0;
3838
+ if (v?.minSelections != null && count < v.minSelections) {
3839
+ return fmt(strings.formChooseAtLeast, { min: v.minSelections });
3840
+ }
3841
+ if (v?.maxSelections != null && count > v.maxSelections) {
3842
+ return fmt(strings.formChooseAtMost, { max: v.maxSelections });
3843
+ }
3844
+ return void 0;
3845
+ }
3846
+ const text = typeof value === "string" ? value.trim() : "";
3847
+ if (!text) return required ? strings.formRequired : void 0;
3848
+ switch (field.type) {
3849
+ case "email":
3850
+ if (!EMAIL_RE2.test(text)) return strings.formInvalidEmail;
3851
+ break;
3852
+ case "url":
3853
+ if (!URL_RE.test(text)) return strings.formInvalidUrl;
3854
+ break;
3855
+ case "tel":
3856
+ if (!TEL_RE.test(text)) return strings.formInvalidTel;
3857
+ break;
3858
+ case "number": {
3859
+ const n = Number(text);
3860
+ if (!Number.isFinite(n)) return strings.formInvalidNumber;
3861
+ if (v?.min != null && n < v.min) return fmt(strings.formNumberTooSmall, { min: v.min });
3862
+ if (v?.max != null && n > v.max) return fmt(strings.formNumberTooLarge, { max: v.max });
3863
+ break;
3864
+ }
3865
+ default:
3866
+ break;
3867
+ }
3868
+ if (v?.minLength != null && text.length < v.minLength) return fmt(strings.formTooShort, { min: v.minLength });
3869
+ if (v?.maxLength != null && text.length > v.maxLength) return fmt(strings.formTooLong, { max: v.maxLength });
3870
+ if (v?.pattern) {
3871
+ try {
3872
+ if (!new RegExp(v.pattern).test(text)) return strings.formPatternMismatch;
3873
+ } catch {
3874
+ }
3875
+ }
3876
+ return void 0;
3877
+ }
3878
+ function validateForm(fields, values, strings) {
3879
+ const errors = {};
3880
+ for (const field of fields) {
3881
+ const err = validateField(field, values[field.name], strings);
3882
+ if (err) errors[field.name] = err;
3883
+ }
3884
+ return errors;
3885
+ }
3886
+ function flattenValues(values) {
3887
+ const out = {};
3888
+ for (const [k, v] of Object.entries(values)) {
3889
+ const flat = Array.isArray(v) ? v.join(", ") : v;
3890
+ if (flat && flat.trim()) out[k] = flat.trim();
3891
+ }
3892
+ return out;
3893
+ }
3894
+
3895
+ // src/ui/form/dynamic-form.tsx
3896
+ import { jsx as jsx10, jsxs as jsxs8 } from "preact/jsx-runtime";
3897
+ var p10 = BRAND.cssPrefix;
3898
+ var OTHER = "__other__";
3899
+ function DynamicForm({
3900
+ fields,
3901
+ strings,
3902
+ submitLabel,
3903
+ onSubmit,
3904
+ skipLabel,
3905
+ onSkip,
3906
+ disabled,
3907
+ rootTestId,
3908
+ submitTestId,
3909
+ skipTestId
3910
+ }) {
3911
+ const [values, setValues] = useState5(() => seedValues(fields));
3912
+ const [other, setOther] = useState5({});
3913
+ const [errors, setErrors] = useState5({});
3914
+ const clearError = (name) => {
3915
+ if (errors[name]) setErrors((prev) => ({ ...prev, [name]: "" }));
3916
+ };
3917
+ const setValue = (name, v) => {
3918
+ setValues((prev) => ({ ...prev, [name]: v }));
3919
+ clearError(name);
3920
+ };
3921
+ const setOtherText = (name, t) => {
3922
+ setOther((prev) => ({ ...prev, [name]: t }));
3923
+ clearError(name);
3924
+ };
3925
+ const submit = (e) => {
3926
+ e.preventDefault();
3927
+ if (disabled) return;
3928
+ const resolved = resolveValues(fields, values, other);
3929
+ const errs = validateForm(fields, resolved, strings);
3930
+ if (Object.keys(errs).length > 0) {
3931
+ setErrors(errs);
3932
+ return;
3933
+ }
3934
+ onSubmit(flattenValues(resolved));
3935
+ };
3936
+ return /* @__PURE__ */ jsxs8("form", { class: `${p10}-form`, onSubmit: submit, "data-testid": rootTestId, noValidate: true, children: [
3937
+ fields.map((field) => /* @__PURE__ */ jsx10(
3938
+ Field,
3939
+ {
3940
+ field,
3941
+ value: values[field.name],
3942
+ otherText: other[field.name] ?? "",
3943
+ error: errors[field.name],
3944
+ disabled,
3945
+ strings,
3946
+ onChange: (v) => setValue(field.name, v),
3947
+ onOtherChange: (t) => setOtherText(field.name, t)
3948
+ },
3949
+ field.name
3950
+ )),
3951
+ /* @__PURE__ */ jsxs8("div", { class: `${p10}-form-actions`, children: [
3952
+ skipLabel && onSkip ? /* @__PURE__ */ jsx10("button", { type: "button", class: `${p10}-form-skip`, onClick: onSkip, disabled, "data-testid": skipTestId, children: skipLabel }) : null,
3953
+ /* @__PURE__ */ jsx10("button", { type: "submit", class: `${p10}-form-submit`, disabled, "data-testid": submitTestId, children: submitLabel })
3954
+ ] })
3955
+ ] });
3956
+ }
3957
+ function Field({
3958
+ field,
3959
+ value,
3960
+ otherText,
3961
+ error,
3962
+ disabled,
3963
+ strings,
3964
+ onChange,
3965
+ onOtherChange
3966
+ }) {
3967
+ const fieldTid = tid(TID.formField, field.name);
3968
+ const control = renderControl({ field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid });
3969
+ return /* @__PURE__ */ jsxs8("label", { class: `${p10}-field`, "data-field": field.name, "data-invalid": error ? "true" : void 0, children: [
3970
+ /* @__PURE__ */ jsxs8("span", { class: `${p10}-field-label`, children: [
3971
+ field.label,
3972
+ field.required ?? true ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-req`, "aria-hidden": "true", children: " *" }) : null
3973
+ ] }),
3974
+ control,
3975
+ field.validationHint && !error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-hint`, children: field.validationHint }) : null,
3976
+ error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-error`, role: "alert", children: error }) : null
3977
+ ] });
3978
+ }
3979
+ function renderControl(args) {
3980
+ const { field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid } = args;
3981
+ const str2 = typeof value === "string" ? value : "";
3982
+ switch (field.type) {
3983
+ case "textarea":
3984
+ return /* @__PURE__ */ jsx10(
3985
+ "textarea",
3986
+ {
3987
+ class: `${p10}-field-input`,
3988
+ rows: 3,
3989
+ value: str2,
3990
+ placeholder: field.placeholder,
3991
+ disabled,
3992
+ onInput: (e) => onChange(e.target.value),
3993
+ "data-testid": fieldTid
3994
+ }
3995
+ );
3996
+ case "select":
3997
+ return /* @__PURE__ */ jsxs8(
3998
+ "select",
3999
+ {
4000
+ class: `${p10}-field-input`,
4001
+ value: str2,
4002
+ disabled,
4003
+ onChange: (e) => onChange(e.target.value),
4004
+ "data-testid": fieldTid,
4005
+ children: [
4006
+ /* @__PURE__ */ jsx10("option", { value: "", children: field.placeholder ?? "\u2014" }),
4007
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsx10("option", { value: o.value, children: o.label ?? o.value }, o.value))
4008
+ ]
4009
+ }
4010
+ );
4011
+ case "radio": {
4012
+ const isOther = field.allowOther && str2 === OTHER;
4013
+ return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, role: "radiogroup", "data-testid": fieldTid, children: [
4014
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4015
+ /* @__PURE__ */ jsx10(
4016
+ "input",
4017
+ {
4018
+ type: "radio",
4019
+ name: `${p10}-${field.name}`,
4020
+ checked: str2 === o.value,
4021
+ disabled,
4022
+ onChange: () => onChange(o.value)
4023
+ }
4024
+ ),
4025
+ /* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
4026
+ ] }, o.value)),
4027
+ field.allowOther ? /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4028
+ /* @__PURE__ */ jsx10(
4029
+ "input",
4030
+ {
4031
+ type: "radio",
4032
+ name: `${p10}-${field.name}`,
4033
+ checked: str2 === OTHER,
4034
+ disabled,
4035
+ onChange: () => onChange(OTHER)
4036
+ }
4037
+ ),
4038
+ /* @__PURE__ */ jsx10("span", { children: strings.formOther })
4039
+ ] }) : null,
4040
+ isOther ? /* @__PURE__ */ jsx10(
4041
+ "input",
4042
+ {
4043
+ class: `${p10}-field-input`,
4044
+ value: otherText,
4045
+ placeholder: field.placeholder ?? strings.formOtherPlaceholder,
4046
+ disabled,
4047
+ onInput: (e) => onOtherChange(e.target.value)
4048
+ }
4049
+ ) : null
4050
+ ] });
4051
+ }
4052
+ case "checkbox":
4053
+ return /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4054
+ /* @__PURE__ */ jsx10(
4055
+ "input",
4056
+ {
4057
+ type: "checkbox",
4058
+ checked: str2 === "true",
4059
+ disabled,
4060
+ onChange: (e) => onChange(e.target.checked ? "true" : ""),
4061
+ "data-testid": fieldTid
4062
+ }
4063
+ ),
4064
+ /* @__PURE__ */ jsx10("span", { children: field.placeholder ?? field.label })
4065
+ ] });
4066
+ case "multiselect": {
4067
+ const selected = Array.isArray(value) ? value : [];
4068
+ const toggle = (v, on) => onChange(on ? [...selected, v] : selected.filter((x) => x !== v));
4069
+ return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, "data-testid": fieldTid, children: [
4070
+ (field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
4071
+ /* @__PURE__ */ jsx10(
4072
+ "input",
4073
+ {
4074
+ type: "checkbox",
4075
+ checked: selected.includes(o.value),
4076
+ disabled,
4077
+ onChange: (e) => toggle(o.value, e.target.checked)
4078
+ }
4079
+ ),
4080
+ /* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
4081
+ ] }, o.value)),
4082
+ field.allowOther || (field.options ?? []).length === 0 ? /* @__PURE__ */ jsx10(
4083
+ "textarea",
4084
+ {
4085
+ class: `${p10}-field-input`,
4086
+ rows: 2,
4087
+ value: otherText,
4088
+ placeholder: field.placeholder ?? strings.formOtherPlaceholder,
4089
+ disabled,
4090
+ onInput: (e) => onOtherChange(e.target.value)
4091
+ }
4092
+ ) : null
4093
+ ] });
4094
+ }
4095
+ default:
4096
+ return /* @__PURE__ */ jsx10(
4097
+ "input",
4098
+ {
4099
+ class: `${p10}-field-input`,
4100
+ type: inputType(field.type),
4101
+ value: str2,
4102
+ placeholder: field.placeholder,
4103
+ disabled,
4104
+ onInput: (e) => onChange(e.target.value),
4105
+ "data-testid": fieldTid
4106
+ }
4107
+ );
4108
+ }
4109
+ }
4110
+ function inputType(type) {
4111
+ return type === "number" || type === "email" || type === "tel" || type === "url" ? type : "text";
4112
+ }
4113
+ function seedValues(fields) {
4114
+ const out = {};
4115
+ for (const f of fields) {
4116
+ if (f.defaultValue == null) continue;
4117
+ out[f.name] = f.type === "multiselect" ? f.defaultValue.split(",").map((s) => s.trim()).filter(Boolean) : f.defaultValue;
4118
+ }
4119
+ return out;
4120
+ }
4121
+ function resolveValues(fields, values, other) {
4122
+ const out = { ...values };
4123
+ for (const f of fields) {
4124
+ const otherText = other[f.name]?.trim();
4125
+ if (f.type === "radio" && f.allowOther && values[f.name] === OTHER) {
4126
+ out[f.name] = otherText ?? "";
4127
+ } else if (f.type === "multiselect" && otherText) {
4128
+ const tokens = otherText.split(/[,\n;]+/).map((t) => t.trim()).filter(Boolean);
4129
+ const base = Array.isArray(values[f.name]) ? values[f.name] : [];
4130
+ out[f.name] = [...base, ...tokens];
4131
+ }
4132
+ }
4133
+ return out;
4134
+ }
4135
+
4136
+ // src/ui/intake-gate.tsx
4137
+ import { jsx as jsx11, jsxs as jsxs9 } from "preact/jsx-runtime";
4138
+ var p11 = BRAND.cssPrefix;
4139
+ function IntakeGate({ intake, strings, onComplete }) {
4140
+ return /* @__PURE__ */ jsxs9("div", { class: `${p11}-intake`, "data-testid": TID.intakeForm, children: [
4141
+ intake.title ? /* @__PURE__ */ jsx11("h3", { class: `${p11}-intake-title`, children: intake.title }) : null,
4142
+ intake.description ? /* @__PURE__ */ jsx11("p", { class: `${p11}-intake-desc`, children: intake.description }) : null,
4143
+ /* @__PURE__ */ jsx11(
4144
+ DynamicForm,
4145
+ {
4146
+ fields: intake.fields,
4147
+ strings,
4148
+ submitLabel: intake.submitLabel ?? strings.intakeSubmit,
4149
+ onSubmit: onComplete,
4150
+ skipLabel: intake.skippable ? strings.intakeSkip : void 0,
4151
+ onSkip: intake.skippable ? () => onComplete({}) : void 0,
4152
+ submitTestId: TID.intakeSubmit,
4153
+ skipTestId: TID.intakeSkip
4154
+ }
4155
+ )
4156
+ ] });
4157
+ }
4158
+
3536
4159
  // src/ui/message-list.tsx
3537
- import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as useState5 } from "preact/hooks";
3538
- import { useComputed as useComputed3 } from "@preact/signals";
4160
+ import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as useState6 } from "preact/hooks";
4161
+ import { useComputed as useComputed5 } from "@preact/signals";
3539
4162
 
3540
4163
  // src/ui/message-bubble.tsx
3541
- import { useComputed as useComputed2 } from "@preact/signals";
4164
+ import { useComputed as useComputed4 } from "@preact/signals";
3542
4165
 
3543
4166
  // src/ui/markdown.tsx
3544
4167
  import { useEffect as useEffect7, useMemo, useRef as useRef4 } from "preact/hooks";
3545
4168
  import { effect, signal as signal4 } from "@preact/signals";
3546
4169
  import * as smd from "streaming-markdown";
3547
- import { jsx as jsx10 } from "preact/jsx-runtime";
4170
+ import { jsx as jsx12 } from "preact/jsx-runtime";
3548
4171
  function MarkdownView({ textSig, doneSig }) {
3549
4172
  const ref = useRef4(null);
3550
4173
  useEffect7(() => {
@@ -3594,12 +4217,12 @@ function MarkdownView({ textSig, doneSig }) {
3594
4217
  el.removeEventListener("click", onClick);
3595
4218
  };
3596
4219
  }, [textSig, doneSig]);
3597
- return /* @__PURE__ */ jsx10("div", { ref });
4220
+ return /* @__PURE__ */ jsx12("div", { ref });
3598
4221
  }
3599
4222
  function StaticMarkdown({ text }) {
3600
4223
  const textSig = useMemo(() => signal4(text), [text]);
3601
4224
  const doneSig = useMemo(() => signal4(true), []);
3602
- return /* @__PURE__ */ jsx10(MarkdownView, { textSig, doneSig });
4225
+ return /* @__PURE__ */ jsx12(MarkdownView, { textSig, doneSig });
3603
4226
  }
3604
4227
  function hardenLink(a) {
3605
4228
  const href = a.getAttribute("href") ?? "";
@@ -3611,29 +4234,247 @@ function hardenLink(a) {
3611
4234
  a.rel = [...tokens].join(" ");
3612
4235
  }
3613
4236
 
4237
+ // src/ui/tool-approval.tsx
4238
+ import { useComputed as useComputed2, useSignal } from "@preact/signals";
4239
+ import { Fragment, jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
4240
+ var p12 = BRAND.cssPrefix;
4241
+ function ToolApproval({ part, strings, active, onDecision }) {
4242
+ const approval = useComputed2(() => part.approvalSig.value);
4243
+ const input = useComputed2(() => part.inputSig.value);
4244
+ const reason = useSignal("");
4245
+ const decided = approval.value?.approved !== void 0;
4246
+ if (decided) {
4247
+ const ap = approval.value;
4248
+ return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval ${p12}-tool-decided`, "data-testid": TID.toolDecision, children: [
4249
+ /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-label`, "data-approved": ap?.approved ? "true" : "false", children: ap?.approved ? strings.approved : strings.rejected }),
4250
+ /* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName }),
4251
+ ap?.reason ? /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-value`, children: ap.reason }) : null
4252
+ ] });
4253
+ }
4254
+ return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval`, "data-testid": TID.toolApproval, children: [
4255
+ /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-head`, children: [
4256
+ /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-badge`, children: strings.approvalRequired }),
4257
+ /* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName })
4258
+ ] }),
4259
+ summarizeInput(input.value) ? /* @__PURE__ */ jsx13("pre", { class: `${p12}-tool-args`, children: summarizeInput(input.value) }) : null,
4260
+ active ? /* @__PURE__ */ jsxs10(Fragment, { children: [
4261
+ /* @__PURE__ */ jsx13(
4262
+ "input",
4263
+ {
4264
+ class: `${p12}-field-input`,
4265
+ value: reason.value,
4266
+ placeholder: strings.approvalReason,
4267
+ onInput: (e) => {
4268
+ reason.value = e.target.value;
4269
+ }
4270
+ }
4271
+ ),
4272
+ /* @__PURE__ */ jsxs10("div", { class: `${p12}-form-actions`, children: [
4273
+ /* @__PURE__ */ jsx13(
4274
+ "button",
4275
+ {
4276
+ type: "button",
4277
+ class: `${p12}-tool-reject`,
4278
+ onClick: () => onDecision(part.toolCallId, false, reason.value.trim() || void 0),
4279
+ "data-testid": TID.toolReject,
4280
+ children: strings.reject
4281
+ }
4282
+ ),
4283
+ /* @__PURE__ */ jsx13(
4284
+ "button",
4285
+ {
4286
+ type: "button",
4287
+ class: `${p12}-tool-approve`,
4288
+ onClick: () => onDecision(part.toolCallId, true, reason.value.trim() || void 0),
4289
+ "data-testid": TID.toolApprove,
4290
+ children: strings.approve
4291
+ }
4292
+ )
4293
+ ] })
4294
+ ] }) : /* @__PURE__ */ jsx13("p", { class: `${p12}-tool-stale-note`, children: strings.stepNoLongerActive })
4295
+ ] });
4296
+ }
4297
+ function summarizeInput(input) {
4298
+ if (input == null) return "";
4299
+ try {
4300
+ const json = typeof input === "string" ? input : JSON.stringify(input, null, 2);
4301
+ return json.length > 600 ? `${json.slice(0, 600)}\u2026` : json;
4302
+ } catch {
4303
+ return "";
4304
+ }
4305
+ }
4306
+
4307
+ // src/ui/tool-ask-input.tsx
4308
+ import { useComputed as useComputed3 } from "@preact/signals";
4309
+
4310
+ // src/ui/form/field.ts
4311
+ function parseAskUserInput(input) {
4312
+ const raw = input && typeof input === "object" ? input : {};
4313
+ const responseType = raw.responseType;
4314
+ return {
4315
+ title: str(raw.title),
4316
+ question: str(raw.question) ?? "Please provide the missing information.",
4317
+ description: str(raw.description),
4318
+ placeholder: str(raw.placeholder),
4319
+ responseType: responseType === "single-choice" || responseType === "multi-choice" || responseType === "confirmation" || responseType === "free-text" ? responseType : "free-text",
4320
+ choices: Array.isArray(raw.choices) ? raw.choices : void 0,
4321
+ allowOther: typeof raw.allowOther === "boolean" ? raw.allowOther : void 0,
4322
+ required: typeof raw.required === "boolean" ? raw.required : true,
4323
+ defaultValues: Array.isArray(raw.defaultValues) ? raw.defaultValues.filter((v) => typeof v === "string") : void 0,
4324
+ minSelections: num(raw.minSelections),
4325
+ maxSelections: num(raw.maxSelections),
4326
+ validationHint: str(raw.validationHint)
4327
+ };
4328
+ }
4329
+ function askInputToFields(req) {
4330
+ if (req.responseType === "confirmation") return [];
4331
+ const options = (req.choices ?? []).map(normalizeChoice).filter((c) => c !== null);
4332
+ let type = "textarea";
4333
+ if (req.responseType === "single-choice" && options.length > 0) type = "radio";
4334
+ else if (req.responseType === "multi-choice") type = "multiselect";
4335
+ const defaultValue = type === "multiselect" ? req.defaultValues?.join(", ") : req.defaultValues?.[0];
4336
+ return [
4337
+ {
4338
+ name: "answer",
4339
+ label: req.question,
4340
+ type,
4341
+ placeholder: req.placeholder,
4342
+ required: req.required ?? true,
4343
+ defaultValue,
4344
+ options: options.length > 0 ? options : void 0,
4345
+ allowOther: req.allowOther,
4346
+ validationHint: req.validationHint,
4347
+ validation: type === "multiselect" ? { minSelections: req.minSelections, maxSelections: req.maxSelections } : void 0
4348
+ }
4349
+ ];
4350
+ }
4351
+ function normalizeChoice(c) {
4352
+ if (typeof c === "string") return c ? { value: c, label: c } : null;
4353
+ if (c && typeof c.value === "string" && c.value)
4354
+ return { value: c.value, label: c.label ?? c.value, description: c.description };
4355
+ return null;
4356
+ }
4357
+ function str(v) {
4358
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
4359
+ }
4360
+ function num(v) {
4361
+ return typeof v === "number" && Number.isFinite(v) ? v : void 0;
4362
+ }
4363
+
4364
+ // src/ui/tool-ask-input.tsx
4365
+ import { jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
4366
+ var p13 = BRAND.cssPrefix;
4367
+ function ToolAskInput({ part, strings, active, onSubmit }) {
4368
+ const state = useComputed3(() => part.stateSig.value);
4369
+ const request = useComputed3(() => parseAskUserInput(part.inputSig.value));
4370
+ const decided = state.value === "output" || state.value === "error";
4371
+ if (decided) {
4372
+ return /* @__PURE__ */ jsx14(DecidedSummary, { part, strings });
4373
+ }
4374
+ if (!active) {
4375
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-stale`, "data-testid": TID.toolAskInput, children: [
4376
+ /* @__PURE__ */ jsx14(Header, { strings, title: request.value.title ?? request.value.question }),
4377
+ /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-stale-note`, children: strings.stepNoLongerActive })
4378
+ ] });
4379
+ }
4380
+ const req = request.value;
4381
+ const fields = askInputToFields(req);
4382
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input`, "data-testid": TID.toolAskInput, children: [
4383
+ /* @__PURE__ */ jsx14(Header, { strings, title: req.title }),
4384
+ req.description ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-desc`, children: req.description }) : null,
4385
+ req.responseType === "confirmation" ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-question`, children: req.question }) : null,
4386
+ req.responseType === "confirmation" ? /* @__PURE__ */ jsxs11("div", { class: `${p13}-form-actions`, children: [
4387
+ /* @__PURE__ */ jsx14(
4388
+ "button",
4389
+ {
4390
+ type: "button",
4391
+ class: `${p13}-form-skip`,
4392
+ onClick: () => onSubmit(part.toolCallId, { confirmed: false }),
4393
+ "data-testid": TID.toolInputSkip,
4394
+ children: strings.reject
4395
+ }
4396
+ ),
4397
+ /* @__PURE__ */ jsx14(
4398
+ "button",
4399
+ {
4400
+ type: "button",
4401
+ class: `${p13}-form-submit`,
4402
+ onClick: () => onSubmit(part.toolCallId, { confirmed: true }),
4403
+ "data-testid": TID.toolInputSubmit,
4404
+ children: strings.approve
4405
+ }
4406
+ )
4407
+ ] }) : /* @__PURE__ */ jsx14(
4408
+ DynamicForm,
4409
+ {
4410
+ fields,
4411
+ strings,
4412
+ submitLabel: strings.inputSubmit,
4413
+ onSubmit: (values) => onSubmit(part.toolCallId, values),
4414
+ skipLabel: req.required === false ? strings.inputSkip : void 0,
4415
+ onSkip: req.required === false ? () => onSubmit(part.toolCallId, {}) : void 0,
4416
+ submitTestId: TID.toolInputSubmit,
4417
+ skipTestId: TID.toolInputSkip
4418
+ }
4419
+ )
4420
+ ] });
4421
+ }
4422
+ function Header({ strings, title }) {
4423
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-head`, children: [
4424
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-badge`, children: strings.inputRequired }),
4425
+ title ? /* @__PURE__ */ jsx14("strong", { class: `${p13}-tool-title`, children: title }) : null
4426
+ ] });
4427
+ }
4428
+ function DecidedSummary({ part, strings }) {
4429
+ const output = useComputed3(() => part.outputSig.value);
4430
+ const text = summarizeOutput(output.value) || strings.inputSubmitted;
4431
+ return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-decided`, "data-testid": TID.toolDecision, children: [
4432
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-label`, children: strings.inputSubmitted }),
4433
+ /* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-value`, children: text })
4434
+ ] });
4435
+ }
4436
+ function summarizeOutput(output) {
4437
+ if (output == null) return "";
4438
+ if (typeof output === "string") return output;
4439
+ if (typeof output === "object") {
4440
+ const rec = output;
4441
+ if ("confirmed" in rec) return rec.confirmed ? "Yes" : "No";
4442
+ return Object.values(rec).filter((v) => typeof v === "string" || typeof v === "number").join(", ");
4443
+ }
4444
+ return String(output);
4445
+ }
4446
+
3614
4447
  // src/ui/tool-chip.tsx
3615
- import { jsx as jsx11, jsxs as jsxs8 } from "preact/jsx-runtime";
4448
+ import { jsx as jsx15, jsxs as jsxs12 } from "preact/jsx-runtime";
3616
4449
  function ToolChip({ part, strings }) {
3617
- const p29 = BRAND.cssPrefix;
3618
- return /* @__PURE__ */ jsxs8("span", { class: `${p29}-tool-chip`, role: "status", children: [
3619
- /* @__PURE__ */ jsxs8("span", { children: [
4450
+ const p33 = BRAND.cssPrefix;
4451
+ return /* @__PURE__ */ jsxs12("span", { class: `${p33}-tool-chip`, role: "status", children: [
4452
+ /* @__PURE__ */ jsxs12("span", { children: [
3620
4453
  strings.usedTool,
3621
4454
  ":"
3622
4455
  ] }),
3623
- /* @__PURE__ */ jsx11("strong", { children: part.toolName })
4456
+ /* @__PURE__ */ jsx15("strong", { children: part.toolName })
3624
4457
  ] });
3625
4458
  }
3626
4459
 
3627
4460
  // src/ui/message-bubble.tsx
3628
- import { jsx as jsx12, jsxs as jsxs9 } from "preact/jsx-runtime";
3629
- var p10 = BRAND.cssPrefix;
3630
- function MessageBubble({ message, strings, responseMode, showReasoning, showToolCalls }) {
3631
- const parts = useComputed2(() => message.partsSig.value);
4461
+ import { jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
4462
+ var p14 = BRAND.cssPrefix;
4463
+ function MessageBubble({
4464
+ message,
4465
+ strings,
4466
+ responseMode,
4467
+ showReasoning,
4468
+ showToolCalls,
4469
+ interactive = false,
4470
+ tool
4471
+ }) {
4472
+ const parts = useComputed4(() => message.partsSig.value);
3632
4473
  const partList = parts.value;
3633
- const hasAnswerText = useComputed2(
4474
+ const hasAnswerText = useComputed4(
3634
4475
  () => message.partsSig.value.some((part) => part.kind === "text" && part.textSig.value.length > 0)
3635
4476
  );
3636
- const reasoningVisible = useComputed2(
4477
+ const reasoningVisible = useComputed4(
3637
4478
  () => showReasoning && message.partsSig.value.some((part) => part.kind === "reasoning")
3638
4479
  );
3639
4480
  const streaming = message.role === "assistant" && message.status === "streaming";
@@ -3641,23 +4482,25 @@ function MessageBubble({ message, strings, responseMode, showReasoning, showTool
3641
4482
  const working = streaming && !hasAnswerText.value;
3642
4483
  const showStreamDots = streaming && !bufferedHold && !(reasoningVisible.value && working);
3643
4484
  const stamp = formatStamp(message.createdAt);
3644
- 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: [
3645
- /* @__PURE__ */ jsxs9("div", { class: `${p10}-bubble`, children: [
3646
- bufferedHold ? /* @__PURE__ */ jsx12(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx12(
4485
+ 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: [
4486
+ /* @__PURE__ */ jsxs13("div", { class: `${p14}-bubble`, children: [
4487
+ bufferedHold ? /* @__PURE__ */ jsx16(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx16(
3647
4488
  PartView,
3648
4489
  {
3649
4490
  part,
3650
4491
  active: working,
3651
4492
  strings,
3652
4493
  showReasoning,
3653
- showToolCalls
4494
+ showToolCalls,
4495
+ interactive,
4496
+ tool
3654
4497
  },
3655
4498
  partKey(part)
3656
4499
  )),
3657
- showStreamDots && /* @__PURE__ */ jsx12(TypingDots, {}),
3658
- message.status === "error" && message.errorText ? /* @__PURE__ */ jsx12("div", { class: `${p10}-error`, role: "alert", children: /* @__PURE__ */ jsx12("span", { children: message.errorText }) }) : null
4500
+ showStreamDots && /* @__PURE__ */ jsx16(TypingDots, {}),
4501
+ message.status === "error" && message.errorText ? /* @__PURE__ */ jsx16("div", { class: `${p14}-error`, role: "alert", children: /* @__PURE__ */ jsx16("span", { children: message.errorText }) }) : null
3659
4502
  ] }),
3660
- stamp ? /* @__PURE__ */ jsx12("time", { class: `${p10}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
4503
+ stamp ? /* @__PURE__ */ jsx16("time", { class: `${p14}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
3661
4504
  ] }) });
3662
4505
  }
3663
4506
  function formatStamp(createdAt) {
@@ -3678,32 +4521,62 @@ function PartView({
3678
4521
  active,
3679
4522
  strings,
3680
4523
  showReasoning,
3681
- showToolCalls
4524
+ showToolCalls,
4525
+ interactive,
4526
+ tool
3682
4527
  }) {
3683
4528
  switch (part.kind) {
3684
4529
  case "text":
3685
- return /* @__PURE__ */ jsx12(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
4530
+ return /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
3686
4531
  case "reasoning":
3687
- return showReasoning ? /* @__PURE__ */ jsx12(ReasoningView, { part, active, strings }) : null;
4532
+ return showReasoning ? /* @__PURE__ */ jsx16(ReasoningView, { part, active, strings }) : null;
3688
4533
  case "tool":
3689
- return showToolCalls ? /* @__PURE__ */ jsx12(ToolChip, { part, strings }) : null;
4534
+ return /* @__PURE__ */ jsx16(
4535
+ ToolPartView,
4536
+ {
4537
+ part,
4538
+ strings,
4539
+ showToolCalls,
4540
+ interactive,
4541
+ tool
4542
+ }
4543
+ );
3690
4544
  case "file":
3691
4545
  if (part.mediaType.startsWith("image/")) {
3692
- return /* @__PURE__ */ jsx12("img", { src: part.url, alt: "", loading: "lazy" });
4546
+ return /* @__PURE__ */ jsx16("img", { src: part.url, alt: "", loading: "lazy" });
3693
4547
  }
3694
- return /* @__PURE__ */ jsx12("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
4548
+ return /* @__PURE__ */ jsx16("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
3695
4549
  case "source":
3696
4550
  return null;
3697
4551
  }
3698
4552
  }
4553
+ function ToolPartView({
4554
+ part,
4555
+ strings,
4556
+ showToolCalls,
4557
+ interactive,
4558
+ tool
4559
+ }) {
4560
+ const state = useComputed4(() => part.stateSig.value);
4561
+ const hasApproval = useComputed4(() => part.approvalSig.value !== void 0);
4562
+ if (tool?.humanInLoop) {
4563
+ if (hasApproval.value || state.value === "awaiting-approval") {
4564
+ return /* @__PURE__ */ jsx16(ToolApproval, { part, strings, active: interactive, onDecision: tool.onDecision });
4565
+ }
4566
+ if (isAskUserInputTool(part.toolName) || state.value === "awaiting-input") {
4567
+ return /* @__PURE__ */ jsx16(ToolAskInput, { part, strings, active: interactive, onSubmit: tool.onResult });
4568
+ }
4569
+ }
4570
+ return showToolCalls ? /* @__PURE__ */ jsx16(ToolChip, { part, strings }) : null;
4571
+ }
3699
4572
  function ReasoningView({
3700
4573
  part,
3701
4574
  active,
3702
4575
  strings
3703
4576
  }) {
3704
- return /* @__PURE__ */ jsxs9("details", { class: `${p10}-reasoning`, open: active, "data-active": active ? "true" : void 0, children: [
3705
- /* @__PURE__ */ jsx12("summary", { class: `${p10}-reasoning-summary`, children: /* @__PURE__ */ jsx12("span", { class: `${p10}-reasoning-label`, children: active ? strings.thinking : strings.thoughts }) }),
3706
- /* @__PURE__ */ jsx12("div", { class: `${p10}-reasoning-body`, children: /* @__PURE__ */ jsx12(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig }) })
4577
+ return /* @__PURE__ */ jsxs13("details", { class: `${p14}-reasoning`, open: active, "data-active": active ? "true" : void 0, children: [
4578
+ /* @__PURE__ */ jsx16("summary", { class: `${p14}-reasoning-summary`, children: /* @__PURE__ */ jsx16("span", { class: `${p14}-reasoning-label`, children: active ? strings.thinking : strings.thoughts }) }),
4579
+ /* @__PURE__ */ jsx16("div", { class: `${p14}-reasoning-body`, children: /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig }) })
3707
4580
  ] });
3708
4581
  }
3709
4582
  function partKey(part) {
@@ -3720,29 +4593,38 @@ function partKey(part) {
3720
4593
  }
3721
4594
  }
3722
4595
  function TypingDots() {
3723
- return /* @__PURE__ */ jsxs9("span", { class: `${p10}-typing`, "aria-hidden": "true", children: [
3724
- /* @__PURE__ */ jsx12("span", {}),
3725
- /* @__PURE__ */ jsx12("span", {}),
3726
- /* @__PURE__ */ jsx12("span", {})
4596
+ return /* @__PURE__ */ jsxs13("span", { class: `${p14}-typing`, "aria-hidden": "true", children: [
4597
+ /* @__PURE__ */ jsx16("span", {}),
4598
+ /* @__PURE__ */ jsx16("span", {}),
4599
+ /* @__PURE__ */ jsx16("span", {})
3727
4600
  ] });
3728
4601
  }
3729
4602
  function LoadingSpinner({ label }) {
3730
- return /* @__PURE__ */ jsxs9("span", { class: `${p10}-loading`, role: "status", children: [
3731
- /* @__PURE__ */ jsx12("span", { class: `${p10}-loading-spinner`, "aria-hidden": "true" }),
3732
- /* @__PURE__ */ jsx12("span", { class: `${p10}-loading-label`, children: label })
4603
+ return /* @__PURE__ */ jsxs13("span", { class: `${p14}-loading`, role: "status", children: [
4604
+ /* @__PURE__ */ jsx16("span", { class: `${p14}-loading-spinner`, "aria-hidden": "true" }),
4605
+ /* @__PURE__ */ jsx16("span", { class: `${p14}-loading-label`, children: label })
3733
4606
  ] });
3734
4607
  }
3735
4608
 
3736
4609
  // src/ui/message-list.tsx
3737
- import { jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
3738
- var p11 = BRAND.cssPrefix;
4610
+ import { jsx as jsx17, jsxs as jsxs14 } from "preact/jsx-runtime";
4611
+ var p15 = BRAND.cssPrefix;
3739
4612
  var STICK_THRESHOLD = 120;
3740
4613
  var DIVIDER_IDLE_MS = 1200;
3741
- function MessageList({ messagesSig, strings, responseMode, showReasoning, showToolCalls, loading }) {
4614
+ function MessageList({
4615
+ messagesSig,
4616
+ strings,
4617
+ responseMode,
4618
+ showReasoning,
4619
+ showToolCalls,
4620
+ loading,
4621
+ idle,
4622
+ tool
4623
+ }) {
3742
4624
  const ref = useRef5(null);
3743
- const messages = useComputed3(() => messagesSig.value);
3744
- const [showJump, setShowJump] = useState5(false);
3745
- const [scrolling, setScrolling] = useState5(false);
4625
+ const messages = useComputed5(() => messagesSig.value);
4626
+ const [showJump, setShowJump] = useState6(false);
4627
+ const [scrolling, setScrolling] = useState6(false);
3746
4628
  const hasHydratedRef = useRef5(false);
3747
4629
  const firstMessageId = messages.value[0]?.id;
3748
4630
  useLayoutEffect(() => {
@@ -3797,18 +4679,18 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
3797
4679
  const el = ref.current;
3798
4680
  if (!el) return;
3799
4681
  const syncJump = () => setShowJump(el.scrollHeight - el.scrollTop - el.clientHeight > STICK_THRESHOLD * 2);
3800
- let idle;
4682
+ let idleTimer;
3801
4683
  const onScroll = () => {
3802
4684
  syncJump();
3803
4685
  setScrolling(true);
3804
- clearTimeout(idle);
3805
- idle = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
4686
+ clearTimeout(idleTimer);
4687
+ idleTimer = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
3806
4688
  };
3807
4689
  el.addEventListener("scroll", onScroll, { passive: true });
3808
4690
  syncJump();
3809
4691
  return () => {
3810
4692
  el.removeEventListener("scroll", onScroll);
3811
- clearTimeout(idle);
4693
+ clearTimeout(idleTimer);
3812
4694
  };
3813
4695
  }, []);
3814
4696
  const jumpToBottom = () => {
@@ -3817,54 +4699,57 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
3817
4699
  };
3818
4700
  const rows = [];
3819
4701
  let prevDay = "";
4702
+ const lastId = messages.value.at(-1)?.id;
3820
4703
  for (const m of messages.value) {
3821
4704
  const day = dayKey(m.createdAt);
3822
4705
  if (day && day !== prevDay) {
3823
4706
  rows.push(
3824
- /* @__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}`)
4707
+ /* @__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}`)
3825
4708
  );
3826
4709
  prevDay = day;
3827
4710
  }
3828
4711
  rows.push(
3829
- /* @__PURE__ */ jsx13(
4712
+ /* @__PURE__ */ jsx17(
3830
4713
  MessageBubble,
3831
4714
  {
3832
4715
  message: m,
3833
4716
  strings,
3834
4717
  responseMode,
3835
4718
  showReasoning,
3836
- showToolCalls
4719
+ showToolCalls,
4720
+ interactive: Boolean(idle) && m.id === lastId,
4721
+ tool
3837
4722
  },
3838
4723
  m.id
3839
4724
  )
3840
4725
  );
3841
4726
  }
3842
- return /* @__PURE__ */ jsxs10("div", { class: `${p11}-list-wrap`, children: [
3843
- /* @__PURE__ */ jsxs10(
4727
+ return /* @__PURE__ */ jsxs14("div", { class: `${p15}-list-wrap`, children: [
4728
+ /* @__PURE__ */ jsxs14(
3844
4729
  "div",
3845
4730
  {
3846
4731
  ref,
3847
- class: `${p11}-list`,
4732
+ class: `${p15}-list`,
3848
4733
  role: "log",
3849
4734
  "aria-live": "polite",
3850
4735
  "aria-relevant": "additions text",
3851
4736
  "data-scrolling": scrolling ? "true" : void 0,
3852
4737
  children: [
3853
- loading && messages.value.length === 0 ? /* @__PURE__ */ jsx13("div", { class: `${p11}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
4738
+ loading && messages.value.length === 0 ? /* @__PURE__ */ jsx17("div", { class: `${p15}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
3854
4739
  rows
3855
4740
  ]
3856
4741
  }
3857
4742
  ),
3858
- showJump ? /* @__PURE__ */ jsx13(
4743
+ showJump ? /* @__PURE__ */ jsx17(
3859
4744
  "button",
3860
4745
  {
3861
4746
  type: "button",
3862
- class: `${p11}-jump`,
4747
+ class: `${p15}-jump`,
3863
4748
  onClick: jumpToBottom,
3864
4749
  "aria-label": strings.scrollToBottom,
3865
4750
  title: strings.scrollToBottom,
3866
4751
  "data-testid": TID.scrollToBottom,
3867
- children: /* @__PURE__ */ jsx13(ChevronDownIcon, {})
4752
+ children: /* @__PURE__ */ jsx17(ChevronDownIcon, {})
3868
4753
  }
3869
4754
  ) : null
3870
4755
  ] });
@@ -3893,7 +4778,7 @@ function dayLabel(createdAt, strings) {
3893
4778
  }
3894
4779
 
3895
4780
  // src/ui/conversation-list.tsx
3896
- import { useEffect as useEffect9, useState as useState6 } from "preact/hooks";
4781
+ import { useEffect as useEffect9, useState as useState7 } from "preact/hooks";
3897
4782
 
3898
4783
  // src/ui/history-groups.ts
3899
4784
  var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
@@ -3923,7 +4808,7 @@ function startOfDay(ms) {
3923
4808
  }
3924
4809
 
3925
4810
  // src/ui/conversation-list.tsx
3926
- import { Fragment, jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
4811
+ import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs15 } from "preact/jsx-runtime";
3927
4812
  var log11 = logger.scope("history");
3928
4813
  var BUCKET_TO_STRING = {
3929
4814
  today: "dateToday",
@@ -3932,9 +4817,9 @@ var BUCKET_TO_STRING = {
3932
4817
  older: "dateOlder"
3933
4818
  };
3934
4819
  function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }) {
3935
- const p29 = BRAND.cssPrefix;
3936
- const [state, setState] = useState6("loading");
3937
- const [sessions, setChats] = useState6([]);
4820
+ const p33 = BRAND.cssPrefix;
4821
+ const [state, setState] = useState7("loading");
4822
+ const [sessions, setChats] = useState7([]);
3938
4823
  useEffect9(() => {
3939
4824
  let cancelled = false;
3940
4825
  transport.listSessions({ visitorId }).then((res) => {
@@ -3950,38 +4835,38 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
3950
4835
  cancelled = true;
3951
4836
  };
3952
4837
  }, [transport, visitorId]);
3953
- 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: [
3954
- /* @__PURE__ */ jsx14(PlusIcon, {}),
4838
+ 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: [
4839
+ /* @__PURE__ */ jsx18(PlusIcon, {}),
3955
4840
  strings.historyNewChat
3956
4841
  ] }) }) : null;
3957
4842
  if (state === "loading") {
3958
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
3959
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-empty`, children: strings.historyLoading }),
4843
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4844
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyLoading }),
3960
4845
  newChatButton
3961
4846
  ] });
3962
4847
  }
3963
4848
  if (state === "error" || sessions.length === 0) {
3964
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
3965
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-empty`, children: strings.historyEmpty }),
4849
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4850
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyEmpty }),
3966
4851
  newChatButton
3967
4852
  ] });
3968
4853
  }
3969
4854
  const groups = groupByBucket(Date.now(), sessions);
3970
- return /* @__PURE__ */ jsxs11(Fragment, { children: [
3971
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history`, role: "list", children: groups.map((group) => /* @__PURE__ */ jsxs11("div", { class: `${p29}-history-group`, children: [
3972
- /* @__PURE__ */ jsx14("div", { class: `${p29}-history-heading`, children: strings[BUCKET_TO_STRING[group.bucket]] }),
3973
- group.sessions.map((chat) => /* @__PURE__ */ jsxs11(
4855
+ return /* @__PURE__ */ jsxs15(Fragment2, { children: [
4856
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history`, role: "list", children: groups.map((group) => /* @__PURE__ */ jsxs15("div", { class: `${p33}-history-group`, children: [
4857
+ /* @__PURE__ */ jsx18("div", { class: `${p33}-history-heading`, children: strings[BUCKET_TO_STRING[group.bucket]] }),
4858
+ group.sessions.map((chat) => /* @__PURE__ */ jsxs15(
3974
4859
  "button",
3975
4860
  {
3976
4861
  type: "button",
3977
4862
  role: "listitem",
3978
- class: `${p29}-history-item`,
4863
+ class: `${p33}-history-item`,
3979
4864
  onClick: () => onSelect(chat),
3980
4865
  "data-closed": chat.canContinue ? void 0 : "true",
3981
4866
  "data-testid": tid(TID.historyItem, chat.sessionId),
3982
4867
  children: [
3983
- /* @__PURE__ */ jsx14("span", { class: `${p29}-history-title`, children: chat.title }),
3984
- chat.preview ? /* @__PURE__ */ jsx14("span", { class: `${p29}-history-preview`, children: chat.preview }) : null
4868
+ /* @__PURE__ */ jsx18("span", { class: `${p33}-history-title`, children: chat.title }),
4869
+ chat.preview ? /* @__PURE__ */ jsx18("span", { class: `${p33}-history-preview`, children: chat.preview }) : null
3985
4870
  ]
3986
4871
  },
3987
4872
  chat.sessionId
@@ -3992,21 +4877,21 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
3992
4877
  }
3993
4878
 
3994
4879
  // src/ui/chat-history-pane.tsx
3995
- import { jsx as jsx15 } from "preact/jsx-runtime";
4880
+ import { jsx as jsx19 } from "preact/jsx-runtime";
3996
4881
  function ChatHistoryPane(props2) {
3997
- return /* @__PURE__ */ jsx15(ConversationList, { ...props2 });
4882
+ return /* @__PURE__ */ jsx19(ConversationList, { ...props2 });
3998
4883
  }
3999
4884
 
4000
4885
  // src/ui/suggestions.tsx
4001
- import { jsx as jsx16 } from "preact/jsx-runtime";
4002
- var p12 = BRAND.cssPrefix;
4886
+ import { jsx as jsx20 } from "preact/jsx-runtime";
4887
+ var p16 = BRAND.cssPrefix;
4003
4888
  function Suggestions({ suggestions, onPick }) {
4004
4889
  if (suggestions.length === 0) return null;
4005
- return /* @__PURE__ */ jsx16("div", { class: `${p12}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx16(
4890
+ return /* @__PURE__ */ jsx20("div", { class: `${p16}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx20(
4006
4891
  "button",
4007
4892
  {
4008
4893
  type: "button",
4009
- class: `${p12}-suggestion`,
4894
+ class: `${p16}-suggestion`,
4010
4895
  onClick: () => onPick(s),
4011
4896
  "data-testid": tid(TID.suggestion, i),
4012
4897
  children: s.label
@@ -4016,8 +4901,8 @@ function Suggestions({ suggestions, onPick }) {
4016
4901
  }
4017
4902
 
4018
4903
  // src/ui/panel.tsx
4019
- import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs12 } from "preact/jsx-runtime";
4020
- var p13 = BRAND.cssPrefix;
4904
+ import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
4905
+ var p17 = BRAND.cssPrefix;
4021
4906
  function Panel(props2) {
4022
4907
  const { options, onClose } = props2;
4023
4908
  const s = options.strings;
@@ -4041,18 +4926,18 @@ function Panel(props2) {
4041
4926
  }, []);
4042
4927
  const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
4043
4928
  useDragMove(containerRef.current, options.mode === "modal");
4044
- return /* @__PURE__ */ jsxs12(
4929
+ return /* @__PURE__ */ jsxs16(
4045
4930
  "div",
4046
4931
  {
4047
4932
  ref: containerRef,
4048
- class: `${p13}-panel`,
4933
+ class: `${p17}-panel`,
4049
4934
  role: "dialog",
4050
4935
  "aria-modal": "false",
4051
4936
  "aria-label": s.panelTitle,
4052
4937
  style: { position: "relative" },
4053
4938
  "data-testid": TID.panel,
4054
4939
  children: [
4055
- /* @__PURE__ */ jsx17(
4940
+ /* @__PURE__ */ jsx21(
4056
4941
  PanelContent,
4057
4942
  {
4058
4943
  ...props2,
@@ -4061,7 +4946,7 @@ function Panel(props2) {
4061
4946
  composerAttachApiRef
4062
4947
  }
4063
4948
  ),
4064
- /* @__PURE__ */ jsx17(PoweredByBar, { poweredBy: props2.options.poweredBy })
4949
+ /* @__PURE__ */ jsx21(PoweredByBar, { poweredBy: props2.options.poweredBy })
4065
4950
  ]
4066
4951
  }
4067
4952
  );
@@ -4092,13 +4977,39 @@ function PanelContent(props2) {
4092
4977
  onSend,
4093
4978
  onStop,
4094
4979
  onSuggestion,
4980
+ intakePending,
4981
+ onIntakeComplete,
4982
+ tool,
4095
4983
  containerEl,
4096
4984
  dragOver,
4097
4985
  composerAttachApiRef
4098
4986
  } = props2;
4099
4987
  const s = options.strings;
4100
- return /* @__PURE__ */ jsxs12(Fragment2, { children: [
4101
- view === "history" ? /* @__PURE__ */ jsx17(
4988
+ let composerArea;
4989
+ if (intakePending) {
4990
+ composerArea = /* @__PURE__ */ jsx21(IntakeGate, { intake: options.intake, strings: s, onComplete: onIntakeComplete });
4991
+ } else if (canSend) {
4992
+ composerArea = /* @__PURE__ */ jsxs16(Fragment3, { children: [
4993
+ /* @__PURE__ */ jsx21(Suggestions, { suggestions, onPick: onSuggestion }),
4994
+ /* @__PURE__ */ jsx21(
4995
+ Composer,
4996
+ {
4997
+ options,
4998
+ transport,
4999
+ feedback,
5000
+ bus,
5001
+ isStreaming,
5002
+ onSend,
5003
+ onStop,
5004
+ attachApiRef: composerAttachApiRef
5005
+ }
5006
+ )
5007
+ ] });
5008
+ } else {
5009
+ composerArea = /* @__PURE__ */ jsx21(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear });
5010
+ }
5011
+ return /* @__PURE__ */ jsxs16(Fragment3, { children: [
5012
+ view === "history" ? /* @__PURE__ */ jsx21(
4102
5013
  HistoryHeader,
4103
5014
  {
4104
5015
  strings: s,
@@ -4106,22 +5017,22 @@ function PanelContent(props2) {
4106
5017
  onClose,
4107
5018
  showClose: canShowClose(options.mode, panelSize, options.actions)
4108
5019
  }
4109
- ) : /* @__PURE__ */ jsxs12("header", { class: `${p13}-header`, "data-testid": TID.panelHeader, children: [
4110
- onBack ? /* @__PURE__ */ jsx17(
5020
+ ) : /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, "data-testid": TID.panelHeader, children: [
5021
+ onBack ? /* @__PURE__ */ jsx21(
4111
5022
  "button",
4112
5023
  {
4113
5024
  type: "button",
4114
- class: `${p13}-icon-btn`,
5025
+ class: `${p17}-icon-btn`,
4115
5026
  onClick: onBack,
4116
5027
  "aria-label": s.moduleBack,
4117
5028
  title: s.moduleBack,
4118
- children: /* @__PURE__ */ jsx17(BackIcon, {})
5029
+ children: /* @__PURE__ */ jsx21(BackIcon, {})
4119
5030
  }
4120
5031
  ) : null,
4121
- agent ? /* @__PURE__ */ jsx17(AgentBadge, { agent }) : /* @__PURE__ */ jsx17("h1", { children: s.panelTitle }),
4122
- /* @__PURE__ */ jsx17(HeaderActions, { panelProps: props2, variant: "chat" })
5032
+ agent ? /* @__PURE__ */ jsx21(AgentBadge, { agent }) : /* @__PURE__ */ jsx21("h1", { children: s.panelTitle }),
5033
+ /* @__PURE__ */ jsx21(HeaderActions, { panelProps: props2, variant: "chat" })
4123
5034
  ] }),
4124
- view === "history" ? /* @__PURE__ */ jsx17(
5035
+ view === "history" ? /* @__PURE__ */ jsx21(
4125
5036
  ChatHistoryPane,
4126
5037
  {
4127
5038
  transport,
@@ -4130,9 +5041,9 @@ function PanelContent(props2) {
4130
5041
  onSelect: (chat) => onSelectHistoryChat(chat.sessionId),
4131
5042
  onNewChat
4132
5043
  }
4133
- ) : /* @__PURE__ */ jsxs12(Fragment2, { children: [
4134
- /* @__PURE__ */ jsx17(DropZone, { visible: dragOver, strings: s }),
4135
- /* @__PURE__ */ jsx17(
5044
+ ) : /* @__PURE__ */ jsxs16(Fragment3, { children: [
5045
+ /* @__PURE__ */ jsx21(DropZone, { visible: dragOver, strings: s }),
5046
+ /* @__PURE__ */ jsx21(
4136
5047
  MessageList,
4137
5048
  {
4138
5049
  messagesSig,
@@ -4140,28 +5051,15 @@ function PanelContent(props2) {
4140
5051
  responseMode: options.responseMode,
4141
5052
  showReasoning: options.showReasoning,
4142
5053
  showToolCalls: options.showToolCalls,
4143
- loading: loadingMessages
5054
+ loading: loadingMessages,
5055
+ idle: !isStreaming,
5056
+ tool
4144
5057
  }
4145
5058
  ),
4146
- canSend ? /* @__PURE__ */ jsxs12(Fragment2, { children: [
4147
- /* @__PURE__ */ jsx17(Suggestions, { suggestions, onPick: onSuggestion }),
4148
- /* @__PURE__ */ jsx17(
4149
- Composer,
4150
- {
4151
- options,
4152
- transport,
4153
- feedback,
4154
- bus,
4155
- isStreaming,
4156
- onSend,
4157
- onStop,
4158
- attachApiRef: composerAttachApiRef
4159
- }
4160
- )
4161
- ] }) : /* @__PURE__ */ jsx17(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear }),
4162
- /* @__PURE__ */ jsx17(ComposerFooter, { disclaimer: options.composerDisclaimer })
5059
+ composerArea,
5060
+ /* @__PURE__ */ jsx21(ComposerFooter, { disclaimer: options.composerDisclaimer })
4163
5061
  ] }),
4164
- options.size.resize?.enabled ? /* @__PURE__ */ jsx17(
5062
+ options.size.resize?.enabled ? /* @__PURE__ */ jsx21(
4165
5063
  ResizeGrip,
4166
5064
  {
4167
5065
  panelEl: containerEl,
@@ -4180,86 +5078,86 @@ function HistoryHeader({
4180
5078
  onClose,
4181
5079
  showClose
4182
5080
  }) {
4183
- return /* @__PURE__ */ jsxs12("header", { class: `${p13}-header`, children: [
4184
- /* @__PURE__ */ jsx17(
5081
+ return /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, children: [
5082
+ /* @__PURE__ */ jsx21(
4185
5083
  "button",
4186
5084
  {
4187
5085
  type: "button",
4188
- class: `${p13}-icon-btn`,
5086
+ class: `${p17}-icon-btn`,
4189
5087
  onClick: onBack,
4190
5088
  "aria-label": strings.historyBack,
4191
5089
  title: strings.historyBack,
4192
- children: /* @__PURE__ */ jsx17(BackIcon, {})
5090
+ children: /* @__PURE__ */ jsx21(BackIcon, {})
4193
5091
  }
4194
5092
  ),
4195
- /* @__PURE__ */ jsx17("h1", { children: strings.historyTitle }),
4196
- showClose ? /* @__PURE__ */ jsx17(
5093
+ /* @__PURE__ */ jsx21("h1", { children: strings.historyTitle }),
5094
+ showClose ? /* @__PURE__ */ jsx21(
4197
5095
  "button",
4198
5096
  {
4199
5097
  type: "button",
4200
- class: `${p13}-icon-btn`,
5098
+ class: `${p17}-icon-btn`,
4201
5099
  onClick: onClose,
4202
5100
  "aria-label": strings.close,
4203
5101
  title: strings.close,
4204
- children: /* @__PURE__ */ jsx17(CloseIcon, {})
5102
+ children: /* @__PURE__ */ jsx21(CloseIcon, {})
4205
5103
  }
4206
5104
  ) : null
4207
5105
  ] });
4208
5106
  }
4209
5107
  function ReadOnlyBanner({ label, ctaLabel, onNewChat }) {
4210
- return /* @__PURE__ */ jsxs12("div", { class: `${p13}-readonly-banner`, role: "note", children: [
4211
- /* @__PURE__ */ jsx17("span", { class: `${p13}-readonly-label`, children: label }),
4212
- /* @__PURE__ */ jsx17("button", { type: "button", class: `${p13}-readonly-cta`, onClick: onNewChat, children: ctaLabel })
5108
+ return /* @__PURE__ */ jsxs16("div", { class: `${p17}-readonly-banner`, role: "note", children: [
5109
+ /* @__PURE__ */ jsx21("span", { class: `${p17}-readonly-label`, children: label }),
5110
+ /* @__PURE__ */ jsx21("button", { type: "button", class: `${p17}-readonly-cta`, onClick: onNewChat, children: ctaLabel })
4213
5111
  ] });
4214
5112
  }
4215
5113
  function ComposerFooter({ disclaimer }) {
4216
5114
  if (!disclaimer) return null;
4217
- return /* @__PURE__ */ jsx17("div", { class: `${p13}-composer-footer`, children: /* @__PURE__ */ jsx17("div", { class: `${p13}-disclaimer`, children: disclaimer }) });
5115
+ return /* @__PURE__ */ jsx21("div", { class: `${p17}-composer-footer`, children: /* @__PURE__ */ jsx21("div", { class: `${p17}-disclaimer`, children: disclaimer }) });
4218
5116
  }
4219
5117
  function PoweredByBar({ poweredBy }) {
4220
5118
  if (!poweredBy) return null;
4221
- return /* @__PURE__ */ jsx17("div", { class: `${p13}-poweredby-bar`, children: /* @__PURE__ */ jsx17(PoweredBy, { logoUrl: poweredBy.logoUrl, text: poweredBy.text, href: poweredBy.href }) });
5119
+ return /* @__PURE__ */ jsx21("div", { class: `${p17}-poweredby-bar`, children: /* @__PURE__ */ jsx21(PoweredBy, { logoUrl: poweredBy.logoUrl, text: poweredBy.text, href: poweredBy.href }) });
4222
5120
  }
4223
5121
  function PoweredBy({ logoUrl, text, href }) {
4224
- const inner = /* @__PURE__ */ jsxs12(Fragment2, { children: [
4225
- logoUrl ? /* @__PURE__ */ jsx17("img", { class: `${p13}-poweredby-logo`, src: logoUrl, alt: "", loading: "lazy" }) : null,
4226
- text ? /* @__PURE__ */ jsx17("span", { children: text }) : null
5122
+ const inner = /* @__PURE__ */ jsxs16(Fragment3, { children: [
5123
+ logoUrl ? /* @__PURE__ */ jsx21("img", { class: `${p17}-poweredby-logo`, src: logoUrl, alt: "", loading: "lazy" }) : null,
5124
+ text ? /* @__PURE__ */ jsx21("span", { children: text }) : null
4227
5125
  ] });
4228
5126
  if (href) {
4229
- return /* @__PURE__ */ jsx17("a", { class: `${p13}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
5127
+ return /* @__PURE__ */ jsx21("a", { class: `${p17}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
4230
5128
  }
4231
- return /* @__PURE__ */ jsx17("span", { class: `${p13}-poweredby`, children: inner });
5129
+ return /* @__PURE__ */ jsx21("span", { class: `${p17}-poweredby`, children: inner });
4232
5130
  }
4233
5131
 
4234
5132
  // src/ui/sidebar.tsx
4235
- import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs13 } from "preact/jsx-runtime";
5133
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
4236
5134
  function Sidebar(props2) {
4237
- const p29 = BRAND.cssPrefix;
5135
+ const p33 = BRAND.cssPrefix;
4238
5136
  const { site, blocks, strings, collapsed } = props2;
4239
5137
  const navigation = blocks?.navigation ?? [];
4240
5138
  const linkCards = blocks?.linkCards ?? [];
4241
5139
  const toggleLabel = collapsed ? strings.expandSidebar : strings.collapseSidebar;
4242
- return /* @__PURE__ */ jsxs13("aside", { class: `${p29}-sidebar`, "data-collapsed": collapsed ? "true" : "false", "data-testid": TID.sidebar, children: [
4243
- /* @__PURE__ */ jsxs13("div", { class: `${p29}-sidebar-header`, children: [
4244
- /* @__PURE__ */ jsx18(SidebarBrand, { site }),
4245
- /* @__PURE__ */ jsx18(
5140
+ return /* @__PURE__ */ jsxs17("aside", { class: `${p33}-sidebar`, "data-collapsed": collapsed ? "true" : "false", "data-testid": TID.sidebar, children: [
5141
+ /* @__PURE__ */ jsxs17("div", { class: `${p33}-sidebar-header`, children: [
5142
+ /* @__PURE__ */ jsx22(SidebarBrand, { site }),
5143
+ /* @__PURE__ */ jsx22(
4246
5144
  "button",
4247
5145
  {
4248
5146
  type: "button",
4249
- class: `${p29}-sidebar-toggle`,
5147
+ class: `${p33}-sidebar-toggle`,
4250
5148
  "aria-label": toggleLabel,
4251
5149
  "aria-expanded": collapsed ? "false" : "true",
4252
5150
  title: toggleLabel,
4253
5151
  onClick: props2.onToggleCollapsed,
4254
5152
  "data-testid": TID.sidebarToggle,
4255
- children: /* @__PURE__ */ jsx18(SidebarToggleIcon, { collapsed })
5153
+ children: /* @__PURE__ */ jsx22(SidebarToggleIcon, { collapsed })
4256
5154
  }
4257
5155
  )
4258
5156
  ] }),
4259
- collapsed ? null : /* @__PURE__ */ jsxs13(Fragment3, { children: [
4260
- navigation.length > 0 ? /* @__PURE__ */ jsx18("nav", { class: `${p29}-sidebar-section`, "data-section": "navigation", children: /* @__PURE__ */ jsx18(SidebarNav, { items: navigation }) }) : null,
4261
- linkCards.length > 0 ? /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-section`, "data-section": "link-cards", children: /* @__PURE__ */ jsx18(SidebarCards, { items: linkCards }) }) : null,
4262
- props2.showConversations ? /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-conversations`, children: /* @__PURE__ */ jsx18(
5157
+ collapsed ? null : /* @__PURE__ */ jsxs17(Fragment4, { children: [
5158
+ navigation.length > 0 ? /* @__PURE__ */ jsx22("nav", { class: `${p33}-sidebar-section`, "data-section": "navigation", children: /* @__PURE__ */ jsx22(SidebarNav, { items: navigation }) }) : null,
5159
+ linkCards.length > 0 ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-section`, "data-section": "link-cards", children: /* @__PURE__ */ jsx22(SidebarCards, { items: linkCards }) }) : null,
5160
+ props2.showConversations ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-conversations`, children: /* @__PURE__ */ jsx22(
4263
5161
  ConversationList,
4264
5162
  {
4265
5163
  transport: props2.transport,
@@ -4273,18 +5171,18 @@ function Sidebar(props2) {
4273
5171
  ] });
4274
5172
  }
4275
5173
  function SidebarBrand({ site }) {
4276
- const p29 = BRAND.cssPrefix;
5174
+ const p33 = BRAND.cssPrefix;
4277
5175
  if (site?.logo?.url) {
4278
5176
  const alt = site.logo.alt ?? site.title ?? "Logo";
4279
- return /* @__PURE__ */ jsxs13("picture", { children: [
4280
- site.logoDark?.url ? /* @__PURE__ */ jsx18("source", { srcset: site.logoDark.url, media: "(prefers-color-scheme: dark)" }) : null,
4281
- /* @__PURE__ */ jsx18("img", { class: `${p29}-sidebar-logo`, src: site.logo.url, alt })
5177
+ return /* @__PURE__ */ jsxs17("picture", { children: [
5178
+ site.logoDark?.url ? /* @__PURE__ */ jsx22("source", { srcset: site.logoDark.url, media: "(prefers-color-scheme: dark)" }) : null,
5179
+ /* @__PURE__ */ jsx22("img", { class: `${p33}-sidebar-logo`, src: site.logo.url, alt })
4282
5180
  ] });
4283
5181
  }
4284
- return /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-title`, children: site?.title ?? BRAND.name });
5182
+ return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-title`, children: site?.title ?? BRAND.name });
4285
5183
  }
4286
5184
  function SidebarToggleIcon({ collapsed }) {
4287
- return /* @__PURE__ */ jsx18(
5185
+ return /* @__PURE__ */ jsx22(
4288
5186
  "svg",
4289
5187
  {
4290
5188
  width: "16",
@@ -4294,38 +5192,38 @@ function SidebarToggleIcon({ collapsed }) {
4294
5192
  stroke: "currentColor",
4295
5193
  "stroke-width": "2",
4296
5194
  "aria-hidden": "true",
4297
- children: collapsed ? /* @__PURE__ */ jsx18("polyline", { points: "9 6 15 12 9 18" }) : /* @__PURE__ */ jsx18("polyline", { points: "15 6 9 12 15 18" })
5195
+ children: collapsed ? /* @__PURE__ */ jsx22("polyline", { points: "9 6 15 12 9 18" }) : /* @__PURE__ */ jsx22("polyline", { points: "15 6 9 12 15 18" })
4298
5196
  }
4299
5197
  );
4300
5198
  }
4301
5199
  function SidebarNav({ items }) {
4302
- const p29 = BRAND.cssPrefix;
4303
- return /* @__PURE__ */ jsx18("ul", { class: `${p29}-sidebar-nav`, children: items.map((item) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsxs13(
5200
+ const p33 = BRAND.cssPrefix;
5201
+ return /* @__PURE__ */ jsx22("ul", { class: `${p33}-sidebar-nav`, children: items.map((item) => /* @__PURE__ */ jsx22("li", { children: /* @__PURE__ */ jsxs17(
4304
5202
  "a",
4305
5203
  {
4306
- class: `${p29}-sidebar-nav-item`,
5204
+ class: `${p33}-sidebar-nav-item`,
4307
5205
  href: item.href,
4308
5206
  target: item.href ? "_blank" : void 0,
4309
5207
  rel: item.href ? "noreferrer" : void 0,
4310
5208
  children: [
4311
- item.icon ? /* @__PURE__ */ jsx18("span", { class: `${p29}-sidebar-nav-icon`, "data-icon": item.icon }) : null,
4312
- /* @__PURE__ */ jsx18("span", { class: `${p29}-sidebar-nav-label`, children: item.label })
5209
+ item.icon ? /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-icon`, "data-icon": item.icon }) : null,
5210
+ /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-label`, children: item.label })
4313
5211
  ]
4314
5212
  }
4315
5213
  ) }, item.id ?? item.label)) });
4316
5214
  }
4317
5215
  function SidebarCards({ items }) {
4318
- const p29 = BRAND.cssPrefix;
4319
- return /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs13(
5216
+ const p33 = BRAND.cssPrefix;
5217
+ return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs17(
4320
5218
  "a",
4321
5219
  {
4322
- class: `${p29}-sidebar-card`,
5220
+ class: `${p33}-sidebar-card`,
4323
5221
  href: item.href,
4324
5222
  target: item.href ? "_blank" : void 0,
4325
5223
  rel: item.href ? "noreferrer" : void 0,
4326
5224
  children: [
4327
- /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-card-label`, children: item.label }),
4328
- item.description ? /* @__PURE__ */ jsx18("div", { class: `${p29}-sidebar-card-desc`, children: item.description }) : null
5225
+ /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-label`, children: item.label }),
5226
+ item.description ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-desc`, children: item.description }) : null
4329
5227
  ]
4330
5228
  },
4331
5229
  item.id ?? item.label
@@ -4333,11 +5231,11 @@ function SidebarCards({ items }) {
4333
5231
  }
4334
5232
 
4335
5233
  // src/ui/page-shell.tsx
4336
- import { jsx as jsx19, jsxs as jsxs14 } from "preact/jsx-runtime";
4337
- var p14 = BRAND.cssPrefix;
5234
+ import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
5235
+ var p18 = BRAND.cssPrefix;
4338
5236
  function PageShell(props2) {
4339
- return /* @__PURE__ */ jsxs14("main", { class: `${p14}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
4340
- /* @__PURE__ */ jsx19(
5237
+ return /* @__PURE__ */ jsxs18("main", { class: `${p18}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
5238
+ /* @__PURE__ */ jsx23(
4341
5239
  Sidebar,
4342
5240
  {
4343
5241
  site: props2.site,
@@ -4352,7 +5250,7 @@ function PageShell(props2) {
4352
5250
  onToggleCollapsed: props2.onToggleSidebarCollapsed
4353
5251
  }
4354
5252
  ),
4355
- /* @__PURE__ */ jsx19("section", { class: `${p14}-page-chat`, "aria-label": "Chat", children: props2.children })
5253
+ /* @__PURE__ */ jsx23("section", { class: `${p18}-page-chat`, "aria-label": "Chat", children: props2.children })
4356
5254
  ] });
4357
5255
  }
4358
5256
 
@@ -4390,7 +5288,7 @@ var atTabRoot = (s) => activeStack(s).length === 0;
4390
5288
 
4391
5289
  // src/ui/messenger-home.tsx
4392
5290
  import { useCallback as useCallback4, useEffect as useEffect15, useRef as useRef7 } from "preact/hooks";
4393
- import { useComputed as useComputed4 } from "@preact/signals";
5291
+ import { useComputed as useComputed6 } from "@preact/signals";
4394
5292
 
4395
5293
  // src/ui/modules/messages.tsx
4396
5294
  var chatLayout = {
@@ -4399,83 +5297,83 @@ var chatLayout = {
4399
5297
  };
4400
5298
 
4401
5299
  // src/ui/modules/help.tsx
4402
- import { useEffect as useEffect11, useMemo as useMemo2, useState as useState7 } from "preact/hooks";
5300
+ import { useEffect as useEffect11, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
4403
5301
 
4404
5302
  // src/ui/back-header.tsx
4405
- import { jsx as jsx20, jsxs as jsxs15 } from "preact/jsx-runtime";
4406
- var p15 = BRAND.cssPrefix;
5303
+ import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
5304
+ var p19 = BRAND.cssPrefix;
4407
5305
  function TitleBar({ title, actions }) {
4408
- return /* @__PURE__ */ jsxs15("header", { class: `${p15}-back-header`, "data-variant": "title", children: [
4409
- /* @__PURE__ */ jsx20("span", { class: `${p15}-back-spacer`, "aria-hidden": "true" }),
4410
- /* @__PURE__ */ jsx20("h1", { class: `${p15}-back-title`, children: title }),
4411
- actions ?? /* @__PURE__ */ jsx20("span", { class: `${p15}-back-spacer`, "aria-hidden": "true" })
5306
+ return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-variant": "title", children: [
5307
+ /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" }),
5308
+ /* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
5309
+ actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
4412
5310
  ] });
4413
5311
  }
4414
5312
  function BackHeader({ title, backLabel, onBack, actions, testid }) {
4415
- return /* @__PURE__ */ jsxs15("header", { class: `${p15}-back-header`, "data-testid": testid, children: [
4416
- /* @__PURE__ */ jsx20("button", { type: "button", class: `${p15}-icon-btn`, onClick: onBack, "aria-label": backLabel, title: backLabel, children: /* @__PURE__ */ jsx20(BackIcon, {}) }),
4417
- /* @__PURE__ */ jsx20("h1", { class: `${p15}-back-title`, children: title }),
4418
- actions ?? /* @__PURE__ */ jsx20("span", { class: `${p15}-back-spacer`, "aria-hidden": "true" })
5313
+ return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-testid": testid, children: [
5314
+ /* @__PURE__ */ jsx24("button", { type: "button", class: `${p19}-icon-btn`, onClick: onBack, "aria-label": backLabel, title: backLabel, children: /* @__PURE__ */ jsx24(BackIcon, {}) }),
5315
+ /* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
5316
+ actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
4419
5317
  ] });
4420
5318
  }
4421
5319
 
4422
5320
  // src/ui/home-search.tsx
4423
- import { jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
4424
- var p16 = BRAND.cssPrefix;
5321
+ import { jsx as jsx25, jsxs as jsxs20 } from "preact/jsx-runtime";
5322
+ var p20 = BRAND.cssPrefix;
4425
5323
  function HomeSearchButton({ placeholder, onActivate }) {
4426
- return /* @__PURE__ */ jsxs16("button", { type: "button", class: `${p16}-home-search`, onClick: onActivate, "data-testid": TID.homeSearch, children: [
4427
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-text`, children: placeholder }),
4428
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx21(SearchIcon, {}) })
5324
+ return /* @__PURE__ */ jsxs20("button", { type: "button", class: `${p20}-home-search`, onClick: onActivate, "data-testid": TID.homeSearch, children: [
5325
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-text`, children: placeholder }),
5326
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
4429
5327
  ] });
4430
5328
  }
4431
5329
  function HelpSearchInput({ placeholder, value, onInput }) {
4432
- return /* @__PURE__ */ jsxs16("div", { class: `${p16}-home-search`, "data-input": "true", children: [
4433
- /* @__PURE__ */ jsx21(
5330
+ return /* @__PURE__ */ jsxs20("div", { class: `${p20}-home-search`, "data-input": "true", children: [
5331
+ /* @__PURE__ */ jsx25(
4434
5332
  "input",
4435
5333
  {
4436
5334
  type: "search",
4437
- class: `${p16}-home-search-input`,
5335
+ class: `${p20}-home-search-input`,
4438
5336
  placeholder,
4439
5337
  value,
4440
5338
  onInput: (e) => onInput(e.currentTarget.value),
4441
5339
  "data-testid": TID.helpSearch
4442
5340
  }
4443
5341
  ),
4444
- /* @__PURE__ */ jsx21("span", { class: `${p16}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx21(SearchIcon, {}) })
5342
+ /* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
4445
5343
  ] });
4446
5344
  }
4447
5345
 
4448
5346
  // src/ui/list-row.tsx
4449
- import { jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
4450
- var p17 = BRAND.cssPrefix;
5347
+ import { jsx as jsx26, jsxs as jsxs21 } from "preact/jsx-runtime";
5348
+ var p21 = BRAND.cssPrefix;
4451
5349
  function ListRow({ title, subtitle, onClick, testid }) {
4452
- return /* @__PURE__ */ jsxs17("button", { type: "button", class: `${p17}-list-row`, onClick, "data-testid": testid, children: [
4453
- /* @__PURE__ */ jsxs17("span", { class: `${p17}-list-row-body`, children: [
4454
- /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-title`, children: title }),
4455
- subtitle ? /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-sub`, children: subtitle }) : null
5350
+ return /* @__PURE__ */ jsxs21("button", { type: "button", class: `${p21}-list-row`, onClick, "data-testid": testid, children: [
5351
+ /* @__PURE__ */ jsxs21("span", { class: `${p21}-list-row-body`, children: [
5352
+ /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-title`, children: title }),
5353
+ subtitle ? /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-sub`, children: subtitle }) : null
4456
5354
  ] }),
4457
- /* @__PURE__ */ jsx22("span", { class: `${p17}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx22(ChevronRightIcon, {}) })
5355
+ /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(ChevronRightIcon, {}) })
4458
5356
  ] });
4459
5357
  }
4460
5358
 
4461
5359
  // src/ui/module-state.tsx
4462
- import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
4463
- var p18 = BRAND.cssPrefix;
5360
+ import { jsx as jsx27, jsxs as jsxs22 } from "preact/jsx-runtime";
5361
+ var p22 = BRAND.cssPrefix;
4464
5362
  function ModuleState({
4465
5363
  tone = "info",
4466
5364
  message,
4467
5365
  onRetry,
4468
5366
  strings
4469
5367
  }) {
4470
- return /* @__PURE__ */ jsxs18("div", { class: `${p18}-module-empty`, role: tone === "error" ? "alert" : "status", "aria-live": "polite", children: [
4471
- /* @__PURE__ */ jsx23("span", { children: message }),
4472
- onRetry ? /* @__PURE__ */ jsx23("button", { type: "button", class: `${p18}-module-retry`, onClick: onRetry, children: strings.errorRetry }) : null
5368
+ return /* @__PURE__ */ jsxs22("div", { class: `${p22}-module-empty`, role: tone === "error" ? "alert" : "status", "aria-live": "polite", children: [
5369
+ /* @__PURE__ */ jsx27("span", { children: message }),
5370
+ onRetry ? /* @__PURE__ */ jsx27("button", { type: "button", class: `${p22}-module-retry`, onClick: onRetry, children: strings.errorRetry }) : null
4473
5371
  ] });
4474
5372
  }
4475
5373
 
4476
5374
  // src/ui/modules/help.tsx
4477
- import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
4478
- var p19 = BRAND.cssPrefix;
5375
+ import { jsx as jsx28, jsxs as jsxs23 } from "preact/jsx-runtime";
5376
+ var p23 = BRAND.cssPrefix;
4479
5377
  var log12 = logger.scope("help");
4480
5378
  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 });
4481
5379
  function groupByCategory(items) {
@@ -4504,7 +5402,7 @@ function fuzzySearch(items, query) {
4504
5402
  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);
4505
5403
  }
4506
5404
  function ArticleRow({ article, nav }) {
4507
- return /* @__PURE__ */ jsx24(
5405
+ return /* @__PURE__ */ jsx28(
4508
5406
  ListRow,
4509
5407
  {
4510
5408
  title: article.title,
@@ -4516,11 +5414,11 @@ function ArticleRow({ article, nav }) {
4516
5414
  }
4517
5415
  function HelpRoot({ transport, strings, config, nav, panelProps }) {
4518
5416
  const tags = config.contentTags;
4519
- const [state, setState] = useState7("loading");
4520
- const [errorMsg, setErrorMsg] = useState7(strings.errorGeneric);
4521
- const [items, setItems] = useState7([]);
4522
- const [query, setQuery] = useState7("");
4523
- const [reloadKey, setReloadKey] = useState7(0);
5417
+ const [state, setState] = useState8("loading");
5418
+ const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
5419
+ const [items, setItems] = useState8([]);
5420
+ const [query, setQuery] = useState8("");
5421
+ const [reloadKey, setReloadKey] = useState8(0);
4524
5422
  useEffect11(() => {
4525
5423
  let cancelled = false;
4526
5424
  setState("loading");
@@ -4541,46 +5439,46 @@ function HelpRoot({ transport, strings, config, nav, panelProps }) {
4541
5439
  const results = useMemo2(() => fuzzySearch(items, query), [items, query]);
4542
5440
  function renderBody() {
4543
5441
  if (query.trim().length > 0) {
4544
- if (results.length === 0) return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpSearchEmpty, strings });
4545
- return /* @__PURE__ */ jsx24("div", { class: `${p19}-help-card`, children: results.map((a) => /* @__PURE__ */ jsx24(ArticleRow, { article: a, nav }, a.id)) });
5442
+ if (results.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpSearchEmpty, strings });
5443
+ return /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: results.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) });
4546
5444
  }
4547
- if (state === "loading") return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpLoading, strings });
5445
+ if (state === "loading") return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpLoading, strings });
4548
5446
  if (state === "error") {
4549
- return /* @__PURE__ */ jsx24(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
5447
+ return /* @__PURE__ */ jsx28(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
4550
5448
  }
4551
- if (items.length === 0) return /* @__PURE__ */ jsx24(ModuleState, { message: strings.helpEmpty, strings });
4552
- return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */ jsxs19("section", { class: `${p19}-help-group`, children: [
4553
- category ? /* @__PURE__ */ jsx24("h2", { class: `${p19}-help-section-title`, children: category }) : null,
4554
- /* @__PURE__ */ jsx24("div", { class: `${p19}-help-card`, children: rows.map((a) => /* @__PURE__ */ jsx24(ArticleRow, { article: a, nav }, a.id)) })
5449
+ if (items.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpEmpty, strings });
5450
+ return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */ jsxs23("section", { class: `${p23}-help-group`, children: [
5451
+ category ? /* @__PURE__ */ jsx28("h2", { class: `${p23}-help-section-title`, children: category }) : null,
5452
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: rows.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) })
4555
5453
  ] }, category));
4556
5454
  }
4557
- return /* @__PURE__ */ jsxs19("div", { class: `${p19}-module`, children: [
4558
- /* @__PURE__ */ jsx24(TitleBar, { title: strings.helpTitle, actions: /* @__PURE__ */ jsx24(HeaderActions, { panelProps, variant: "plain" }) }),
4559
- /* @__PURE__ */ jsx24("div", { class: `${p19}-module-pad`, children: /* @__PURE__ */ jsx24(HelpSearchInput, { placeholder: strings.helpSearchPlaceholder, value: query, onInput: setQuery }) }),
4560
- /* @__PURE__ */ jsx24("div", { class: `${p19}-help-list`, children: renderBody() })
5455
+ return /* @__PURE__ */ jsxs23("div", { class: `${p23}-module`, children: [
5456
+ /* @__PURE__ */ jsx28(TitleBar, { title: strings.helpTitle, actions: /* @__PURE__ */ jsx28(HeaderActions, { panelProps, variant: "plain" }) }),
5457
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-module-pad`, children: /* @__PURE__ */ jsx28(HelpSearchInput, { placeholder: strings.helpSearchPlaceholder, value: query, onInput: setQuery }) }),
5458
+ /* @__PURE__ */ jsx28("div", { class: `${p23}-help-list`, children: renderBody() })
4561
5459
  ] });
4562
5460
  }
4563
5461
  var helpLayout = {
4564
5462
  Icon: HelpIcon,
4565
- Root: (props2) => /* @__PURE__ */ jsx24(HelpRoot, { ...props2 })
5463
+ Root: (props2) => /* @__PURE__ */ jsx28(HelpRoot, { ...props2 })
4566
5464
  };
4567
5465
 
4568
5466
  // src/ui/modules/home.tsx
4569
- import { useEffect as useEffect12, useState as useState8 } from "preact/hooks";
5467
+ import { useEffect as useEffect12, useState as useState9 } from "preact/hooks";
4570
5468
 
4571
5469
  // src/ui/home-card.tsx
4572
- import { jsx as jsx25 } from "preact/jsx-runtime";
4573
- var p20 = BRAND.cssPrefix;
5470
+ import { jsx as jsx29 } from "preact/jsx-runtime";
5471
+ var p24 = BRAND.cssPrefix;
4574
5472
  function HomeCard({ onClick, children, testid }) {
4575
5473
  if (onClick) {
4576
- return /* @__PURE__ */ jsx25("button", { type: "button", class: `${p20}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
5474
+ return /* @__PURE__ */ jsx29("button", { type: "button", class: `${p24}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
4577
5475
  }
4578
- return /* @__PURE__ */ jsx25("div", { class: `${p20}-home-card`, "data-testid": testid, children });
5476
+ return /* @__PURE__ */ jsx29("div", { class: `${p24}-home-card`, "data-testid": testid, children });
4579
5477
  }
4580
5478
 
4581
5479
  // src/ui/modules/home.tsx
4582
- import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs20 } from "preact/jsx-runtime";
4583
- var p21 = BRAND.cssPrefix;
5480
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs24 } from "preact/jsx-runtime";
5481
+ var p25 = BRAND.cssPrefix;
4584
5482
  var log13 = logger.scope("home");
4585
5483
  function resolveGreeting(props2) {
4586
5484
  const name = props2.options.userContext?.name;
@@ -4594,8 +5492,8 @@ function resolveGreeting(props2) {
4594
5492
  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 });
4595
5493
  function HomeRoot(props2) {
4596
5494
  const { transport, strings, config, nav, panelProps } = props2;
4597
- const [recent, setRecent] = useState8(null);
4598
- const [content, setContent] = useState8([]);
5495
+ const [recent, setRecent] = useState9(null);
5496
+ const [content, setContent] = useState9([]);
4599
5497
  const tagsKey = config.contentTags?.join(",");
4600
5498
  useEffect12(() => {
4601
5499
  if (!config.showRecentMessages) return;
@@ -4617,49 +5515,49 @@ function HomeRoot(props2) {
4617
5515
  const avatars = config.userAvatars ?? [];
4618
5516
  const status = config.status;
4619
5517
  const contentTitle = config.contentBlockTitle ? moduleLabel(strings, config.contentBlockTitle) : strings.homeContentTitle;
4620
- return /* @__PURE__ */ jsx26("div", { class: `${p21}-module ${p21}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-scroll`, children: [
4621
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-hero`, children: [
4622
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-hero-top`, children: [
4623
- 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" }),
4624
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-hero-actions`, children: [
4625
- 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,
4626
- /* @__PURE__ */ jsx26(HeaderActions, { panelProps, variant: "plain" })
5518
+ return /* @__PURE__ */ jsx30("div", { class: `${p25}-module ${p25}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-scroll`, children: [
5519
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero`, children: [
5520
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-top`, children: [
5521
+ 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" }),
5522
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-actions`, children: [
5523
+ 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,
5524
+ /* @__PURE__ */ jsx30(HeaderActions, { panelProps, variant: "plain" })
4627
5525
  ] })
4628
5526
  ] }),
4629
- config.showGreeting !== false ? /* @__PURE__ */ jsxs20(Fragment4, { children: [
4630
- /* @__PURE__ */ jsx26("h1", { class: `${p21}-home-greeting`, "data-testid": TID.homeGreeting, children: greeting.title }),
4631
- greeting.subtitle ? /* @__PURE__ */ jsx26("p", { class: `${p21}-home-lead`, children: greeting.subtitle }) : null
5527
+ config.showGreeting !== false ? /* @__PURE__ */ jsxs24(Fragment5, { children: [
5528
+ /* @__PURE__ */ jsx30("h1", { class: `${p25}-home-greeting`, "data-testid": TID.homeGreeting, children: greeting.title }),
5529
+ greeting.subtitle ? /* @__PURE__ */ jsx30("p", { class: `${p25}-home-lead`, children: greeting.subtitle }) : null
4632
5530
  ] }) : null
4633
5531
  ] }),
4634
- /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-cards`, children: [
4635
- config.showSearchBar !== false ? /* @__PURE__ */ jsx26(
5532
+ /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-cards`, children: [
5533
+ config.showSearchBar !== false ? /* @__PURE__ */ jsx30(
4636
5534
  HomeSearchButton,
4637
5535
  {
4638
5536
  placeholder: strings.homeSearchPlaceholder,
4639
5537
  onActivate: () => nav.switchToLayout("help")
4640
5538
  }
4641
5539
  ) : null,
4642
- 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: [
4643
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-avatar`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(BubblesIcon, {}) }),
4644
- /* @__PURE__ */ jsxs20("span", { class: `${p21}-home-recent-body`, children: [
4645
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-title`, children: recent.title }),
4646
- recent.preview ? /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-preview`, children: recent.preview }) : null
5540
+ 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: [
5541
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-avatar`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(BubblesIcon, {}) }),
5542
+ /* @__PURE__ */ jsxs24("span", { class: `${p25}-home-recent-body`, children: [
5543
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-title`, children: recent.title }),
5544
+ recent.preview ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-preview`, children: recent.preview }) : null
4647
5545
  ] }),
4648
- (recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx26("span", { class: `${p21}-home-recent-dot`, "aria-label": "Unread" }) : null
5546
+ (recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-dot`, "aria-label": "Unread" }) : null
4649
5547
  ] }) }) : null,
4650
- status ? /* @__PURE__ */ jsx26(
5548
+ status ? /* @__PURE__ */ jsx30(
4651
5549
  HomeCard,
4652
5550
  {
4653
5551
  onClick: status.url ? () => nav.push({ kind: "iframe", url: status.url, title: status.text }) : void 0,
4654
- children: /* @__PURE__ */ jsxs20("div", { class: `${p21}-home-status`, "data-level": status.level ?? "operational", children: [
4655
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-status-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(StatusOkIcon, {}) }),
4656
- /* @__PURE__ */ jsx26("span", { class: `${p21}-home-status-text`, children: status.text })
5552
+ children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-status`, "data-level": status.level ?? "operational", children: [
5553
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(StatusOkIcon, {}) }),
5554
+ /* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-text`, children: status.text })
4657
5555
  ] })
4658
5556
  }
4659
5557
  ) : null,
4660
- content.length > 0 ? /* @__PURE__ */ jsxs20("section", { class: `${p21}-home-content`, children: [
4661
- /* @__PURE__ */ jsx26("div", { class: `${p21}-home-content-title`, children: contentTitle }),
4662
- /* @__PURE__ */ jsx26("div", { class: `${p21}-home-content-list`, children: content.map((item) => /* @__PURE__ */ jsx26(
5558
+ content.length > 0 ? /* @__PURE__ */ jsxs24("section", { class: `${p25}-home-content`, children: [
5559
+ /* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-title`, children: contentTitle }),
5560
+ /* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-list`, children: content.map((item) => /* @__PURE__ */ jsx30(
4663
5561
  ListRow,
4664
5562
  {
4665
5563
  title: item.title,
@@ -4675,20 +5573,20 @@ function HomeRoot(props2) {
4675
5573
  }
4676
5574
  var homeLayout = {
4677
5575
  Icon: HomeIcon,
4678
- Root: (props2) => /* @__PURE__ */ jsx26(HomeRoot, { ...props2 })
5576
+ Root: (props2) => /* @__PURE__ */ jsx30(HomeRoot, { ...props2 })
4679
5577
  };
4680
5578
 
4681
5579
  // src/ui/modules/news.tsx
4682
- import { useEffect as useEffect13, useState as useState9 } from "preact/hooks";
4683
- import { jsx as jsx27, jsxs as jsxs21 } from "preact/jsx-runtime";
4684
- var p22 = BRAND.cssPrefix;
5580
+ import { useEffect as useEffect13, useState as useState10 } from "preact/hooks";
5581
+ import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
5582
+ var p26 = BRAND.cssPrefix;
4685
5583
  var log14 = logger.scope("news");
4686
5584
  function NewsRoot({ transport, strings, config, nav, panelProps }) {
4687
5585
  const tags = config.contentTags;
4688
- const [state, setState] = useState9("loading");
4689
- const [errorMsg, setErrorMsg] = useState9(strings.errorGeneric);
4690
- const [items, setItems] = useState9([]);
4691
- const [reloadKey, setReloadKey] = useState9(0);
5586
+ const [state, setState] = useState10("loading");
5587
+ const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
5588
+ const [items, setItems] = useState10([]);
5589
+ const [reloadKey, setReloadKey] = useState10(0);
4692
5590
  useEffect13(() => {
4693
5591
  let cancelled = false;
4694
5592
  setState("loading");
@@ -4707,38 +5605,38 @@ function NewsRoot({ transport, strings, config, nav, panelProps }) {
4707
5605
  };
4708
5606
  }, [transport, tags, reloadKey]);
4709
5607
  function renderBody() {
4710
- if (state === "loading") return /* @__PURE__ */ jsx27(ModuleState, { message: strings.newsLoading, strings });
5608
+ if (state === "loading") return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsLoading, strings });
4711
5609
  if (state === "error") {
4712
- return /* @__PURE__ */ jsx27(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
5610
+ return /* @__PURE__ */ jsx31(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
4713
5611
  }
4714
- if (items.length === 0) return /* @__PURE__ */ jsx27(ModuleState, { message: strings.newsEmpty, strings });
4715
- return /* @__PURE__ */ jsx27("div", { class: `${p22}-news-list`, children: items.map((item) => /* @__PURE__ */ jsxs21(
5612
+ if (items.length === 0) return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsEmpty, strings });
5613
+ return /* @__PURE__ */ jsx31("div", { class: `${p26}-news-list`, children: items.map((item) => /* @__PURE__ */ jsxs25(
4716
5614
  "button",
4717
5615
  {
4718
5616
  type: "button",
4719
- class: `${p22}-news-card`,
5617
+ class: `${p26}-news-card`,
4720
5618
  onClick: () => nav.push({ kind: "content", id: item.id, title: item.title }),
4721
5619
  "data-testid": tid(TID.newsItem, item.id),
4722
5620
  children: [
4723
- item.image ? /* @__PURE__ */ jsx27("img", { class: `${p22}-news-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
4724
- /* @__PURE__ */ jsxs21("span", { class: `${p22}-news-body`, children: [
4725
- 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,
4726
- /* @__PURE__ */ jsx27("span", { class: `${p22}-news-title`, children: item.title }),
4727
- item.description ? /* @__PURE__ */ jsx27("span", { class: `${p22}-news-summary`, children: item.description }) : null
5621
+ item.image ? /* @__PURE__ */ jsx31("img", { class: `${p26}-news-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
5622
+ /* @__PURE__ */ jsxs25("span", { class: `${p26}-news-body`, children: [
5623
+ 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,
5624
+ /* @__PURE__ */ jsx31("span", { class: `${p26}-news-title`, children: item.title }),
5625
+ item.description ? /* @__PURE__ */ jsx31("span", { class: `${p26}-news-summary`, children: item.description }) : null
4728
5626
  ] })
4729
5627
  ]
4730
5628
  },
4731
5629
  item.id
4732
5630
  )) });
4733
5631
  }
4734
- return /* @__PURE__ */ jsxs21("div", { class: `${p22}-module`, children: [
4735
- /* @__PURE__ */ jsx27(TitleBar, { title: strings.newsTitle, actions: /* @__PURE__ */ jsx27(HeaderActions, { panelProps, variant: "plain" }) }),
4736
- /* @__PURE__ */ jsx27("div", { class: `${p22}-module-scroll`, children: renderBody() })
5632
+ return /* @__PURE__ */ jsxs25("div", { class: `${p26}-module`, children: [
5633
+ /* @__PURE__ */ jsx31(TitleBar, { title: strings.newsTitle, actions: /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" }) }),
5634
+ /* @__PURE__ */ jsx31("div", { class: `${p26}-module-scroll`, children: renderBody() })
4737
5635
  ] });
4738
5636
  }
4739
5637
  var newsLayout = {
4740
5638
  Icon: NewsIcon,
4741
- Root: (props2) => /* @__PURE__ */ jsx27(NewsRoot, { ...props2 })
5639
+ Root: (props2) => /* @__PURE__ */ jsx31(NewsRoot, { ...props2 })
4742
5640
  };
4743
5641
 
4744
5642
  // src/ui/modules/registry.ts
@@ -4750,28 +5648,28 @@ var LAYOUTS = {
4750
5648
  };
4751
5649
 
4752
5650
  // src/ui/home-tab-bar.tsx
4753
- import { jsx as jsx28, jsxs as jsxs22 } from "preact/jsx-runtime";
4754
- var p23 = BRAND.cssPrefix;
5651
+ import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
5652
+ var p27 = BRAND.cssPrefix;
4755
5653
  function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
4756
- return /* @__PURE__ */ jsx28("nav", { class: `${p23}-tabbar`, role: "tablist", "aria-label": strings.panelTitle, children: modules.map((m) => {
5654
+ return /* @__PURE__ */ jsx32("nav", { class: `${p27}-tabbar`, role: "tablist", "aria-label": strings.panelTitle, children: modules.map((m) => {
4757
5655
  const Icon = LAYOUTS[m.layout].Icon;
4758
5656
  const selected = m.id === activeTab;
4759
5657
  const badge = m.layout === "chat" && unreadCount > 0 ? unreadCount > 9 ? "9+" : String(unreadCount) : null;
4760
- return /* @__PURE__ */ jsxs22(
5658
+ return /* @__PURE__ */ jsxs26(
4761
5659
  "button",
4762
5660
  {
4763
5661
  type: "button",
4764
5662
  role: "tab",
4765
5663
  "aria-selected": selected,
4766
- class: `${p23}-tab`,
5664
+ class: `${p27}-tab`,
4767
5665
  onClick: () => onSelect(m.id),
4768
5666
  "data-testid": tid(TID.tab, m.id),
4769
5667
  children: [
4770
- /* @__PURE__ */ jsxs22("span", { class: `${p23}-tab-icon`, "aria-hidden": "true", children: [
4771
- /* @__PURE__ */ jsx28(Icon, {}),
4772
- badge ? /* @__PURE__ */ jsx28("span", { class: `${p23}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
5668
+ /* @__PURE__ */ jsxs26("span", { class: `${p27}-tab-icon`, "aria-hidden": "true", children: [
5669
+ /* @__PURE__ */ jsx32(Icon, {}),
5670
+ badge ? /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
4773
5671
  ] }),
4774
- /* @__PURE__ */ jsx28("span", { class: `${p23}-tab-label`, children: moduleLabel(strings, m.label) })
5672
+ /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-label`, children: moduleLabel(strings, m.label) })
4775
5673
  ]
4776
5674
  },
4777
5675
  m.id
@@ -4780,12 +5678,12 @@ function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
4780
5678
  }
4781
5679
 
4782
5680
  // src/ui/iframe-view.tsx
4783
- import { jsx as jsx29, jsxs as jsxs23 } from "preact/jsx-runtime";
4784
- var p24 = BRAND.cssPrefix;
5681
+ import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
5682
+ var p28 = BRAND.cssPrefix;
4785
5683
  var SANDBOX = "allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads";
4786
5684
  function IframeView({ url, title, strings, onBack, actions }) {
4787
- return /* @__PURE__ */ jsxs23("div", { class: `${p24}-module`, children: [
4788
- /* @__PURE__ */ jsx29(
5685
+ return /* @__PURE__ */ jsxs27("div", { class: `${p28}-module`, children: [
5686
+ /* @__PURE__ */ jsx33(
4789
5687
  BackHeader,
4790
5688
  {
4791
5689
  title: title || strings.moduleBack,
@@ -4794,10 +5692,10 @@ function IframeView({ url, title, strings, onBack, actions }) {
4794
5692
  actions
4795
5693
  }
4796
5694
  ),
4797
- /* @__PURE__ */ jsx29(
5695
+ /* @__PURE__ */ jsx33(
4798
5696
  "iframe",
4799
5697
  {
4800
- class: `${p24}-content-frame`,
5698
+ class: `${p28}-content-frame`,
4801
5699
  src: url,
4802
5700
  title: title || "content",
4803
5701
  sandbox: SANDBOX,
@@ -4810,14 +5708,14 @@ function IframeView({ url, title, strings, onBack, actions }) {
4810
5708
  }
4811
5709
 
4812
5710
  // src/ui/content-view.tsx
4813
- import { useCallback as useCallback3, useEffect as useEffect14, useState as useState10 } from "preact/hooks";
4814
- import { jsx as jsx30, jsxs as jsxs24 } from "preact/jsx-runtime";
4815
- var p25 = BRAND.cssPrefix;
5711
+ import { useCallback as useCallback3, useEffect as useEffect14, useState as useState11 } from "preact/hooks";
5712
+ import { jsx as jsx34, jsxs as jsxs28 } from "preact/jsx-runtime";
5713
+ var p29 = BRAND.cssPrefix;
4816
5714
  var log15 = logger.scope("content");
4817
5715
  function ContentView({ id, title, transport, strings, onBack, actions }) {
4818
- const [item, setItem] = useState10(null);
4819
- const [failed, setFailed] = useState10(false);
4820
- const [reloadKey, setReloadKey] = useState10(0);
5716
+ const [item, setItem] = useState11(null);
5717
+ const [failed, setFailed] = useState11(false);
5718
+ const [reloadKey, setReloadKey] = useState11(0);
4821
5719
  const retry = useCallback3(() => {
4822
5720
  setFailed(false);
4823
5721
  setItem(null);
@@ -4840,17 +5738,17 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
4840
5738
  };
4841
5739
  }, [transport, id, reloadKey]);
4842
5740
  function renderBody() {
4843
- if (failed) return /* @__PURE__ */ jsx30(ModuleState, { tone: "error", message: strings.errorGeneric, onRetry: retry, strings });
4844
- if (item === null) return /* @__PURE__ */ jsx30(ModuleState, { message: strings.contentLoading, strings });
4845
- return /* @__PURE__ */ jsxs24("article", { class: `${p25}-content`, "data-testid": TID.contentView, children: [
4846
- item.image ? /* @__PURE__ */ jsx30("img", { class: `${p25}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
4847
- item.description ? /* @__PURE__ */ jsx30("p", { class: `${p25}-content-subtitle`, children: item.description }) : null,
4848
- 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,
4849
- /* @__PURE__ */ jsx30(StaticMarkdown, { text: item.content ?? "" })
5741
+ if (failed) return /* @__PURE__ */ jsx34(ModuleState, { tone: "error", message: strings.errorGeneric, onRetry: retry, strings });
5742
+ if (item === null) return /* @__PURE__ */ jsx34(ModuleState, { message: strings.contentLoading, strings });
5743
+ return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
5744
+ item.image ? /* @__PURE__ */ jsx34("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
5745
+ item.description ? /* @__PURE__ */ jsx34("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
5746
+ 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,
5747
+ /* @__PURE__ */ jsx34(StaticMarkdown, { text: item.content ?? "" })
4850
5748
  ] });
4851
5749
  }
4852
- return /* @__PURE__ */ jsxs24("div", { class: `${p25}-module`, children: [
4853
- /* @__PURE__ */ jsx30(
5750
+ return /* @__PURE__ */ jsxs28("div", { class: `${p29}-module`, children: [
5751
+ /* @__PURE__ */ jsx34(
4854
5752
  BackHeader,
4855
5753
  {
4856
5754
  title: item?.title || title || strings.moduleBack,
@@ -4860,13 +5758,13 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
4860
5758
  testid: TID.backHeader
4861
5759
  }
4862
5760
  ),
4863
- /* @__PURE__ */ jsx30("div", { class: `${p25}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
5761
+ /* @__PURE__ */ jsx34("div", { class: `${p29}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
4864
5762
  ] });
4865
5763
  }
4866
5764
 
4867
5765
  // src/ui/messenger-home.tsx
4868
- import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
4869
- var p26 = BRAND.cssPrefix;
5766
+ import { jsx as jsx35, jsxs as jsxs29 } from "preact/jsx-runtime";
5767
+ var p30 = BRAND.cssPrefix;
4870
5768
  function MessengerHome({
4871
5769
  panelProps,
4872
5770
  enabledModules,
@@ -4898,7 +5796,7 @@ function MessengerHome({
4898
5796
  }, []);
4899
5797
  const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
4900
5798
  useDragMove(containerRef.current, options.mode === "modal");
4901
- const navState = useComputed4(() => nav.sig.value).value;
5799
+ const navState = useComputed6(() => nav.sig.value).value;
4902
5800
  const top = topScreen(navState);
4903
5801
  const activeModule = options.modules.byId[navState.activeTab];
4904
5802
  const isReader = top?.kind === "iframe" || top?.kind === "content";
@@ -4934,12 +5832,12 @@ function MessengerHome({
4934
5832
  nav: moduleNav,
4935
5833
  panelProps
4936
5834
  });
4937
- const plainActions = /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" });
5835
+ const plainActions = /* @__PURE__ */ jsx35(HeaderActions, { panelProps, variant: "plain" });
4938
5836
  let body;
4939
5837
  if (top?.kind === "iframe") {
4940
- body = /* @__PURE__ */ jsx31(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
5838
+ body = /* @__PURE__ */ jsx35(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
4941
5839
  } else if (top?.kind === "content") {
4942
- body = /* @__PURE__ */ jsx31(
5840
+ body = /* @__PURE__ */ jsx35(
4943
5841
  ContentView,
4944
5842
  {
4945
5843
  id: top.id,
@@ -4951,7 +5849,7 @@ function MessengerHome({
4951
5849
  }
4952
5850
  );
4953
5851
  } else if (activeModule?.layout === "chat") {
4954
- body = /* @__PURE__ */ jsx31(
5852
+ body = /* @__PURE__ */ jsx35(
4955
5853
  PanelContent,
4956
5854
  {
4957
5855
  ...panelProps,
@@ -4962,23 +5860,23 @@ function MessengerHome({
4962
5860
  );
4963
5861
  } else if (activeModule) {
4964
5862
  const Root = LAYOUTS[activeModule.layout].Root;
4965
- body = Root ? /* @__PURE__ */ jsx31(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
5863
+ body = Root ? /* @__PURE__ */ jsx35(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
4966
5864
  } else {
4967
5865
  body = null;
4968
5866
  }
4969
- return /* @__PURE__ */ jsxs25(
5867
+ return /* @__PURE__ */ jsxs29(
4970
5868
  "div",
4971
5869
  {
4972
5870
  ref: containerRef,
4973
- class: `${p26}-panel ${p26}-messenger`,
5871
+ class: `${p30}-panel ${p30}-messenger`,
4974
5872
  role: "dialog",
4975
5873
  "aria-modal": "false",
4976
5874
  "aria-label": strings.panelTitle,
4977
5875
  style: { position: "relative" },
4978
5876
  "data-testid": TID.messengerHome,
4979
5877
  children: [
4980
- /* @__PURE__ */ jsx31("div", { class: `${p26}-messenger-body`, children: body }),
4981
- showTabBar ? /* @__PURE__ */ jsx31(
5878
+ /* @__PURE__ */ jsx35("div", { class: `${p30}-messenger-body`, children: body }),
5879
+ showTabBar ? /* @__PURE__ */ jsx35(
4982
5880
  HomeTabBar,
4983
5881
  {
4984
5882
  modules: enabledModules,
@@ -4988,8 +5886,8 @@ function MessengerHome({
4988
5886
  onSelect: nav.switchTab
4989
5887
  }
4990
5888
  ) : null,
4991
- /* @__PURE__ */ jsx31(PoweredByBar, { poweredBy: options.poweredBy }),
4992
- options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx31(
5889
+ /* @__PURE__ */ jsx35(PoweredByBar, { poweredBy: options.poweredBy }),
5890
+ options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx35(
4993
5891
  ResizeGrip,
4994
5892
  {
4995
5893
  panelEl: containerRef.current,
@@ -5006,29 +5904,29 @@ function MessengerHome({
5006
5904
  }
5007
5905
 
5008
5906
  // src/ui/modules-empty.tsx
5009
- import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
5010
- var p27 = BRAND.cssPrefix;
5907
+ import { jsx as jsx36, jsxs as jsxs30 } from "preact/jsx-runtime";
5908
+ var p31 = BRAND.cssPrefix;
5011
5909
  function ModulesEmpty({ strings, onClose }) {
5012
- return /* @__PURE__ */ jsxs26(
5910
+ return /* @__PURE__ */ jsxs30(
5013
5911
  "div",
5014
5912
  {
5015
- class: `${p27}-panel ${p27}-modules-empty`,
5913
+ class: `${p31}-panel ${p31}-modules-empty`,
5016
5914
  role: "dialog",
5017
5915
  "aria-label": strings.panelTitle,
5018
5916
  "data-testid": TID.modulesEmpty,
5019
5917
  children: [
5020
- onClose ? /* @__PURE__ */ jsx32(
5918
+ onClose ? /* @__PURE__ */ jsx36(
5021
5919
  "button",
5022
5920
  {
5023
5921
  type: "button",
5024
- class: `${p27}-icon-btn ${p27}-modules-empty-close`,
5922
+ class: `${p31}-icon-btn ${p31}-modules-empty-close`,
5025
5923
  onClick: onClose,
5026
5924
  "aria-label": strings.close,
5027
5925
  title: strings.close,
5028
- children: /* @__PURE__ */ jsx32(CloseIcon, {})
5926
+ children: /* @__PURE__ */ jsx36(CloseIcon, {})
5029
5927
  }
5030
5928
  ) : null,
5031
- /* @__PURE__ */ jsx32("p", { class: `${p27}-modules-empty-text`, children: strings.modulesEmpty })
5929
+ /* @__PURE__ */ jsx36("p", { class: `${p31}-modules-empty-text`, children: strings.modulesEmpty })
5032
5930
  ]
5033
5931
  }
5034
5932
  );
@@ -5083,11 +5981,11 @@ function animateTypewriter(msg, text, charsPerSecond, abort) {
5083
5981
  }
5084
5982
 
5085
5983
  // src/ui/use-launcher-callout.ts
5086
- import { useCallback as useCallback5, useEffect as useEffect16, useState as useState11 } from "preact/hooks";
5984
+ import { useCallback as useCallback5, useEffect as useEffect16, useState as useState12 } from "preact/hooks";
5087
5985
  function useLauncherCallout({ callout, persistence }) {
5088
5986
  const textKey = callout?.text ?? "";
5089
5987
  const persistent = callout?.persistent ?? true;
5090
- const [dismissed, setDismissed] = useState11(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
5988
+ const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
5091
5989
  useEffect16(() => {
5092
5990
  setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
5093
5991
  }, [textKey, persistent, persistence]);
@@ -5099,21 +5997,21 @@ function useLauncherCallout({ callout, persistence }) {
5099
5997
  }
5100
5998
 
5101
5999
  // src/ui/app.tsx
5102
- import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
6000
+ import { jsx as jsx37, jsxs as jsxs31 } from "preact/jsx-runtime";
5103
6001
  var log16 = logger.scope("app");
5104
- var p28 = BRAND.cssPrefix;
6002
+ var p32 = BRAND.cssPrefix;
5105
6003
  function App({ options, hostElement, bus }) {
5106
- const [persistence] = useState12(() => createPersistence(options.widgetId, options.storage));
5107
- const [visitorId, setVisitorId] = useState12(() => persistence.getVisitorId());
6004
+ const [persistence] = useState13(() => createPersistence(options.widgetId, options.storage));
6005
+ const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
5108
6006
  const initialSettings = persistence.loadUserPrefs();
5109
- const [activeLocale, setActiveLocale] = useState12(() => initialSettings.locale ?? options.locale);
5110
- const [activeThemeMode, setActiveThemeMode] = useState12(
6007
+ const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
6008
+ const [activeThemeMode, setActiveThemeMode] = useState13(
5111
6009
  () => initialSettings.themeMode ?? options.themeMode
5112
6010
  );
5113
- const sessionIdSig = useSignal(persistence.loadSessionId());
5114
- const messagesSig = useSignal([]);
5115
- const unreadCountSig = useSignal(0);
5116
- const [loadingMessages, setLoadingMessages] = useState12(false);
6011
+ const sessionIdSig = useSignal2(persistence.loadSessionId());
6012
+ const messagesSig = useSignal2([]);
6013
+ const unreadCountSig = useSignal2(0);
6014
+ const [loadingMessages, setLoadingMessages] = useState13(false);
5117
6015
  function landingTab() {
5118
6016
  const list = options.modules.list;
5119
6017
  const ids = new Set(list.map((m) => m.id));
@@ -5132,14 +6030,14 @@ function App({ options, hostElement, bus }) {
5132
6030
  const homeNav = homeNavRef.current;
5133
6031
  const chatTabIdRef = useRef8(void 0);
5134
6032
  chatTabIdRef.current = chatTabId();
5135
- const [sessionReady, setSessionReady] = useState12(false);
6033
+ const [sessionReady, setSessionReady] = useState13(false);
5136
6034
  const isInlineLike = options.mode === "standalone" || options.mode === "inline";
5137
6035
  const initialPanelRef = useRef8(
5138
6036
  resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
5139
6037
  );
5140
- const [isOpen, setIsOpen] = useState12(initialPanelRef.current.panelOpen);
6038
+ const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
5141
6039
  const initialPanelApplied = useRef8(false);
5142
- const [launcherLeaving, setLauncherLeaving] = useState12(false);
6040
+ const [launcherLeaving, setLauncherLeaving] = useState13(false);
5143
6041
  const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
5144
6042
  callout: options.launcher.callout,
5145
6043
  persistence
@@ -5150,19 +6048,20 @@ function App({ options, hostElement, bus }) {
5150
6048
  bus.emit("calloutDismiss", void 0);
5151
6049
  dismissCalloutRaw();
5152
6050
  }, [bus, dismissCalloutRaw]);
5153
- const [panelSize, setPanelSize] = useState12(initialPanelRef.current.panelSize);
6051
+ const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
5154
6052
  const initialSizeApplied = useRef8(false);
5155
- const [view, setView] = useState12("chat");
5156
- const [canSend, setCanSend] = useState12(true);
5157
- const [streaming, setStreaming] = useState12(false);
5158
- const [agent, setAgent] = useState12(null);
5159
- const [suggestions, setSuggestions] = useState12([]);
5160
- const [activeCancel, setActiveCancel] = useState12(null);
6053
+ const [view, setView] = useState13("chat");
6054
+ const [canSend, setCanSend] = useState13(true);
6055
+ const [streaming, setStreaming] = useState13(false);
6056
+ const [agent, setAgent] = useState13(null);
6057
+ const [suggestions, setSuggestions] = useState13([]);
6058
+ const [activeCancel, setActiveCancel] = useState13(null);
5161
6059
  const welcomeAbortRef = useRef8(null);
5162
- const [parsedSite, setParsedSite] = useState12(void 0);
5163
- const [parsedBlocks, setParsedBlocks] = useState12(void 0);
5164
- const [sidebarCollapsed, setSidebarCollapsed] = useState12(() => persistence.loadSidebarCollapsed() ?? false);
5165
- const [transport] = useState12(
6060
+ const [parsedSite, setParsedSite] = useState13(void 0);
6061
+ const [parsedBlocks, setParsedBlocks] = useState13(void 0);
6062
+ const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
6063
+ const [intakeValues, setIntakeValues] = useState13(() => persistence.loadIntake());
6064
+ const [transport] = useState13(
5166
6065
  () => new AgentTransport({
5167
6066
  baseUrl: options.baseUrl,
5168
6067
  auth: createAuth({
@@ -5173,8 +6072,8 @@ function App({ options, hostElement, bus }) {
5173
6072
  endpoints: options.endpoints
5174
6073
  })
5175
6074
  );
5176
- const [reducer] = useState12(() => new StreamReducer(messagesSig));
5177
- const [feedback] = useState12(() => new FeedbackBus(options.sound, options.haptics));
6075
+ const [reducer] = useState13(() => new StreamReducer(messagesSig));
6076
+ const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
5178
6077
  const patchAndSync = useCallback6(
5179
6078
  (patch) => {
5180
6079
  persistence.patchUserPrefs(patch);
@@ -5344,9 +6243,11 @@ function App({ options, hostElement, bus }) {
5344
6243
  );
5345
6244
  const userSig = JSON.stringify(options.userContext ?? null);
5346
6245
  const pageSig = JSON.stringify(options.pageContext ?? null);
6246
+ const intakeSig = JSON.stringify(intakeValues ?? null);
5347
6247
  useEffect17(() => {
5348
- transport.setContext(options.userContext, toWirePageContext(options.pageContext));
5349
- }, [transport, userSig, pageSig]);
6248
+ const merged = intakeValues ? { ...intakeValues, ...options.userContext } : options.userContext;
6249
+ transport.setContext(merged, toWirePageContext(options.pageContext));
6250
+ }, [transport, userSig, pageSig, intakeSig]);
5350
6251
  const runResume = useCallback6(
5351
6252
  async (handle) => {
5352
6253
  let bubble = null;
@@ -5434,24 +6335,8 @@ function App({ options, hostElement, bus }) {
5434
6335
  document.addEventListener("keydown", onKey);
5435
6336
  return () => document.removeEventListener("keydown", onKey);
5436
6337
  }, [isOpen, options.mode]);
5437
- const handleSend = useCallback6(
5438
- async (text, attachments) => {
5439
- log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
5440
- if (streaming) return;
5441
- bus.emit("send", { text, attachmentCount: attachments.length });
5442
- if (suggestions.length > 0) setSuggestions([]);
5443
- const uploaded = await uploadAttachments(transport, attachments, (err) => {
5444
- log16.warn("upload failed", { err });
5445
- bus.emit("error", err);
5446
- options.onError?.(err);
5447
- });
5448
- feedback.unlock();
5449
- feedback.play("messageSent");
5450
- const userMsg = makeUserMessage(text, uploaded);
5451
- const assistantMsg = makeAssistantMessage();
5452
- messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
5453
- reducer.attach(assistantMsg);
5454
- emitMessage(bus, options, "user", text);
6338
+ const streamAssistant = useCallback6(
6339
+ async (assistantMsg, trigger) => {
5455
6340
  const activeSessionId = sessionIdSig.value ?? uuid7();
5456
6341
  if (!sessionIdSig.value) {
5457
6342
  sessionIdSig.value = activeSessionId;
@@ -5460,10 +6345,10 @@ function App({ options, hostElement, bus }) {
5460
6345
  const body = buildSendMessageRequest({
5461
6346
  messages: messagesSig.value.slice(0, -1).map(fromReactive),
5462
6347
  sessionId: activeSessionId,
5463
- // textModel + imageModel are backend-only — selected per
5464
- // deployment in the dashboard, never passed up by the widget.
6348
+ // textModel + imageModel are backend-only — selected per deployment.
5465
6349
  tools: options.features.tools,
5466
6350
  responseMode: options.responseMode,
6351
+ trigger,
5467
6352
  // Identity + preferences ride on every message — server may need
5468
6353
  // them to route, persist, or reconcile in-flight.
5469
6354
  visitorId,
@@ -5495,19 +6380,95 @@ function App({ options, hostElement, bus }) {
5495
6380
  messagesSig.value = [...messagesSig.value];
5496
6381
  }
5497
6382
  },
5498
- [
5499
- streaming,
5500
- transport,
5501
- reducer,
5502
- messagesSig,
5503
- sessionIdSig,
5504
- options,
5505
- bus,
5506
- suggestions.length,
5507
- feedback,
5508
- persistence,
5509
- visitorId
5510
- ]
6383
+ [transport, reducer, messagesSig, sessionIdSig, options, bus, feedback, persistence, visitorId]
6384
+ );
6385
+ const resolveTool = useCallback6(
6386
+ (toolCallId, trigger, mutate) => {
6387
+ if (streaming) return;
6388
+ const last = messagesSig.value.at(-1);
6389
+ const part = last?.partsSig.value.find(
6390
+ (pt) => pt.kind === "tool" && pt.toolCallId === toolCallId
6391
+ );
6392
+ if (!part) {
6393
+ log16.warn("resolveTool: tool part not found", { toolCallId });
6394
+ return;
6395
+ }
6396
+ mutate(part);
6397
+ if (last) last.partsSig.value = [...last.partsSig.value];
6398
+ const assistantMsg = makeAssistantMessage();
6399
+ messagesSig.value = [...messagesSig.value, assistantMsg];
6400
+ reducer.attach(assistantMsg);
6401
+ void streamAssistant(assistantMsg, trigger);
6402
+ },
6403
+ [streaming, messagesSig, reducer, streamAssistant]
6404
+ );
6405
+ const handleToolResult = useCallback6(
6406
+ (toolCallId, output) => {
6407
+ log16.info("toolResult", { toolCallId });
6408
+ bus.emit("toolResult", { toolCallId });
6409
+ resolveTool(toolCallId, TRIGGER.toolResult, (part) => {
6410
+ part.outputSig.value = output;
6411
+ part.stateSig.value = "output";
6412
+ });
6413
+ },
6414
+ [bus, resolveTool]
6415
+ );
6416
+ const handleToolDecision = useCallback6(
6417
+ (toolCallId, approved, reason) => {
6418
+ log16.info("toolDecision", { toolCallId, approved });
6419
+ bus.emit("toolDecision", { toolCallId, approved });
6420
+ resolveTool(toolCallId, TRIGGER.toolApproval, (part) => {
6421
+ const id = part.approvalSig.value?.id ?? toolCallId;
6422
+ part.approvalSig.value = { id, approved, reason };
6423
+ part.stateSig.value = "output";
6424
+ });
6425
+ },
6426
+ [bus, resolveTool]
6427
+ );
6428
+ const toolInteraction = useMemo3(
6429
+ () => ({ humanInLoop: options.features.humanInLoop, onResult: handleToolResult, onDecision: handleToolDecision }),
6430
+ [options.features.humanInLoop, handleToolResult, handleToolDecision]
6431
+ );
6432
+ const intakePending = options.intake.enabled && intakeValues === null;
6433
+ const handleIntakeComplete = useCallback6(
6434
+ (values) => {
6435
+ const hasValues = Object.keys(values).length > 0;
6436
+ log16.info("intakeComplete", { fields: Object.keys(values).length, skipped: !hasValues });
6437
+ persistence.saveIntake(values);
6438
+ setIntakeValues(values);
6439
+ bus.emit("intakeSubmit", values);
6440
+ if (!hasValues) return;
6441
+ const activeSessionId = sessionIdSig.value ?? uuid7();
6442
+ if (!sessionIdSig.value) {
6443
+ sessionIdSig.value = activeSessionId;
6444
+ persistence.saveSessionId(activeSessionId);
6445
+ transport.primeIdentity(void 0, activeSessionId);
6446
+ }
6447
+ void transport.submitIntake(activeSessionId, values);
6448
+ },
6449
+ [persistence, bus, sessionIdSig, transport]
6450
+ );
6451
+ const handleSend = useCallback6(
6452
+ async (text, attachments) => {
6453
+ log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
6454
+ if (streaming) return;
6455
+ bus.emit("send", { text, attachmentCount: attachments.length });
6456
+ if (suggestions.length > 0) setSuggestions([]);
6457
+ const uploaded = await uploadAttachments(transport, attachments, (err) => {
6458
+ log16.warn("upload failed", { err });
6459
+ bus.emit("error", err);
6460
+ options.onError?.(err);
6461
+ });
6462
+ feedback.unlock();
6463
+ feedback.play("messageSent");
6464
+ const userMsg = makeUserMessage(text, uploaded);
6465
+ const assistantMsg = makeAssistantMessage();
6466
+ messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
6467
+ reducer.attach(assistantMsg);
6468
+ emitMessage(bus, options, "user", text);
6469
+ await streamAssistant(assistantMsg, TRIGGER.submitMessage);
6470
+ },
6471
+ [streaming, transport, bus, options, suggestions.length, messagesSig, reducer, streamAssistant]
5511
6472
  );
5512
6473
  const handleStop = useCallback6(() => {
5513
6474
  log16.info("stop");
@@ -5711,7 +6672,10 @@ function App({ options, hostElement, bus }) {
5711
6672
  log16.info("suggestion", { text });
5712
6673
  bus.emit("suggestion", { text });
5713
6674
  void handleSend(text, []);
5714
- }
6675
+ },
6676
+ intakePending,
6677
+ onIntakeComplete: handleIntakeComplete,
6678
+ tool: toolInteraction
5715
6679
  };
5716
6680
  const onSelectSession = (sessionId) => {
5717
6681
  void handleSelectHistoryChat(sessionId);
@@ -5723,12 +6687,12 @@ function App({ options, hostElement, bus }) {
5723
6687
  const renderSurface = (size) => {
5724
6688
  const closeable = isActionVisible("close", effectiveOptions.mode, size);
5725
6689
  if (enabledModules.length === 0) {
5726
- return /* @__PURE__ */ jsx33(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
6690
+ return /* @__PURE__ */ jsx37(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
5727
6691
  }
5728
6692
  if (enabledModules.length === 1 && enabledModules[0]?.layout === "chat") {
5729
- return /* @__PURE__ */ jsx33(Panel, { ...panelProps, panelSize: size });
6693
+ return /* @__PURE__ */ jsx37(Panel, { ...panelProps, panelSize: size });
5730
6694
  }
5731
- return /* @__PURE__ */ jsx33(
6695
+ return /* @__PURE__ */ jsx37(
5732
6696
  MessengerHome,
5733
6697
  {
5734
6698
  panelProps: { ...panelProps, panelSize: size, onClose: closeable ? handleClose : void 0 },
@@ -5746,7 +6710,7 @@ function App({ options, hostElement, bus }) {
5746
6710
  void handleSelectHistoryChat(chat.sessionId);
5747
6711
  };
5748
6712
  const messagesEnabled = enabledModules.some((m) => m.layout === "chat");
5749
- return /* @__PURE__ */ jsx33("div", { class: `${p28}-anchor`, children: /* @__PURE__ */ jsx33(
6713
+ return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: /* @__PURE__ */ jsx37(
5750
6714
  PageShell,
5751
6715
  {
5752
6716
  site: parsedSite,
@@ -5765,15 +6729,15 @@ function App({ options, hostElement, bus }) {
5765
6729
  }
5766
6730
  if (isInlineLike) {
5767
6731
  const inlineSize = options.mode === "standalone" ? "fullscreen" : panelSize;
5768
- return /* @__PURE__ */ jsx33("div", { class: `${p28}-anchor`, children: renderSurface(inlineSize) });
6732
+ return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: renderSurface(inlineSize) });
5769
6733
  }
5770
6734
  const drawerEdgeTab = options.mode === "drawer";
5771
6735
  const triggerOwnedByPage = options.mode === "modal";
5772
6736
  const launcherVisible = !triggerOwnedByPage && !options.launcher.hidden && (!isOpen || launcherLeaving);
5773
6737
  const calloutToRender = launcherVisible && !launcherLeaving && !calloutDismissed && !drawerEdgeTab ? effectiveOptions.launcher.callout : null;
5774
- return /* @__PURE__ */ jsxs27("div", { class: `${p28}-anchor`, "data-launcher-size": effectiveOptions.launcher.size, children: [
6738
+ return /* @__PURE__ */ jsxs31("div", { class: `${p32}-anchor`, "data-launcher-size": effectiveOptions.launcher.size, children: [
5775
6739
  isOpen ? renderSurface(panelSize) : null,
5776
- launcherVisible ? /* @__PURE__ */ jsx33(
6740
+ launcherVisible ? /* @__PURE__ */ jsx37(
5777
6741
  Launcher,
5778
6742
  {
5779
6743
  onToggle: handleOpen,
@@ -5783,7 +6747,7 @@ function App({ options, hostElement, bus }) {
5783
6747
  edgeTab: drawerEdgeTab
5784
6748
  }
5785
6749
  ) : null,
5786
- calloutToRender ? /* @__PURE__ */ jsx33(
6750
+ calloutToRender ? /* @__PURE__ */ jsx37(
5787
6751
  LauncherCallout,
5788
6752
  {
5789
6753
  callout: calloutToRender,
@@ -5982,6 +6946,10 @@ var EVENT_NAMES = [
5982
6946
  "selectChat",
5983
6947
  "suggestion",
5984
6948
  "toggleHistory",
6949
+ // Forms + human-in-the-loop
6950
+ "intakeSubmit",
6951
+ "toolResult",
6952
+ "toolDecision",
5985
6953
  // Composer / attachments / voice
5986
6954
  "attach",
5987
6955
  "removeAttachment",