@burdenoff/website-sdk 2026.829.2 → 2026.829.4
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/dist/components/explore.js +86 -2
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +87 -3
- package/dist/components/explore.mjs.map +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +22 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +22 -1
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +86 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat-8eL7WdLc.d.mts → use-explore-chat-B-E7jN1H.d.mts} +5 -0
- package/dist/{use-explore-chat-8eL7WdLc.d.ts → use-explore-chat-B-E7jN1H.d.ts} +5 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/content/Markdown.tsx","../../src/content/prose-styles.tsx","../../src/client/security.ts","../../src/client/graphql-client.ts","../../src/client/provider.tsx","../../src/components/explore-types.ts","../../src/data/products.ts","../../src/utils/recaptcha-v3.ts","../../src/hooks/use-explore-chat.ts","../../src/hooks/use-speech-input.ts","../../src/seo/page-head.tsx","../../src/utils/cn.ts","../../src/ui/button.tsx","../../src/ui/textarea.tsx","../../src/components/explore.tsx"],"names":["jsx","ReactMarkdown","remarkGfm","rehypeSanitize","createContext","useContext","useMemo","useState","useRef","useCallback","useEffect","Helmet","twMerge","clsx","cva","React","Slot","React2","BookOpenText","Layers","Link2","jsxs","ExternalLink","Sparkles","TriangleAlert","ArrowUp","ChevronLeft","ChevronRight","RotateCcw","HistoryIcon","Trash2","Mic","Square"],"mappings":"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","file":"explore.js","sourcesContent":["import type { ReactNode } from \"react\";\n\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeSanitize from \"rehype-sanitize\";\nimport remarkGfm from \"remark-gfm\";\n\nimport type { Components } from \"react-markdown\";\n\nexport interface MarkdownProps {\n /** Markdown source to render. */\n children: string;\n /** Additional classes for the wrapper element. */\n className?: string;\n /** Render without a wrapping block element, suitable for inline content. */\n inline?: boolean;\n /** Optional react-markdown component overrides. */\n components?: Components;\n}\n\nconst defaultComponents: Components = {\n a: ({ href, children, ...props }) => {\n const isExternal =\n typeof href === \"string\" &&\n (href.startsWith(\"http://\") || href.startsWith(\"https://\"));\n return (\n <a\n href={href}\n {...props}\n {...(isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : { rel: \"noopener noreferrer\" })}\n >\n {children}\n </a>\n );\n },\n};\n\n/**\n * Shared markdown renderer for website content.\n *\n * - Uses `react-markdown` for standards-compliant parsing.\n * - Enables GitHub Flavored Markdown (tables, task lists, strikethrough, autolinks).\n * - Sanitizes HTML via `rehype-sanitize` so raw markup in markdown is stripped.\n * - External links open in a new tab with safe rel attributes.\n */\nexport function Markdown({\n children,\n className,\n inline,\n components,\n}: MarkdownProps): ReactNode {\n const content = (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeSanitize]}\n components={{ ...defaultComponents, ...components }}\n {...(inline ? { disallowedElements: [\"p\"], unwrapDisallowed: true } : {})}\n >\n {children}\n </ReactMarkdown>\n );\n\n if (inline) {\n return <span className={className}>{content}</span>;\n }\n\n return <div className={className}>{content}</div>;\n}\n","\"use client\";\n\n/**\n * Self-contained prose styles for SDK content renderers.\n *\n * These components inject a scoped `.boff-prose` stylesheet so markdown content\n * renders correctly even when the host website does not install\n * `@tailwindcss/typography` or define `.prose` CSS.\n */\n\nexport const PROSE_CSS = `\n.boff-prose {\n max-width: none;\n}\n\n.boff-prose h1 {\n font-size: 2.25rem;\n font-weight: 800;\n line-height: 1.2;\n margin-top: 0;\n margin-bottom: 1rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h2 {\n font-size: 1.75rem;\n font-weight: 700;\n line-height: 1.3;\n margin-top: 2rem;\n margin-bottom: 1rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h3 {\n font-size: 1.5rem;\n font-weight: 600;\n line-height: 1.4;\n margin-top: 1.5rem;\n margin-bottom: 0.75rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h4 {\n font-size: 1.25rem;\n font-weight: 600;\n line-height: 1.5;\n margin-top: 1.25rem;\n margin-bottom: 0.5rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose p {\n margin-bottom: 1rem;\n line-height: 1.75;\n color: hsl(var(--foreground));\n}\n\n.boff-prose ul,\n.boff-prose ol {\n margin-bottom: 1rem;\n padding-left: 1.5rem;\n}\n\n.boff-prose ul {\n list-style-type: disc;\n}\n\n.boff-prose ol {\n list-style-type: decimal;\n}\n\n.boff-prose li {\n margin-bottom: 0.25rem;\n line-height: 1.75;\n color: hsl(var(--foreground));\n}\n\n.boff-prose li > ul,\n.boff-prose li > ol {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n\n.boff-prose a {\n color: hsl(var(--primary));\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.boff-prose a:hover {\n opacity: 0.8;\n}\n\n.boff-prose hr {\n border: none;\n height: 1px;\n background-color: hsl(var(--border));\n margin: 2rem 0;\n}\n\n.boff-prose blockquote {\n border-left: 4px solid hsl(var(--border));\n padding-left: 1rem;\n margin: 1.5rem 0;\n font-style: italic;\n color: hsl(var(--muted-foreground));\n}\n\n.boff-prose strong {\n font-weight: 700;\n color: hsl(var(--foreground));\n}\n\n.boff-prose code {\n background-color: hsl(var(--muted));\n padding: 0.125rem 0.25rem;\n border-radius: 0.25rem;\n font-size: 0.875em;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n.boff-prose pre {\n background-color: hsl(var(--muted));\n padding: 1rem;\n border-radius: 0.5rem;\n overflow-x: auto;\n margin-bottom: 1rem;\n}\n\n.boff-prose pre code {\n background-color: transparent;\n padding: 0;\n}\n\n.boff-prose img {\n max-width: 100%;\n height: auto;\n}\n\n.boff-prose table {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: 1rem;\n}\n\n.boff-prose th,\n.boff-prose td {\n border: 1px solid hsl(var(--border));\n padding: 0.5rem;\n text-align: left;\n}\n\n.boff-prose th {\n font-weight: 600;\n background-color: hsl(var(--muted));\n}\n\n/* Smaller variant used inside cards and compact panels */\n.boff-prose-sm {\n font-size: 0.875rem;\n}\n\n.boff-prose-sm h1 {\n font-size: 1.75rem;\n}\n\n.boff-prose-sm h2 {\n font-size: 1.5rem;\n}\n\n.boff-prose-sm h3 {\n font-size: 1.25rem;\n}\n\n.boff-prose-sm h4 {\n font-size: 1.125rem;\n}\n\n.boff-prose-sm p,\n.boff-prose-sm li {\n line-height: 1.625;\n}\n`;\n\nexport function ProseStyles() {\n return <style dangerouslySetInnerHTML={{ __html: PROSE_CSS }} />;\n}\n","const LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst RESERVED_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"x-actor-id\",\n \"x-actor-type\",\n \"x-consent-granted-by\",\n \"x-consent-scope\",\n \"x-consent-granted-at\",\n \"x-consent-expires-at\",\n]);\n\nexport function validateGatewayUrl(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"Gateway URL must be a valid absolute URL\");\n }\n\n if (url.protocol === \"https:\") {\n return url.toString();\n }\n\n if (\n url.protocol === \"http:\" &&\n LOOPBACK_HOSTS.has(url.hostname.toLowerCase())\n ) {\n return url.toString();\n }\n\n throw new Error(\"Gateway URL must use HTTPS unless it targets localhost\");\n}\n\nexport function sanitizeHeaders(\n headers?: Record<string, string>,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([key]) => !RESERVED_HEADERS.has(key.toLowerCase()),\n ),\n );\n}\n\n/**\n * Hostnames whose Cloudflare Access application gates the GraphQL gateway.\n *\n * Only the alpha gateways are gated; the production gateways are public, so a token is never\n * attached there even if one is configured.\n */\nconst CF_ACCESS_GATED_HOSTS = new Set([\n \"alphagraphql.burdenoff.com\",\n \"alphagraphqlworkspaces.burdenoff.com\",\n]);\n\n/**\n * Service-token headers for a gated gateway, or nothing.\n *\n * Returns an empty object unless the target really is a gated host AND both halves of the token\n * are present — a half-configured token would send a malformed credential to every request.\n */\nexport function cfAccessHeaders(\n gatewayUrl: string,\n cfAccess?: { clientId?: string; clientSecret?: string },\n): Record<string, string> {\n const clientId = cfAccess?.clientId?.trim();\n const clientSecret = cfAccess?.clientSecret?.trim();\n if (!clientId || !clientSecret) return {};\n\n let host: string;\n try {\n host = new URL(gatewayUrl).hostname.toLowerCase();\n } catch {\n return {};\n }\n if (!CF_ACCESS_GATED_HOSTS.has(host)) return {};\n\n return {\n \"CF-Access-Client-Id\": clientId,\n \"CF-Access-Client-Secret\": clientSecret,\n };\n}\n","/**\n * Lightweight GraphQL client for the Burdenoff Web SDK.\n * Uses native fetch - zero external dependencies.\n * All calls are unauthenticated (public gateway operations only).\n */\n\nimport {\n cfAccessHeaders,\n sanitizeHeaders,\n validateGatewayUrl,\n} from \"./security\";\n\nexport interface WebSDKClientConfig {\n /** Global public gateway URL (e.g. \"https://api.burdenoff.com/global/graphql\") */\n gatewayUrl: string;\n /** Platform product ID for scoping operations */\n productId: string;\n /** Product slug (used for public product queries) */\n productSlug?: string;\n /** reCAPTCHA site key (if not fetched from product config) */\n recaptchaSiteKey?: string;\n /** Rybbit analytics site ID */\n rybbitSiteId?: string;\n /** Custom headers to include in all requests */\n headers?: Record<string, string>;\n /**\n * Cloudflare Access service token, for the ALPHA gateway hosts only.\n *\n * `alphagraphql.burdenoff.com` sits behind a Cloudflare Access application, so an\n * unauthenticated browser XHR is answered with a 302 to the Access login on a different\n * origin — which the browser reports as an opaque CORS failure rather than a 401. Attaching\n * the service-token headers is how every app shell already passes that gate (fe-libs\n * `installGatewayFetchRewrite`); the website SDK previously had no equivalent, so contact,\n * newsletter, waitlist and explore all failed on alpha.\n *\n * Vite only inlines `VITE_*` into APP source, never into a bundled library, so the host app\n * must read `import.meta.env` and pass the values in. Production gateways are not gated and\n * receive no headers.\n */\n cfAccess?: { clientId?: string; clientSecret?: string };\n /**\n * Per-request timeout in ms. Kept below the gateway's operation timeout so a\n * stalled request surfaces as an error the UI can render, instead of leaving\n * a page stuck on loading skeletons forever. Default 12000.\n */\n timeoutMs?: number;\n /**\n * Extra attempts for transient failures (timeout / network / 5xx / 429) on\n * QUERIES ONLY. Mutations are never retried — a retried contact-form or\n * waitlist submit would double-submit. Default 1 (2 attempts total).\n */\n maxRetries?: number;\n}\n\n/**\n * Per-call overrides for {@link WebSDKClient.query}.\n *\n * The defaults (5-minute response cache + in-flight deduplication) are right\n * for the read-once content queries most SDK components make, and wrong for a\n * poll loop: the second poll of the same `(query, variables)` pair would be\n * served straight from the cache and the UI would freeze on the first\n * response forever. Pass `{ cache: false }` for anything polled.\n */\nexport interface WebSDKQueryOptions {\n /**\n * Use the response cache and in-flight deduplication. Default `true`.\n * `false` skips the cache read, the dedupe map AND the cache write, so the\n * call always hits the network and never poisons a later cached read.\n */\n cache?: boolean;\n /** Override the client-wide request timeout for this call only. */\n timeoutMs?: number;\n}\n\n/** Per-call overrides for {@link WebSDKClient.mutate}. */\nexport interface WebSDKMutateOptions {\n /** Override the client-wide request timeout for this call only. */\n timeoutMs?: number;\n}\n\nexport interface GraphQLResponse<T = Record<string, unknown>> {\n data?: T;\n errors?: Array<{\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n }>;\n}\n\nexport class WebSDKClient {\n private config: WebSDKClientConfig;\n private queryCache = new Map<\n string,\n { data: GraphQLResponse<unknown>; ts: number }\n >();\n private inflight = new Map<string, Promise<GraphQLResponse<unknown>>>();\n private static CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n private static MAX_CACHE_ENTRIES = 100;\n private static DEFAULT_TIMEOUT_MS = 12_000;\n private static DEFAULT_MAX_RETRIES = 1;\n private static RETRY_BASE_DELAY_MS = 400;\n\n constructor(config: WebSDKClientConfig) {\n this.config = {\n ...config,\n gatewayUrl: validateGatewayUrl(config.gatewayUrl),\n headers: sanitizeHeaders(config.headers),\n };\n }\n\n getConfig(): WebSDKClientConfig {\n return this.config;\n }\n\n /**\n * Execute a GraphQL query (with deduplication and caching).\n *\n * Pass `{ cache: false }` to bypass the cache entirely — required for poll\n * loops, where every tick must reach the network.\n */\n async query<T = Record<string, unknown>>(\n query: string,\n variables?: Record<string, unknown>,\n options?: WebSDKQueryOptions,\n ): Promise<GraphQLResponse<T>> {\n // Uncached path: no cache read, no in-flight dedupe, no cache write.\n // Deliberately bypasses the dedupe map too — two identical polls issued a\n // few hundred ms apart must both hit the network, otherwise the second one\n // resolves with the first one's (already stale) snapshot.\n if (options?.cache === false) {\n return this.request<T>(query, variables, true, options.timeoutMs);\n }\n\n const cacheKey = JSON.stringify({ query, variables });\n\n // Return cached response if still valid, evict if expired\n const cached = this.queryCache.get(cacheKey);\n if (cached) {\n if (Date.now() - cached.ts < WebSDKClient.CACHE_TTL) {\n return cached.data as GraphQLResponse<T>;\n }\n this.queryCache.delete(cacheKey);\n }\n\n // Deduplicate: if same query is already in-flight, reuse the promise\n const existing = this.inflight.get(cacheKey);\n if (existing) {\n return existing as Promise<GraphQLResponse<T>>;\n }\n\n const promise = this.request<T>(query, variables, true, options?.timeoutMs)\n .then((result) => {\n // Cache successful responses only\n if (result.data && !result.errors?.length) {\n if (this.queryCache.size >= WebSDKClient.MAX_CACHE_ENTRIES) {\n const oldestEntry = this.queryCache.keys().next().value;\n if (oldestEntry) {\n this.queryCache.delete(oldestEntry);\n }\n }\n this.queryCache.set(cacheKey, { data: result, ts: Date.now() });\n }\n return result;\n })\n .finally(() => {\n this.inflight.delete(cacheKey);\n });\n\n this.inflight.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Execute a GraphQL mutation\n */\n async mutate<T = Record<string, unknown>>(\n mutation: string,\n variables?: Record<string, unknown>,\n options?: WebSDKMutateOptions,\n ): Promise<GraphQLResponse<T>> {\n // retry=false: a retried mutation could double-submit (contact form,\n // waitlist signup, order). Only the timeout applies here.\n return this.request<T>(mutation, variables, false, options?.timeoutMs);\n }\n\n /** HTTP statuses worth another attempt — transient server/edge conditions. */\n private static isRetriableStatus(status: number): boolean {\n return status === 429 || status === 408 || (status >= 500 && status < 600);\n }\n\n private static sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Perform the HTTP call with a hard timeout. Every outcome resolves to a\n * GraphQLResponse — callers never hang, so a UI's `loading` state always\n * settles into data or a renderable error.\n */\n private async attempt<T>(\n query: string,\n variables: Record<string, unknown> | undefined,\n timeoutMs: number,\n ): Promise<{ res: GraphQLResponse<T>; retriable: boolean }> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(this.config.gatewayUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-product-id\": this.config.productId,\n ...this.config.headers,\n ...cfAccessHeaders(this.config.gatewayUrl, this.config.cfAccess),\n },\n body: JSON.stringify({ query, variables }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n console.error(\n \"[WebSDK] GraphQL request failed\",\n response.status,\n response.statusText,\n );\n return {\n res: {\n errors: [\n {\n message: `HTTP ${response.status}: ${response.statusText}`,\n extensions: { code: `HTTP_${response.status}` },\n },\n ],\n },\n retriable: WebSDKClient.isRetriableStatus(response.status),\n };\n }\n\n return {\n res: (await response.json()) as GraphQLResponse<T>,\n retriable: false,\n };\n } catch (error) {\n const aborted =\n error instanceof Error &&\n (error.name === \"AbortError\" || controller.signal.aborted);\n const message = aborted\n ? `Request timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : \"Network error\";\n console.error(\"[WebSDK] Network error\", message);\n return {\n res: {\n errors: [\n {\n message,\n extensions: { code: aborted ? \"TIMEOUT\" : \"NETWORK_ERROR\" },\n },\n ],\n },\n // Transport-level failures are worth one more try; a genuine outage\n // just fails twice quickly and still renders an error state.\n retriable: true,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async request<T>(\n query: string,\n variables?: Record<string, unknown>,\n retry = true,\n timeoutOverrideMs?: number,\n ): Promise<GraphQLResponse<T>> {\n const timeoutMs =\n timeoutOverrideMs ??\n this.config.timeoutMs ??\n WebSDKClient.DEFAULT_TIMEOUT_MS;\n const maxRetries = retry\n ? (this.config.maxRetries ?? WebSDKClient.DEFAULT_MAX_RETRIES)\n : 0;\n\n let last: GraphQLResponse<T> | undefined;\n for (let i = 0; i <= maxRetries; i++) {\n const { res, retriable } = await this.attempt<T>(\n query,\n variables,\n timeoutMs,\n );\n if (!retriable || i === maxRetries) return res;\n last = res;\n // Small backoff with jitter so a burst of clients doesn't retry in lockstep.\n await WebSDKClient.sleep(\n WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200,\n );\n }\n return last as GraphQLResponse<T>;\n }\n}\n","/**\n * React context provider for the Web SDK client.\n * Wraps the application with WebSDKClient configuration.\n */\n\"use client\";\n\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { resolveGatewayUrl } from \"./gateway-resolver\";\nimport { WebSDKClient, type WebSDKClientConfig } from \"./graphql-client\";\n\nconst WebSDKContext = createContext<WebSDKClient | null>(null);\n\nexport interface WebSDKProviderProps {\n /** SDK client configuration */\n config: WebSDKClientConfig;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the WebSDKClient available to all child components.\n *\n * @example\n * ```tsx\n * <WebSDKProvider config={{\n * gatewayUrl: \"https://api.burdenoff.com/global/graphql\",\n * productId: \"your-product-id\",\n * productSlug: \"your-product\",\n * }}>\n * <App />\n * </WebSDKProvider>\n * ```\n */\nexport function WebSDKProvider({ config, children }: WebSDKProviderProps) {\n const client = useMemo(() => {\n const resolvedConfig = {\n ...config,\n gatewayUrl: resolveGatewayUrl(config.gatewayUrl),\n };\n return new WebSDKClient(resolvedConfig);\n }, [config]);\n\n return (\n <WebSDKContext.Provider value={client}>{children}</WebSDKContext.Provider>\n );\n}\n\n/**\n * Hook to access the WebSDKClient instance.\n * Must be used within a WebSDKProvider.\n */\nexport function useWebSDK(): WebSDKClient {\n const client = useContext(WebSDKContext);\n if (!client) {\n throw new Error(\"useWebSDK must be used within a WebSDKProvider\");\n }\n return client;\n}\n\n/**\n * Hook to access the SDK configuration.\n * Useful for components that need config values like productId, recaptchaSiteKey, etc.\n */\nexport function useWebSDKConfig(): WebSDKClientConfig {\n const client = useWebSDK();\n return client.getConfig();\n}\n","/**\n * Explore chat — TypeScript mirror of the public `/explore` GraphQL contract.\n *\n * Canonical source: `~/products/dev/platform/context/explore/CONTRACT.md` §1\n * (global-support-svc, served through the global PUBLIC gateway with\n * `@rbac(public: true, scopeType: \"global\")`).\n *\n * Nothing in this file may drift from that document. If a shape here looks\n * wrong, fix CONTRACT.md first and tell the backend workstreams — never patch\n * it locally.\n *\n * Nullability note: the contract marks `title`, `description`, `product`,\n * `imageUrl`, `partialContent`, `errorCode`, `completedAt`, `productSlug`,\n * `recaptchaSiteKey` and `remainingToday` as nullable, so every one of them is\n * `?: T | null` here — a GraphQL `null` and an omitted selection both have to\n * be representable.\n */\n\n// ============================================================================\n// Enums (string unions — the wire format is the enum name)\n// ============================================================================\n\nexport type ExploreMessageRole = \"USER\" | \"ASSISTANT\";\n\nexport type ExploreMessageStatus =\n \"PENDING\" | \"RUNNING\" | \"COMPLETED\" | \"FAILED\";\n\n/**\n * The `ExploreCta.kind` values enumerated in CONTRACT.md §1.\n *\n * `ExploreCtaLink.kind` is deliberately typed `string`, not this union: the\n * field is `String!` on the wire, and a kind added server-side must render\n * (falling back to the neutral CTA style) rather than break the build of 38\n * websites. Use this union when you are *producing* a kind.\n */\nexport type ExploreCtaKind =\n | \"CONTACT\"\n | \"PARTNERS\"\n | \"PRICING\"\n | \"SERVICES\"\n | \"WAITLIST\"\n | \"STORE\"\n | \"APP\"\n | \"DOCS\"\n | \"OTHER\";\n\n/**\n * Error codes surfaced through `extensions.code`. `HTTP_429` is what the\n * gateway emits when it rate-limits at the edge; the SDK client also produces\n * `TIMEOUT` / `NETWORK_ERROR` for transport failures.\n */\nexport type ExploreErrorCode =\n | \"EXPLORE_DISABLED\"\n | \"RATE_LIMITED\"\n | \"EXPLORE_GLOBAL_LIMIT\"\n | \"CAPTCHA_REQUIRED\"\n | \"CAPTCHA_FAILED\"\n | \"MESSAGE_TOO_LONG\"\n | \"MESSAGE_EMPTY\"\n | \"CONVERSATION_LIMIT\"\n | \"CONVERSATION_BUSY\"\n | \"UPSTREAM_UNAVAILABLE\"\n | \"NOT_FOUND\"\n | \"HTTP_429\"\n | \"TIMEOUT\"\n | \"NETWORK_ERROR\";\n\n// ============================================================================\n// Object types\n// ============================================================================\n\n/** `type ExploreReference` — a cited source page for an answer. */\nexport interface ExploreReference {\n url: string;\n title?: string | null;\n description?: string | null;\n product?: string | null;\n imageUrl?: string | null;\n /** 1-based citation number; the answer text carries a matching `[n]` marker. */\n index?: number | null;\n}\n\n/**\n * `type ExploreCta` — a suggested next step attached to an answer.\n *\n * Named `ExploreCtaLink` in the SDK because `ExploreCta` is taken by the\n * exported nav component (`<ExploreCta variant=\"header\" />`). Same shape,\n * different name; the GraphQL type is unchanged.\n */\nexport interface ExploreCtaLink {\n /** One of {@link ExploreCtaKind}; unknown values render with the neutral style. */\n kind: string;\n label: string;\n url: string;\n product?: string | null;\n}\n\n/** `type ExploreMessage`. `content` is `\"\"` while the turn is PENDING. */\nexport interface ExploreMessage {\n id: string;\n conversationId: string;\n role: ExploreMessageRole;\n status: ExploreMessageStatus;\n /** Final answer, markdown. Empty string until the turn completes. */\n content: string;\n /** Streaming preview while PENDING/RUNNING. */\n partialContent?: string | null;\n /** Human-readable progress lines, e.g. \"Searching vibecontrols…\". */\n activity: string[];\n references: ExploreReference[];\n ctas: ExploreCtaLink[];\n /** Up to three suggested next questions, derived from what the answer covered. */\n followUps?: string[] | null;\n /**\n * False when the corpus could not answer. A grounded answer always cites, so an answer\n * with no source is the honest \"we do not have this\" signal rather than a hedge.\n */\n answered?: boolean | null;\n errorCode?: string | null;\n createdAt: string;\n completedAt?: string | null;\n}\n\n/** `type ExploreConversation`. `token` is the client's only handle. */\nexport interface ExploreConversation {\n id: string;\n token: string;\n productSlug?: string | null;\n turnCount: number;\n createdAt: string;\n}\n\n/** `type ExploreProduct` — one product the harness can answer about. */\nexport interface ExploreProduct {\n slug: string;\n name: string;\n tagline?: string | null;\n website: string;\n}\n\n/** `type ExploreLimits` — server-owned caps the composer enforces locally. */\nexport interface ExploreLimits {\n maxMessageLength: number;\n maxTurnsPerConversation: number;\n messagesPerDay: number;\n historyTurns: number;\n}\n\n/**\n * `type ExploreCatalog` — everything the page needs before the first message.\n *\n * `captchaRequired` + `recaptchaSiteKey` are what turn reCAPTCHA v3 on: it is\n * a backend secret change, and no website redeploy is involved.\n */\nexport interface ExploreCatalog {\n enabled: boolean;\n products: ExploreProduct[];\n examplePrompts: string[];\n welcomeTitle: string;\n welcomeBody: string;\n limits: ExploreLimits;\n captchaRequired: boolean;\n recaptchaSiteKey?: string | null;\n}\n\n/** `input SendExploreMessageInput`. */\nexport interface SendExploreMessageInput {\n /** Omit to start a new conversation. */\n conversationToken?: string;\n /** The site the visitor is on — a soft hint, not a hard filter. */\n productSlug?: string;\n message: string;\n /** Only sent when `catalog.captchaRequired`. */\n recaptchaToken?: string;\n locale?: string;\n pageUrl?: string;\n}\n\n/**\n * `type SendExploreMessageResult`.\n *\n * **`assistantMessage.id` is the id to poll** — it comes back `PENDING`.\n */\nexport interface SendExploreMessageResult {\n conversation: ExploreConversation;\n userMessage: ExploreMessage;\n assistantMessage: ExploreMessage;\n remainingToday?: number | null;\n}\n\n// ============================================================================\n// GraphQL documents\n//\n// Only the fields the UI actually renders are requested — a narrower selection\n// set is cheaper to poll (this runs once every ~1.5s per active visitor) and\n// keeps the contract surface the websites depend on small.\n// ============================================================================\n\n/**\n * Shared selection set for every `ExploreMessage` in this file. Inlined as a\n * template string rather than a GraphQL `fragment` so each document stays a\n * single self-contained operation (the SDK client posts raw strings and has no\n * fragment registry).\n */\nconst EXPLORE_MESSAGE_FIELDS = /* GraphQL */ `\n id\n conversationId\n role\n status\n content\n partialContent\n activity\n references {\n url\n title\n description\n product\n imageUrl\n index\n }\n ctas {\n kind\n label\n url\n product\n }\n followUps\n answered\n errorCode\n createdAt\n completedAt\n`;\n\n/** Loaded once per page. Safe to serve from the SDK's 5-minute query cache. */\nexport const EXPLORE_CATALOG_QUERY = /* GraphQL */ `\n query ExploreCatalog($productSlug: String) {\n exploreCatalog(productSlug: $productSlug) {\n enabled\n products {\n slug\n name\n tagline\n website\n }\n examplePrompts\n welcomeTitle\n welcomeBody\n limits {\n maxMessageLength\n maxTurnsPerConversation\n messagesPerDay\n historyTurns\n }\n captchaRequired\n recaptchaSiteKey\n }\n }\n`;\n\n/**\n * The poll. MUST be issued with `client.query(..., { cache: false })` — the\n * default 5-minute cache would return the first PENDING snapshot forever and\n * the answer would never appear.\n */\nexport const EXPLORE_MESSAGE_QUERY = /* GraphQL */ `\n query ExploreMessage($conversationToken: String!, $id: ID!) {\n exploreMessage(conversationToken: $conversationToken, id: $id) {\n ${EXPLORE_MESSAGE_FIELDS}\n }\n }\n`;\n\n/** Submit half of the submit + poll pair. */\nexport const SEND_EXPLORE_MESSAGE_MUTATION = /* GraphQL */ `\n mutation SendExploreMessage($input: SendExploreMessageInput!) {\n sendExploreMessage(input: $input) {\n conversation {\n id\n token\n productSlug\n turnCount\n createdAt\n }\n userMessage {\n ${EXPLORE_MESSAGE_FIELDS}\n }\n assistantMessage {\n ${EXPLORE_MESSAGE_FIELDS}\n }\n remainingToday\n }\n }\n`;\n\n// ============================================================================\n// Response envelopes (what `client.query`/`client.mutate` resolve `data` to)\n// ============================================================================\n\nexport interface ExploreCatalogQueryData {\n exploreCatalog: ExploreCatalog;\n}\n\nexport interface ExploreMessageQueryData {\n exploreMessage: ExploreMessage | null;\n}\n\nexport interface SendExploreMessageMutationData {\n sendExploreMessage: SendExploreMessageResult;\n}\n\n/**\n * Record that the visitor followed a link the answer offered.\n *\n * Fire-and-forget: the browser is navigating away as this goes out, so the result is never\n * waited on and a failure is never surfaced. The server reports `recorded: false` rather\n * than erroring for anything it cannot attribute.\n */\nexport const RECORD_EXPLORE_CLICK_MUTATION = /* GraphQL */ `\n mutation RecordExploreClick($input: RecordExploreClickInput!) {\n recordExploreClick(input: $input) {\n recorded\n }\n }\n`;\n","import type { WebsiteSwitcherProduct } from \"../components/website-switcher\";\n\n/**\n * Canonical Burdenoff ecosystem product list used by WebsiteSwitcher.\n *\n * Sourced from `~/products/websites/burdenoff-website/src/data/products.ts`.\n * Keep this in sync when products are added, renamed, or moved.\n */\nexport const ECOSYSTEM_PRODUCTS: WebsiteSwitcherProduct[] = [\n {\n slug: \"workspaces\",\n name: \"Workspaces\",\n websiteUrl: \"https://burdenoff.com\",\n },\n {\n slug: \"vibecontrols\",\n name: \"VibeControls\",\n websiteUrl: \"https://vibecontrols.com\",\n },\n {\n slug: \"fluidgrids\",\n name: \"FluidGrids\",\n websiteUrl: \"https://fluidgrids.com\",\n },\n // Botlit ships on botlit.ai — botlit.com does not resolve.\n { slug: \"botlit\", name: \"Botlit\", websiteUrl: \"https://www.botlit.ai\" },\n {\n slug: \"bigconsole\",\n name: \"BigConsole\",\n websiteUrl: \"https://bigconsole.com\",\n },\n {\n slug: \"semanticfed\",\n name: \"SemanticFed\",\n websiteUrl: \"https://semanticfed.com\",\n },\n {\n slug: \"intelwatchtower\",\n name: \"IntelWatchtower\",\n websiteUrl: \"https://intelwatchtower.com\",\n },\n { slug: \"buildmyiq\", name: \"BuildMyIQ\", websiteUrl: \"https://buildmyiq.com\" },\n {\n slug: \"assethandler\",\n name: \"AssetHandler\",\n websiteUrl: \"https://assethandler.com\",\n },\n {\n slug: \"crewfoundry\",\n name: \"CrewFoundry\",\n websiteUrl: \"https://crewfoundry.com\",\n },\n {\n slug: \"planmagnet\",\n name: \"PlanMagnet\",\n websiteUrl: \"https://planmagnet.com\",\n },\n {\n slug: \"eventfullymanaged\",\n name: \"EventfullyManaged\",\n websiteUrl: \"https://eventfullymanaged.com\",\n },\n {\n slug: \"headshotmarketing\",\n name: \"HeadshotMarketing\",\n websiteUrl: \"https://headshotmarketing.com\",\n },\n {\n slug: \"technospam\",\n name: \"TechnoSpam\",\n websiteUrl: \"https://technospam.com\",\n },\n { slug: \"kadaikodi\", name: \"Kadaikodi\", websiteUrl: \"https://kadaikodi.com\" },\n {\n slug: \"movethewheels\",\n name: \"MoveTheWheels\",\n websiteUrl: \"https://movethewheels.com\",\n },\n {\n slug: \"healthybowl\",\n name: \"Healthy Bowl\",\n websiteUrl: \"https://gethealthybowl.com\",\n },\n { slug: \"ggnomad\", name: \"GGNomad\", websiteUrl: \"https://ggnomad.com\" },\n {\n slug: \"timecampus\",\n name: \"TimeCampus\",\n websiteUrl: \"https://timecampus.com\",\n },\n {\n slug: \"manufacturedops\",\n name: \"ManufacturedOps\",\n websiteUrl: \"https://manufacturedops.com\",\n },\n {\n slug: \"theglobalfuel\",\n name: \"TheGlobalFuel\",\n websiteUrl: \"https://theglobalfuel.com\",\n },\n {\n slug: \"housingvista\",\n name: \"HousingVista\",\n websiteUrl: \"https://housingvista.com\",\n },\n {\n slug: \"proserviceworld\",\n name: \"ProServiceWorld\",\n websiteUrl: \"https://proserviceworld.com\",\n },\n {\n slug: \"mybodyshield\",\n name: \"MyBodyShield\",\n websiteUrl: \"https://mybodyshield.com\",\n },\n {\n slug: \"artistrybase\",\n name: \"ArtistryBase\",\n websiteUrl: \"https://artistrybase.com\",\n },\n {\n slug: \"theculturepost\",\n name: \"TheCulturePost\",\n websiteUrl: \"https://theculturepost.com\",\n },\n { slug: \"collabkin\", name: \"CollabKin\", websiteUrl: \"https://collabkin.com\" },\n {\n slug: \"comradecircle\",\n name: \"ComradeCircle\",\n websiteUrl: \"https://comradecircle.com\",\n },\n {\n slug: \"brainyrich\",\n name: \"BrainyRich\",\n websiteUrl: \"https://brainyrich.com\",\n },\n {\n slug: \"cosmicintersection\",\n name: \"CosmicIntersection\",\n websiteUrl: \"https://cosmicintersection.com\",\n },\n {\n slug: \"govcitizenhub\",\n name: \"GovCitizenHub\",\n websiteUrl: \"https://govcitizenhub.com\",\n },\n {\n slug: \"adaptercloud\",\n name: \"AdapterCloud\",\n websiteUrl: \"https://adaptercloud.com\",\n },\n {\n slug: \"subscriberbot\",\n name: \"Subscriber Bot\",\n websiteUrl: \"https://subscriberbot.com\",\n },\n {\n slug: \"hookmovies\",\n name: \"HookMovies\",\n websiteUrl: \"https://hookmovies.com\",\n },\n {\n slug: \"coolandlovely\",\n name: \"CoolAndLovely\",\n websiteUrl: \"https://coolandlovely.com\",\n },\n {\n slug: \"atheletebridge\",\n name: \"AthleteBridge\",\n websiteUrl: \"https://atheletebridge.com\",\n },\n {\n slug: \"labsofscience\",\n name: \"LabsOfScience\",\n websiteUrl: \"https://labsofscience.com\",\n },\n {\n slug: \"ecoimpacthub\",\n name: \"EcoImpactHub\",\n websiteUrl: \"https://ecoimpacthub.com\",\n },\n];\n","/**\n * reCAPTCHA v3 (invisible, score-based) loader and token minter.\n *\n * Deliberately dependency-free: the SDK already ships the `react-google-recaptcha`\n * peer for the **v2 checkbox** used by `ContactPage`, and the two widgets cannot\n * share a script tag — v3 needs `?render=<siteKey>` on the URL, v2 must not have\n * it. This module injects its own v3 script and leaves the v2 integration alone.\n *\n * The Explore chat turns v3 on purely from the backend catalog\n * (`exploreCatalog.captchaRequired && recaptchaSiteKey`), so nothing is loaded\n * and no third-party request is made on sites where captcha is off.\n */\n\n/** The slice of the `grecaptcha` global this module uses. */\nexport interface RecaptchaV3 {\n /** Runs the callback once the API is fully initialised. */\n ready(callback: () => void): void;\n /** Mints a single-use token for `action`. */\n execute(siteKey: string, options: { action: string }): Promise<string>;\n}\n\ndeclare global {\n interface Window {\n grecaptcha?: RecaptchaV3;\n }\n}\n\nconst SCRIPT_ID = \"boff-recaptcha-v3\";\nconst SCRIPT_SRC = \"https://www.google.com/recaptcha/api.js?render=\";\n\n/** Default action name reported to reCAPTCHA for Explore chat submissions. */\nexport const EXPLORE_RECAPTCHA_ACTION = \"explore_chat\";\n\n/**\n * One in-flight/settled promise per site key. Guarantees the script tag is\n * injected at most once even when several components mount at the same time,\n * and lets later callers await the same load instead of racing it.\n */\nconst loaders = new Map<string, Promise<RecaptchaV3>>();\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/**\n * Load the reCAPTCHA v3 script for `siteKey` and resolve once `grecaptcha` is\n * ready to mint tokens.\n *\n * - Injects the script at most once per site key (subsequent calls reuse the\n * same promise).\n * - Adopts an already-present script tag (e.g. injected by the host site)\n * rather than adding a second one.\n * - Rejects rather than hanging when the script fails to load, so the caller\n * can decide whether to submit without a token or surface an error.\n */\nexport function loadRecaptchaV3(siteKey: string): Promise<RecaptchaV3> {\n if (!siteKey) {\n return Promise.reject(new Error(\"reCAPTCHA site key is required\"));\n }\n if (!isBrowser()) {\n return Promise.reject(\n new Error(\"reCAPTCHA v3 can only be loaded in a browser\"),\n );\n }\n\n const existing = loaders.get(siteKey);\n if (existing) return existing;\n\n const promise = new Promise<RecaptchaV3>((resolve, reject) => {\n const ready = () => {\n const api = window.grecaptcha;\n if (!api) {\n reject(new Error(\"reCAPTCHA loaded but grecaptcha is unavailable\"));\n return;\n }\n // `ready` queues until the API has finished initialising internally;\n // calling `execute` before that throws.\n api.ready(() => resolve(api));\n };\n\n // Already loaded by this module, another SDK instance, or the host site.\n if (window.grecaptcha) {\n ready();\n return;\n }\n\n const scriptId = `${SCRIPT_ID}-${siteKey}`;\n const found = document.getElementById(scriptId);\n if (found) {\n found.addEventListener(\"load\", ready, { once: true });\n found.addEventListener(\n \"error\",\n () => reject(new Error(\"Failed to load reCAPTCHA v3\")),\n { once: true },\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.id = scriptId;\n script.src = `${SCRIPT_SRC}${encodeURIComponent(siteKey)}`;\n script.async = true;\n script.defer = true;\n script.addEventListener(\"load\", ready, { once: true });\n script.addEventListener(\n \"error\",\n () => {\n // Drop the memo so a later attempt can retry a transient CDN failure\n // instead of being stuck with a permanently rejected promise.\n loaders.delete(siteKey);\n reject(new Error(\"Failed to load reCAPTCHA v3\"));\n },\n { once: true },\n );\n document.head.appendChild(script);\n });\n\n loaders.set(siteKey, promise);\n return promise;\n}\n\n/**\n * Mint a single-use reCAPTCHA v3 token, loading the script on first use.\n *\n * Tokens are valid for ~2 minutes and are consumed by one verification, so\n * this must be called per submission — never cached.\n */\nexport async function getRecaptchaV3Token(\n siteKey: string,\n action: string = EXPLORE_RECAPTCHA_ACTION,\n): Promise<string> {\n const api = await loadRecaptchaV3(siteKey);\n return api.execute(siteKey, { action });\n}\n","/**\n * useExploreChat — the `/explore` conversation state machine.\n *\n * Implements the client half of CONTRACT.md §1: a **submit + poll** exchange.\n * `sendExploreMessage` returns immediately with a PENDING assistant message;\n * the answer arrives by polling `exploreMessage(conversationToken, id)` roughly\n * every 1.5s until it reports COMPLETED or FAILED. Both gateway hops cap a\n * subgraph call at 20s while a turn takes 5-60s, which is why there is no\n * request that simply waits for the answer.\n *\n * Design rules this hook exists to enforce:\n *\n * 1. **The catalog never gates the first paint.** `catalog` is populated with a\n * static fallback synchronously, so `ExplorePage` can render its `<h1>` on\n * the very first render. The websites' prerender waits for an `h1`; if that\n * heading depended on a network round-trip, 38 static builds would capture a\n * blank page.\n * 2. **Polls bypass the query cache.** `client.query(..., { cache: false })` —\n * the default 5-minute cache would hand every later poll the first PENDING\n * snapshot and the answer would never appear.\n * 3. **Nothing outlives the component.** Unmount and `stop()` both cancel the\n * poll chain through a generation counter, so a late response can never\n * write into an unmounted tree.\n */\n\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { useWebSDK } from \"../client/provider\";\nimport {\n EXPLORE_CATALOG_QUERY,\n EXPLORE_MESSAGE_QUERY,\n RECORD_EXPLORE_CLICK_MUTATION,\n SEND_EXPLORE_MESSAGE_MUTATION,\n} from \"../components/explore-types\";\nimport { ECOSYSTEM_PRODUCTS } from \"../data/products\";\nimport { getRecaptchaV3Token } from \"../utils/recaptcha-v3\";\n\nimport type {\n ExploreCatalog,\n ExploreCatalogQueryData,\n ExploreLimits,\n ExploreMessage,\n ExploreMessageQueryData,\n SendExploreMessageInput,\n SendExploreMessageMutationData,\n} from \"../components/explore-types\";\n\n// ============================================================================\n// Public types\n// ============================================================================\n\n/**\n * Where the conversation is right now.\n *\n * - `loading` — catalog request in flight (the fallback catalog is already\n * rendered, so this is a refinement, not a blank screen).\n * - `ready` — idle; the composer accepts input.\n * - `sending` — `sendExploreMessage` in flight.\n * - `streaming` — polling the assistant turn; `activity` is live.\n * - `error` — the last turn failed; `retry()` is meaningful and the\n * composer stays usable.\n * - `limited` — rate limited; the composer is disabled.\n * - `disabled` — `exploreCatalog.enabled === false`.\n */\nexport type ExploreChatPhase =\n | \"loading\"\n | \"ready\"\n | \"sending\"\n | \"streaming\"\n | \"error\"\n | \"limited\"\n | \"disabled\";\n\n/** Coarse bucket the UI switches its banner copy and affordances on. */\nexport type ExploreChatErrorKind =\n | \"rate-limit\"\n | \"captcha\"\n | \"timeout\"\n | \"network\"\n | \"disabled\"\n | \"validation\"\n | \"unknown\";\n\nexport interface ExploreChatError {\n /** UI bucket. */\n kind: ExploreChatErrorKind;\n /** Raw `extensions.code` (or a client-side code such as `TIMEOUT`). */\n code: string;\n /** Human-readable, safe to render. */\n message: string;\n /** Whether re-sending the same message could plausibly succeed. */\n retryable: boolean;\n}\n\nexport interface UseExploreChatOptions {\n /** Slug of the product site this page is on — a soft hint to the harness. */\n productSlug?: string;\n /** Full URL of the page, forwarded as `pageUrl`. */\n pageUrl?: string;\n /** BCP-47 locale, forwarded as `locale`. */\n locale?: string;\n /** Poll cadence in ms. Default 1500 (CONTRACT.md §1). */\n pollIntervalMs?: number;\n /** Give up on a turn after this long. Default 90000 (the edge poll timeout). */\n pollTimeoutMs?: number;\n /**\n * Prompts to offer when `exploreCatalog` supplies none. Resolution order is\n * catalog → this option → {@link DEFAULT_EXPLORE_EXAMPLE_PROMPTS}, so a site\n * can ship product-specific prompts without waiting on the backend and still\n * be overridden centrally once the catalog carries them.\n */\n examplePrompts?: string[];\n /** localStorage key for the ACTIVE conversation. Default `boff.explore.v1`. */\n storageKey?: string;\n /** Persist the conversation across reloads within the tab. Default true. */\n persist?: boolean;\n /** Called with the message text each time a send is accepted locally. */\n onSend?: (message: string) => void;\n}\n\nexport interface UseExploreChatResult {\n phase: ExploreChatPhase;\n /** Never null — starts as the static fallback, upgraded by the server. */\n catalog: ExploreCatalog;\n messages: ExploreMessage[];\n /** Latest progress line of the in-flight turn, or null when idle. */\n activity: string | null;\n /** Messages left today for this visitor, when the server reports it. */\n remainingToday: number | null;\n error: ExploreChatError | null;\n /** Product the visitor pinned the conversation to, or null for \"all\". */\n focusProduct: string | null;\n setFocusProduct: (slug: string | null) => void;\n send: (message: string) => Promise<void>;\n /** Stop polling and keep whatever text has streamed so far. */\n stop: () => void;\n /** Re-send the last message after a failed turn. */\n retry: () => void;\n /** Clear the conversation and the persisted session. */\n reset: () => void;\n /** Past conversations held in THIS browser, newest first. */\n history: ArchivedExploreConversation[];\n /** Reopen a past conversation and continue it. */\n openConversation: (token: string) => void;\n /** Forget one past conversation (local only). */\n deleteConversation: (token: string) => void;\n /** Forget every past conversation held in this browser. */\n clearHistory: () => void;\n /**\n * Record that the visitor followed a link this answer offered. Fire-and-forget — never\n * awaited, never throws, and must never delay the navigation it is reporting on.\n */\n recordClick: (\n messageId: string,\n kind: \"CTA\" | \"REFERENCE\",\n url: string,\n ) => void;\n canSend: boolean;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_STORAGE_KEY = \"boff.explore.v1\";\n/** Where past conversations live. Derived from the active key so a custom key stays paired. */\nconst HISTORY_SUFFIX = \".history\";\n/**\n * How many past conversations to keep, and how many messages of each. Bounded on purpose:\n * localStorage is a few MB per origin and shared with everything else the site stores, so an\n * unbounded archive would eventually start throwing QuotaExceededError on write.\n */\nconst MAX_ARCHIVED_CONVERSATIONS = 15;\nconst MAX_ARCHIVED_MESSAGES = 20;\nconst DEFAULT_POLL_INTERVAL_MS = 1_500;\n/** Matches `EXPLORE_AGENT_TIMEOUT_MS` (CONTRACT.md §3) — the edge gives up too. */\nconst DEFAULT_POLL_TIMEOUT_MS = 90_000;\n/** Per-poll HTTP timeout. Short: a stuck poll must not stall the chain. */\nconst POLL_REQUEST_TIMEOUT_MS = 10_000;\n/** The submit hop enqueues a job; generous but well under the gateway's 20s. */\nconst SEND_REQUEST_TIMEOUT_MS = 18_000;\n/** Transient poll failures tolerated before the turn is declared dead. */\nconst MAX_CONSECUTIVE_POLL_FAILURES = 4;\n/** Cap on what goes into localStorage — a conversation must not grow unbounded. */\nconst MAX_PERSISTED_MESSAGES = 40;\n\n/** Fallback limits, mirroring the server defaults in CONTRACT.md §3. */\nexport const FALLBACK_EXPLORE_LIMITS: ExploreLimits = {\n maxMessageLength: 2000,\n maxTurnsPerConversation: 20,\n messagesPerDay: 100,\n historyTurns: 6,\n};\n\n/**\n * Prompts shown when neither the catalog nor the consumer supplies any.\n * Deliberately product-agnostic — this SDK renders on 38 different sites.\n */\nexport const DEFAULT_EXPLORE_EXAMPLE_PROMPTS: string[] = [\n \"What does this product actually do?\",\n \"Which Burdenoff product fits my team?\",\n \"How do I get started, step by step?\",\n \"What does it integrate with?\",\n];\n\nconst FALLBACK_WELCOME_TITLE = \"Ask anything about our products\";\nconst FALLBACK_WELCOME_BODY =\n \"Get straight answers drawn from our product documentation and public pages — with links back to the exact page each answer came from.\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction buildFallbackCatalog(examplePrompts?: string[]): ExploreCatalog {\n return {\n enabled: true,\n products: ECOSYSTEM_PRODUCTS.map((p) => ({\n slug: p.slug,\n name: p.name,\n tagline: null,\n website: p.websiteUrl,\n })),\n examplePrompts: examplePrompts?.length\n ? examplePrompts\n : DEFAULT_EXPLORE_EXAMPLE_PROMPTS,\n welcomeTitle: FALLBACK_WELCOME_TITLE,\n welcomeBody: FALLBACK_WELCOME_BODY,\n limits: FALLBACK_EXPLORE_LIMITS,\n captchaRequired: false,\n recaptchaSiteKey: null,\n };\n}\n\n/**\n * Harden a server catalog against partial/degraded responses so a missing\n * field can never blank the page or produce `maxMessageLength: 0` (which would\n * silently disable the composer).\n */\nfunction normalizeCatalog(\n raw: ExploreCatalog,\n fallback: ExploreCatalog,\n): ExploreCatalog {\n return {\n enabled: raw.enabled !== false,\n products: raw.products?.length ? raw.products : fallback.products,\n examplePrompts: raw.examplePrompts?.length\n ? raw.examplePrompts\n : fallback.examplePrompts,\n welcomeTitle: raw.welcomeTitle || fallback.welcomeTitle,\n welcomeBody: raw.welcomeBody || fallback.welcomeBody,\n limits: {\n maxMessageLength:\n raw.limits?.maxMessageLength || fallback.limits.maxMessageLength,\n maxTurnsPerConversation:\n raw.limits?.maxTurnsPerConversation ||\n fallback.limits.maxTurnsPerConversation,\n messagesPerDay:\n raw.limits?.messagesPerDay || fallback.limits.messagesPerDay,\n historyTurns: raw.limits?.historyTurns || fallback.limits.historyTurns,\n },\n captchaRequired: raw.captchaRequired === true,\n recaptchaSiteKey: raw.recaptchaSiteKey ?? null,\n };\n}\n\nconst RATE_LIMIT_CODES = new Set([\n \"RATE_LIMITED\",\n \"HTTP_429\",\n \"EXPLORE_GLOBAL_LIMIT\",\n]);\nconst CAPTCHA_CODES = new Set([\"CAPTCHA_FAILED\", \"CAPTCHA_REQUIRED\"]);\nconst NETWORK_CODES = new Set([\n \"NETWORK_ERROR\",\n \"UPSTREAM_UNAVAILABLE\",\n \"CONVERSATION_BUSY\",\n \"PROVIDER_ERROR\",\n \"QUEUE_FULL\",\n]);\nconst VALIDATION_CODES = new Set([\n \"MESSAGE_TOO_LONG\",\n \"MESSAGE_EMPTY\",\n \"CONVERSATION_LIMIT\",\n \"INVALID_INPUT\",\n]);\n\n/**\n * Map a `extensions.code` (or a client-side transport code) onto the bucket the\n * UI renders. Unknown codes are treated as retryable — a transient backend\n * condition we have not enumerated is far more likely than a permanent one.\n */\nexport function classifyExploreError(\n code: string | null | undefined,\n serverMessage?: string | null,\n): ExploreChatError {\n const c = code ?? \"UNKNOWN\";\n if (RATE_LIMIT_CODES.has(c)) {\n return {\n kind: \"rate-limit\",\n code: c,\n message:\n \"You've reached the message limit for now. Please try again later.\",\n retryable: false,\n };\n }\n if (CAPTCHA_CODES.has(c)) {\n return {\n kind: \"captcha\",\n code: c,\n message:\n \"We couldn't verify that you're human. Please try sending that again.\",\n retryable: true,\n };\n }\n if (c === \"TIMEOUT\" || c === \"TOOL_BUDGET\") {\n return {\n kind: \"timeout\",\n code: c,\n message: \"That answer took too long to come back. Try asking again.\",\n retryable: true,\n };\n }\n if (NETWORK_CODES.has(c)) {\n return {\n kind: \"network\",\n code: c,\n message:\n \"We couldn't reach the assistant just now. Check your connection and try again.\",\n retryable: true,\n };\n }\n if (c === \"EXPLORE_DISABLED\") {\n return {\n kind: \"disabled\",\n code: c,\n message: \"Explore is unavailable at the moment. Please check back soon.\",\n retryable: false,\n };\n }\n if (VALIDATION_CODES.has(c)) {\n return {\n kind: \"validation\",\n code: c,\n message: serverMessage || \"That message couldn't be sent.\",\n retryable: false,\n };\n }\n if (c === \"EMPTY_ANSWER\") {\n return {\n kind: \"unknown\",\n code: c,\n message:\n \"No answer came back for that one. Try rephrasing, or ask something more specific.\",\n retryable: true,\n };\n }\n return {\n kind: \"unknown\",\n code: c,\n message: serverMessage || \"Something went wrong. Please try again.\",\n retryable: true,\n };\n}\n\ninterface PersistedExploreState {\n conversationToken: string | null;\n messages: ExploreMessage[];\n focusProduct: string | null;\n}\n\n/** One past conversation, as shown in the history list and restored on click. */\nexport interface ArchivedExploreConversation {\n token: string;\n /** First thing the visitor asked — the human-readable label for the thread. */\n title: string;\n /** ISO timestamp of the last message in the thread. */\n updatedAt: string;\n messageCount: number;\n focusProduct: string | null;\n messages: ExploreMessage[];\n}\n\nfunction historyKey(key: string): string {\n return `${key}${HISTORY_SUFFIX}`;\n}\n\nfunction readArchive(key: string): ArchivedExploreConversation[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = window.localStorage.getItem(historyKey(key));\n if (!raw) return [];\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (entry): entry is ArchivedExploreConversation =>\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as ArchivedExploreConversation).token === \"string\" &&\n Array.isArray((entry as ArchivedExploreConversation).messages),\n );\n } catch {\n return [];\n }\n}\n\nfunction writeArchive(\n key: string,\n entries: ArchivedExploreConversation[],\n): void {\n if (typeof window === \"undefined\") return;\n try {\n if (entries.length === 0) {\n window.localStorage.removeItem(historyKey(key));\n return;\n }\n window.localStorage.setItem(historyKey(key), JSON.stringify(entries));\n } catch {\n /* private mode or quota — the archive is a convenience, never load-bearing */\n }\n}\n\n/**\n * Fold the given thread into the archive, newest first.\n *\n * Upsert by token rather than append: the same conversation is archived after every completed\n * turn so an abruptly closed tab still leaves a record, and appending would fill the list with\n * duplicates of one thread.\n */\nfunction upsertArchive(\n key: string,\n thread: {\n token: string | null;\n messages: ExploreMessage[];\n focusProduct: string | null;\n },\n): ArchivedExploreConversation[] {\n if (!thread.token) return readArchive(key);\n const real = thread.messages.filter(\n (m) => m.content.trim() !== \"\" || m.role === \"USER\",\n );\n if (real.length === 0) return readArchive(key);\n\n const firstUser = real.find((m) => m.role === \"USER\");\n const entry: ArchivedExploreConversation = {\n token: thread.token,\n title: (firstUser?.content ?? \"Conversation\").trim().slice(0, 80),\n updatedAt: real[real.length - 1]?.createdAt ?? new Date().toISOString(),\n messageCount: real.length,\n focusProduct: thread.focusProduct,\n messages: real.slice(-MAX_ARCHIVED_MESSAGES),\n };\n\n const rest = readArchive(key).filter((e) => e.token !== entry.token);\n const next = [entry, ...rest].slice(0, MAX_ARCHIVED_CONVERSATIONS);\n writeArchive(key, next);\n return next;\n}\n\nfunction readPersisted(key: string): PersistedExploreState | null {\n // SSR / prerender: there is no localStorage, and reading one during the\n // first client render would desync hydration anyway.\n if (typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(key);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\") return null;\n const record = parsed as Partial<PersistedExploreState>;\n return {\n conversationToken:\n typeof record.conversationToken === \"string\"\n ? record.conversationToken\n : null,\n messages: Array.isArray(record.messages)\n ? record.messages.slice(-MAX_PERSISTED_MESSAGES)\n : [],\n focusProduct:\n typeof record.focusProduct === \"string\" ? record.focusProduct : null,\n };\n } catch {\n /* corrupt or unavailable storage — start a fresh conversation */\n return null;\n }\n}\n\n/**\n * A turn that never produced any text is worth dropping rather than rendering\n * as an empty bubble — used by `stop()` and by the failure paths.\n */\nfunction visibleText(message: ExploreMessage): string {\n return message.content || message.partialContent || \"\";\n}\n\nfunction countUserTurns(messages: ExploreMessage[]): number {\n return messages.filter((m) => m.role === \"USER\").length;\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useExploreChat(\n options: UseExploreChatOptions = {},\n): UseExploreChatResult {\n const {\n productSlug,\n pageUrl,\n locale,\n examplePrompts,\n pollIntervalMs = DEFAULT_POLL_INTERVAL_MS,\n pollTimeoutMs = DEFAULT_POLL_TIMEOUT_MS,\n storageKey = DEFAULT_STORAGE_KEY,\n persist = true,\n onSend,\n } = options;\n\n const client = useWebSDK();\n\n // The fallback catalog is the initial value AND the merge base for the\n // server response. Keyed on the prompt CONTENT, not the array identity —\n // a consumer passing an inline `examplePrompts={[...]}` literal would\n // otherwise rebuild it every render and re-fire the catalog effect.\n const promptKey = JSON.stringify(examplePrompts ?? []);\n const fallbackCatalog = useMemo(\n () => buildFallbackCatalog(JSON.parse(promptKey) as string[]),\n [promptKey],\n );\n\n const [catalog, setCatalog] = useState<ExploreCatalog>(fallbackCatalog);\n const [messages, setMessages] = useState<ExploreMessage[]>([]);\n const [phase, setPhase] = useState<ExploreChatPhase>(\"loading\");\n const [error, setError] = useState<ExploreChatError | null>(null);\n const [remainingToday, setRemainingToday] = useState<number | null>(null);\n const [focusProduct, setFocusProductState] = useState<string | null>(null);\n const [turnCount, setTurnCount] = useState(0);\n // Mirror of `messages` for callbacks that must not re-create on every message.\n const messagesRef = useRef<ExploreMessage[]>([]);\n const [archive, setArchive] = useState<ArchivedExploreConversation[]>([]);\n\n const [hydrated, setHydrated] = useState(false);\n\n // Refs mirror the state that async callbacks read, so `send`/`poll` never\n // close over a stale value and never need to be re-created mid-flight.\n const mountedRef = useRef(true);\n const pollGenerationRef = useRef(0);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const conversationTokenRef = useRef<string | null>(null);\n const catalogRef = useRef<ExploreCatalog>(fallbackCatalog);\n const turnCountRef = useRef(0);\n const focusProductRef = useRef<string | null>(null);\n const lastSentTextRef = useRef<string | null>(null);\n const inFlightRef = useRef(false);\n\n catalogRef.current = catalog;\n\n const clearPollTimer = useCallback(() => {\n if (pollTimerRef.current !== null) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n }, []);\n\n /** Invalidate any running poll chain. Late responses become no-ops. */\n const cancelPolling = useCallback(() => {\n pollGenerationRef.current += 1;\n clearPollTimer();\n }, [clearPollTimer]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n pollGenerationRef.current += 1;\n if (pollTimerRef.current !== null) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n };\n }, []);\n\n // --------------------------------------------------------------------------\n // Hydrate from localStorage (effect, not lazy state, so the FIRST client\n // render matches the prerendered HTML and hydration stays clean).\n // --------------------------------------------------------------------------\n useEffect(() => {\n if (!persist) {\n setHydrated(true);\n return;\n }\n setArchive(readArchive(storageKey));\n const stored = readPersisted(storageKey);\n if (stored) {\n conversationTokenRef.current = stored.conversationToken;\n focusProductRef.current = stored.focusProduct;\n // A turn that was still streaming when the tab was closed can never be\n // resumed from here — the poll chain is gone. Land it as-is.\n const settled = stored.messages.flatMap<ExploreMessage>((m) => {\n if (m.role !== \"ASSISTANT\") return [m];\n if (m.status !== \"PENDING\" && m.status !== \"RUNNING\") return [m];\n const text = visibleText(m);\n if (!text) return [];\n return [{ ...m, status: \"COMPLETED\", content: text }];\n });\n setMessages(settled);\n setFocusProductState(stored.focusProduct);\n const turns = countUserTurns(settled);\n turnCountRef.current = turns;\n setTurnCount(turns);\n }\n setHydrated(true);\n }, [persist, storageKey]);\n\n // --------------------------------------------------------------------------\n // Persist (after hydration, so the initial empty state never wipes storage).\n // --------------------------------------------------------------------------\n useEffect(() => {\n if (!persist || !hydrated || typeof window === \"undefined\") return;\n try {\n const payload: PersistedExploreState = {\n conversationToken: conversationTokenRef.current,\n messages: messages.slice(-MAX_PERSISTED_MESSAGES),\n focusProduct,\n };\n // Nothing worth restoring (fresh page, or just after reset()): drop the\n // key entirely rather than leaving an empty husk behind.\n if (\n !payload.conversationToken &&\n payload.messages.length === 0 &&\n !payload.focusProduct\n ) {\n window.localStorage.removeItem(storageKey);\n return;\n }\n window.localStorage.setItem(storageKey, JSON.stringify(payload));\n } catch {\n /* private mode / quota exceeded — persistence is a nicety, not a feature */\n }\n }, [persist, hydrated, storageKey, messages, focusProduct]);\n\n // Mirror messages into a ref for callbacks, and fold a settled thread into the archive.\n // Archiving on every settled turn (not only on reset) is what makes an abruptly closed tab\n // still leave a record the visitor can come back to.\n useEffect(() => {\n messagesRef.current = messages;\n if (!persist || !hydrated) return;\n const settled = messages.some(\n (m) =>\n m.role === \"ASSISTANT\" &&\n (m.status === \"COMPLETED\" || m.status === \"FAILED\"),\n );\n if (!settled) return;\n setArchive(\n upsertArchive(storageKey, {\n token: conversationTokenRef.current,\n messages,\n focusProduct: focusProductRef.current,\n }),\n );\n }, [messages, persist, hydrated, storageKey]);\n\n // --------------------------------------------------------------------------\n // Catalog. Cached (the default) — it is per-page-load configuration, not a\n // poll. A failure keeps the fallback so the page NEVER renders blank.\n // --------------------------------------------------------------------------\n useEffect(() => {\n let cancelled = false;\n const load = async () => {\n const res = await client.query<ExploreCatalogQueryData>(\n EXPLORE_CATALOG_QUERY,\n { productSlug: productSlug ?? null },\n );\n if (cancelled || !mountedRef.current) return;\n\n const raw = res.data?.exploreCatalog;\n if (res.errors?.length || !raw) {\n console.warn(\n \"[WebSDK] exploreCatalog unavailable — using the built-in fallback catalog\",\n res.errors?.[0]?.message,\n );\n setPhase((prev) => (prev === \"loading\" ? \"ready\" : prev));\n return;\n }\n\n const next = normalizeCatalog(raw, fallbackCatalog);\n setCatalog(next);\n catalogRef.current = next;\n setPhase((prev) => {\n if (!next.enabled) return \"disabled\";\n return prev === \"loading\" ? \"ready\" : prev;\n });\n };\n void load();\n return () => {\n cancelled = true;\n };\n }, [client, productSlug, fallbackCatalog]);\n\n // --------------------------------------------------------------------------\n // Poll chain\n // --------------------------------------------------------------------------\n const startPolling = useCallback(\n (conversationToken: string, messageId: string) => {\n pollGenerationRef.current += 1;\n const generation = pollGenerationRef.current;\n const startedAt = Date.now();\n let consecutiveFailures = 0;\n\n const isStale = () =>\n !mountedRef.current || generation !== pollGenerationRef.current;\n\n const finishWithError = (chatError: ExploreChatError) => {\n inFlightRef.current = false;\n setMessages((prev) =>\n prev.flatMap<ExploreMessage>((m) => {\n if (m.id !== messageId) return [m];\n const text = visibleText(m);\n if (!text) return [];\n return [{ ...m, status: \"FAILED\", content: text }];\n }),\n );\n setError(chatError);\n setPhase(chatError.kind === \"rate-limit\" ? \"limited\" : \"error\");\n };\n\n const tick = async () => {\n if (isStale()) return;\n\n if (Date.now() - startedAt > pollTimeoutMs) {\n finishWithError(classifyExploreError(\"TIMEOUT\"));\n return;\n }\n\n // `cache: false` is load-bearing — see CONTRACT.md §4.\n const res = await client.query<ExploreMessageQueryData>(\n EXPLORE_MESSAGE_QUERY,\n { conversationToken, id: messageId },\n { cache: false, timeoutMs: POLL_REQUEST_TIMEOUT_MS },\n );\n if (isStale()) return;\n\n const first = res.errors?.[0];\n if (first) {\n const code =\n typeof first.extensions?.code === \"string\"\n ? first.extensions.code\n : undefined;\n const classified = classifyExploreError(code, first.message);\n // Hard stops: retrying a rate limit or a disabled feature is pointless.\n if (!classified.retryable) {\n finishWithError(classified);\n return;\n }\n consecutiveFailures += 1;\n if (consecutiveFailures >= MAX_CONSECUTIVE_POLL_FAILURES) {\n finishWithError(classified);\n return;\n }\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n return;\n }\n\n const message = res.data?.exploreMessage;\n if (!message) {\n // Can happen briefly right after submit; tolerate a few misses.\n consecutiveFailures += 1;\n if (consecutiveFailures >= MAX_CONSECUTIVE_POLL_FAILURES) {\n finishWithError(classifyExploreError(\"NOT_FOUND\"));\n return;\n }\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n return;\n }\n\n consecutiveFailures = 0;\n // Replace in place so `partialContent` renders as it streams.\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? message : m)),\n );\n\n if (message.status === \"COMPLETED\") {\n inFlightRef.current = false;\n setError(null);\n setPhase(\"ready\");\n return;\n }\n if (message.status === \"FAILED\") {\n finishWithError(\n classifyExploreError(message.errorCode ?? \"UPSTREAM_UNAVAILABLE\"),\n );\n return;\n }\n\n setPhase(\"streaming\");\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n };\n\n // First poll after one interval — the turn cannot possibly be done sooner.\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n },\n [client, pollIntervalMs, pollTimeoutMs],\n );\n\n // --------------------------------------------------------------------------\n // send\n // --------------------------------------------------------------------------\n const submit = useCallback(\n async (\n text: string,\n optimisticId: string,\n captchaAttempt: number,\n ): Promise<void> => {\n const activeCatalog = catalogRef.current;\n\n let recaptchaToken: string | undefined;\n if (activeCatalog.captchaRequired && activeCatalog.recaptchaSiteKey) {\n try {\n recaptchaToken = await getRecaptchaV3Token(\n activeCatalog.recaptchaSiteKey,\n );\n } catch (err) {\n console.warn(\"[WebSDK] reCAPTCHA v3 token could not be minted\", err);\n // Send without a token and let the backend decide — it owns the\n // policy, and a blocked third-party script must not silently kill\n // the whole feature.\n }\n }\n\n const input: SendExploreMessageInput = {\n message: text,\n ...(conversationTokenRef.current\n ? { conversationToken: conversationTokenRef.current }\n : {}),\n ...(focusProductRef.current || productSlug\n ? { productSlug: focusProductRef.current ?? productSlug }\n : {}),\n ...(recaptchaToken ? { recaptchaToken } : {}),\n ...(locale ? { locale } : {}),\n ...(pageUrl ? { pageUrl } : {}),\n };\n\n const res = await client.mutate<SendExploreMessageMutationData>(\n SEND_EXPLORE_MESSAGE_MUTATION,\n { input },\n { timeoutMs: SEND_REQUEST_TIMEOUT_MS },\n );\n if (!mountedRef.current) return;\n\n const first = res.errors?.[0];\n const result = res.data?.sendExploreMessage;\n\n if (first || !result) {\n const code =\n typeof first?.extensions?.code === \"string\"\n ? first.extensions.code\n : undefined;\n const classified = classifyExploreError(code, first?.message);\n\n // CAPTCHA_FAILED: one silent re-mint + re-send before bothering the\n // visitor. v3 tokens expire in ~2 minutes and are single-use, so a\n // stale one is a routine, self-healing failure.\n if (classified.kind === \"captcha\" && captchaAttempt === 0) {\n await submit(text, optimisticId, 1);\n return;\n }\n\n inFlightRef.current = false;\n setError(classified);\n setPhase(classified.kind === \"rate-limit\" ? \"limited\" : \"error\");\n return;\n }\n\n conversationTokenRef.current = result.conversation.token;\n turnCountRef.current = result.conversation.turnCount;\n setTurnCount(result.conversation.turnCount);\n setRemainingToday(result.remainingToday ?? null);\n\n const userMessage = result.userMessage;\n const assistantMessage = result.assistantMessage;\n\n // Swap the optimistic user bubble for the server's, then append the\n // PENDING assistant turn that the poll chain will fill in. The `some`\n // guard keeps the visitor's words on screen even in the impossible case\n // where the optimistic bubble is already gone.\n setMessages((prev) => {\n const replaced = prev.some((m) => m.id === optimisticId)\n ? prev.map((m) => (m.id === optimisticId ? userMessage : m))\n : [...prev, userMessage];\n return [...replaced, assistantMessage];\n });\n\n if (\n assistantMessage.status === \"COMPLETED\" ||\n assistantMessage.status === \"FAILED\"\n ) {\n inFlightRef.current = false;\n if (assistantMessage.status === \"FAILED\") {\n const classified = classifyExploreError(\n assistantMessage.errorCode ?? \"UPSTREAM_UNAVAILABLE\",\n );\n setError(classified);\n setPhase(\"error\");\n } else {\n setPhase(\"ready\");\n }\n return;\n }\n\n setPhase(\"streaming\");\n startPolling(result.conversation.token, assistantMessage.id);\n },\n [client, locale, pageUrl, productSlug, startPolling],\n );\n\n const send = useCallback(\n async (message: string): Promise<void> => {\n const text = message.trim();\n if (!text) return;\n if (inFlightRef.current) return;\n\n const activeCatalog = catalogRef.current;\n if (!activeCatalog.enabled) {\n setError(classifyExploreError(\"EXPLORE_DISABLED\"));\n setPhase(\"disabled\");\n return;\n }\n if (text.length > activeCatalog.limits.maxMessageLength) {\n setError({\n kind: \"validation\",\n code: \"MESSAGE_TOO_LONG\",\n message: `That message is ${text.length} characters — the limit is ${activeCatalog.limits.maxMessageLength}.`,\n retryable: false,\n });\n return;\n }\n if (\n turnCountRef.current >= activeCatalog.limits.maxTurnsPerConversation\n ) {\n setError({\n kind: \"validation\",\n code: \"CONVERSATION_LIMIT\",\n message: `This conversation has reached its ${activeCatalog.limits.maxTurnsPerConversation}-message limit. Start a new chat to keep going.`,\n retryable: false,\n });\n return;\n }\n\n inFlightRef.current = true;\n lastSentTextRef.current = text;\n setError(null);\n setPhase(\"sending\");\n cancelPolling();\n\n // Optimistic user bubble — the composer clears instantly instead of\n // waiting a network round-trip for the visitor's own words.\n const optimistic: ExploreMessage = {\n id: makeOptimisticId(),\n conversationId: conversationTokenRef.current ?? \"pending\",\n role: \"USER\",\n status: \"COMPLETED\",\n content: text,\n partialContent: null,\n activity: [],\n references: [],\n ctas: [],\n errorCode: null,\n createdAt: new Date().toISOString(),\n completedAt: new Date().toISOString(),\n };\n setMessages((prev) => [...prev, optimistic]);\n turnCountRef.current += 1;\n setTurnCount(turnCountRef.current);\n onSend?.(text);\n\n try {\n await submit(text, optimistic.id, 0);\n } catch (err) {\n if (!mountedRef.current) return;\n console.error(\"[WebSDK] Explore send failed\", err);\n inFlightRef.current = false;\n setError(classifyExploreError(\"NETWORK_ERROR\"));\n setPhase(\"error\");\n }\n },\n [cancelPolling, onSend, submit],\n );\n\n const stop = useCallback(() => {\n cancelPolling();\n inFlightRef.current = false;\n setMessages((prev) =>\n prev.flatMap<ExploreMessage>((m) => {\n if (m.role !== \"ASSISTANT\") return [m];\n if (m.status !== \"PENDING\" && m.status !== \"RUNNING\") return [m];\n const text = visibleText(m);\n // Nothing streamed yet — drop the placeholder instead of leaving an\n // empty bubble behind.\n if (!text) return [];\n return [\n {\n ...m,\n status: \"COMPLETED\",\n content: text,\n completedAt: new Date().toISOString(),\n },\n ];\n }),\n );\n setPhase((prev) =>\n prev === \"sending\" || prev === \"streaming\" ? \"ready\" : prev,\n );\n }, [cancelPolling]);\n\n const retry = useCallback(() => {\n const text = lastSentTextRef.current;\n if (!text) return;\n cancelPolling();\n inFlightRef.current = false;\n // Drop the failed turn (and the user bubble that produced it) so the retry\n // does not stack a duplicate pair into the transcript.\n setMessages((prev) => {\n const next = [...prev];\n const last = next[next.length - 1];\n if (last?.role === \"ASSISTANT\" && last.status === \"FAILED\") next.pop();\n const prior = next[next.length - 1];\n if (prior?.role === \"USER\" && prior.content === text) next.pop();\n return next;\n });\n turnCountRef.current = Math.max(0, turnCountRef.current - 1);\n setTurnCount(turnCountRef.current);\n void send(text);\n }, [cancelPolling, send]);\n\n const reset = useCallback(() => {\n // Archive the thread being left behind, so \"New chat\" never destroys history.\n setArchive(\n upsertArchive(storageKey, {\n token: conversationTokenRef.current,\n messages: messagesRef.current,\n focusProduct: focusProductRef.current,\n }),\n );\n cancelPolling();\n inFlightRef.current = false;\n conversationTokenRef.current = null;\n lastSentTextRef.current = null;\n turnCountRef.current = 0;\n setTurnCount(0);\n setMessages([]);\n setError(null);\n setRemainingToday(null);\n setPhase(catalogRef.current.enabled ? \"ready\" : \"disabled\");\n if (typeof window !== \"undefined\") {\n try {\n window.localStorage.removeItem(storageKey);\n } catch {\n /* storage unavailable — nothing to clear */\n }\n }\n }, [cancelPolling, storageKey]);\n\n /**\n * Reopen a past conversation. The messages come from the local archive rather than the server:\n * the backend expires a job's state, and a visitor looking at their own history should see it\n * whether or not the server still holds anything. The token is restored too, so the next\n * message continues the SAME server-side conversation.\n */\n const openConversation = useCallback(\n (token: string) => {\n const entry = readArchive(storageKey).find((e) => e.token === token);\n if (!entry) return;\n // Archive whatever is on screen first, or switching away would lose it.\n upsertArchive(storageKey, {\n token: conversationTokenRef.current,\n messages: messagesRef.current,\n focusProduct: focusProductRef.current,\n });\n cancelPolling();\n inFlightRef.current = false;\n conversationTokenRef.current = entry.token;\n turnCountRef.current = entry.messages.filter(\n (m) => m.role === \"USER\",\n ).length;\n setTurnCount(turnCountRef.current);\n setMessages(entry.messages);\n focusProductRef.current = entry.focusProduct;\n setFocusProductState(entry.focusProduct);\n setError(null);\n setPhase(catalogRef.current.enabled ? \"ready\" : \"disabled\");\n setArchive(readArchive(storageKey));\n },\n [cancelPolling, storageKey],\n );\n\n /** Forget one past conversation. Local only — see the page's storage notice. */\n const deleteConversation = useCallback(\n (token: string) => {\n const next = readArchive(storageKey).filter((e) => e.token !== token);\n writeArchive(storageKey, next);\n setArchive(next);\n },\n [storageKey],\n );\n\n /** Forget every past conversation held in this browser. */\n const clearHistory = useCallback(() => {\n writeArchive(storageKey, []);\n setArchive([]);\n }, [storageKey]);\n\n const setFocusProduct = useCallback((slug: string | null) => {\n focusProductRef.current = slug;\n setFocusProductState(slug);\n }, []);\n\n const activity = useMemo<string | null>(() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const m = messages[i];\n if (!m || m.role !== \"ASSISTANT\") continue;\n if (m.status !== \"PENDING\" && m.status !== \"RUNNING\") return null;\n const lines = m.activity ?? [];\n return lines.length ? (lines[lines.length - 1] ?? null) : null;\n }\n return null;\n }, [messages]);\n\n const canSend =\n (phase === \"ready\" || phase === \"error\") &&\n catalog.enabled &&\n turnCount < catalog.limits.maxTurnsPerConversation;\n\n /**\n * Tell the server the visitor followed one of the links this answer offered.\n *\n * Deliberately fire-and-forget and never awaited: the browser is navigating away as this\n * goes out, so anything that blocked on it would delay the click the visitor actually\n * made. Failures are swallowed — analytics must never break navigation.\n */\n const recordClick = useCallback(\n (messageId: string, kind: \"CTA\" | \"REFERENCE\", url: string): void => {\n const token = conversationTokenRef.current;\n if (!token) return;\n try {\n void client\n .mutate(RECORD_EXPLORE_CLICK_MUTATION, {\n input: { conversationToken: token, messageId, kind, url },\n })\n .catch(() => {\n /* the visitor is mid-navigation; there is nothing useful to do here */\n });\n } catch {\n /* client unavailable — same reasoning */\n }\n },\n [client],\n );\n\n return {\n phase,\n catalog,\n messages,\n activity,\n remainingToday,\n error,\n focusProduct,\n setFocusProduct,\n send,\n stop,\n retry,\n reset,\n canSend,\n history: archive,\n openConversation,\n deleteConversation,\n clearHistory,\n recordClick,\n };\n}\n\n/**\n * Client-only id for the optimistic user bubble, swapped for the server's\n * `userMessage.id` as soon as the mutation resolves. The counter only has to\n * make ids unique within a tab, never across one.\n */\nlet optimisticCounter = 0;\n\nfunction makeOptimisticId(): string {\n optimisticCounter += 1;\n return `boff-explore-local-${Date.now()}-${optimisticCounter}`;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Dictation for the explore composer, on the browser's own speech recogniser.\n *\n * Uses the Web Speech API directly — no dependency, no network call of our own, no audio ever\n * leaving the browser through us. Support is genuinely partial (Chrome, Edge and Safari expose\n * it, most commonly behind the `webkit` prefix; Firefox does not implement it at all), so the\n * caller MUST hide the microphone entirely when `supported` is false rather than offering a\n * control that cannot work.\n *\n * Interim results are surfaced separately from final ones so the composer can show speech\n * appearing live while only committing settled text to the draft.\n *\n * ## Mobile\n *\n * Mobile took three separate fixes, each of which looked like the whole problem:\n *\n * 1. **The prompt never appeared.** `recognition.start()` raises the permission prompt on\n * desktop Chrome but on Android Chrome and iOS fires `not-allowed` without showing\n * anything, so a visitor who had never been asked was told to change a browser setting.\n * `getUserMedia` is what actually prompts, so it is primed first.\n * 2. **Granting still failed.** Recognition opens its OWN capture, and starting it in the same\n * tick that the primed stream is being torn down races that teardown. It now waits for the\n * release, and retries once — Android frequently refuses the first attempt after a\n * permission is newly granted and accepts the second.\n * 3. **`continuous` is not honoured on mobile.** Android Chrome ends the session after a\n * single utterance regardless, and asking for continuous mode makes it fail sooner. Mobile\n * therefore runs single-shot and is restarted from `onend` for as long as the visitor is\n * still dictating, which behaves like continuous without fighting the platform.\n */\n\ninterface SpeechRecognitionAlternativeLike {\n transcript: string;\n}\ninterface SpeechRecognitionResultLike {\n readonly isFinal: boolean;\n readonly length: number;\n [index: number]: SpeechRecognitionAlternativeLike;\n}\ninterface SpeechRecognitionEventLike {\n readonly resultIndex: number;\n readonly results: {\n readonly length: number;\n [index: number]: SpeechRecognitionResultLike;\n };\n}\ninterface SpeechRecognitionErrorEventLike {\n readonly error: string;\n}\ninterface SpeechRecognitionLike {\n lang: string;\n continuous: boolean;\n interimResults: boolean;\n maxAlternatives: number;\n start: () => void;\n stop: () => void;\n abort: () => void;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;\n onend: (() => void) | null;\n onstart: (() => void) | null;\n}\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\n\ninterface SpeechWindow {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n}\n\nfunction getRecognitionCtor(): SpeechRecognitionCtor | null {\n if (typeof window === \"undefined\") return null;\n const w = window as unknown as SpeechWindow;\n return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;\n}\n\n/**\n * Coarse pointer means a touch device, which is what actually predicts the recogniser's\n * behaviour here — not the screen size, and not a UA string that lies.\n */\nfunction isTouchDevice(): boolean {\n if (typeof window === \"undefined\" || !window.matchMedia) return false;\n try {\n return window.matchMedia(\"(pointer: coarse)\").matches;\n } catch {\n return false;\n }\n}\n\nconst MIC_DENIED_MESSAGE =\n \"Microphone access was blocked. Allow it in your browser's site settings to dictate.\";\nconst MIC_UNAVAILABLE_MESSAGE =\n \"Dictation isn't available in this browser. You can type instead.\";\n\n/** Let a released capture settle before recognition opens its own. */\nconst RELEASE_SETTLE_MS = 250;\n/** Android often refuses the first start after a fresh grant and accepts the next. */\nconst RETRY_DELAY_MS = 350;\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n/**\n * Ask for the microphone the only way that reliably raises a prompt on mobile.\n *\n * `confirmed` reports whether access was actually VERIFIED, which is what separates \"you need\n * to grant this\" from \"your browser cannot do this\" further down.\n *\n * Must be called synchronously from the user gesture that requested dictation — awaiting\n * anything first spends the gesture and the browser then rejects the request outright.\n */\nasync function ensureMicrophoneAccess(): Promise<\n | { ok: true; confirmed: boolean; primed: boolean }\n | { ok: false; message: string }\n> {\n const media =\n typeof navigator === \"undefined\" ? undefined : navigator.mediaDevices;\n // Older/unusual browsers without mediaDevices: fall through and let recognition try. It\n // may well work, and refusing here would remove dictation from browsers that support it.\n if (!media?.getUserMedia)\n return { ok: true, confirmed: false, primed: false };\n\n // `granted` means the prompt would not appear anyway, so skip the extra capture — which\n // also avoids the teardown race entirely on repeat use.\n //\n // A `denied` reading is deliberately NOT trusted to short-circuit. The Permissions API\n // reports `denied` for a prompt the visitor merely dismissed, and its microphone support\n // is uneven across mobile browsers — believing it would recreate the exact bug this\n // function exists to fix, telling someone to change a setting instead of asking them.\n // getUserMedia is the authoritative check, and when access really is denied it rejects\n // immediately without showing anything, so the only cost of asking is a settled promise.\n //\n // `permissions` is absent on Safari and `microphone` is not a valid name everywhere, so\n // every part of this is optional and failure is non-fatal.\n try {\n const status = await navigator.permissions?.query({\n name: \"microphone\" as PermissionName,\n });\n if (status?.state === \"granted\")\n return { ok: true, confirmed: true, primed: false };\n } catch {\n /* permissions API unavailable or the name is unsupported — prompt below instead */\n }\n\n try {\n const stream = await media.getUserMedia({ audio: true });\n // Release immediately: this capture existed only to raise the prompt, and leaving it\n // open would show a recording indicator for the whole session — and on mobile would\n // occupy the very microphone recognition is about to ask for.\n for (const track of stream.getTracks()) track.stop();\n return { ok: true, confirmed: true, primed: true };\n } catch (error) {\n const name =\n typeof error === \"object\" && error !== null && \"name\" in error\n ? String((error as { name: unknown }).name)\n : \"\";\n if (name === \"NotAllowedError\" || name === \"SecurityError\") {\n return { ok: false, message: MIC_DENIED_MESSAGE };\n }\n if (name === \"NotFoundError\" || name === \"DevicesNotFoundError\") {\n return { ok: false, message: \"No microphone was found.\" };\n }\n return {\n ok: false,\n message: \"Dictation could not start. You can type instead.\",\n };\n }\n}\n\n/** Messages a visitor can act on. `not-allowed` is the one that needs real explanation. */\nfunction describeError(code: string): string {\n switch (code) {\n case \"not-allowed\":\n case \"service-not-allowed\":\n return MIC_DENIED_MESSAGE;\n case \"no-speech\":\n return \"I didn't catch anything — try again a little closer to the mic.\";\n case \"audio-capture\":\n return \"No microphone was found.\";\n case \"network\":\n return \"Speech recognition needs a network connection.\";\n case \"aborted\":\n return \"\";\n default:\n return \"Dictation stopped unexpectedly. You can type instead.\";\n }\n}\n\nexport interface UseSpeechInputOptions {\n /** Receives settled text as it is recognised. Append it to the draft. */\n onFinalTranscript: (text: string) => void;\n /** BCP-47 tag. Defaults to the browser's language. */\n lang?: string;\n /** Called when the recogniser reports a problem worth showing. */\n onError?: (message: string) => void;\n}\n\nexport interface UseSpeechInputResult {\n /** False when the browser has no speech recogniser — hide the control entirely. */\n supported: boolean;\n listening: boolean;\n /** Words recognised but not yet settled; render as a live hint, do not store. */\n interim: string;\n error: string | null;\n start: () => void;\n stop: () => void;\n toggle: () => void;\n}\n\nexport function useSpeechInput({\n onFinalTranscript,\n lang,\n onError,\n}: UseSpeechInputOptions): UseSpeechInputResult {\n const [supported] = useState(() => getRecognitionCtor() !== null);\n const [listening, setListening] = useState(false);\n const [interim, setInterim] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n\n const recognitionRef = useRef<SpeechRecognitionLike | null>(null);\n /**\n * Bumped on every start()/stop(). A permission prompt, a settle delay or a retry resolving\n * after the visitor moved on must not open a microphone behind them.\n */\n const startTokenRef = useRef(0);\n /**\n * True only when the microphone was actually VERIFIED for this attempt — permission\n * reported granted, or getUserMedia succeeded. Stays false on browsers with no\n * mediaDevices, where nothing was checked and a recogniser `not-allowed` may still be a\n * real permission problem.\n */\n const micConfirmedRef = useRef(false);\n /** The visitor's intent, as opposed to whether a session happens to be open right now. */\n const wantsListeningRef = useRef(false);\n /** One retry per start(), for the Android \"refuses the first attempt\" case. */\n const retriedRef = useRef(false);\n\n // Held in refs so the recogniser's long-lived handlers always call the latest closures\n // without tearing down and re-creating the recogniser on every render.\n const finalRef = useRef(onFinalTranscript);\n const errorRef = useRef(onError);\n finalRef.current = onFinalTranscript;\n errorRef.current = onError;\n\n const langRef = useRef(lang);\n langRef.current = lang;\n\n const stop = useCallback(() => {\n startTokenRef.current += 1;\n wantsListeningRef.current = false;\n setListening(false);\n setInterim(\"\");\n const recognition = recognitionRef.current;\n if (!recognition) return;\n try {\n recognition.stop();\n } catch {\n /* already stopped */\n }\n }, []);\n\n /** Open a recogniser session. Separate from start() so a retry can reuse it. */\n const openSession = useCallback((token: number) => {\n const Ctor = getRecognitionCtor();\n if (!Ctor || token !== startTokenRef.current) return;\n\n const recognition = new Ctor();\n recognition.lang =\n langRef.current ??\n (typeof navigator === \"undefined\"\n ? \"en-US\"\n : navigator.language || \"en-US\");\n // Continuous mode is a desktop-only affordance. Android Chrome ends the session after a\n // single utterance whatever this says, and asking for continuous makes it fail sooner —\n // mobile is restarted from `onend` instead, which behaves the same to the visitor.\n recognition.continuous = !isTouchDevice();\n recognition.interimResults = true;\n recognition.maxAlternatives = 1;\n\n recognition.onstart = () => {\n if (token !== startTokenRef.current) return;\n // NOTE: the retry budget is deliberately NOT reset here. It belongs to the visitor's\n // press, not to the session — a browser that fires onstart and then immediately\n // errors would otherwise retry forever.\n setError(null);\n setListening(true);\n };\n\n recognition.onresult = (event) => {\n if (token !== startTokenRef.current) return;\n let settled = \"\";\n let pending = \"\";\n for (let i = event.resultIndex; i < event.results.length; i += 1) {\n const result = event.results[i];\n if (!result) continue;\n const text = result[0]?.transcript ?? \"\";\n if (result.isFinal) settled += text;\n else pending += text;\n }\n setInterim(pending);\n if (settled.trim() !== \"\") finalRef.current(settled);\n };\n\n recognition.onerror = (event) => {\n if (token !== startTokenRef.current) return;\n\n // Android commonly refuses the FIRST start after a permission is newly granted and\n // accepts the next one. Retry once, silently, before telling the visitor anything —\n // an error message they can do nothing about is worse than a short pause.\n if (\n (event.error === \"not-allowed\" ||\n event.error === \"service-not-allowed\") &&\n micConfirmedRef.current &&\n !retriedRef.current\n ) {\n retriedRef.current = true;\n void sleep(RETRY_DELAY_MS).then(() => {\n if (token !== startTokenRef.current || !wantsListeningRef.current)\n return;\n openSessionRef.current?.(token);\n });\n return;\n }\n\n // The microphone was verified moments ago, so a `not-allowed` that survived the retry\n // is the SPEECH SERVICE refusing, not a permission the visitor can grant. Sending them\n // to a site setting would point at something that cannot help.\n const message =\n micConfirmedRef.current &&\n (event.error === \"not-allowed\" || event.error === \"service-not-allowed\")\n ? MIC_UNAVAILABLE_MESSAGE\n : describeError(event.error);\n\n wantsListeningRef.current = false;\n setListening(false);\n setInterim(\"\");\n if (message !== \"\") {\n setError(message);\n errorRef.current?.(message);\n }\n };\n\n recognition.onend = () => {\n if (token !== startTokenRef.current) return;\n setInterim(\"\");\n // Single-shot mobile sessions end after each utterance. While the visitor still has\n // dictation switched on, reopen so it behaves like continuous mode.\n if (wantsListeningRef.current && isTouchDevice()) {\n void sleep(120).then(() => {\n if (token !== startTokenRef.current || !wantsListeningRef.current)\n return;\n openSessionRef.current?.(token);\n });\n return;\n }\n setListening(false);\n };\n\n recognitionRef.current = recognition;\n try {\n recognition.start();\n } catch {\n // Chrome throws InvalidStateError if start() races a session that is still closing.\n // The onend handler above will not fire for a session that never began, so settle here.\n wantsListeningRef.current = false;\n setListening(false);\n }\n }, []);\n\n // openSession refers to itself from its own handlers (retry, mobile restart), which a plain\n // const cannot do inside useCallback.\n const openSessionRef = useRef<((token: number) => void) | null>(null);\n openSessionRef.current = openSession;\n\n const start = useCallback(() => {\n if (!getRecognitionCtor()) return;\n\n startTokenRef.current += 1;\n const token = startTokenRef.current;\n wantsListeningRef.current = true;\n retriedRef.current = false;\n micConfirmedRef.current = false;\n\n // Show the pressed state straight away: the permission prompt can sit on screen for a\n // while on mobile, and a mic button that looks inert invites a second tap.\n setError(null);\n setListening(true);\n\n void ensureMicrophoneAccess().then(async (access) => {\n // A stop() or a newer start() landed while the prompt was open — abandon this attempt.\n if (token !== startTokenRef.current) return;\n\n if (!access.ok) {\n wantsListeningRef.current = false;\n setListening(false);\n setError(access.message);\n errorRef.current?.(access.message);\n return;\n }\n\n micConfirmedRef.current = access.confirmed;\n\n // Recognition opens its own capture. Starting in the same tick that the primed stream\n // is being torn down races that teardown and is refused — this is what made \"I granted\n // it and it still says blocked\" happen on mobile.\n if (access.primed) {\n await sleep(RELEASE_SETTLE_MS);\n if (token !== startTokenRef.current) return;\n }\n\n openSessionRef.current?.(token);\n });\n }, []);\n\n const toggle = useCallback(() => {\n if (listening) stop();\n else start();\n }, [listening, start, stop]);\n\n // Never leave the microphone open behind a closed page.\n useEffect(\n () => () => {\n startTokenRef.current += 1;\n wantsListeningRef.current = false;\n const recognition = recognitionRef.current;\n if (!recognition) return;\n recognition.onresult = null;\n recognition.onerror = null;\n recognition.onend = null;\n recognition.onstart = null;\n try {\n recognition.abort();\n } catch {\n /* nothing to abort */\n }\n },\n [],\n );\n\n return { supported, listening, interim, error, start, stop, toggle };\n}\n","/**\n * PageHead Component\n * Manages dynamic meta tags for SEO optimization on a per-page basis.\n * Supports JSON-LD structured data, Open Graph, Twitter Cards, favicons, and robots directives.\n *\n * @example\n * ```tsx\n * <PageHead\n * title=\"About Us\"\n * description=\"Learn about our mission and team\"\n * productName=\"MyProduct\"\n * keywords=\"about, team, mission\"\n * image=\"/og-about.png\"\n * url=\"https://myproduct.com/about\"\n * favicon=\"/favicon.ico\"\n * robots=\"index, follow\"\n * locale=\"en_US\"\n * twitterHandle=\"@burdenoff\"\n * themeColor=\"#1a1a2e\"\n * structuredData={{\n * \"@context\": \"https://schema.org\",\n * \"@type\": \"WebPage\",\n * name: \"About Us\",\n * }}\n * />\n * ```\n */\n\nimport { Helmet } from \"react-helmet-async\";\n\nexport interface PageHeadProps {\n /** Page title */\n title: string;\n /** Meta description */\n description?: string;\n /** Product/brand name (appended to title) */\n productName?: string;\n /** SEO keywords */\n keywords?: string;\n /** Open Graph image URL */\n image?: string;\n /** Page canonical URL */\n url?: string;\n /** Favicon URL */\n favicon?: string;\n /** Robots directive (e.g., \"index, follow\") */\n robots?: string;\n /** Open Graph locale (e.g., \"en_US\") */\n locale?: string;\n /** Twitter handle (e.g., \"@burdenoff\") */\n twitterHandle?: string;\n /** Theme color for mobile browsers */\n themeColor?: string;\n /** JSON-LD structured data objects */\n structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;\n /** Additional meta tags */\n additionalMeta?: Array<{\n name?: string;\n property?: string;\n content: string;\n }>;\n}\n\n/**\n * Build a self-referencing canonical URL from the current location.\n *\n * Query strings and hashes are dropped (they never identify a distinct\n * canonical document here) and the trailing slash is normalised away for\n * everything but the site root. Returns `undefined` outside a DOM so the\n * component degrades to its previous behaviour under plain string rendering.\n */\nfunction canonicalFromLocation(): string | undefined {\n if (typeof window === \"undefined\" || !window.location) return undefined;\n const { origin, pathname } = window.location;\n if (!origin || origin === \"null\") return undefined;\n const path = pathname === \"/\" ? \"/\" : pathname.replace(/\\/+$/, \"\");\n return `${origin}${path}`;\n}\n\n/**\n * Absolutise an Open Graph image URL.\n *\n * Already-absolute URLs pass through. A root-relative path resolves against\n * the origin, and any other relative path against the page URL. Without a\n * resolvable base the original value is returned unchanged.\n */\nfunction resolveImageUrl(\n image: string | undefined,\n base: string | undefined,\n): string | undefined {\n if (!image || /^https?:\\/\\//i.test(image)) return image;\n if (!base) return image;\n try {\n return new URL(image, base).toString();\n } catch {\n return image;\n }\n}\n\nexport function PageHead({\n title,\n description,\n productName,\n keywords,\n image,\n url,\n favicon,\n robots = \"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\",\n locale = \"en_US\",\n twitterHandle,\n themeColor = \"#000000\",\n structuredData,\n additionalMeta,\n}: PageHeadProps) {\n const fullTitle =\n productName && !title.includes(productName)\n ? `${title} | ${productName}`\n : title;\n\n // Self-referencing canonical by default.\n //\n // Without this, a route that renders PageHead but omits `url` emits no\n // canonical at all, so the static `<link rel=\"canonical\">` in index.html\n // survives and every such page declares itself a duplicate of the home\n // page — Google then drops /pricing, /privacy, /terms and friends from the\n // index. Deriving it from the current location keeps each page pointing at\n // itself; callers that genuinely need a cross-canonical still pass `url`.\n //\n // During prerender the DOM location already reflects the route being\n // rendered, so this resolves correctly ahead of hydration.\n const resolvedUrl = url ?? canonicalFromLocation();\n\n // Root-relative images (\"/og.png\") belong to the ORIGIN, not to the current\n // path — concatenating them onto the page URL yields /features/og.png and a\n // broken share card. Anything else is resolved relative to the page itself.\n const fullImageUrl = resolveImageUrl(image, resolvedUrl);\n\n // Normalize structured data to an array\n const structuredDataItems: Array<Record<string, unknown>> = structuredData\n ? Array.isArray(structuredData)\n ? structuredData\n : [structuredData]\n : [];\n\n return (\n <Helmet>\n {/* Primary Meta Tags */}\n <title>{fullTitle}</title>\n <meta name=\"title\" content={fullTitle} />\n {description && <meta name=\"description\" content={description} />}\n {keywords && <meta name=\"keywords\" content={keywords} />}\n <meta name=\"author\" content=\"Burdenoff Consultancy Services Pvt Ltd\" />\n <meta name=\"robots\" content={robots} />\n\n {/* Canonical URL */}\n {resolvedUrl && <link rel=\"canonical\" href={resolvedUrl} />}\n\n {/* Favicon */}\n {favicon && <link rel=\"icon\" href={favicon} />}\n\n {/* Open Graph / Facebook */}\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:title\" content={fullTitle} />\n {description && <meta property=\"og:description\" content={description} />}\n {fullImageUrl && <meta property=\"og:image\" content={fullImageUrl} />}\n {resolvedUrl && <meta property=\"og:url\" content={resolvedUrl} />}\n <meta property=\"og:locale\" content={locale} />\n {productName && <meta property=\"og:site_name\" content={productName} />}\n\n {/* Twitter Card */}\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content={fullTitle} />\n {description && <meta name=\"twitter:description\" content={description} />}\n {fullImageUrl && <meta name=\"twitter:image\" content={fullImageUrl} />}\n {twitterHandle && <meta name=\"twitter:creator\" content={twitterHandle} />}\n\n {/* Theme Color */}\n <meta name=\"theme-color\" content={themeColor} />\n\n {/* JSON-LD Structured Data */}\n {structuredDataItems.map((data, index) => (\n <script key={`ld-${index}`} type=\"application/ld+json\">\n {JSON.stringify(data)}\n </script>\n ))}\n\n {/* Additional Meta Tags */}\n {additionalMeta?.map((meta, index) => (\n <meta\n key={`meta-${index}`}\n {...(meta.name ? { name: meta.name } : {})}\n {...(meta.property ? { property: meta.property } : {})}\n content={meta.content}\n />\n ))}\n </Helmet>\n );\n}\n","/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.ComponentProps<\"textarea\">\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n","/**\n * ExplorePage — the public `/explore` AI chat surface.\n *\n * Ships on 38 marketing sites, so it is written as a *marketing* page that\n * happens to be a chat, not a chat widget dropped onto a marketing site:\n *\n * - The welcome state discloses what the assistant can do **before** the\n * visitor types — a real `<h1>`, a one-line pitch, three capability bullets,\n * clickable example prompts and product-focus chips.\n * - That `<h1>` renders on the FIRST render, from props or the hook's built-in\n * fallback catalog, never from the catalog fetch. The websites' prerender\n * waits for an `h1`; a heading behind a network round-trip would bake 38\n * blank static pages.\n * - Colours are semantic tokens only (`bg-card`, `text-muted-foreground`,\n * `border-border`, …) so the page is correct in light AND dark mode on every\n * product's palette. No raw hex/rgb/hsl anywhere.\n *\n * Import from the package ROOT — `@burdenoff/website-sdk` — never from\n * `@burdenoff/website-sdk/components/explore`. tsup builds with\n * `splitting: false`, so a sub-path bundle carries its own copy of the React\n * context and cannot see the app's `WebSDKProvider`.\n *\n * @example\n * ```tsx\n * import { ExplorePage } from '@burdenoff/website-sdk'\n *\n * <ExplorePage\n * productSlug=\"vibecontrols\"\n * heightMode=\"viewport\"\n * viewportOffset=\"4rem\" // site header height\n * onNavigate={(path) => navigate(path)}\n * seo={{ url: 'https://vibecontrols.com/explore' }}\n * />\n * ```\n */\n\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n ArrowUp,\n BookOpenText,\n ChevronLeft,\n ChevronRight,\n ExternalLink,\n Layers,\n Link2,\n RotateCcw,\n Sparkles,\n History as HistoryIcon,\n Mic,\n Square,\n Trash2,\n TriangleAlert,\n} from \"lucide-react\";\n\nimport { Markdown } from \"../content/Markdown\";\nimport { ProseStyles } from \"../content/prose-styles\";\nimport { useExploreChat } from \"../hooks/use-explore-chat\";\nimport { useSpeechInput } from \"../hooks/use-speech-input\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Textarea } from \"../ui/textarea\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n ExploreCtaLink,\n ExploreMessage,\n ExploreReference,\n} from \"./explore-types\";\nimport type { ExploreChatError } from \"../hooks/use-explore-chat\";\n\n// ============================================================================\n// Props\n// ============================================================================\n\nexport interface ExplorePageProps {\n /** SEO metadata. Rendered through `PageHead` when provided. */\n seo?: {\n title?: string;\n description?: string;\n keywords?: string;\n image?: string;\n url?: string;\n };\n /** Slug of the product site this page lives on — a soft hint to the harness. */\n productSlug?: string;\n /**\n * Example prompts shown when `exploreCatalog` supplies none. Resolution\n * order: catalog → this prop → the SDK's built-in list.\n */\n examplePrompts?: string[];\n /** Extra classes for the page root. */\n className?: string;\n /**\n * `viewport` (default) pins the chat to the viewport with an internally\n * scrolling transcript — the right feel for a dedicated `/explore` route.\n * `auto` lets the page grow, for embedding inside a longer page.\n */\n heightMode?: \"viewport\" | \"auto\";\n /**\n * Chrome to subtract in `viewport` mode — the site header (and footer)\n * height. A number is treated as pixels. Default `0`.\n */\n viewportOffset?: string | number;\n /** SPA navigation for internal CTA paths. Falls back to a plain link. */\n onNavigate?: (path: string) => void;\n /** Fired with the message text every time a send is accepted. */\n onSend?: (message: string) => void;\n /** Overrides `exploreCatalog.welcomeTitle` — also the page `<h1>`. */\n welcomeTitle?: string;\n /** Overrides `exploreCatalog.welcomeBody`. */\n welcomeBody?: string;\n}\n\n// ============================================================================\n// Local styling (scoped, token-driven)\n// ============================================================================\n\nconst EXPLORE_CSS = `\n@keyframes boff-explore-pulse {\n 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-2px); }\n}\n.boff-explore-dot {\n display: inline-block;\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: hsl(var(--muted-foreground));\n animation: boff-explore-pulse 1.2s ease-in-out infinite;\n}\n@keyframes boff-explore-caret {\n 0%, 45% { opacity: 1; }\n 50%, 100% { opacity: 0; }\n}\n.boff-explore-caret {\n display: inline-block;\n width: 2px;\n height: 1em;\n margin-left: 2px;\n vertical-align: text-bottom;\n background-color: hsl(var(--primary));\n animation: boff-explore-caret 1s step-end infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n .boff-explore-dot,\n .boff-explore-caret { animation: none; }\n .boff-explore-dot { opacity: 0.6; }\n}\n.boff-explore-scroll {\n scrollbar-width: thin;\n scrollbar-color: hsl(var(--border)) transparent;\n}\n.boff-explore-scroll::-webkit-scrollbar { width: 10px; }\n.boff-explore-scroll::-webkit-scrollbar-track { background: transparent; }\n.boff-explore-scroll::-webkit-scrollbar-thumb {\n background-color: hsl(var(--border));\n border: 3px solid transparent;\n border-radius: 9999px;\n background-clip: content-box;\n}\n\n/* The product strip scrolls inside itself; a visible scrollbar would read as a broken\n layout rather than an affordance, and reserving its gutter shifts the chips. */\n.boff-explore-strip {\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n.boff-explore-strip::-webkit-scrollbar { display: none; }\n\n@keyframes boff-explore-fade-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: none; }\n}\n.boff-explore-fade { animation: boff-explore-fade-in 220ms ease-out; }\n@media (prefers-reduced-motion: reduce) {\n .boff-explore-fade { animation: none; }\n}\n\n/* Nothing inside an answer may widen the page. Model output carries long URLs, code and\n tables — each of those overflows a phone by default, and one overflowing child makes the\n WHOLE document horizontally scrollable, not just the bubble. */\n.boff-explore-body,\n.boff-explore-body p,\n.boff-explore-body li,\n.boff-explore-body a,\n.boff-explore-body h1,\n.boff-explore-body h2,\n.boff-explore-body h3 {\n overflow-wrap: anywhere;\n word-break: break-word;\n}\n.boff-explore-body pre {\n overflow-x: auto;\n max-width: 100%;\n}\n.boff-explore-body table {\n display: block;\n overflow-x: auto;\n max-width: 100%;\n}\n.boff-explore-body img {\n max-width: 100%;\n height: auto;\n}\n`;\n\nfunction ExploreStyles() {\n return <style dangerouslySetInnerHTML={{ __html: EXPLORE_CSS }} />;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst CAPABILITIES = [\n {\n icon: BookOpenText,\n title: \"Grounded in our own docs\",\n body: \"Every answer comes from published product pages and documentation — never invented.\",\n },\n {\n icon: Layers,\n title: \"Compare across the ecosystem\",\n body: \"Ask which product fits your team, or how two of them work together.\",\n },\n {\n icon: Link2,\n title: \"Straight to the right page\",\n body: \"Get the sources and next steps — pricing, docs, a demo — without hunting.\",\n },\n] as const;\n\n/** CTA kind → button styling. Unknown kinds fall through to the outline look. */\nconst CTA_VARIANTS: Record<string, \"default\" | \"secondary\" | \"outline\"> = {\n CONTACT: \"default\",\n WAITLIST: \"default\",\n APP: \"default\",\n PRICING: \"secondary\",\n STORE: \"secondary\",\n PARTNERS: \"secondary\",\n DOCS: \"outline\",\n SERVICES: \"outline\",\n OTHER: \"outline\",\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeOffset(offset: string | number | undefined): string {\n if (offset === undefined) return \"0px\";\n return typeof offset === \"number\" ? `${offset}px` : offset;\n}\n\n/** A same-origin path the host router can handle, as opposed to `https://…`. */\nfunction isInternalPath(url: string): boolean {\n return url.startsWith(\"/\") && !url.startsWith(\"//\");\n}\n\nfunction hostnameOf(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n /* relative or malformed URL — the label is decorative, so degrade quietly */\n return \"\";\n }\n}\n\nfunction initialOf(value: string | null | undefined, fallback: string): string {\n const source = (value || fallback).trim();\n return source ? source.slice(0, 1).toUpperCase() : \"?\";\n}\n\n/**\n * The product's own logo, derived from the reference's origin.\n *\n * Every Burdenoff product site serves `/favicon.svg`, so the logo needs no registry and no\n * bundled assets — the reference URL already names the product. Deliberately NOT\n * `/favicon-512.png`: that path returns 200 with `text/html` because the SPA fallback\n * answers unknown paths, so it would render as a broken image rather than 404 into the\n * fallback below.\n */\nexport function logoUrlOf(url: string): string | null {\n try {\n const { origin, protocol } = new URL(url);\n if (protocol !== \"https:\" && protocol !== \"http:\") return null;\n return `${origin}/favicon.svg`;\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// Reference card\n// ============================================================================\n\nfunction ReferenceCard({\n reference,\n onFollow,\n}: {\n reference: ExploreReference;\n onFollow?: (url: string) => void;\n}) {\n const [imageFailed, setImageFailed] = useState(false);\n const [logoFailed, setLogoFailed] = useState(false);\n const host = hostnameOf(reference.url);\n const logoUrl = logoUrlOf(reference.url);\n const showImage = Boolean(reference.imageUrl) && !imageFailed;\n const showLogo = Boolean(logoUrl) && !logoFailed;\n\n // The letter plate is the last resort only. Every product's first letter collides with\n // several others (A for AdapterCloud and AssetHandler, B for BrainyRich and BuildMyIQ …),\n // so it identifies nothing — it exists purely so a card is never a blank hole.\n const letterPlate = (\n <div className=\"flex h-full w-full items-center justify-center bg-gradient-to-br from-primary/25 via-primary/5 to-secondary\">\n <span className=\"text-sm font-semibold text-primary/70 sm:text-2xl\">\n {initialOf(reference.product, reference.title || host)}\n </span>\n </div>\n );\n\n const logoImg = showLogo ? (\n <img\n src={logoUrl ?? \"\"}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setLogoFailed(true)}\n className=\"h-full w-full object-contain p-1.5 sm:p-0\"\n />\n ) : (\n letterPlate\n );\n\n return (\n <a\n data-boff-explore=\"reference\"\n data-index={reference.index ?? undefined}\n href={reference.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={() => onFollow?.(reference.url)}\n /* Mobile is a compact row, not a 16:9 card. Stacked preview cards pushed the answer\n itself off the top of a phone screen — five sources were taller than the response. */\n className=\"group flex flex-row items-center gap-3 overflow-hidden rounded-xl border border-border bg-card p-2 transition-colors hover:border-primary/40 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:flex-col sm:items-stretch sm:gap-0 sm:p-0\"\n >\n {/* Mobile: a small square logo. An og:image is a wide banner and is unreadable at 44px,\n so the phone layout always shows the product mark instead. */}\n <div className=\"relative h-11 w-11 shrink-0 overflow-hidden rounded-lg bg-muted sm:hidden\">\n {logoImg}\n </div>\n\n {/* sm+: the preview card, falling back to the product logo on a tinted plate. */}\n <div className=\"relative hidden aspect-[16/9] w-full overflow-hidden bg-muted sm:block\">\n {showImage ? (\n <img\n src={reference.imageUrl ?? \"\"}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setImageFailed(true)}\n className=\"h-full w-full object-cover transition-transform duration-300 group-hover:scale-105\"\n />\n ) : showLogo ? (\n <div className=\"flex h-full w-full items-center justify-center bg-gradient-to-br from-primary/15 via-transparent to-secondary/60 p-6\">\n <img\n src={logoUrl ?? \"\"}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setLogoFailed(true)}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n ) : (\n letterPlate\n )}\n </div>\n\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5 sm:gap-1.5 sm:p-3\">\n <p className=\"line-clamp-2 text-sm font-semibold leading-snug text-card-foreground\">\n {reference.index ? (\n <span className=\"mr-1.5 inline-flex h-4 min-w-4 items-center justify-center rounded bg-primary/10 px-1 text-[10px] font-bold text-primary\">\n {reference.index}\n </span>\n ) : null}\n {reference.title || host || reference.url}\n </p>\n {reference.description ? (\n <p className=\"line-clamp-2 text-xs leading-relaxed text-muted-foreground max-sm:hidden\">\n {reference.description}\n </p>\n ) : null}\n <div className=\"flex items-center gap-2 sm:mt-auto sm:pt-2\">\n {reference.product ? (\n <span className=\"rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground max-sm:hidden\">\n {reference.product}\n </span>\n ) : null}\n <span className=\"inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground sm:ml-auto\">\n <ExternalLink className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">{host}</span>\n </span>\n </div>\n </div>\n </a>\n );\n}\n\n// ============================================================================\n// CTA button\n// ============================================================================\n\nfunction CtaButton({\n cta,\n onNavigate,\n onFollow,\n}: {\n cta: ExploreCtaLink;\n onNavigate?: (path: string) => void;\n onFollow?: (url: string) => void;\n}) {\n const variant = CTA_VARIANTS[cta.kind] ?? \"outline\";\n const internal = isInternalPath(cta.url);\n\n // Internal path + a router from the host: keep it an SPA navigation.\n if (internal && onNavigate) {\n return (\n <Button\n data-boff-explore=\"cta\"\n data-kind={cta.kind}\n type=\"button\"\n size=\"sm\"\n variant={variant}\n onClick={() => {\n onFollow?.(cta.url);\n onNavigate(cta.url);\n }}\n >\n {cta.label}\n </Button>\n );\n }\n\n return (\n <Button asChild size=\"sm\" variant={variant}>\n <a\n data-boff-explore=\"cta\"\n data-kind={cta.kind}\n href={cta.url}\n onClick={() => onFollow?.(cta.url)}\n {...(internal\n ? {}\n : { target: \"_blank\", rel: \"noopener noreferrer\" as const })}\n >\n {cta.label}\n {internal ? null : <ExternalLink className=\"ml-1 h-3 w-3\" />}\n </a>\n </Button>\n );\n}\n\n// ============================================================================\n// Thinking indicator\n// ============================================================================\n\nfunction ThinkingIndicator({ activity }: { activity: string | null }) {\n return (\n <div\n data-boff-explore=\"thinking\"\n className=\"flex items-center gap-2.5 rounded-2xl border border-border bg-muted/60 px-3.5 py-2.5 text-sm text-muted-foreground\"\n >\n <span className=\"flex items-center gap-1\" aria-hidden=\"true\">\n <span className=\"boff-explore-dot\" />\n <span\n className=\"boff-explore-dot\"\n style={{ animationDelay: \"150ms\" }}\n />\n <span\n className=\"boff-explore-dot\"\n style={{ animationDelay: \"300ms\" }}\n />\n </span>\n <span className=\"truncate\">{activity || \"Thinking…\"}</span>\n </div>\n );\n}\n\n// ============================================================================\n// Message bubbles\n// ============================================================================\n\nfunction UserBubble({ message }: { message: ExploreMessage }) {\n return (\n <div className=\"flex justify-end\">\n <div\n data-boff-explore=\"user\"\n className=\"max-w-[85%] whitespace-pre-wrap break-words rounded-2xl rounded-br-md bg-primary px-4 py-2.5 text-sm leading-relaxed text-primary-foreground shadow-sm\"\n >\n {message.content}\n </div>\n </div>\n );\n}\n\nfunction AssistantBubble({\n message,\n activity,\n onNavigate,\n anchorRef,\n onFollow,\n onFollowUp,\n}: {\n message: ExploreMessage;\n activity: string | null;\n onNavigate?: (path: string) => void;\n /** Set on the newest assistant turn so the transcript can align its top. */\n anchorRef?: React.Ref<HTMLDivElement>;\n onFollow?: (kind: \"CTA\" | \"REFERENCE\", url: string) => void;\n onFollowUp?: (question: string) => void;\n}) {\n const streaming =\n message.status === \"PENDING\" || message.status === \"RUNNING\";\n const body = message.content || message.partialContent || \"\";\n const failed = message.status === \"FAILED\";\n\n return (\n <div\n ref={anchorRef}\n data-boff-explore=\"assistant\"\n data-status={message.status}\n className=\"flex scroll-mt-4 gap-3\"\n >\n <span\n aria-hidden=\"true\"\n className=\"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\"\n >\n <Sparkles className=\"h-4 w-4\" />\n </span>\n\n <div className=\"min-w-0 flex-1 space-y-3\">\n {/* The corpus had nothing. Saying so outright is more credible than a hedged\n paragraph that reads like an answer — and it points somewhere useful. */}\n {message.status === \"COMPLETED\" && message.answered === false ? (\n <div\n data-boff-explore=\"no-answer\"\n className=\"flex items-start gap-2 rounded-xl border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-foreground\"\n >\n <TriangleAlert className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-amber-600 dark:text-amber-400\" />\n <span>\n I couldn't find this in our documentation, so the answer\n below is not grounded in a source. Try rephrasing, or{\" \"}\n <a\n href=\"/contact\"\n className=\"underline underline-offset-2 hover:text-primary\"\n onClick={(event) => {\n if (!onNavigate) return;\n event.preventDefault();\n onNavigate(\"/contact\");\n }}\n >\n ask a human\n </a>\n .\n </span>\n </div>\n ) : null}\n\n {body ? (\n <div className=\"rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm\">\n <div className=\"boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground\">\n <Markdown>{body}</Markdown>\n </div>\n {streaming ? (\n <span className=\"boff-explore-caret\" aria-hidden=\"true\" />\n ) : null}\n </div>\n ) : null}\n\n {streaming ? <ThinkingIndicator activity={activity} /> : null}\n\n {failed && !body ? (\n <div className=\"rounded-2xl rounded-tl-md border border-border bg-muted px-4 py-3 text-sm text-muted-foreground\">\n That answer didn't come through. Try asking again.\n </div>\n ) : null}\n\n {message.references.length > 0 ? (\n <div>\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Sources\n </p>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {message.references.map((reference) => (\n <ReferenceCard\n key={reference.url}\n reference={reference}\n onFollow={(url) => onFollow?.(\"REFERENCE\", url)}\n />\n ))}\n </div>\n </div>\n ) : null}\n\n {message.ctas.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 pt-0.5\">\n {message.ctas.map((cta) => (\n <CtaButton\n key={`${cta.kind}-${cta.url}`}\n cta={cta}\n onNavigate={onNavigate}\n onFollow={(url) => onFollow?.(\"CTA\", url)}\n />\n ))}\n </div>\n ) : null}\n\n {/* One question is a lookup; a second is a conversation. These are derived from\n what the answer actually cited, so they are always answerable. */}\n {message.status === \"COMPLETED\" &&\n (message.followUps?.length ?? 0) > 0 ? (\n <div className=\"space-y-1.5 pt-0.5\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n Next you could ask\n </p>\n <div className=\"flex flex-wrap gap-1.5\">\n {(message.followUps ?? []).map((question) => (\n <button\n key={question}\n data-boff-explore=\"follow-up\"\n type=\"button\"\n onClick={() => onFollowUp?.(question)}\n className=\"group inline-flex max-w-full items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1 text-left text-xs text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <span className=\"truncate\">{question}</span>\n <ArrowUp className=\"h-3 w-3 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary\" />\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Error banner\n// ============================================================================\n\nfunction ErrorBanner({\n error,\n onRetry,\n onReset,\n}: {\n error: ExploreChatError;\n onRetry: () => void;\n onReset: () => void;\n}) {\n const showRetry = error.retryable;\n const showReset = error.code === \"CONVERSATION_LIMIT\";\n\n return (\n <div\n data-boff-explore=\"error\"\n data-error-kind={error.kind}\n role=\"alert\"\n className=\"mb-3 flex items-start gap-3 rounded-xl border border-destructive/40 bg-destructive/10 px-3 py-2.5\"\n >\n {/* Solid destructive chip for the icon: `text-destructive` alone loses\n contrast against a dark background in dark mode. */}\n <span\n aria-hidden=\"true\"\n className=\"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-destructive text-destructive-foreground\"\n >\n <TriangleAlert className=\"h-3 w-3\" />\n </span>\n <p className=\"flex-1 text-sm leading-relaxed text-foreground\">\n {error.message}\n </p>\n {showRetry ? (\n <Button\n data-boff-explore=\"retry\"\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={onRetry}\n >\n Retry\n </Button>\n ) : null}\n {showReset ? (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onReset}>\n New chat\n </Button>\n ) : null}\n </div>\n );\n}\n\n// ============================================================================\n// Welcome / capability disclosure\n// ============================================================================\n\n/**\n * Example prompts as a single auto-advancing line.\n *\n * They used to wrap into a block several rows tall, which on a phone pushed everything below\n * it — including the composer — off the screen. One line costs a fixed ~40px no matter how\n * many prompts there are, and rotating through them keeps every prompt reachable without a\n * \"show more\".\n *\n * Autoplay pauses on hover and on keyboard focus, and never starts at all for visitors who\n * asked for reduced motion — for them the arrows are the whole interaction.\n */\nfunction PromptCarousel({\n prompts,\n onPrompt,\n disabled,\n}: {\n prompts: string[];\n onPrompt: (prompt: string) => void;\n disabled: boolean;\n}) {\n const [index, setIndex] = useState(0);\n const [paused, setPaused] = useState(false);\n\n const count = prompts.length;\n const current = prompts[index % count] ?? prompts[0] ?? \"\";\n\n const go = useCallback(\n (delta: number) => {\n setIndex((i) => (i + delta + count) % count);\n },\n [count],\n );\n\n useEffect(() => {\n if (paused || disabled || count < 2) return;\n if (\n typeof window !== \"undefined\" &&\n window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches\n ) {\n return;\n }\n const timer = setInterval(() => setIndex((i) => (i + 1) % count), 4500);\n return () => clearInterval(timer);\n }, [paused, disabled, count]);\n\n if (count === 0) return null;\n\n return (\n <div\n className=\"flex min-w-0 items-center gap-1.5\"\n role=\"group\"\n aria-roledescription=\"carousel\"\n aria-label=\"Example questions\"\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocusCapture={() => setPaused(true)}\n onBlurCapture={() => setPaused(false)}\n >\n {count > 1 ? (\n <button\n type=\"button\"\n aria-label=\"Previous suggestion\"\n onClick={() => go(-1)}\n className=\"hidden h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:inline-flex\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </button>\n ) : null}\n\n <button\n key={current}\n data-boff-explore=\"chip\"\n data-chip-kind=\"prompt\"\n type=\"button\"\n disabled={disabled}\n aria-label={`Ask: ${current}`}\n aria-live={paused ? \"polite\" : \"off\"}\n onClick={() => onPrompt(current)}\n /* min-w-0 + truncate is what keeps a long prompt from widening the page. */\n className=\"boff-explore-fade group flex min-w-0 flex-1 items-center gap-2 rounded-full border border-border bg-card px-4 py-2 text-left text-sm text-card-foreground shadow-sm transition-colors hover:border-primary/50 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <Sparkles className=\"h-3.5 w-3.5 shrink-0 text-primary\" />\n <span className=\"truncate\">{current}</span>\n <ArrowUp className=\"ml-auto h-3.5 w-3.5 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary\" />\n </button>\n\n {count > 1 ? (\n <button\n type=\"button\"\n aria-label=\"Next suggestion\"\n onClick={() => go(1)}\n className=\"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n );\n}\n\n/**\n * Product focus chips on one line, expandable.\n *\n * Collapsed is a single clipped row; expanded wraps to the full set. The row scrolls inside\n * itself rather than pushing the page wide — `overflow-x-auto` on a `min-w-0` flex child is\n * contained, and the scrollbar is hidden so it reads as a strip, not a scroller.\n */\nfunction ProductStrip({\n products,\n focusProduct,\n onFocus,\n}: {\n products: Array<{ slug: string; name: string; tagline?: string | null }>;\n focusProduct: string | null;\n onFocus: (slug: string | null) => void;\n}) {\n const [expanded, setExpanded] = useState(false);\n\n const chipClass = (active: boolean) =>\n cn(\n \"shrink-0 rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n );\n\n return (\n <div\n className=\"flex min-w-0 items-center gap-2\"\n role=\"group\"\n aria-label=\"Focus the assistant on one product\"\n >\n <div\n className={cn(\n \"boff-explore-strip flex min-w-0 flex-1 gap-2\",\n expanded ? \"flex-wrap\" : \"flex-nowrap overflow-x-auto\",\n )}\n >\n <button\n data-boff-explore=\"chip\"\n data-chip-kind=\"product\"\n data-product=\"all\"\n type=\"button\"\n aria-pressed={focusProduct === null}\n onClick={() => onFocus(null)}\n className={chipClass(focusProduct === null)}\n >\n All products\n </button>\n {products.map((product) => (\n <button\n key={product.slug}\n data-boff-explore=\"chip\"\n data-chip-kind=\"product\"\n data-product={product.slug}\n type=\"button\"\n aria-pressed={focusProduct === product.slug}\n title={product.tagline ?? product.name}\n onClick={() =>\n onFocus(focusProduct === product.slug ? null : product.slug)\n }\n className={chipClass(focusProduct === product.slug)}\n >\n {product.name}\n </button>\n ))}\n </div>\n {products.length > 0 ? (\n <button\n type=\"button\"\n data-boff-explore=\"products-toggle\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n className=\"shrink-0 whitespace-nowrap rounded-full px-2 py-1 text-xs font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n {expanded ? \"Show less\" : `All ${products.length}`}\n </button>\n ) : null}\n </div>\n );\n}\n\n/**\n * The storage notice, behind a link.\n *\n * It has to be said — conversations really are kept — but as three permanent sentences under\n * the composer it was the largest thing on a phone screen. A link plus a dialog says the same\n * thing and costs one line.\n *\n * Hand-rolled rather than a Radix dialog: `@radix-ui/react-dialog` is not among the SDK's peer\n * dependencies, and adding one would mean an install across all 39 consuming sites for a\n * single popup.\n */\nfunction DisclaimerDialog({\n open,\n onClose,\n captchaOn,\n}: {\n open: boolean;\n onClose: () => void;\n captchaOn: boolean;\n}) {\n const panelRef = useRef<HTMLDivElement>(null);\n const closeRef = useRef<HTMLButtonElement>(null);\n const titleId = \"boff-explore-disclaimer-title\";\n\n useEffect(() => {\n if (!open) return;\n\n // Remember where focus came from so it can be handed back — a dialog that dumps focus\n // at the top of the document strands a keyboard or screen-reader user.\n const opener =\n document.activeElement instanceof HTMLElement\n ? document.activeElement\n : null;\n\n // Deliberately NOT filtered by `offsetParent !== null`. That is the usual visibility\n // test, but offsetParent is null for elements inside a `position: fixed` container —\n // which this dialog is — so the filter silently emptied the list and the trap never\n // engaged. The panel only exists while open and holds nothing hidden, so every match\n // here is focusable by construction.\n const focusable = () =>\n Array.from(\n panelRef.current?.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex=\"-1\"])',\n ) ?? [],\n );\n\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n return;\n }\n // Focus trap. Without it Tab walks straight out of the dialog and onto the page\n // behind the overlay, where the visitor cannot see what is focused.\n if (event.key !== \"Tab\") return;\n const items = focusable();\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n if (\n event.shiftKey &&\n (active === first || !panelRef.current?.contains(active))\n ) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first?.focus();\n }\n };\n\n document.addEventListener(\"keydown\", onKey);\n closeRef.current?.focus();\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n opener?.focus();\n };\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <div\n data-boff-explore=\"disclaimer-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className=\"fixed inset-0 z-50 flex items-end justify-center bg-foreground/40 p-4 backdrop-blur-sm sm:items-center\"\n onClick={onClose}\n >\n <div\n ref={panelRef}\n className=\"w-full max-w-md rounded-2xl border border-border bg-card p-5 shadow-xl\"\n onClick={(event) => event.stopPropagation()}\n >\n <div className=\"flex items-start gap-3\">\n <span\n aria-hidden=\"true\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\"\n >\n <TriangleAlert className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0\">\n <p\n id={titleId}\n className=\"text-sm font-semibold text-card-foreground\"\n >\n How this assistant works\n </p>\n <div className=\"mt-2 space-y-2 text-xs leading-relaxed text-muted-foreground\">\n <p>\n Answers are generated from our public documentation and can be\n imperfect — check anything important against the linked sources.\n </p>\n {/* Conversations are recorded server-side, so say so plainly. */}\n <p>\n Conversations are saved in this browser so you can come back to\n them, and are also stored on our servers to help us improve\n these answers. Please don't share personal or confidential\n information.\n </p>\n {captchaOn ? (\n <p>\n Protected by reCAPTCHA — the Google Privacy Policy and Terms\n of Service apply.\n </p>\n ) : null}\n </div>\n </div>\n </div>\n <div className=\"mt-4 flex justify-end\">\n <Button\n ref={closeRef}\n size=\"sm\"\n variant=\"secondary\"\n onClick={onClose}\n >\n Got it\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction WelcomeState({\n title,\n body,\n prompts,\n products,\n focusProduct,\n onPrompt,\n onFocus,\n disabled,\n}: {\n title: string;\n body: string;\n prompts: string[];\n products: Array<{ slug: string; name: string; tagline?: string | null }>;\n focusProduct: string | null;\n onPrompt: (prompt: string) => void;\n onFocus: (slug: string | null) => void;\n disabled: boolean;\n}) {\n return (\n <div className=\"mx-auto w-full max-w-3xl px-4 py-8 sm:py-12\">\n <div className=\"text-center\">\n <span className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-3 py-1 text-xs font-medium text-muted-foreground\">\n <Sparkles className=\"h-3.5 w-3.5\" />\n AI answers, grounded in our documentation\n </span>\n {/* Rendered synchronously on the first paint — the static prerender\n waits for an <h1> and must never capture a blank page. */}\n <h1 className=\"mt-4 text-balance break-words text-2xl font-bold tracking-tight sm:text-4xl\">\n {title}\n </h1>\n <p className=\"mx-auto mt-2.5 max-w-2xl text-pretty text-sm leading-relaxed text-muted-foreground sm:text-lg\">\n {body}\n </p>\n </div>\n\n <ul className=\"mt-7 grid gap-2.5 sm:grid-cols-3\">\n {CAPABILITIES.map(({ icon: Icon, title: capTitle, body: capBody }) => (\n <li\n key={capTitle}\n className=\"rounded-xl border border-border/70 bg-card/60 p-3.5 text-left transition-colors hover:border-border\"\n >\n <span className=\"mb-2.5 flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <Icon className=\"h-4 w-4\" />\n </span>\n <p className=\"text-sm font-semibold text-card-foreground\">\n {capTitle}\n </p>\n <p className=\"mt-1 text-xs leading-relaxed text-muted-foreground\">\n {capBody}\n </p>\n </li>\n ))}\n </ul>\n\n {prompts.length > 0 ? (\n <div className=\"mt-8\">\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Try asking\n </p>\n <PromptCarousel\n prompts={prompts}\n onPrompt={onPrompt}\n disabled={disabled}\n />\n </div>\n ) : null}\n\n {products.length > 0 ? (\n <div className=\"mt-6\">\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Focus on a product\n </p>\n <ProductStrip\n products={products}\n focusProduct={focusProduct}\n onFocus={onFocus}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\n// ============================================================================\n// Main component\n// ============================================================================\n\nexport function ExplorePage({\n seo,\n productSlug,\n examplePrompts,\n className,\n heightMode = \"viewport\",\n viewportOffset,\n onNavigate,\n onSend,\n welcomeTitle,\n welcomeBody,\n}: ExplorePageProps) {\n const pageUrl = useMemo(\n () => (typeof window === \"undefined\" ? undefined : window.location.href),\n [],\n );\n\n const {\n phase,\n catalog,\n messages,\n activity,\n remainingToday,\n error,\n focusProduct,\n setFocusProduct,\n send,\n stop,\n retry,\n reset,\n canSend,\n history,\n openConversation,\n deleteConversation,\n clearHistory,\n recordClick,\n } = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });\n\n const [draft, setDraft] = useState(\"\");\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Dictation, on the browser's own recogniser. Settled speech is appended to whatever is\n // already typed, so a visitor can mix typing and talking in one message.\n const [historyOpen, setHistoryOpen] = useState(false);\n\n const speechStopRef = useRef<() => void>(() => undefined);\n const stopDictation = useCallback(() => {\n speechStopRef.current();\n }, []);\n\n const speech = useSpeechInput({\n onFinalTranscript: (text) => {\n setDraft((current) => {\n const joined =\n current.trim() === \"\"\n ? text.trimStart()\n : `${current.trimEnd()} ${text.trim()}`;\n return joined;\n });\n textareaRef.current?.focus();\n },\n });\n speechStopRef.current = speech.stop;\n const [disclaimerOpen, setDisclaimerOpen] = useState(false);\n const scrollRef = useRef<HTMLDivElement>(null);\n const latestAssistantRef = useRef<HTMLDivElement>(null);\n /** id of the answer whose top has already been aligned, so it happens once per turn. */\n const alignedForRef = useRef<string | null>(null);\n const stickToBottomRef = useRef(true);\n const composingRef = useRef(false);\n\n const busy = phase === \"sending\" || phase === \"streaming\";\n const showWelcome = messages.length === 0;\n const maxLength = catalog.limits.maxMessageLength;\n const overLimit = draft.length > maxLength;\n const canSubmit = canSend && draft.trim().length > 0 && !overLimit && !busy;\n\n const resolvedTitle = welcomeTitle ?? catalog.welcomeTitle;\n const resolvedBody = welcomeBody ?? catalog.welcomeBody;\n // Resolution order (catalog → prop → SDK built-in) lives in the hook, which\n // seeds its fallback catalog from the `examplePrompts` prop.\n const prompts = catalog.examplePrompts;\n\n const focusedProductName = useMemo(\n () => catalog.products.find((p) => p.slug === focusProduct)?.name ?? null,\n [catalog.products, focusProduct],\n );\n\n // --- auto-grow the composer -------------------------------------------\n useEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n el.style.height = `${Math.min(el.scrollHeight, 200)}px`;\n }, [draft]);\n\n // --- transcript positioning --------------------------------------------\n //\n // An answer plus its sources is routinely taller than a phone screen, so pinning the\n // transcript to the BOTTOM landed the visitor below the sources and made them scroll up\n // to find the response they had just asked for. Instead each new answer is anchored by\n // its TOP: the reply starts where the eye already is and grows downward.\n //\n // Bottom-sticking is kept only for the pre-answer phase, so the \"thinking\" indicator\n // stays visible while the turn is still running.\n const handleScroll = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n stickToBottomRef.current =\n el.scrollHeight - el.scrollTop - el.clientHeight < 80;\n }, []);\n\n const latestAssistantId = useMemo(() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message && message.role === \"ASSISTANT\") return message.id;\n }\n return null;\n }, [messages]);\n\n useEffect(() => {\n const el = scrollRef.current;\n const anchor = latestAssistantRef.current;\n if (!el || !anchor || !latestAssistantId) return;\n\n // Only align once per answer, and never against a visitor who has scrolled away to\n // read something else — yanking the viewport out from under them is worse than the\n // problem this solves.\n if (alignedForRef.current === latestAssistantId) return;\n if (!stickToBottomRef.current) return;\n\n // Wait for the answer to actually have height; aligning an empty bubble puts the top\n // of a zero-height element at the top of an otherwise blank transcript.\n if (anchor.offsetHeight === 0) return;\n\n alignedForRef.current = latestAssistantId;\n // Measured as a rect delta rather than via `offsetTop`: offsetTop is relative to the\n // nearest POSITIONED ancestor, and this scroll container is not positioned, so it would\n // resolve against something further up the page and land in the wrong place.\n // `scrollIntoView` is also wrong here — on mobile it scrolls the page as well as the\n // container, dragging the composer off-screen.\n const delta =\n anchor.getBoundingClientRect().top - el.getBoundingClientRect().top;\n el.scrollTop = Math.max(0, el.scrollTop + delta - 12);\n }, [latestAssistantId, messages]);\n\n // While the turn is still running there is no answer to anchor yet, so keep the thinking\n // indicator in view the old way.\n useEffect(() => {\n if (!stickToBottomRef.current) return;\n if (latestAssistantId && alignedForRef.current === latestAssistantId)\n return;\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [activity, latestAssistantId, messages]);\n\n // --- send --------------------------------------------------------------\n const submitDraft = useCallback(() => {\n const text = draft.trim();\n if (!text || overLimit || busy || !canSend) return;\n // Close the microphone on send — leaving it hot would keep dictating into the next message.\n stopDictation();\n setDraft(\"\");\n stickToBottomRef.current = true;\n void send(text);\n textareaRef.current?.focus();\n }, [busy, canSend, draft, overLimit, send, stopDictation]);\n\n const sendPrompt = useCallback(\n (prompt: string) => {\n if (!canSend || busy) return;\n setDraft(\"\");\n stickToBottomRef.current = true;\n void send(prompt);\n },\n [busy, canSend, send],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey) return;\n // IME safety: while a CJK/other candidate window is open, Enter commits\n // the candidate and must not send the message.\n if (composingRef.current || event.nativeEvent.isComposing) return;\n event.preventDefault();\n submitDraft();\n },\n [submitDraft],\n );\n\n const composerDisabled =\n phase === \"limited\" || phase === \"disabled\" || !catalog.enabled;\n const captchaOn = Boolean(\n catalog.captchaRequired && catalog.recaptchaSiteKey,\n );\n\n const rootStyle =\n heightMode === \"viewport\"\n ? { height: `calc(100dvh - ${normalizeOffset(viewportOffset)})` }\n : undefined;\n\n return (\n <div\n data-boff-explore=\"page\"\n data-phase={phase}\n className={cn(\n \"flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground\",\n heightMode === \"auto\" && \"min-h-[70vh]\",\n className,\n )}\n style={rootStyle}\n >\n {seo ? (\n <PageHead\n title={seo.title ?? \"Explore — ask anything about our products\"}\n description={\n seo.description ??\n \"Ask questions in plain English and get answers drawn from our product documentation, with links to the exact pages they came from.\"\n }\n keywords={seo.keywords}\n image={seo.image}\n url={seo.url}\n />\n ) : null}\n <ProseStyles />\n <ExploreStyles />\n\n {/* Compact header in conversation mode — keeps exactly one <h1> on the\n page whichever state we are in. */}\n {!showWelcome ? (\n <div className=\"flex items-center gap-2.5 border-b border-border px-4 py-2.5\">\n <span\n aria-hidden=\"true\"\n className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\"\n >\n <Sparkles className=\"h-4 w-4\" />\n </span>\n <h1 className=\"truncate text-sm font-semibold\">{resolvedTitle}</h1>\n {focusedProductName ? (\n <span className=\"hidden shrink-0 rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground sm:inline\">\n {focusedProductName}\n </span>\n ) : null}\n <Button\n data-boff-explore=\"new-chat\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto shrink-0 text-muted-foreground\"\n onClick={reset}\n >\n <RotateCcw className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">New chat</span>\n </Button>\n {history.length > 0 ? (\n <Button\n data-boff-explore=\"history-toggle\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"shrink-0 text-muted-foreground\"\n aria-expanded={historyOpen}\n onClick={() => {\n setHistoryOpen((open) => !open);\n }}\n >\n <HistoryIcon className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">\n History ({history.length})\n </span>\n </Button>\n ) : null}\n </div>\n ) : null}\n\n {/* Past conversations, held in this browser only. */}\n {historyOpen && history.length > 0 ? (\n <div\n data-boff-explore=\"history-panel\"\n className=\"border-b border-border bg-muted/30 px-4 py-3\"\n >\n <div className=\"mx-auto w-full max-w-3xl\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Your recent conversations\n </p>\n <Button\n data-boff-explore=\"history-clear\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-7 shrink-0 text-xs text-muted-foreground hover:text-destructive\"\n onClick={() => {\n clearHistory();\n setHistoryOpen(false);\n }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n Clear history\n </Button>\n </div>\n <ul className=\"space-y-1\">\n {history.map((entry) => (\n <li key={entry.token} className=\"flex items-center gap-1\">\n <button\n data-boff-explore=\"history-item\"\n type=\"button\"\n className=\"flex-1 truncate rounded-md px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground\"\n onClick={() => {\n openConversation(entry.token);\n setHistoryOpen(false);\n }}\n >\n <span className=\"truncate\">{entry.title}</span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {entry.messageCount} message\n {entry.messageCount === 1 ? \"\" : \"s\"}\n </span>\n </button>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-7 w-7 shrink-0 text-muted-foreground hover:text-destructive\"\n aria-label={`Delete conversation: ${entry.title}`}\n onClick={() => {\n deleteConversation(entry.token);\n }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </li>\n ))}\n </ul>\n </div>\n </div>\n ) : null}\n\n {/* Transcript */}\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n data-boff-explore=\"messages\"\n role=\"log\"\n aria-live=\"polite\"\n aria-label=\"Explore conversation\"\n className=\"boff-explore-scroll min-h-0 min-w-0 flex-1 overflow-y-auto overflow-x-hidden\"\n >\n {showWelcome ? (\n <WelcomeState\n title={resolvedTitle}\n body={resolvedBody}\n prompts={prompts}\n products={catalog.products}\n focusProduct={focusProduct}\n onPrompt={sendPrompt}\n onFocus={setFocusProduct}\n disabled={!canSend || busy}\n />\n ) : (\n <div className=\"mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6\">\n {messages.map((message) =>\n message.role === \"USER\" ? (\n <UserBubble key={message.id} message={message} />\n ) : (\n <AssistantBubble\n key={message.id}\n message={message}\n activity={activity}\n onNavigate={onNavigate}\n anchorRef={\n message.id === latestAssistantId\n ? latestAssistantRef\n : undefined\n }\n onFollow={(kind, url) => recordClick(message.id, kind, url)}\n onFollowUp={sendPrompt}\n />\n ),\n )}\n </div>\n )}\n </div>\n\n <DisclaimerDialog\n open={disclaimerOpen}\n onClose={() => setDisclaimerOpen(false)}\n captchaOn={captchaOn}\n />\n\n {/* Composer */}\n <div className=\"border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md\">\n <form\n data-boff-explore=\"composer\"\n className=\"mx-auto w-full max-w-3xl\"\n onSubmit={(event) => {\n event.preventDefault();\n submitDraft();\n }}\n >\n {error ? (\n <ErrorBanner error={error} onRetry={retry} onReset={reset} />\n ) : null}\n\n <div\n className={cn(\n \"flex min-w-0 items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-all\",\n overLimit\n ? \"border-destructive/60\"\n : \"border-border focus-within:border-primary/40 focus-within:ring-1 focus-within:ring-ring\",\n )}\n >\n <Textarea\n ref={textareaRef}\n value={draft}\n rows={1}\n disabled={composerDisabled}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onCompositionStart={() => {\n composingRef.current = true;\n }}\n onCompositionEnd={() => {\n composingRef.current = false;\n }}\n aria-label=\"Ask a question\"\n placeholder={\n composerDisabled\n ? phase === \"limited\"\n ? \"Message limit reached — please try again later\"\n : \"Explore is unavailable right now\"\n : focusedProductName\n ? `Ask about ${focusedProductName}…`\n : \"Ask anything about our products…\"\n }\n className=\"max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-sm shadow-none focus-visible:ring-0 md:text-sm\"\n />\n {speech.supported ? (\n <Button\n data-boff-explore=\"mic\"\n data-listening={speech.listening ? \"true\" : \"false\"}\n type=\"button\"\n size=\"icon\"\n variant={speech.listening ? \"default\" : \"ghost\"}\n disabled={composerDisabled}\n aria-label={\n speech.listening ? \"Stop dictating\" : \"Dictate your question\"\n }\n aria-pressed={speech.listening}\n title={\n speech.listening ? \"Stop dictating\" : \"Dictate your question\"\n }\n onClick={speech.toggle}\n className={cn(speech.listening && \"animate-pulse\")}\n >\n <Mic className=\"h-4 w-4\" />\n </Button>\n ) : null}\n {busy ? (\n <Button\n data-boff-explore=\"stop\"\n type=\"button\"\n size=\"icon\"\n variant=\"secondary\"\n aria-label=\"Stop generating\"\n onClick={stop}\n >\n <Square className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n data-boff-explore=\"send\"\n type=\"submit\"\n size=\"icon\"\n disabled={!canSubmit}\n aria-label=\"Send message\"\n >\n <ArrowUp className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n\n {speech.listening || speech.interim !== \"\" ? (\n <p\n data-boff-explore=\"dictation\"\n className=\"mt-2 flex items-center gap-2 text-xs text-muted-foreground\"\n aria-live=\"polite\"\n >\n <span className=\"relative flex h-2 w-2 shrink-0\">\n <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75\" />\n <span className=\"relative inline-flex h-2 w-2 rounded-full bg-primary\" />\n </span>\n <span className=\"italic\">\n {speech.interim !== \"\" ? speech.interim : \"Listening…\"}\n </span>\n </p>\n ) : null}\n {speech.error !== null ? (\n <p\n data-boff-explore=\"dictation-error\"\n className=\"mt-2 text-xs text-destructive\"\n >\n {speech.error}\n </p>\n ) : null}\n\n <div className=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"hidden sm:inline\">\n Enter to send · Shift + Enter for a new line\n </span>\n {remainingToday !== null ? (\n <span data-boff-explore=\"remaining\">\n {remainingToday} message{remainingToday === 1 ? \"\" : \"s\"} left\n today\n </span>\n ) : null}\n <span\n className={cn(\n \"ml-auto tabular-nums\",\n overLimit && \"font-medium text-destructive\",\n )}\n >\n {draft.length.toLocaleString()} / {maxLength.toLocaleString()}\n </span>\n </div>\n\n {/* One line instead of three sentences. The notice still has to be said — the\n conversation really is stored — but as permanent body copy it was the tallest\n thing on a phone screen, directly under the control people came here to use. */}\n <div className=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"min-w-0 truncate\">\n Grounded in our docs — check anything important.\n </span>\n <button\n type=\"button\"\n data-boff-explore=\"disclaimer\"\n onClick={() => setDisclaimerOpen(true)}\n className=\"shrink-0 underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n Disclaimer\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/content/Markdown.tsx","../../src/content/prose-styles.tsx","../../src/client/security.ts","../../src/client/graphql-client.ts","../../src/client/provider.tsx","../../src/components/explore-types.ts","../../src/data/products.ts","../../src/utils/recaptcha-v3.ts","../../src/hooks/use-explore-chat.ts","../../src/hooks/use-speech-input.ts","../../src/seo/page-head.tsx","../../src/utils/cn.ts","../../src/ui/button.tsx","../../src/ui/textarea.tsx","../../src/components/explore.tsx"],"names":["jsx","ReactMarkdown","remarkGfm","rehypeSanitize","createContext","useContext","useMemo","useState","useRef","useCallback","useEffect","Helmet","twMerge","clsx","cva","React","Slot","React2","BookOpenText","Layers","Link2","jsxs","ExternalLink","Sparkles","TriangleAlert","ArrowUp","ChevronLeft","ChevronRight","RotateCcw","HistoryIcon","Trash2","Mic","Square"],"mappings":"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","file":"explore.js","sourcesContent":["import type { ReactNode } from \"react\";\n\nimport ReactMarkdown from \"react-markdown\";\nimport rehypeSanitize from \"rehype-sanitize\";\nimport remarkGfm from \"remark-gfm\";\n\nimport type { Components } from \"react-markdown\";\n\nexport interface MarkdownProps {\n /** Markdown source to render. */\n children: string;\n /** Additional classes for the wrapper element. */\n className?: string;\n /** Render without a wrapping block element, suitable for inline content. */\n inline?: boolean;\n /** Optional react-markdown component overrides. */\n components?: Components;\n}\n\nconst defaultComponents: Components = {\n a: ({ href, children, ...props }) => {\n const isExternal =\n typeof href === \"string\" &&\n (href.startsWith(\"http://\") || href.startsWith(\"https://\"));\n return (\n <a\n href={href}\n {...props}\n {...(isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : { rel: \"noopener noreferrer\" })}\n >\n {children}\n </a>\n );\n },\n};\n\n/**\n * Shared markdown renderer for website content.\n *\n * - Uses `react-markdown` for standards-compliant parsing.\n * - Enables GitHub Flavored Markdown (tables, task lists, strikethrough, autolinks).\n * - Sanitizes HTML via `rehype-sanitize` so raw markup in markdown is stripped.\n * - External links open in a new tab with safe rel attributes.\n */\nexport function Markdown({\n children,\n className,\n inline,\n components,\n}: MarkdownProps): ReactNode {\n const content = (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeSanitize]}\n components={{ ...defaultComponents, ...components }}\n {...(inline ? { disallowedElements: [\"p\"], unwrapDisallowed: true } : {})}\n >\n {children}\n </ReactMarkdown>\n );\n\n if (inline) {\n return <span className={className}>{content}</span>;\n }\n\n return <div className={className}>{content}</div>;\n}\n","\"use client\";\n\n/**\n * Self-contained prose styles for SDK content renderers.\n *\n * These components inject a scoped `.boff-prose` stylesheet so markdown content\n * renders correctly even when the host website does not install\n * `@tailwindcss/typography` or define `.prose` CSS.\n */\n\nexport const PROSE_CSS = `\n.boff-prose {\n max-width: none;\n}\n\n.boff-prose h1 {\n font-size: 2.25rem;\n font-weight: 800;\n line-height: 1.2;\n margin-top: 0;\n margin-bottom: 1rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h2 {\n font-size: 1.75rem;\n font-weight: 700;\n line-height: 1.3;\n margin-top: 2rem;\n margin-bottom: 1rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h3 {\n font-size: 1.5rem;\n font-weight: 600;\n line-height: 1.4;\n margin-top: 1.5rem;\n margin-bottom: 0.75rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose h4 {\n font-size: 1.25rem;\n font-weight: 600;\n line-height: 1.5;\n margin-top: 1.25rem;\n margin-bottom: 0.5rem;\n color: hsl(var(--foreground));\n}\n\n.boff-prose p {\n margin-bottom: 1rem;\n line-height: 1.75;\n color: hsl(var(--foreground));\n}\n\n.boff-prose ul,\n.boff-prose ol {\n margin-bottom: 1rem;\n padding-left: 1.5rem;\n}\n\n.boff-prose ul {\n list-style-type: disc;\n}\n\n.boff-prose ol {\n list-style-type: decimal;\n}\n\n.boff-prose li {\n margin-bottom: 0.25rem;\n line-height: 1.75;\n color: hsl(var(--foreground));\n}\n\n.boff-prose li > ul,\n.boff-prose li > ol {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n\n.boff-prose a {\n color: hsl(var(--primary));\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.boff-prose a:hover {\n opacity: 0.8;\n}\n\n.boff-prose hr {\n border: none;\n height: 1px;\n background-color: hsl(var(--border));\n margin: 2rem 0;\n}\n\n.boff-prose blockquote {\n border-left: 4px solid hsl(var(--border));\n padding-left: 1rem;\n margin: 1.5rem 0;\n font-style: italic;\n color: hsl(var(--muted-foreground));\n}\n\n.boff-prose strong {\n font-weight: 700;\n color: hsl(var(--foreground));\n}\n\n.boff-prose code {\n background-color: hsl(var(--muted));\n padding: 0.125rem 0.25rem;\n border-radius: 0.25rem;\n font-size: 0.875em;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n.boff-prose pre {\n background-color: hsl(var(--muted));\n padding: 1rem;\n border-radius: 0.5rem;\n overflow-x: auto;\n margin-bottom: 1rem;\n}\n\n.boff-prose pre code {\n background-color: transparent;\n padding: 0;\n}\n\n.boff-prose img {\n max-width: 100%;\n height: auto;\n}\n\n.boff-prose table {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: 1rem;\n}\n\n.boff-prose th,\n.boff-prose td {\n border: 1px solid hsl(var(--border));\n padding: 0.5rem;\n text-align: left;\n}\n\n.boff-prose th {\n font-weight: 600;\n background-color: hsl(var(--muted));\n}\n\n/* Smaller variant used inside cards and compact panels */\n.boff-prose-sm {\n font-size: 0.875rem;\n}\n\n.boff-prose-sm h1 {\n font-size: 1.75rem;\n}\n\n.boff-prose-sm h2 {\n font-size: 1.5rem;\n}\n\n.boff-prose-sm h3 {\n font-size: 1.25rem;\n}\n\n.boff-prose-sm h4 {\n font-size: 1.125rem;\n}\n\n.boff-prose-sm p,\n.boff-prose-sm li {\n line-height: 1.625;\n}\n`;\n\nexport function ProseStyles() {\n return <style dangerouslySetInnerHTML={{ __html: PROSE_CSS }} />;\n}\n","const LOOPBACK_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\"]);\nconst RESERVED_HEADERS = new Set([\n \"authorization\",\n \"cookie\",\n \"x-actor-id\",\n \"x-actor-type\",\n \"x-consent-granted-by\",\n \"x-consent-scope\",\n \"x-consent-granted-at\",\n \"x-consent-expires-at\",\n]);\n\nexport function validateGatewayUrl(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"Gateway URL must be a valid absolute URL\");\n }\n\n if (url.protocol === \"https:\") {\n return url.toString();\n }\n\n if (\n url.protocol === \"http:\" &&\n LOOPBACK_HOSTS.has(url.hostname.toLowerCase())\n ) {\n return url.toString();\n }\n\n throw new Error(\"Gateway URL must use HTTPS unless it targets localhost\");\n}\n\nexport function sanitizeHeaders(\n headers?: Record<string, string>,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n\n return Object.fromEntries(\n Object.entries(headers).filter(\n ([key]) => !RESERVED_HEADERS.has(key.toLowerCase()),\n ),\n );\n}\n\n/**\n * Hostnames whose Cloudflare Access application gates the GraphQL gateway.\n *\n * Only the alpha gateways are gated; the production gateways are public, so a token is never\n * attached there even if one is configured.\n */\nconst CF_ACCESS_GATED_HOSTS = new Set([\n \"alphagraphql.burdenoff.com\",\n \"alphagraphqlworkspaces.burdenoff.com\",\n]);\n\n/**\n * Service-token headers for a gated gateway, or nothing.\n *\n * Returns an empty object unless the target really is a gated host AND both halves of the token\n * are present — a half-configured token would send a malformed credential to every request.\n */\nexport function cfAccessHeaders(\n gatewayUrl: string,\n cfAccess?: { clientId?: string; clientSecret?: string },\n): Record<string, string> {\n const clientId = cfAccess?.clientId?.trim();\n const clientSecret = cfAccess?.clientSecret?.trim();\n if (!clientId || !clientSecret) return {};\n\n let host: string;\n try {\n host = new URL(gatewayUrl).hostname.toLowerCase();\n } catch {\n return {};\n }\n if (!CF_ACCESS_GATED_HOSTS.has(host)) return {};\n\n return {\n \"CF-Access-Client-Id\": clientId,\n \"CF-Access-Client-Secret\": clientSecret,\n };\n}\n","/**\n * Lightweight GraphQL client for the Burdenoff Web SDK.\n * Uses native fetch - zero external dependencies.\n * All calls are unauthenticated (public gateway operations only).\n */\n\nimport {\n cfAccessHeaders,\n sanitizeHeaders,\n validateGatewayUrl,\n} from \"./security\";\n\nexport interface WebSDKClientConfig {\n /** Global public gateway URL (e.g. \"https://api.burdenoff.com/global/graphql\") */\n gatewayUrl: string;\n /** Platform product ID for scoping operations */\n productId: string;\n /** Product slug (used for public product queries) */\n productSlug?: string;\n /** reCAPTCHA site key (if not fetched from product config) */\n recaptchaSiteKey?: string;\n /** Rybbit analytics site ID */\n rybbitSiteId?: string;\n /** Custom headers to include in all requests */\n headers?: Record<string, string>;\n /**\n * Cloudflare Access service token, for the ALPHA gateway hosts only.\n *\n * `alphagraphql.burdenoff.com` sits behind a Cloudflare Access application, so an\n * unauthenticated browser XHR is answered with a 302 to the Access login on a different\n * origin — which the browser reports as an opaque CORS failure rather than a 401. Attaching\n * the service-token headers is how every app shell already passes that gate (fe-libs\n * `installGatewayFetchRewrite`); the website SDK previously had no equivalent, so contact,\n * newsletter, waitlist and explore all failed on alpha.\n *\n * Vite only inlines `VITE_*` into APP source, never into a bundled library, so the host app\n * must read `import.meta.env` and pass the values in. Production gateways are not gated and\n * receive no headers.\n */\n cfAccess?: { clientId?: string; clientSecret?: string };\n /**\n * Per-request timeout in ms. Kept below the gateway's operation timeout so a\n * stalled request surfaces as an error the UI can render, instead of leaving\n * a page stuck on loading skeletons forever. Default 12000.\n */\n timeoutMs?: number;\n /**\n * Extra attempts for transient failures (timeout / network / 5xx / 429) on\n * QUERIES ONLY. Mutations are never retried — a retried contact-form or\n * waitlist submit would double-submit. Default 1 (2 attempts total).\n */\n maxRetries?: number;\n}\n\n/**\n * Per-call overrides for {@link WebSDKClient.query}.\n *\n * The defaults (5-minute response cache + in-flight deduplication) are right\n * for the read-once content queries most SDK components make, and wrong for a\n * poll loop: the second poll of the same `(query, variables)` pair would be\n * served straight from the cache and the UI would freeze on the first\n * response forever. Pass `{ cache: false }` for anything polled.\n */\nexport interface WebSDKQueryOptions {\n /**\n * Use the response cache and in-flight deduplication. Default `true`.\n * `false` skips the cache read, the dedupe map AND the cache write, so the\n * call always hits the network and never poisons a later cached read.\n */\n cache?: boolean;\n /** Override the client-wide request timeout for this call only. */\n timeoutMs?: number;\n}\n\n/** Per-call overrides for {@link WebSDKClient.mutate}. */\nexport interface WebSDKMutateOptions {\n /** Override the client-wide request timeout for this call only. */\n timeoutMs?: number;\n}\n\nexport interface GraphQLResponse<T = Record<string, unknown>> {\n data?: T;\n errors?: Array<{\n message: string;\n locations?: Array<{ line: number; column: number }>;\n path?: Array<string | number>;\n extensions?: Record<string, unknown>;\n }>;\n}\n\nexport class WebSDKClient {\n private config: WebSDKClientConfig;\n private queryCache = new Map<\n string,\n { data: GraphQLResponse<unknown>; ts: number }\n >();\n private inflight = new Map<string, Promise<GraphQLResponse<unknown>>>();\n private static CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n private static MAX_CACHE_ENTRIES = 100;\n private static DEFAULT_TIMEOUT_MS = 12_000;\n private static DEFAULT_MAX_RETRIES = 1;\n private static RETRY_BASE_DELAY_MS = 400;\n\n constructor(config: WebSDKClientConfig) {\n this.config = {\n ...config,\n gatewayUrl: validateGatewayUrl(config.gatewayUrl),\n headers: sanitizeHeaders(config.headers),\n };\n }\n\n getConfig(): WebSDKClientConfig {\n return this.config;\n }\n\n /**\n * Execute a GraphQL query (with deduplication and caching).\n *\n * Pass `{ cache: false }` to bypass the cache entirely — required for poll\n * loops, where every tick must reach the network.\n */\n async query<T = Record<string, unknown>>(\n query: string,\n variables?: Record<string, unknown>,\n options?: WebSDKQueryOptions,\n ): Promise<GraphQLResponse<T>> {\n // Uncached path: no cache read, no in-flight dedupe, no cache write.\n // Deliberately bypasses the dedupe map too — two identical polls issued a\n // few hundred ms apart must both hit the network, otherwise the second one\n // resolves with the first one's (already stale) snapshot.\n if (options?.cache === false) {\n return this.request<T>(query, variables, true, options.timeoutMs);\n }\n\n const cacheKey = JSON.stringify({ query, variables });\n\n // Return cached response if still valid, evict if expired\n const cached = this.queryCache.get(cacheKey);\n if (cached) {\n if (Date.now() - cached.ts < WebSDKClient.CACHE_TTL) {\n return cached.data as GraphQLResponse<T>;\n }\n this.queryCache.delete(cacheKey);\n }\n\n // Deduplicate: if same query is already in-flight, reuse the promise\n const existing = this.inflight.get(cacheKey);\n if (existing) {\n return existing as Promise<GraphQLResponse<T>>;\n }\n\n const promise = this.request<T>(query, variables, true, options?.timeoutMs)\n .then((result) => {\n // Cache successful responses only\n if (result.data && !result.errors?.length) {\n if (this.queryCache.size >= WebSDKClient.MAX_CACHE_ENTRIES) {\n const oldestEntry = this.queryCache.keys().next().value;\n if (oldestEntry) {\n this.queryCache.delete(oldestEntry);\n }\n }\n this.queryCache.set(cacheKey, { data: result, ts: Date.now() });\n }\n return result;\n })\n .finally(() => {\n this.inflight.delete(cacheKey);\n });\n\n this.inflight.set(cacheKey, promise);\n return promise;\n }\n\n /**\n * Execute a GraphQL mutation\n */\n async mutate<T = Record<string, unknown>>(\n mutation: string,\n variables?: Record<string, unknown>,\n options?: WebSDKMutateOptions,\n ): Promise<GraphQLResponse<T>> {\n // retry=false: a retried mutation could double-submit (contact form,\n // waitlist signup, order). Only the timeout applies here.\n return this.request<T>(mutation, variables, false, options?.timeoutMs);\n }\n\n /** HTTP statuses worth another attempt — transient server/edge conditions. */\n private static isRetriableStatus(status: number): boolean {\n return status === 429 || status === 408 || (status >= 500 && status < 600);\n }\n\n private static sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Perform the HTTP call with a hard timeout. Every outcome resolves to a\n * GraphQLResponse — callers never hang, so a UI's `loading` state always\n * settles into data or a renderable error.\n */\n private async attempt<T>(\n query: string,\n variables: Record<string, unknown> | undefined,\n timeoutMs: number,\n ): Promise<{ res: GraphQLResponse<T>; retriable: boolean }> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(this.config.gatewayUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-product-id\": this.config.productId,\n ...this.config.headers,\n ...cfAccessHeaders(this.config.gatewayUrl, this.config.cfAccess),\n },\n body: JSON.stringify({ query, variables }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n console.error(\n \"[WebSDK] GraphQL request failed\",\n response.status,\n response.statusText,\n );\n return {\n res: {\n errors: [\n {\n message: `HTTP ${response.status}: ${response.statusText}`,\n extensions: { code: `HTTP_${response.status}` },\n },\n ],\n },\n retriable: WebSDKClient.isRetriableStatus(response.status),\n };\n }\n\n return {\n res: (await response.json()) as GraphQLResponse<T>,\n retriable: false,\n };\n } catch (error) {\n const aborted =\n error instanceof Error &&\n (error.name === \"AbortError\" || controller.signal.aborted);\n const message = aborted\n ? `Request timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : \"Network error\";\n console.error(\"[WebSDK] Network error\", message);\n return {\n res: {\n errors: [\n {\n message,\n extensions: { code: aborted ? \"TIMEOUT\" : \"NETWORK_ERROR\" },\n },\n ],\n },\n // Transport-level failures are worth one more try; a genuine outage\n // just fails twice quickly and still renders an error state.\n retriable: true,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async request<T>(\n query: string,\n variables?: Record<string, unknown>,\n retry = true,\n timeoutOverrideMs?: number,\n ): Promise<GraphQLResponse<T>> {\n const timeoutMs =\n timeoutOverrideMs ??\n this.config.timeoutMs ??\n WebSDKClient.DEFAULT_TIMEOUT_MS;\n const maxRetries = retry\n ? (this.config.maxRetries ?? WebSDKClient.DEFAULT_MAX_RETRIES)\n : 0;\n\n let last: GraphQLResponse<T> | undefined;\n for (let i = 0; i <= maxRetries; i++) {\n const { res, retriable } = await this.attempt<T>(\n query,\n variables,\n timeoutMs,\n );\n if (!retriable || i === maxRetries) return res;\n last = res;\n // Small backoff with jitter so a burst of clients doesn't retry in lockstep.\n await WebSDKClient.sleep(\n WebSDKClient.RETRY_BASE_DELAY_MS * (i + 1) + Math.random() * 200,\n );\n }\n return last as GraphQLResponse<T>;\n }\n}\n","/**\n * React context provider for the Web SDK client.\n * Wraps the application with WebSDKClient configuration.\n */\n\"use client\";\n\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { resolveGatewayUrl } from \"./gateway-resolver\";\nimport { WebSDKClient, type WebSDKClientConfig } from \"./graphql-client\";\n\nconst WebSDKContext = createContext<WebSDKClient | null>(null);\n\nexport interface WebSDKProviderProps {\n /** SDK client configuration */\n config: WebSDKClientConfig;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the WebSDKClient available to all child components.\n *\n * @example\n * ```tsx\n * <WebSDKProvider config={{\n * gatewayUrl: \"https://api.burdenoff.com/global/graphql\",\n * productId: \"your-product-id\",\n * productSlug: \"your-product\",\n * }}>\n * <App />\n * </WebSDKProvider>\n * ```\n */\nexport function WebSDKProvider({ config, children }: WebSDKProviderProps) {\n const client = useMemo(() => {\n const resolvedConfig = {\n ...config,\n gatewayUrl: resolveGatewayUrl(config.gatewayUrl),\n };\n return new WebSDKClient(resolvedConfig);\n }, [config]);\n\n return (\n <WebSDKContext.Provider value={client}>{children}</WebSDKContext.Provider>\n );\n}\n\n/**\n * Hook to access the WebSDKClient instance.\n * Must be used within a WebSDKProvider.\n */\nexport function useWebSDK(): WebSDKClient {\n const client = useContext(WebSDKContext);\n if (!client) {\n throw new Error(\"useWebSDK must be used within a WebSDKProvider\");\n }\n return client;\n}\n\n/**\n * Hook to access the SDK configuration.\n * Useful for components that need config values like productId, recaptchaSiteKey, etc.\n */\nexport function useWebSDKConfig(): WebSDKClientConfig {\n const client = useWebSDK();\n return client.getConfig();\n}\n","/**\n * Explore chat — TypeScript mirror of the public `/explore` GraphQL contract.\n *\n * Canonical source: `~/products/dev/platform/context/explore/CONTRACT.md` §1\n * (global-support-svc, served through the global PUBLIC gateway with\n * `@rbac(public: true, scopeType: \"global\")`).\n *\n * Nothing in this file may drift from that document. If a shape here looks\n * wrong, fix CONTRACT.md first and tell the backend workstreams — never patch\n * it locally.\n *\n * Nullability note: the contract marks `title`, `description`, `product`,\n * `imageUrl`, `partialContent`, `errorCode`, `completedAt`, `productSlug`,\n * `recaptchaSiteKey` and `remainingToday` as nullable, so every one of them is\n * `?: T | null` here — a GraphQL `null` and an omitted selection both have to\n * be representable.\n */\n\n// ============================================================================\n// Enums (string unions — the wire format is the enum name)\n// ============================================================================\n\nexport type ExploreMessageRole = \"USER\" | \"ASSISTANT\";\n\nexport type ExploreMessageStatus =\n \"PENDING\" | \"RUNNING\" | \"COMPLETED\" | \"FAILED\";\n\n/**\n * The `ExploreCta.kind` values enumerated in CONTRACT.md §1.\n *\n * `ExploreCtaLink.kind` is deliberately typed `string`, not this union: the\n * field is `String!` on the wire, and a kind added server-side must render\n * (falling back to the neutral CTA style) rather than break the build of 38\n * websites. Use this union when you are *producing* a kind.\n */\nexport type ExploreCtaKind =\n | \"CONTACT\"\n | \"PARTNERS\"\n | \"PRICING\"\n | \"SERVICES\"\n | \"WAITLIST\"\n | \"STORE\"\n | \"APP\"\n | \"DOCS\"\n | \"OTHER\";\n\n/**\n * Error codes surfaced through `extensions.code`. `HTTP_429` is what the\n * gateway emits when it rate-limits at the edge; the SDK client also produces\n * `TIMEOUT` / `NETWORK_ERROR` for transport failures.\n */\nexport type ExploreErrorCode =\n | \"EXPLORE_DISABLED\"\n | \"RATE_LIMITED\"\n | \"EXPLORE_GLOBAL_LIMIT\"\n | \"CAPTCHA_REQUIRED\"\n | \"CAPTCHA_FAILED\"\n | \"MESSAGE_TOO_LONG\"\n | \"MESSAGE_EMPTY\"\n | \"CONVERSATION_LIMIT\"\n | \"CONVERSATION_BUSY\"\n | \"UPSTREAM_UNAVAILABLE\"\n | \"NOT_FOUND\"\n | \"HTTP_429\"\n | \"TIMEOUT\"\n | \"NETWORK_ERROR\";\n\n// ============================================================================\n// Object types\n// ============================================================================\n\n/** `type ExploreReference` — a cited source page for an answer. */\nexport interface ExploreReference {\n url: string;\n title?: string | null;\n description?: string | null;\n product?: string | null;\n imageUrl?: string | null;\n /** 1-based citation number; the answer text carries a matching `[n]` marker. */\n index?: number | null;\n}\n\n/**\n * `type ExploreCta` — a suggested next step attached to an answer.\n *\n * Named `ExploreCtaLink` in the SDK because `ExploreCta` is taken by the\n * exported nav component (`<ExploreCta variant=\"header\" />`). Same shape,\n * different name; the GraphQL type is unchanged.\n */\nexport interface ExploreCtaLink {\n /** One of {@link ExploreCtaKind}; unknown values render with the neutral style. */\n kind: string;\n label: string;\n url: string;\n product?: string | null;\n}\n\n/** `type ExploreMessage`. `content` is `\"\"` while the turn is PENDING. */\nexport interface ExploreMessage {\n id: string;\n conversationId: string;\n role: ExploreMessageRole;\n status: ExploreMessageStatus;\n /** Final answer, markdown. Empty string until the turn completes. */\n content: string;\n /** Streaming preview while PENDING/RUNNING. */\n partialContent?: string | null;\n /** Human-readable progress lines, e.g. \"Searching vibecontrols…\". */\n activity: string[];\n references: ExploreReference[];\n ctas: ExploreCtaLink[];\n /** Up to three suggested next questions, derived from what the answer covered. */\n followUps?: string[] | null;\n /**\n * False when the corpus could not answer. A grounded answer always cites, so an answer\n * with no source is the honest \"we do not have this\" signal rather than a hedge.\n */\n answered?: boolean | null;\n errorCode?: string | null;\n createdAt: string;\n completedAt?: string | null;\n}\n\n/** `type ExploreConversation`. `token` is the client's only handle. */\nexport interface ExploreConversation {\n id: string;\n token: string;\n productSlug?: string | null;\n turnCount: number;\n createdAt: string;\n}\n\n/** `type ExploreProduct` — one product the harness can answer about. */\nexport interface ExploreProduct {\n slug: string;\n name: string;\n tagline?: string | null;\n website: string;\n}\n\n/** `type ExploreLimits` — server-owned caps the composer enforces locally. */\nexport interface ExploreLimits {\n maxMessageLength: number;\n maxTurnsPerConversation: number;\n messagesPerDay: number;\n historyTurns: number;\n}\n\n/**\n * `type ExploreCatalog` — everything the page needs before the first message.\n *\n * `captchaRequired` + `recaptchaSiteKey` are what turn reCAPTCHA v3 on: it is\n * a backend secret change, and no website redeploy is involved.\n */\nexport interface ExploreCatalog {\n enabled: boolean;\n products: ExploreProduct[];\n examplePrompts: string[];\n welcomeTitle: string;\n welcomeBody: string;\n limits: ExploreLimits;\n captchaRequired: boolean;\n recaptchaSiteKey?: string | null;\n}\n\n/** `input SendExploreMessageInput`. */\nexport interface SendExploreMessageInput {\n /** Omit to start a new conversation. */\n conversationToken?: string;\n /** The site the visitor is on — a soft hint, not a hard filter. */\n productSlug?: string;\n message: string;\n /** Only sent when `catalog.captchaRequired`. */\n recaptchaToken?: string;\n locale?: string;\n pageUrl?: string;\n}\n\n/**\n * `type SendExploreMessageResult`.\n *\n * **`assistantMessage.id` is the id to poll** — it comes back `PENDING`.\n */\nexport interface SendExploreMessageResult {\n conversation: ExploreConversation;\n userMessage: ExploreMessage;\n assistantMessage: ExploreMessage;\n remainingToday?: number | null;\n}\n\n// ============================================================================\n// GraphQL documents\n//\n// Only the fields the UI actually renders are requested — a narrower selection\n// set is cheaper to poll (this runs once every ~1.5s per active visitor) and\n// keeps the contract surface the websites depend on small.\n// ============================================================================\n\n/**\n * Shared selection set for every `ExploreMessage` in this file. Inlined as a\n * template string rather than a GraphQL `fragment` so each document stays a\n * single self-contained operation (the SDK client posts raw strings and has no\n * fragment registry).\n */\nconst EXPLORE_MESSAGE_FIELDS = /* GraphQL */ `\n id\n conversationId\n role\n status\n content\n partialContent\n activity\n references {\n url\n title\n description\n product\n imageUrl\n index\n }\n ctas {\n kind\n label\n url\n product\n }\n followUps\n answered\n errorCode\n createdAt\n completedAt\n`;\n\n/** Loaded once per page. Safe to serve from the SDK's 5-minute query cache. */\nexport const EXPLORE_CATALOG_QUERY = /* GraphQL */ `\n query ExploreCatalog($productSlug: String) {\n exploreCatalog(productSlug: $productSlug) {\n enabled\n products {\n slug\n name\n tagline\n website\n }\n examplePrompts\n welcomeTitle\n welcomeBody\n limits {\n maxMessageLength\n maxTurnsPerConversation\n messagesPerDay\n historyTurns\n }\n captchaRequired\n recaptchaSiteKey\n }\n }\n`;\n\n/**\n * The poll. MUST be issued with `client.query(..., { cache: false })` — the\n * default 5-minute cache would return the first PENDING snapshot forever and\n * the answer would never appear.\n */\nexport const EXPLORE_MESSAGE_QUERY = /* GraphQL */ `\n query ExploreMessage($conversationToken: String!, $id: ID!) {\n exploreMessage(conversationToken: $conversationToken, id: $id) {\n ${EXPLORE_MESSAGE_FIELDS}\n }\n }\n`;\n\n/** Submit half of the submit + poll pair. */\nexport const SEND_EXPLORE_MESSAGE_MUTATION = /* GraphQL */ `\n mutation SendExploreMessage($input: SendExploreMessageInput!) {\n sendExploreMessage(input: $input) {\n conversation {\n id\n token\n productSlug\n turnCount\n createdAt\n }\n userMessage {\n ${EXPLORE_MESSAGE_FIELDS}\n }\n assistantMessage {\n ${EXPLORE_MESSAGE_FIELDS}\n }\n remainingToday\n }\n }\n`;\n\n// ============================================================================\n// Response envelopes (what `client.query`/`client.mutate` resolve `data` to)\n// ============================================================================\n\nexport interface ExploreCatalogQueryData {\n exploreCatalog: ExploreCatalog;\n}\n\nexport interface ExploreMessageQueryData {\n exploreMessage: ExploreMessage | null;\n}\n\nexport interface SendExploreMessageMutationData {\n sendExploreMessage: SendExploreMessageResult;\n}\n\n/**\n * Record that the visitor followed a link the answer offered.\n *\n * Fire-and-forget: the browser is navigating away as this goes out, so the result is never\n * waited on and a failure is never surfaced. The server reports `recorded: false` rather\n * than erroring for anything it cannot attribute.\n */\nexport const RECORD_EXPLORE_CLICK_MUTATION = /* GraphQL */ `\n mutation RecordExploreClick($input: RecordExploreClickInput!) {\n recordExploreClick(input: $input) {\n recorded\n }\n }\n`;\n\n/**\n * Mint a read-only link to this conversation.\n *\n * The returned secret is NOT the conversation token — it opens a read-only view and cannot\n * be used to continue the thread, so it is safe to put in a URL that gets forwarded.\n */\nexport const CREATE_EXPLORE_SHARE_LINK_MUTATION = /* GraphQL */ `\n mutation CreateExploreShareLink($conversationToken: String!) {\n createExploreShareLink(conversationToken: $conversationToken) {\n shareToken\n }\n }\n`;\n","import type { WebsiteSwitcherProduct } from \"../components/website-switcher\";\n\n/**\n * Canonical Burdenoff ecosystem product list used by WebsiteSwitcher.\n *\n * Sourced from `~/products/websites/burdenoff-website/src/data/products.ts`.\n * Keep this in sync when products are added, renamed, or moved.\n */\nexport const ECOSYSTEM_PRODUCTS: WebsiteSwitcherProduct[] = [\n {\n slug: \"workspaces\",\n name: \"Workspaces\",\n websiteUrl: \"https://burdenoff.com\",\n },\n {\n slug: \"vibecontrols\",\n name: \"VibeControls\",\n websiteUrl: \"https://vibecontrols.com\",\n },\n {\n slug: \"fluidgrids\",\n name: \"FluidGrids\",\n websiteUrl: \"https://fluidgrids.com\",\n },\n // Botlit ships on botlit.ai — botlit.com does not resolve.\n { slug: \"botlit\", name: \"Botlit\", websiteUrl: \"https://www.botlit.ai\" },\n {\n slug: \"bigconsole\",\n name: \"BigConsole\",\n websiteUrl: \"https://bigconsole.com\",\n },\n {\n slug: \"semanticfed\",\n name: \"SemanticFed\",\n websiteUrl: \"https://semanticfed.com\",\n },\n {\n slug: \"intelwatchtower\",\n name: \"IntelWatchtower\",\n websiteUrl: \"https://intelwatchtower.com\",\n },\n { slug: \"buildmyiq\", name: \"BuildMyIQ\", websiteUrl: \"https://buildmyiq.com\" },\n {\n slug: \"assethandler\",\n name: \"AssetHandler\",\n websiteUrl: \"https://assethandler.com\",\n },\n {\n slug: \"crewfoundry\",\n name: \"CrewFoundry\",\n websiteUrl: \"https://crewfoundry.com\",\n },\n {\n slug: \"planmagnet\",\n name: \"PlanMagnet\",\n websiteUrl: \"https://planmagnet.com\",\n },\n {\n slug: \"eventfullymanaged\",\n name: \"EventfullyManaged\",\n websiteUrl: \"https://eventfullymanaged.com\",\n },\n {\n slug: \"headshotmarketing\",\n name: \"HeadshotMarketing\",\n websiteUrl: \"https://headshotmarketing.com\",\n },\n {\n slug: \"technospam\",\n name: \"TechnoSpam\",\n websiteUrl: \"https://technospam.com\",\n },\n { slug: \"kadaikodi\", name: \"Kadaikodi\", websiteUrl: \"https://kadaikodi.com\" },\n {\n slug: \"movethewheels\",\n name: \"MoveTheWheels\",\n websiteUrl: \"https://movethewheels.com\",\n },\n {\n slug: \"healthybowl\",\n name: \"Healthy Bowl\",\n websiteUrl: \"https://gethealthybowl.com\",\n },\n { slug: \"ggnomad\", name: \"GGNomad\", websiteUrl: \"https://ggnomad.com\" },\n {\n slug: \"timecampus\",\n name: \"TimeCampus\",\n websiteUrl: \"https://timecampus.com\",\n },\n {\n slug: \"manufacturedops\",\n name: \"ManufacturedOps\",\n websiteUrl: \"https://manufacturedops.com\",\n },\n {\n slug: \"theglobalfuel\",\n name: \"TheGlobalFuel\",\n websiteUrl: \"https://theglobalfuel.com\",\n },\n {\n slug: \"housingvista\",\n name: \"HousingVista\",\n websiteUrl: \"https://housingvista.com\",\n },\n {\n slug: \"proserviceworld\",\n name: \"ProServiceWorld\",\n websiteUrl: \"https://proserviceworld.com\",\n },\n {\n slug: \"mybodyshield\",\n name: \"MyBodyShield\",\n websiteUrl: \"https://mybodyshield.com\",\n },\n {\n slug: \"artistrybase\",\n name: \"ArtistryBase\",\n websiteUrl: \"https://artistrybase.com\",\n },\n {\n slug: \"theculturepost\",\n name: \"TheCulturePost\",\n websiteUrl: \"https://theculturepost.com\",\n },\n { slug: \"collabkin\", name: \"CollabKin\", websiteUrl: \"https://collabkin.com\" },\n {\n slug: \"comradecircle\",\n name: \"ComradeCircle\",\n websiteUrl: \"https://comradecircle.com\",\n },\n {\n slug: \"brainyrich\",\n name: \"BrainyRich\",\n websiteUrl: \"https://brainyrich.com\",\n },\n {\n slug: \"cosmicintersection\",\n name: \"CosmicIntersection\",\n websiteUrl: \"https://cosmicintersection.com\",\n },\n {\n slug: \"govcitizenhub\",\n name: \"GovCitizenHub\",\n websiteUrl: \"https://govcitizenhub.com\",\n },\n {\n slug: \"adaptercloud\",\n name: \"AdapterCloud\",\n websiteUrl: \"https://adaptercloud.com\",\n },\n {\n slug: \"subscriberbot\",\n name: \"Subscriber Bot\",\n websiteUrl: \"https://subscriberbot.com\",\n },\n {\n slug: \"hookmovies\",\n name: \"HookMovies\",\n websiteUrl: \"https://hookmovies.com\",\n },\n {\n slug: \"coolandlovely\",\n name: \"CoolAndLovely\",\n websiteUrl: \"https://coolandlovely.com\",\n },\n {\n slug: \"atheletebridge\",\n name: \"AthleteBridge\",\n websiteUrl: \"https://atheletebridge.com\",\n },\n {\n slug: \"labsofscience\",\n name: \"LabsOfScience\",\n websiteUrl: \"https://labsofscience.com\",\n },\n {\n slug: \"ecoimpacthub\",\n name: \"EcoImpactHub\",\n websiteUrl: \"https://ecoimpacthub.com\",\n },\n];\n","/**\n * reCAPTCHA v3 (invisible, score-based) loader and token minter.\n *\n * Deliberately dependency-free: the SDK already ships the `react-google-recaptcha`\n * peer for the **v2 checkbox** used by `ContactPage`, and the two widgets cannot\n * share a script tag — v3 needs `?render=<siteKey>` on the URL, v2 must not have\n * it. This module injects its own v3 script and leaves the v2 integration alone.\n *\n * The Explore chat turns v3 on purely from the backend catalog\n * (`exploreCatalog.captchaRequired && recaptchaSiteKey`), so nothing is loaded\n * and no third-party request is made on sites where captcha is off.\n */\n\n/** The slice of the `grecaptcha` global this module uses. */\nexport interface RecaptchaV3 {\n /** Runs the callback once the API is fully initialised. */\n ready(callback: () => void): void;\n /** Mints a single-use token for `action`. */\n execute(siteKey: string, options: { action: string }): Promise<string>;\n}\n\ndeclare global {\n interface Window {\n grecaptcha?: RecaptchaV3;\n }\n}\n\nconst SCRIPT_ID = \"boff-recaptcha-v3\";\nconst SCRIPT_SRC = \"https://www.google.com/recaptcha/api.js?render=\";\n\n/** Default action name reported to reCAPTCHA for Explore chat submissions. */\nexport const EXPLORE_RECAPTCHA_ACTION = \"explore_chat\";\n\n/**\n * One in-flight/settled promise per site key. Guarantees the script tag is\n * injected at most once even when several components mount at the same time,\n * and lets later callers await the same load instead of racing it.\n */\nconst loaders = new Map<string, Promise<RecaptchaV3>>();\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/**\n * Load the reCAPTCHA v3 script for `siteKey` and resolve once `grecaptcha` is\n * ready to mint tokens.\n *\n * - Injects the script at most once per site key (subsequent calls reuse the\n * same promise).\n * - Adopts an already-present script tag (e.g. injected by the host site)\n * rather than adding a second one.\n * - Rejects rather than hanging when the script fails to load, so the caller\n * can decide whether to submit without a token or surface an error.\n */\nexport function loadRecaptchaV3(siteKey: string): Promise<RecaptchaV3> {\n if (!siteKey) {\n return Promise.reject(new Error(\"reCAPTCHA site key is required\"));\n }\n if (!isBrowser()) {\n return Promise.reject(\n new Error(\"reCAPTCHA v3 can only be loaded in a browser\"),\n );\n }\n\n const existing = loaders.get(siteKey);\n if (existing) return existing;\n\n const promise = new Promise<RecaptchaV3>((resolve, reject) => {\n const ready = () => {\n const api = window.grecaptcha;\n if (!api) {\n reject(new Error(\"reCAPTCHA loaded but grecaptcha is unavailable\"));\n return;\n }\n // `ready` queues until the API has finished initialising internally;\n // calling `execute` before that throws.\n api.ready(() => resolve(api));\n };\n\n // Already loaded by this module, another SDK instance, or the host site.\n if (window.grecaptcha) {\n ready();\n return;\n }\n\n const scriptId = `${SCRIPT_ID}-${siteKey}`;\n const found = document.getElementById(scriptId);\n if (found) {\n found.addEventListener(\"load\", ready, { once: true });\n found.addEventListener(\n \"error\",\n () => reject(new Error(\"Failed to load reCAPTCHA v3\")),\n { once: true },\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.id = scriptId;\n script.src = `${SCRIPT_SRC}${encodeURIComponent(siteKey)}`;\n script.async = true;\n script.defer = true;\n script.addEventListener(\"load\", ready, { once: true });\n script.addEventListener(\n \"error\",\n () => {\n // Drop the memo so a later attempt can retry a transient CDN failure\n // instead of being stuck with a permanently rejected promise.\n loaders.delete(siteKey);\n reject(new Error(\"Failed to load reCAPTCHA v3\"));\n },\n { once: true },\n );\n document.head.appendChild(script);\n });\n\n loaders.set(siteKey, promise);\n return promise;\n}\n\n/**\n * Mint a single-use reCAPTCHA v3 token, loading the script on first use.\n *\n * Tokens are valid for ~2 minutes and are consumed by one verification, so\n * this must be called per submission — never cached.\n */\nexport async function getRecaptchaV3Token(\n siteKey: string,\n action: string = EXPLORE_RECAPTCHA_ACTION,\n): Promise<string> {\n const api = await loadRecaptchaV3(siteKey);\n return api.execute(siteKey, { action });\n}\n","/**\n * useExploreChat — the `/explore` conversation state machine.\n *\n * Implements the client half of CONTRACT.md §1: a **submit + poll** exchange.\n * `sendExploreMessage` returns immediately with a PENDING assistant message;\n * the answer arrives by polling `exploreMessage(conversationToken, id)` roughly\n * every 1.5s until it reports COMPLETED or FAILED. Both gateway hops cap a\n * subgraph call at 20s while a turn takes 5-60s, which is why there is no\n * request that simply waits for the answer.\n *\n * Design rules this hook exists to enforce:\n *\n * 1. **The catalog never gates the first paint.** `catalog` is populated with a\n * static fallback synchronously, so `ExplorePage` can render its `<h1>` on\n * the very first render. The websites' prerender waits for an `h1`; if that\n * heading depended on a network round-trip, 38 static builds would capture a\n * blank page.\n * 2. **Polls bypass the query cache.** `client.query(..., { cache: false })` —\n * the default 5-minute cache would hand every later poll the first PENDING\n * snapshot and the answer would never appear.\n * 3. **Nothing outlives the component.** Unmount and `stop()` both cancel the\n * poll chain through a generation counter, so a late response can never\n * write into an unmounted tree.\n */\n\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { useWebSDK } from \"../client/provider\";\nimport {\n EXPLORE_CATALOG_QUERY,\n EXPLORE_MESSAGE_QUERY,\n CREATE_EXPLORE_SHARE_LINK_MUTATION,\n RECORD_EXPLORE_CLICK_MUTATION,\n SEND_EXPLORE_MESSAGE_MUTATION,\n} from \"../components/explore-types\";\nimport { ECOSYSTEM_PRODUCTS } from \"../data/products\";\nimport { getRecaptchaV3Token } from \"../utils/recaptcha-v3\";\n\nimport type {\n ExploreCatalog,\n ExploreCatalogQueryData,\n ExploreLimits,\n ExploreMessage,\n ExploreMessageQueryData,\n SendExploreMessageInput,\n SendExploreMessageMutationData,\n} from \"../components/explore-types\";\n\n// ============================================================================\n// Public types\n// ============================================================================\n\n/**\n * Where the conversation is right now.\n *\n * - `loading` — catalog request in flight (the fallback catalog is already\n * rendered, so this is a refinement, not a blank screen).\n * - `ready` — idle; the composer accepts input.\n * - `sending` — `sendExploreMessage` in flight.\n * - `streaming` — polling the assistant turn; `activity` is live.\n * - `error` — the last turn failed; `retry()` is meaningful and the\n * composer stays usable.\n * - `limited` — rate limited; the composer is disabled.\n * - `disabled` — `exploreCatalog.enabled === false`.\n */\nexport type ExploreChatPhase =\n | \"loading\"\n | \"ready\"\n | \"sending\"\n | \"streaming\"\n | \"error\"\n | \"limited\"\n | \"disabled\";\n\n/** Coarse bucket the UI switches its banner copy and affordances on. */\nexport type ExploreChatErrorKind =\n | \"rate-limit\"\n | \"captcha\"\n | \"timeout\"\n | \"network\"\n | \"disabled\"\n | \"validation\"\n | \"unknown\";\n\nexport interface ExploreChatError {\n /** UI bucket. */\n kind: ExploreChatErrorKind;\n /** Raw `extensions.code` (or a client-side code such as `TIMEOUT`). */\n code: string;\n /** Human-readable, safe to render. */\n message: string;\n /** Whether re-sending the same message could plausibly succeed. */\n retryable: boolean;\n}\n\nexport interface UseExploreChatOptions {\n /** Slug of the product site this page is on — a soft hint to the harness. */\n productSlug?: string;\n /** Full URL of the page, forwarded as `pageUrl`. */\n pageUrl?: string;\n /** BCP-47 locale, forwarded as `locale`. */\n locale?: string;\n /** Poll cadence in ms. Default 1500 (CONTRACT.md §1). */\n pollIntervalMs?: number;\n /** Give up on a turn after this long. Default 90000 (the edge poll timeout). */\n pollTimeoutMs?: number;\n /**\n * Prompts to offer when `exploreCatalog` supplies none. Resolution order is\n * catalog → this option → {@link DEFAULT_EXPLORE_EXAMPLE_PROMPTS}, so a site\n * can ship product-specific prompts without waiting on the backend and still\n * be overridden centrally once the catalog carries them.\n */\n examplePrompts?: string[];\n /** localStorage key for the ACTIVE conversation. Default `boff.explore.v1`. */\n storageKey?: string;\n /** Persist the conversation across reloads within the tab. Default true. */\n persist?: boolean;\n /** Called with the message text each time a send is accepted locally. */\n onSend?: (message: string) => void;\n}\n\nexport interface UseExploreChatResult {\n phase: ExploreChatPhase;\n /** Never null — starts as the static fallback, upgraded by the server. */\n catalog: ExploreCatalog;\n messages: ExploreMessage[];\n /** Latest progress line of the in-flight turn, or null when idle. */\n activity: string | null;\n /** Messages left today for this visitor, when the server reports it. */\n remainingToday: number | null;\n error: ExploreChatError | null;\n /** Product the visitor pinned the conversation to, or null for \"all\". */\n focusProduct: string | null;\n setFocusProduct: (slug: string | null) => void;\n send: (message: string) => Promise<void>;\n /** Stop polling and keep whatever text has streamed so far. */\n stop: () => void;\n /** Re-send the last message after a failed turn. */\n retry: () => void;\n /** Clear the conversation and the persisted session. */\n reset: () => void;\n /** Past conversations held in THIS browser, newest first. */\n history: ArchivedExploreConversation[];\n /** Reopen a past conversation and continue it. */\n openConversation: (token: string) => void;\n /** Forget one past conversation (local only). */\n deleteConversation: (token: string) => void;\n /** Forget every past conversation held in this browser. */\n clearHistory: () => void;\n /**\n * Record that the visitor followed a link this answer offered. Fire-and-forget — never\n * awaited, never throws, and must never delay the navigation it is reporting on.\n */\n recordClick: (\n messageId: string,\n kind: \"CTA\" | \"REFERENCE\",\n url: string,\n ) => void;\n /**\n * Mint a read-only link to this conversation, or null when there is nothing to share yet.\n * The secret returned is not the conversation token and cannot continue the thread.\n */\n createShareLink: () => Promise<string | null>;\n canSend: boolean;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_STORAGE_KEY = \"boff.explore.v1\";\n/** Where past conversations live. Derived from the active key so a custom key stays paired. */\nconst HISTORY_SUFFIX = \".history\";\n/**\n * How many past conversations to keep, and how many messages of each. Bounded on purpose:\n * localStorage is a few MB per origin and shared with everything else the site stores, so an\n * unbounded archive would eventually start throwing QuotaExceededError on write.\n */\nconst MAX_ARCHIVED_CONVERSATIONS = 15;\nconst MAX_ARCHIVED_MESSAGES = 20;\nconst DEFAULT_POLL_INTERVAL_MS = 1_500;\n/** Matches `EXPLORE_AGENT_TIMEOUT_MS` (CONTRACT.md §3) — the edge gives up too. */\nconst DEFAULT_POLL_TIMEOUT_MS = 90_000;\n/** Per-poll HTTP timeout. Short: a stuck poll must not stall the chain. */\nconst POLL_REQUEST_TIMEOUT_MS = 10_000;\n/** The submit hop enqueues a job; generous but well under the gateway's 20s. */\nconst SEND_REQUEST_TIMEOUT_MS = 18_000;\n/** Transient poll failures tolerated before the turn is declared dead. */\nconst MAX_CONSECUTIVE_POLL_FAILURES = 4;\n/** Cap on what goes into localStorage — a conversation must not grow unbounded. */\nconst MAX_PERSISTED_MESSAGES = 40;\n\n/** Fallback limits, mirroring the server defaults in CONTRACT.md §3. */\nexport const FALLBACK_EXPLORE_LIMITS: ExploreLimits = {\n maxMessageLength: 2000,\n maxTurnsPerConversation: 20,\n messagesPerDay: 100,\n historyTurns: 6,\n};\n\n/**\n * Prompts shown when neither the catalog nor the consumer supplies any.\n * Deliberately product-agnostic — this SDK renders on 38 different sites.\n */\nexport const DEFAULT_EXPLORE_EXAMPLE_PROMPTS: string[] = [\n \"What does this product actually do?\",\n \"Which Burdenoff product fits my team?\",\n \"How do I get started, step by step?\",\n \"What does it integrate with?\",\n];\n\nconst FALLBACK_WELCOME_TITLE = \"Ask anything about our products\";\nconst FALLBACK_WELCOME_BODY =\n \"Get straight answers drawn from our product documentation and public pages — with links back to the exact page each answer came from.\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction buildFallbackCatalog(examplePrompts?: string[]): ExploreCatalog {\n return {\n enabled: true,\n products: ECOSYSTEM_PRODUCTS.map((p) => ({\n slug: p.slug,\n name: p.name,\n tagline: null,\n website: p.websiteUrl,\n })),\n examplePrompts: examplePrompts?.length\n ? examplePrompts\n : DEFAULT_EXPLORE_EXAMPLE_PROMPTS,\n welcomeTitle: FALLBACK_WELCOME_TITLE,\n welcomeBody: FALLBACK_WELCOME_BODY,\n limits: FALLBACK_EXPLORE_LIMITS,\n captchaRequired: false,\n recaptchaSiteKey: null,\n };\n}\n\n/**\n * Harden a server catalog against partial/degraded responses so a missing\n * field can never blank the page or produce `maxMessageLength: 0` (which would\n * silently disable the composer).\n */\nfunction normalizeCatalog(\n raw: ExploreCatalog,\n fallback: ExploreCatalog,\n): ExploreCatalog {\n return {\n enabled: raw.enabled !== false,\n products: raw.products?.length ? raw.products : fallback.products,\n examplePrompts: raw.examplePrompts?.length\n ? raw.examplePrompts\n : fallback.examplePrompts,\n welcomeTitle: raw.welcomeTitle || fallback.welcomeTitle,\n welcomeBody: raw.welcomeBody || fallback.welcomeBody,\n limits: {\n maxMessageLength:\n raw.limits?.maxMessageLength || fallback.limits.maxMessageLength,\n maxTurnsPerConversation:\n raw.limits?.maxTurnsPerConversation ||\n fallback.limits.maxTurnsPerConversation,\n messagesPerDay:\n raw.limits?.messagesPerDay || fallback.limits.messagesPerDay,\n historyTurns: raw.limits?.historyTurns || fallback.limits.historyTurns,\n },\n captchaRequired: raw.captchaRequired === true,\n recaptchaSiteKey: raw.recaptchaSiteKey ?? null,\n };\n}\n\nconst RATE_LIMIT_CODES = new Set([\n \"RATE_LIMITED\",\n \"HTTP_429\",\n \"EXPLORE_GLOBAL_LIMIT\",\n]);\nconst CAPTCHA_CODES = new Set([\"CAPTCHA_FAILED\", \"CAPTCHA_REQUIRED\"]);\nconst NETWORK_CODES = new Set([\n \"NETWORK_ERROR\",\n \"UPSTREAM_UNAVAILABLE\",\n \"CONVERSATION_BUSY\",\n \"PROVIDER_ERROR\",\n \"QUEUE_FULL\",\n]);\nconst VALIDATION_CODES = new Set([\n \"MESSAGE_TOO_LONG\",\n \"MESSAGE_EMPTY\",\n \"CONVERSATION_LIMIT\",\n \"INVALID_INPUT\",\n]);\n\n/**\n * Map a `extensions.code` (or a client-side transport code) onto the bucket the\n * UI renders. Unknown codes are treated as retryable — a transient backend\n * condition we have not enumerated is far more likely than a permanent one.\n */\nexport function classifyExploreError(\n code: string | null | undefined,\n serverMessage?: string | null,\n): ExploreChatError {\n const c = code ?? \"UNKNOWN\";\n if (RATE_LIMIT_CODES.has(c)) {\n return {\n kind: \"rate-limit\",\n code: c,\n message:\n \"You've reached the message limit for now. Please try again later.\",\n retryable: false,\n };\n }\n if (CAPTCHA_CODES.has(c)) {\n return {\n kind: \"captcha\",\n code: c,\n message:\n \"We couldn't verify that you're human. Please try sending that again.\",\n retryable: true,\n };\n }\n if (c === \"TIMEOUT\" || c === \"TOOL_BUDGET\") {\n return {\n kind: \"timeout\",\n code: c,\n message: \"That answer took too long to come back. Try asking again.\",\n retryable: true,\n };\n }\n if (NETWORK_CODES.has(c)) {\n return {\n kind: \"network\",\n code: c,\n message:\n \"We couldn't reach the assistant just now. Check your connection and try again.\",\n retryable: true,\n };\n }\n if (c === \"EXPLORE_DISABLED\") {\n return {\n kind: \"disabled\",\n code: c,\n message: \"Explore is unavailable at the moment. Please check back soon.\",\n retryable: false,\n };\n }\n if (VALIDATION_CODES.has(c)) {\n return {\n kind: \"validation\",\n code: c,\n message: serverMessage || \"That message couldn't be sent.\",\n retryable: false,\n };\n }\n if (c === \"EMPTY_ANSWER\") {\n return {\n kind: \"unknown\",\n code: c,\n message:\n \"No answer came back for that one. Try rephrasing, or ask something more specific.\",\n retryable: true,\n };\n }\n return {\n kind: \"unknown\",\n code: c,\n message: serverMessage || \"Something went wrong. Please try again.\",\n retryable: true,\n };\n}\n\ninterface PersistedExploreState {\n conversationToken: string | null;\n messages: ExploreMessage[];\n focusProduct: string | null;\n}\n\n/** One past conversation, as shown in the history list and restored on click. */\nexport interface ArchivedExploreConversation {\n token: string;\n /** First thing the visitor asked — the human-readable label for the thread. */\n title: string;\n /** ISO timestamp of the last message in the thread. */\n updatedAt: string;\n messageCount: number;\n focusProduct: string | null;\n messages: ExploreMessage[];\n}\n\nfunction historyKey(key: string): string {\n return `${key}${HISTORY_SUFFIX}`;\n}\n\nfunction readArchive(key: string): ArchivedExploreConversation[] {\n if (typeof window === \"undefined\") return [];\n try {\n const raw = window.localStorage.getItem(historyKey(key));\n if (!raw) return [];\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (entry): entry is ArchivedExploreConversation =>\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as ArchivedExploreConversation).token === \"string\" &&\n Array.isArray((entry as ArchivedExploreConversation).messages),\n );\n } catch {\n return [];\n }\n}\n\nfunction writeArchive(\n key: string,\n entries: ArchivedExploreConversation[],\n): void {\n if (typeof window === \"undefined\") return;\n try {\n if (entries.length === 0) {\n window.localStorage.removeItem(historyKey(key));\n return;\n }\n window.localStorage.setItem(historyKey(key), JSON.stringify(entries));\n } catch {\n /* private mode or quota — the archive is a convenience, never load-bearing */\n }\n}\n\n/**\n * Fold the given thread into the archive, newest first.\n *\n * Upsert by token rather than append: the same conversation is archived after every completed\n * turn so an abruptly closed tab still leaves a record, and appending would fill the list with\n * duplicates of one thread.\n */\nfunction upsertArchive(\n key: string,\n thread: {\n token: string | null;\n messages: ExploreMessage[];\n focusProduct: string | null;\n },\n): ArchivedExploreConversation[] {\n if (!thread.token) return readArchive(key);\n const real = thread.messages.filter(\n (m) => m.content.trim() !== \"\" || m.role === \"USER\",\n );\n if (real.length === 0) return readArchive(key);\n\n const firstUser = real.find((m) => m.role === \"USER\");\n const entry: ArchivedExploreConversation = {\n token: thread.token,\n title: (firstUser?.content ?? \"Conversation\").trim().slice(0, 80),\n updatedAt: real[real.length - 1]?.createdAt ?? new Date().toISOString(),\n messageCount: real.length,\n focusProduct: thread.focusProduct,\n messages: real.slice(-MAX_ARCHIVED_MESSAGES),\n };\n\n const rest = readArchive(key).filter((e) => e.token !== entry.token);\n const next = [entry, ...rest].slice(0, MAX_ARCHIVED_CONVERSATIONS);\n writeArchive(key, next);\n return next;\n}\n\nfunction readPersisted(key: string): PersistedExploreState | null {\n // SSR / prerender: there is no localStorage, and reading one during the\n // first client render would desync hydration anyway.\n if (typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(key);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\") return null;\n const record = parsed as Partial<PersistedExploreState>;\n return {\n conversationToken:\n typeof record.conversationToken === \"string\"\n ? record.conversationToken\n : null,\n messages: Array.isArray(record.messages)\n ? record.messages.slice(-MAX_PERSISTED_MESSAGES)\n : [],\n focusProduct:\n typeof record.focusProduct === \"string\" ? record.focusProduct : null,\n };\n } catch {\n /* corrupt or unavailable storage — start a fresh conversation */\n return null;\n }\n}\n\n/**\n * A turn that never produced any text is worth dropping rather than rendering\n * as an empty bubble — used by `stop()` and by the failure paths.\n */\nfunction visibleText(message: ExploreMessage): string {\n return message.content || message.partialContent || \"\";\n}\n\nfunction countUserTurns(messages: ExploreMessage[]): number {\n return messages.filter((m) => m.role === \"USER\").length;\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useExploreChat(\n options: UseExploreChatOptions = {},\n): UseExploreChatResult {\n const {\n productSlug,\n pageUrl,\n locale,\n examplePrompts,\n pollIntervalMs = DEFAULT_POLL_INTERVAL_MS,\n pollTimeoutMs = DEFAULT_POLL_TIMEOUT_MS,\n storageKey = DEFAULT_STORAGE_KEY,\n persist = true,\n onSend,\n } = options;\n\n const client = useWebSDK();\n\n // The fallback catalog is the initial value AND the merge base for the\n // server response. Keyed on the prompt CONTENT, not the array identity —\n // a consumer passing an inline `examplePrompts={[...]}` literal would\n // otherwise rebuild it every render and re-fire the catalog effect.\n const promptKey = JSON.stringify(examplePrompts ?? []);\n const fallbackCatalog = useMemo(\n () => buildFallbackCatalog(JSON.parse(promptKey) as string[]),\n [promptKey],\n );\n\n const [catalog, setCatalog] = useState<ExploreCatalog>(fallbackCatalog);\n const [messages, setMessages] = useState<ExploreMessage[]>([]);\n const [phase, setPhase] = useState<ExploreChatPhase>(\"loading\");\n const [error, setError] = useState<ExploreChatError | null>(null);\n const [remainingToday, setRemainingToday] = useState<number | null>(null);\n const [focusProduct, setFocusProductState] = useState<string | null>(null);\n const [turnCount, setTurnCount] = useState(0);\n // Mirror of `messages` for callbacks that must not re-create on every message.\n const messagesRef = useRef<ExploreMessage[]>([]);\n const [archive, setArchive] = useState<ArchivedExploreConversation[]>([]);\n\n const [hydrated, setHydrated] = useState(false);\n\n // Refs mirror the state that async callbacks read, so `send`/`poll` never\n // close over a stale value and never need to be re-created mid-flight.\n const mountedRef = useRef(true);\n const pollGenerationRef = useRef(0);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const conversationTokenRef = useRef<string | null>(null);\n const catalogRef = useRef<ExploreCatalog>(fallbackCatalog);\n const turnCountRef = useRef(0);\n const focusProductRef = useRef<string | null>(null);\n const lastSentTextRef = useRef<string | null>(null);\n const inFlightRef = useRef(false);\n\n catalogRef.current = catalog;\n\n const clearPollTimer = useCallback(() => {\n if (pollTimerRef.current !== null) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n }, []);\n\n /** Invalidate any running poll chain. Late responses become no-ops. */\n const cancelPolling = useCallback(() => {\n pollGenerationRef.current += 1;\n clearPollTimer();\n }, [clearPollTimer]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n pollGenerationRef.current += 1;\n if (pollTimerRef.current !== null) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n };\n }, []);\n\n // --------------------------------------------------------------------------\n // Hydrate from localStorage (effect, not lazy state, so the FIRST client\n // render matches the prerendered HTML and hydration stays clean).\n // --------------------------------------------------------------------------\n useEffect(() => {\n if (!persist) {\n setHydrated(true);\n return;\n }\n setArchive(readArchive(storageKey));\n const stored = readPersisted(storageKey);\n if (stored) {\n conversationTokenRef.current = stored.conversationToken;\n focusProductRef.current = stored.focusProduct;\n // A turn that was still streaming when the tab was closed can never be\n // resumed from here — the poll chain is gone. Land it as-is.\n const settled = stored.messages.flatMap<ExploreMessage>((m) => {\n if (m.role !== \"ASSISTANT\") return [m];\n if (m.status !== \"PENDING\" && m.status !== \"RUNNING\") return [m];\n const text = visibleText(m);\n if (!text) return [];\n return [{ ...m, status: \"COMPLETED\", content: text }];\n });\n setMessages(settled);\n setFocusProductState(stored.focusProduct);\n const turns = countUserTurns(settled);\n turnCountRef.current = turns;\n setTurnCount(turns);\n }\n setHydrated(true);\n }, [persist, storageKey]);\n\n // --------------------------------------------------------------------------\n // Persist (after hydration, so the initial empty state never wipes storage).\n // --------------------------------------------------------------------------\n useEffect(() => {\n if (!persist || !hydrated || typeof window === \"undefined\") return;\n try {\n const payload: PersistedExploreState = {\n conversationToken: conversationTokenRef.current,\n messages: messages.slice(-MAX_PERSISTED_MESSAGES),\n focusProduct,\n };\n // Nothing worth restoring (fresh page, or just after reset()): drop the\n // key entirely rather than leaving an empty husk behind.\n if (\n !payload.conversationToken &&\n payload.messages.length === 0 &&\n !payload.focusProduct\n ) {\n window.localStorage.removeItem(storageKey);\n return;\n }\n window.localStorage.setItem(storageKey, JSON.stringify(payload));\n } catch {\n /* private mode / quota exceeded — persistence is a nicety, not a feature */\n }\n }, [persist, hydrated, storageKey, messages, focusProduct]);\n\n // Mirror messages into a ref for callbacks, and fold a settled thread into the archive.\n // Archiving on every settled turn (not only on reset) is what makes an abruptly closed tab\n // still leave a record the visitor can come back to.\n useEffect(() => {\n messagesRef.current = messages;\n if (!persist || !hydrated) return;\n const settled = messages.some(\n (m) =>\n m.role === \"ASSISTANT\" &&\n (m.status === \"COMPLETED\" || m.status === \"FAILED\"),\n );\n if (!settled) return;\n setArchive(\n upsertArchive(storageKey, {\n token: conversationTokenRef.current,\n messages,\n focusProduct: focusProductRef.current,\n }),\n );\n }, [messages, persist, hydrated, storageKey]);\n\n // --------------------------------------------------------------------------\n // Catalog. Cached (the default) — it is per-page-load configuration, not a\n // poll. A failure keeps the fallback so the page NEVER renders blank.\n // --------------------------------------------------------------------------\n useEffect(() => {\n let cancelled = false;\n const load = async () => {\n const res = await client.query<ExploreCatalogQueryData>(\n EXPLORE_CATALOG_QUERY,\n { productSlug: productSlug ?? null },\n );\n if (cancelled || !mountedRef.current) return;\n\n const raw = res.data?.exploreCatalog;\n if (res.errors?.length || !raw) {\n console.warn(\n \"[WebSDK] exploreCatalog unavailable — using the built-in fallback catalog\",\n res.errors?.[0]?.message,\n );\n setPhase((prev) => (prev === \"loading\" ? \"ready\" : prev));\n return;\n }\n\n const next = normalizeCatalog(raw, fallbackCatalog);\n setCatalog(next);\n catalogRef.current = next;\n setPhase((prev) => {\n if (!next.enabled) return \"disabled\";\n return prev === \"loading\" ? \"ready\" : prev;\n });\n };\n void load();\n return () => {\n cancelled = true;\n };\n }, [client, productSlug, fallbackCatalog]);\n\n // --------------------------------------------------------------------------\n // Poll chain\n // --------------------------------------------------------------------------\n const startPolling = useCallback(\n (conversationToken: string, messageId: string) => {\n pollGenerationRef.current += 1;\n const generation = pollGenerationRef.current;\n const startedAt = Date.now();\n let consecutiveFailures = 0;\n\n const isStale = () =>\n !mountedRef.current || generation !== pollGenerationRef.current;\n\n const finishWithError = (chatError: ExploreChatError) => {\n inFlightRef.current = false;\n setMessages((prev) =>\n prev.flatMap<ExploreMessage>((m) => {\n if (m.id !== messageId) return [m];\n const text = visibleText(m);\n if (!text) return [];\n return [{ ...m, status: \"FAILED\", content: text }];\n }),\n );\n setError(chatError);\n setPhase(chatError.kind === \"rate-limit\" ? \"limited\" : \"error\");\n };\n\n const tick = async () => {\n if (isStale()) return;\n\n if (Date.now() - startedAt > pollTimeoutMs) {\n finishWithError(classifyExploreError(\"TIMEOUT\"));\n return;\n }\n\n // `cache: false` is load-bearing — see CONTRACT.md §4.\n const res = await client.query<ExploreMessageQueryData>(\n EXPLORE_MESSAGE_QUERY,\n { conversationToken, id: messageId },\n { cache: false, timeoutMs: POLL_REQUEST_TIMEOUT_MS },\n );\n if (isStale()) return;\n\n const first = res.errors?.[0];\n if (first) {\n const code =\n typeof first.extensions?.code === \"string\"\n ? first.extensions.code\n : undefined;\n const classified = classifyExploreError(code, first.message);\n // Hard stops: retrying a rate limit or a disabled feature is pointless.\n if (!classified.retryable) {\n finishWithError(classified);\n return;\n }\n consecutiveFailures += 1;\n if (consecutiveFailures >= MAX_CONSECUTIVE_POLL_FAILURES) {\n finishWithError(classified);\n return;\n }\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n return;\n }\n\n const message = res.data?.exploreMessage;\n if (!message) {\n // Can happen briefly right after submit; tolerate a few misses.\n consecutiveFailures += 1;\n if (consecutiveFailures >= MAX_CONSECUTIVE_POLL_FAILURES) {\n finishWithError(classifyExploreError(\"NOT_FOUND\"));\n return;\n }\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n return;\n }\n\n consecutiveFailures = 0;\n // Replace in place so `partialContent` renders as it streams.\n setMessages((prev) =>\n prev.map((m) => (m.id === messageId ? message : m)),\n );\n\n if (message.status === \"COMPLETED\") {\n inFlightRef.current = false;\n setError(null);\n setPhase(\"ready\");\n return;\n }\n if (message.status === \"FAILED\") {\n finishWithError(\n classifyExploreError(message.errorCode ?? \"UPSTREAM_UNAVAILABLE\"),\n );\n return;\n }\n\n setPhase(\"streaming\");\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n };\n\n // First poll after one interval — the turn cannot possibly be done sooner.\n pollTimerRef.current = setTimeout(() => void tick(), pollIntervalMs);\n },\n [client, pollIntervalMs, pollTimeoutMs],\n );\n\n // --------------------------------------------------------------------------\n // send\n // --------------------------------------------------------------------------\n const submit = useCallback(\n async (\n text: string,\n optimisticId: string,\n captchaAttempt: number,\n ): Promise<void> => {\n const activeCatalog = catalogRef.current;\n\n let recaptchaToken: string | undefined;\n if (activeCatalog.captchaRequired && activeCatalog.recaptchaSiteKey) {\n try {\n recaptchaToken = await getRecaptchaV3Token(\n activeCatalog.recaptchaSiteKey,\n );\n } catch (err) {\n console.warn(\"[WebSDK] reCAPTCHA v3 token could not be minted\", err);\n // Send without a token and let the backend decide — it owns the\n // policy, and a blocked third-party script must not silently kill\n // the whole feature.\n }\n }\n\n const input: SendExploreMessageInput = {\n message: text,\n ...(conversationTokenRef.current\n ? { conversationToken: conversationTokenRef.current }\n : {}),\n ...(focusProductRef.current || productSlug\n ? { productSlug: focusProductRef.current ?? productSlug }\n : {}),\n ...(recaptchaToken ? { recaptchaToken } : {}),\n ...(locale ? { locale } : {}),\n ...(pageUrl ? { pageUrl } : {}),\n };\n\n const res = await client.mutate<SendExploreMessageMutationData>(\n SEND_EXPLORE_MESSAGE_MUTATION,\n { input },\n { timeoutMs: SEND_REQUEST_TIMEOUT_MS },\n );\n if (!mountedRef.current) return;\n\n const first = res.errors?.[0];\n const result = res.data?.sendExploreMessage;\n\n if (first || !result) {\n const code =\n typeof first?.extensions?.code === \"string\"\n ? first.extensions.code\n : undefined;\n const classified = classifyExploreError(code, first?.message);\n\n // CAPTCHA_FAILED: one silent re-mint + re-send before bothering the\n // visitor. v3 tokens expire in ~2 minutes and are single-use, so a\n // stale one is a routine, self-healing failure.\n if (classified.kind === \"captcha\" && captchaAttempt === 0) {\n await submit(text, optimisticId, 1);\n return;\n }\n\n inFlightRef.current = false;\n setError(classified);\n setPhase(classified.kind === \"rate-limit\" ? \"limited\" : \"error\");\n return;\n }\n\n conversationTokenRef.current = result.conversation.token;\n turnCountRef.current = result.conversation.turnCount;\n setTurnCount(result.conversation.turnCount);\n setRemainingToday(result.remainingToday ?? null);\n\n const userMessage = result.userMessage;\n const assistantMessage = result.assistantMessage;\n\n // Swap the optimistic user bubble for the server's, then append the\n // PENDING assistant turn that the poll chain will fill in. The `some`\n // guard keeps the visitor's words on screen even in the impossible case\n // where the optimistic bubble is already gone.\n setMessages((prev) => {\n const replaced = prev.some((m) => m.id === optimisticId)\n ? prev.map((m) => (m.id === optimisticId ? userMessage : m))\n : [...prev, userMessage];\n return [...replaced, assistantMessage];\n });\n\n if (\n assistantMessage.status === \"COMPLETED\" ||\n assistantMessage.status === \"FAILED\"\n ) {\n inFlightRef.current = false;\n if (assistantMessage.status === \"FAILED\") {\n const classified = classifyExploreError(\n assistantMessage.errorCode ?? \"UPSTREAM_UNAVAILABLE\",\n );\n setError(classified);\n setPhase(\"error\");\n } else {\n setPhase(\"ready\");\n }\n return;\n }\n\n setPhase(\"streaming\");\n startPolling(result.conversation.token, assistantMessage.id);\n },\n [client, locale, pageUrl, productSlug, startPolling],\n );\n\n const send = useCallback(\n async (message: string): Promise<void> => {\n const text = message.trim();\n if (!text) return;\n if (inFlightRef.current) return;\n\n const activeCatalog = catalogRef.current;\n if (!activeCatalog.enabled) {\n setError(classifyExploreError(\"EXPLORE_DISABLED\"));\n setPhase(\"disabled\");\n return;\n }\n if (text.length > activeCatalog.limits.maxMessageLength) {\n setError({\n kind: \"validation\",\n code: \"MESSAGE_TOO_LONG\",\n message: `That message is ${text.length} characters — the limit is ${activeCatalog.limits.maxMessageLength}.`,\n retryable: false,\n });\n return;\n }\n if (\n turnCountRef.current >= activeCatalog.limits.maxTurnsPerConversation\n ) {\n setError({\n kind: \"validation\",\n code: \"CONVERSATION_LIMIT\",\n message: `This conversation has reached its ${activeCatalog.limits.maxTurnsPerConversation}-message limit. Start a new chat to keep going.`,\n retryable: false,\n });\n return;\n }\n\n inFlightRef.current = true;\n lastSentTextRef.current = text;\n setError(null);\n setPhase(\"sending\");\n cancelPolling();\n\n // Optimistic user bubble — the composer clears instantly instead of\n // waiting a network round-trip for the visitor's own words.\n const optimistic: ExploreMessage = {\n id: makeOptimisticId(),\n conversationId: conversationTokenRef.current ?? \"pending\",\n role: \"USER\",\n status: \"COMPLETED\",\n content: text,\n partialContent: null,\n activity: [],\n references: [],\n ctas: [],\n errorCode: null,\n createdAt: new Date().toISOString(),\n completedAt: new Date().toISOString(),\n };\n setMessages((prev) => [...prev, optimistic]);\n turnCountRef.current += 1;\n setTurnCount(turnCountRef.current);\n onSend?.(text);\n\n try {\n await submit(text, optimistic.id, 0);\n } catch (err) {\n if (!mountedRef.current) return;\n console.error(\"[WebSDK] Explore send failed\", err);\n inFlightRef.current = false;\n setError(classifyExploreError(\"NETWORK_ERROR\"));\n setPhase(\"error\");\n }\n },\n [cancelPolling, onSend, submit],\n );\n\n const stop = useCallback(() => {\n cancelPolling();\n inFlightRef.current = false;\n setMessages((prev) =>\n prev.flatMap<ExploreMessage>((m) => {\n if (m.role !== \"ASSISTANT\") return [m];\n if (m.status !== \"PENDING\" && m.status !== \"RUNNING\") return [m];\n const text = visibleText(m);\n // Nothing streamed yet — drop the placeholder instead of leaving an\n // empty bubble behind.\n if (!text) return [];\n return [\n {\n ...m,\n status: \"COMPLETED\",\n content: text,\n completedAt: new Date().toISOString(),\n },\n ];\n }),\n );\n setPhase((prev) =>\n prev === \"sending\" || prev === \"streaming\" ? \"ready\" : prev,\n );\n }, [cancelPolling]);\n\n const retry = useCallback(() => {\n const text = lastSentTextRef.current;\n if (!text) return;\n cancelPolling();\n inFlightRef.current = false;\n // Drop the failed turn (and the user bubble that produced it) so the retry\n // does not stack a duplicate pair into the transcript.\n setMessages((prev) => {\n const next = [...prev];\n const last = next[next.length - 1];\n if (last?.role === \"ASSISTANT\" && last.status === \"FAILED\") next.pop();\n const prior = next[next.length - 1];\n if (prior?.role === \"USER\" && prior.content === text) next.pop();\n return next;\n });\n turnCountRef.current = Math.max(0, turnCountRef.current - 1);\n setTurnCount(turnCountRef.current);\n void send(text);\n }, [cancelPolling, send]);\n\n const reset = useCallback(() => {\n // Archive the thread being left behind, so \"New chat\" never destroys history.\n setArchive(\n upsertArchive(storageKey, {\n token: conversationTokenRef.current,\n messages: messagesRef.current,\n focusProduct: focusProductRef.current,\n }),\n );\n cancelPolling();\n inFlightRef.current = false;\n conversationTokenRef.current = null;\n lastSentTextRef.current = null;\n turnCountRef.current = 0;\n setTurnCount(0);\n setMessages([]);\n setError(null);\n setRemainingToday(null);\n setPhase(catalogRef.current.enabled ? \"ready\" : \"disabled\");\n if (typeof window !== \"undefined\") {\n try {\n window.localStorage.removeItem(storageKey);\n } catch {\n /* storage unavailable — nothing to clear */\n }\n }\n }, [cancelPolling, storageKey]);\n\n /**\n * Reopen a past conversation. The messages come from the local archive rather than the server:\n * the backend expires a job's state, and a visitor looking at their own history should see it\n * whether or not the server still holds anything. The token is restored too, so the next\n * message continues the SAME server-side conversation.\n */\n const openConversation = useCallback(\n (token: string) => {\n const entry = readArchive(storageKey).find((e) => e.token === token);\n if (!entry) return;\n // Archive whatever is on screen first, or switching away would lose it.\n upsertArchive(storageKey, {\n token: conversationTokenRef.current,\n messages: messagesRef.current,\n focusProduct: focusProductRef.current,\n });\n cancelPolling();\n inFlightRef.current = false;\n conversationTokenRef.current = entry.token;\n turnCountRef.current = entry.messages.filter(\n (m) => m.role === \"USER\",\n ).length;\n setTurnCount(turnCountRef.current);\n setMessages(entry.messages);\n focusProductRef.current = entry.focusProduct;\n setFocusProductState(entry.focusProduct);\n setError(null);\n setPhase(catalogRef.current.enabled ? \"ready\" : \"disabled\");\n setArchive(readArchive(storageKey));\n },\n [cancelPolling, storageKey],\n );\n\n /** Forget one past conversation. Local only — see the page's storage notice. */\n const deleteConversation = useCallback(\n (token: string) => {\n const next = readArchive(storageKey).filter((e) => e.token !== token);\n writeArchive(storageKey, next);\n setArchive(next);\n },\n [storageKey],\n );\n\n /** Forget every past conversation held in this browser. */\n const clearHistory = useCallback(() => {\n writeArchive(storageKey, []);\n setArchive([]);\n }, [storageKey]);\n\n const setFocusProduct = useCallback((slug: string | null) => {\n focusProductRef.current = slug;\n setFocusProductState(slug);\n }, []);\n\n const activity = useMemo<string | null>(() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const m = messages[i];\n if (!m || m.role !== \"ASSISTANT\") continue;\n if (m.status !== \"PENDING\" && m.status !== \"RUNNING\") return null;\n const lines = m.activity ?? [];\n return lines.length ? (lines[lines.length - 1] ?? null) : null;\n }\n return null;\n }, [messages]);\n\n const canSend =\n (phase === \"ready\" || phase === \"error\") &&\n catalog.enabled &&\n turnCount < catalog.limits.maxTurnsPerConversation;\n\n /**\n * Tell the server the visitor followed one of the links this answer offered.\n *\n * Deliberately fire-and-forget and never awaited: the browser is navigating away as this\n * goes out, so anything that blocked on it would delay the click the visitor actually\n * made. Failures are swallowed — analytics must never break navigation.\n */\n const createShareLink = useCallback(async (): Promise<string | null> => {\n const token = conversationTokenRef.current;\n if (!token) return null;\n try {\n const result = await client.mutate<{\n createExploreShareLink?: { shareToken?: string | null } | null;\n }>(CREATE_EXPLORE_SHARE_LINK_MUTATION, { conversationToken: token });\n return result?.data?.createExploreShareLink?.shareToken ?? null;\n } catch {\n // Sharing is a convenience; a failure must not take the conversation down with it.\n return null;\n }\n }, [client]);\n\n const recordClick = useCallback(\n (messageId: string, kind: \"CTA\" | \"REFERENCE\", url: string): void => {\n const token = conversationTokenRef.current;\n if (!token) return;\n try {\n void client\n .mutate(RECORD_EXPLORE_CLICK_MUTATION, {\n input: { conversationToken: token, messageId, kind, url },\n })\n .catch(() => {\n /* the visitor is mid-navigation; there is nothing useful to do here */\n });\n } catch {\n /* client unavailable — same reasoning */\n }\n },\n [client],\n );\n\n return {\n phase,\n catalog,\n messages,\n activity,\n remainingToday,\n error,\n focusProduct,\n setFocusProduct,\n send,\n stop,\n retry,\n reset,\n canSend,\n history: archive,\n openConversation,\n deleteConversation,\n clearHistory,\n recordClick,\n createShareLink,\n };\n}\n\n/**\n * Client-only id for the optimistic user bubble, swapped for the server's\n * `userMessage.id` as soon as the mutation resolves. The counter only has to\n * make ids unique within a tab, never across one.\n */\nlet optimisticCounter = 0;\n\nfunction makeOptimisticId(): string {\n optimisticCounter += 1;\n return `boff-explore-local-${Date.now()}-${optimisticCounter}`;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Dictation for the explore composer, on the browser's own speech recogniser.\n *\n * Uses the Web Speech API directly — no dependency, no network call of our own, no audio ever\n * leaving the browser through us. Support is genuinely partial (Chrome, Edge and Safari expose\n * it, most commonly behind the `webkit` prefix; Firefox does not implement it at all), so the\n * caller MUST hide the microphone entirely when `supported` is false rather than offering a\n * control that cannot work.\n *\n * Interim results are surfaced separately from final ones so the composer can show speech\n * appearing live while only committing settled text to the draft.\n *\n * ## Mobile\n *\n * Mobile took three separate fixes, each of which looked like the whole problem:\n *\n * 1. **The prompt never appeared.** `recognition.start()` raises the permission prompt on\n * desktop Chrome but on Android Chrome and iOS fires `not-allowed` without showing\n * anything, so a visitor who had never been asked was told to change a browser setting.\n * `getUserMedia` is what actually prompts, so it is primed first.\n * 2. **Granting still failed.** Recognition opens its OWN capture, and starting it in the same\n * tick that the primed stream is being torn down races that teardown. It now waits for the\n * release, and retries once — Android frequently refuses the first attempt after a\n * permission is newly granted and accepts the second.\n * 3. **`continuous` is not honoured on mobile.** Android Chrome ends the session after a\n * single utterance regardless, and asking for continuous mode makes it fail sooner. Mobile\n * therefore runs single-shot and is restarted from `onend` for as long as the visitor is\n * still dictating, which behaves like continuous without fighting the platform.\n */\n\ninterface SpeechRecognitionAlternativeLike {\n transcript: string;\n}\ninterface SpeechRecognitionResultLike {\n readonly isFinal: boolean;\n readonly length: number;\n [index: number]: SpeechRecognitionAlternativeLike;\n}\ninterface SpeechRecognitionEventLike {\n readonly resultIndex: number;\n readonly results: {\n readonly length: number;\n [index: number]: SpeechRecognitionResultLike;\n };\n}\ninterface SpeechRecognitionErrorEventLike {\n readonly error: string;\n}\ninterface SpeechRecognitionLike {\n lang: string;\n continuous: boolean;\n interimResults: boolean;\n maxAlternatives: number;\n start: () => void;\n stop: () => void;\n abort: () => void;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;\n onend: (() => void) | null;\n onstart: (() => void) | null;\n}\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\n\ninterface SpeechWindow {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n}\n\nfunction getRecognitionCtor(): SpeechRecognitionCtor | null {\n if (typeof window === \"undefined\") return null;\n const w = window as unknown as SpeechWindow;\n return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;\n}\n\n/**\n * Coarse pointer means a touch device, which is what actually predicts the recogniser's\n * behaviour here — not the screen size, and not a UA string that lies.\n */\nfunction isTouchDevice(): boolean {\n if (typeof window === \"undefined\" || !window.matchMedia) return false;\n try {\n return window.matchMedia(\"(pointer: coarse)\").matches;\n } catch {\n return false;\n }\n}\n\nconst MIC_DENIED_MESSAGE =\n \"Microphone access was blocked. Allow it in your browser's site settings to dictate.\";\nconst MIC_UNAVAILABLE_MESSAGE =\n \"Dictation isn't available in this browser. You can type instead.\";\n\n/** Let a released capture settle before recognition opens its own. */\nconst RELEASE_SETTLE_MS = 250;\n/** Android often refuses the first start after a fresh grant and accepts the next. */\nconst RETRY_DELAY_MS = 350;\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n/**\n * Ask for the microphone the only way that reliably raises a prompt on mobile.\n *\n * `confirmed` reports whether access was actually VERIFIED, which is what separates \"you need\n * to grant this\" from \"your browser cannot do this\" further down.\n *\n * Must be called synchronously from the user gesture that requested dictation — awaiting\n * anything first spends the gesture and the browser then rejects the request outright.\n */\nasync function ensureMicrophoneAccess(): Promise<\n | { ok: true; confirmed: boolean; primed: boolean }\n | { ok: false; message: string }\n> {\n const media =\n typeof navigator === \"undefined\" ? undefined : navigator.mediaDevices;\n // Older/unusual browsers without mediaDevices: fall through and let recognition try. It\n // may well work, and refusing here would remove dictation from browsers that support it.\n if (!media?.getUserMedia)\n return { ok: true, confirmed: false, primed: false };\n\n // `granted` means the prompt would not appear anyway, so skip the extra capture — which\n // also avoids the teardown race entirely on repeat use.\n //\n // A `denied` reading is deliberately NOT trusted to short-circuit. The Permissions API\n // reports `denied` for a prompt the visitor merely dismissed, and its microphone support\n // is uneven across mobile browsers — believing it would recreate the exact bug this\n // function exists to fix, telling someone to change a setting instead of asking them.\n // getUserMedia is the authoritative check, and when access really is denied it rejects\n // immediately without showing anything, so the only cost of asking is a settled promise.\n //\n // `permissions` is absent on Safari and `microphone` is not a valid name everywhere, so\n // every part of this is optional and failure is non-fatal.\n try {\n const status = await navigator.permissions?.query({\n name: \"microphone\" as PermissionName,\n });\n if (status?.state === \"granted\")\n return { ok: true, confirmed: true, primed: false };\n } catch {\n /* permissions API unavailable or the name is unsupported — prompt below instead */\n }\n\n try {\n const stream = await media.getUserMedia({ audio: true });\n // Release immediately: this capture existed only to raise the prompt, and leaving it\n // open would show a recording indicator for the whole session — and on mobile would\n // occupy the very microphone recognition is about to ask for.\n for (const track of stream.getTracks()) track.stop();\n return { ok: true, confirmed: true, primed: true };\n } catch (error) {\n const name =\n typeof error === \"object\" && error !== null && \"name\" in error\n ? String((error as { name: unknown }).name)\n : \"\";\n if (name === \"NotAllowedError\" || name === \"SecurityError\") {\n return { ok: false, message: MIC_DENIED_MESSAGE };\n }\n if (name === \"NotFoundError\" || name === \"DevicesNotFoundError\") {\n return { ok: false, message: \"No microphone was found.\" };\n }\n return {\n ok: false,\n message: \"Dictation could not start. You can type instead.\",\n };\n }\n}\n\n/** Messages a visitor can act on. `not-allowed` is the one that needs real explanation. */\nfunction describeError(code: string): string {\n switch (code) {\n case \"not-allowed\":\n case \"service-not-allowed\":\n return MIC_DENIED_MESSAGE;\n case \"no-speech\":\n return \"I didn't catch anything — try again a little closer to the mic.\";\n case \"audio-capture\":\n return \"No microphone was found.\";\n case \"network\":\n return \"Speech recognition needs a network connection.\";\n case \"aborted\":\n return \"\";\n default:\n return \"Dictation stopped unexpectedly. You can type instead.\";\n }\n}\n\nexport interface UseSpeechInputOptions {\n /** Receives settled text as it is recognised. Append it to the draft. */\n onFinalTranscript: (text: string) => void;\n /** BCP-47 tag. Defaults to the browser's language. */\n lang?: string;\n /** Called when the recogniser reports a problem worth showing. */\n onError?: (message: string) => void;\n}\n\nexport interface UseSpeechInputResult {\n /** False when the browser has no speech recogniser — hide the control entirely. */\n supported: boolean;\n listening: boolean;\n /** Words recognised but not yet settled; render as a live hint, do not store. */\n interim: string;\n error: string | null;\n start: () => void;\n stop: () => void;\n toggle: () => void;\n}\n\nexport function useSpeechInput({\n onFinalTranscript,\n lang,\n onError,\n}: UseSpeechInputOptions): UseSpeechInputResult {\n const [supported] = useState(() => getRecognitionCtor() !== null);\n const [listening, setListening] = useState(false);\n const [interim, setInterim] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n\n const recognitionRef = useRef<SpeechRecognitionLike | null>(null);\n /**\n * Bumped on every start()/stop(). A permission prompt, a settle delay or a retry resolving\n * after the visitor moved on must not open a microphone behind them.\n */\n const startTokenRef = useRef(0);\n /**\n * True only when the microphone was actually VERIFIED for this attempt — permission\n * reported granted, or getUserMedia succeeded. Stays false on browsers with no\n * mediaDevices, where nothing was checked and a recogniser `not-allowed` may still be a\n * real permission problem.\n */\n const micConfirmedRef = useRef(false);\n /** The visitor's intent, as opposed to whether a session happens to be open right now. */\n const wantsListeningRef = useRef(false);\n /** One retry per start(), for the Android \"refuses the first attempt\" case. */\n const retriedRef = useRef(false);\n\n // Held in refs so the recogniser's long-lived handlers always call the latest closures\n // without tearing down and re-creating the recogniser on every render.\n const finalRef = useRef(onFinalTranscript);\n const errorRef = useRef(onError);\n finalRef.current = onFinalTranscript;\n errorRef.current = onError;\n\n const langRef = useRef(lang);\n langRef.current = lang;\n\n const stop = useCallback(() => {\n startTokenRef.current += 1;\n wantsListeningRef.current = false;\n setListening(false);\n setInterim(\"\");\n const recognition = recognitionRef.current;\n if (!recognition) return;\n try {\n recognition.stop();\n } catch {\n /* already stopped */\n }\n }, []);\n\n /** Open a recogniser session. Separate from start() so a retry can reuse it. */\n const openSession = useCallback((token: number) => {\n const Ctor = getRecognitionCtor();\n if (!Ctor || token !== startTokenRef.current) return;\n\n const recognition = new Ctor();\n recognition.lang =\n langRef.current ??\n (typeof navigator === \"undefined\"\n ? \"en-US\"\n : navigator.language || \"en-US\");\n // Continuous mode is a desktop-only affordance. Android Chrome ends the session after a\n // single utterance whatever this says, and asking for continuous makes it fail sooner —\n // mobile is restarted from `onend` instead, which behaves the same to the visitor.\n recognition.continuous = !isTouchDevice();\n recognition.interimResults = true;\n recognition.maxAlternatives = 1;\n\n recognition.onstart = () => {\n if (token !== startTokenRef.current) return;\n // NOTE: the retry budget is deliberately NOT reset here. It belongs to the visitor's\n // press, not to the session — a browser that fires onstart and then immediately\n // errors would otherwise retry forever.\n setError(null);\n setListening(true);\n };\n\n recognition.onresult = (event) => {\n if (token !== startTokenRef.current) return;\n let settled = \"\";\n let pending = \"\";\n for (let i = event.resultIndex; i < event.results.length; i += 1) {\n const result = event.results[i];\n if (!result) continue;\n const text = result[0]?.transcript ?? \"\";\n if (result.isFinal) settled += text;\n else pending += text;\n }\n setInterim(pending);\n if (settled.trim() !== \"\") finalRef.current(settled);\n };\n\n recognition.onerror = (event) => {\n if (token !== startTokenRef.current) return;\n\n // Android commonly refuses the FIRST start after a permission is newly granted and\n // accepts the next one. Retry once, silently, before telling the visitor anything —\n // an error message they can do nothing about is worse than a short pause.\n if (\n (event.error === \"not-allowed\" ||\n event.error === \"service-not-allowed\") &&\n micConfirmedRef.current &&\n !retriedRef.current\n ) {\n retriedRef.current = true;\n void sleep(RETRY_DELAY_MS).then(() => {\n if (token !== startTokenRef.current || !wantsListeningRef.current)\n return;\n openSessionRef.current?.(token);\n });\n return;\n }\n\n // The microphone was verified moments ago, so a `not-allowed` that survived the retry\n // is the SPEECH SERVICE refusing, not a permission the visitor can grant. Sending them\n // to a site setting would point at something that cannot help.\n const message =\n micConfirmedRef.current &&\n (event.error === \"not-allowed\" || event.error === \"service-not-allowed\")\n ? MIC_UNAVAILABLE_MESSAGE\n : describeError(event.error);\n\n wantsListeningRef.current = false;\n setListening(false);\n setInterim(\"\");\n if (message !== \"\") {\n setError(message);\n errorRef.current?.(message);\n }\n };\n\n recognition.onend = () => {\n if (token !== startTokenRef.current) return;\n setInterim(\"\");\n // Single-shot mobile sessions end after each utterance. While the visitor still has\n // dictation switched on, reopen so it behaves like continuous mode.\n if (wantsListeningRef.current && isTouchDevice()) {\n void sleep(120).then(() => {\n if (token !== startTokenRef.current || !wantsListeningRef.current)\n return;\n openSessionRef.current?.(token);\n });\n return;\n }\n setListening(false);\n };\n\n recognitionRef.current = recognition;\n try {\n recognition.start();\n } catch {\n // Chrome throws InvalidStateError if start() races a session that is still closing.\n // The onend handler above will not fire for a session that never began, so settle here.\n wantsListeningRef.current = false;\n setListening(false);\n }\n }, []);\n\n // openSession refers to itself from its own handlers (retry, mobile restart), which a plain\n // const cannot do inside useCallback.\n const openSessionRef = useRef<((token: number) => void) | null>(null);\n openSessionRef.current = openSession;\n\n const start = useCallback(() => {\n if (!getRecognitionCtor()) return;\n\n startTokenRef.current += 1;\n const token = startTokenRef.current;\n wantsListeningRef.current = true;\n retriedRef.current = false;\n micConfirmedRef.current = false;\n\n // Show the pressed state straight away: the permission prompt can sit on screen for a\n // while on mobile, and a mic button that looks inert invites a second tap.\n setError(null);\n setListening(true);\n\n void ensureMicrophoneAccess().then(async (access) => {\n // A stop() or a newer start() landed while the prompt was open — abandon this attempt.\n if (token !== startTokenRef.current) return;\n\n if (!access.ok) {\n wantsListeningRef.current = false;\n setListening(false);\n setError(access.message);\n errorRef.current?.(access.message);\n return;\n }\n\n micConfirmedRef.current = access.confirmed;\n\n // Recognition opens its own capture. Starting in the same tick that the primed stream\n // is being torn down races that teardown and is refused — this is what made \"I granted\n // it and it still says blocked\" happen on mobile.\n if (access.primed) {\n await sleep(RELEASE_SETTLE_MS);\n if (token !== startTokenRef.current) return;\n }\n\n openSessionRef.current?.(token);\n });\n }, []);\n\n const toggle = useCallback(() => {\n if (listening) stop();\n else start();\n }, [listening, start, stop]);\n\n // Never leave the microphone open behind a closed page.\n useEffect(\n () => () => {\n startTokenRef.current += 1;\n wantsListeningRef.current = false;\n const recognition = recognitionRef.current;\n if (!recognition) return;\n recognition.onresult = null;\n recognition.onerror = null;\n recognition.onend = null;\n recognition.onstart = null;\n try {\n recognition.abort();\n } catch {\n /* nothing to abort */\n }\n },\n [],\n );\n\n return { supported, listening, interim, error, start, stop, toggle };\n}\n","/**\n * PageHead Component\n * Manages dynamic meta tags for SEO optimization on a per-page basis.\n * Supports JSON-LD structured data, Open Graph, Twitter Cards, favicons, and robots directives.\n *\n * @example\n * ```tsx\n * <PageHead\n * title=\"About Us\"\n * description=\"Learn about our mission and team\"\n * productName=\"MyProduct\"\n * keywords=\"about, team, mission\"\n * image=\"/og-about.png\"\n * url=\"https://myproduct.com/about\"\n * favicon=\"/favicon.ico\"\n * robots=\"index, follow\"\n * locale=\"en_US\"\n * twitterHandle=\"@burdenoff\"\n * themeColor=\"#1a1a2e\"\n * structuredData={{\n * \"@context\": \"https://schema.org\",\n * \"@type\": \"WebPage\",\n * name: \"About Us\",\n * }}\n * />\n * ```\n */\n\nimport { Helmet } from \"react-helmet-async\";\n\nexport interface PageHeadProps {\n /** Page title */\n title: string;\n /** Meta description */\n description?: string;\n /** Product/brand name (appended to title) */\n productName?: string;\n /** SEO keywords */\n keywords?: string;\n /** Open Graph image URL */\n image?: string;\n /** Page canonical URL */\n url?: string;\n /** Favicon URL */\n favicon?: string;\n /** Robots directive (e.g., \"index, follow\") */\n robots?: string;\n /** Open Graph locale (e.g., \"en_US\") */\n locale?: string;\n /** Twitter handle (e.g., \"@burdenoff\") */\n twitterHandle?: string;\n /** Theme color for mobile browsers */\n themeColor?: string;\n /** JSON-LD structured data objects */\n structuredData?: Record<string, unknown> | Array<Record<string, unknown>>;\n /** Additional meta tags */\n additionalMeta?: Array<{\n name?: string;\n property?: string;\n content: string;\n }>;\n}\n\n/**\n * Build a self-referencing canonical URL from the current location.\n *\n * Query strings and hashes are dropped (they never identify a distinct\n * canonical document here) and the trailing slash is normalised away for\n * everything but the site root. Returns `undefined` outside a DOM so the\n * component degrades to its previous behaviour under plain string rendering.\n */\nfunction canonicalFromLocation(): string | undefined {\n if (typeof window === \"undefined\" || !window.location) return undefined;\n const { origin, pathname } = window.location;\n if (!origin || origin === \"null\") return undefined;\n const path = pathname === \"/\" ? \"/\" : pathname.replace(/\\/+$/, \"\");\n return `${origin}${path}`;\n}\n\n/**\n * Absolutise an Open Graph image URL.\n *\n * Already-absolute URLs pass through. A root-relative path resolves against\n * the origin, and any other relative path against the page URL. Without a\n * resolvable base the original value is returned unchanged.\n */\nfunction resolveImageUrl(\n image: string | undefined,\n base: string | undefined,\n): string | undefined {\n if (!image || /^https?:\\/\\//i.test(image)) return image;\n if (!base) return image;\n try {\n return new URL(image, base).toString();\n } catch {\n return image;\n }\n}\n\nexport function PageHead({\n title,\n description,\n productName,\n keywords,\n image,\n url,\n favicon,\n robots = \"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\",\n locale = \"en_US\",\n twitterHandle,\n themeColor = \"#000000\",\n structuredData,\n additionalMeta,\n}: PageHeadProps) {\n const fullTitle =\n productName && !title.includes(productName)\n ? `${title} | ${productName}`\n : title;\n\n // Self-referencing canonical by default.\n //\n // Without this, a route that renders PageHead but omits `url` emits no\n // canonical at all, so the static `<link rel=\"canonical\">` in index.html\n // survives and every such page declares itself a duplicate of the home\n // page — Google then drops /pricing, /privacy, /terms and friends from the\n // index. Deriving it from the current location keeps each page pointing at\n // itself; callers that genuinely need a cross-canonical still pass `url`.\n //\n // During prerender the DOM location already reflects the route being\n // rendered, so this resolves correctly ahead of hydration.\n const resolvedUrl = url ?? canonicalFromLocation();\n\n // Root-relative images (\"/og.png\") belong to the ORIGIN, not to the current\n // path — concatenating them onto the page URL yields /features/og.png and a\n // broken share card. Anything else is resolved relative to the page itself.\n const fullImageUrl = resolveImageUrl(image, resolvedUrl);\n\n // Normalize structured data to an array\n const structuredDataItems: Array<Record<string, unknown>> = structuredData\n ? Array.isArray(structuredData)\n ? structuredData\n : [structuredData]\n : [];\n\n return (\n <Helmet>\n {/* Primary Meta Tags */}\n <title>{fullTitle}</title>\n <meta name=\"title\" content={fullTitle} />\n {description && <meta name=\"description\" content={description} />}\n {keywords && <meta name=\"keywords\" content={keywords} />}\n <meta name=\"author\" content=\"Burdenoff Consultancy Services Pvt Ltd\" />\n <meta name=\"robots\" content={robots} />\n\n {/* Canonical URL */}\n {resolvedUrl && <link rel=\"canonical\" href={resolvedUrl} />}\n\n {/* Favicon */}\n {favicon && <link rel=\"icon\" href={favicon} />}\n\n {/* Open Graph / Facebook */}\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:title\" content={fullTitle} />\n {description && <meta property=\"og:description\" content={description} />}\n {fullImageUrl && <meta property=\"og:image\" content={fullImageUrl} />}\n {resolvedUrl && <meta property=\"og:url\" content={resolvedUrl} />}\n <meta property=\"og:locale\" content={locale} />\n {productName && <meta property=\"og:site_name\" content={productName} />}\n\n {/* Twitter Card */}\n <meta name=\"twitter:card\" content=\"summary_large_image\" />\n <meta name=\"twitter:title\" content={fullTitle} />\n {description && <meta name=\"twitter:description\" content={description} />}\n {fullImageUrl && <meta name=\"twitter:image\" content={fullImageUrl} />}\n {twitterHandle && <meta name=\"twitter:creator\" content={twitterHandle} />}\n\n {/* Theme Color */}\n <meta name=\"theme-color\" content={themeColor} />\n\n {/* JSON-LD Structured Data */}\n {structuredDataItems.map((data, index) => (\n <script key={`ld-${index}`} type=\"application/ld+json\">\n {JSON.stringify(data)}\n </script>\n ))}\n\n {/* Additional Meta Tags */}\n {additionalMeta?.map((meta, index) => (\n <meta\n key={`meta-${index}`}\n {...(meta.name ? { name: meta.name } : {})}\n {...(meta.property ? { property: meta.property } : {})}\n content={meta.content}\n />\n ))}\n </Helmet>\n );\n}\n","/**\n * Utility function to merge Tailwind CSS classes\n * Combines clsx and tailwind-merge for optimal class handling\n */\n\nimport { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge multiple class names intelligently\n * - Handles conditional classes via clsx\n * - Deduplicates and resolves Tailwind conflicts via tailwind-merge\n *\n * @example\n * ```ts\n * cn('px-4 py-2', 'bg-blue-500', { 'text-white': isActive })\n * // => 'px-4 py-2 bg-blue-500 text-white' (if isActive is true)\n * ```\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../utils/cn\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-md px-3 text-xs\",\n lg: \"h-10 rounded-md px-8\",\n icon: \"h-9 w-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\n\nimport { cn } from \"../utils/cn\";\n\nconst Textarea = React.forwardRef<\n HTMLTextAreaElement,\n React.ComponentProps<\"textarea\">\n>(({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n \"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n});\nTextarea.displayName = \"Textarea\";\n\nexport { Textarea };\n","/**\n * ExplorePage — the public `/explore` AI chat surface.\n *\n * Ships on 38 marketing sites, so it is written as a *marketing* page that\n * happens to be a chat, not a chat widget dropped onto a marketing site:\n *\n * - The welcome state discloses what the assistant can do **before** the\n * visitor types — a real `<h1>`, a one-line pitch, three capability bullets,\n * clickable example prompts and product-focus chips.\n * - That `<h1>` renders on the FIRST render, from props or the hook's built-in\n * fallback catalog, never from the catalog fetch. The websites' prerender\n * waits for an `h1`; a heading behind a network round-trip would bake 38\n * blank static pages.\n * - Colours are semantic tokens only (`bg-card`, `text-muted-foreground`,\n * `border-border`, …) so the page is correct in light AND dark mode on every\n * product's palette. No raw hex/rgb/hsl anywhere.\n *\n * Import from the package ROOT — `@burdenoff/website-sdk` — never from\n * `@burdenoff/website-sdk/components/explore`. tsup builds with\n * `splitting: false`, so a sub-path bundle carries its own copy of the React\n * context and cannot see the app's `WebSDKProvider`.\n *\n * @example\n * ```tsx\n * import { ExplorePage } from '@burdenoff/website-sdk'\n *\n * <ExplorePage\n * productSlug=\"vibecontrols\"\n * heightMode=\"viewport\"\n * viewportOffset=\"4rem\" // site header height\n * onNavigate={(path) => navigate(path)}\n * seo={{ url: 'https://vibecontrols.com/explore' }}\n * />\n * ```\n */\n\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n ArrowUp,\n BookOpenText,\n ChevronLeft,\n ChevronRight,\n ExternalLink,\n Layers,\n Link2,\n RotateCcw,\n Sparkles,\n History as HistoryIcon,\n Mic,\n Square,\n Trash2,\n TriangleAlert,\n} from \"lucide-react\";\n\nimport { Markdown } from \"../content/Markdown\";\nimport { ProseStyles } from \"../content/prose-styles\";\nimport { useExploreChat } from \"../hooks/use-explore-chat\";\nimport { useSpeechInput } from \"../hooks/use-speech-input\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Textarea } from \"../ui/textarea\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n ExploreCtaLink,\n ExploreMessage,\n ExploreReference,\n} from \"./explore-types\";\nimport type { ExploreChatError } from \"../hooks/use-explore-chat\";\n\n// ============================================================================\n// Props\n// ============================================================================\n\nexport interface ExplorePageProps {\n /** SEO metadata. Rendered through `PageHead` when provided. */\n seo?: {\n title?: string;\n description?: string;\n keywords?: string;\n image?: string;\n url?: string;\n };\n /** Slug of the product site this page lives on — a soft hint to the harness. */\n productSlug?: string;\n /**\n * Example prompts shown when `exploreCatalog` supplies none. Resolution\n * order: catalog → this prop → the SDK's built-in list.\n */\n examplePrompts?: string[];\n /** Extra classes for the page root. */\n className?: string;\n /**\n * `viewport` (default) pins the chat to the viewport with an internally\n * scrolling transcript — the right feel for a dedicated `/explore` route.\n * `auto` lets the page grow, for embedding inside a longer page.\n */\n heightMode?: \"viewport\" | \"auto\";\n /**\n * Chrome to subtract in `viewport` mode — the site header (and footer)\n * height. A number is treated as pixels. Default `0`.\n */\n viewportOffset?: string | number;\n /** SPA navigation for internal CTA paths. Falls back to a plain link. */\n onNavigate?: (path: string) => void;\n /** Fired with the message text every time a send is accepted. */\n onSend?: (message: string) => void;\n /** Overrides `exploreCatalog.welcomeTitle` — also the page `<h1>`. */\n welcomeTitle?: string;\n /** Overrides `exploreCatalog.welcomeBody`. */\n welcomeBody?: string;\n}\n\n// ============================================================================\n// Local styling (scoped, token-driven)\n// ============================================================================\n\nconst EXPLORE_CSS = `\n@keyframes boff-explore-pulse {\n 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-2px); }\n}\n.boff-explore-dot {\n display: inline-block;\n width: 5px;\n height: 5px;\n border-radius: 9999px;\n background-color: hsl(var(--muted-foreground));\n animation: boff-explore-pulse 1.2s ease-in-out infinite;\n}\n@keyframes boff-explore-caret {\n 0%, 45% { opacity: 1; }\n 50%, 100% { opacity: 0; }\n}\n.boff-explore-caret {\n display: inline-block;\n width: 2px;\n height: 1em;\n margin-left: 2px;\n vertical-align: text-bottom;\n background-color: hsl(var(--primary));\n animation: boff-explore-caret 1s step-end infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n .boff-explore-dot,\n .boff-explore-caret { animation: none; }\n .boff-explore-dot { opacity: 0.6; }\n}\n.boff-explore-scroll {\n scrollbar-width: thin;\n scrollbar-color: hsl(var(--border)) transparent;\n}\n.boff-explore-scroll::-webkit-scrollbar { width: 10px; }\n.boff-explore-scroll::-webkit-scrollbar-track { background: transparent; }\n.boff-explore-scroll::-webkit-scrollbar-thumb {\n background-color: hsl(var(--border));\n border: 3px solid transparent;\n border-radius: 9999px;\n background-clip: content-box;\n}\n\n/* The product strip scrolls inside itself; a visible scrollbar would read as a broken\n layout rather than an affordance, and reserving its gutter shifts the chips. */\n.boff-explore-strip {\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n.boff-explore-strip::-webkit-scrollbar { display: none; }\n\n@keyframes boff-explore-fade-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: none; }\n}\n.boff-explore-fade { animation: boff-explore-fade-in 220ms ease-out; }\n@media (prefers-reduced-motion: reduce) {\n .boff-explore-fade { animation: none; }\n}\n\n/* Nothing inside an answer may widen the page. Model output carries long URLs, code and\n tables — each of those overflows a phone by default, and one overflowing child makes the\n WHOLE document horizontally scrollable, not just the bubble. */\n.boff-explore-body,\n.boff-explore-body p,\n.boff-explore-body li,\n.boff-explore-body a,\n.boff-explore-body h1,\n.boff-explore-body h2,\n.boff-explore-body h3 {\n overflow-wrap: anywhere;\n word-break: break-word;\n}\n.boff-explore-body pre {\n overflow-x: auto;\n max-width: 100%;\n}\n.boff-explore-body table {\n display: block;\n overflow-x: auto;\n max-width: 100%;\n}\n.boff-explore-body img {\n max-width: 100%;\n height: auto;\n}\n`;\n\nfunction ExploreStyles() {\n return <style dangerouslySetInnerHTML={{ __html: EXPLORE_CSS }} />;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst CAPABILITIES = [\n {\n icon: BookOpenText,\n title: \"Grounded in our own docs\",\n body: \"Every answer comes from published product pages and documentation — never invented.\",\n },\n {\n icon: Layers,\n title: \"Compare across the ecosystem\",\n body: \"Ask which product fits your team, or how two of them work together.\",\n },\n {\n icon: Link2,\n title: \"Straight to the right page\",\n body: \"Get the sources and next steps — pricing, docs, a demo — without hunting.\",\n },\n] as const;\n\n/** CTA kind → button styling. Unknown kinds fall through to the outline look. */\nconst CTA_VARIANTS: Record<string, \"default\" | \"secondary\" | \"outline\"> = {\n CONTACT: \"default\",\n WAITLIST: \"default\",\n APP: \"default\",\n PRICING: \"secondary\",\n STORE: \"secondary\",\n PARTNERS: \"secondary\",\n DOCS: \"outline\",\n SERVICES: \"outline\",\n OTHER: \"outline\",\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeOffset(offset: string | number | undefined): string {\n if (offset === undefined) return \"0px\";\n return typeof offset === \"number\" ? `${offset}px` : offset;\n}\n\n/** A same-origin path the host router can handle, as opposed to `https://…`. */\nfunction isInternalPath(url: string): boolean {\n return url.startsWith(\"/\") && !url.startsWith(\"//\");\n}\n\nfunction hostnameOf(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n /* relative or malformed URL — the label is decorative, so degrade quietly */\n return \"\";\n }\n}\n\nfunction initialOf(value: string | null | undefined, fallback: string): string {\n const source = (value || fallback).trim();\n return source ? source.slice(0, 1).toUpperCase() : \"?\";\n}\n\n/**\n * The product's own logo, derived from the reference's origin.\n *\n * Every Burdenoff product site serves `/favicon.svg`, so the logo needs no registry and no\n * bundled assets — the reference URL already names the product. Deliberately NOT\n * `/favicon-512.png`: that path returns 200 with `text/html` because the SPA fallback\n * answers unknown paths, so it would render as a broken image rather than 404 into the\n * fallback below.\n */\nexport function logoUrlOf(url: string): string | null {\n try {\n const { origin, protocol } = new URL(url);\n if (protocol !== \"https:\" && protocol !== \"http:\") return null;\n return `${origin}/favicon.svg`;\n } catch {\n return null;\n }\n}\n\n// ============================================================================\n// Reference card\n// ============================================================================\n\nfunction ReferenceCard({\n reference,\n onFollow,\n}: {\n reference: ExploreReference;\n onFollow?: (url: string) => void;\n}) {\n const [imageFailed, setImageFailed] = useState(false);\n const [logoFailed, setLogoFailed] = useState(false);\n const host = hostnameOf(reference.url);\n const logoUrl = logoUrlOf(reference.url);\n const showImage = Boolean(reference.imageUrl) && !imageFailed;\n const showLogo = Boolean(logoUrl) && !logoFailed;\n\n // The letter plate is the last resort only. Every product's first letter collides with\n // several others (A for AdapterCloud and AssetHandler, B for BrainyRich and BuildMyIQ …),\n // so it identifies nothing — it exists purely so a card is never a blank hole.\n const letterPlate = (\n <div className=\"flex h-full w-full items-center justify-center bg-gradient-to-br from-primary/25 via-primary/5 to-secondary\">\n <span className=\"text-sm font-semibold text-primary/70 sm:text-2xl\">\n {initialOf(reference.product, reference.title || host)}\n </span>\n </div>\n );\n\n const logoImg = showLogo ? (\n <img\n src={logoUrl ?? \"\"}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setLogoFailed(true)}\n className=\"h-full w-full object-contain p-1.5 sm:p-0\"\n />\n ) : (\n letterPlate\n );\n\n return (\n <a\n data-boff-explore=\"reference\"\n data-index={reference.index ?? undefined}\n href={reference.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={() => onFollow?.(reference.url)}\n /* Mobile is a compact row, not a 16:9 card. Stacked preview cards pushed the answer\n itself off the top of a phone screen — five sources were taller than the response. */\n className=\"group flex flex-row items-center gap-3 overflow-hidden rounded-xl border border-border bg-card p-2 transition-colors hover:border-primary/40 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:flex-col sm:items-stretch sm:gap-0 sm:p-0\"\n >\n {/* Mobile: a small square logo. An og:image is a wide banner and is unreadable at 44px,\n so the phone layout always shows the product mark instead. */}\n <div className=\"relative h-11 w-11 shrink-0 overflow-hidden rounded-lg bg-muted sm:hidden\">\n {logoImg}\n </div>\n\n {/* sm+: the preview card, falling back to the product logo on a tinted plate. */}\n <div className=\"relative hidden aspect-[16/9] w-full overflow-hidden bg-muted sm:block\">\n {showImage ? (\n <img\n src={reference.imageUrl ?? \"\"}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setImageFailed(true)}\n className=\"h-full w-full object-cover transition-transform duration-300 group-hover:scale-105\"\n />\n ) : showLogo ? (\n <div className=\"flex h-full w-full items-center justify-center bg-gradient-to-br from-primary/15 via-transparent to-secondary/60 p-6\">\n <img\n src={logoUrl ?? \"\"}\n alt=\"\"\n loading=\"lazy\"\n onError={() => setLogoFailed(true)}\n className=\"max-h-full max-w-full object-contain\"\n />\n </div>\n ) : (\n letterPlate\n )}\n </div>\n\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5 sm:gap-1.5 sm:p-3\">\n <p className=\"line-clamp-2 text-sm font-semibold leading-snug text-card-foreground\">\n {reference.index ? (\n <span className=\"mr-1.5 inline-flex h-4 min-w-4 items-center justify-center rounded bg-primary/10 px-1 text-[10px] font-bold text-primary\">\n {reference.index}\n </span>\n ) : null}\n {reference.title || host || reference.url}\n </p>\n {reference.description ? (\n <p className=\"line-clamp-2 text-xs leading-relaxed text-muted-foreground max-sm:hidden\">\n {reference.description}\n </p>\n ) : null}\n <div className=\"flex items-center gap-2 sm:mt-auto sm:pt-2\">\n {reference.product ? (\n <span className=\"rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground max-sm:hidden\">\n {reference.product}\n </span>\n ) : null}\n <span className=\"inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground sm:ml-auto\">\n <ExternalLink className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">{host}</span>\n </span>\n </div>\n </div>\n </a>\n );\n}\n\n// ============================================================================\n// CTA button\n// ============================================================================\n\nfunction CtaButton({\n cta,\n onNavigate,\n onFollow,\n}: {\n cta: ExploreCtaLink;\n onNavigate?: (path: string) => void;\n onFollow?: (url: string) => void;\n}) {\n const variant = CTA_VARIANTS[cta.kind] ?? \"outline\";\n const internal = isInternalPath(cta.url);\n\n // Internal path + a router from the host: keep it an SPA navigation.\n if (internal && onNavigate) {\n return (\n <Button\n data-boff-explore=\"cta\"\n data-kind={cta.kind}\n type=\"button\"\n size=\"sm\"\n variant={variant}\n onClick={() => {\n onFollow?.(cta.url);\n onNavigate(cta.url);\n }}\n >\n {cta.label}\n </Button>\n );\n }\n\n return (\n <Button asChild size=\"sm\" variant={variant}>\n <a\n data-boff-explore=\"cta\"\n data-kind={cta.kind}\n href={cta.url}\n onClick={() => onFollow?.(cta.url)}\n {...(internal\n ? {}\n : { target: \"_blank\", rel: \"noopener noreferrer\" as const })}\n >\n {cta.label}\n {internal ? null : <ExternalLink className=\"ml-1 h-3 w-3\" />}\n </a>\n </Button>\n );\n}\n\n// ============================================================================\n// Thinking indicator\n// ============================================================================\n\nfunction ThinkingIndicator({ activity }: { activity: string | null }) {\n return (\n <div\n data-boff-explore=\"thinking\"\n className=\"flex items-center gap-2.5 rounded-2xl border border-border bg-muted/60 px-3.5 py-2.5 text-sm text-muted-foreground\"\n >\n <span className=\"flex items-center gap-1\" aria-hidden=\"true\">\n <span className=\"boff-explore-dot\" />\n <span\n className=\"boff-explore-dot\"\n style={{ animationDelay: \"150ms\" }}\n />\n <span\n className=\"boff-explore-dot\"\n style={{ animationDelay: \"300ms\" }}\n />\n </span>\n <span className=\"truncate\">{activity || \"Thinking…\"}</span>\n </div>\n );\n}\n\n// ============================================================================\n// Message bubbles\n// ============================================================================\n\nfunction UserBubble({ message }: { message: ExploreMessage }) {\n return (\n <div className=\"flex justify-end\">\n <div\n data-boff-explore=\"user\"\n className=\"max-w-[85%] whitespace-pre-wrap break-words rounded-2xl rounded-br-md bg-primary px-4 py-2.5 text-sm leading-relaxed text-primary-foreground shadow-sm\"\n >\n {message.content}\n </div>\n </div>\n );\n}\n\nfunction AssistantBubble({\n message,\n activity,\n onNavigate,\n anchorRef,\n onFollow,\n onFollowUp,\n}: {\n message: ExploreMessage;\n activity: string | null;\n onNavigate?: (path: string) => void;\n /** Set on the newest assistant turn so the transcript can align its top. */\n anchorRef?: React.Ref<HTMLDivElement>;\n onFollow?: (kind: \"CTA\" | \"REFERENCE\", url: string) => void;\n onFollowUp?: (question: string) => void;\n}) {\n const streaming =\n message.status === \"PENDING\" || message.status === \"RUNNING\";\n const body = message.content || message.partialContent || \"\";\n const failed = message.status === \"FAILED\";\n\n return (\n <div\n ref={anchorRef}\n data-boff-explore=\"assistant\"\n data-status={message.status}\n className=\"flex scroll-mt-4 gap-3\"\n >\n <span\n aria-hidden=\"true\"\n className=\"mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\"\n >\n <Sparkles className=\"h-4 w-4\" />\n </span>\n\n <div className=\"min-w-0 flex-1 space-y-3\">\n {/* The corpus had nothing. Saying so outright is more credible than a hedged\n paragraph that reads like an answer — and it points somewhere useful. */}\n {message.status === \"COMPLETED\" && message.answered === false ? (\n <div\n data-boff-explore=\"no-answer\"\n className=\"flex items-start gap-2 rounded-xl border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-foreground\"\n >\n <TriangleAlert className=\"mt-0.5 h-3.5 w-3.5 shrink-0 text-amber-600 dark:text-amber-400\" />\n <span>\n I couldn't find this in our documentation, so the answer\n below is not grounded in a source. Try rephrasing, or{\" \"}\n <a\n href=\"/contact\"\n className=\"underline underline-offset-2 hover:text-primary\"\n onClick={(event) => {\n if (!onNavigate) return;\n event.preventDefault();\n onNavigate(\"/contact\");\n }}\n >\n ask a human\n </a>\n .\n </span>\n </div>\n ) : null}\n\n {body ? (\n <div className=\"rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm\">\n <div className=\"boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground\">\n <Markdown>{body}</Markdown>\n </div>\n {streaming ? (\n <span className=\"boff-explore-caret\" aria-hidden=\"true\" />\n ) : null}\n </div>\n ) : null}\n\n {streaming ? <ThinkingIndicator activity={activity} /> : null}\n\n {failed && !body ? (\n <div className=\"rounded-2xl rounded-tl-md border border-border bg-muted px-4 py-3 text-sm text-muted-foreground\">\n That answer didn't come through. Try asking again.\n </div>\n ) : null}\n\n {message.references.length > 0 ? (\n <div>\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Sources\n </p>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {message.references.map((reference) => (\n <ReferenceCard\n key={reference.url}\n reference={reference}\n onFollow={(url) => onFollow?.(\"REFERENCE\", url)}\n />\n ))}\n </div>\n </div>\n ) : null}\n\n {message.ctas.length > 0 ? (\n <div className=\"flex flex-wrap gap-2 pt-0.5\">\n {message.ctas.map((cta) => (\n <CtaButton\n key={`${cta.kind}-${cta.url}`}\n cta={cta}\n onNavigate={onNavigate}\n onFollow={(url) => onFollow?.(\"CTA\", url)}\n />\n ))}\n </div>\n ) : null}\n\n {/* One question is a lookup; a second is a conversation. These are derived from\n what the answer actually cited, so they are always answerable. */}\n {message.status === \"COMPLETED\" &&\n (message.followUps?.length ?? 0) > 0 ? (\n <div className=\"space-y-1.5 pt-0.5\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n Next you could ask\n </p>\n <div className=\"flex flex-wrap gap-1.5\">\n {(message.followUps ?? []).map((question) => (\n <button\n key={question}\n data-boff-explore=\"follow-up\"\n type=\"button\"\n onClick={() => onFollowUp?.(question)}\n className=\"group inline-flex max-w-full items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1 text-left text-xs text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <span className=\"truncate\">{question}</span>\n <ArrowUp className=\"h-3 w-3 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary\" />\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Error banner\n// ============================================================================\n\nfunction ErrorBanner({\n error,\n onRetry,\n onReset,\n}: {\n error: ExploreChatError;\n onRetry: () => void;\n onReset: () => void;\n}) {\n const showRetry = error.retryable;\n const showReset = error.code === \"CONVERSATION_LIMIT\";\n\n return (\n <div\n data-boff-explore=\"error\"\n data-error-kind={error.kind}\n role=\"alert\"\n className=\"mb-3 flex items-start gap-3 rounded-xl border border-destructive/40 bg-destructive/10 px-3 py-2.5\"\n >\n {/* Solid destructive chip for the icon: `text-destructive` alone loses\n contrast against a dark background in dark mode. */}\n <span\n aria-hidden=\"true\"\n className=\"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-destructive text-destructive-foreground\"\n >\n <TriangleAlert className=\"h-3 w-3\" />\n </span>\n <p className=\"flex-1 text-sm leading-relaxed text-foreground\">\n {error.message}\n </p>\n {showRetry ? (\n <Button\n data-boff-explore=\"retry\"\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n onClick={onRetry}\n >\n Retry\n </Button>\n ) : null}\n {showReset ? (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onReset}>\n New chat\n </Button>\n ) : null}\n </div>\n );\n}\n\n// ============================================================================\n// Welcome / capability disclosure\n// ============================================================================\n\n/**\n * Example prompts as a single auto-advancing line.\n *\n * They used to wrap into a block several rows tall, which on a phone pushed everything below\n * it — including the composer — off the screen. One line costs a fixed ~40px no matter how\n * many prompts there are, and rotating through them keeps every prompt reachable without a\n * \"show more\".\n *\n * Autoplay pauses on hover and on keyboard focus, and never starts at all for visitors who\n * asked for reduced motion — for them the arrows are the whole interaction.\n */\nfunction PromptCarousel({\n prompts,\n onPrompt,\n disabled,\n}: {\n prompts: string[];\n onPrompt: (prompt: string) => void;\n disabled: boolean;\n}) {\n const [index, setIndex] = useState(0);\n const [paused, setPaused] = useState(false);\n\n const count = prompts.length;\n const current = prompts[index % count] ?? prompts[0] ?? \"\";\n\n const go = useCallback(\n (delta: number) => {\n setIndex((i) => (i + delta + count) % count);\n },\n [count],\n );\n\n useEffect(() => {\n if (paused || disabled || count < 2) return;\n if (\n typeof window !== \"undefined\" &&\n window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches\n ) {\n return;\n }\n const timer = setInterval(() => setIndex((i) => (i + 1) % count), 4500);\n return () => clearInterval(timer);\n }, [paused, disabled, count]);\n\n if (count === 0) return null;\n\n return (\n <div\n className=\"flex min-w-0 items-center gap-1.5\"\n role=\"group\"\n aria-roledescription=\"carousel\"\n aria-label=\"Example questions\"\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocusCapture={() => setPaused(true)}\n onBlurCapture={() => setPaused(false)}\n >\n {count > 1 ? (\n <button\n type=\"button\"\n aria-label=\"Previous suggestion\"\n onClick={() => go(-1)}\n className=\"hidden h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:inline-flex\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </button>\n ) : null}\n\n <button\n key={current}\n data-boff-explore=\"chip\"\n data-chip-kind=\"prompt\"\n type=\"button\"\n disabled={disabled}\n aria-label={`Ask: ${current}`}\n aria-live={paused ? \"polite\" : \"off\"}\n onClick={() => onPrompt(current)}\n /* min-w-0 + truncate is what keeps a long prompt from widening the page. */\n className=\"boff-explore-fade group flex min-w-0 flex-1 items-center gap-2 rounded-full border border-border bg-card px-4 py-2 text-left text-sm text-card-foreground shadow-sm transition-colors hover:border-primary/50 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <Sparkles className=\"h-3.5 w-3.5 shrink-0 text-primary\" />\n <span className=\"truncate\">{current}</span>\n <ArrowUp className=\"ml-auto h-3.5 w-3.5 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary\" />\n </button>\n\n {count > 1 ? (\n <button\n type=\"button\"\n aria-label=\"Next suggestion\"\n onClick={() => go(1)}\n className=\"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n );\n}\n\n/**\n * Product focus chips on one line, expandable.\n *\n * Collapsed is a single clipped row; expanded wraps to the full set. The row scrolls inside\n * itself rather than pushing the page wide — `overflow-x-auto` on a `min-w-0` flex child is\n * contained, and the scrollbar is hidden so it reads as a strip, not a scroller.\n */\nfunction ProductStrip({\n products,\n focusProduct,\n onFocus,\n}: {\n products: Array<{ slug: string; name: string; tagline?: string | null }>;\n focusProduct: string | null;\n onFocus: (slug: string | null) => void;\n}) {\n const [expanded, setExpanded] = useState(false);\n\n const chipClass = (active: boolean) =>\n cn(\n \"shrink-0 rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n );\n\n return (\n <div\n className=\"flex min-w-0 items-center gap-2\"\n role=\"group\"\n aria-label=\"Focus the assistant on one product\"\n >\n <div\n className={cn(\n \"boff-explore-strip flex min-w-0 flex-1 gap-2\",\n expanded ? \"flex-wrap\" : \"flex-nowrap overflow-x-auto\",\n )}\n >\n <button\n data-boff-explore=\"chip\"\n data-chip-kind=\"product\"\n data-product=\"all\"\n type=\"button\"\n aria-pressed={focusProduct === null}\n onClick={() => onFocus(null)}\n className={chipClass(focusProduct === null)}\n >\n All products\n </button>\n {products.map((product) => (\n <button\n key={product.slug}\n data-boff-explore=\"chip\"\n data-chip-kind=\"product\"\n data-product={product.slug}\n type=\"button\"\n aria-pressed={focusProduct === product.slug}\n title={product.tagline ?? product.name}\n onClick={() =>\n onFocus(focusProduct === product.slug ? null : product.slug)\n }\n className={chipClass(focusProduct === product.slug)}\n >\n {product.name}\n </button>\n ))}\n </div>\n {products.length > 0 ? (\n <button\n type=\"button\"\n data-boff-explore=\"products-toggle\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n className=\"shrink-0 whitespace-nowrap rounded-full px-2 py-1 text-xs font-medium text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n {expanded ? \"Show less\" : `All ${products.length}`}\n </button>\n ) : null}\n </div>\n );\n}\n\n/**\n * The storage notice, behind a link.\n *\n * It has to be said — conversations really are kept — but as three permanent sentences under\n * the composer it was the largest thing on a phone screen. A link plus a dialog says the same\n * thing and costs one line.\n *\n * Hand-rolled rather than a Radix dialog: `@radix-ui/react-dialog` is not among the SDK's peer\n * dependencies, and adding one would mean an install across all 39 consuming sites for a\n * single popup.\n */\nfunction DisclaimerDialog({\n open,\n onClose,\n captchaOn,\n}: {\n open: boolean;\n onClose: () => void;\n captchaOn: boolean;\n}) {\n const panelRef = useRef<HTMLDivElement>(null);\n const closeRef = useRef<HTMLButtonElement>(null);\n const titleId = \"boff-explore-disclaimer-title\";\n\n useEffect(() => {\n if (!open) return;\n\n // Remember where focus came from so it can be handed back — a dialog that dumps focus\n // at the top of the document strands a keyboard or screen-reader user.\n const opener =\n document.activeElement instanceof HTMLElement\n ? document.activeElement\n : null;\n\n // Deliberately NOT filtered by `offsetParent !== null`. That is the usual visibility\n // test, but offsetParent is null for elements inside a `position: fixed` container —\n // which this dialog is — so the filter silently emptied the list and the trap never\n // engaged. The panel only exists while open and holds nothing hidden, so every match\n // here is focusable by construction.\n const focusable = () =>\n Array.from(\n panelRef.current?.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex=\"-1\"])',\n ) ?? [],\n );\n\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n return;\n }\n // Focus trap. Without it Tab walks straight out of the dialog and onto the page\n // behind the overlay, where the visitor cannot see what is focused.\n if (event.key !== \"Tab\") return;\n const items = focusable();\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n if (\n event.shiftKey &&\n (active === first || !panelRef.current?.contains(active))\n ) {\n event.preventDefault();\n last?.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first?.focus();\n }\n };\n\n document.addEventListener(\"keydown\", onKey);\n closeRef.current?.focus();\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n opener?.focus();\n };\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <div\n data-boff-explore=\"disclaimer-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className=\"fixed inset-0 z-50 flex items-end justify-center bg-foreground/40 p-4 backdrop-blur-sm sm:items-center\"\n onClick={onClose}\n >\n <div\n ref={panelRef}\n className=\"w-full max-w-md rounded-2xl border border-border bg-card p-5 shadow-xl\"\n onClick={(event) => event.stopPropagation()}\n >\n <div className=\"flex items-start gap-3\">\n <span\n aria-hidden=\"true\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\"\n >\n <TriangleAlert className=\"h-4 w-4\" />\n </span>\n <div className=\"min-w-0\">\n <p\n id={titleId}\n className=\"text-sm font-semibold text-card-foreground\"\n >\n How this assistant works\n </p>\n <div className=\"mt-2 space-y-2 text-xs leading-relaxed text-muted-foreground\">\n <p>\n Answers are generated from our public documentation and can be\n imperfect — check anything important against the linked sources.\n </p>\n {/* Conversations are recorded server-side, so say so plainly. */}\n <p>\n Conversations are saved in this browser so you can come back to\n them, and are also stored on our servers to help us improve\n these answers. Please don't share personal or confidential\n information.\n </p>\n {captchaOn ? (\n <p>\n Protected by reCAPTCHA — the Google Privacy Policy and Terms\n of Service apply.\n </p>\n ) : null}\n </div>\n </div>\n </div>\n <div className=\"mt-4 flex justify-end\">\n <Button\n ref={closeRef}\n size=\"sm\"\n variant=\"secondary\"\n onClick={onClose}\n >\n Got it\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction WelcomeState({\n title,\n body,\n prompts,\n products,\n focusProduct,\n onPrompt,\n onFocus,\n disabled,\n}: {\n title: string;\n body: string;\n prompts: string[];\n products: Array<{ slug: string; name: string; tagline?: string | null }>;\n focusProduct: string | null;\n onPrompt: (prompt: string) => void;\n onFocus: (slug: string | null) => void;\n disabled: boolean;\n}) {\n return (\n <div className=\"mx-auto w-full max-w-3xl px-4 py-8 sm:py-12\">\n <div className=\"text-center\">\n <span className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted px-3 py-1 text-xs font-medium text-muted-foreground\">\n <Sparkles className=\"h-3.5 w-3.5\" />\n AI answers, grounded in our documentation\n </span>\n {/* Rendered synchronously on the first paint — the static prerender\n waits for an <h1> and must never capture a blank page. */}\n <h1 className=\"mt-4 text-balance break-words text-2xl font-bold tracking-tight sm:text-4xl\">\n {title}\n </h1>\n <p className=\"mx-auto mt-2.5 max-w-2xl text-pretty text-sm leading-relaxed text-muted-foreground sm:text-lg\">\n {body}\n </p>\n </div>\n\n <ul className=\"mt-7 grid gap-2.5 sm:grid-cols-3\">\n {CAPABILITIES.map(({ icon: Icon, title: capTitle, body: capBody }) => (\n <li\n key={capTitle}\n className=\"rounded-xl border border-border/70 bg-card/60 p-3.5 text-left transition-colors hover:border-border\"\n >\n <span className=\"mb-2.5 flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <Icon className=\"h-4 w-4\" />\n </span>\n <p className=\"text-sm font-semibold text-card-foreground\">\n {capTitle}\n </p>\n <p className=\"mt-1 text-xs leading-relaxed text-muted-foreground\">\n {capBody}\n </p>\n </li>\n ))}\n </ul>\n\n {prompts.length > 0 ? (\n <div className=\"mt-8\">\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Try asking\n </p>\n <PromptCarousel\n prompts={prompts}\n onPrompt={onPrompt}\n disabled={disabled}\n />\n </div>\n ) : null}\n\n {products.length > 0 ? (\n <div className=\"mt-6\">\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Focus on a product\n </p>\n <ProductStrip\n products={products}\n focusProduct={focusProduct}\n onFocus={onFocus}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\n// ============================================================================\n// Main component\n// ============================================================================\n\nexport function ExplorePage({\n seo,\n productSlug,\n examplePrompts,\n className,\n heightMode = \"viewport\",\n viewportOffset,\n onNavigate,\n onSend,\n welcomeTitle,\n welcomeBody,\n}: ExplorePageProps) {\n const pageUrl = useMemo(\n () => (typeof window === \"undefined\" ? undefined : window.location.href),\n [],\n );\n\n const {\n phase,\n catalog,\n messages,\n activity,\n remainingToday,\n error,\n focusProduct,\n setFocusProduct,\n send,\n stop,\n retry,\n reset,\n canSend,\n history,\n openConversation,\n deleteConversation,\n clearHistory,\n recordClick,\n createShareLink,\n } = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });\n\n const [draft, setDraft] = useState(\"\");\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Dictation, on the browser's own recogniser. Settled speech is appended to whatever is\n // already typed, so a visitor can mix typing and talking in one message.\n const [historyOpen, setHistoryOpen] = useState(false);\n\n const speechStopRef = useRef<() => void>(() => undefined);\n const stopDictation = useCallback(() => {\n speechStopRef.current();\n }, []);\n\n const speech = useSpeechInput({\n onFinalTranscript: (text) => {\n setDraft((current) => {\n const joined =\n current.trim() === \"\"\n ? text.trimStart()\n : `${current.trimEnd()} ${text.trim()}`;\n return joined;\n });\n textareaRef.current?.focus();\n },\n });\n speechStopRef.current = speech.stop;\n const [disclaimerOpen, setDisclaimerOpen] = useState(false);\n const [shareLabel, setShareLabel] = useState(\"Share\");\n const [shareUrl, setShareUrl] = useState<string | null>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const latestAssistantRef = useRef<HTMLDivElement>(null);\n /** id of the answer whose top has already been aligned, so it happens once per turn. */\n const alignedForRef = useRef<string | null>(null);\n const stickToBottomRef = useRef(true);\n const composingRef = useRef(false);\n\n const busy = phase === \"sending\" || phase === \"streaming\";\n const showWelcome = messages.length === 0;\n const maxLength = catalog.limits.maxMessageLength;\n const overLimit = draft.length > maxLength;\n const canSubmit = canSend && draft.trim().length > 0 && !overLimit && !busy;\n\n const resolvedTitle = welcomeTitle ?? catalog.welcomeTitle;\n const resolvedBody = welcomeBody ?? catalog.welcomeBody;\n // Resolution order (catalog → prop → SDK built-in) lives in the hook, which\n // seeds its fallback catalog from the `examplePrompts` prop.\n const prompts = catalog.examplePrompts;\n\n const focusedProductName = useMemo(\n () => catalog.products.find((p) => p.slug === focusProduct)?.name ?? null,\n [catalog.products, focusProduct],\n );\n\n // --- auto-grow the composer -------------------------------------------\n useEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n el.style.height = `${Math.min(el.scrollHeight, 200)}px`;\n }, [draft]);\n\n // --- transcript positioning --------------------------------------------\n //\n // An answer plus its sources is routinely taller than a phone screen, so pinning the\n // transcript to the BOTTOM landed the visitor below the sources and made them scroll up\n // to find the response they had just asked for. Instead each new answer is anchored by\n // its TOP: the reply starts where the eye already is and grows downward.\n //\n // Bottom-sticking is kept only for the pre-answer phase, so the \"thinking\" indicator\n // stays visible while the turn is still running.\n const handleScroll = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n stickToBottomRef.current =\n el.scrollHeight - el.scrollTop - el.clientHeight < 80;\n }, []);\n\n const latestAssistantId = useMemo(() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message && message.role === \"ASSISTANT\") return message.id;\n }\n return null;\n }, [messages]);\n\n useEffect(() => {\n const el = scrollRef.current;\n const anchor = latestAssistantRef.current;\n if (!el || !anchor || !latestAssistantId) return;\n\n // Only align once per answer, and never against a visitor who has scrolled away to\n // read something else — yanking the viewport out from under them is worse than the\n // problem this solves.\n if (alignedForRef.current === latestAssistantId) return;\n if (!stickToBottomRef.current) return;\n\n // Wait for the answer to actually have height; aligning an empty bubble puts the top\n // of a zero-height element at the top of an otherwise blank transcript.\n if (anchor.offsetHeight === 0) return;\n\n alignedForRef.current = latestAssistantId;\n // Measured as a rect delta rather than via `offsetTop`: offsetTop is relative to the\n // nearest POSITIONED ancestor, and this scroll container is not positioned, so it would\n // resolve against something further up the page and land in the wrong place.\n // `scrollIntoView` is also wrong here — on mobile it scrolls the page as well as the\n // container, dragging the composer off-screen.\n const delta =\n anchor.getBoundingClientRect().top - el.getBoundingClientRect().top;\n el.scrollTop = Math.max(0, el.scrollTop + delta - 12);\n }, [latestAssistantId, messages]);\n\n // While the turn is still running there is no answer to anchor yet, so keep the thinking\n // indicator in view the old way.\n useEffect(() => {\n if (!stickToBottomRef.current) return;\n if (latestAssistantId && alignedForRef.current === latestAssistantId)\n return;\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [activity, latestAssistantId, messages]);\n\n /**\n * Copy a read-only link to this conversation.\n *\n * The URL carries a share secret, never the conversation token — that one also authorises\n * posting, so a forwarded link built from it would let the recipient continue someone\n * else's thread. Feedback is the button label itself, because a toast renderer is not\n * guaranteed to be mounted on every host site.\n */\n const handleShare = useCallback(async () => {\n setShareLabel(\"Copying…\");\n setShareUrl(null);\n const token = await createShareLink();\n if (!token) {\n setShareLabel(\"Unavailable\");\n setTimeout(() => setShareLabel(\"Share\"), 2500);\n return;\n }\n // `pageUrl` is undefined during SSR/prerender, but this only runs from a click, so\n // window is present; fall back rather than assert.\n const base = (pageUrl ?? window.location.href).split(\"?\")[0];\n const url = `${base}?c=${encodeURIComponent(token)}`;\n try {\n await navigator.clipboard.writeText(url);\n setShareLabel(\"Copied\");\n setTimeout(() => setShareLabel(\"Share\"), 2500);\n } catch {\n // The clipboard needs a secure context and a live gesture, and can simply be refused.\n // Show the link so the visitor can copy it by hand — a click that appears to do\n // nothing is worse than one extra step.\n setShareUrl(url);\n setShareLabel(\"Share\");\n }\n }, [createShareLink, pageUrl]);\n\n // --- send --------------------------------------------------------------\n const submitDraft = useCallback(() => {\n const text = draft.trim();\n if (!text || overLimit || busy || !canSend) return;\n // Close the microphone on send — leaving it hot would keep dictating into the next message.\n stopDictation();\n setDraft(\"\");\n stickToBottomRef.current = true;\n void send(text);\n textareaRef.current?.focus();\n }, [busy, canSend, draft, overLimit, send, stopDictation]);\n\n const sendPrompt = useCallback(\n (prompt: string) => {\n if (!canSend || busy) return;\n setDraft(\"\");\n stickToBottomRef.current = true;\n void send(prompt);\n },\n [busy, canSend, send],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key !== \"Enter\" || event.shiftKey) return;\n // IME safety: while a CJK/other candidate window is open, Enter commits\n // the candidate and must not send the message.\n if (composingRef.current || event.nativeEvent.isComposing) return;\n event.preventDefault();\n submitDraft();\n },\n [submitDraft],\n );\n\n const composerDisabled =\n phase === \"limited\" || phase === \"disabled\" || !catalog.enabled;\n const captchaOn = Boolean(\n catalog.captchaRequired && catalog.recaptchaSiteKey,\n );\n\n const rootStyle =\n heightMode === \"viewport\"\n ? { height: `calc(100dvh - ${normalizeOffset(viewportOffset)})` }\n : undefined;\n\n return (\n <div\n data-boff-explore=\"page\"\n data-phase={phase}\n className={cn(\n \"flex w-full min-w-0 flex-col overflow-x-hidden bg-background text-foreground\",\n heightMode === \"auto\" && \"min-h-[70vh]\",\n className,\n )}\n style={rootStyle}\n >\n {seo ? (\n <PageHead\n title={seo.title ?? \"Explore — ask anything about our products\"}\n description={\n seo.description ??\n \"Ask questions in plain English and get answers drawn from our product documentation, with links to the exact pages they came from.\"\n }\n keywords={seo.keywords}\n image={seo.image}\n url={seo.url}\n />\n ) : null}\n <ProseStyles />\n <ExploreStyles />\n\n {/* Compact header in conversation mode — keeps exactly one <h1> on the\n page whichever state we are in. */}\n {!showWelcome ? (\n <div className=\"flex items-center gap-2.5 border-b border-border px-4 py-2.5\">\n <span\n aria-hidden=\"true\"\n className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary\"\n >\n <Sparkles className=\"h-4 w-4\" />\n </span>\n <h1 className=\"truncate text-sm font-semibold\">{resolvedTitle}</h1>\n {focusedProductName ? (\n <span className=\"hidden shrink-0 rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground sm:inline\">\n {focusedProductName}\n </span>\n ) : null}\n <Button\n data-boff-explore=\"new-chat\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"ml-auto shrink-0 text-muted-foreground\"\n onClick={reset}\n >\n <RotateCcw className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">New chat</span>\n </Button>\n {messages.length > 0 ? (\n <Button\n data-boff-explore=\"share\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"shrink-0 text-muted-foreground\"\n title=\"Copy a read-only link to this conversation\"\n onClick={() => {\n void handleShare();\n }}\n >\n <Link2 className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">{shareLabel}</span>\n </Button>\n ) : null}\n {history.length > 0 ? (\n <Button\n data-boff-explore=\"history-toggle\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"shrink-0 text-muted-foreground\"\n aria-expanded={historyOpen}\n onClick={() => {\n setHistoryOpen((open) => !open);\n }}\n >\n <HistoryIcon className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">\n History ({history.length})\n </span>\n </Button>\n ) : null}\n </div>\n ) : null}\n\n {/* Past conversations, held in this browser only. */}\n {historyOpen && history.length > 0 ? (\n <div\n data-boff-explore=\"history-panel\"\n className=\"border-b border-border bg-muted/30 px-4 py-3\"\n >\n <div className=\"mx-auto w-full max-w-3xl\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Your recent conversations\n </p>\n <Button\n data-boff-explore=\"history-clear\"\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-7 shrink-0 text-xs text-muted-foreground hover:text-destructive\"\n onClick={() => {\n clearHistory();\n setHistoryOpen(false);\n }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n Clear history\n </Button>\n </div>\n <ul className=\"space-y-1\">\n {history.map((entry) => (\n <li key={entry.token} className=\"flex items-center gap-1\">\n <button\n data-boff-explore=\"history-item\"\n type=\"button\"\n className=\"flex-1 truncate rounded-md px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground\"\n onClick={() => {\n openConversation(entry.token);\n setHistoryOpen(false);\n }}\n >\n <span className=\"truncate\">{entry.title}</span>\n <span className=\"ml-2 text-xs text-muted-foreground\">\n {entry.messageCount} message\n {entry.messageCount === 1 ? \"\" : \"s\"}\n </span>\n </button>\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-7 w-7 shrink-0 text-muted-foreground hover:text-destructive\"\n aria-label={`Delete conversation: ${entry.title}`}\n onClick={() => {\n deleteConversation(entry.token);\n }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </li>\n ))}\n </ul>\n </div>\n </div>\n ) : null}\n\n {/* Transcript */}\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n data-boff-explore=\"messages\"\n role=\"log\"\n aria-live=\"polite\"\n aria-label=\"Explore conversation\"\n className=\"boff-explore-scroll min-h-0 min-w-0 flex-1 overflow-y-auto overflow-x-hidden\"\n >\n {showWelcome ? (\n <WelcomeState\n title={resolvedTitle}\n body={resolvedBody}\n prompts={prompts}\n products={catalog.products}\n focusProduct={focusProduct}\n onPrompt={sendPrompt}\n onFocus={setFocusProduct}\n disabled={!canSend || busy}\n />\n ) : (\n <div className=\"mx-auto w-full min-w-0 max-w-3xl space-y-6 px-4 py-6\">\n {messages.map((message) =>\n message.role === \"USER\" ? (\n <UserBubble key={message.id} message={message} />\n ) : (\n <AssistantBubble\n key={message.id}\n message={message}\n activity={activity}\n onNavigate={onNavigate}\n anchorRef={\n message.id === latestAssistantId\n ? latestAssistantRef\n : undefined\n }\n onFollow={(kind, url) => recordClick(message.id, kind, url)}\n onFollowUp={sendPrompt}\n />\n ),\n )}\n </div>\n )}\n </div>\n\n <DisclaimerDialog\n open={disclaimerOpen}\n onClose={() => setDisclaimerOpen(false)}\n captchaOn={captchaOn}\n />\n\n {/* Composer */}\n <div className=\"border-t border-border bg-background/85 px-4 pb-[max(1rem,env(safe-area-inset-bottom))] pt-3 backdrop-blur-md\">\n <form\n data-boff-explore=\"composer\"\n className=\"mx-auto w-full max-w-3xl\"\n onSubmit={(event) => {\n event.preventDefault();\n submitDraft();\n }}\n >\n {error ? (\n <ErrorBanner error={error} onRetry={retry} onReset={reset} />\n ) : null}\n\n <div\n className={cn(\n \"flex min-w-0 items-end gap-2 rounded-2xl border bg-card p-2 shadow-sm transition-all\",\n overLimit\n ? \"border-destructive/60\"\n : \"border-border focus-within:border-primary/40 focus-within:ring-1 focus-within:ring-ring\",\n )}\n >\n <Textarea\n ref={textareaRef}\n value={draft}\n rows={1}\n disabled={composerDisabled}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onCompositionStart={() => {\n composingRef.current = true;\n }}\n onCompositionEnd={() => {\n composingRef.current = false;\n }}\n aria-label=\"Ask a question\"\n placeholder={\n composerDisabled\n ? phase === \"limited\"\n ? \"Message limit reached — please try again later\"\n : \"Explore is unavailable right now\"\n : focusedProductName\n ? `Ask about ${focusedProductName}…`\n : \"Ask anything about our products…\"\n }\n className=\"max-h-[200px] min-h-[44px] w-full min-w-0 flex-1 resize-none border-0 bg-transparent px-2 py-2.5 text-sm shadow-none focus-visible:ring-0 md:text-sm\"\n />\n {speech.supported ? (\n <Button\n data-boff-explore=\"mic\"\n data-listening={speech.listening ? \"true\" : \"false\"}\n type=\"button\"\n size=\"icon\"\n variant={speech.listening ? \"default\" : \"ghost\"}\n disabled={composerDisabled}\n aria-label={\n speech.listening ? \"Stop dictating\" : \"Dictate your question\"\n }\n aria-pressed={speech.listening}\n title={\n speech.listening ? \"Stop dictating\" : \"Dictate your question\"\n }\n onClick={speech.toggle}\n className={cn(speech.listening && \"animate-pulse\")}\n >\n <Mic className=\"h-4 w-4\" />\n </Button>\n ) : null}\n {busy ? (\n <Button\n data-boff-explore=\"stop\"\n type=\"button\"\n size=\"icon\"\n variant=\"secondary\"\n aria-label=\"Stop generating\"\n onClick={stop}\n >\n <Square className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n data-boff-explore=\"send\"\n type=\"submit\"\n size=\"icon\"\n disabled={!canSubmit}\n aria-label=\"Send message\"\n >\n <ArrowUp className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n\n {speech.listening || speech.interim !== \"\" ? (\n <p\n data-boff-explore=\"dictation\"\n className=\"mt-2 flex items-center gap-2 text-xs text-muted-foreground\"\n aria-live=\"polite\"\n >\n <span className=\"relative flex h-2 w-2 shrink-0\">\n <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-primary opacity-75\" />\n <span className=\"relative inline-flex h-2 w-2 rounded-full bg-primary\" />\n </span>\n <span className=\"italic\">\n {speech.interim !== \"\" ? speech.interim : \"Listening…\"}\n </span>\n </p>\n ) : null}\n {speech.error !== null ? (\n <p\n data-boff-explore=\"dictation-error\"\n className=\"mt-2 text-xs text-destructive\"\n >\n {speech.error}\n </p>\n ) : null}\n\n <div className=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"hidden sm:inline\">\n Enter to send · Shift + Enter for a new line\n </span>\n {remainingToday !== null ? (\n <span data-boff-explore=\"remaining\">\n {remainingToday} message{remainingToday === 1 ? \"\" : \"s\"} left\n today\n </span>\n ) : null}\n <span\n className={cn(\n \"ml-auto tabular-nums\",\n overLimit && \"font-medium text-destructive\",\n )}\n >\n {draft.length.toLocaleString()} / {maxLength.toLocaleString()}\n </span>\n </div>\n\n {/* One line instead of three sentences. The notice still has to be said — the\n conversation really is stored — but as permanent body copy it was the tallest\n thing on a phone screen, directly under the control people came here to use. */}\n {shareUrl ? (\n <div className=\"mt-2 flex items-center gap-2\">\n <input\n data-boff-explore=\"share-url\"\n readOnly\n value={shareUrl}\n aria-label=\"Read-only link to this conversation\"\n onFocus={(event) => event.currentTarget.select()}\n className=\"min-w-0 flex-1 rounded-md border border-border bg-muted px-2 py-1 text-xs text-muted-foreground\"\n />\n <button\n type=\"button\"\n className=\"shrink-0 text-xs underline underline-offset-2\"\n onClick={() => setShareUrl(null)}\n >\n Done\n </button>\n </div>\n ) : null}\n\n <div className=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"min-w-0 truncate\">\n Grounded in our docs — check anything important.\n </span>\n <button\n type=\"button\"\n data-boff-explore=\"disclaimer\"\n onClick={() => setDisclaimerOpen(true)}\n className=\"shrink-0 underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n Disclaimer\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"]}
|