@burdenoff/website-sdk 2026.1101.3 → 2026.1102.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +234 -14
  2. package/dist/avatar-live-view/index.d.mts +1 -1
  3. package/dist/avatar-live-view/index.d.ts +1 -1
  4. package/dist/avatar-live-view/index.js +71 -24
  5. package/dist/avatar-live-view/index.js.map +1 -1
  6. package/dist/avatar-live-view/index.mjs +69 -22
  7. package/dist/avatar-live-view/index.mjs.map +1 -1
  8. package/dist/{chunk-Y4V5CEWD.mjs → chunk-2LPDCXQH.mjs} +7 -4
  9. package/dist/chunk-2LPDCXQH.mjs.map +1 -0
  10. package/dist/{chunk-FFADMVIK.mjs → chunk-ETI2HQEC.mjs} +7 -5
  11. package/dist/chunk-ETI2HQEC.mjs.map +1 -0
  12. package/dist/{chunk-23H4JUL4.js → chunk-OIQHIGGU.js} +20 -3
  13. package/dist/chunk-OIQHIGGU.js.map +1 -0
  14. package/dist/{chunk-OYEUNZJY.js → chunk-PIXTBL63.js} +7 -3
  15. package/dist/chunk-PIXTBL63.js.map +1 -0
  16. package/dist/{chunk-BX2USEWF.mjs → chunk-QOHPLTGT.mjs} +19 -4
  17. package/dist/chunk-QOHPLTGT.mjs.map +1 -0
  18. package/dist/{chunk-O76QDGRM.js → chunk-R742FS5E.js} +8 -4
  19. package/dist/chunk-R742FS5E.js.map +1 -0
  20. package/dist/components/explore-cta.d.mts +7 -0
  21. package/dist/components/explore-cta.d.ts +7 -0
  22. package/dist/components/explore-cta.js +2 -2
  23. package/dist/components/explore-cta.mjs +1 -1
  24. package/dist/components/explore.js +13 -13
  25. package/dist/components/explore.mjs +1 -1
  26. package/dist/{explore-avatar-live-config-B171o1Yo.d.ts → explore-avatar-live-config-C1ILEcY8.d.ts} +16 -4
  27. package/dist/{explore-avatar-live-config-BGsGwbcq.d.mts → explore-avatar-live-config-D-hO90-A.d.mts} +16 -4
  28. package/dist/index.d.mts +107 -4
  29. package/dist/index.d.ts +107 -4
  30. package/dist/index.js +209 -43
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +173 -7
  33. package/dist/index.mjs.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/chunk-23H4JUL4.js.map +0 -1
  36. package/dist/chunk-BX2USEWF.mjs.map +0 -1
  37. package/dist/chunk-FFADMVIK.mjs.map +0 -1
  38. package/dist/chunk-O76QDGRM.js.map +0 -1
  39. package/dist/chunk-OYEUNZJY.js.map +0 -1
  40. package/dist/chunk-Y4V5CEWD.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/careers.tsx","../src/components/careers-submission.tsx","../src/components/concepts-types.ts","../src/components/concept-lightbox.tsx","../src/components/concepts.tsx","../src/components/answers-i18n.ts","../src/components/answers-types.ts","../src/components/answers.tsx","../src/components/explore-avatar-live.tsx","../src/components/explore-panel.tsx"],"names":["useRef","useState","toast","jsxs","jsx","CheckCircle","Fragment","ReCAPTCHA","Send","reactVersion","Info","useId","useCallback","useEffect","ChevronRight","META_DESCRIPTION_LIMIT","RELATED_LIMIT","normaliseSiteUrl","absoluteUrl","sortByOrder","clampText","slugifyAnchor","searchTokens","matchesSearch","copyKey","FilterChip","useMemo","Search","SECTION_HEADING","CHIP","ExternalLink","ArrowLeft","ArrowRight","useContext","open","onOpenChange","attempt","Maximize2","X"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\";\n\n/**\n * Careers Apply Form\n *\n * Public job-application form for product careers pages (e.g.\n * burdenoff.com/careers). Mirrors `ContactPage` — reCAPTCHA-gated submit via\n * the WebSDKClient — plus a resume upload. The resume is read client-side and\n * sent as base64 in the `submitJobApplication` mutation; the backend uploads it\n * to a private bucket server-side (no public presign endpoint).\n *\n * @example\n * ```tsx\n * <CareersApplyForm\n * productName=\"VibeControls\"\n * positions={[\"Senior Engineer\", \"Product Designer\"]}\n * />\n * ```\n */\n\nimport { useRef, useState } from \"react\";\n\nimport { CheckCircle, Send, Upload } from \"lucide-react\";\nimport ReCAPTCHA from \"react-google-recaptcha\";\nimport { toast } from \"sonner\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { useProduct } from \"../product/product-provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Textarea } from \"../ui/textarea\";\n\nimport type { WebSDKClient } from \"../client/graphql-client\";\n\n// Resumes only — must match the backend allow-list (PDF/DOC/DOCX).\nconst ALLOWED_RESUME_TYPES: Record<string, string> = {\n \"application/pdf\": \"PDF\",\n \"application/msword\": \"DOC\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"DOCX\",\n};\n// Some browsers/OSes report an empty or generic `file.type` for valid\n// .doc/.docx uploads. Fall back to the file extension → canonical MIME so the\n// upload validates client-side AND the backend (which checks `contentType`)\n// accepts it.\nconst EXT_TO_MIME: Record<string, string> = {\n pdf: \"application/pdf\",\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n};\nconst DEFAULT_MAX_RESUME_BYTES = 10 * 1024 * 1024; // 10MB — matches backend cap\n\n/** Resolve a canonical resume MIME from `file.type`, falling back to extension. */\nfunction resolveResumeType(file: File): string | null {\n if (ALLOWED_RESUME_TYPES[file.type]) return file.type;\n const ext = file.name.split(\".\").pop()?.toLowerCase();\n return ext && EXT_TO_MIME[ext] ? EXT_TO_MIME[ext] : null;\n}\n\n/** A job posting option for the CareersApplyForm dropdown. */\nexport interface CareersPostingOption {\n /** Posting ID — sent as `jobPostingId` in the application input. */\n id: string;\n /** Display title — also sent as the `position` string. */\n title: string;\n}\n\nexport interface CareersApplyFormProps {\n /** Product name (falls back to product context / SDK config). */\n productName?: string;\n /** reCAPTCHA site key (falls back to SDK config). */\n recaptchaSiteKey?: string;\n /**\n * Position options for the dropdown. When empty, a free-text \"position\"\n * input is shown instead so the form works before a postings list exists.\n */\n positions?: readonly string[];\n /**\n * Job postings for the dropdown (e.g. from `usePublicJobPostings`). When\n * non-empty this takes precedence over `positions`: the selected posting's\n * title is sent as `position` and its ID as `jobPostingId` so the\n * application is linked to the posting.\n */\n postings?: readonly CareersPostingOption[];\n heroTitle?: string;\n heroDescription?: string;\n /**\n * `1` (default) renders a full page hero `<h1>`; `2` renders a compact\n * `<h2>` section header for embedding under a page that owns the `<h1>`.\n */\n headingLevel?: 1 | 2;\n /** Max resume size in bytes (default 10MB, matches backend). */\n maxResumeBytes?: number;\n className?: string;\n seo?: { title?: string; description?: string; keywords?: string };\n}\n\nconst SUBMIT_JOB_APPLICATION_MUTATION = /* GraphQL */ `\n mutation SubmitJobApplication($input: SubmitJobApplicationInput!) {\n submitJobApplication(input: $input) {\n success\n message\n }\n }\n`;\n\ninterface JobApplicationData {\n firstName: string;\n lastName: string;\n email: string;\n phone?: string;\n position: string;\n /** Linked job posting ID — included only when a posting was selected. */\n jobPostingId?: string;\n linkedinUrl?: string;\n portfolioUrl?: string;\n coverLetter?: string;\n resumeBase64: string;\n resumeFileName: string;\n resumeContentType: string;\n recaptchaToken?: string;\n}\n\n/** Read a File as raw base64 (strips the `data:...;base64,` prefix). */\nfunction fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = typeof reader.result === \"string\" ? reader.result : \"\";\n const comma = result.indexOf(\",\");\n resolve(comma >= 0 ? result.slice(comma + 1) : result);\n };\n reader.onerror = () => reject(new Error(\"Failed to read the resume file\"));\n reader.readAsDataURL(file);\n });\n}\n\nasync function submitApplication(\n client: WebSDKClient,\n data: JobApplicationData,\n productId: string,\n): Promise<{ success: boolean; message?: string }> {\n try {\n const result = await client.mutate<{\n submitJobApplication: { success: boolean; message: string };\n }>(SUBMIT_JOB_APPLICATION_MUTATION, {\n input: {\n firstName: data.firstName,\n lastName: data.lastName,\n email: data.email.trim().toLowerCase(),\n position: data.position,\n resumeBase64: data.resumeBase64,\n resumeFileName: data.resumeFileName,\n resumeContentType: data.resumeContentType,\n productId,\n ...(data.phone ? { phone: data.phone } : {}),\n ...(data.linkedinUrl ? { linkedinUrl: data.linkedinUrl } : {}),\n ...(data.portfolioUrl ? { portfolioUrl: data.portfolioUrl } : {}),\n ...(data.coverLetter ? { coverLetter: data.coverLetter } : {}),\n ...(data.jobPostingId ? { jobPostingId: data.jobPostingId } : {}),\n ...(data.recaptchaToken ? { recaptchaToken: data.recaptchaToken } : {}),\n },\n });\n\n if (result.errors?.length) {\n return {\n success: false,\n message: result.errors[0]?.message ?? \"Failed to submit application\",\n };\n }\n const response = result.data?.submitJobApplication;\n return response?.success\n ? { success: true, message: response.message || \"Application submitted!\" }\n : {\n success: false,\n message: response?.message || \"Failed to submit application\",\n };\n } catch (error) {\n console.error(\"Job application submission error:\", error);\n return { success: false, message: \"Network error. Please try again.\" };\n }\n}\n\nexport function CareersApplyForm({\n productName,\n recaptchaSiteKey,\n positions = [],\n postings = [],\n heroTitle = \"Become a part of the team\",\n heroDescription = \"Tell us about yourself and upload your resume — we'll be in touch.\",\n headingLevel = 1,\n maxResumeBytes = DEFAULT_MAX_RESUME_BYTES,\n className,\n seo,\n}: CareersApplyFormProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const resolvedProductId = product?.id || config.productId;\n const displayName = productName ?? product?.name ?? config.productId;\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n product?.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [resumeFile, setResumeFile] = useState<File | null>(null);\n const [resumeType, setResumeType] = useState<string | null>(null);\n const [resumeError, setResumeError] = useState<string | null>(null);\n\n const maxMb = Math.floor(maxResumeBytes / (1024 * 1024));\n\n const clearResume = (): void => {\n setResumeFile(null);\n setResumeType(null);\n };\n\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n setResumeError(null);\n const file = e.target.files?.[0] ?? null;\n if (!file) {\n clearResume();\n return;\n }\n const type = resolveResumeType(file);\n if (!type) {\n clearResume();\n setResumeError(\"Resume must be a PDF, DOC, or DOCX file.\");\n return;\n }\n if (file.size > maxResumeBytes) {\n clearResume();\n setResumeError(`Resume must be ${maxMb}MB or smaller.`);\n return;\n }\n setResumeFile(file);\n setResumeType(type);\n };\n\n const handleSubmit = async (\n e: React.FormEvent<HTMLFormElement>,\n ): Promise<void> => {\n e.preventDefault();\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n if (!resumeFile) {\n setResumeError(\"Please attach your resume (PDF, DOC, or DOCX).\");\n return;\n }\n if (!resolvedProductId) {\n // Mirrors ContactPage. Warn so a misconfigured provider (no product\n // context and no config.productId) is visible rather than silently\n // sending an unattributed submission.\n console.warn(\n \"[CareersApplyForm] No productId resolved — submission will not be attributed to a product.\",\n );\n }\n\n const form = e.currentTarget;\n setIsSubmitting(true);\n try {\n const formData = new FormData(form);\n const resumeBase64 = await fileToBase64(resumeFile);\n // When postings drive the dropdown the submitted value is the posting\n // ID — resolve it back to the title for the `position` string and link\n // the application via `jobPostingId`.\n const positionValue = (formData.get(\"position\") as string) ?? \"\";\n const selectedPosting =\n postings.length > 0\n ? postings.find((p) => p.id === positionValue)\n : undefined;\n const result = await submitApplication(\n client,\n {\n firstName: (formData.get(\"firstName\") as string) ?? \"\",\n lastName: (formData.get(\"lastName\") as string) ?? \"\",\n email: (formData.get(\"email\") as string) ?? \"\",\n phone: (formData.get(\"phone\") as string) || undefined,\n position: selectedPosting ? selectedPosting.title : positionValue,\n jobPostingId: selectedPosting?.id,\n linkedinUrl: (formData.get(\"linkedinUrl\") as string) || undefined,\n portfolioUrl: (formData.get(\"portfolioUrl\") as string) || undefined,\n coverLetter: (formData.get(\"coverLetter\") as string) || undefined,\n resumeBase64,\n resumeFileName: resumeFile.name,\n // Use the resolved type (handles browsers that report an empty\n // file.type for .doc/.docx).\n resumeContentType: resumeType ?? resumeFile.type,\n recaptchaToken,\n },\n resolvedProductId,\n );\n\n if (result.success) {\n setSubmitted(true);\n toast.success(result.message ?? \"Application submitted!\");\n } else {\n toast.error(result.message ?? \"Failed to submit application\");\n recaptchaRef.current?.reset();\n }\n } catch (err) {\n console.error(\"Careers form error:\", err);\n toast.error(\"Something went wrong. Please try again.\");\n recaptchaRef.current?.reset();\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const Heading = headingLevel === 2 ? \"h2\" : \"h1\";\n const headingClass =\n headingLevel === 2\n ? \"text-2xl md:text-3xl font-bold mb-3\"\n : \"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\";\n\n return (\n <div className={className}>\n {seo && (\n <PageHead\n title={seo.title ?? `Careers — ${displayName}`}\n description={seo.description ?? heroDescription}\n keywords={seo.keywords}\n />\n )}\n\n <section\n className={\n headingLevel === 2\n ? \"py-12 md:py-16\"\n : \"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\"\n }\n >\n <div className=\"max-w-3xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-8 sm:mb-10\">\n <Heading className={headingClass}>{heroTitle}</Heading>\n <p className=\"text-lg text-muted-foreground leading-relaxed\">\n {heroDescription}\n </p>\n </div>\n\n {submitted ? (\n <div className=\"text-center rounded-xl border border-border bg-card p-10\">\n <CheckCircle className=\"mx-auto mb-4 h-12 w-12 text-accent\" />\n <h3 className=\"text-xl font-semibold text-foreground mb-2\">\n Application received\n </h3>\n <p className=\"text-muted-foreground\">\n Thanks for applying to {displayName}. We&apos;ve emailed you a\n confirmation and our team will be in touch.\n </p>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"firstName\">First name *</Label>\n <Input\n id=\"firstName\"\n name=\"firstName\"\n required\n placeholder=\"Ada\"\n />\n </div>\n <div>\n <Label htmlFor=\"lastName\">Last name *</Label>\n <Input\n id=\"lastName\"\n name=\"lastName\"\n required\n placeholder=\"Lovelace\"\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"email\">Email *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n placeholder=\"ada@example.com\"\n />\n </div>\n <div>\n <Label htmlFor=\"phone\">Phone</Label>\n <Input\n id=\"phone\"\n name=\"phone\"\n placeholder=\"+1 555 010 0100\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"position\">Position *</Label>\n {postings.length > 0 ? (\n <select\n id=\"position\"\n name=\"position\"\n required\n defaultValue=\"\"\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"\" disabled>\n Select a role\n </option>\n {postings.map((p) => (\n <option key={p.id} value={p.id}>\n {p.title}\n </option>\n ))}\n </select>\n ) : positions.length > 0 ? (\n <select\n id=\"position\"\n name=\"position\"\n required\n defaultValue=\"\"\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"\" disabled>\n Select a role\n </option>\n {positions.map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n ) : (\n <Input\n id=\"position\"\n name=\"position\"\n required\n placeholder=\"Role you're applying for\"\n />\n )}\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"linkedinUrl\">LinkedIn</Label>\n <Input\n id=\"linkedinUrl\"\n name=\"linkedinUrl\"\n type=\"url\"\n placeholder=\"https://linkedin.com/in/…\"\n />\n </div>\n <div>\n <Label htmlFor=\"portfolioUrl\">Portfolio / GitHub</Label>\n <Input\n id=\"portfolioUrl\"\n name=\"portfolioUrl\"\n type=\"url\"\n placeholder=\"https://…\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"coverLetter\">Cover letter</Label>\n <Textarea\n id=\"coverLetter\"\n name=\"coverLetter\"\n rows={5}\n placeholder=\"Tell us why you'd be a great fit…\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"resume\">\n Resume * (PDF, DOC, or DOCX — max {maxMb}MB)\n </Label>\n <label\n htmlFor=\"resume\"\n className=\"mt-1 flex cursor-pointer items-center gap-3 rounded-md border border-dashed border-input bg-background px-4 py-3 text-sm hover:bg-muted/40 transition-colors\"\n >\n <Upload\n className=\"h-5 w-5 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <span className=\"text-foreground\">\n {resumeFile ? resumeFile.name : \"Choose a file…\"}\n </span>\n <input\n id=\"resume\"\n name=\"resume\"\n type=\"file\"\n accept=\".pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n className=\"sr-only\"\n aria-describedby={resumeError ? \"resume-error\" : undefined}\n aria-invalid={resumeError ? true : undefined}\n onChange={handleFileChange}\n />\n </label>\n {resumeError && (\n <p\n id=\"resume-error\"\n role=\"alert\"\n className=\"mt-1 text-sm text-destructive\"\n >\n {resumeError}\n </p>\n )}\n </div>\n\n {effectiveRecaptchaSiteKey && (\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n )}\n\n <Button\n type=\"submit\"\n size=\"lg\"\n disabled={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {isSubmitting ? (\n \"Submitting…\"\n ) : (\n <>\n <Send className=\"mr-2 h-4 w-4\" /> Submit application\n </>\n )}\n </Button>\n </form>\n )}\n </div>\n </section>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Careers Submission Form\n *\n * Public assignment-response form for product careers pages — candidates who\n * already applied (via `CareersApplyForm`) submit their take-home assignment\n * here: a GitHub repo URL and a Jam/video walkthrough URL. Mirrors\n * `CareersApplyForm` — reCAPTCHA-gated submit via the WebSDKClient — calling\n * the `submitAssignmentResponse` mutation. The backend links the response to\n * the existing application by email, so the error UX calls out the \"no\n * application found\" case explicitly.\n *\n * @example\n * ```tsx\n * <CareersSubmissionForm\n * productName=\"VibeControls\"\n * postings={[{ id: \"posting-1\", title: \"Senior Engineer\" }]}\n * />\n * ```\n */\n\nimport { useRef, useState } from \"react\";\n\nimport { CheckCircle, Send } from \"lucide-react\";\nimport ReCAPTCHA from \"react-google-recaptcha\";\nimport { toast } from \"sonner\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { useProduct } from \"../product/product-provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Textarea } from \"../ui/textarea\";\n\nimport type { CareersPostingOption } from \"./careers\";\nimport type { WebSDKClient } from \"../client/graphql-client\";\n\nexport interface CareersSubmissionFormProps {\n /** Product name (falls back to product context / SDK config). */\n productName?: string;\n /** reCAPTCHA site key (falls back to SDK config). */\n recaptchaSiteKey?: string;\n /**\n * Job postings for the dropdown (e.g. from `usePublicJobPostings`). When\n * non-empty the selected posting's ID is sent as `jobPostingId` and its\n * title as `position`. When empty, a free-text \"position\" input is shown\n * instead so the form works before a postings list exists.\n */\n postings?: readonly CareersPostingOption[];\n heroTitle?: string;\n heroDescription?: string;\n /**\n * `1` (default) renders a full page hero `<h1>`; `2` renders a compact\n * `<h2>` section header for embedding under a page that owns the `<h1>`.\n */\n headingLevel?: 1 | 2;\n className?: string;\n seo?: { title?: string; description?: string; keywords?: string };\n}\n\nconst SUBMIT_ASSIGNMENT_RESPONSE_MUTATION = /* GraphQL */ `\n mutation SubmitAssignmentResponse($input: SubmitAssignmentResponseInput!) {\n submitAssignmentResponse(input: $input) {\n success\n message\n applicationId\n roundId\n }\n }\n`;\n\ninterface AssignmentResponseData {\n name?: string;\n email: string;\n position: string;\n /** Linked job posting ID — included only when a posting was selected. */\n jobPostingId?: string;\n repoUrl: string;\n videoUrl: string;\n notes?: string;\n recaptchaToken?: string;\n}\n\n/** True when `value` parses as an absolute http(s) URL. */\nexport function isValidUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nasync function submitAssignmentResponse(\n client: WebSDKClient,\n data: AssignmentResponseData,\n): Promise<{ success: boolean; message?: string }> {\n try {\n const result = await client.mutate<{\n submitAssignmentResponse: {\n success: boolean;\n message: string;\n applicationId?: string | null;\n roundId?: string | null;\n };\n }>(SUBMIT_ASSIGNMENT_RESPONSE_MUTATION, {\n input: {\n email: data.email.trim().toLowerCase(),\n repoUrl: data.repoUrl.trim(),\n videoUrl: data.videoUrl.trim(),\n recaptchaToken: data.recaptchaToken ?? \"\",\n ...(data.name ? { name: data.name } : {}),\n ...(data.position ? { position: data.position } : {}),\n ...(data.jobPostingId ? { jobPostingId: data.jobPostingId } : {}),\n ...(data.notes ? { notes: data.notes } : {}),\n },\n });\n\n if (result.errors?.length) {\n return {\n success: false,\n message: result.errors[0]?.message ?? \"Failed to submit assignment\",\n };\n }\n const response = result.data?.submitAssignmentResponse;\n return response?.success\n ? { success: true, message: response.message || \"Assignment submitted!\" }\n : {\n success: false,\n message: response?.message || \"Failed to submit assignment\",\n };\n } catch (error) {\n console.error(\"Assignment submission error:\", error);\n return { success: false, message: \"Network error. Please try again.\" };\n }\n}\n\n/**\n * Backend message for the \"no application found\" case — the candidate must\n * use the same email they applied with (or apply first).\n */\nconst NO_APPLICATION_HINT =\n \"Please use the same email address you applied with — or submit an application first.\";\n\nfunction isNoApplicationError(message: string): boolean {\n return /no application|not found/i.test(message);\n}\n\n/**\n * Sentinel option that switches the position field to free text — a\n * candidate's original posting may have closed since they applied, so the\n * dropdown (open postings only) must never be the only way to enter it.\n */\nconst OTHER_POSITION = \"__other__\";\n\nexport function CareersSubmissionForm({\n productName,\n recaptchaSiteKey,\n postings = [],\n heroTitle = \"Submit your assignment\",\n heroDescription = \"Share your GitHub repo and a short video walkthrough — make sure to use the same email you applied with.\",\n headingLevel = 1,\n className,\n seo,\n}: CareersSubmissionFormProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const displayName = productName ?? product?.name ?? config.productId;\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n product?.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submittedMessage, setSubmittedMessage] = useState<string | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n const [useFreeTextPosition, setUseFreeTextPosition] = useState(\n postings.length === 0,\n );\n\n const handleSubmit = async (\n e: React.FormEvent<HTMLFormElement>,\n ): Promise<void> => {\n e.preventDefault();\n setFormError(null);\n\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n\n const form = e.currentTarget;\n const formData = new FormData(form);\n const name = ((formData.get(\"name\") as string) ?? \"\").trim();\n const email = ((formData.get(\"email\") as string) ?? \"\").trim();\n const positionValue = ((formData.get(\"position\") as string) ?? \"\").trim();\n const repoUrl = ((formData.get(\"repoUrl\") as string) ?? \"\").trim();\n const videoUrl = ((formData.get(\"videoUrl\") as string) ?? \"\").trim();\n const notes = ((formData.get(\"notes\") as string) ?? \"\").trim();\n\n // When postings drive the dropdown the submitted value is the posting\n // ID — resolve it back to the title for the `position` string and link\n // the response via `jobPostingId`. Free text (including the closed-role\n // fallback) has no matching posting, so it falls through as typed.\n const selectedPosting =\n postings.length > 0 && !useFreeTextPosition\n ? postings.find((p) => p.id === positionValue)\n : undefined;\n const position = selectedPosting ? selectedPosting.title : positionValue;\n\n // Client-side validation — native `required`/`type=\"url\"` covers real\n // browsers, but keep explicit checks so the rules hold everywhere.\n if (!email) {\n setFormError(\"Please enter the email address you applied with.\");\n return;\n }\n if (!position) {\n setFormError(\"Please select or enter the position you applied for.\");\n return;\n }\n if (!repoUrl || !isValidUrl(repoUrl)) {\n setFormError(\n \"Please enter a valid GitHub repository URL (e.g. https://github.com/you/project).\",\n );\n return;\n }\n if (!videoUrl || !isValidUrl(videoUrl)) {\n setFormError(\n \"Please enter a valid video URL (e.g. a Jam or Loom link starting with https://).\",\n );\n return;\n }\n\n setIsSubmitting(true);\n try {\n const result = await submitAssignmentResponse(client, {\n name: name || undefined,\n email,\n position,\n jobPostingId: selectedPosting?.id,\n repoUrl,\n videoUrl,\n notes: notes || undefined,\n recaptchaToken,\n });\n\n if (result.success) {\n setSubmittedMessage(result.message ?? \"Assignment submitted!\");\n toast.success(result.message ?? \"Assignment submitted!\");\n } else {\n const message = result.message ?? \"Failed to submit assignment\";\n setFormError(\n isNoApplicationError(message)\n ? `${message} ${NO_APPLICATION_HINT}`\n : message,\n );\n toast.error(message);\n recaptchaRef.current?.reset();\n }\n } catch (err) {\n console.error(\"Careers submission form error:\", err);\n setFormError(\"Something went wrong. Please try again.\");\n toast.error(\"Something went wrong. Please try again.\");\n recaptchaRef.current?.reset();\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const Heading = headingLevel === 2 ? \"h2\" : \"h1\";\n const headingClass =\n headingLevel === 2\n ? \"text-2xl md:text-3xl font-bold mb-3\"\n : \"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\";\n\n return (\n <div className={className}>\n {seo && (\n <PageHead\n title={seo.title ?? `Submit your assignment — ${displayName}`}\n description={seo.description ?? heroDescription}\n keywords={seo.keywords}\n />\n )}\n\n <section\n className={\n headingLevel === 2\n ? \"py-12 md:py-16\"\n : \"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\"\n }\n >\n <div className=\"max-w-3xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-8 sm:mb-10\">\n <Heading className={headingClass}>{heroTitle}</Heading>\n <p className=\"text-lg text-muted-foreground leading-relaxed\">\n {heroDescription}\n </p>\n </div>\n\n {submittedMessage ? (\n <div className=\"text-center rounded-xl border border-border bg-card p-10\">\n <CheckCircle className=\"mx-auto mb-4 h-12 w-12 text-accent\" />\n <h3 className=\"text-xl font-semibold text-foreground mb-2\">\n Assignment received\n </h3>\n <p className=\"text-muted-foreground\">{submittedMessage}</p>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"name\">Name</Label>\n <Input id=\"name\" name=\"name\" placeholder=\"Ada Lovelace\" />\n </div>\n <div>\n <Label htmlFor=\"email\">Email *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n placeholder=\"ada@example.com\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"position\">Position *</Label>\n {postings.length > 0 && !useFreeTextPosition ? (\n <>\n <select\n id=\"position\"\n name=\"position\"\n required\n defaultValue=\"\"\n onChange={(e) => {\n if (e.target.value === OTHER_POSITION) {\n setUseFreeTextPosition(true);\n }\n }}\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"\" disabled>\n Select a role\n </option>\n {postings.map((p) => (\n <option key={p.id} value={p.id}>\n {p.title}\n </option>\n ))}\n <option value={OTHER_POSITION}>\n My role isn&apos;t listed\n </option>\n </select>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Applied to a role that&apos;s since closed? Choose{\" \"}\n <em>My role isn&apos;t listed</em> and type it in — you\n can still submit.\n </p>\n </>\n ) : (\n <>\n <Input\n id=\"position\"\n name=\"position\"\n required\n placeholder=\"Role you applied for\"\n />\n {postings.length > 0 && (\n <button\n type=\"button\"\n onClick={() => setUseFreeTextPosition(false)}\n className=\"mt-1 text-xs text-accent hover:underline\"\n >\n Choose from open roles instead\n </button>\n )}\n </>\n )}\n </div>\n\n <div>\n <Label htmlFor=\"repoUrl\">GitHub repository URL *</Label>\n <Input\n id=\"repoUrl\"\n name=\"repoUrl\"\n type=\"url\"\n required\n placeholder=\"https://github.com/you/assignment\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"videoUrl\">\n Video walkthrough URL (Jam, Loom, …) *\n </Label>\n <Input\n id=\"videoUrl\"\n name=\"videoUrl\"\n type=\"url\"\n required\n placeholder=\"https://jam.dev/c/…\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"notes\">Notes</Label>\n <Textarea\n id=\"notes\"\n name=\"notes\"\n rows={4}\n placeholder=\"Anything we should know before reviewing…\"\n />\n </div>\n\n {formError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {formError}\n </p>\n )}\n\n {effectiveRecaptchaSiteKey && (\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n )}\n\n <Button\n type=\"submit\"\n size=\"lg\"\n disabled={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {isSubmitting ? (\n \"Submitting…\"\n ) : (\n <>\n <Send className=\"mr-2 h-4 w-4\" /> Submit assignment\n </>\n )}\n </Button>\n </form>\n )}\n </div>\n </section>\n </div>\n );\n}\n","/**\n * Concept pages — the shared data contract.\n *\n * Every product website renders `/concepts` and `/concept/:slug` from a GENERATED\n * `src/data/concepts.ts` (`dev/scripts/concepts/build_site_concepts.py`), which types its\n * exports against these interfaces. The explore backend parses the same pages out of each\n * site's `llms-full.txt`, so a field renamed here breaks 37 site builds and the corpus at\n * once — change the generator and this file together, never one of them alone.\n *\n * Canonical source: `dev/platform/context/publishing/concepts/01-architecture.md` → \"Contracts\".\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\n/** The frame a mockup was drawn for. Drives nothing but layout hints. */\nexport type ConceptDevice = \"desktop\" | \"mobile\" | \"tablet\" | \"wide\" | \"other\";\n\n/** One mockup image. Paths are site-relative; the pages absolutise them for SEO. */\nexport interface ConceptImage {\n /** Stable id: the source path under the mockups folder, extension dropped, `/` → `--`. */\n key: string;\n /** Full-size image, e.g. `/mockups/15-sessions-list.webp`. */\n src: string;\n /** 640px-wide thumbnail, e.g. `/mockups/thumbs/15-sessions-list.webp`. */\n thumb: string;\n /** Intrinsic size of `src`. */\n width: number;\n height: number;\n /** Intrinsic size of `thumb`. */\n thumbWidth: number;\n thumbHeight: number;\n /** Short screen title. */\n title: string;\n /** Alt text. Always starts \"Concept illustration of\". */\n alt: string;\n /** One-line caption. */\n caption: string;\n /** 80–170 words describing what the illustration shows. */\n description: string;\n device: ConceptDevice;\n}\n\n/** A feature or flow, illustrated by one or more mockups. */\nexport interface Concept {\n slug: string;\n /** 1-based position across the product's concepts; drives listing and prev/next. */\n order: number;\n title: string;\n /** Matches a `ConceptCategory.name`. */\n category: string;\n tagline: string;\n metaDescription: string;\n overview: string[];\n highlights: string[];\n workflow: string[];\n audience: string[];\n keywords: string[];\n /** Slugs of related concepts on the same site. */\n related: string[];\n images: ConceptImage[];\n /**\n * Cross-product industry solutions on burdenoff.com/domains that feature this concept.\n * Generated from the domain dossiers; absent (or empty) when the concept is in none.\n */\n solutions?: ConceptSolution[];\n}\n\n/**\n * One industry solution — a page on https://burdenoff.com/domains that shows several\n * Burdenoff products working together in one domain (healthcare, logistics, …). A concept\n * page links to the solutions that feature it; a site's `/concepts` page lists every\n * solution its product takes part in.\n */\nexport interface ConceptSolution {\n /** Domain slug, e.g. `\"healthcare\"`. */\n domain: string;\n /** Domain display name, e.g. `\"Healthcare Providers\"`. */\n name: string;\n /** Absolute URL of the solution page, or of this concept's place in it. */\n url: string;\n /** Absolute URL of the domain illustration (a 16:9 thumbnail). */\n image?: string;\n /** One sentence: what this concept (or product) does in that solution. */\n summary?: string;\n}\n\nexport interface ConceptCategory {\n name: string;\n description: string;\n}\n\n/** Props the pages pass to a site's link adapter. */\nexport interface ConceptLinkProps {\n href: string;\n className?: string;\n children: ReactNode;\n \"aria-label\"?: string;\n}\n\n/**\n * The link the pages render for every internal URL. Sites pass a tiny adapter around their\n * router's `Link` so moving between concepts stays a client-side navigation; without one the\n * pages fall back to a plain `<a href>`.\n */\nexport type ConceptLinkComponent = ComponentType<ConceptLinkProps>;\n\n/**\n * The disclaimer shown beside every concept image. The same sentence applies to all of them\n * — including the few that began as real captures — so a visitor never has to guess which\n * picture shows the shipping product.\n */\nexport const CONCEPT_ILLUSTRATION_NOTICE =\n \"These images are illustrations of the concept, not screenshots of the actual product.\";\n\n/**\n * The disclaimer shown above every concept's \"How it works\" steps.\n *\n * A numbered list under that heading reads as a procedure — the sequence of screens a\n * visitor would click through — when what it actually describes is how the pieces of the\n * concept relate. The illustration notice covers the pictures; nothing covered the steps,\n * so the most instruction-shaped part of the page was the least qualified.\n *\n * Rendered with NO data gate, exactly like CONCEPT_ILLUSTRATION_NOTICE. Keying a\n * disclosure to a generated field is how it disappears silently the first time a\n * generator omits that field, and the page would then look more authoritative, not less.\n * The section's own `workflow.length > 0` check is the only condition: no steps, no\n * heading, nothing to qualify.\n *\n * The sentence says nothing about launch or availability. Every product behind these\n * pages is generally available, and a notice that hinted otherwise would be false on\n * every site that renders it.\n */\nexport const CONCEPT_WORKFLOW_NOTICE =\n \"These steps illustrate how the concept fits together — not a walkthrough of the product's current interface.\";\n\n/** Where every industry solution is listed. */\nexport const DOMAINS_URL = \"https://burdenoff.com/domains\";\n\n/** The landing page route. */\nexport const CONCEPTS_PATH = \"/concepts\";\n\n/** Prefix of every concept detail route: `/concept/<slug>`. */\nexport const CONCEPT_PATH_PREFIX = \"/concept\";\n\n/** Site-relative URL of a concept's detail page. */\nexport function conceptPath(slug: string): string {\n // Slugs are generated as [a-z0-9-], so this is a no-op for real data; it only keeps a\n // malformed slug from escaping its path segment.\n return `${CONCEPT_PATH_PREFIX}/${encodeURIComponent(slug)}`;\n}\n\n/**\n * Resolve a route parameter to its concept. Returns `undefined` for an unknown slug — the\n * site then redirects to `/concepts` rather than rendering a soft 404.\n */\nexport function getConceptBySlug(\n concepts: readonly Concept[],\n slug: string | null | undefined,\n): Concept | undefined {\n if (!slug) return undefined;\n const wanted = slug.trim().toLowerCase();\n if (!wanted) return undefined;\n return concepts.find((concept) => concept.slug === wanted);\n}\n","/**\n * ConceptLightbox — full-size view of one concept's illustrations.\n *\n * - A native `<dialog>` opened with `showModal()`: the browser supplies the top layer, the\n * inert page behind it, the focus containment and Esc-to-close. Nothing here re-implements\n * those.\n * - The parent mounts it ONLY while it is open. A closed dialog left in the tree would be\n * baked into every prerendered concept page, and the llms extractor would read its caption\n * and notice as page content.\n * - ← / → step through the concept's images and wrap at either end, so a held arrow key never\n * lands on a disabled button (disabling the focused control drops focus to the document).\n * - Returning focus to the control that opened it is the parent's job — it knows which\n * trigger that was even after the visitor has stepped to another image.\n */\n\"use client\";\n\nimport { useCallback, useEffect, useId, useRef } from \"react\";\nimport type { KeyboardEvent, MouseEvent, SyntheticEvent } from \"react\";\n\nimport { ChevronLeft, ChevronRight, Info, X } from \"lucide-react\";\n\nimport { CONCEPT_ILLUSTRATION_NOTICE } from \"./concepts-types\";\n\nimport type { ConceptImage } from \"./concepts-types\";\n\nexport interface ConceptLightboxProps {\n images: readonly ConceptImage[];\n /** Index into `images` of the illustration on screen. */\n index: number;\n /** The concept these illustrations belong to — shown above the image title. */\n conceptTitle: string;\n onIndexChange: (index: number) => void;\n onClose: () => void;\n}\n\nconst NAV_BUTTON =\n \"inline-flex h-11 w-11 items-center justify-center rounded-full border border-border bg-card text-foreground shadow-md transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n\nexport function ConceptLightbox({\n images,\n index,\n conceptTitle,\n onIndexChange,\n onClose,\n}: ConceptLightboxProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const closeRef = useRef<HTMLButtonElement>(null);\n /** False when the browser has no `showModal()` and Esc has to be handled here. */\n const nativeModalRef = useRef(false);\n const titleId = useId();\n\n const count = images.length;\n const position = count > 0 ? ((index % count) + count) % count : 0;\n const image = images[position];\n\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n if (typeof dialog.showModal === \"function\") {\n if (!dialog.open) dialog.showModal();\n nativeModalRef.current = true;\n } else {\n // No top layer in this engine: show it in place and handle Esc ourselves.\n dialog.setAttribute(\"open\", \"\");\n nativeModalRef.current = false;\n }\n closeRef.current?.focus();\n return () => {\n if (dialog.open && typeof dialog.close === \"function\") dialog.close();\n };\n }, []);\n\n const go = useCallback(\n (delta: number) => {\n if (count < 2) return;\n onIndexChange((position + delta + count) % count);\n },\n [count, onIndexChange, position],\n );\n\n // Esc closes the dialog natively and then fires `close`. StrictMode re-runs the mount\n // effect (close, then showModal again), so a `close` event can arrive for a dialog that is\n // already open again — that one must not tear the lightbox down.\n const handleClose = useCallback(\n (event: SyntheticEvent<HTMLDialogElement>) => {\n if (event.currentTarget.open) return;\n onClose();\n },\n [onClose],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDialogElement>) => {\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n go(1);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n go(-1);\n } else if (event.key === \"Escape\" && !nativeModalRef.current) {\n event.preventDefault();\n onClose();\n }\n },\n [go, onClose],\n );\n\n // A click on the empty stage around the picture dismisses, as it does on every lightbox.\n const handleStageClick = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (event.target === event.currentTarget) onClose();\n },\n [onClose],\n );\n\n if (!image) return null;\n\n return (\n <dialog\n ref={dialogRef}\n data-concepts=\"lightbox\"\n aria-labelledby={titleId}\n onClose={handleClose}\n onKeyDown={handleKeyDown}\n className=\"fixed inset-0 z-50 m-0 h-full max-h-none w-full max-w-none overflow-y-auto overscroll-contain border-0 bg-background/95 p-0 text-foreground backdrop-blur-sm\"\n >\n <div className=\"flex min-h-full flex-col\">\n <div className=\"flex items-start justify-between gap-4 border-b border-border px-4 py-3 sm:px-6\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {conceptTitle}\n {count > 1 ? ` · ${position + 1} / ${count}` : null}\n </p>\n <h2\n id={titleId}\n className=\"truncate text-base font-semibold text-foreground sm:text-lg\"\n >\n {image.title}\n </h2>\n </div>\n <button\n ref={closeRef}\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close\"\n data-concepts=\"lightbox-close\"\n className=\"inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-border bg-card text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <X aria-hidden=\"true\" className=\"h-5 w-5\" />\n </button>\n </div>\n\n <div\n className=\"relative flex flex-1 items-center justify-center px-4 py-4 sm:px-20\"\n onClick={handleStageClick}\n >\n {/* Keyed so a step to the next image never shows the previous one under the new\n title while it loads. */}\n <img\n key={image.key}\n src={image.src}\n alt={image.alt}\n width={image.width}\n height={image.height}\n decoding=\"async\"\n className=\"h-auto max-h-[calc(100vh-14rem)] w-auto max-w-full rounded-lg border border-border bg-muted object-contain shadow-lg\"\n />\n {count > 1 ? (\n <>\n <button\n type=\"button\"\n onClick={() => go(-1)}\n aria-label=\"Previous illustration\"\n data-concepts=\"lightbox-prev\"\n className={`absolute left-2 top-1/2 -translate-y-1/2 sm:left-4 ${NAV_BUTTON}`}\n >\n <ChevronLeft aria-hidden=\"true\" className=\"h-5 w-5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => go(1)}\n aria-label=\"Next illustration\"\n data-concepts=\"lightbox-next\"\n className={`absolute right-2 top-1/2 -translate-y-1/2 sm:right-4 ${NAV_BUTTON}`}\n >\n <ChevronRight aria-hidden=\"true\" className=\"h-5 w-5\" />\n </button>\n </>\n ) : null}\n </div>\n\n <div className=\"border-t border-border px-4 py-3 sm:px-6\">\n <p className=\"text-sm leading-relaxed text-foreground\">\n {image.caption}\n </p>\n <p className=\"mt-1.5 flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground\">\n <Info aria-hidden=\"true\" className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n <span>{CONCEPT_ILLUSTRATION_NOTICE}</span>\n </p>\n </div>\n </div>\n </dialog>\n );\n}\n","/**\n * Concept pages — `/concepts` and `/concept/:slug` on every product website.\n *\n * A concept is a feature or flow of the product, shown through the mockups drawn for it and\n * explained in reviewed copy. The data is generated per site (`src/data/concepts.ts`) and\n * passed in; nothing here fetches, so both pages prerender completely and make no runtime\n * third-party requests.\n *\n * Written against three readers, in this order of strictness:\n *\n * - **Visitors.** Every image is labelled an illustration, never a screenshot: a badge on the\n * picture and the same notice callout on both pages. Colours are semantic tokens only, so\n * the pages are correct in light and dark mode on every product's palette.\n * - **Search engines.** One `<h1>` per page, a self-canonical URL, absolute Open Graph images\n * and JSON-LD (`CollectionPage` + `ItemList` on the landing page, `ImageGallery` on a\n * concept, `BreadcrumbList` on both).\n * - **The llms extractor** (`scripts/llms.mjs` on every site). It turns each gallery\n * `<img data-llms-image>` into its own `![alt](url)` line and takes the text line right\n * after it as the caption, so each gallery figure is title → image → `<figcaption>` →\n * description, with no block element in between. Only the gallery carries\n * `data-llms-image`; the hero repeats the first image and must not count twice. The\n * lightbox is mounted only while open, so it never reaches the prerendered HTML at all.\n *\n * Import from the package ROOT — `@burdenoff/website-sdk` — like every other page component\n * (tsup builds with `splitting: false`).\n *\n * @example\n * ```tsx\n * import { ConceptsPage, ConceptDetailPage, getConceptBySlug } from '@burdenoff/website-sdk'\n * import { CONCEPTS, CONCEPT_CATEGORIES } from '@/data/concepts'\n *\n * <ConceptsPage productName=\"VibeControls\" siteUrl=\"https://vibecontrols.com\"\n * concepts={CONCEPTS} categories={CONCEPT_CATEGORIES} linkComponent={SiteLink} />\n * ```\n */\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n version as reactVersion,\n} from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport {\n ArrowLeft,\n ArrowRight,\n Check,\n ChevronRight,\n ExternalLink,\n ImageIcon,\n Info,\n Maximize2,\n Search,\n} from \"lucide-react\";\n\nimport { ConceptLightbox } from \"./concept-lightbox\";\nimport {\n CONCEPT_ILLUSTRATION_NOTICE,\n CONCEPT_WORKFLOW_NOTICE,\n CONCEPTS_PATH,\n DOMAINS_URL,\n conceptPath,\n} from \"./concepts-types\";\nimport { PageHead } from \"../seo/page-head\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n Concept,\n ConceptCategory,\n ConceptImage,\n ConceptLinkComponent,\n ConceptLinkProps,\n ConceptSolution,\n} from \"./concepts-types\";\n\n// ============================================================================\n// Props\n// ============================================================================\n\nexport interface ConceptsPageProps {\n /** Product display name, e.g. `\"VibeControls\"`. */\n productName: string;\n /** Public origin of the site, e.g. `\"https://vibecontrols.com\"`. Used for absolute URLs. */\n siteUrl: string;\n concepts: readonly Concept[];\n /** Section order and descriptions. Concepts in an unlisted category still render, last. */\n categories?: readonly ConceptCategory[];\n /** Call to action rendered in the hero (e.g. the site's primary buttons). */\n cta?: ReactNode;\n /** Router adapter for internal links. Defaults to a plain `<a href>`. */\n linkComponent?: ConceptLinkComponent;\n /** Overrides the `<h1>`. Default: `\"<productName> concepts\"`. */\n title?: string;\n /** Overrides the meta description (and the hero lead). Default: built from the counts. */\n description?: string;\n /**\n * Industry solutions on burdenoff.com/domains that this product takes part in. Rendered as\n * a band after the concepts; omitted when empty.\n */\n solutions?: readonly ConceptSolution[];\n /** \"Browse every solution\" target. Default: {@link DOMAINS_URL}. */\n solutionsUrl?: string;\n /** Extra classes for the page root. */\n className?: string;\n}\n\nexport interface ConceptDetailPageProps {\n productName: string;\n siteUrl: string;\n /** The concept to render. The site resolves the slug and redirects when it is unknown. */\n concept: Concept;\n /** Every concept on the site — for related concepts and previous / next. */\n concepts: readonly Concept[];\n categories?: readonly ConceptCategory[];\n /** Call to action rendered as a band at the end of the page. */\n cta?: ReactNode;\n linkComponent?: ConceptLinkComponent;\n className?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst META_DESCRIPTION_LIMIT = 160;\nconst RELATED_LIMIT = 4;\n\n/**\n * `fetchpriority=\"high\"` for the hero, spelled the way the running React accepts it. React 19\n * knows the `fetchPriority` prop and warns about the lowercase form; React 18 (still inside\n * the peer range, and what this repo tests on) does not know it and warns unless it is\n * lowercase. Both put the same attribute in the DOM.\n */\nconst HERO_FETCH_PRIORITY: Record<string, string> =\n Number.parseInt(reactVersion, 10) >= 19\n ? { fetchPriority: \"high\" }\n : { fetchpriority: \"high\" };\n\n/** The origin without trailing slashes, so paths can be appended as-is. */\nfunction normaliseSiteUrl(siteUrl: string): string {\n return siteUrl.trim().replace(/\\/+$/, \"\");\n}\n\n/** Absolute form of a site-relative path; absolute URLs pass through. */\nfunction absoluteUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nfunction sortByOrder(concepts: readonly Concept[]): Concept[] {\n return [...concepts].sort(\n (a, b) => a.order - b.order || a.slug.localeCompare(b.slug),\n );\n}\n\nfunction plural(count: number, singular: string, pluralForm: string): string {\n return `${count} ${count === 1 ? singular : pluralForm}`;\n}\n\nfunction illustrationCount(count: number): string {\n return plural(count, \"illustration\", \"illustrations\");\n}\n\nfunction listSentence(items: readonly string[]): string {\n if (items.length <= 1) return items.join(\"\");\n return `${items.slice(0, -1).join(\", \")} and ${items[items.length - 1]}`;\n}\n\n/** Cut at a word boundary so a meta description never ends mid-word. */\nfunction clampText(text: string, limit: number): string {\n if (text.length <= limit) return text;\n const cut = text.slice(0, limit - 1);\n const lastSpace = cut.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\\s,;:—–-]+$/, \"\")}…`;\n}\n\n/**\n * The landing page's default meta description: counts, then as many category names as fit\n * in 160 characters, always mentioning that the pictures are illustrations. A site with no\n * concepts yet gets a description without counts rather than one announcing zero.\n */\nfunction defaultLandingDescription(\n productName: string,\n conceptTotal: number,\n imageTotal: number,\n categoryNames: readonly string[],\n): string {\n if (conceptTotal === 0) {\n return clampText(\n `Concepts of how ${productName} works, each a feature or flow explained with illustrations.`,\n META_DESCRIPTION_LIMIT,\n );\n }\n const head = `Explore ${plural(conceptTotal, `${productName} concept`, `${productName} concepts`)} with ${illustrationCount(imageTotal)}`;\n for (let take = Math.min(categoryNames.length, 4); take >= 1; take -= 1) {\n const more = categoryNames.length > take ? \" and more\" : \"\";\n const text = `${head} across ${listSentence(categoryNames.slice(0, take))}${more}.`;\n if (text.length <= META_DESCRIPTION_LIMIT) return text;\n }\n return clampText(`${head} of how the product works.`, META_DESCRIPTION_LIMIT);\n}\n\nfunction slugifyAnchor(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\ninterface CategoryGroup {\n name: string;\n description: string;\n /** DOM id of the section heading — unique even when two names slugify alike. */\n anchor: string;\n concepts: Concept[];\n}\n\n/**\n * Concepts grouped in the order `categories` lists them. Empty categories are dropped, and a\n * concept whose category is missing from the list still gets a section (after the listed\n * ones) rather than silently disappearing from the page.\n */\nfunction groupByCategory(\n ordered: readonly Concept[],\n categories: readonly ConceptCategory[] | undefined,\n): CategoryGroup[] {\n const byName = new Map<string, Concept[]>();\n for (const concept of ordered) {\n const list = byName.get(concept.category);\n if (list) list.push(concept);\n else byName.set(concept.category, [concept]);\n }\n\n const described: Array<Omit<CategoryGroup, \"anchor\">> = [];\n for (const category of categories ?? []) {\n const list = byName.get(category.name);\n if (!list) continue;\n described.push({\n name: category.name,\n description: category.description,\n concepts: list,\n });\n byName.delete(category.name);\n }\n for (const [name, list] of byName) {\n described.push({ name, description: \"\", concepts: list });\n }\n\n const used = new Set<string>();\n return described.map((group) => {\n const base = `concepts-${slugifyAnchor(group.name) || \"category\"}`;\n let anchor = base;\n for (let n = 2; used.has(anchor); n += 1) anchor = `${base}-${n}`;\n used.add(anchor);\n return { ...group, anchor };\n });\n}\n\nfunction searchTokens(query: string): string[] {\n return query.toLowerCase().split(/\\s+/).filter(Boolean);\n}\n\nfunction matchesSearch(concept: Concept, tokens: readonly string[]): boolean {\n if (tokens.length === 0) return true;\n const haystack = [\n concept.title,\n concept.tagline,\n concept.category,\n ...concept.keywords,\n ]\n .join(\" \")\n .toLowerCase();\n return tokens.every((token) => haystack.includes(token));\n}\n\nfunction isPortrait(width: number, height: number): boolean {\n return height > width;\n}\n\n/**\n * Key for a list rendered from the copy. The text alone collides when a list repeats an\n * entry, so the position qualifies it; these lists never reorder, so that is stable.\n */\nfunction copyKey(index: number, text: string): string {\n return `${index}-${text}`;\n}\n\n// ============================================================================\n// Shared pieces\n// ============================================================================\n\nfunction DefaultConceptLink({\n href,\n className,\n children,\n \"aria-label\": ariaLabel,\n}: ConceptLinkProps) {\n return (\n <a href={href} className={className} aria-label={ariaLabel}>\n {children}\n </a>\n );\n}\n\n/** The illustration disclaimer, as a callout that cannot be mistaken for body copy. */\nfunction IllustrationNotice({ className }: { className?: string }) {\n return (\n <div\n role=\"note\"\n data-concepts=\"notice\"\n data-concepts-notice=\"\"\n className={cn(\n \"flex items-start gap-3 rounded-xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm leading-relaxed text-foreground\",\n className,\n )}\n >\n <Info\n aria-hidden=\"true\"\n className=\"mt-0.5 h-4 w-4 shrink-0 text-primary\"\n />\n <p>{CONCEPT_ILLUSTRATION_NOTICE}</p>\n </div>\n );\n}\n\n/**\n * The workflow disclaimer, shown above a concept's numbered steps.\n *\n * Deliberately NOT the `data-concepts-notice` attribute IllustrationNotice carries: three\n * existing assertions select that attribute with `querySelector` and read the single node\n * they get back, so a second element wearing it would make those tests pass while\n * describing the wrong element. It renders no heading either — the detail page's heading\n * order is pinned.\n */\nfunction WorkflowNotice({ className }: { className?: string }) {\n return (\n <div\n role=\"note\"\n data-concepts=\"workflow-notice\"\n data-concepts-workflow-notice=\"\"\n className={cn(\n \"mt-4 flex items-start gap-3 rounded-xl border border-border bg-muted/50 px-4 py-3 text-sm leading-relaxed text-muted-foreground\",\n className,\n )}\n >\n <Info\n aria-hidden=\"true\"\n className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\"\n />\n <p>{CONCEPT_WORKFLOW_NOTICE}</p>\n </div>\n );\n}\n\n/**\n * The \"Illustration\" label laid over every concept picture. Hidden from assistive tech: every\n * alt text already begins \"Concept illustration of\", so reading the badge too is noise.\n */\nfunction IllustrationBadge({ className }: { className?: string }) {\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"pointer-events-none absolute left-2 top-2 inline-flex items-center rounded-full border border-border bg-background/90 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-foreground shadow-sm\",\n className,\n )}\n >\n Illustration\n </span>\n );\n}\n\n/**\n * A concept card: thumbnail, title, tagline and image count, all one link.\n *\n * The thumbnail is decorative here (`alt=\"\"`): the card's own title names the concept, and\n * the full alt text belongs to the concept page, where the image is the content.\n */\nfunction ConceptCard({\n concept,\n Link,\n}: {\n concept: Concept;\n Link: ConceptLinkComponent;\n}) {\n const image = concept.images[0];\n const portrait = image\n ? isPortrait(image.thumbWidth, image.thumbHeight)\n : false;\n\n return (\n <Link\n href={conceptPath(concept.slug)}\n className=\"group flex h-full flex-col overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none\"\n >\n <div className=\"relative aspect-[16/10] overflow-hidden border-b border-border bg-muted\">\n {image ? (\n <img\n src={image.thumb}\n alt=\"\"\n width={image.thumbWidth}\n height={image.thumbHeight}\n loading=\"lazy\"\n decoding=\"async\"\n className={cn(\n \"h-full w-full\",\n portrait ? \"object-contain p-3\" : \"object-cover object-top\",\n )}\n />\n ) : null}\n <IllustrationBadge />\n </div>\n <div className=\"flex flex-1 flex-col gap-2 p-4\">\n <h3 className=\"text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary\">\n {concept.title}\n </h3>\n <p className=\"line-clamp-3 text-sm leading-relaxed text-muted-foreground\">\n {concept.tagline}\n </p>\n <span className=\"mt-auto inline-flex items-center gap-1.5 pt-1 text-xs font-medium text-muted-foreground\">\n <ImageIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {illustrationCount(concept.images.length)}\n </span>\n </div>\n </Link>\n );\n}\n\nfunction FilterChip({\n label,\n count,\n active,\n category,\n onSelect,\n}: {\n label: string;\n count: number;\n active: boolean;\n category: string;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-category={category}\n onClick={onSelect}\n className={cn(\n \"inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-card text-foreground hover:border-primary/40 hover:bg-muted\",\n )}\n >\n <span>{label}</span>\n <span\n className={cn(\n \"rounded-full px-1.5 text-xs tabular-nums\",\n active\n ? \"bg-primary-foreground text-primary\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {count}\n </span>\n </button>\n );\n}\n\n/**\n * Industry solutions that feature this product or concept — cards linking to\n * burdenoff.com/domains, where several products are shown working together.\n *\n * The domain art is decorative (`alt=\"\"`, no `data-llms-image`): the card's heading names the\n * solution, and only concept illustrations may reach the llms extractor. The links leave the\n * site, so they are plain anchors that open a new tab, whatever router adapter the site uses.\n */\nfunction SolutionsSection({\n id,\n title,\n lead,\n solutions,\n moreHref,\n moreLabel,\n className,\n}: {\n id: string;\n title: string;\n lead: string;\n solutions: readonly ConceptSolution[];\n moreHref?: string;\n moreLabel?: string;\n className?: string;\n}) {\n return (\n <section\n id={id}\n aria-labelledby={`${id}-heading`}\n data-concepts=\"solutions\"\n className={cn(\"scroll-mt-24\", className)}\n >\n <div className=\"max-w-3xl\">\n <h2\n id={`${id}-heading`}\n className=\"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\"\n >\n {title}\n </h2>\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">{lead}</p>\n </div>\n <ul\n role=\"list\"\n className={cn(\n \"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2\",\n solutions.length >= 3 ? \"lg:grid-cols-3\" : \"lg:grid-cols-2\",\n )}\n >\n {solutions.map((solution) => (\n <li\n key={`${solution.domain}:${solution.url}`}\n data-domain={solution.domain}\n >\n <a\n href={solution.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"group flex h-full flex-col overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none\"\n >\n {solution.image ? (\n <div className=\"aspect-[16/9] overflow-hidden border-b border-border bg-muted\">\n <img\n src={solution.image}\n alt=\"\"\n width={640}\n height={360}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"h-full w-full object-cover transition duration-300 group-hover:scale-[1.03] motion-reduce:transition-none motion-reduce:group-hover:scale-100\"\n />\n </div>\n ) : null}\n <div className=\"flex flex-1 flex-col gap-2 p-4\">\n <p className=\"text-xs font-semibold uppercase tracking-[0.16em] text-primary\">\n Industry solution\n </p>\n <h3 className=\"text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary\">\n {solution.name}\n </h3>\n {solution.summary ? (\n <p className=\"line-clamp-3 text-sm leading-relaxed text-muted-foreground\">\n {solution.summary}\n </p>\n ) : null}\n <span className=\"mt-auto inline-flex items-center gap-1.5 pt-1 text-sm font-medium text-primary\">\n See the solution\n <ExternalLink aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n <span className=\"sr-only\">(opens in a new tab)</span>\n </span>\n </div>\n </a>\n </li>\n ))}\n </ul>\n {moreHref ? (\n <a\n href={moreHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mt-6 inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {moreLabel ?? \"Browse every industry solution\"}\n <ArrowRight aria-hidden=\"true\" className=\"h-4 w-4\" />\n <span className=\"sr-only\">(opens in a new tab)</span>\n </a>\n ) : null}\n </section>\n );\n}\n\n// ============================================================================\n// Landing page\n// ============================================================================\n\n/**\n * `/concepts` — every concept on the site, grouped by category, with a client-side search\n * and category filter. Filters start at \"All\", so the prerendered page lists everything.\n */\nexport function ConceptsPage({\n productName,\n siteUrl,\n concepts,\n categories,\n cta,\n linkComponent,\n title,\n description,\n solutions,\n solutionsUrl,\n className,\n}: ConceptsPageProps) {\n const Link = linkComponent ?? DefaultConceptLink;\n const base = normaliseSiteUrl(siteUrl);\n const searchId = useId();\n\n const ordered = useMemo(() => sortByOrder(concepts), [concepts]);\n const groups = useMemo(\n () => groupByCategory(ordered, categories),\n [ordered, categories],\n );\n const imageTotal = useMemo(\n () => ordered.reduce((sum, concept) => sum + concept.images.length, 0),\n [ordered],\n );\n\n const [query, setQuery] = useState(\"\");\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n\n const hasConcepts = ordered.length > 0;\n const tokens = useMemo(() => searchTokens(query), [query]);\n const searched = useMemo(\n () => ordered.filter((concept) => matchesSearch(concept, tokens)),\n [ordered, tokens],\n );\n // Chip counts follow the search, so each chip says how many results it would show.\n const countsByCategory = useMemo(() => {\n const counts = new Map<string, number>();\n for (const concept of searched) {\n counts.set(concept.category, (counts.get(concept.category) ?? 0) + 1);\n }\n return counts;\n }, [searched]);\n const visibleGroups = useMemo(() => {\n const visible = new Set(\n searched.filter(\n (concept) =>\n activeCategory === null || concept.category === activeCategory,\n ),\n );\n return groups\n .map((group) => ({\n ...group,\n concepts: group.concepts.filter((concept) => visible.has(concept)),\n }))\n .filter((group) => group.concepts.length > 0);\n }, [groups, searched, activeCategory]);\n const visibleTotal = visibleGroups.reduce(\n (sum, group) => sum + group.concepts.length,\n 0,\n );\n const filtering = tokens.length > 0 || activeCategory !== null;\n\n const clearFilters = useCallback(() => {\n setQuery(\"\");\n setActiveCategory(null);\n }, []);\n\n const heading = title ?? `${productName} concepts`;\n const metaDescription =\n description ??\n defaultLandingDescription(\n productName,\n ordered.length,\n imageTotal,\n groups.map((group) => group.name),\n );\n const lead =\n description ??\n `A guided tour of ${productName}, one concept at a time. Each concept groups the illustrations of a feature or flow and explains what it does, how it works and who it is for.`;\n\n const canonical = `${base}${CONCEPTS_PATH}`;\n const firstImage = ordered.find((concept) => concept.images[0])?.images[0];\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"CollectionPage\",\n name: heading,\n description: metaDescription,\n url: canonical,\n isPartOf: { \"@type\": \"WebSite\", name: productName, url: `${base}/` },\n mainEntity: {\n \"@type\": \"ItemList\",\n numberOfItems: ordered.length,\n itemListElement: ordered.map((concept, index) => {\n const image = concept.images[0];\n return {\n \"@type\": \"ListItem\",\n position: index + 1,\n url: absoluteUrl(base, conceptPath(concept.slug)),\n name: concept.title,\n ...(image ? { image: absoluteUrl(base, image.src) } : {}),\n };\n }),\n },\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n { \"@type\": \"ListItem\", position: 1, name: \"Home\", item: `${base}/` },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: \"Concepts\",\n item: canonical,\n },\n ],\n },\n ],\n [base, canonical, heading, metaDescription, ordered, productName],\n );\n\n return (\n <div\n data-concepts=\"landing\"\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title=\"Concepts\"\n description={metaDescription}\n productName={productName}\n keywords={[\n `${productName} concepts`,\n `${productName} illustrations`,\n ...groups.map((group) => group.name),\n ].join(\", \")}\n image={firstImage ? absoluteUrl(base, firstImage.src) : undefined}\n url={canonical}\n structuredData={structuredData}\n />\n\n <section className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-6xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8\">\n <p className=\"text-xs font-semibold uppercase tracking-[0.2em] text-primary\">\n Concepts\n </p>\n <h1 className=\"mt-3 max-w-3xl text-4xl font-bold tracking-tight text-foreground sm:text-5xl\">\n {heading}\n </h1>\n <p className=\"mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground\">\n {lead}\n </p>\n {hasConcepts ? (\n <p className=\"mt-6 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground\">\n <span>\n <strong className=\"text-lg font-semibold text-foreground\">\n {ordered.length}\n </strong>{\" \"}\n {ordered.length === 1 ? \"concept\" : \"concepts\"}\n </span>\n <span>\n <strong className=\"text-lg font-semibold text-foreground\">\n {imageTotal}\n </strong>{\" \"}\n {imageTotal === 1 ? \"illustration\" : \"illustrations\"}\n </span>\n </p>\n ) : null}\n <IllustrationNotice className=\"mt-6 max-w-2xl\" />\n {cta ? <div className=\"mt-8 flex flex-wrap gap-3\">{cta}</div> : null}\n </div>\n </section>\n\n <div className=\"mx-auto max-w-6xl px-4 pb-20 sm:px-6 lg:px-8\">\n {hasConcepts ? (\n <>\n <div\n role=\"search\"\n data-concepts=\"filter\"\n className=\"flex flex-col gap-4 py-8\"\n >\n <div className=\"relative w-full max-w-md\">\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n />\n <label htmlFor={searchId} className=\"sr-only\">\n Search concepts\n </label>\n <input\n id={searchId}\n type=\"search\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search concepts\"\n autoComplete=\"off\"\n className=\"h-10 w-full rounded-lg border border-border bg-background pl-9 pr-3 text-sm text-foreground shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </div>\n <div\n role=\"group\"\n aria-label=\"Filter by category\"\n className=\"flex flex-wrap gap-2\"\n >\n <FilterChip\n label=\"All\"\n category=\"all\"\n count={searched.length}\n active={activeCategory === null}\n onSelect={() => setActiveCategory(null)}\n />\n {groups.map((group) => (\n <FilterChip\n key={group.anchor}\n label={group.name}\n category={group.name}\n count={countsByCategory.get(group.name) ?? 0}\n active={activeCategory === group.name}\n onSelect={() =>\n setActiveCategory((current) =>\n current === group.name ? null : group.name,\n )\n }\n />\n ))}\n </div>\n {/* Visible only while a filter is on; announced whenever the result set changes. */}\n <p\n aria-live=\"polite\"\n className={\n filtering ? \"text-sm text-muted-foreground\" : \"sr-only\"\n }\n >\n Showing {visibleTotal} of {ordered.length}{\" \"}\n {ordered.length === 1 ? \"concept\" : \"concepts\"}\n </p>\n </div>\n\n {visibleTotal === 0 ? (\n <div\n data-concepts=\"empty\"\n className=\"rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <Search\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n No concepts match your filters\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n Try a different search, or show every category.\n </p>\n <button\n type=\"button\"\n onClick={clearFilters}\n className=\"mt-6 inline-flex items-center rounded-full border border-border bg-card px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <div className=\"space-y-14\">\n {visibleGroups.map((group) => (\n <section key={group.anchor} aria-labelledby={group.anchor}>\n <div className=\"max-w-3xl\">\n <h2\n id={group.anchor}\n className=\"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\"\n >\n {group.name}\n </h2>\n {group.description ? (\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">\n {group.description}\n </p>\n ) : null}\n </div>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3\"\n >\n {group.concepts.map((concept) => (\n <li\n key={concept.slug}\n data-concepts=\"card\"\n data-slug={concept.slug}\n >\n <ConceptCard concept={concept} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n )}\n </>\n ) : (\n // Nothing published yet: no filter bar with an \"All 0\" chip, and no empty state\n // that blames filters the visitor never set.\n <div\n data-concepts=\"none\"\n className=\"mt-10 rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <ImageIcon\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n No concepts published yet\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {productName} concepts will appear here as they are published.\n </p>\n </div>\n )}\n\n {solutions && solutions.length > 0 ? (\n <SolutionsSection\n id=\"industry-solutions\"\n title={`${productName} in industry solutions`}\n lead={`See how ${productName} works with other Burdenoff products to solve real problems in specific industries — each solution walks through the challenges, the products involved and the concepts behind them.`}\n solutions={solutions}\n moreHref={solutionsUrl ?? DOMAINS_URL}\n moreLabel=\"Browse every industry solution\"\n className=\"mt-16 border-t border-border pt-14\"\n />\n ) : null}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Detail page\n// ============================================================================\n\nconst SECTION_HEADING =\n \"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\";\nconst CHIP =\n \"inline-flex items-center rounded-full border border-border bg-muted/50 px-3 py-1 text-sm text-foreground\";\n\nfunction IllustrationFigure({\n image,\n onOpen,\n}: {\n image: ConceptImage;\n onOpen: (trigger: HTMLElement) => void;\n}) {\n const portrait = isPortrait(image.width, image.height);\n return (\n // The block the llms extractor reads: title, image line, caption, description — in\n // that order and with nothing in between. The description sits outside <figure>\n // because a <figcaption> must be the figure's first or last child.\n <div className=\"space-y-4\">\n <figure id={`illustration-${image.key}`} className=\"scroll-mt-24\">\n <h3 className=\"text-lg font-semibold text-foreground\">{image.title}</h3>\n <button\n type=\"button\"\n onClick={(event) => onOpen(event.currentTarget)}\n data-concepts=\"illustration\"\n className={cn(\n \"group relative mt-3 block w-full overflow-hidden rounded-2xl border border-border shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n portrait ? \"bg-muted p-4 sm:p-6\" : \"bg-muted\",\n )}\n >\n <img\n data-llms-image=\"\"\n src={image.src}\n alt={image.alt}\n width={image.width}\n height={image.height}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"mx-auto block h-auto max-h-[80vh] w-auto max-w-full\"\n />\n <IllustrationBadge className=\"left-3 top-3\" />\n <span\n aria-hidden=\"true\"\n className=\"absolute bottom-3 right-3 inline-flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm transition-opacity group-hover:opacity-100 sm:opacity-80\"\n >\n <Maximize2 className=\"h-4 w-4\" />\n </span>\n <span className=\"sr-only\">Enlarge illustration</span>\n </button>\n <figcaption className=\"mt-3 text-sm font-medium text-foreground\">\n {image.caption}\n </figcaption>\n </figure>\n <p className=\"leading-relaxed text-muted-foreground\">\n {image.description}\n </p>\n </div>\n );\n}\n\n/**\n * `/concept/:slug` — one concept: hero illustration, the copy, every illustration with its\n * caption and description, related concepts and previous / next by `order`.\n */\nexport function ConceptDetailPage(props: ConceptDetailPageProps) {\n // Keyed by slug: a router reuses this component when the visitor moves from one concept\n // to another, and that is a new page — lightbox closed, no stale focus target — not an\n // update of the old one.\n return <ConceptDetail key={props.concept.slug} {...props} />;\n}\n\nfunction ConceptDetail({\n productName,\n siteUrl,\n concept,\n concepts,\n categories,\n cta,\n linkComponent,\n className,\n}: ConceptDetailPageProps) {\n const Link = linkComponent ?? DefaultConceptLink;\n const base = normaliseSiteUrl(siteUrl);\n const headingId = useId();\n\n const ordered = useMemo(() => sortByOrder(concepts), [concepts]);\n const position = ordered.findIndex((item) => item.slug === concept.slug);\n const previous = position > 0 ? ordered[position - 1] : undefined;\n const next =\n position >= 0 && position < ordered.length - 1\n ? ordered[position + 1]\n : undefined;\n\n // Curated related concepts first; the rest of the category when none resolve. A slug\n // listed twice (the generator accepts repeats) still shows one card.\n const related = useMemo(() => {\n const bySlug = new Map(ordered.map((item) => [item.slug, item]));\n const curated = [...new Set(concept.related)]\n .map((slug) => bySlug.get(slug))\n .filter(\n (item): item is Concept =>\n item !== undefined && item.slug !== concept.slug,\n );\n const list =\n curated.length > 0\n ? curated\n : ordered.filter(\n (item) =>\n item.category === concept.category && item.slug !== concept.slug,\n );\n return list.slice(0, RELATED_LIMIT);\n }, [concept, ordered]);\n const relatedIsCurated = concept.related.some((slug) =>\n related.some((item) => item.slug === slug),\n );\n const categoryDescription = categories?.find(\n (category) => category.name === concept.category,\n )?.description;\n\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n const openLightbox = useCallback((index: number, trigger: HTMLElement) => {\n triggerRef.current = trigger;\n setLightboxIndex(index);\n }, []);\n const closeLightbox = useCallback(() => setLightboxIndex(null), []);\n\n // Focus goes back to the control that opened the lightbox — not to the top of the page,\n // which would strand a keyboard user far from where they were reading.\n useEffect(() => {\n if (lightboxIndex !== null) return;\n const trigger = triggerRef.current;\n if (!trigger) return;\n triggerRef.current = null;\n if (trigger.isConnected) trigger.focus();\n }, [lightboxIndex]);\n\n const canonical = absoluteUrl(base, conceptPath(concept.slug));\n const hero = concept.images[0];\n const imageTotal = concept.images.length;\n const solutions = concept.solutions ?? [];\n const solutionCount = solutions.length;\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ImageGallery\",\n name: concept.title,\n description: concept.metaDescription,\n url: canonical,\n keywords: concept.keywords.join(\", \"),\n about: { \"@type\": \"Thing\", name: productName },\n image: concept.images.map((image) => ({\n \"@type\": \"ImageObject\",\n contentUrl: absoluteUrl(base, image.src),\n thumbnailUrl: absoluteUrl(base, image.thumb),\n name: image.title,\n caption: image.caption,\n description: image.description,\n width: image.width,\n height: image.height,\n })),\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n { \"@type\": \"ListItem\", position: 1, name: \"Home\", item: `${base}/` },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: \"Concepts\",\n item: `${base}${CONCEPTS_PATH}`,\n },\n {\n \"@type\": \"ListItem\",\n position: 3,\n name: concept.title,\n item: canonical,\n },\n ],\n },\n ],\n [base, canonical, concept, productName],\n );\n\n return (\n <article\n data-concepts=\"detail\"\n data-slug={concept.slug}\n aria-labelledby={headingId}\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title={`${concept.title} — Concept`}\n description={concept.metaDescription}\n productName={productName}\n keywords={concept.keywords.join(\", \")}\n image={hero ? absoluteUrl(base, hero.src) : undefined}\n url={canonical}\n structuredData={structuredData}\n />\n\n <header className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-6xl px-4 pb-10 pt-8 sm:px-6 lg:px-8\">\n <nav aria-label=\"Breadcrumb\">\n <ol className=\"flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground\">\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href=\"/\"\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n Home\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href={CONCEPTS_PATH}\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n Concepts\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li\n aria-current=\"page\"\n className=\"min-w-0 truncate text-foreground\"\n >\n {concept.title}\n </li>\n </ol>\n </nav>\n\n <div className=\"mt-6 flex flex-wrap items-center gap-2\">\n <span\n data-concepts=\"category\"\n title={categoryDescription}\n className=\"inline-flex items-center rounded-full border border-primary/30 bg-primary/10 px-3 py-1 text-xs font-semibold text-primary\"\n >\n {concept.category}\n </span>\n <span className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground\">\n <ImageIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {illustrationCount(imageTotal)}\n </span>\n {solutionCount > 0 ? (\n <a\n href=\"#concept-solutions\"\n data-concepts=\"solutions-chip\"\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {solutionCount === 1\n ? \"Part of 1 industry solution\"\n : `Part of ${solutionCount} industry solutions`}\n </a>\n ) : null}\n </div>\n <h1\n id={headingId}\n className=\"mt-4 max-w-4xl text-3xl font-bold tracking-tight text-foreground sm:text-4xl lg:text-5xl\"\n >\n {concept.title}\n </h1>\n <p className=\"mt-4 max-w-3xl text-lg leading-relaxed text-muted-foreground\">\n {concept.tagline}\n </p>\n <IllustrationNotice className=\"mt-6 max-w-3xl\" />\n </div>\n </header>\n\n {hero ? (\n <div className=\"mx-auto max-w-6xl px-4 pt-10 sm:px-6 lg:px-8\">\n {/* No data-llms-image and no caption: the gallery below carries this image, and\n the extractor must see it exactly once. */}\n <figure data-concepts=\"hero\">\n <button\n type=\"button\"\n onClick={(event) => openLightbox(0, event.currentTarget)}\n className={cn(\n \"group relative block w-full overflow-hidden rounded-2xl border border-border bg-muted shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n isPortrait(hero.width, hero.height) && \"p-4 sm:p-6\",\n )}\n >\n <img\n src={hero.src}\n alt={hero.alt}\n width={hero.width}\n height={hero.height}\n loading=\"eager\"\n {...HERO_FETCH_PRIORITY}\n className=\"mx-auto block h-auto max-h-[75vh] w-auto max-w-full\"\n />\n <IllustrationBadge className=\"left-3 top-3\" />\n <span\n aria-hidden=\"true\"\n className=\"absolute bottom-3 right-3 inline-flex items-center gap-1.5 rounded-full border border-border bg-background/90 px-3 py-1 text-xs font-medium text-foreground shadow-sm\"\n >\n <Maximize2 className=\"h-3.5 w-3.5\" />\n Enlarge\n </span>\n <span className=\"sr-only\">Enlarge illustration</span>\n </button>\n </figure>\n </div>\n ) : null}\n\n <div className=\"mx-auto max-w-6xl px-4 py-14 sm:px-6 lg:px-8\">\n <div className=\"max-w-3xl space-y-12\">\n {concept.overview.length > 0 ? (\n <section aria-labelledby={`${headingId}-overview`}>\n <h2 id={`${headingId}-overview`} className={SECTION_HEADING}>\n Overview\n </h2>\n <div className=\"mt-4 space-y-4 text-base leading-relaxed text-foreground\">\n {concept.overview.map((paragraph, index) => (\n <p key={copyKey(index, paragraph)}>{paragraph}</p>\n ))}\n </div>\n </section>\n ) : null}\n\n {concept.highlights.length > 0 ? (\n <section aria-labelledby={`${headingId}-highlights`}>\n <h2 id={`${headingId}-highlights`} className={SECTION_HEADING}>\n What this concept shows\n </h2>\n <ul role=\"list\" className=\"mt-4 space-y-3\">\n {concept.highlights.map((highlight, index) => (\n <li\n key={copyKey(index, highlight)}\n className=\"flex items-start gap-3 leading-relaxed text-foreground\"\n >\n <span\n aria-hidden=\"true\"\n className=\"mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\"\n >\n <Check className=\"h-3.5 w-3.5\" />\n </span>\n <span>{highlight}</span>\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {concept.workflow.length > 0 ? (\n <section aria-labelledby={`${headingId}-workflow`}>\n <h2 id={`${headingId}-workflow`} className={SECTION_HEADING}>\n How it works\n </h2>\n <WorkflowNotice />\n <ol role=\"list\" className=\"mt-4 space-y-4\">\n {concept.workflow.map((step, index) => (\n <li\n key={copyKey(index, step)}\n className=\"flex items-start gap-4\"\n >\n <span\n aria-hidden=\"true\"\n className=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-border bg-card text-sm font-semibold tabular-nums text-foreground\"\n >\n {index + 1}\n </span>\n <span className=\"pt-0.5 leading-relaxed text-foreground\">\n {step}\n </span>\n </li>\n ))}\n </ol>\n </section>\n ) : null}\n\n {concept.audience.length > 0 ? (\n <section aria-labelledby={`${headingId}-audience`}>\n <h2 id={`${headingId}-audience`} className={SECTION_HEADING}>\n {\"Who it's for\"}\n </h2>\n <ul role=\"list\" className=\"mt-4 flex flex-wrap gap-2\">\n {concept.audience.map((who, index) => (\n <li key={copyKey(index, who)} className={CHIP}>\n {who}\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n </div>\n\n {imageTotal > 0 ? (\n <section\n aria-labelledby={`${headingId}-illustrations`}\n className=\"mt-16\"\n >\n <div className=\"max-w-3xl\">\n <h2 id={`${headingId}-illustrations`} className={SECTION_HEADING}>\n Illustrations\n </h2>\n <p className=\"mt-2 text-muted-foreground\">\n {illustrationCount(imageTotal)} of this concept. Select one to\n view it full size.\n </p>\n </div>\n <div className=\"mt-8 space-y-14\">\n {concept.images.map((image, index) => (\n <IllustrationFigure\n key={image.key}\n image={image}\n onOpen={(trigger) => openLightbox(index, trigger)}\n />\n ))}\n </div>\n </section>\n ) : null}\n\n {concept.keywords.length > 0 ? (\n <section aria-labelledby={`${headingId}-topics`} className=\"mt-16\">\n <h2 id={`${headingId}-topics`} className={SECTION_HEADING}>\n Topics\n </h2>\n <ul role=\"list\" className=\"mt-4 flex flex-wrap gap-2\">\n {concept.keywords.map((keyword, index) => (\n <li key={copyKey(index, keyword)} className={CHIP}>\n {keyword}\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {related.length > 0 ? (\n <section\n aria-labelledby={`${headingId}-related`}\n data-concepts=\"related\"\n className=\"mt-16\"\n >\n <h2 id={`${headingId}-related`} className={SECTION_HEADING}>\n {relatedIsCurated\n ? \"Related concepts\"\n : `More in ${concept.category}`}\n </h2>\n <ul\n role=\"list\"\n className={cn(\n \"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2\",\n related.length >= 4 ? \"lg:grid-cols-4\" : \"lg:grid-cols-3\",\n )}\n >\n {related.map((item) => (\n <li key={item.slug} data-concepts=\"card\" data-slug={item.slug}>\n <ConceptCard concept={item} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {solutionCount > 0 ? (\n <SolutionsSection\n id=\"concept-solutions\"\n title={\n solutionCount === 1\n ? \"Part of an industry solution\"\n : \"Part of industry solutions\"\n }\n lead={`This concept appears in ${solutionCount === 1 ? \"a cross-product solution\" : \"cross-product solutions\"} on burdenoff.com — see how it works alongside other Burdenoff products to solve a problem in that industry.`}\n solutions={solutions}\n className=\"mt-16\"\n />\n ) : null}\n\n {previous || next ? (\n <nav\n aria-label=\"Previous and next concepts\"\n data-concepts=\"pager\"\n className=\"mt-16 grid grid-cols-1 gap-4 sm:grid-cols-2\"\n >\n {previous ? (\n <Link\n href={conceptPath(previous.slug)}\n className=\"group flex items-center gap-3 rounded-2xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n Previous concept\n </span>\n <span className=\"block truncate font-semibold\">\n {previous.title}\n </span>\n </span>\n </Link>\n ) : (\n <span className=\"hidden sm:block\" />\n )}\n {next ? (\n <Link\n href={conceptPath(next.slug)}\n className=\"group flex items-center justify-end gap-3 rounded-2xl border border-border bg-card p-4 text-right text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n Next concept\n </span>\n <span className=\"block truncate font-semibold\">\n {next.title}\n </span>\n </span>\n <ArrowRight\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n </Link>\n ) : null}\n </nav>\n ) : null}\n\n <div className=\"mt-10\">\n <Link\n href={CONCEPTS_PATH}\n className=\"inline-flex items-center gap-2 rounded text-sm font-medium text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft aria-hidden=\"true\" className=\"h-4 w-4\" />\n All {productName} concepts\n </Link>\n </div>\n </div>\n\n {cta ? (\n <section\n data-concepts=\"cta\"\n className=\"border-t border-border bg-muted/30\"\n >\n <div className=\"mx-auto flex max-w-6xl flex-wrap items-center gap-4 px-4 py-12 sm:px-6 lg:px-8\">\n {cta}\n </div>\n </section>\n ) : null}\n\n {lightboxIndex !== null ? (\n <ConceptLightbox\n images={concept.images}\n index={lightboxIndex}\n conceptTitle={concept.title}\n onIndexChange={setLightboxIndex}\n onClose={closeLightbox}\n />\n ) : null}\n </article>\n );\n}\n","/**\n * Localisation for the published answer pages.\n *\n * Same arrangement, and the same reasons, as `explore-i18n.ts`: the strings are bundled\n * rather than fetched, because these pages are prerendered and a runtime translation request\n * in front of the first paint would defeat the point of prerendering them. The locale set,\n * the resolver and the `{placeholder}` filler are IMPORTED from there rather than repeated —\n * one locale list for the whole explore surface, so a seventh language is added in one place.\n *\n * ## What is localised, and what is not\n *\n * The chrome — headings, labels, the provenance note, the breadcrumb — is localised into the\n * six locales the products ship. **The answer itself is English**, because that is what the\n * harness produced for the curated English question; nothing here translates it, and nothing\n * here pretends it is translated.\n *\n * That split is also MARKED UP, not merely true: the pages carry `dir=\"rtl\"` on their own\n * subtree in Arabic (`isRtlLocale`, re-exported here so the pages have one locale module), and\n * put `lang=\"en\"` on the English content inside it. A page that declares itself Arabic and\n * then prints an English answer tells a screen reader to read English with Arabic phonemes,\n * and tells a crawler the answer is in a language it is not.\n *\n * ## The borrowed strings\n *\n * `answerTable`, `conceptIllustration`, `opensInNewTab` and the product-video card's and\n * player's words (`productVideo`, `productVideoTitle`, `playVideo`, `closeVideo`,\n * `enterFullScreen`, `exitFullScreen`, `videoUnavailable`) come straight from\n * `exploreStrings`. They are the\n * words the ANSWER BODY renders, and the answer body is the same component on both surfaces\n * — two phrasings for the same caveat read as two different caveats, which is the rule the\n * illustration badge already follows.\n */\n\nimport {\n type ExploreLocale,\n exploreStrings,\n fill,\n isRtlLocale,\n resolveExploreLocale,\n} from \"./explore-i18n\";\n\nimport type { AnswerRendererStrings } from \"./explore-answer\";\n\nexport { fill, isRtlLocale, resolveExploreLocale };\nexport type { ExploreLocale };\n\nexport interface AnswerStrings extends AnswerRendererStrings {\n breadcrumbHome: string;\n /** The section's own name: breadcrumb, nav item, back link. */\n answers: string;\n /** The index page's `<h1>`. Takes `{product}`. */\n indexHeading: string;\n /** The lead under it. Takes `{product}`. */\n indexLead: string;\n /** `<title>` of the index page; PageHead appends the product name itself. */\n seoIndexTitle: string;\n /** Its `<meta name=\"description\">`. Takes `{product}`. */\n seoIndexDescription: string;\n searchLabel: string;\n searchPlaceholder: string;\n filterByTopic: string;\n allTopics: string;\n /** Takes `{shown}` and `{total}`. */\n showingCount: string;\n noMatchesTitle: string;\n noMatchesBody: string;\n clearFilters: string;\n noneYetTitle: string;\n /** Takes `{product}`. */\n noneYetBody: string;\n questionCountOne: string;\n /** Takes `{count}`. */\n questionCountMany: string;\n sourceCountOne: string;\n /** Takes `{count}`. */\n sourceCountMany: string;\n answerHeading: string;\n sourcesHeading: string;\n sourcesLead: string;\n aboutTitle: string;\n /**\n * The honest description of what the reader is looking at. Takes `{date}`.\n *\n * Every clause is load-bearing, and the wording was chosen against the alternatives:\n *\n * - **\"Produced by our own assistant\"** — not \"written by our team\", which would be false,\n * and not \"AI-powered answers\", which is marketing language for a disclosure.\n * - **\"on {date}\"** — an answer is a snapshot of what the documentation said on a day. The\n * single genuinely misleading thing these pages could do is present a year-old answer as\n * current, so the date is in the sentence rather than in small print beside it.\n * - **\"The pages it drew on are linked under the answer\"** — it tells the reader where to\n * check, which is the only thing that makes the rest of the note actionable.\n * - **\"not a statement from a person\"** — the sentence people actually need. This is a\n * marketing surface, and a visitor who takes a generated paragraph for a commitment from\n * us has been misled by us.\n * - **\"where it and a linked page disagree, the page is right\"** — says which source wins,\n * instead of a hedge (\"may contain errors\") that tells nobody what to do about it.\n *\n * Deliberately NOT said: that the answers are \"frequently asked\" or \"the questions our\n * customers ask most\". They are a question set we chose. We have no measurement behind a\n * popularity claim — and the one table that could measure it is the visitor question log,\n * which this feature must never read (see `answers-types.ts`).\n */\n aboutBody: string;\n /** Takes `{date}`. */\n answeredOn: string;\n topicsHeading: string;\n relatedHeading: string;\n /** Takes `{topic}`. */\n moreInTopic: string;\n previousQuestion: string;\n nextQuestion: string;\n /** Takes `{product}`. */\n allAnswers: string;\n askYourOwn: string;\n}\n\n/** The chrome half — everything but the strings borrowed from `exploreStrings`. */\ntype AnswerChrome = Omit<AnswerStrings, keyof AnswerRendererStrings>;\n\n/**\n * English is the source of truth. Every other locale is a FULL object, so a missing key is a\n * type error at build time rather than a raw key on a live marketing page.\n */\nconst EN: AnswerChrome = {\n breadcrumbHome: \"Home\",\n answers: \"Answers\",\n indexHeading: \"{product} answers\",\n indexLead:\n \"Questions about {product}, each answered by our own assistant from our published documentation — with links to the pages the answer came from.\",\n seoIndexTitle: \"Answers\",\n seoIndexDescription:\n \"Questions about {product}, answered from our published documentation, each with links to the pages the answer came from.\",\n searchLabel: \"Search questions\",\n searchPlaceholder: \"Search questions\",\n filterByTopic: \"Filter by topic\",\n allTopics: \"All\",\n showingCount: \"Showing {shown} of {total} questions\",\n noMatchesTitle: \"No questions match your filters\",\n noMatchesBody: \"Try a different search, or show every topic.\",\n clearFilters: \"Clear filters\",\n noneYetTitle: \"No answers published yet\",\n noneYetBody: \"{product} answers will appear here as they are published.\",\n questionCountOne: \"1 question\",\n questionCountMany: \"{count} questions\",\n sourceCountOne: \"1 source\",\n sourceCountMany: \"{count} sources\",\n answerHeading: \"Answer\",\n sourcesHeading: \"Sources\",\n sourcesLead: \"The pages this answer was drawn from.\",\n aboutTitle: \"About this answer\",\n aboutBody:\n \"Produced by our own assistant on {date} from our published documentation. The pages it drew on are linked under the answer. It is generated text, not a statement from a person — where it and a linked page disagree, the page is right.\",\n answeredOn: \"Answered {date}\",\n topicsHeading: \"Topics\",\n relatedHeading: \"Related questions\",\n moreInTopic: \"More in {topic}\",\n previousQuestion: \"Previous question\",\n nextQuestion: \"Next question\",\n allAnswers: \"All {product} answers\",\n askYourOwn: \"Ask your own question\",\n};\n\nconst ZH: AnswerChrome = {\n breadcrumbHome: \"首页\",\n answers: \"问答\",\n indexHeading: \"{product} 问答\",\n indexLead:\n \"关于 {product} 的问题,每个回答都由我们自己的助手依据已公开的文档生成,并附上回答所依据页面的链接。\",\n seoIndexTitle: \"问答\",\n seoIndexDescription:\n \"关于 {product} 的问题,依据我们已公开的文档作答,每个回答都附有来源页面的链接。\",\n searchLabel: \"搜索问题\",\n searchPlaceholder: \"搜索问题\",\n filterByTopic: \"按主题筛选\",\n allTopics: \"全部\",\n showingCount: \"显示 {total} 个问题中的 {shown} 个\",\n noMatchesTitle: \"没有符合筛选条件的问题\",\n noMatchesBody: \"换个搜索词,或显示全部主题。\",\n clearFilters: \"清除筛选\",\n noneYetTitle: \"尚未发布问答\",\n noneYetBody: \"{product} 的问答发布后会显示在这里。\",\n questionCountOne: \"1 个问题\",\n questionCountMany: \"{count} 个问题\",\n sourceCountOne: \"1 个来源\",\n sourceCountMany: \"{count} 个来源\",\n answerHeading: \"回答\",\n sourcesHeading: \"来源\",\n sourcesLead: \"本回答所依据的页面。\",\n aboutTitle: \"关于这个回答\",\n aboutBody:\n \"本回答由我们自己的助手于 {date} 依据已公开的文档生成,所依据的页面列在回答下方。这是自动生成的文本,并非某位同事的说法——如果它与所链接的页面不一致,请以页面为准。\",\n answeredOn: \"回答于 {date}\",\n topicsHeading: \"主题\",\n relatedHeading: \"相关问题\",\n moreInTopic: \"更多「{topic}」问题\",\n previousQuestion: \"上一个问题\",\n nextQuestion: \"下一个问题\",\n allAnswers: \"全部 {product} 问答\",\n askYourOwn: \"提出你的问题\",\n};\n\nconst HI: AnswerChrome = {\n breadcrumbHome: \"होम\",\n answers: \"उत्तर\",\n indexHeading: \"{product} के उत्तर\",\n indexLead:\n \"{product} से जुड़े सवाल, जिनका उत्तर हमारा अपना सहायक हमारे प्रकाशित दस्तावेज़ों से देता है — और जिन पन्नों से उत्तर आया, उनके लिंक साथ में हैं।\",\n seoIndexTitle: \"उत्तर\",\n seoIndexDescription:\n \"{product} से जुड़े सवालों के उत्तर, हमारे प्रकाशित दस्तावेज़ों से — हर उत्तर के साथ स्रोत पन्नों के लिंक।\",\n searchLabel: \"सवाल खोजें\",\n searchPlaceholder: \"सवाल खोजें\",\n filterByTopic: \"विषय से छाँटें\",\n allTopics: \"सभी\",\n showingCount: \"{total} में से {shown} सवाल दिख रहे हैं\",\n noMatchesTitle: \"आपकी छँटाई से कोई सवाल मेल नहीं खाता\",\n noMatchesBody: \"कुछ और खोजें, या सभी विषय दिखाएँ।\",\n clearFilters: \"छँटाई हटाएँ\",\n noneYetTitle: \"अभी कोई उत्तर प्रकाशित नहीं हुआ\",\n noneYetBody: \"{product} के उत्तर प्रकाशित होते ही यहाँ दिखेंगे।\",\n questionCountOne: \"1 सवाल\",\n questionCountMany: \"{count} सवाल\",\n sourceCountOne: \"1 स्रोत\",\n sourceCountMany: \"{count} स्रोत\",\n answerHeading: \"उत्तर\",\n sourcesHeading: \"स्रोत\",\n sourcesLead: \"यह उत्तर जिन पन्नों से लिया गया है।\",\n aboutTitle: \"इस उत्तर के बारे में\",\n aboutBody:\n \"यह उत्तर {date} को हमारे अपने सहायक ने हमारे प्रकाशित दस्तावेज़ों से तैयार किया था। जिन पन्नों का उपयोग हुआ, वे उत्तर के नीचे दिए गए हैं। यह अपने-आप तैयार किया गया पाठ है, किसी व्यक्ति का कथन नहीं — अगर इसमें और लिंक किए गए पन्ने में फ़र्क़ हो, तो पन्ना सही है।\",\n answeredOn: \"{date} को उत्तर दिया गया\",\n topicsHeading: \"विषय\",\n relatedHeading: \"संबंधित सवाल\",\n moreInTopic: \"{topic} में और\",\n previousQuestion: \"पिछला सवाल\",\n nextQuestion: \"अगला सवाल\",\n allAnswers: \"{product} के सभी उत्तर\",\n askYourOwn: \"अपना सवाल पूछें\",\n};\n\nconst ES: AnswerChrome = {\n breadcrumbHome: \"Inicio\",\n answers: \"Respuestas\",\n indexHeading: \"Respuestas sobre {product}\",\n indexLead:\n \"Preguntas sobre {product}, respondidas por nuestro propio asistente a partir de nuestra documentación publicada, con enlaces a las páginas de las que salió cada respuesta.\",\n seoIndexTitle: \"Respuestas\",\n seoIndexDescription:\n \"Preguntas sobre {product} respondidas a partir de nuestra documentación publicada, cada una con enlaces a las páginas de origen.\",\n searchLabel: \"Buscar preguntas\",\n searchPlaceholder: \"Buscar preguntas\",\n filterByTopic: \"Filtrar por tema\",\n allTopics: \"Todas\",\n showingCount: \"Mostrando {shown} de {total} preguntas\",\n noMatchesTitle: \"Ninguna pregunta coincide con los filtros\",\n noMatchesBody: \"Prueba otra búsqueda o muestra todos los temas.\",\n clearFilters: \"Quitar filtros\",\n noneYetTitle: \"Todavía no hay respuestas publicadas\",\n noneYetBody:\n \"Las respuestas sobre {product} aparecerán aquí a medida que se publiquen.\",\n questionCountOne: \"1 pregunta\",\n questionCountMany: \"{count} preguntas\",\n sourceCountOne: \"1 fuente\",\n sourceCountMany: \"{count} fuentes\",\n answerHeading: \"Respuesta\",\n sourcesHeading: \"Fuentes\",\n sourcesLead: \"Las páginas de las que salió esta respuesta.\",\n aboutTitle: \"Sobre esta respuesta\",\n aboutBody:\n \"La preparó nuestro propio asistente el {date} a partir de nuestra documentación publicada. Las páginas que utilizó están enlazadas debajo de la respuesta. Es texto generado, no la palabra de una persona: si la respuesta y una página enlazada no coinciden, manda la página.\",\n answeredOn: \"Respondida el {date}\",\n topicsHeading: \"Temas\",\n relatedHeading: \"Preguntas relacionadas\",\n moreInTopic: \"Más de {topic}\",\n previousQuestion: \"Pregunta anterior\",\n nextQuestion: \"Pregunta siguiente\",\n allAnswers: \"Todas las respuestas sobre {product}\",\n askYourOwn: \"Haz tu propia pregunta\",\n};\n\nconst AR: AnswerChrome = {\n breadcrumbHome: \"الرئيسية\",\n answers: \"الإجابات\",\n indexHeading: \"إجابات {product}\",\n indexLead:\n \"أسئلة حول {product}، يجيب عنها مساعدنا اعتمادًا على وثائقنا المنشورة، مع روابط إلى الصفحات التي جاءت منها كل إجابة.\",\n seoIndexTitle: \"الإجابات\",\n seoIndexDescription:\n \"أسئلة حول {product} مُجاب عنها من وثائقنا المنشورة، مع روابط إلى صفحات المصدر لكل إجابة.\",\n searchLabel: \"ابحث في الأسئلة\",\n searchPlaceholder: \"ابحث في الأسئلة\",\n filterByTopic: \"تصفية حسب الموضوع\",\n allTopics: \"الكل\",\n showingCount: \"عرض {shown} من {total} سؤالًا\",\n noMatchesTitle: \"لا توجد أسئلة تطابق التصفية\",\n noMatchesBody: \"جرّب بحثًا آخر، أو اعرض كل المواضيع.\",\n clearFilters: \"مسح التصفية\",\n noneYetTitle: \"لم تُنشر إجابات بعد\",\n noneYetBody: \"ستظهر إجابات {product} هنا فور نشرها.\",\n questionCountOne: \"سؤال واحد\",\n questionCountMany: \"{count} أسئلة\",\n sourceCountOne: \"مصدر واحد\",\n sourceCountMany: \"{count} مصادر\",\n answerHeading: \"الإجابة\",\n sourcesHeading: \"المصادر\",\n sourcesLead: \"الصفحات التي استُمدت منها هذه الإجابة.\",\n aboutTitle: \"عن هذه الإجابة\",\n aboutBody:\n \"أعدّها مساعدنا في {date} اعتمادًا على وثائقنا المنشورة، والصفحات التي استند إليها مذكورة أسفل الإجابة. هذا نص مُولَّد آليًا وليس كلام شخص — وإذا اختلف مع صفحة مرتبطة، فالصفحة هي الصحيحة.\",\n answeredOn: \"أُجيب عنه في {date}\",\n topicsHeading: \"المواضيع\",\n relatedHeading: \"أسئلة ذات صلة\",\n moreInTopic: \"المزيد في {topic}\",\n previousQuestion: \"السؤال السابق\",\n nextQuestion: \"السؤال التالي\",\n allAnswers: \"كل إجابات {product}\",\n askYourOwn: \"اطرح سؤالك\",\n};\n\nconst TA: AnswerChrome = {\n breadcrumbHome: \"முகப்பு\",\n answers: \"பதில்கள்\",\n indexHeading: \"{product} பதில்கள்\",\n indexLead:\n \"{product} பற்றிய கேள்விகள் — ஒவ்வொன்றுக்கும் எங்கள் உதவியாளர் எங்கள் வெளியிடப்பட்ட ஆவணங்களிலிருந்து அளித்த பதில், பதில் வந்த பக்கங்களுக்கான இணைப்புகளுடன்.\",\n seoIndexTitle: \"பதில்கள்\",\n seoIndexDescription:\n \"{product} பற்றிய கேள்விகளுக்கு எங்கள் வெளியிடப்பட்ட ஆவணங்களிலிருந்து பதில்கள் — ஒவ்வொன்றிலும் மூலப் பக்கங்களுக்கான இணைப்புகளுடன்.\",\n searchLabel: \"கேள்விகளைத் தேடுங்கள்\",\n searchPlaceholder: \"கேள்விகளைத் தேடுங்கள்\",\n filterByTopic: \"தலைப்பின்படி வடிகட்டு\",\n allTopics: \"அனைத்தும்\",\n showingCount: \"{total} கேள்விகளில் {shown} காட்டப்படுகிறது\",\n noMatchesTitle: \"வடிகட்டலுக்குப் பொருந்தும் கேள்வி இல்லை\",\n noMatchesBody:\n \"வேறு ஒன்றைத் தேடுங்கள், அல்லது எல்லாத் தலைப்புகளையும் காட்டுங்கள்.\",\n clearFilters: \"வடிகட்டலை நீக்கு\",\n noneYetTitle: \"இதுவரை பதில்கள் வெளியிடப்படவில்லை\",\n noneYetBody: \"{product} பதில்கள் வெளியிடப்படும்போது இங்கே தோன்றும்.\",\n questionCountOne: \"1 கேள்வி\",\n questionCountMany: \"{count} கேள்விகள்\",\n sourceCountOne: \"1 மூலம்\",\n sourceCountMany: \"{count} மூலங்கள்\",\n answerHeading: \"பதில்\",\n sourcesHeading: \"மூலங்கள்\",\n sourcesLead: \"இந்தப் பதில் எடுக்கப்பட்ட பக்கங்கள்.\",\n aboutTitle: \"இந்தப் பதில் பற்றி\",\n aboutBody:\n \"இதை எங்கள் உதவியாளர் {date} அன்று எங்கள் வெளியிடப்பட்ட ஆவணங்களிலிருந்து உருவாக்கியது; பயன்படுத்திய பக்கங்கள் பதிலுக்குக் கீழே இணைக்கப்பட்டுள்ளன. இது தானாக உருவாக்கப்பட்ட உரை, ஒரு நபரின் கூற்று அல்ல — இதற்கும் இணைக்கப்பட்ட பக்கத்திற்கும் வேறுபாடு இருந்தால், பக்கமே சரி.\",\n answeredOn: \"{date} அன்று பதிலளிக்கப்பட்டது\",\n topicsHeading: \"தலைப்புகள்\",\n relatedHeading: \"தொடர்புடைய கேள்விகள்\",\n moreInTopic: \"{topic} இல் மேலும்\",\n previousQuestion: \"முந்தைய கேள்வி\",\n nextQuestion: \"அடுத்த கேள்வி\",\n allAnswers: \"{product} அனைத்துப் பதில்களும்\",\n askYourOwn: \"உங்கள் கேள்வியைக் கேளுங்கள்\",\n};\n\nconst CHROME: Record<ExploreLocale, AnswerChrome> = {\n en: EN,\n zh: ZH,\n hi: HI,\n es: ES,\n ar: AR,\n ta: TA,\n};\n\nexport function answerStrings(locale: ExploreLocale): AnswerStrings {\n const chrome = CHROME[locale] ?? EN;\n const explore = exploreStrings(locale);\n return {\n ...chrome,\n answerTable: explore.answerTable,\n conceptIllustration: explore.conceptIllustration,\n opensInNewTab: explore.opensInNewTab,\n productVideo: explore.productVideo,\n productVideoTitle: explore.productVideoTitle,\n playVideo: explore.playVideo,\n closeVideo: explore.closeVideo,\n enterFullScreen: explore.enterFullScreen,\n exitFullScreen: explore.exitFullScreen,\n videoUnavailable: explore.videoUnavailable,\n };\n}\n\n/**\n * The BCP-47 tag a date is formatted with.\n *\n * Deliberately NOT the speech tags `explore-i18n` uses: `ar-SA` selects the Umm al-Qura\n * calendar in ICU, so an answer dated 2026-09-22 would publish as a Hijri date nobody\n * intended and no other locale on the page agrees with. Plain `ar` keeps the Gregorian\n * calendar.\n *\n * English is `en-GB` for the day-month order; the month is spelled out either way, so the\n * date is unambiguous to every reader rather than only to one hemisphere.\n */\nconst DATE_TAGS: Record<ExploreLocale, string> = {\n en: \"en-GB\",\n zh: \"zh-CN\",\n hi: \"hi-IN\",\n es: \"es-ES\",\n ar: \"ar\",\n ta: \"ta-IN\",\n};\n\n/**\n * `answeredAt` as a date a person reads.\n *\n * Two things are pinned rather than left to the environment, because these pages are\n * serialised from the post-hydration DOM: the machine that prerenders them and the browser\n * that hydrates them must produce the SAME string, or React replaces the node on hydration.\n *\n * - **An explicit locale tag**, never the ambient default — the prerender runs in headless\n * Chromium on a server whose locale is nobody's.\n * - **An explicit numbering system.** CLDR has changed the default digits for `ar` before;\n * two engines on different CLDR versions would then render the same date differently, and\n * the text React hydrated would not be the text it prerendered. All six locales already\n * default to Latin digits, so this pins today's output rather than changing it.\n * - **`timeZone: \"UTC\"`**, because `new Date(\"2026-09-22\")` is UTC midnight and formatting it\n * in a negative-offset zone would print the 21st. A published date that moves by a day\n * depending on who looks at it is worse than no date.\n *\n * Returns `\"\"` for an unparseable value so a bad row loses its date line rather than printing\n * \"Invalid Date\" on a marketing page.\n */\nexport function formatAnswerDate(value: string, locale: ExploreLocale): string {\n const at = new Date(value);\n if (Number.isNaN(at.getTime())) return \"\";\n try {\n return new Intl.DateTimeFormat(DATE_TAGS[locale] ?? \"en-GB\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n timeZone: \"UTC\",\n numberingSystem: \"latn\",\n }).format(at);\n } catch {\n // An engine without the locale data still shows the day, in the form it was stored.\n return value.slice(0, 10);\n }\n}\n","/**\n * Published answers — the shared data contract.\n *\n * ## Where the questions come from, and where they must NEVER come from\n *\n * Every product website publishes a set of question-and-answer pages built from a **curated\n * question list**, answered by the live explore API against the baked corpus. The question\n * list is written by us; the answer is the harness's own output for that question.\n *\n * They are **never** built from stored visitor conversations. `explore_messages` holds every\n * question a real visitor has typed into `/explore`, and publishing those as indexed pages\n * would be a privacy breach. That the rows carry no name does not save it: a question is not\n * anonymous content. \"Our farm outside Coimbatore has three staff and we are being billed X\"\n * identifies a business with nobody's name attached, and the person who typed it consented to\n * being answered, not to being published. That table is an analytics and answer-quality input,\n * which is what it was built for.\n *\n * So: nothing in this module, in `answers.tsx`, or in whatever generates a site's\n * `src/data/answers.ts` may read `ExploreMessage`, `ExploreConversation` or `ExploreFeedback`\n * rows. A {@link PublishedAnswer} has no conversation id, no message id, no visitor field and\n * no free text that came from one — by construction, not by a denylist, because a denylist\n * leaks the first column nobody thought of.\n *\n * ## The same care downstream\n *\n * A published answer must not contain anything that is not already public on our own\n * websites. The harness only answers from the corpus, which is built from published pages, and\n * every source here is a public URL — {@link isPublishedSourceUrl} is the page's own last\n * check before it renders one as a link.\n *\n * ## Shape\n *\n * Each site ships a generated `src/data/answers.ts` exporting `ANSWERS`, `ANSWER_TOPICS` and\n * `ANSWERS_PRODUCT_NAME`, typed against these interfaces — the same arrangement the concept\n * pages use (`dev/platform/context/publishing/concepts/01-architecture.md`). A field renamed here changes\n * every site's generated data module, so change the generator and this file together.\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\n/**\n * One page an answer cited.\n *\n * Always a public URL on one of our own sites: the harness strips every link whose origin is\n * not in its catalog before the answer is ever stored, and this is what the page renders as a\n * real, followable link under the answer.\n */\nexport interface PublishedAnswerSource {\n /** Absolute `https://` URL of the page. */\n url: string;\n /** The page's own title, as published. */\n title: string;\n /** Product display name, when the page belongs to one product. */\n product?: string;\n}\n\n/** A curated question, and the answer our assistant produced for it. */\nexport interface PublishedAnswer {\n /** Kebab-case, unique per site; the `/answer/<slug>` route. */\n slug: string;\n /** 1-based position across the site's answers; drives listing order and previous/next. */\n order: number;\n /** The question, as we wrote it. The page's `<h1>`. */\n question: string;\n /**\n * The answer, as GitHub-flavoured markdown — exactly what the harness returned.\n *\n * It can contain GFM tables (a comparison or a plan list comes back as one; see\n * `dev/platform/context/publishing/explore/CONTRACT.md` §7), links and concept illustrations, so it is\n * rendered by the SAME renderer the chat uses and not by a second one.\n */\n answer: string;\n /** Grouping on the index page; matches a {@link PublishedAnswerTopic} name. */\n topic: string;\n /** One line under the question, on the card and in the hero. */\n summary: string;\n /** The `<meta name=\"description\">` for this answer's page. */\n metaDescription: string;\n /** Search keywords, also used by the index page's filter. */\n keywords: string[];\n /** The pages the answer cited, in the order it cited them. */\n sources: PublishedAnswerSource[];\n /** Slugs of related answers on the same site. */\n related: string[];\n /**\n * When the answer was produced, ISO-8601 (`2026-09-22`, or a full timestamp).\n *\n * Shown on the page and put in the structured data. An answer is a snapshot of what the\n * documentation said on a day; publishing it without saying which day would be the one\n * genuinely misleading thing about these pages.\n */\n answeredAt: string;\n}\n\n/**\n * Every field a {@link PublishedAnswer} has, written out once.\n *\n * Typed as a TOTAL map of the interface's keys: adding a field to {@link PublishedAnswer}\n * does not compile until someone also writes it down here, and removing one does not compile\n * until someone deletes it here. That is the point — the field that would break this feature's\n * one rule is a conversation id, a message id or a visitor's own words, and nobody adds one of\n * those to a published contract by accident twice.\n *\n * It lives in this module, not in a test, because `tsconfig.json` excludes `**\\/*.test.ts(x)`\n * from the program: a totality constraint written in a test file is never compiled and can\n * therefore never fail. Here it is compiled by `bun run type-check`, which the PR gate and both\n * publish workflows run, so the constraint is enforced on every path that ships this package.\n *\n * `answers.ssr.test.tsx` then checks the runtime half: that this list still matches the\n * interface field for field, and that no name in it could hold a visitor's conversation. Sites\n * generating `src/data/answers.ts` can use it the same way, to assert a generated row carries\n * these keys and no others.\n */\nexport const PUBLISHED_ANSWER_FIELDS: Record<keyof PublishedAnswer, true> = {\n slug: true,\n order: true,\n question: true,\n answer: true,\n topic: true,\n summary: true,\n metaDescription: true,\n keywords: true,\n sources: true,\n related: true,\n answeredAt: true,\n};\n\nexport interface PublishedAnswerTopic {\n name: string;\n description: string;\n}\n\n/** Props the pages pass to a site's link adapter. */\nexport interface AnswerLinkProps {\n href: string;\n className?: string;\n children: ReactNode;\n \"aria-label\"?: string;\n}\n\n/**\n * The link the pages render for every internal URL. Sites pass a small adapter around their\n * router's `Link`, so moving between answers stays a client-side navigation; without one the\n * pages fall back to a plain `<a href>`.\n */\nexport type AnswerLinkComponent = ComponentType<AnswerLinkProps>;\n\n/** The index route. */\nexport const ANSWERS_PATH = \"/answers\";\n\n/** Prefix of every answer detail route: `/answer/<slug>`. */\nexport const ANSWER_PATH_PREFIX = \"/answer\";\n\n/** Site-relative URL of one answer's page. */\nexport function answerPath(slug: string): string {\n // Slugs are generated as [a-z0-9-], so this is a no-op for real data; it only keeps a\n // malformed slug from escaping its path segment.\n return `${ANSWER_PATH_PREFIX}/${encodeURIComponent(slug)}`;\n}\n\n/**\n * Resolve a route parameter to its answer. Returns `undefined` for an unknown slug — the site\n * then redirects to `/answers` rather than rendering a soft 404.\n */\nexport function getAnswerBySlug(\n answers: readonly PublishedAnswer[],\n slug: string | null | undefined,\n): PublishedAnswer | undefined {\n if (!slug) return undefined;\n const wanted = slug.trim().toLowerCase();\n if (!wanted) return undefined;\n return answers.find((answer) => answer.slug === wanted);\n}\n\n/**\n * True when a source URL is safe to publish as a link.\n *\n * `https` only, and a real host: these pages are prerendered and crawled, so a `javascript:`\n * or `data:` URL that reached the generated data would ship to every visitor as a live link,\n * and a relative one would resolve against whichever answer page happened to render it. The\n * ORIGIN allow-list belongs in the generator, which knows the catalog; this is the page's own\n * last check, in the same spirit as the inline-image guard in the chat.\n */\nexport function isPublishedSourceUrl(url: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return false;\n }\n return (\n parsed.protocol === \"https:\" &&\n parsed.hostname !== \"\" &&\n !parsed.username &&\n !parsed.password\n );\n}\n\n/**\n * The host shown beside a source, `www.` removed.\n *\n * Same normalisation the chat's reference cards apply, so a source reads the same way whether\n * a visitor met it in a conversation or on one of these pages. Returns `\"\"` for anything\n * unparseable — the label is decorative, and {@link isPublishedSourceUrl} has already decided\n * whether the link renders at all.\n */\nexport function answerSourceHost(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n return \"\";\n }\n}\n","/**\n * Published answers — `/answers` and `/answer/:slug` on every product website.\n *\n * A published answer is a CURATED question plus the answer our own explore assistant produced\n * for it against the baked corpus. The data is generated per site (`src/data/answers.ts`) and\n * passed in; nothing here fetches, so both pages prerender completely and make no runtime\n * third-party requests — the same arrangement as the concept pages next door.\n *\n * ## The rule this feature is built around\n *\n * These pages are NEVER built from stored visitor conversations. `explore_messages` holds\n * what real people typed into the chat, and publishing that as indexed pages would be a\n * privacy breach whether or not the rows carry a name. Nothing in this module reads\n * `ExploreMessage`, `ExploreConversation` or `ExploreFeedback`, and {@link PublishedAnswer}\n * has nowhere to put one. The long version, and why \"it is anonymous\" is not a defence, is in\n * `answers-types.ts`.\n *\n * ## Written against three readers, in this order of strictness\n *\n * - **Visitors.** The page says what it is: a dated, generated answer, with the pages it drew\n * on linked under it and a sentence saying the page wins when the two disagree. Colours are\n * semantic tokens only, so every product's palette is correct in light and dark mode.\n * - **Search engines.** One `<h1>` per page (the question), a self-canonical URL, a\n * per-answer description, and JSON-LD: `FAQPage` with a single `Question` and its\n * `acceptedAnswer` on a detail page, `CollectionPage` + `ItemList` on the index, and a\n * `BreadcrumbList` on both. `FAQPage` rather than `QAPage`: `QAPage` describes a forum\n * where members post competing answers, which would misdescribe a page we wrote.\n * - **The reader who cannot see the page.** Real heading order, real lists, a labelled\n * breadcrumb, a focusable named region around a wide table, and links that say where they\n * go. The chrome is localised into six locales and the English question and answer are\n * marked as English inside it ({@link ENGLISH_TEXT}), so the Arabic page reads right to left\n * without announcing an English paragraph in Arabic. Nothing here is fixed, sticky or\n * measured in pixels, because these pages are serialised from the POST-HYDRATION DOM:\n * anything measured at render becomes static HTML for every later visitor, whatever their\n * screen.\n *\n * ## One renderer\n *\n * The answer body is markdown from the same harness the chat renders, GFM tables and all, so\n * it goes through {@link ExploreAnswerBody} — the very component `/explore` uses. A second\n * renderer would pass review the day it was written and drift the first time either half was\n * fixed. The only addition is {@link ANSWER_HEADING_SHIFT}, which demotes the answer's own\n * headings so they nest under the page's; see the note there.\n *\n * ## One thing the site wiring must get right\n *\n * The explore corpus is built from each site's prerendered `llms-full.txt`. If these pages go\n * into it, the assistant starts grounding new answers in its own published output, and a\n * mistake in one answer becomes a source for the next. **Exclude `/answers` and `/answer/*`\n * from the llms files** when wiring a site, even though they are in the sitemap: they are for\n * search engines and readers, not for the corpus.\n *\n * @example\n * ```tsx\n * import { AnswersPage, AnswerDetailPage, getAnswerBySlug } from '@burdenoff/website-sdk'\n * import { ANSWERS, ANSWER_TOPICS } from '@/data/answers'\n *\n * <AnswersPage productName=\"VibeControls\" siteUrl=\"https://vibecontrols.com\"\n * answers={ANSWERS} topics={ANSWER_TOPICS} linkComponent={SiteLink} />\n * ```\n */\n\"use client\";\n\nimport { useCallback, useId, useMemo, useState } from \"react\";\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport {\n ArrowLeft,\n ArrowRight,\n BookOpenText,\n ChevronRight,\n ExternalLink,\n Info,\n Search,\n Sparkles,\n} from \"lucide-react\";\n\nimport {\n type AnswerStrings,\n answerStrings,\n fill,\n formatAnswerDate,\n isRtlLocale,\n resolveExploreLocale,\n} from \"./answers-i18n\";\nimport {\n ANSWERS_PATH,\n answerPath,\n answerSourceHost,\n isPublishedSourceUrl,\n} from \"./answers-types\";\nimport {\n ExploreAnswerBody,\n ExploreAnswerStyles,\n answerSpeechText,\n inlineImageOrigins,\n productSlugsByOrigin,\n} from \"./explore-answer\";\nimport { ProseStyles } from \"../content/prose-styles\";\nimport { ECOSYSTEM_PRODUCTS } from \"../data/products\";\nimport { PageHead } from \"../seo/page-head\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n AnswerLinkComponent,\n AnswerLinkProps,\n PublishedAnswer,\n PublishedAnswerSource,\n PublishedAnswerTopic,\n} from \"./answers-types\";\nimport type { Components, ExtraProps } from \"react-markdown\";\n\n// ============================================================================\n// Props\n// ============================================================================\n\nexport interface AnswersPageProps {\n /** Product display name, e.g. `\"VibeControls\"`. */\n productName: string;\n /** Public origin of the site, e.g. `\"https://vibecontrols.com\"`. Used for absolute URLs. */\n siteUrl: string;\n answers: readonly PublishedAnswer[];\n /** Section order and descriptions. Answers in an unlisted topic still render, last. */\n topics?: readonly PublishedAnswerTopic[];\n /** Call to action rendered in the hero (e.g. the site's primary buttons). */\n cta?: ReactNode;\n /** Router adapter for internal links. Defaults to a plain `<a href>`. */\n linkComponent?: AnswerLinkComponent;\n /** Overrides the `<h1>`. Default: the localised `\"<productName> answers\"`. */\n title?: string;\n /** Overrides the meta description and the hero lead. */\n description?: string;\n /**\n * BCP-47 locale for the page chrome. Defaults to the document's own `lang`, then the\n * browser. The ANSWERS themselves are English whatever this says — see `answers-i18n.ts`.\n */\n locale?: string;\n /** Extra classes for the page root. */\n className?: string;\n}\n\nexport interface AnswerDetailPageProps {\n productName: string;\n siteUrl: string;\n /** The answer to render. The site resolves the slug and redirects when it is unknown. */\n answer: PublishedAnswer;\n /** Every answer on the site — for related questions and previous / next. */\n answers: readonly PublishedAnswer[];\n topics?: readonly PublishedAnswerTopic[];\n /**\n * Extra origins an illustration embedded in the answer may load from.\n *\n * The site's own origin and the origins of this answer's sources are always allowed, which\n * covers every image the harness can legitimately have embedded. Pass more only when an\n * answer cites a page whose images live elsewhere in the catalog, and pass a stable array.\n */\n imageOrigins?: readonly string[];\n /**\n * Where \"Ask your own question\" goes. `null` removes the link — pass that on a site with no\n * `/explore` route, rather than shipping a link to a page that does not exist.\n */\n askHref?: string | null;\n /** Call to action rendered as a band at the end of the page. */\n cta?: ReactNode;\n linkComponent?: AnswerLinkComponent;\n locale?: string;\n className?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst META_DESCRIPTION_LIMIT = 160;\nconst TITLE_LIMIT = 100;\nconst RELATED_LIMIT = 4;\n\n/** The origin without trailing slashes, so paths can be appended as-is. */\nfunction normaliseSiteUrl(siteUrl: string): string {\n return siteUrl.trim().replace(/\\/+$/, \"\");\n}\n\n/** Absolute form of a site-relative path; absolute URLs pass through. */\nfunction absoluteUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nfunction sortByOrder(answers: readonly PublishedAnswer[]): PublishedAnswer[] {\n return [...answers].sort(\n (a, b) => a.order - b.order || a.slug.localeCompare(b.slug),\n );\n}\n\n/** Cut at a word boundary, so a title or description never ends mid-word. */\nfunction clampText(text: string, limit: number): string {\n if (text.length <= limit) return text;\n const cut = text.slice(0, limit - 1);\n const lastSpace = cut.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\\s,;:—–-]+$/, \"\")}…`;\n}\n\nfunction questionCount(T: AnswerStrings, count: number): string {\n return count === 1\n ? T.questionCountOne\n : fill(T.questionCountMany, { count: String(count) });\n}\n\nfunction sourceCount(T: AnswerStrings, count: number): string {\n return count === 1\n ? T.sourceCountOne\n : fill(T.sourceCountMany, { count: String(count) });\n}\n\nfunction slugifyAnchor(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\n/**\n * The sources safe to render as links, in the order the answer cited them, once each.\n *\n * Two filters, each for its own reason:\n *\n * - A source that fails {@link isPublishedSourceUrl} is DROPPED rather than rendered as plain\n * text: the section says \"the pages this answer was drawn from\", and a line there that\n * cannot be followed reads as a page we are hiding.\n * - A URL cited TWICE is listed once. An answer that draws on `/pricing` for two separate\n * claims legitimately cites it twice, and nothing upstream promises otherwise — the harness\n * strips off-catalog links but does not deduplicate what is left. Rendered as-is that is the\n * same card printed twice, \"4 sources\" over three pages, the same page twice in the JSON-LD\n * `citation`, and two React children under one key.\n *\n * The FIRST occurrence wins, so the order is the order the answer cited them in and the\n * retained title is the one the answer introduced the page with.\n */\nfunction publishableSources(\n sources: readonly PublishedAnswerSource[],\n): PublishedAnswerSource[] {\n const seen = new Set<string>();\n const kept: PublishedAnswerSource[] = [];\n for (const source of sources) {\n if (!isPublishedSourceUrl(source.url) || seen.has(source.url)) continue;\n seen.add(source.url);\n kept.push(source);\n }\n return kept;\n}\n\ninterface TopicGroup {\n name: string;\n description: string;\n /** DOM id of the section heading — unique even when two names slugify alike. */\n anchor: string;\n answers: PublishedAnswer[];\n}\n\n/**\n * Answers grouped in the order `topics` lists them. Empty topics are dropped, and an answer\n * whose topic is missing from the list still gets a section (after the listed ones) rather\n * than silently disappearing from the page.\n */\nfunction groupByTopic(\n ordered: readonly PublishedAnswer[],\n topics: readonly PublishedAnswerTopic[] | undefined,\n): TopicGroup[] {\n const byName = new Map<string, PublishedAnswer[]>();\n for (const answer of ordered) {\n const list = byName.get(answer.topic);\n if (list) list.push(answer);\n else byName.set(answer.topic, [answer]);\n }\n\n const described: Array<Omit<TopicGroup, \"anchor\">> = [];\n for (const topic of topics ?? []) {\n const list = byName.get(topic.name);\n if (!list) continue;\n described.push({\n name: topic.name,\n description: topic.description,\n answers: list,\n });\n byName.delete(topic.name);\n }\n for (const [name, list] of byName) {\n described.push({ name, description: \"\", answers: list });\n }\n\n const used = new Set<string>();\n return described.map((group) => {\n const base = `answers-${slugifyAnchor(group.name) || \"topic\"}`;\n let anchor = base;\n for (let n = 2; used.has(anchor); n += 1) anchor = `${base}-${n}`;\n used.add(anchor);\n return { ...group, anchor };\n });\n}\n\nfunction searchTokens(query: string): string[] {\n return query.toLowerCase().split(/\\s+/).filter(Boolean);\n}\n\nfunction matchesSearch(\n answer: PublishedAnswer,\n tokens: readonly string[],\n): boolean {\n if (tokens.length === 0) return true;\n const haystack = [\n answer.question,\n answer.summary,\n answer.topic,\n ...answer.keywords,\n ]\n .join(\" \")\n .toLowerCase();\n return tokens.every((token) => haystack.includes(token));\n}\n\n/**\n * Key for a list rendered from the copy. The text alone collides when a list repeats an\n * entry, so the position qualifies it; these lists never reorder, so that is stable.\n */\nfunction copyKey(index: number, text: string): string {\n return `${index}-${text}`;\n}\n\n// ============================================================================\n// The answer body's headings\n// ============================================================================\n\n/**\n * A heading inside an answer, rendered one or two levels lower than it was written.\n *\n * `node` is react-markdown's hast node, not a DOM attribute, so it is dropped rather than\n * spread onto the element — the same thing `MarkdownLink` does.\n */\nfunction demoteHeading(Tag: \"h3\" | \"h4\" | \"h5\" | \"h6\") {\n function DemotedHeading({\n node: _node,\n ...props\n }: ComponentProps<\"h2\"> & ExtraProps) {\n return <Tag {...props} />;\n }\n DemotedHeading.displayName = `DemotedHeading(${Tag})`;\n return DemotedHeading;\n}\n\n/**\n * Heading overrides for a PUBLISHED answer, merged over the shared answer components.\n *\n * In the chat an answer is one message in a stream and its `#` headings bother nobody. On a\n * crawled page the outline is the page's structure: the question is the `<h1>` and \"Answer\"\n * is an `<h2>`, so an answer that opens with `## Plans` would put a second `<h2>` inside a\n * section and an answer that opens with `#` would put a SECOND `<h1>` on the page. Both are\n * things a crawler reads as the page changing subject.\n *\n * So every heading the model wrote is pushed below the page's own: `#` and `##` become `<h3>`\n * (the first real level inside the answer section), and the rest follow, floored at `<h6>`.\n * The words are untouched — only the level moves.\n *\n * Module-level on purpose: react-markdown uses an override as the element TYPE, so rebuilding\n * this object during a render would remount everything under it.\n */\nexport const ANSWER_HEADING_SHIFT: Components = {\n h1: demoteHeading(\"h3\"),\n h2: demoteHeading(\"h3\"),\n h3: demoteHeading(\"h4\"),\n h4: demoteHeading(\"h5\"),\n h5: demoteHeading(\"h6\"),\n h6: demoteHeading(\"h6\"),\n};\n\n// ============================================================================\n// Shared pieces\n// ============================================================================\n\n/**\n * Marks an element whose text is the QUESTION or the ANSWER, and therefore English on every\n * locale's page.\n *\n * The chrome is translated into all six locales; the content is not, because the harness\n * answered a curated English question and nothing here pretends otherwise. Left unmarked\n * inside an `ar` page, that English prose is announced with Arabic phonemes and indexed as\n * Arabic — so the two things the brief names, the question and the answer, say what they are.\n *\n * Deliberately NOT applied to topic names, keywords or a source's title. Those are labels of a\n * word or two, where the cost of a mispronunciation is nothing like three paragraphs read in\n * the wrong language, and tagging every data-derived string would spread this across the file\n * until nobody could tell which ones mattered.\n */\nconst ENGLISH_TEXT = { lang: \"en\" } as const;\n\n/**\n * Every product site, as the answer body reads a catalog — the same list `/explore` falls back\n * on before its server catalog lands. A published page has no catalog of its own, and a\n * product video needs one twice:\n *\n * - **`data-product`** is the product's slug in the chat, and an e2e selector written for one\n * surface must match the other. Without a map the card would name the file's host, which is\n * not the slug for HealthyBowl (gethealthybowl.com) or Workspaces (burdenoff.com).\n * - **Where the video may come from.** The page's image list is this site plus the answer's\n * sources, and a video is never a source (§7) — so on a hub page, a question about another\n * product would lose its video unless that product's pages happened to be cited.\n */\nconst ECOSYSTEM_SITES = ECOSYSTEM_PRODUCTS.map((product) => ({\n slug: product.slug,\n website: product.websiteUrl,\n}));\nconst ECOSYSTEM_PRODUCT_SLUGS = productSlugsByOrigin(ECOSYSTEM_SITES);\nconst ECOSYSTEM_ORIGINS = inlineImageOrigins(ECOSYSTEM_SITES);\n\nfunction DefaultAnswerLink({\n href,\n className,\n children,\n \"aria-label\": ariaLabel,\n}: AnswerLinkProps) {\n return (\n <a href={href} className={className} aria-label={ariaLabel}>\n {children}\n </a>\n );\n}\n\n/**\n * One question on the index: the question itself, its one-line summary, and how many pages\n * back the answer. The whole card is the link.\n */\nfunction AnswerCard({\n answer,\n strings: T,\n Link,\n}: {\n answer: PublishedAnswer;\n strings: AnswerStrings;\n Link: AnswerLinkComponent;\n}) {\n const sources = publishableSources(answer.sources).length;\n return (\n <Link\n href={answerPath(answer.slug)}\n className=\"group flex h-full flex-col gap-2 rounded-2xl border border-border bg-card p-5 text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none\"\n >\n <h3\n {...ENGLISH_TEXT}\n className=\"text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary\"\n >\n {answer.question}\n </h3>\n <p\n {...ENGLISH_TEXT}\n className=\"line-clamp-3 text-sm leading-relaxed text-muted-foreground\"\n >\n {answer.summary}\n </p>\n {sources > 0 ? (\n <span className=\"mt-auto inline-flex items-center gap-1.5 pt-2 text-xs font-medium text-muted-foreground\">\n <BookOpenText aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {sourceCount(T, sources)}\n </span>\n ) : null}\n </Link>\n );\n}\n\nfunction FilterChip({\n label,\n count,\n active,\n topic,\n onSelect,\n}: {\n label: string;\n count: number;\n active: boolean;\n topic: string;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-topic={topic}\n onClick={onSelect}\n className={cn(\n \"inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-card text-foreground hover:border-primary/40 hover:bg-muted\",\n )}\n >\n <span>{label}</span>\n <span\n className={cn(\n \"rounded-full px-1.5 text-xs tabular-nums\",\n active\n ? \"bg-primary-foreground text-primary\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {count}\n </span>\n </button>\n );\n}\n\n// ============================================================================\n// Index page\n// ============================================================================\n\n/**\n * `/answers` — every published answer on the site, grouped by topic, with a client-side\n * search and topic filter. Filters start at \"All\", so the prerendered page lists everything.\n */\nexport function AnswersPage({\n productName,\n siteUrl,\n answers,\n topics,\n cta,\n linkComponent,\n title,\n description,\n locale,\n className,\n}: AnswersPageProps) {\n const Link = linkComponent ?? DefaultAnswerLink;\n const base = normaliseSiteUrl(siteUrl);\n const searchId = useId();\n const activeLocale = useMemo(() => resolveExploreLocale(locale), [locale]);\n const T = useMemo(() => answerStrings(activeLocale), [activeLocale]);\n const rtl = isRtlLocale(activeLocale);\n\n const ordered = useMemo(() => sortByOrder(answers), [answers]);\n const groups = useMemo(\n () => groupByTopic(ordered, topics),\n [ordered, topics],\n );\n\n const [query, setQuery] = useState(\"\");\n const [activeTopic, setActiveTopic] = useState<string | null>(null);\n\n const hasAnswers = ordered.length > 0;\n const tokens = useMemo(() => searchTokens(query), [query]);\n const searched = useMemo(\n () => ordered.filter((answer) => matchesSearch(answer, tokens)),\n [ordered, tokens],\n );\n // Chip counts follow the search, so each chip says how many results it would show.\n const countsByTopic = useMemo(() => {\n const counts = new Map<string, number>();\n for (const answer of searched) {\n counts.set(answer.topic, (counts.get(answer.topic) ?? 0) + 1);\n }\n return counts;\n }, [searched]);\n const visibleGroups = useMemo(() => {\n const visible = new Set(\n searched.filter(\n (answer) => activeTopic === null || answer.topic === activeTopic,\n ),\n );\n return groups\n .map((group) => ({\n ...group,\n answers: group.answers.filter((answer) => visible.has(answer)),\n }))\n .filter((group) => group.answers.length > 0);\n }, [groups, searched, activeTopic]);\n const visibleTotal = visibleGroups.reduce(\n (sum, group) => sum + group.answers.length,\n 0,\n );\n const filtering = tokens.length > 0 || activeTopic !== null;\n\n const clearFilters = useCallback(() => {\n setQuery(\"\");\n setActiveTopic(null);\n }, []);\n\n const heading = title ?? fill(T.indexHeading, { product: productName });\n const metaDescription =\n description ??\n clampText(\n fill(T.seoIndexDescription, { product: productName }),\n META_DESCRIPTION_LIMIT,\n );\n const lead = description ?? fill(T.indexLead, { product: productName });\n const canonical = `${base}${ANSWERS_PATH}`;\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"CollectionPage\",\n name: heading,\n description: metaDescription,\n url: canonical,\n isPartOf: { \"@type\": \"WebSite\", name: productName, url: `${base}/` },\n mainEntity: {\n \"@type\": \"ItemList\",\n numberOfItems: ordered.length,\n itemListElement: ordered.map((answer, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n url: absoluteUrl(base, answerPath(answer.slug)),\n name: answer.question,\n })),\n },\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n {\n \"@type\": \"ListItem\",\n position: 1,\n name: T.breadcrumbHome,\n item: `${base}/`,\n },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: T.answers,\n item: canonical,\n },\n ],\n },\n ],\n [base, canonical, heading, metaDescription, ordered, productName, T],\n );\n\n return (\n <div\n data-answers=\"landing\"\n data-locale={activeLocale}\n /* Arabic is the one RTL locale in the product set. Scoped to this subtree rather than\n set on <html>, exactly as the chat does it, because the SDK is a guest on someone\n else's page. */\n dir={rtl ? \"rtl\" : undefined}\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title={T.seoIndexTitle}\n description={metaDescription}\n productName={productName}\n keywords={[\n fill(T.indexHeading, { product: productName }),\n ...groups.map((group) => group.name),\n ].join(\", \")}\n url={canonical}\n structuredData={structuredData}\n />\n\n <section className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-6xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8\">\n <p className=\"text-xs font-semibold uppercase tracking-[0.2em] text-primary\">\n {T.answers}\n </p>\n <h1 className=\"mt-3 max-w-3xl text-4xl font-bold tracking-tight text-foreground sm:text-5xl\">\n {heading}\n </h1>\n <p className=\"mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground\">\n {lead}\n </p>\n {hasAnswers ? (\n <p className=\"mt-6 text-sm text-muted-foreground\">\n <strong className=\"text-lg font-semibold text-foreground\">\n {ordered.length}\n </strong>{\" \"}\n {questionCount(T, ordered.length)}\n </p>\n ) : null}\n {cta ? <div className=\"mt-8 flex flex-wrap gap-3\">{cta}</div> : null}\n </div>\n </section>\n\n <div className=\"mx-auto max-w-6xl px-4 pb-20 sm:px-6 lg:px-8\">\n {hasAnswers ? (\n <>\n <div\n role=\"search\"\n data-answers=\"filter\"\n className=\"flex flex-col gap-4 py-8\"\n >\n <div className=\"relative w-full max-w-md\">\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n />\n <label htmlFor={searchId} className=\"sr-only\">\n {T.searchLabel}\n </label>\n <input\n id={searchId}\n type=\"search\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder={T.searchPlaceholder}\n autoComplete=\"off\"\n className=\"h-10 w-full rounded-lg border border-border bg-background pl-9 pr-3 text-sm text-foreground shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </div>\n <div\n role=\"group\"\n aria-label={T.filterByTopic}\n className=\"flex flex-wrap gap-2\"\n >\n <FilterChip\n label={T.allTopics}\n topic=\"all\"\n count={searched.length}\n active={activeTopic === null}\n onSelect={() => setActiveTopic(null)}\n />\n {groups.map((group) => (\n <FilterChip\n key={group.anchor}\n label={group.name}\n topic={group.name}\n count={countsByTopic.get(group.name) ?? 0}\n active={activeTopic === group.name}\n onSelect={() =>\n setActiveTopic((current) =>\n current === group.name ? null : group.name,\n )\n }\n />\n ))}\n </div>\n {/* Visible only while a filter is on; announced whenever the result set changes. */}\n <p\n aria-live=\"polite\"\n className={\n filtering ? \"text-sm text-muted-foreground\" : \"sr-only\"\n }\n >\n {fill(T.showingCount, {\n shown: String(visibleTotal),\n total: String(ordered.length),\n })}\n </p>\n </div>\n\n {visibleTotal === 0 ? (\n <div\n data-answers=\"empty\"\n className=\"rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <Search\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n {T.noMatchesTitle}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {T.noMatchesBody}\n </p>\n <button\n type=\"button\"\n onClick={clearFilters}\n className=\"mt-6 inline-flex items-center rounded-full border border-border bg-card px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {T.clearFilters}\n </button>\n </div>\n ) : (\n <div className=\"space-y-14\">\n {visibleGroups.map((group) => (\n <section key={group.anchor} aria-labelledby={group.anchor}>\n <div className=\"max-w-3xl\">\n <h2\n id={group.anchor}\n className=\"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\"\n >\n {group.name}\n </h2>\n {group.description ? (\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">\n {group.description}\n </p>\n ) : null}\n </div>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3\"\n >\n {group.answers.map((answer) => (\n <li\n key={answer.slug}\n data-answers=\"card\"\n data-slug={answer.slug}\n >\n <AnswerCard answer={answer} strings={T} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n )}\n </>\n ) : (\n // Nothing published yet: no filter bar with an \"All 0\" chip, and no empty state\n // that blames filters the visitor never set.\n <div\n data-answers=\"none\"\n className=\"mt-10 rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <Sparkles\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n {T.noneYetTitle}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {fill(T.noneYetBody, { product: productName })}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Detail page\n// ============================================================================\n\nconst SECTION_HEADING =\n \"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\";\nconst CHIP =\n \"inline-flex items-center rounded-full border border-border bg-muted/50 px-3 py-1 text-sm text-foreground\";\n\n/**\n * The note that says what this page is: generated, dated, and second to the pages it links.\n *\n * A callout with `role=\"note\"` rather than a line of body copy, because on a marketing page a\n * disclosure set in the same type as the sales copy is a disclosure nobody reads. The wording\n * itself, and what was deliberately not claimed, is documented on `aboutBody` in\n * `answers-i18n.ts`.\n */\nfunction ProvenanceNote({\n strings: T,\n date,\n className,\n}: {\n strings: AnswerStrings;\n date: string;\n className?: string;\n}) {\n return (\n <div\n role=\"note\"\n aria-label={T.aboutTitle}\n data-answers=\"provenance\"\n className={cn(\n \"flex items-start gap-3 rounded-xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm leading-relaxed text-foreground\",\n className,\n )}\n >\n <Info\n aria-hidden=\"true\"\n className=\"mt-0.5 h-4 w-4 shrink-0 text-primary\"\n />\n <p>\n <span className=\"font-semibold\">{T.aboutTitle}</span>\n {\" — \"}\n {fill(T.aboutBody, { date })}\n </p>\n </div>\n );\n}\n\n/** One cited page, as a real link. */\nfunction SourceLink({\n source,\n strings: T,\n}: {\n source: PublishedAnswerSource;\n strings: AnswerStrings;\n}) {\n const host = answerSourceHost(source.url);\n return (\n <a\n data-answers=\"source\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"group flex h-full flex-col gap-1.5 rounded-xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <span className=\"text-sm font-semibold leading-snug transition-colors group-hover:text-primary\">\n {source.title || host || source.url}\n </span>\n <span className=\"mt-auto flex items-center gap-2 pt-1 text-xs text-muted-foreground\">\n {source.product ? (\n <span className=\"rounded-full bg-secondary px-2 py-0.5 font-medium text-secondary-foreground\">\n {source.product}\n </span>\n ) : null}\n <span className=\"inline-flex min-w-0 items-center gap-1\">\n <ExternalLink aria-hidden=\"true\" className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">{host}</span>\n </span>\n </span>\n <span className=\"sr-only\">({T.opensInNewTab})</span>\n </a>\n );\n}\n\n/**\n * `/answer/:slug` — one question, the answer, and the pages it came from.\n */\nexport function AnswerDetailPage(props: AnswerDetailPageProps) {\n // Keyed by slug: a router reuses this component when the visitor moves from one answer to\n // another, and that is a new page — not an update of the old one.\n return <AnswerDetail key={props.answer.slug} {...props} />;\n}\n\nfunction AnswerDetail({\n productName,\n siteUrl,\n answer,\n answers,\n topics,\n imageOrigins,\n askHref = \"/explore\",\n cta,\n linkComponent,\n locale,\n className,\n}: AnswerDetailPageProps) {\n const Link = linkComponent ?? DefaultAnswerLink;\n const base = normaliseSiteUrl(siteUrl);\n const headingId = useId();\n const activeLocale = useMemo(() => resolveExploreLocale(locale), [locale]);\n const T = useMemo(() => answerStrings(activeLocale), [activeLocale]);\n const rtl = isRtlLocale(activeLocale);\n const dateLabel = useMemo(\n () => formatAnswerDate(answer.answeredAt, activeLocale),\n [answer.answeredAt, activeLocale],\n );\n\n const ordered = useMemo(() => sortByOrder(answers), [answers]);\n const position = ordered.findIndex((item) => item.slug === answer.slug);\n const previous = position > 0 ? ordered[position - 1] : undefined;\n const next =\n position >= 0 && position < ordered.length - 1\n ? ordered[position + 1]\n : undefined;\n\n // Curated related answers first; the rest of the topic when none resolve. A slug listed\n // twice still shows one card.\n const related = useMemo(() => {\n const bySlug = new Map(ordered.map((item) => [item.slug, item]));\n const curated = [...new Set(answer.related)]\n .map((slug) => bySlug.get(slug))\n .filter(\n (item): item is PublishedAnswer =>\n item !== undefined && item.slug !== answer.slug,\n );\n const list =\n curated.length > 0\n ? curated\n : ordered.filter(\n (item) => item.topic === answer.topic && item.slug !== answer.slug,\n );\n return list.slice(0, RELATED_LIMIT);\n }, [answer, ordered]);\n const relatedIsCurated = answer.related.some((slug) =>\n related.some((item) => item.slug === slug),\n );\n const topicDescription = topics?.find(\n (topic) => topic.name === answer.topic,\n )?.description;\n\n const sources = useMemo(\n () => publishableSources(answer.sources),\n [answer.sources],\n );\n\n /**\n * Origins an illustration inside the answer may load from: this site, every site the answer\n * cited, and anything the caller adds. The harness has already removed every image it did\n * not put there; this is the browser's own second check, exactly as in the chat.\n */\n const answerImageOrigins = useMemo(\n () =>\n inlineImageOrigins([\n { website: base },\n ...sources.map((source) => ({ website: source.url })),\n ...(imageOrigins ?? []).map((origin) => ({ website: origin })),\n ]),\n [base, sources, imageOrigins],\n );\n /** Those, and every product site — see `ECOSYSTEM_SITES`. */\n const answerVideoOrigins = useMemo(\n () => new Set([...answerImageOrigins, ...ECOSYSTEM_ORIGINS]),\n [answerImageOrigins],\n );\n\n const canonical = absoluteUrl(base, answerPath(answer.slug));\n\n /**\n * The answer as plain text for the structured data.\n *\n * The SPEECH stripper, not the clipboard one, and the difference matters in exactly the\n * place this feature cares about. `acceptedAnswer.text` is consumed by machines that read\n * it out; the clipboard form keeps a table as pipes (right for a paste into a README,\n * unreadable said aloud) and spells every URL out mid-sentence. The speech form reads each\n * row with its cells under their own column headings and a link as its label — and the URLs\n * are not lost, because `citation` below carries them as data.\n */\n const answerText = useMemo(\n () => answerSpeechText(answer.answer),\n [answer.answer],\n );\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"FAQPage\",\n name: answer.question,\n description: answer.metaDescription,\n url: canonical,\n inLanguage: \"en\",\n isPartOf: { \"@type\": \"WebSite\", name: productName, url: `${base}/` },\n mainEntity: {\n \"@type\": \"Question\",\n name: answer.question,\n text: answer.question,\n answerCount: 1,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: answerText,\n url: canonical,\n dateCreated: answer.answeredAt,\n // The organisation published it. Naming a person would be the one outright\n // false claim these pages could make.\n author: { \"@type\": \"Organization\", name: productName },\n ...(sources.length > 0\n ? {\n citation: sources.map((source) => ({\n \"@type\": \"WebPage\",\n name: source.title,\n url: source.url,\n })),\n }\n : {}),\n },\n },\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n {\n \"@type\": \"ListItem\",\n position: 1,\n name: T.breadcrumbHome,\n item: `${base}/`,\n },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: T.answers,\n item: `${base}${ANSWERS_PATH}`,\n },\n {\n \"@type\": \"ListItem\",\n position: 3,\n name: answer.question,\n item: canonical,\n },\n ],\n },\n ],\n [answer, answerText, base, canonical, productName, sources, T],\n );\n\n return (\n <article\n data-answers=\"detail\"\n data-slug={answer.slug}\n data-locale={activeLocale}\n aria-labelledby={headingId}\n /* Arabic is the one RTL locale in the product set. Scoped to this subtree rather than\n set on <html>, exactly as the chat does it, because the SDK is a guest on someone\n else's page. */\n dir={rtl ? \"rtl\" : undefined}\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title={clampText(answer.question, TITLE_LIMIT)}\n description={answer.metaDescription}\n productName={productName}\n keywords={answer.keywords.join(\", \")}\n url={canonical}\n structuredData={structuredData}\n />\n {/* The answer body's own stylesheets. Both are scoped and idempotent, and without them\n a wide table has nothing holding it inside the page. */}\n <ProseStyles />\n <ExploreAnswerStyles />\n\n <header className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-4xl px-4 pb-10 pt-8 sm:px-6 lg:px-8\">\n <nav aria-label=\"Breadcrumb\">\n <ol className=\"flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground\">\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href=\"/\"\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {T.breadcrumbHome}\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href={ANSWERS_PATH}\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {T.answers}\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li\n aria-current=\"page\"\n {...ENGLISH_TEXT}\n className=\"min-w-0 truncate text-foreground\"\n >\n {answer.question}\n </li>\n </ol>\n </nav>\n\n <div className=\"mt-6 flex flex-wrap items-center gap-2\">\n <span\n data-answers=\"topic\"\n title={topicDescription}\n className=\"inline-flex items-center rounded-full border border-primary/30 bg-primary/10 px-3 py-1 text-xs font-semibold text-primary\"\n >\n {answer.topic}\n </span>\n {dateLabel ? (\n <span className=\"inline-flex items-center rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground\">\n {/* A machine-readable date beside the words, so \"when\" survives being\n scraped, quoted or read by an assistant. */}\n <time dateTime={answer.answeredAt}>\n {fill(T.answeredOn, { date: dateLabel })}\n </time>\n </span>\n ) : null}\n </div>\n <h1\n id={headingId}\n {...ENGLISH_TEXT}\n className=\"mt-4 text-3xl font-bold tracking-tight text-foreground sm:text-4xl\"\n >\n {answer.question}\n </h1>\n {answer.summary ? (\n <p\n {...ENGLISH_TEXT}\n className=\"mt-4 text-lg leading-relaxed text-muted-foreground\"\n >\n {answer.summary}\n </p>\n ) : null}\n <ProvenanceNote strings={T} date={dateLabel} className=\"mt-6\" />\n </div>\n </header>\n\n <div className=\"mx-auto max-w-4xl px-4 py-12 sm:px-6 lg:px-8\">\n <section aria-labelledby={`${headingId}-answer`}>\n <h2 id={`${headingId}-answer`} className={SECTION_HEADING}>\n {T.answerHeading}\n </h2>\n {/* `dir=\"ltr\"` as well as `lang`, and only here. The answer is English prose with\n lists, fenced code and GFM tables in it; inherited RTL would right-align every\n line of it and start each table at the wrong edge, which the table's own\n `text-align: start` would faithfully follow. A question, by contrast, is one line\n that can sit with the rest of an RTL page's text. */}\n <div data-answers=\"body\" {...ENGLISH_TEXT} dir=\"ltr\">\n {/* The chat's renderer, unchanged apart from the heading levels: same GFM tables,\n same contained scroller, same card-per-row layout under 30rem. */}\n <ExploreAnswerBody\n strings={T}\n imageOrigins={answerImageOrigins}\n videoOrigins={answerVideoOrigins}\n productSlugs={ECOSYSTEM_PRODUCT_SLUGS}\n components={ANSWER_HEADING_SHIFT}\n className=\"mt-4\"\n >\n {answer.answer}\n </ExploreAnswerBody>\n </div>\n </section>\n\n {sources.length > 0 ? (\n <section\n aria-labelledby={`${headingId}-sources`}\n data-answers=\"sources\"\n className=\"mt-14\"\n >\n <h2 id={`${headingId}-sources`} className={SECTION_HEADING}>\n {T.sourcesHeading}\n </h2>\n <p className=\"mt-2 text-muted-foreground\">{T.sourcesLead}</p>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2\"\n >\n {sources.map((source) => (\n <li key={source.url}>\n <SourceLink source={source} strings={T} />\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {answer.keywords.length > 0 ? (\n <section aria-labelledby={`${headingId}-topics`} className=\"mt-14\">\n <h2 id={`${headingId}-topics`} className={SECTION_HEADING}>\n {T.topicsHeading}\n </h2>\n <ul role=\"list\" className=\"mt-4 flex flex-wrap gap-2\">\n {answer.keywords.map((keyword, index) => (\n <li key={copyKey(index, keyword)} className={CHIP}>\n {keyword}\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {related.length > 0 ? (\n <section\n aria-labelledby={`${headingId}-related`}\n data-answers=\"related\"\n className=\"mt-14\"\n >\n <h2 id={`${headingId}-related`} className={SECTION_HEADING}>\n {relatedIsCurated\n ? T.relatedHeading\n : fill(T.moreInTopic, { topic: answer.topic })}\n </h2>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2\"\n >\n {related.map((item) => (\n <li key={item.slug} data-answers=\"card\" data-slug={item.slug}>\n <AnswerCard answer={item} strings={T} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {previous || next ? (\n <nav\n aria-label={`${T.previousQuestion} / ${T.nextQuestion}`}\n data-answers=\"pager\"\n /* `minmax(0,1fr)`, not the implicit `auto` track. A grid track's automatic\n minimum is the item's MIN-CONTENT size, and `min-w-0` on the inner span\n caps the flex item's shrink floor without reducing that contribution — so\n a long question title blew the single-column track out to ~803px inside a\n 288px nav and scrolled the whole document sideways on a phone. Measured at\n 320px before this: documentElement.scrollWidth 596-902 across the fleet,\n each matching the anchor's width to within the page gutter. */\n className=\"mt-14 grid grid-cols-[minmax(0,1fr)] gap-4 sm:grid-cols-2\"\n >\n {previous ? (\n <Link\n href={answerPath(previous.slug)}\n className=\"group flex min-w-0 items-center gap-3 rounded-2xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {T.previousQuestion}\n </span>\n <span\n {...ENGLISH_TEXT}\n className=\"block truncate font-semibold\"\n >\n {previous.question}\n </span>\n </span>\n </Link>\n ) : (\n <span className=\"hidden sm:block\" />\n )}\n {next ? (\n <Link\n href={answerPath(next.slug)}\n className=\"group flex min-w-0 items-center justify-end gap-3 rounded-2xl border border-border bg-card p-4 text-right text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {T.nextQuestion}\n </span>\n <span\n {...ENGLISH_TEXT}\n className=\"block truncate font-semibold\"\n >\n {next.question}\n </span>\n </span>\n <ArrowRight\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n </Link>\n ) : null}\n </nav>\n ) : null}\n\n <div className=\"mt-10 flex flex-wrap items-center gap-x-6 gap-y-3\">\n <Link\n href={ANSWERS_PATH}\n className=\"inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft aria-hidden=\"true\" className=\"h-4 w-4\" />\n {fill(T.allAnswers, { product: productName })}\n </Link>\n {askHref ? (\n <Link\n href={askHref}\n className=\"inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Sparkles aria-hidden=\"true\" className=\"h-4 w-4\" />\n {T.askYourOwn}\n </Link>\n ) : null}\n </div>\n </div>\n\n {cta ? (\n <section\n data-answers=\"cta\"\n className=\"border-t border-border bg-muted/30\"\n >\n <div className=\"mx-auto flex max-w-4xl flex-wrap items-center gap-4 px-4 py-12 sm:px-6 lg:px-8\">\n {cta}\n </div>\n </section>\n ) : null}\n </article>\n );\n}\n","/**\n * ExploreAvatarLive — the Avatar tab's live avatar (BOFF-9797), opt-in: the part of it that lives in the package root.\n *\n * `ExplorePanel` renders this only when its host passes `avatar.live`. Without it the Avatar tab is exactly what it\n * was: the approved still, \"Live avatar coming soon\" and \"Continue in Chat\".\n *\n * This is deliberately small. The live avatar itself (the view, its state machine, its requests, its words in six\n * locales and the bot check, in `explore-avatar-live-view.tsx`) weighs about 12 KB gzipped, a tenth of what a site that\n * uses the panel already carries, and a site that does not use it must not pay for it. So that is a chunk of its own,\n * which this component loads the first time the Avatar view is opened with the live avatar switched on, and not\n * before: not on page load, not when the panel opens, not for a site that never passes `avatar.live`. What stays here\n * is what has to be known without it:\n *\n * - whether the live avatar can run on this page at all (a complete config, a gateway, the panel's conversation, a\n * locale with reviewed words). When it cannot, the Avatar tab is shown as it was and the chunk is never loaded;\n * - what the Avatar tab shows until the chunk is there: the picture, as the view's own first step, so the server's\n * markup, a prerendered page and the first client render are the same as they have always been;\n * - the page's React contexts. The package builds each entry on its own, so the chunk cannot read the page's\n * `WebSDKProvider` or the panel's conversation itself (it would get a second, empty copy of each). It is handed\n * what it reads as props instead.\n *\n * A chunk that cannot be loaded (offline, or a deploy that has replaced it), or that has not arrived within\n * `VIEW_LOAD_TIMEOUT_MS`, leaves the tab as it was, and is asked for again each time the Avatar view is opened. Whether\n * that fetches it again is the browser's to say, not this component's: Safari and Firefox fetch a module that failed\n * again, but Chromium-based browsers keep the failed fetch for as long as the page lives, so there the tab stays as it\n * was until the page is reloaded. Until a load has succeeded, the tab keeps showing what it was before the live avatar,\n * also while a later attempt is under way, so a visitor does not see it flicker back to the bare picture.\n */\n\"use client\";\n\nimport {\n useContext,\n useEffect,\n useMemo,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\n\nimport {\n avatarApiBase,\n isAvatarLiveLocaleReviewed,\n liveConfigComplete,\n type ExplorePanelAvatarLive,\n} from \"./explore-avatar-live-config\";\nimport { ExploreConversationContext } from \"./explore-conversation\";\nimport { exploreStrings, type ExploreLocale } from \"./explore-i18n\";\nimport { useWebSDKConfig } from \"../client/provider\";\nimport { cfAccessHeaders } from \"../client/security\";\n\nimport type { AvatarLiveViewProps } from \"./explore-avatar-live-view\";\n\nexport type { ExplorePanelAvatarLive };\n\n/** The live avatar's view, once its chunk is loaded. */\ntype AvatarLiveViewComponent = ComponentType<AvatarLiveViewProps>;\n\n/**\n * How long the Avatar view waits for the view's chunk before it shows the tab as it was before the live avatar (a\n * stalled connection would otherwise leave the bare picture up for good). The same patience as the availability\n * request that follows the chunk.\n */\nconst VIEW_LOAD_TIMEOUT_MS = 8_000;\n\n/**\n * Load the view's chunk. The package build leaves this `import()` as it is, pointing at the file it builds beside this\n * one (`tsup.config.ts`), so a site's bundler splits it into a chunk of its own; `scripts/validate-avatar-live.mjs`\n * checks that it did.\n */\nexport function loadAvatarLiveView(): Promise<AvatarLiveViewComponent> {\n return import(\"./explore-avatar-live-view\").then(\n (loaded) => loaded.AvatarLiveView,\n );\n}\n\nexport interface ExploreAvatarLiveProps {\n live: ExplorePanelAvatarLive;\n /** The Avatar view is showing: the panel is open and its Avatar tab is selected. */\n active: boolean;\n locale: ExploreLocale;\n /** The product the panel speaks for, when it is one product's own; null on the portfolio's. */\n productName: string | null;\n /** The approved still picture. */\n still: { src: string; alt: string };\n /** The Avatar tab as it was before the live avatar: shown whenever the live avatar is not offered or not reachable. */\n fallback: ReactNode;\n /** Back to the Chat tab. Leaving the Avatar tab ends a session, like any other way out of it. */\n onContinueInChat: () => void;\n /**\n * How the view's chunk is loaded. For a test that needs it to fail or to wait; the panel never passes it. Keep it\n * stable between renders: a new function is a new load.\n */\n loadView?: () => Promise<AvatarLiveViewComponent>;\n}\n\nexport function ExploreAvatarLive({\n live,\n active,\n locale,\n productName,\n still,\n fallback,\n onContinueInChat,\n loadView = loadAvatarLiveView,\n}: ExploreAvatarLiveProps) {\n const T = exploreStrings(locale);\n const config = useWebSDKConfig();\n const conversation = useContext(ExploreConversationContext);\n\n const base = avatarApiBase(config.gatewayUrl);\n const headers = useMemo(\n () => cfAccessHeaders(config.gatewayUrl, config.cfAccess),\n [config.gatewayUrl, config.cfAccess],\n );\n const complete = liveConfigComplete(live);\n // Nothing to ask the server about: an incomplete config, no gateway, no shared conversation to read (no provider, or a\n // read-only shared one), or a locale whose strings have not been reviewed. The tab stays as it was.\n const off =\n !complete ||\n base === null ||\n conversation === null ||\n conversation.isSharedView ||\n !isAvatarLiveLocaleReviewed(locale);\n\n useEffect(() => {\n if (!complete) {\n console.warn(\n \"[WebSDK] ExplorePanel: avatar.live needs site, load, turnstileSiteKey and manifestVersion; the live avatar stays off.\",\n );\n }\n }, [complete]);\n\n const [View, setView] = useState<AvatarLiveViewComponent | null>(null);\n // The chunk could not be had, or not in time, and has not come since. It stays set until a load succeeds, including\n // while the next attempt is under way: the tab is then the one it was before the live avatar, and not the bare picture\n // the view starts from.\n const [failed, setFailed] = useState(false);\n\n // The chunk is wanted from the moment the Avatar view shows with the live avatar on, and asked for again each time it\n // shows until it is there. Once it is loaded it stays: the view decides for itself what to do when the live avatar\n // goes off (see `AvatarLiveView`).\n const wanted = active && !off;\n useEffect(() => {\n if (!wanted || View !== null) return;\n let cancelled = false;\n let loading: Promise<AvatarLiveViewComponent>;\n try {\n loading = loadView();\n } catch (error) {\n loading = Promise.reject(error);\n }\n // A chunk that neither arrives nor fails would leave the bare picture up with no way on. Past the limit the tab is\n // the one it was before the live avatar; a chunk that arrives later is used all the same, if the visitor is still\n // on the Avatar view.\n const patience = setTimeout(() => {\n if (!cancelled) setFailed(true);\n }, VIEW_LOAD_TIMEOUT_MS);\n loading.then(\n (component) => {\n // A component is a function: `setView(component)` would call it as an updater. (The view being set runs this\n // effect's cleanup, which stops the clock.)\n if (!cancelled) setView(() => component);\n },\n () => {\n clearTimeout(patience);\n if (!cancelled) setFailed(true);\n },\n );\n return () => {\n cancelled = true;\n clearTimeout(patience);\n };\n }, [wanted, View, loadView]);\n\n if (View !== null) {\n return (\n <View\n live={live}\n active={active}\n locale={locale}\n productName={productName}\n still={still}\n fallback={fallback}\n onContinueInChat={onContinueInChat}\n continueInChat={T.continueInChat}\n off={off}\n base={base}\n headers={headers}\n conversation={conversation}\n />\n );\n }\n\n if (off || failed) {\n return (\n // `display: contents`: the earlier Avatar view's picture, line and button lay out in the pane exactly as before.\n <div\n style={{ display: \"contents\" }}\n data-boff-explore=\"avatar-live\"\n data-phase={off ? \"off\" : \"inert\"}\n >\n {fallback}\n </div>\n );\n }\n\n // Until the view is there: what it shows before it has asked anything (its `idle` step), so that what the server\n // renders, what a prerendered page holds and what the first client render shows are all the same picture.\n return (\n <div\n data-boff-explore=\"avatar-live\"\n data-phase=\"idle\"\n className=\"flex max-h-full w-full flex-col items-center gap-4 overflow-y-auto\"\n >\n <img\n src={still.src}\n alt={still.alt}\n decoding=\"async\"\n width={128}\n height={128}\n className=\"shrink-0 rounded-full border border-border object-cover shadow-sm h-32 w-32\"\n />\n <p\n role=\"status\"\n data-boff-explore=\"avatar-live-status\"\n className=\"text-sm text-muted-foreground\"\n />\n <div data-boff-explore=\"avatar-live-bot-check\" />\n </div>\n );\n}\n","/**\n * ExplorePanel — the site-wide assistant panel (BOFF-9697).\n *\n * The site's Explore conversation in a compact panel over whatever page is showing, with Chat and Avatar views, and\n * an Expand control that grows the SAME panel to the full window (Restore shrinks it back). Opt-in: a site renders it\n * under an `ExploreChatProvider` (above its routes, inside its router) and lets its floating `ExploreCta` open it.\n * Every other site is unchanged.\n *\n * - **One conversation, never remounted.** The chat view is `ExplorePage presentation=\"panel\"`. It mounts on the\n * first open and stays mounted: Expand, Restore, the tabs and closing change only CSS, so the draft, the transcript,\n * its scroll position and an answer still on its way all survive. Closed, it is hidden but stays laid out\n * (`visibility`/`content-visibility`), which is what keeps the transcript's scroll position.\n * - **Non-modal, and never over the host's bottom bar.** `bottomOffset` (a consent banner's height, say) is kept clear\n * in both sizes, so the banner stays visible and usable, and the page behind stays scrollable. Render the panel after\n * the site header and before the banner: at the same `zIndex` the later element paints on top, so the expanded panel\n * covers the header and never the banner.\n * - **Escape and the phone's Back step back:** expanded, then compact, then closed. Back works through history\n * entries the panel adds for its own steps (the same URL, so the host's router stays where it is), and the page\n * keeps its scroll position through them. Closing by any route takes those entries off again.\n * - **The on-screen keyboard** never covers the composer: while open, the panel follows the visual viewport.\n * - **Closing, or the Avatar view, stops listening and reading aloud** (`active`); the conversation is kept.\n * - **The avatar:** by default the Avatar view shows the host's approved picture, labelled \"Live avatar coming soon\",\n * and a \"Continue in Chat\" action. No session, no animation, no call to any avatar service.\n * - **The live avatar (BOFF-9797), opt-in:** a host that passes `avatar.live` gets the receive-only live avatar in that\n * view instead (`ExploreAvatarLive`): nothing is asked until the view opens, and nothing loaded until the visitor\n * agrees. The live avatar's own code is a chunk of its own, fetched when the view first opens, so a panel without\n * `avatar.live` carries a few lines of it and no more. Without `avatar.live`, the panel renders exactly what it did\n * before.\n *\n * Import from the package ROOT (tsup `splitting: false`), like `ExplorePage` and `ExploreChatProvider`.\n */\n\"use client\";\n\nimport {\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type RefObject,\n} from \"react\";\n\nimport { Maximize2, Minimize2, X } from \"lucide-react\";\n\nimport { ExplorePage } from \"./explore\";\nimport {\n ExploreAvatarLive,\n type ExplorePanelAvatarLive,\n} from \"./explore-avatar-live\";\nimport { ExploreCatalogProductsContext } from \"./explore-conversation\";\nimport {\n exploreStrings,\n fill,\n isRtlLocale,\n resolveExploreLocale,\n} from \"./explore-i18n\";\nimport {\n pinnedProductSlug,\n productNameFor,\n type ExploreScope,\n} from \"./explore-scope\";\nimport { ECOSYSTEM_PRODUCTS } from \"../data/products\";\nimport { cn } from \"../utils/cn\";\n\n/**\n * The keys this panel keeps in `history.state`, beside the host router's own:\n *\n * boffExplorePanel \"open\" | \"expanded\" on the panel's own entries (the same URL as the entry below them)\n * boffExplorePanelPos every entry the panel has seen, its own and the host's, in the order it saw them, so a\n * traversal can tell Back from Forward\n * boffExplorePanelDoc the page load that wrote them: anything an earlier page load left is the old panel's\n */\nconst MARK_KEY = \"boffExplorePanel\";\nconst POS_KEY = \"boffExplorePanelPos\";\nconst DOC_KEY = \"boffExplorePanelDoc\";\n\n/** This page load. */\nconst DOC_ID = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n\n/** The last position handed out in this page load; module-wide, so a remounted panel carries on from it. */\nlet lastPos = 0;\n\n/**\n * The host's own `scrollRestoration`, for the entries the panel leaves as \"manual\" (`pushMark`). Module-wide too: an\n * entry a panel left as \"manual\" still gets its mode back after that panel has remounted.\n */\nlet hostMode: ScrollRestoration | null = null;\n\n/** The phone layout (a bottom sheet): the stylesheet's breakpoint. */\nconst NARROW_QUERY = \"(max-width: 639px)\";\n\n/** No precise pointer: focusing the composer there would raise the keyboard over the panel before it was asked for. */\nconst TOUCH_FIRST_QUERY = \"(hover: none) and (pointer: coarse)\";\n\n/** Frames to keep trying the composer's focus: past its 150 ms transition at 60 Hz, with room to spare. */\nconst COMPOSER_FOCUS_TRIES = 15;\n\ntype PanelMark = \"open\" | \"expanded\";\ntype PanelSize = \"compact\" | \"expanded\";\ntype PanelView = \"chat\" | \"avatar\";\n\nexport type { ExplorePanelAvatarLive };\n\nexport interface ExplorePanelAvatar {\n /** The approved picture: a URL the page may load. */\n src: string;\n /** The avatar's name, for the picture's text alternative. */\n name?: string;\n /**\n * BOFF-9797. Opt in to the receive-only live avatar in the Avatar view, for this site. Absent (the default): the\n * Avatar view is the picture, \"Live avatar coming soon\" and \"Continue in Chat\", exactly as before, and nothing is\n * asked of any server. Needs the panel under an `ExploreChatProvider`. See the README's \"Live avatar\".\n */\n live?: ExplorePanelAvatarLive;\n}\n\nexport interface ExplorePanelProps {\n /** Whether the panel shows. The host owns it (its floating button opens the panel). */\n open: boolean;\n /**\n * Called with `false` when the visitor closes the panel: the close button, Escape, the phone's Back, or following a\n * link from the conversation on a phone.\n */\n onOpenChange: (open: boolean) => void;\n /** The panel's id, for the button's `controls`. Default `boff-explore-panel`. */\n id?: string;\n /** Passed to the chat view (`ExplorePage`). */\n productSlug?: string;\n locale?: string;\n /**\n * BOFF-9796. Passed to the chat view: see `ExplorePageProps.scope`. `product` (with `productSlug`) makes the panel\n * one product's own assistant and titles it \"{product} assistant\"; given `examplePrompts`, those are then its only\n * example prompts. Default `portfolio`: the panel as it was.\n */\n scope?: ExploreScope;\n /**\n * BOFF-9796. Passed to the chat view: see `ExplorePageProps.productName`. In the `product` scope it is also the\n * panel's title, at once, before any catalog. Default: the catalog's name for `productSlug`.\n */\n productName?: string;\n /**\n * BOFF-9796. Passed to the chat view: see `ExplorePageProps.examplePrompts`. In the `product` scope they are the only\n * prompts the panel shows, whatever the catalog has; without them it falls back to the catalog's, less any that name\n * another product and the SDK's portfolio prompt. A product site should pass its own.\n */\n examplePrompts?: string[];\n /**\n * The host router's navigate, for links in the conversation. On a phone the panel closes first (the sheet would\n * cover the page); on a wider screen it stays open beside the page. Absent: links load the page normally.\n */\n onNavigate?: (path: string) => void;\n welcomeTitle?: string;\n welcomeBody?: string;\n /** The site's Explore route, for share links made in the panel. Default `/explore`. */\n explorePath?: string;\n /** The Avatar view's picture. Absent: the panel has no Avatar view and no tabs. */\n avatar?: ExplorePanelAvatar;\n /**\n * A CSS length the panel keeps clear at the bottom of the window in both sizes: the host's own bottom bar, such as a\n * consent banner (`var(--site-consent-banner-height, 0px)`). Default `0px`.\n */\n bottomOffset?: string;\n /** The panel's `z-index`. Default 50: with the header and the banner both at 50, DOM order decides (see above). */\n zIndex?: number;\n /** Where focus goes back when the panel closes: the button that opened it. */\n returnFocusRef?: RefObject<HTMLElement | null>;\n /** Extra classes for the panel. */\n className?: string;\n}\n\ntype CssVars = Record<`--${string}`, string>;\n\n/*\n * Layout only: colours, the border's colour and the shadow come from the host's theme, through utility classes.\n *\n * --boff-explore-shell-bottom the host's bottom bar (`bottomOffset`)\n * --boff-explore-shell-lift set while the visible area differs from the page's (the on-screen keyboard, or iOS\n * panning): the slice of the page hidden below it. The panel keeps clear of the larger\n * of that and the bottom bar (a keyboard covers the bar too; a pan can leave it showing)\n * --boff-explore-shell-room set with it: the visible height left for the panel, which `dvh` does not follow\n * --boff-explore-shell-top set with it: the visible area's top, for the expanded panel\n */\nconst PANEL_CSS = `\n.boff-explore-shell {\n --boff-explore-shell-lift-at: max(var(--boff-explore-shell-lift, 0px), var(--boff-explore-shell-bottom, 0px));\n --boff-explore-shell-room-at: var(--boff-explore-shell-room, calc(100vh - var(--boff-explore-shell-bottom, 0px)));\n position: fixed;\n z-index: var(--boff-explore-shell-z, 50);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n overscroll-behavior: contain;\n inset-inline-end: 1rem;\n bottom: calc(1rem + var(--boff-explore-shell-lift-at));\n width: min(26rem, calc(100vw - 2rem));\n height: min(40rem, calc(var(--boff-explore-shell-room-at) - 6rem));\n border-width: 1px;\n border-style: solid;\n border-radius: 1rem;\n}\n@supports (height: 100dvh) {\n .boff-explore-shell {\n --boff-explore-shell-room-at: var(--boff-explore-shell-room, calc(100dvh - var(--boff-explore-shell-bottom, 0px)));\n }\n}\n@media (max-width: 639px) {\n .boff-explore-shell[data-size=\"compact\"] {\n inset-inline: 0;\n bottom: var(--boff-explore-shell-lift-at);\n width: auto;\n height: min(75vh, calc(var(--boff-explore-shell-room-at) - 4rem));\n border-width: 1px 0 0;\n border-radius: 1rem 1rem 0 0;\n }\n @supports (height: 100dvh) {\n .boff-explore-shell[data-size=\"compact\"] {\n height: min(75dvh, calc(var(--boff-explore-shell-room-at) - 4rem));\n }\n }\n}\n.boff-explore-shell[data-size=\"expanded\"] {\n inset: var(--boff-explore-shell-top, 0px) 0 var(--boff-explore-shell-lift-at) 0;\n width: auto;\n height: auto;\n border-width: 0;\n border-radius: 0;\n box-shadow: none;\n}\n.boff-explore-shell[data-open=\"false\"] {\n visibility: hidden;\n content-visibility: hidden;\n}\n.boff-explore-shell:focus { outline: none; }\n`;\n\n/**\n * BOFF-9796: the title of one product's own panel (\"Healthy Bowl assistant\", 157px on one line) is longer than the room\n * a phone leaves it beside the tabs and the buttons: 78px at 320px and 118px at 360px, in English.\n *\n * So it wraps rather than being cut short on one line: to at most two lines, on 18px lines, which makes two lines exactly\n * as tall as the 36px controls beside it, so the header keeps its height and the controls their place. Where its box is\n * too narrow to hold the product's name on one 14px line (under 6rem: English at 320px, and Tamil, whose tabs are\n * wider, at 360px), it steps down to 12px on 16px lines. A container query on the title's own box rather than a media\n * query, because its room is whatever the locale's tabs leave, not the viewport's width.\n *\n * Two lines hold the whole title in English and most locales at 320px and wider. A narrower box can still clamp it,\n * with an ellipsis at the end of its second line: Tamil's at 320px, where its wider tabs leave the title under 4rem, and\n * English's, among others, on a screen narrower than 320px. A further step down for those is left for later.\n *\n * A stylesheet of its own, rendered in the product scope only, so the portfolio's panel renders exactly what it always\n * has. Two classes deep, like the page's rules, so a host's own Tailwind (v3 or v4) never outranks it.\n */\nconst PRODUCT_TITLE_CSS = `\n.boff-explore-shell .boff-explore-shell-title { container-type: inline-size; }\n.boff-explore-shell .boff-explore-shell-title-text {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow: hidden;\n overflow-wrap: break-word;\n line-height: 1.125rem;\n}\n@container (max-width: 6rem) {\n .boff-explore-shell .boff-explore-shell-title-text { font-size: 0.75rem; line-height: 1rem; }\n}\n`;\n\nfunction stateRecord(): Record<string, unknown> {\n const state: unknown = window.history.state;\n return state !== null && typeof state === \"object\"\n ? (state as Record<string, unknown>)\n : {};\n}\n\n/** The current entry carries keys this page load wrote. */\nfunction stampedHere(): boolean {\n return stateRecord()[DOC_KEY] === DOC_ID;\n}\n\n/** The panel's mark on the current history entry, when the entry is one of the panel's own. */\nfunction readMark(): PanelMark | null {\n if (typeof window === \"undefined\" || !stampedHere()) return null;\n const mark = stateRecord()[MARK_KEY];\n return mark === \"open\" || mark === \"expanded\" ? mark : null;\n}\n\n/** Where the current entry stands among the entries the panel has seen, or null for one it has not. */\nfunction readPos(): number | null {\n if (typeof window === \"undefined\" || !stampedHere()) return null;\n const pos = stateRecord()[POS_KEY];\n return typeof pos === \"number\" ? pos : null;\n}\n\n/**\n * Give the current entry its place (a host entry the panel sees for the first time). Keys an earlier page load left\n * here (a reload, a restored tab) go: that panel is gone, and its \"open\" would make Back close a panel that is not\n * there. A refusal (Safari caps history calls per window of time) only costs that entry its place.\n */\nfunction stamp(): void {\n if (typeof window === \"undefined\" || readPos() !== null) return;\n const rest = { ...stateRecord() };\n delete rest[MARK_KEY];\n delete rest[POS_KEY];\n delete rest[DOC_KEY];\n lastPos += 1;\n try {\n window.history.replaceState(\n { ...rest, [POS_KEY]: lastPos, [DOC_KEY]: DOC_ID },\n \"\",\n );\n } catch {\n /* refused: see above */\n }\n}\n\n/**\n * A history entry for one of the panel's steps: the same URL, the host router's state kept as it is. False when the\n * browser refused it (Safari's cap): the panel then works without that Back step.\n *\n * The entry being left is switched to `scrollRestoration: \"manual\"` first. Every entry remembers the scroll position\n * it was left at, and on \"auto\" the browser puts it back on Back, which would jump a page the visitor has scrolled\n * since the panel opened. Chromium and Firefox take that mode from the entry as it was left (a change made during\n * `popstate` is ignored; measured on all three engines), so it has to be set before the push. The new entry gets the\n * host's own mode at once, and the left one gets it back when Back lands on it (`restoreScrollMode`).\n */\nfunction pushMark(mark: PanelMark): boolean {\n const { history } = window;\n const mode =\n \"scrollRestoration\" in history ? history.scrollRestoration : null;\n try {\n if (mode !== null) history.scrollRestoration = \"manual\";\n lastPos += 1;\n history.pushState(\n {\n ...stateRecord(),\n [MARK_KEY]: mark,\n [POS_KEY]: lastPos,\n [DOC_KEY]: DOC_ID,\n },\n \"\",\n );\n return true;\n } catch {\n return false;\n } finally {\n if (mode !== null) history.scrollRestoration = mode;\n }\n}\n\n/**\n * Give an entry the panel left as \"manual\" (see `pushMark`) the host's own mode back once the engine's restore window\n * has passed (two frames after `popstate` is past it on Chromium, Firefox and WebKit alike), then run `then`.\n */\nfunction restoreScrollMode(mode: ScrollRestoration, then?: () => void): void {\n const { history } = window;\n const put = () => {\n if (history.scrollRestoration === \"manual\")\n history.scrollRestoration = mode;\n then?.();\n };\n if (typeof window.requestAnimationFrame !== \"function\") {\n window.setTimeout(put, 50);\n return;\n }\n window.requestAnimationFrame(() => window.requestAnimationFrame(put));\n}\n\n/**\n * Close what the conversation opened over itself: the product-video player (a modal `<dialog>`, portalled to\n * `<body>`, so it is looked for there) and the disclaimer (its backdrop closes it). True when something was open.\n */\nfunction closeInnerDialogs(shell: HTMLElement | null): boolean {\n let closed = false;\n document\n .querySelectorAll<HTMLDialogElement>(\n 'dialog[data-boff-explore=\"video-dialog\"]',\n )\n .forEach((dialog) => {\n if (!dialog.open) return;\n dialog.close();\n closed = true;\n });\n const disclaimer = shell?.querySelector<HTMLElement>(\n '[data-boff-explore=\"disclaimer-dialog\"]',\n );\n if (disclaimer) {\n disclaimer.click();\n closed = true;\n }\n return closed;\n}\n\n/** How many of the panel's own entries are on top of the stack: an \"expanded\" one always sits on an \"open\" one. */\nfunction marksOnTop(mark: PanelMark | null): number {\n if (mark === \"expanded\") return 2;\n return mark === \"open\" ? 1 : 0;\n}\n\nfunction matches(query: string): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(query).matches\n );\n}\n\nexport function ExplorePanel({\n open,\n onOpenChange,\n id = \"boff-explore-panel\",\n productSlug,\n locale,\n scope,\n productName,\n examplePrompts,\n onNavigate,\n welcomeTitle,\n welcomeBody,\n explorePath,\n avatar,\n bottomOffset,\n zIndex,\n returnFocusRef,\n className,\n}: ExplorePanelProps) {\n const resolvedLocale = resolveExploreLocale(locale);\n const T = useMemo(() => exploreStrings(resolvedLocale), [resolvedLocale]);\n const rtl = isRtlLocale(resolvedLocale);\n // BOFF-9796: one product's own assistant is titled with its name: the host's, else the catalog's (the provider's, or,\n // with none, the SDK's own list, which every fallback catalog starts from). The generic title when neither knows it,\n // and always in the portfolio scope.\n const catalogProducts = useContext(ExploreCatalogProductsContext);\n const pinnedSlug = pinnedProductSlug(scope, productSlug);\n const pinnedName = useMemo(\n () =>\n pinnedSlug === null\n ? null\n : productNameFor(\n catalogProducts ?? ECOSYSTEM_PRODUCTS,\n pinnedSlug,\n productName,\n ),\n [catalogProducts, pinnedSlug, productName],\n );\n const title =\n pinnedName === null\n ? T.panelTitle\n : fill(T.panelTitleProduct, { product: pinnedName });\n const uid = useId();\n const titleId = `${uid}-title`;\n const chatTabId = `${uid}-chat-tab`;\n const avatarTabId = `${uid}-avatar-tab`;\n const chatPaneId = `${uid}-chat`;\n const avatarPaneId = `${uid}-avatar`;\n\n const [mounted, setMounted] = useState(open);\n const [size, setSize] = useState<PanelSize>(\"compact\");\n const [view, setView] = useState<PanelView>(\"chat\");\n const [focusRequest, setFocusRequest] = useState<\"in\" | \"back\" | null>(\n open ? \"in\" : null,\n );\n // Opening and closing, seen during render (React's pattern for state that follows a prop change): the panel mounts\n // on its first opening and stays mounted, and every close comes back compact.\n const [wasOpen, setWasOpen] = useState(open);\n if (open !== wasOpen) {\n setWasOpen(open);\n if (open) {\n setMounted(true);\n setFocusRequest(\"in\");\n } else {\n setSize(\"compact\");\n setFocusRequest(\"back\");\n }\n }\n\n const shellRef = useRef<HTMLDivElement>(null);\n const chatPaneRef = useRef<HTMLDivElement>(null);\n const chatTabRef = useRef<HTMLButtonElement>(null);\n const avatarTabRef = useRef<HTMLButtonElement>(null);\n /** Traversals the panel started itself: their `popstate` is not the visitor's Back. */\n const ownPopsRef = useRef(0);\n /** Set from the panel's own traversal landing until the entry it left as \"manual\" has its mode back. */\n const settlingRef = useRef(false);\n /** Work held until the panel's own traversal has settled (a push before it would be undone by it). */\n const afterPopRef = useRef<Array<() => void>>([]);\n /** The current entry as the panel last saw it: its mark, and its place. */\n const markRef = useRef<PanelMark | null>(null);\n const posRef = useRef<number | null>(null);\n /** The page the panel last saw as current, to tell a page change from a step of the panel's own. */\n const hrefRef = useRef<string | null>(null);\n /**\n * The latest `open` and `onOpenChange`. The `popstate` listener reads them here instead of being added again when\n * they change: a router can re-render the page (and flip `open`) from its own `popstate` listener, before the\n * panel's runs, and a listener removed and re-added during that dispatch is never called for it.\n */\n const openRef = useRef(open);\n const onOpenChangeRef = useRef(onOpenChange);\n /** The panel has taken its first look at the current entry. */\n const lookedRef = useRef(false);\n\n const traverse = useCallback((delta: number) => {\n ownPopsRef.current += 1;\n window.history.go(delta);\n }, []);\n\n const push = useCallback((mark: PanelMark): boolean => {\n const { history } = window;\n if (\n \"scrollRestoration\" in history &&\n history.scrollRestoration !== \"manual\"\n ) {\n hostMode = history.scrollRestoration;\n }\n stamp();\n if (!pushMark(mark)) return false;\n markRef.current = mark;\n posRef.current = readPos();\n hrefRef.current = window.location.href;\n return true;\n }, []);\n\n const whenSettled = useCallback((work: () => void) => {\n if (ownPopsRef.current > 0 || settlingRef.current) {\n afterPopRef.current.push(work);\n } else {\n work();\n }\n }, []);\n\n /** Run the held work, in order; a piece of it that starts another traversal holds the rest again. */\n const flush = useCallback(() => {\n settlingRef.current = false;\n while (\n afterPopRef.current.length > 0 &&\n ownPopsRef.current === 0 &&\n !settlingRef.current\n ) {\n afterPopRef.current.shift()?.();\n }\n }, []);\n\n useEffect(() => {\n openRef.current = open;\n onOpenChangeRef.current = onOpenChange;\n });\n\n // Every render (the host's router re-renders the panel on a page change): a page the panel has not seen yet gets its\n // place, and becomes where the panel stands. An entry it HAS seen, current now without the panel having moved there,\n // is a Back or Forward whose `popstate` the panel has not had yet: a router's own `popstate` listener can re-render\n // the page before the panel's runs (measured in Chromium, where listeners on `window` run in the order they were\n // added). That handler needs the entry being left, so the picture is left to it. Skipped as well while the panel's\n // own traversal is under way: its `popstate` does it.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (ownPopsRef.current > 0 || settlingRef.current) return;\n const pos = readPos();\n if (lookedRef.current && pos !== null && pos !== posRef.current) return;\n lookedRef.current = true;\n stamp();\n markRef.current = readMark();\n posRef.current = readPos();\n hrefRef.current = window.location.href;\n });\n\n // Opened: an entry for \"open\", so the phone's Back closes the panel. Closed by any route: what the conversation\n // opened over itself closes too, and the panel's own entries come off again, unless the visitor's Back already took\n // them (or a page change now sits on top of them). After any traversal still under way, either way.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n whenSettled(() => {\n if (openRef.current) {\n if (readMark() === null) push(\"open\");\n return;\n }\n closeInnerDialogs(shellRef.current);\n const count = marksOnTop(readMark());\n if (count > 0) traverse(-count);\n });\n }, [open, push, traverse, whenSettled]);\n\n // The phone's (and the browser's) Back and Forward. Added once, for the panel's lifetime (see `openRef`).\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onPopState = () => {\n const open = openRef.current;\n const onOpenChange = onOpenChangeRef.current;\n const leftMark = markRef.current;\n const leftPos = posRef.current;\n const leftHref = hrefRef.current;\n const mark = readMark();\n const pos = readPos();\n markRef.current = mark;\n posRef.current = pos;\n hrefRef.current = window.location.href;\n const forward = pos !== null && leftPos !== null && pos > leftPos;\n const mode = hostMode;\n // Leaving one of the panel's entries lands on the entry it left as \"manual\" (`pushMark`): its mode goes back.\n const restoring = leftMark !== null && mode !== null;\n\n if (ownPopsRef.current > 0) {\n ownPopsRef.current -= 1;\n if (ownPopsRef.current > 0) return;\n if (restoring) {\n settlingRef.current = true;\n restoreScrollMode(mode, flush);\n } else {\n flush();\n }\n return;\n }\n if (restoring) restoreScrollMode(mode);\n\n if (leftMark !== null && !forward) {\n // Back off one of the panel's steps. What the conversation opened over itself (the video player, the\n // disclaimer) is what that Back closes; the panel's step comes back under it.\n if (open && closeInnerDialogs(shellRef.current)) {\n if (readMark() === null) push(\"open\");\n if (leftMark === \"expanded\" && readMark() === \"open\") {\n push(\"expanded\");\n }\n return;\n }\n setSize(\"compact\");\n if (mark === null && open) onOpenChange(false);\n return;\n }\n // A page change: what the conversation opened over itself (a playing video) does not outlive the page.\n if (leftHref !== null && window.location.href !== leftHref) {\n closeInnerDialogs(shellRef.current);\n }\n // Between the host's own pages, or Forward off the panel's steps onto one: the panel stays as it is.\n if (mark === null) return;\n if (forward) {\n // Forward onto one of the panel's steps redoes it.\n setSize(mark === \"expanded\" ? \"expanded\" : \"compact\");\n if (!open) onOpenChange(true);\n return;\n }\n // Back onto the panel's steps from a later page. Closed there: they are stale, so Back steps over them rather\n // than stopping on a press that shows nothing.\n if (!open) {\n traverse(-marksOnTop(mark));\n return;\n }\n setSize(mark === \"expanded\" ? \"expanded\" : \"compact\");\n };\n window.addEventListener(\"popstate\", onPopState);\n return () => window.removeEventListener(\"popstate\", onPopState);\n }, [flush, push, traverse]);\n\n // While open, follow the visual viewport, so the on-screen keyboard never covers the composer. Written straight to\n // the element: it changes on every keyboard frame, and nothing else in the tree reads it.\n useEffect(() => {\n if (!open || typeof window === \"undefined\") return;\n const viewport = window.visualViewport;\n const shell = shellRef.current;\n if (!viewport || !shell) return;\n const clear = () => {\n shell.style.removeProperty(\"--boff-explore-shell-lift\");\n shell.style.removeProperty(\"--boff-explore-shell-room\");\n shell.style.removeProperty(\"--boff-explore-shell-top\");\n };\n const apply = () => {\n const covered = Math.max(\n 0,\n Math.round(window.innerHeight - viewport.height - viewport.offsetTop),\n );\n // iOS can also pan the visible area down the page, so nothing looks covered at the bottom while the top has\n // moved: the panel follows the visible area whenever it differs from the page's, not only when the bottom does.\n const panned = viewport.offsetTop > 1;\n if (covered <= 1 && !panned) {\n clear();\n return;\n }\n shell.style.setProperty(\"--boff-explore-shell-lift\", `${covered}px`);\n // The visible height, less whatever of the bottom bar still shows inside it (none once a keyboard covers it).\n shell.style.setProperty(\n \"--boff-explore-shell-room\",\n `calc(${Math.round(viewport.height)}px - max(0px, var(--boff-explore-shell-bottom, 0px) - ${covered}px))`,\n );\n shell.style.setProperty(\n \"--boff-explore-shell-top\",\n `${Math.max(0, Math.round(viewport.offsetTop))}px`,\n );\n };\n apply();\n viewport.addEventListener(\"resize\", apply);\n viewport.addEventListener(\"scroll\", apply);\n return () => {\n viewport.removeEventListener(\"resize\", apply);\n viewport.removeEventListener(\"scroll\", apply);\n clear();\n };\n }, [open]);\n\n /**\n * The composer, as soon as it can take focus, while focus is still where `from` put it. The composer sits in a box\n * with a CSS transition on every property, `visibility` included, so after the panel (or the chat) stops being\n * invisible it stays computed as hidden until that transition has actually started, which can be a frame or two\n * later, and a browser will not focus it until then (measured on Chromium and Firefox). So: one try per frame, for\n * at most the transition's length. A composer that never can (Explore unavailable) leaves focus on `from`.\n */\n const focusComposerSoon = useCallback((from: HTMLElement | null) => {\n let tries = 0;\n const next = (attempt: () => void) => {\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(attempt);\n } else {\n window.setTimeout(attempt, 16);\n }\n };\n const attempt = () => {\n if (document.activeElement !== from) return;\n const composer = chatPaneRef.current?.querySelector<HTMLTextAreaElement>(\n \"textarea:not(:disabled)\",\n );\n if (!composer) return;\n composer.focus();\n tries += 1;\n if (document.activeElement !== composer && tries < COMPOSER_FOCUS_TRIES) {\n next(attempt);\n }\n };\n next(attempt);\n }, []);\n\n // Focus into the panel when it opens: the panel itself at once, then the composer (not on a touch-first device,\n // where that would raise the keyboard over the panel unasked). Back to the button when it closes, unless the visitor\n // has already moved on to something else on the page.\n useEffect(() => {\n if (focusRequest === null) return;\n setFocusRequest(null);\n const shell = shellRef.current;\n if (focusRequest === \"back\") {\n const active = document.activeElement;\n if (\n active === null ||\n active === document.body ||\n shell?.contains(active)\n ) {\n returnFocusRef?.current?.focus();\n }\n return;\n }\n if (!shell) return;\n shell.focus();\n if (view === \"chat\" && !matches(TOUCH_FIRST_QUERY)) {\n focusComposerSoon(shell);\n }\n }, [focusComposerSoon, focusRequest, returnFocusRef, view]);\n\n const close = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n const expand = useCallback(() => {\n setSize(\"expanded\");\n whenSettled(() => {\n if (!openRef.current) return;\n if (readMark() === null) push(\"open\");\n if (readMark() === \"open\") push(\"expanded\");\n });\n }, [push, whenSettled]);\n\n const restore = useCallback(() => {\n setSize(\"compact\");\n whenSettled(() => {\n if (readMark() === \"expanded\") traverse(-1);\n });\n }, [traverse, whenSettled]);\n\n const onKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.key !== \"Escape\" || event.defaultPrevented) return;\n // Escape that only cancels an input method's candidate (Chinese, Japanese, …) is the input method's.\n if (event.nativeEvent.isComposing || event.keyCode === 229) return;\n const shell = shellRef.current;\n // Only Escape from inside the panel's own DOM: a portal below it in the React tree (the video player) closes\n // itself.\n if (\n !shell ||\n !(event.target instanceof Node) ||\n !shell.contains(event.target)\n ) {\n return;\n }\n // A dialog inside the conversation (the disclaimer) closes first, on its own.\n if (\n shell.querySelector('dialog[open], [role=\"dialog\"][aria-modal=\"true\"]')\n ) {\n return;\n }\n event.preventDefault();\n if (size === \"expanded\") restore();\n else close();\n },\n [close, restore, size],\n );\n\n // A link followed from the conversation. The panel's own entries come off first, so they are never left buried under\n // the new page (a Back that then shows nothing). On a phone the sheet would cover that page, so the panel closes;\n // wider, it stays open beside the page, compact, with its step on top of the new page so Back closes it first.\n const navigate = useCallback(\n (path: string) => {\n if (!onNavigate) return;\n setSize(\"compact\");\n const stayOpen = !matches(NARROW_QUERY);\n if (!stayOpen) onOpenChange(false);\n whenSettled(() => {\n const go = () => {\n onNavigate(path);\n if (stayOpen && openRef.current && readMark() === null) {\n push(\"open\");\n }\n };\n const count = marksOnTop(readMark());\n if (count === 0) {\n go();\n return;\n }\n afterPopRef.current.push(go);\n traverse(-count);\n });\n },\n [onNavigate, onOpenChange, push, traverse, whenSettled],\n );\n\n // A selected tab takes focus however it was chosen: Safari does not focus a clicked button, and the composer the\n // visitor may have been in is about to be covered.\n const selectView = useCallback((next: PanelView) => {\n setView(next);\n (next === \"chat\" ? chatTabRef : avatarTabRef).current?.focus();\n }, []);\n\n const continueInChat = useCallback(() => {\n setView(\"chat\");\n // The Chat tab at once (the button pressed here is about to be hidden, which would leave focus nowhere), then the\n // composer as soon as it can take focus. A composer that cannot (Explore unavailable) leaves it on the tab.\n const tab = chatTabRef.current;\n tab?.focus();\n focusComposerSoon(tab);\n }, [focusComposerSoon]);\n\n const onTabKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n // Two tabs: either arrow moves to the other one, in either reading direction.\n const other: PanelView = view === \"chat\" ? \"avatar\" : \"chat\";\n const next: Partial<Record<string, PanelView>> = {\n ArrowLeft: other,\n ArrowRight: other,\n Home: \"chat\",\n End: \"avatar\",\n };\n const target = next[event.key];\n if (!target) return;\n event.preventDefault();\n selectView(target);\n },\n [selectView, view],\n );\n\n if (!mounted) return null;\n\n const style: CSSProperties & CssVars = {\n \"--boff-explore-shell-bottom\": bottomOffset ?? \"0px\",\n ...(zIndex === undefined\n ? {}\n : { \"--boff-explore-shell-z\": String(zIndex) }),\n };\n const iconButton =\n \"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n const tabButton =\n \"rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n const expanded = size === \"expanded\";\n const sizeLabel = expanded ? T.exitFullScreen : T.enterFullScreen;\n const avatarAlt = avatar?.name\n ? `${avatar.name}, ${T.liveAvatar}`\n : T.liveAvatar;\n // The Avatar view as it has always been: the picture, \"Live avatar coming soon\" and \"Continue in Chat\". The live\n // avatar falls back to exactly this wherever it is not offered or not reachable.\n const comingSoon = avatar ? (\n <>\n <img\n src={avatar.src}\n alt={avatarAlt}\n loading=\"lazy\"\n decoding=\"async\"\n width={128}\n height={128}\n className=\"h-32 w-32 rounded-full border border-border object-cover shadow-sm\"\n />\n <p className=\"text-base font-semibold\">{T.avatarComingSoon}</p>\n <button\n type=\"button\"\n data-boff-explore=\"panel-continue-chat\"\n className=\"inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n onClick={continueInChat}\n >\n {T.continueInChat}\n </button>\n </>\n ) : null;\n const tabs: Array<{\n key: PanelView;\n id: string;\n pane: string;\n label: string;\n }> = [\n { key: \"chat\", id: chatTabId, pane: chatPaneId, label: T.tabChat },\n { key: \"avatar\", id: avatarTabId, pane: avatarPaneId, label: T.tabAvatar },\n ];\n\n return (\n <div\n ref={shellRef}\n id={id}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={titleId}\n tabIndex={-1}\n data-boff-explore=\"panel-shell\"\n data-open={open ? \"true\" : \"false\"}\n data-size={size}\n dir={rtl ? \"rtl\" : undefined}\n className={cn(\n \"boff-explore-shell border-border bg-background text-foreground shadow-2xl\",\n className,\n )}\n style={style}\n onKeyDown={onKeyDown}\n >\n <style>{PANEL_CSS}</style>\n {pinnedSlug === null ? null : (\n <style dangerouslySetInnerHTML={{ __html: PRODUCT_TITLE_CSS }} />\n )}\n <div className=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-2\">\n {/* The portfolio's short title keeps its one line, and its markup, exactly as they were. One product's own\n wraps (see PRODUCT_TITLE_CSS): its text sits in a box of its own inside the title's, whose width the\n stylesheet's container query reads. */}\n {pinnedSlug === null ? (\n <span\n id={titleId}\n className=\"min-w-0 flex-1 truncate text-sm font-semibold\"\n >\n {title}\n </span>\n ) : (\n <span\n id={titleId}\n className=\"boff-explore-shell-title min-w-0 flex-1\"\n >\n <span className=\"boff-explore-shell-title-text text-sm font-semibold\">\n {title}\n </span>\n </span>\n )}\n {avatar ? (\n <div\n role=\"tablist\"\n aria-label={T.panelViews}\n className=\"inline-flex shrink-0 rounded-lg bg-muted p-0.5\"\n >\n {tabs.map((tab) => (\n <button\n key={tab.key}\n ref={tab.key === \"chat\" ? chatTabRef : avatarTabRef}\n type=\"button\"\n role=\"tab\"\n id={tab.id}\n aria-selected={view === tab.key}\n aria-controls={tab.pane}\n tabIndex={view === tab.key ? 0 : -1}\n data-boff-explore={`panel-tab-${tab.key}`}\n className={cn(\n tabButton,\n view === tab.key\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n onClick={() => selectView(tab.key)}\n onKeyDown={onTabKeyDown}\n >\n {tab.label}\n </button>\n ))}\n </div>\n ) : null}\n <div className=\"flex shrink-0 items-center gap-1\">\n <button\n type=\"button\"\n data-boff-explore={expanded ? \"panel-restore\" : \"panel-expand\"}\n aria-label={sizeLabel}\n title={sizeLabel}\n className={iconButton}\n onClick={expanded ? restore : expand}\n >\n {expanded ? (\n <Minimize2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <Maximize2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n </button>\n <button\n type=\"button\"\n data-boff-explore=\"panel-close\"\n aria-label={T.closePanel}\n title={T.closePanel}\n className={iconButton}\n onClick={close}\n >\n <X className=\"h-4 w-4\" aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n {/* Laid out even under the Avatar view (only made invisible), so the transcript keeps its scroll position. */}\n <div\n ref={chatPaneRef}\n id={chatPaneId}\n role={avatar ? \"tabpanel\" : undefined}\n aria-labelledby={avatar ? chatTabId : undefined}\n data-boff-explore=\"panel-chat\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col\",\n view === \"avatar\" && \"invisible\",\n )}\n >\n <ExplorePage\n presentation=\"panel\"\n active={open && view === \"chat\"}\n productSlug={productSlug}\n locale={locale}\n scope={scope}\n productName={productName}\n examplePrompts={examplePrompts}\n onNavigate={onNavigate ? navigate : undefined}\n welcomeTitle={welcomeTitle}\n welcomeBody={welcomeBody}\n explorePath={explorePath}\n />\n </div>\n {avatar ? (\n <div\n id={avatarPaneId}\n role=\"tabpanel\"\n aria-labelledby={avatarTabId}\n data-boff-explore=\"panel-avatar\"\n className={cn(\n \"absolute inset-0 flex-col items-center justify-center gap-4 overflow-y-auto bg-background p-6 text-center\",\n view === \"avatar\" ? \"flex\" : \"hidden\",\n )}\n >\n {avatar.live ? (\n <ExploreAvatarLive\n live={avatar.live}\n active={open && view === \"avatar\"}\n locale={resolvedLocale}\n productName={pinnedName}\n still={{ src: avatar.src, alt: avatarAlt }}\n fallback={comingSoon}\n onContinueInChat={continueInChat}\n />\n ) : (\n comingSoon\n )}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/careers.tsx","../src/components/careers-submission.tsx","../src/components/concepts-types.ts","../src/components/concept-lightbox.tsx","../src/components/concepts.tsx","../src/components/answers-i18n.ts","../src/components/answers-types.ts","../src/components/answers.tsx","../src/components/explore-avatar-live.tsx","../src/components/explore-panel.tsx","../src/components/site-assistant-dock.tsx","../src/components/website-avatar-live.ts"],"names":["useRef","useState","toast","jsxs","jsx","CheckCircle","Fragment","ReCAPTCHA","Send","reactVersion","Info","useId","useCallback","useEffect","ChevronRight","META_DESCRIPTION_LIMIT","RELATED_LIMIT","normaliseSiteUrl","absoluteUrl","sortByOrder","clampText","slugifyAnchor","searchTokens","matchesSearch","copyKey","FilterChip","useMemo","Search","SECTION_HEADING","CHIP","ExternalLink","ArrowLeft","ArrowRight","useContext","open","onOpenChange","attempt","Maximize2","X"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\";\n\n/**\n * Careers Apply Form\n *\n * Public job-application form for product careers pages (e.g.\n * burdenoff.com/careers). Mirrors `ContactPage` — reCAPTCHA-gated submit via\n * the WebSDKClient — plus a resume upload. The resume is read client-side and\n * sent as base64 in the `submitJobApplication` mutation; the backend uploads it\n * to a private bucket server-side (no public presign endpoint).\n *\n * @example\n * ```tsx\n * <CareersApplyForm\n * productName=\"VibeControls\"\n * positions={[\"Senior Engineer\", \"Product Designer\"]}\n * />\n * ```\n */\n\nimport { useRef, useState } from \"react\";\n\nimport { CheckCircle, Send, Upload } from \"lucide-react\";\nimport ReCAPTCHA from \"react-google-recaptcha\";\nimport { toast } from \"sonner\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { useProduct } from \"../product/product-provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Textarea } from \"../ui/textarea\";\n\nimport type { WebSDKClient } from \"../client/graphql-client\";\n\n// Resumes only — must match the backend allow-list (PDF/DOC/DOCX).\nconst ALLOWED_RESUME_TYPES: Record<string, string> = {\n \"application/pdf\": \"PDF\",\n \"application/msword\": \"DOC\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"DOCX\",\n};\n// Some browsers/OSes report an empty or generic `file.type` for valid\n// .doc/.docx uploads. Fall back to the file extension → canonical MIME so the\n// upload validates client-side AND the backend (which checks `contentType`)\n// accepts it.\nconst EXT_TO_MIME: Record<string, string> = {\n pdf: \"application/pdf\",\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n};\nconst DEFAULT_MAX_RESUME_BYTES = 10 * 1024 * 1024; // 10MB — matches backend cap\n\n/** Resolve a canonical resume MIME from `file.type`, falling back to extension. */\nfunction resolveResumeType(file: File): string | null {\n if (ALLOWED_RESUME_TYPES[file.type]) return file.type;\n const ext = file.name.split(\".\").pop()?.toLowerCase();\n return ext && EXT_TO_MIME[ext] ? EXT_TO_MIME[ext] : null;\n}\n\n/** A job posting option for the CareersApplyForm dropdown. */\nexport interface CareersPostingOption {\n /** Posting ID — sent as `jobPostingId` in the application input. */\n id: string;\n /** Display title — also sent as the `position` string. */\n title: string;\n}\n\nexport interface CareersApplyFormProps {\n /** Product name (falls back to product context / SDK config). */\n productName?: string;\n /** reCAPTCHA site key (falls back to SDK config). */\n recaptchaSiteKey?: string;\n /**\n * Position options for the dropdown. When empty, a free-text \"position\"\n * input is shown instead so the form works before a postings list exists.\n */\n positions?: readonly string[];\n /**\n * Job postings for the dropdown (e.g. from `usePublicJobPostings`). When\n * non-empty this takes precedence over `positions`: the selected posting's\n * title is sent as `position` and its ID as `jobPostingId` so the\n * application is linked to the posting.\n */\n postings?: readonly CareersPostingOption[];\n heroTitle?: string;\n heroDescription?: string;\n /**\n * `1` (default) renders a full page hero `<h1>`; `2` renders a compact\n * `<h2>` section header for embedding under a page that owns the `<h1>`.\n */\n headingLevel?: 1 | 2;\n /** Max resume size in bytes (default 10MB, matches backend). */\n maxResumeBytes?: number;\n className?: string;\n seo?: { title?: string; description?: string; keywords?: string };\n}\n\nconst SUBMIT_JOB_APPLICATION_MUTATION = /* GraphQL */ `\n mutation SubmitJobApplication($input: SubmitJobApplicationInput!) {\n submitJobApplication(input: $input) {\n success\n message\n }\n }\n`;\n\ninterface JobApplicationData {\n firstName: string;\n lastName: string;\n email: string;\n phone?: string;\n position: string;\n /** Linked job posting ID — included only when a posting was selected. */\n jobPostingId?: string;\n linkedinUrl?: string;\n portfolioUrl?: string;\n coverLetter?: string;\n resumeBase64: string;\n resumeFileName: string;\n resumeContentType: string;\n recaptchaToken?: string;\n}\n\n/** Read a File as raw base64 (strips the `data:...;base64,` prefix). */\nfunction fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = typeof reader.result === \"string\" ? reader.result : \"\";\n const comma = result.indexOf(\",\");\n resolve(comma >= 0 ? result.slice(comma + 1) : result);\n };\n reader.onerror = () => reject(new Error(\"Failed to read the resume file\"));\n reader.readAsDataURL(file);\n });\n}\n\nasync function submitApplication(\n client: WebSDKClient,\n data: JobApplicationData,\n productId: string,\n): Promise<{ success: boolean; message?: string }> {\n try {\n const result = await client.mutate<{\n submitJobApplication: { success: boolean; message: string };\n }>(SUBMIT_JOB_APPLICATION_MUTATION, {\n input: {\n firstName: data.firstName,\n lastName: data.lastName,\n email: data.email.trim().toLowerCase(),\n position: data.position,\n resumeBase64: data.resumeBase64,\n resumeFileName: data.resumeFileName,\n resumeContentType: data.resumeContentType,\n productId,\n ...(data.phone ? { phone: data.phone } : {}),\n ...(data.linkedinUrl ? { linkedinUrl: data.linkedinUrl } : {}),\n ...(data.portfolioUrl ? { portfolioUrl: data.portfolioUrl } : {}),\n ...(data.coverLetter ? { coverLetter: data.coverLetter } : {}),\n ...(data.jobPostingId ? { jobPostingId: data.jobPostingId } : {}),\n ...(data.recaptchaToken ? { recaptchaToken: data.recaptchaToken } : {}),\n },\n });\n\n if (result.errors?.length) {\n return {\n success: false,\n message: result.errors[0]?.message ?? \"Failed to submit application\",\n };\n }\n const response = result.data?.submitJobApplication;\n return response?.success\n ? { success: true, message: response.message || \"Application submitted!\" }\n : {\n success: false,\n message: response?.message || \"Failed to submit application\",\n };\n } catch (error) {\n console.error(\"Job application submission error:\", error);\n return { success: false, message: \"Network error. Please try again.\" };\n }\n}\n\nexport function CareersApplyForm({\n productName,\n recaptchaSiteKey,\n positions = [],\n postings = [],\n heroTitle = \"Become a part of the team\",\n heroDescription = \"Tell us about yourself and upload your resume — we'll be in touch.\",\n headingLevel = 1,\n maxResumeBytes = DEFAULT_MAX_RESUME_BYTES,\n className,\n seo,\n}: CareersApplyFormProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const resolvedProductId = product?.id || config.productId;\n const displayName = productName ?? product?.name ?? config.productId;\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n product?.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [resumeFile, setResumeFile] = useState<File | null>(null);\n const [resumeType, setResumeType] = useState<string | null>(null);\n const [resumeError, setResumeError] = useState<string | null>(null);\n\n const maxMb = Math.floor(maxResumeBytes / (1024 * 1024));\n\n const clearResume = (): void => {\n setResumeFile(null);\n setResumeType(null);\n };\n\n const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n setResumeError(null);\n const file = e.target.files?.[0] ?? null;\n if (!file) {\n clearResume();\n return;\n }\n const type = resolveResumeType(file);\n if (!type) {\n clearResume();\n setResumeError(\"Resume must be a PDF, DOC, or DOCX file.\");\n return;\n }\n if (file.size > maxResumeBytes) {\n clearResume();\n setResumeError(`Resume must be ${maxMb}MB or smaller.`);\n return;\n }\n setResumeFile(file);\n setResumeType(type);\n };\n\n const handleSubmit = async (\n e: React.FormEvent<HTMLFormElement>,\n ): Promise<void> => {\n e.preventDefault();\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n if (!resumeFile) {\n setResumeError(\"Please attach your resume (PDF, DOC, or DOCX).\");\n return;\n }\n if (!resolvedProductId) {\n // Mirrors ContactPage. Warn so a misconfigured provider (no product\n // context and no config.productId) is visible rather than silently\n // sending an unattributed submission.\n console.warn(\n \"[CareersApplyForm] No productId resolved — submission will not be attributed to a product.\",\n );\n }\n\n const form = e.currentTarget;\n setIsSubmitting(true);\n try {\n const formData = new FormData(form);\n const resumeBase64 = await fileToBase64(resumeFile);\n // When postings drive the dropdown the submitted value is the posting\n // ID — resolve it back to the title for the `position` string and link\n // the application via `jobPostingId`.\n const positionValue = (formData.get(\"position\") as string) ?? \"\";\n const selectedPosting =\n postings.length > 0\n ? postings.find((p) => p.id === positionValue)\n : undefined;\n const result = await submitApplication(\n client,\n {\n firstName: (formData.get(\"firstName\") as string) ?? \"\",\n lastName: (formData.get(\"lastName\") as string) ?? \"\",\n email: (formData.get(\"email\") as string) ?? \"\",\n phone: (formData.get(\"phone\") as string) || undefined,\n position: selectedPosting ? selectedPosting.title : positionValue,\n jobPostingId: selectedPosting?.id,\n linkedinUrl: (formData.get(\"linkedinUrl\") as string) || undefined,\n portfolioUrl: (formData.get(\"portfolioUrl\") as string) || undefined,\n coverLetter: (formData.get(\"coverLetter\") as string) || undefined,\n resumeBase64,\n resumeFileName: resumeFile.name,\n // Use the resolved type (handles browsers that report an empty\n // file.type for .doc/.docx).\n resumeContentType: resumeType ?? resumeFile.type,\n recaptchaToken,\n },\n resolvedProductId,\n );\n\n if (result.success) {\n setSubmitted(true);\n toast.success(result.message ?? \"Application submitted!\");\n } else {\n toast.error(result.message ?? \"Failed to submit application\");\n recaptchaRef.current?.reset();\n }\n } catch (err) {\n console.error(\"Careers form error:\", err);\n toast.error(\"Something went wrong. Please try again.\");\n recaptchaRef.current?.reset();\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const Heading = headingLevel === 2 ? \"h2\" : \"h1\";\n const headingClass =\n headingLevel === 2\n ? \"text-2xl md:text-3xl font-bold mb-3\"\n : \"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\";\n\n return (\n <div className={className}>\n {seo && (\n <PageHead\n title={seo.title ?? `Careers — ${displayName}`}\n description={seo.description ?? heroDescription}\n keywords={seo.keywords}\n />\n )}\n\n <section\n className={\n headingLevel === 2\n ? \"py-12 md:py-16\"\n : \"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\"\n }\n >\n <div className=\"max-w-3xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-8 sm:mb-10\">\n <Heading className={headingClass}>{heroTitle}</Heading>\n <p className=\"text-lg text-muted-foreground leading-relaxed\">\n {heroDescription}\n </p>\n </div>\n\n {submitted ? (\n <div className=\"text-center rounded-xl border border-border bg-card p-10\">\n <CheckCircle className=\"mx-auto mb-4 h-12 w-12 text-accent\" />\n <h3 className=\"text-xl font-semibold text-foreground mb-2\">\n Application received\n </h3>\n <p className=\"text-muted-foreground\">\n Thanks for applying to {displayName}. We&apos;ve emailed you a\n confirmation and our team will be in touch.\n </p>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"firstName\">First name *</Label>\n <Input\n id=\"firstName\"\n name=\"firstName\"\n required\n placeholder=\"Ada\"\n />\n </div>\n <div>\n <Label htmlFor=\"lastName\">Last name *</Label>\n <Input\n id=\"lastName\"\n name=\"lastName\"\n required\n placeholder=\"Lovelace\"\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"email\">Email *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n placeholder=\"ada@example.com\"\n />\n </div>\n <div>\n <Label htmlFor=\"phone\">Phone</Label>\n <Input\n id=\"phone\"\n name=\"phone\"\n placeholder=\"+1 555 010 0100\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"position\">Position *</Label>\n {postings.length > 0 ? (\n <select\n id=\"position\"\n name=\"position\"\n required\n defaultValue=\"\"\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"\" disabled>\n Select a role\n </option>\n {postings.map((p) => (\n <option key={p.id} value={p.id}>\n {p.title}\n </option>\n ))}\n </select>\n ) : positions.length > 0 ? (\n <select\n id=\"position\"\n name=\"position\"\n required\n defaultValue=\"\"\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"\" disabled>\n Select a role\n </option>\n {positions.map((p) => (\n <option key={p} value={p}>\n {p}\n </option>\n ))}\n </select>\n ) : (\n <Input\n id=\"position\"\n name=\"position\"\n required\n placeholder=\"Role you're applying for\"\n />\n )}\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"linkedinUrl\">LinkedIn</Label>\n <Input\n id=\"linkedinUrl\"\n name=\"linkedinUrl\"\n type=\"url\"\n placeholder=\"https://linkedin.com/in/…\"\n />\n </div>\n <div>\n <Label htmlFor=\"portfolioUrl\">Portfolio / GitHub</Label>\n <Input\n id=\"portfolioUrl\"\n name=\"portfolioUrl\"\n type=\"url\"\n placeholder=\"https://…\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"coverLetter\">Cover letter</Label>\n <Textarea\n id=\"coverLetter\"\n name=\"coverLetter\"\n rows={5}\n placeholder=\"Tell us why you'd be a great fit…\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"resume\">\n Resume * (PDF, DOC, or DOCX — max {maxMb}MB)\n </Label>\n <label\n htmlFor=\"resume\"\n className=\"mt-1 flex cursor-pointer items-center gap-3 rounded-md border border-dashed border-input bg-background px-4 py-3 text-sm hover:bg-muted/40 transition-colors\"\n >\n <Upload\n className=\"h-5 w-5 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <span className=\"text-foreground\">\n {resumeFile ? resumeFile.name : \"Choose a file…\"}\n </span>\n <input\n id=\"resume\"\n name=\"resume\"\n type=\"file\"\n accept=\".pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n className=\"sr-only\"\n aria-describedby={resumeError ? \"resume-error\" : undefined}\n aria-invalid={resumeError ? true : undefined}\n onChange={handleFileChange}\n />\n </label>\n {resumeError && (\n <p\n id=\"resume-error\"\n role=\"alert\"\n className=\"mt-1 text-sm text-destructive\"\n >\n {resumeError}\n </p>\n )}\n </div>\n\n {effectiveRecaptchaSiteKey && (\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n )}\n\n <Button\n type=\"submit\"\n size=\"lg\"\n disabled={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {isSubmitting ? (\n \"Submitting…\"\n ) : (\n <>\n <Send className=\"mr-2 h-4 w-4\" /> Submit application\n </>\n )}\n </Button>\n </form>\n )}\n </div>\n </section>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Careers Submission Form\n *\n * Public assignment-response form for product careers pages — candidates who\n * already applied (via `CareersApplyForm`) submit their take-home assignment\n * here: a GitHub repo URL and a Jam/video walkthrough URL. Mirrors\n * `CareersApplyForm` — reCAPTCHA-gated submit via the WebSDKClient — calling\n * the `submitAssignmentResponse` mutation. The backend links the response to\n * the existing application by email, so the error UX calls out the \"no\n * application found\" case explicitly.\n *\n * @example\n * ```tsx\n * <CareersSubmissionForm\n * productName=\"VibeControls\"\n * postings={[{ id: \"posting-1\", title: \"Senior Engineer\" }]}\n * />\n * ```\n */\n\nimport { useRef, useState } from \"react\";\n\nimport { CheckCircle, Send } from \"lucide-react\";\nimport ReCAPTCHA from \"react-google-recaptcha\";\nimport { toast } from \"sonner\";\n\nimport { useWebSDK, useWebSDKConfig } from \"../client/provider\";\nimport { useProduct } from \"../product/product-provider\";\nimport { PageHead } from \"../seo/page-head\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Label } from \"../ui/label\";\nimport { Textarea } from \"../ui/textarea\";\n\nimport type { CareersPostingOption } from \"./careers\";\nimport type { WebSDKClient } from \"../client/graphql-client\";\n\nexport interface CareersSubmissionFormProps {\n /** Product name (falls back to product context / SDK config). */\n productName?: string;\n /** reCAPTCHA site key (falls back to SDK config). */\n recaptchaSiteKey?: string;\n /**\n * Job postings for the dropdown (e.g. from `usePublicJobPostings`). When\n * non-empty the selected posting's ID is sent as `jobPostingId` and its\n * title as `position`. When empty, a free-text \"position\" input is shown\n * instead so the form works before a postings list exists.\n */\n postings?: readonly CareersPostingOption[];\n heroTitle?: string;\n heroDescription?: string;\n /**\n * `1` (default) renders a full page hero `<h1>`; `2` renders a compact\n * `<h2>` section header for embedding under a page that owns the `<h1>`.\n */\n headingLevel?: 1 | 2;\n className?: string;\n seo?: { title?: string; description?: string; keywords?: string };\n}\n\nconst SUBMIT_ASSIGNMENT_RESPONSE_MUTATION = /* GraphQL */ `\n mutation SubmitAssignmentResponse($input: SubmitAssignmentResponseInput!) {\n submitAssignmentResponse(input: $input) {\n success\n message\n applicationId\n roundId\n }\n }\n`;\n\ninterface AssignmentResponseData {\n name?: string;\n email: string;\n position: string;\n /** Linked job posting ID — included only when a posting was selected. */\n jobPostingId?: string;\n repoUrl: string;\n videoUrl: string;\n notes?: string;\n recaptchaToken?: string;\n}\n\n/** True when `value` parses as an absolute http(s) URL. */\nexport function isValidUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nasync function submitAssignmentResponse(\n client: WebSDKClient,\n data: AssignmentResponseData,\n): Promise<{ success: boolean; message?: string }> {\n try {\n const result = await client.mutate<{\n submitAssignmentResponse: {\n success: boolean;\n message: string;\n applicationId?: string | null;\n roundId?: string | null;\n };\n }>(SUBMIT_ASSIGNMENT_RESPONSE_MUTATION, {\n input: {\n email: data.email.trim().toLowerCase(),\n repoUrl: data.repoUrl.trim(),\n videoUrl: data.videoUrl.trim(),\n recaptchaToken: data.recaptchaToken ?? \"\",\n ...(data.name ? { name: data.name } : {}),\n ...(data.position ? { position: data.position } : {}),\n ...(data.jobPostingId ? { jobPostingId: data.jobPostingId } : {}),\n ...(data.notes ? { notes: data.notes } : {}),\n },\n });\n\n if (result.errors?.length) {\n return {\n success: false,\n message: result.errors[0]?.message ?? \"Failed to submit assignment\",\n };\n }\n const response = result.data?.submitAssignmentResponse;\n return response?.success\n ? { success: true, message: response.message || \"Assignment submitted!\" }\n : {\n success: false,\n message: response?.message || \"Failed to submit assignment\",\n };\n } catch (error) {\n console.error(\"Assignment submission error:\", error);\n return { success: false, message: \"Network error. Please try again.\" };\n }\n}\n\n/**\n * Backend message for the \"no application found\" case — the candidate must\n * use the same email they applied with (or apply first).\n */\nconst NO_APPLICATION_HINT =\n \"Please use the same email address you applied with — or submit an application first.\";\n\nfunction isNoApplicationError(message: string): boolean {\n return /no application|not found/i.test(message);\n}\n\n/**\n * Sentinel option that switches the position field to free text — a\n * candidate's original posting may have closed since they applied, so the\n * dropdown (open postings only) must never be the only way to enter it.\n */\nconst OTHER_POSITION = \"__other__\";\n\nexport function CareersSubmissionForm({\n productName,\n recaptchaSiteKey,\n postings = [],\n heroTitle = \"Submit your assignment\",\n heroDescription = \"Share your GitHub repo and a short video walkthrough — make sure to use the same email you applied with.\",\n headingLevel = 1,\n className,\n seo,\n}: CareersSubmissionFormProps) {\n const client = useWebSDK();\n const config = useWebSDKConfig();\n const { product } = useProduct();\n const displayName = productName ?? product?.name ?? config.productId;\n const effectiveRecaptchaSiteKey =\n recaptchaSiteKey ??\n product?.recaptchaSiteKey ??\n config.recaptchaSiteKey ??\n \"\";\n\n const recaptchaRef = useRef<ReCAPTCHA>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submittedMessage, setSubmittedMessage] = useState<string | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n const [useFreeTextPosition, setUseFreeTextPosition] = useState(\n postings.length === 0,\n );\n\n const handleSubmit = async (\n e: React.FormEvent<HTMLFormElement>,\n ): Promise<void> => {\n e.preventDefault();\n setFormError(null);\n\n const recaptchaToken = recaptchaRef.current?.getValue() ?? \"\";\n if (effectiveRecaptchaSiteKey && !recaptchaToken) {\n toast.error(\"Please complete the reCAPTCHA verification\");\n return;\n }\n\n const form = e.currentTarget;\n const formData = new FormData(form);\n const name = ((formData.get(\"name\") as string) ?? \"\").trim();\n const email = ((formData.get(\"email\") as string) ?? \"\").trim();\n const positionValue = ((formData.get(\"position\") as string) ?? \"\").trim();\n const repoUrl = ((formData.get(\"repoUrl\") as string) ?? \"\").trim();\n const videoUrl = ((formData.get(\"videoUrl\") as string) ?? \"\").trim();\n const notes = ((formData.get(\"notes\") as string) ?? \"\").trim();\n\n // When postings drive the dropdown the submitted value is the posting\n // ID — resolve it back to the title for the `position` string and link\n // the response via `jobPostingId`. Free text (including the closed-role\n // fallback) has no matching posting, so it falls through as typed.\n const selectedPosting =\n postings.length > 0 && !useFreeTextPosition\n ? postings.find((p) => p.id === positionValue)\n : undefined;\n const position = selectedPosting ? selectedPosting.title : positionValue;\n\n // Client-side validation — native `required`/`type=\"url\"` covers real\n // browsers, but keep explicit checks so the rules hold everywhere.\n if (!email) {\n setFormError(\"Please enter the email address you applied with.\");\n return;\n }\n if (!position) {\n setFormError(\"Please select or enter the position you applied for.\");\n return;\n }\n if (!repoUrl || !isValidUrl(repoUrl)) {\n setFormError(\n \"Please enter a valid GitHub repository URL (e.g. https://github.com/you/project).\",\n );\n return;\n }\n if (!videoUrl || !isValidUrl(videoUrl)) {\n setFormError(\n \"Please enter a valid video URL (e.g. a Jam or Loom link starting with https://).\",\n );\n return;\n }\n\n setIsSubmitting(true);\n try {\n const result = await submitAssignmentResponse(client, {\n name: name || undefined,\n email,\n position,\n jobPostingId: selectedPosting?.id,\n repoUrl,\n videoUrl,\n notes: notes || undefined,\n recaptchaToken,\n });\n\n if (result.success) {\n setSubmittedMessage(result.message ?? \"Assignment submitted!\");\n toast.success(result.message ?? \"Assignment submitted!\");\n } else {\n const message = result.message ?? \"Failed to submit assignment\";\n setFormError(\n isNoApplicationError(message)\n ? `${message} ${NO_APPLICATION_HINT}`\n : message,\n );\n toast.error(message);\n recaptchaRef.current?.reset();\n }\n } catch (err) {\n console.error(\"Careers submission form error:\", err);\n setFormError(\"Something went wrong. Please try again.\");\n toast.error(\"Something went wrong. Please try again.\");\n recaptchaRef.current?.reset();\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const Heading = headingLevel === 2 ? \"h2\" : \"h1\";\n const headingClass =\n headingLevel === 2\n ? \"text-2xl md:text-3xl font-bold mb-3\"\n : \"text-3xl sm:text-4xl md:text-5xl font-bold mb-4 sm:mb-6\";\n\n return (\n <div className={className}>\n {seo && (\n <PageHead\n title={seo.title ?? `Submit your assignment — ${displayName}`}\n description={seo.description ?? heroDescription}\n keywords={seo.keywords}\n />\n )}\n\n <section\n className={\n headingLevel === 2\n ? \"py-12 md:py-16\"\n : \"bg-gradient-to-b from-background to-muted/20 py-12 sm:py-16 md:py-20 lg:py-24\"\n }\n >\n <div className=\"max-w-3xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-8 sm:mb-10\">\n <Heading className={headingClass}>{heroTitle}</Heading>\n <p className=\"text-lg text-muted-foreground leading-relaxed\">\n {heroDescription}\n </p>\n </div>\n\n {submittedMessage ? (\n <div className=\"text-center rounded-xl border border-border bg-card p-10\">\n <CheckCircle className=\"mx-auto mb-4 h-12 w-12 text-accent\" />\n <h3 className=\"text-xl font-semibold text-foreground mb-2\">\n Assignment received\n </h3>\n <p className=\"text-muted-foreground\">{submittedMessage}</p>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-5\">\n <div>\n <Label htmlFor=\"name\">Name</Label>\n <Input id=\"name\" name=\"name\" placeholder=\"Ada Lovelace\" />\n </div>\n <div>\n <Label htmlFor=\"email\">Email *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n placeholder=\"ada@example.com\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"position\">Position *</Label>\n {postings.length > 0 && !useFreeTextPosition ? (\n <>\n <select\n id=\"position\"\n name=\"position\"\n required\n defaultValue=\"\"\n onChange={(e) => {\n if (e.target.value === OTHER_POSITION) {\n setUseFreeTextPosition(true);\n }\n }}\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n >\n <option value=\"\" disabled>\n Select a role\n </option>\n {postings.map((p) => (\n <option key={p.id} value={p.id}>\n {p.title}\n </option>\n ))}\n <option value={OTHER_POSITION}>\n My role isn&apos;t listed\n </option>\n </select>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Applied to a role that&apos;s since closed? Choose{\" \"}\n <em>My role isn&apos;t listed</em> and type it in — you\n can still submit.\n </p>\n </>\n ) : (\n <>\n <Input\n id=\"position\"\n name=\"position\"\n required\n placeholder=\"Role you applied for\"\n />\n {postings.length > 0 && (\n <button\n type=\"button\"\n onClick={() => setUseFreeTextPosition(false)}\n className=\"mt-1 text-xs text-accent hover:underline\"\n >\n Choose from open roles instead\n </button>\n )}\n </>\n )}\n </div>\n\n <div>\n <Label htmlFor=\"repoUrl\">GitHub repository URL *</Label>\n <Input\n id=\"repoUrl\"\n name=\"repoUrl\"\n type=\"url\"\n required\n placeholder=\"https://github.com/you/assignment\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"videoUrl\">\n Video walkthrough URL (Jam, Loom, …) *\n </Label>\n <Input\n id=\"videoUrl\"\n name=\"videoUrl\"\n type=\"url\"\n required\n placeholder=\"https://jam.dev/c/…\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"notes\">Notes</Label>\n <Textarea\n id=\"notes\"\n name=\"notes\"\n rows={4}\n placeholder=\"Anything we should know before reviewing…\"\n />\n </div>\n\n {formError && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {formError}\n </p>\n )}\n\n {effectiveRecaptchaSiteKey && (\n <ReCAPTCHA\n ref={recaptchaRef}\n sitekey={effectiveRecaptchaSiteKey}\n />\n )}\n\n <Button\n type=\"submit\"\n size=\"lg\"\n disabled={isSubmitting}\n className=\"w-full sm:w-auto\"\n >\n {isSubmitting ? (\n \"Submitting…\"\n ) : (\n <>\n <Send className=\"mr-2 h-4 w-4\" /> Submit assignment\n </>\n )}\n </Button>\n </form>\n )}\n </div>\n </section>\n </div>\n );\n}\n","/**\n * Concept pages — the shared data contract.\n *\n * Every product website renders `/concepts` and `/concept/:slug` from a GENERATED\n * `src/data/concepts.ts` (`dev/scripts/concepts/build_site_concepts.py`), which types its\n * exports against these interfaces. The explore backend parses the same pages out of each\n * site's `llms-full.txt`, so a field renamed here breaks 37 site builds and the corpus at\n * once — change the generator and this file together, never one of them alone.\n *\n * Canonical source: `dev/platform/context/publishing/concepts/01-architecture.md` → \"Contracts\".\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\n/** The frame a mockup was drawn for. Drives nothing but layout hints. */\nexport type ConceptDevice = \"desktop\" | \"mobile\" | \"tablet\" | \"wide\" | \"other\";\n\n/** One mockup image. Paths are site-relative; the pages absolutise them for SEO. */\nexport interface ConceptImage {\n /** Stable id: the source path under the mockups folder, extension dropped, `/` → `--`. */\n key: string;\n /** Full-size image, e.g. `/mockups/15-sessions-list.webp`. */\n src: string;\n /** 640px-wide thumbnail, e.g. `/mockups/thumbs/15-sessions-list.webp`. */\n thumb: string;\n /** Intrinsic size of `src`. */\n width: number;\n height: number;\n /** Intrinsic size of `thumb`. */\n thumbWidth: number;\n thumbHeight: number;\n /** Short screen title. */\n title: string;\n /** Alt text. Always starts \"Concept illustration of\". */\n alt: string;\n /** One-line caption. */\n caption: string;\n /** 80–170 words describing what the illustration shows. */\n description: string;\n device: ConceptDevice;\n}\n\n/** A feature or flow, illustrated by one or more mockups. */\nexport interface Concept {\n slug: string;\n /** 1-based position across the product's concepts; drives listing and prev/next. */\n order: number;\n title: string;\n /** Matches a `ConceptCategory.name`. */\n category: string;\n tagline: string;\n metaDescription: string;\n overview: string[];\n highlights: string[];\n workflow: string[];\n audience: string[];\n keywords: string[];\n /** Slugs of related concepts on the same site. */\n related: string[];\n images: ConceptImage[];\n /**\n * Cross-product industry solutions on burdenoff.com/domains that feature this concept.\n * Generated from the domain dossiers; absent (or empty) when the concept is in none.\n */\n solutions?: ConceptSolution[];\n}\n\n/**\n * One industry solution — a page on https://burdenoff.com/domains that shows several\n * Burdenoff products working together in one domain (healthcare, logistics, …). A concept\n * page links to the solutions that feature it; a site's `/concepts` page lists every\n * solution its product takes part in.\n */\nexport interface ConceptSolution {\n /** Domain slug, e.g. `\"healthcare\"`. */\n domain: string;\n /** Domain display name, e.g. `\"Healthcare Providers\"`. */\n name: string;\n /** Absolute URL of the solution page, or of this concept's place in it. */\n url: string;\n /** Absolute URL of the domain illustration (a 16:9 thumbnail). */\n image?: string;\n /** One sentence: what this concept (or product) does in that solution. */\n summary?: string;\n}\n\nexport interface ConceptCategory {\n name: string;\n description: string;\n}\n\n/** Props the pages pass to a site's link adapter. */\nexport interface ConceptLinkProps {\n href: string;\n className?: string;\n children: ReactNode;\n \"aria-label\"?: string;\n}\n\n/**\n * The link the pages render for every internal URL. Sites pass a tiny adapter around their\n * router's `Link` so moving between concepts stays a client-side navigation; without one the\n * pages fall back to a plain `<a href>`.\n */\nexport type ConceptLinkComponent = ComponentType<ConceptLinkProps>;\n\n/**\n * The disclaimer shown beside every concept image. The same sentence applies to all of them\n * — including the few that began as real captures — so a visitor never has to guess which\n * picture shows the shipping product.\n */\nexport const CONCEPT_ILLUSTRATION_NOTICE =\n \"These images are illustrations of the concept, not screenshots of the actual product.\";\n\n/**\n * The disclaimer shown above every concept's \"How it works\" steps.\n *\n * A numbered list under that heading reads as a procedure — the sequence of screens a\n * visitor would click through — when what it actually describes is how the pieces of the\n * concept relate. The illustration notice covers the pictures; nothing covered the steps,\n * so the most instruction-shaped part of the page was the least qualified.\n *\n * Rendered with NO data gate, exactly like CONCEPT_ILLUSTRATION_NOTICE. Keying a\n * disclosure to a generated field is how it disappears silently the first time a\n * generator omits that field, and the page would then look more authoritative, not less.\n * The section's own `workflow.length > 0` check is the only condition: no steps, no\n * heading, nothing to qualify.\n *\n * The sentence says nothing about launch or availability. Every product behind these\n * pages is generally available, and a notice that hinted otherwise would be false on\n * every site that renders it.\n */\nexport const CONCEPT_WORKFLOW_NOTICE =\n \"These steps illustrate how the concept fits together — not a walkthrough of the product's current interface.\";\n\n/** Where every industry solution is listed. */\nexport const DOMAINS_URL = \"https://burdenoff.com/domains\";\n\n/** The landing page route. */\nexport const CONCEPTS_PATH = \"/concepts\";\n\n/** Prefix of every concept detail route: `/concept/<slug>`. */\nexport const CONCEPT_PATH_PREFIX = \"/concept\";\n\n/** Site-relative URL of a concept's detail page. */\nexport function conceptPath(slug: string): string {\n // Slugs are generated as [a-z0-9-], so this is a no-op for real data; it only keeps a\n // malformed slug from escaping its path segment.\n return `${CONCEPT_PATH_PREFIX}/${encodeURIComponent(slug)}`;\n}\n\n/**\n * Resolve a route parameter to its concept. Returns `undefined` for an unknown slug — the\n * site then redirects to `/concepts` rather than rendering a soft 404.\n */\nexport function getConceptBySlug(\n concepts: readonly Concept[],\n slug: string | null | undefined,\n): Concept | undefined {\n if (!slug) return undefined;\n const wanted = slug.trim().toLowerCase();\n if (!wanted) return undefined;\n return concepts.find((concept) => concept.slug === wanted);\n}\n","/**\n * ConceptLightbox — full-size view of one concept's illustrations.\n *\n * - A native `<dialog>` opened with `showModal()`: the browser supplies the top layer, the\n * inert page behind it, the focus containment and Esc-to-close. Nothing here re-implements\n * those.\n * - The parent mounts it ONLY while it is open. A closed dialog left in the tree would be\n * baked into every prerendered concept page, and the llms extractor would read its caption\n * and notice as page content.\n * - ← / → step through the concept's images and wrap at either end, so a held arrow key never\n * lands on a disabled button (disabling the focused control drops focus to the document).\n * - Returning focus to the control that opened it is the parent's job — it knows which\n * trigger that was even after the visitor has stepped to another image.\n */\n\"use client\";\n\nimport { useCallback, useEffect, useId, useRef } from \"react\";\nimport type { KeyboardEvent, MouseEvent, SyntheticEvent } from \"react\";\n\nimport { ChevronLeft, ChevronRight, Info, X } from \"lucide-react\";\n\nimport { CONCEPT_ILLUSTRATION_NOTICE } from \"./concepts-types\";\n\nimport type { ConceptImage } from \"./concepts-types\";\n\nexport interface ConceptLightboxProps {\n images: readonly ConceptImage[];\n /** Index into `images` of the illustration on screen. */\n index: number;\n /** The concept these illustrations belong to — shown above the image title. */\n conceptTitle: string;\n onIndexChange: (index: number) => void;\n onClose: () => void;\n}\n\nconst NAV_BUTTON =\n \"inline-flex h-11 w-11 items-center justify-center rounded-full border border-border bg-card text-foreground shadow-md transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n\nexport function ConceptLightbox({\n images,\n index,\n conceptTitle,\n onIndexChange,\n onClose,\n}: ConceptLightboxProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const closeRef = useRef<HTMLButtonElement>(null);\n /** False when the browser has no `showModal()` and Esc has to be handled here. */\n const nativeModalRef = useRef(false);\n const titleId = useId();\n\n const count = images.length;\n const position = count > 0 ? ((index % count) + count) % count : 0;\n const image = images[position];\n\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n if (typeof dialog.showModal === \"function\") {\n if (!dialog.open) dialog.showModal();\n nativeModalRef.current = true;\n } else {\n // No top layer in this engine: show it in place and handle Esc ourselves.\n dialog.setAttribute(\"open\", \"\");\n nativeModalRef.current = false;\n }\n closeRef.current?.focus();\n return () => {\n if (dialog.open && typeof dialog.close === \"function\") dialog.close();\n };\n }, []);\n\n const go = useCallback(\n (delta: number) => {\n if (count < 2) return;\n onIndexChange((position + delta + count) % count);\n },\n [count, onIndexChange, position],\n );\n\n // Esc closes the dialog natively and then fires `close`. StrictMode re-runs the mount\n // effect (close, then showModal again), so a `close` event can arrive for a dialog that is\n // already open again — that one must not tear the lightbox down.\n const handleClose = useCallback(\n (event: SyntheticEvent<HTMLDialogElement>) => {\n if (event.currentTarget.open) return;\n onClose();\n },\n [onClose],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDialogElement>) => {\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n go(1);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n go(-1);\n } else if (event.key === \"Escape\" && !nativeModalRef.current) {\n event.preventDefault();\n onClose();\n }\n },\n [go, onClose],\n );\n\n // A click on the empty stage around the picture dismisses, as it does on every lightbox.\n const handleStageClick = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n if (event.target === event.currentTarget) onClose();\n },\n [onClose],\n );\n\n if (!image) return null;\n\n return (\n <dialog\n ref={dialogRef}\n data-concepts=\"lightbox\"\n aria-labelledby={titleId}\n onClose={handleClose}\n onKeyDown={handleKeyDown}\n className=\"fixed inset-0 z-50 m-0 h-full max-h-none w-full max-w-none overflow-y-auto overscroll-contain border-0 bg-background/95 p-0 text-foreground backdrop-blur-sm\"\n >\n <div className=\"flex min-h-full flex-col\">\n <div className=\"flex items-start justify-between gap-4 border-b border-border px-4 py-3 sm:px-6\">\n <div className=\"min-w-0\">\n <p className=\"truncate text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {conceptTitle}\n {count > 1 ? ` · ${position + 1} / ${count}` : null}\n </p>\n <h2\n id={titleId}\n className=\"truncate text-base font-semibold text-foreground sm:text-lg\"\n >\n {image.title}\n </h2>\n </div>\n <button\n ref={closeRef}\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close\"\n data-concepts=\"lightbox-close\"\n className=\"inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-border bg-card text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <X aria-hidden=\"true\" className=\"h-5 w-5\" />\n </button>\n </div>\n\n <div\n className=\"relative flex flex-1 items-center justify-center px-4 py-4 sm:px-20\"\n onClick={handleStageClick}\n >\n {/* Keyed so a step to the next image never shows the previous one under the new\n title while it loads. */}\n <img\n key={image.key}\n src={image.src}\n alt={image.alt}\n width={image.width}\n height={image.height}\n decoding=\"async\"\n className=\"h-auto max-h-[calc(100vh-14rem)] w-auto max-w-full rounded-lg border border-border bg-muted object-contain shadow-lg\"\n />\n {count > 1 ? (\n <>\n <button\n type=\"button\"\n onClick={() => go(-1)}\n aria-label=\"Previous illustration\"\n data-concepts=\"lightbox-prev\"\n className={`absolute left-2 top-1/2 -translate-y-1/2 sm:left-4 ${NAV_BUTTON}`}\n >\n <ChevronLeft aria-hidden=\"true\" className=\"h-5 w-5\" />\n </button>\n <button\n type=\"button\"\n onClick={() => go(1)}\n aria-label=\"Next illustration\"\n data-concepts=\"lightbox-next\"\n className={`absolute right-2 top-1/2 -translate-y-1/2 sm:right-4 ${NAV_BUTTON}`}\n >\n <ChevronRight aria-hidden=\"true\" className=\"h-5 w-5\" />\n </button>\n </>\n ) : null}\n </div>\n\n <div className=\"border-t border-border px-4 py-3 sm:px-6\">\n <p className=\"text-sm leading-relaxed text-foreground\">\n {image.caption}\n </p>\n <p className=\"mt-1.5 flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground\">\n <Info aria-hidden=\"true\" className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n <span>{CONCEPT_ILLUSTRATION_NOTICE}</span>\n </p>\n </div>\n </div>\n </dialog>\n );\n}\n","/**\n * Concept pages — `/concepts` and `/concept/:slug` on every product website.\n *\n * A concept is a feature or flow of the product, shown through the mockups drawn for it and\n * explained in reviewed copy. The data is generated per site (`src/data/concepts.ts`) and\n * passed in; nothing here fetches, so both pages prerender completely and make no runtime\n * third-party requests.\n *\n * Written against three readers, in this order of strictness:\n *\n * - **Visitors.** Every image is labelled an illustration, never a screenshot: a badge on the\n * picture and the same notice callout on both pages. Colours are semantic tokens only, so\n * the pages are correct in light and dark mode on every product's palette.\n * - **Search engines.** One `<h1>` per page, a self-canonical URL, absolute Open Graph images\n * and JSON-LD (`CollectionPage` + `ItemList` on the landing page, `ImageGallery` on a\n * concept, `BreadcrumbList` on both).\n * - **The llms extractor** (`scripts/llms.mjs` on every site). It turns each gallery\n * `<img data-llms-image>` into its own `![alt](url)` line and takes the text line right\n * after it as the caption, so each gallery figure is title → image → `<figcaption>` →\n * description, with no block element in between. Only the gallery carries\n * `data-llms-image`; the hero repeats the first image and must not count twice. The\n * lightbox is mounted only while open, so it never reaches the prerendered HTML at all.\n *\n * Import from the package ROOT — `@burdenoff/website-sdk` — like every other page component\n * (tsup builds with `splitting: false`).\n *\n * @example\n * ```tsx\n * import { ConceptsPage, ConceptDetailPage, getConceptBySlug } from '@burdenoff/website-sdk'\n * import { CONCEPTS, CONCEPT_CATEGORIES } from '@/data/concepts'\n *\n * <ConceptsPage productName=\"VibeControls\" siteUrl=\"https://vibecontrols.com\"\n * concepts={CONCEPTS} categories={CONCEPT_CATEGORIES} linkComponent={SiteLink} />\n * ```\n */\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n version as reactVersion,\n} from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport {\n ArrowLeft,\n ArrowRight,\n Check,\n ChevronRight,\n ExternalLink,\n ImageIcon,\n Info,\n Maximize2,\n Search,\n} from \"lucide-react\";\n\nimport { ConceptLightbox } from \"./concept-lightbox\";\nimport {\n CONCEPT_ILLUSTRATION_NOTICE,\n CONCEPT_WORKFLOW_NOTICE,\n CONCEPTS_PATH,\n DOMAINS_URL,\n conceptPath,\n} from \"./concepts-types\";\nimport { PageHead } from \"../seo/page-head\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n Concept,\n ConceptCategory,\n ConceptImage,\n ConceptLinkComponent,\n ConceptLinkProps,\n ConceptSolution,\n} from \"./concepts-types\";\n\n// ============================================================================\n// Props\n// ============================================================================\n\nexport interface ConceptsPageProps {\n /** Product display name, e.g. `\"VibeControls\"`. */\n productName: string;\n /** Public origin of the site, e.g. `\"https://vibecontrols.com\"`. Used for absolute URLs. */\n siteUrl: string;\n concepts: readonly Concept[];\n /** Section order and descriptions. Concepts in an unlisted category still render, last. */\n categories?: readonly ConceptCategory[];\n /** Call to action rendered in the hero (e.g. the site's primary buttons). */\n cta?: ReactNode;\n /** Router adapter for internal links. Defaults to a plain `<a href>`. */\n linkComponent?: ConceptLinkComponent;\n /** Overrides the `<h1>`. Default: `\"<productName> concepts\"`. */\n title?: string;\n /** Overrides the meta description (and the hero lead). Default: built from the counts. */\n description?: string;\n /**\n * Industry solutions on burdenoff.com/domains that this product takes part in. Rendered as\n * a band after the concepts; omitted when empty.\n */\n solutions?: readonly ConceptSolution[];\n /** \"Browse every solution\" target. Default: {@link DOMAINS_URL}. */\n solutionsUrl?: string;\n /** Extra classes for the page root. */\n className?: string;\n}\n\nexport interface ConceptDetailPageProps {\n productName: string;\n siteUrl: string;\n /** The concept to render. The site resolves the slug and redirects when it is unknown. */\n concept: Concept;\n /** Every concept on the site — for related concepts and previous / next. */\n concepts: readonly Concept[];\n categories?: readonly ConceptCategory[];\n /** Call to action rendered as a band at the end of the page. */\n cta?: ReactNode;\n linkComponent?: ConceptLinkComponent;\n className?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst META_DESCRIPTION_LIMIT = 160;\nconst RELATED_LIMIT = 4;\n\n/**\n * `fetchpriority=\"high\"` for the hero, spelled the way the running React accepts it. React 19\n * knows the `fetchPriority` prop and warns about the lowercase form; React 18 (still inside\n * the peer range, and what this repo tests on) does not know it and warns unless it is\n * lowercase. Both put the same attribute in the DOM.\n */\nconst HERO_FETCH_PRIORITY: Record<string, string> =\n Number.parseInt(reactVersion, 10) >= 19\n ? { fetchPriority: \"high\" }\n : { fetchpriority: \"high\" };\n\n/** The origin without trailing slashes, so paths can be appended as-is. */\nfunction normaliseSiteUrl(siteUrl: string): string {\n return siteUrl.trim().replace(/\\/+$/, \"\");\n}\n\n/** Absolute form of a site-relative path; absolute URLs pass through. */\nfunction absoluteUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nfunction sortByOrder(concepts: readonly Concept[]): Concept[] {\n return [...concepts].sort(\n (a, b) => a.order - b.order || a.slug.localeCompare(b.slug),\n );\n}\n\nfunction plural(count: number, singular: string, pluralForm: string): string {\n return `${count} ${count === 1 ? singular : pluralForm}`;\n}\n\nfunction illustrationCount(count: number): string {\n return plural(count, \"illustration\", \"illustrations\");\n}\n\nfunction listSentence(items: readonly string[]): string {\n if (items.length <= 1) return items.join(\"\");\n return `${items.slice(0, -1).join(\", \")} and ${items[items.length - 1]}`;\n}\n\n/** Cut at a word boundary so a meta description never ends mid-word. */\nfunction clampText(text: string, limit: number): string {\n if (text.length <= limit) return text;\n const cut = text.slice(0, limit - 1);\n const lastSpace = cut.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\\s,;:—–-]+$/, \"\")}…`;\n}\n\n/**\n * The landing page's default meta description: counts, then as many category names as fit\n * in 160 characters, always mentioning that the pictures are illustrations. A site with no\n * concepts yet gets a description without counts rather than one announcing zero.\n */\nfunction defaultLandingDescription(\n productName: string,\n conceptTotal: number,\n imageTotal: number,\n categoryNames: readonly string[],\n): string {\n if (conceptTotal === 0) {\n return clampText(\n `Concepts of how ${productName} works, each a feature or flow explained with illustrations.`,\n META_DESCRIPTION_LIMIT,\n );\n }\n const head = `Explore ${plural(conceptTotal, `${productName} concept`, `${productName} concepts`)} with ${illustrationCount(imageTotal)}`;\n for (let take = Math.min(categoryNames.length, 4); take >= 1; take -= 1) {\n const more = categoryNames.length > take ? \" and more\" : \"\";\n const text = `${head} across ${listSentence(categoryNames.slice(0, take))}${more}.`;\n if (text.length <= META_DESCRIPTION_LIMIT) return text;\n }\n return clampText(`${head} of how the product works.`, META_DESCRIPTION_LIMIT);\n}\n\nfunction slugifyAnchor(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\ninterface CategoryGroup {\n name: string;\n description: string;\n /** DOM id of the section heading — unique even when two names slugify alike. */\n anchor: string;\n concepts: Concept[];\n}\n\n/**\n * Concepts grouped in the order `categories` lists them. Empty categories are dropped, and a\n * concept whose category is missing from the list still gets a section (after the listed\n * ones) rather than silently disappearing from the page.\n */\nfunction groupByCategory(\n ordered: readonly Concept[],\n categories: readonly ConceptCategory[] | undefined,\n): CategoryGroup[] {\n const byName = new Map<string, Concept[]>();\n for (const concept of ordered) {\n const list = byName.get(concept.category);\n if (list) list.push(concept);\n else byName.set(concept.category, [concept]);\n }\n\n const described: Array<Omit<CategoryGroup, \"anchor\">> = [];\n for (const category of categories ?? []) {\n const list = byName.get(category.name);\n if (!list) continue;\n described.push({\n name: category.name,\n description: category.description,\n concepts: list,\n });\n byName.delete(category.name);\n }\n for (const [name, list] of byName) {\n described.push({ name, description: \"\", concepts: list });\n }\n\n const used = new Set<string>();\n return described.map((group) => {\n const base = `concepts-${slugifyAnchor(group.name) || \"category\"}`;\n let anchor = base;\n for (let n = 2; used.has(anchor); n += 1) anchor = `${base}-${n}`;\n used.add(anchor);\n return { ...group, anchor };\n });\n}\n\nfunction searchTokens(query: string): string[] {\n return query.toLowerCase().split(/\\s+/).filter(Boolean);\n}\n\nfunction matchesSearch(concept: Concept, tokens: readonly string[]): boolean {\n if (tokens.length === 0) return true;\n const haystack = [\n concept.title,\n concept.tagline,\n concept.category,\n ...concept.keywords,\n ]\n .join(\" \")\n .toLowerCase();\n return tokens.every((token) => haystack.includes(token));\n}\n\nfunction isPortrait(width: number, height: number): boolean {\n return height > width;\n}\n\n/**\n * Key for a list rendered from the copy. The text alone collides when a list repeats an\n * entry, so the position qualifies it; these lists never reorder, so that is stable.\n */\nfunction copyKey(index: number, text: string): string {\n return `${index}-${text}`;\n}\n\n// ============================================================================\n// Shared pieces\n// ============================================================================\n\nfunction DefaultConceptLink({\n href,\n className,\n children,\n \"aria-label\": ariaLabel,\n}: ConceptLinkProps) {\n return (\n <a href={href} className={className} aria-label={ariaLabel}>\n {children}\n </a>\n );\n}\n\n/** The illustration disclaimer, as a callout that cannot be mistaken for body copy. */\nfunction IllustrationNotice({ className }: { className?: string }) {\n return (\n <div\n role=\"note\"\n data-concepts=\"notice\"\n data-concepts-notice=\"\"\n className={cn(\n \"flex items-start gap-3 rounded-xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm leading-relaxed text-foreground\",\n className,\n )}\n >\n <Info\n aria-hidden=\"true\"\n className=\"mt-0.5 h-4 w-4 shrink-0 text-primary\"\n />\n <p>{CONCEPT_ILLUSTRATION_NOTICE}</p>\n </div>\n );\n}\n\n/**\n * The workflow disclaimer, shown above a concept's numbered steps.\n *\n * Deliberately NOT the `data-concepts-notice` attribute IllustrationNotice carries: three\n * existing assertions select that attribute with `querySelector` and read the single node\n * they get back, so a second element wearing it would make those tests pass while\n * describing the wrong element. It renders no heading either — the detail page's heading\n * order is pinned.\n */\nfunction WorkflowNotice({ className }: { className?: string }) {\n return (\n <div\n role=\"note\"\n data-concepts=\"workflow-notice\"\n data-concepts-workflow-notice=\"\"\n className={cn(\n \"mt-4 flex items-start gap-3 rounded-xl border border-border bg-muted/50 px-4 py-3 text-sm leading-relaxed text-muted-foreground\",\n className,\n )}\n >\n <Info\n aria-hidden=\"true\"\n className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\"\n />\n <p>{CONCEPT_WORKFLOW_NOTICE}</p>\n </div>\n );\n}\n\n/**\n * The \"Illustration\" label laid over every concept picture. Hidden from assistive tech: every\n * alt text already begins \"Concept illustration of\", so reading the badge too is noise.\n */\nfunction IllustrationBadge({ className }: { className?: string }) {\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"pointer-events-none absolute left-2 top-2 inline-flex items-center rounded-full border border-border bg-background/90 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-foreground shadow-sm\",\n className,\n )}\n >\n Illustration\n </span>\n );\n}\n\n/**\n * A concept card: thumbnail, title, tagline and image count, all one link.\n *\n * The thumbnail is decorative here (`alt=\"\"`): the card's own title names the concept, and\n * the full alt text belongs to the concept page, where the image is the content.\n */\nfunction ConceptCard({\n concept,\n Link,\n}: {\n concept: Concept;\n Link: ConceptLinkComponent;\n}) {\n const image = concept.images[0];\n const portrait = image\n ? isPortrait(image.thumbWidth, image.thumbHeight)\n : false;\n\n return (\n <Link\n href={conceptPath(concept.slug)}\n className=\"group flex h-full flex-col overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none\"\n >\n <div className=\"relative aspect-[16/10] overflow-hidden border-b border-border bg-muted\">\n {image ? (\n <img\n src={image.thumb}\n alt=\"\"\n width={image.thumbWidth}\n height={image.thumbHeight}\n loading=\"lazy\"\n decoding=\"async\"\n className={cn(\n \"h-full w-full\",\n portrait ? \"object-contain p-3\" : \"object-cover object-top\",\n )}\n />\n ) : null}\n <IllustrationBadge />\n </div>\n <div className=\"flex flex-1 flex-col gap-2 p-4\">\n <h3 className=\"text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary\">\n {concept.title}\n </h3>\n <p className=\"line-clamp-3 text-sm leading-relaxed text-muted-foreground\">\n {concept.tagline}\n </p>\n <span className=\"mt-auto inline-flex items-center gap-1.5 pt-1 text-xs font-medium text-muted-foreground\">\n <ImageIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {illustrationCount(concept.images.length)}\n </span>\n </div>\n </Link>\n );\n}\n\nfunction FilterChip({\n label,\n count,\n active,\n category,\n onSelect,\n}: {\n label: string;\n count: number;\n active: boolean;\n category: string;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-category={category}\n onClick={onSelect}\n className={cn(\n \"inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-card text-foreground hover:border-primary/40 hover:bg-muted\",\n )}\n >\n <span>{label}</span>\n <span\n className={cn(\n \"rounded-full px-1.5 text-xs tabular-nums\",\n active\n ? \"bg-primary-foreground text-primary\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {count}\n </span>\n </button>\n );\n}\n\n/**\n * Industry solutions that feature this product or concept — cards linking to\n * burdenoff.com/domains, where several products are shown working together.\n *\n * The domain art is decorative (`alt=\"\"`, no `data-llms-image`): the card's heading names the\n * solution, and only concept illustrations may reach the llms extractor. The links leave the\n * site, so they are plain anchors that open a new tab, whatever router adapter the site uses.\n */\nfunction SolutionsSection({\n id,\n title,\n lead,\n solutions,\n moreHref,\n moreLabel,\n className,\n}: {\n id: string;\n title: string;\n lead: string;\n solutions: readonly ConceptSolution[];\n moreHref?: string;\n moreLabel?: string;\n className?: string;\n}) {\n return (\n <section\n id={id}\n aria-labelledby={`${id}-heading`}\n data-concepts=\"solutions\"\n className={cn(\"scroll-mt-24\", className)}\n >\n <div className=\"max-w-3xl\">\n <h2\n id={`${id}-heading`}\n className=\"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\"\n >\n {title}\n </h2>\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">{lead}</p>\n </div>\n <ul\n role=\"list\"\n className={cn(\n \"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2\",\n solutions.length >= 3 ? \"lg:grid-cols-3\" : \"lg:grid-cols-2\",\n )}\n >\n {solutions.map((solution) => (\n <li\n key={`${solution.domain}:${solution.url}`}\n data-domain={solution.domain}\n >\n <a\n href={solution.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"group flex h-full flex-col overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none\"\n >\n {solution.image ? (\n <div className=\"aspect-[16/9] overflow-hidden border-b border-border bg-muted\">\n <img\n src={solution.image}\n alt=\"\"\n width={640}\n height={360}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"h-full w-full object-cover transition duration-300 group-hover:scale-[1.03] motion-reduce:transition-none motion-reduce:group-hover:scale-100\"\n />\n </div>\n ) : null}\n <div className=\"flex flex-1 flex-col gap-2 p-4\">\n <p className=\"text-xs font-semibold uppercase tracking-[0.16em] text-primary\">\n Industry solution\n </p>\n <h3 className=\"text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary\">\n {solution.name}\n </h3>\n {solution.summary ? (\n <p className=\"line-clamp-3 text-sm leading-relaxed text-muted-foreground\">\n {solution.summary}\n </p>\n ) : null}\n <span className=\"mt-auto inline-flex items-center gap-1.5 pt-1 text-sm font-medium text-primary\">\n See the solution\n <ExternalLink aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n <span className=\"sr-only\">(opens in a new tab)</span>\n </span>\n </div>\n </a>\n </li>\n ))}\n </ul>\n {moreHref ? (\n <a\n href={moreHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mt-6 inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {moreLabel ?? \"Browse every industry solution\"}\n <ArrowRight aria-hidden=\"true\" className=\"h-4 w-4\" />\n <span className=\"sr-only\">(opens in a new tab)</span>\n </a>\n ) : null}\n </section>\n );\n}\n\n// ============================================================================\n// Landing page\n// ============================================================================\n\n/**\n * `/concepts` — every concept on the site, grouped by category, with a client-side search\n * and category filter. Filters start at \"All\", so the prerendered page lists everything.\n */\nexport function ConceptsPage({\n productName,\n siteUrl,\n concepts,\n categories,\n cta,\n linkComponent,\n title,\n description,\n solutions,\n solutionsUrl,\n className,\n}: ConceptsPageProps) {\n const Link = linkComponent ?? DefaultConceptLink;\n const base = normaliseSiteUrl(siteUrl);\n const searchId = useId();\n\n const ordered = useMemo(() => sortByOrder(concepts), [concepts]);\n const groups = useMemo(\n () => groupByCategory(ordered, categories),\n [ordered, categories],\n );\n const imageTotal = useMemo(\n () => ordered.reduce((sum, concept) => sum + concept.images.length, 0),\n [ordered],\n );\n\n const [query, setQuery] = useState(\"\");\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n\n const hasConcepts = ordered.length > 0;\n const tokens = useMemo(() => searchTokens(query), [query]);\n const searched = useMemo(\n () => ordered.filter((concept) => matchesSearch(concept, tokens)),\n [ordered, tokens],\n );\n // Chip counts follow the search, so each chip says how many results it would show.\n const countsByCategory = useMemo(() => {\n const counts = new Map<string, number>();\n for (const concept of searched) {\n counts.set(concept.category, (counts.get(concept.category) ?? 0) + 1);\n }\n return counts;\n }, [searched]);\n const visibleGroups = useMemo(() => {\n const visible = new Set(\n searched.filter(\n (concept) =>\n activeCategory === null || concept.category === activeCategory,\n ),\n );\n return groups\n .map((group) => ({\n ...group,\n concepts: group.concepts.filter((concept) => visible.has(concept)),\n }))\n .filter((group) => group.concepts.length > 0);\n }, [groups, searched, activeCategory]);\n const visibleTotal = visibleGroups.reduce(\n (sum, group) => sum + group.concepts.length,\n 0,\n );\n const filtering = tokens.length > 0 || activeCategory !== null;\n\n const clearFilters = useCallback(() => {\n setQuery(\"\");\n setActiveCategory(null);\n }, []);\n\n const heading = title ?? `${productName} concepts`;\n const metaDescription =\n description ??\n defaultLandingDescription(\n productName,\n ordered.length,\n imageTotal,\n groups.map((group) => group.name),\n );\n const lead =\n description ??\n `A guided tour of ${productName}, one concept at a time. Each concept groups the illustrations of a feature or flow and explains what it does, how it works and who it is for.`;\n\n const canonical = `${base}${CONCEPTS_PATH}`;\n const firstImage = ordered.find((concept) => concept.images[0])?.images[0];\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"CollectionPage\",\n name: heading,\n description: metaDescription,\n url: canonical,\n isPartOf: { \"@type\": \"WebSite\", name: productName, url: `${base}/` },\n mainEntity: {\n \"@type\": \"ItemList\",\n numberOfItems: ordered.length,\n itemListElement: ordered.map((concept, index) => {\n const image = concept.images[0];\n return {\n \"@type\": \"ListItem\",\n position: index + 1,\n url: absoluteUrl(base, conceptPath(concept.slug)),\n name: concept.title,\n ...(image ? { image: absoluteUrl(base, image.src) } : {}),\n };\n }),\n },\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n { \"@type\": \"ListItem\", position: 1, name: \"Home\", item: `${base}/` },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: \"Concepts\",\n item: canonical,\n },\n ],\n },\n ],\n [base, canonical, heading, metaDescription, ordered, productName],\n );\n\n return (\n <div\n data-concepts=\"landing\"\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title=\"Concepts\"\n description={metaDescription}\n productName={productName}\n keywords={[\n `${productName} concepts`,\n `${productName} illustrations`,\n ...groups.map((group) => group.name),\n ].join(\", \")}\n image={firstImage ? absoluteUrl(base, firstImage.src) : undefined}\n url={canonical}\n structuredData={structuredData}\n />\n\n <section className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-6xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8\">\n <p className=\"text-xs font-semibold uppercase tracking-[0.2em] text-primary\">\n Concepts\n </p>\n <h1 className=\"mt-3 max-w-3xl text-4xl font-bold tracking-tight text-foreground sm:text-5xl\">\n {heading}\n </h1>\n <p className=\"mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground\">\n {lead}\n </p>\n {hasConcepts ? (\n <p className=\"mt-6 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground\">\n <span>\n <strong className=\"text-lg font-semibold text-foreground\">\n {ordered.length}\n </strong>{\" \"}\n {ordered.length === 1 ? \"concept\" : \"concepts\"}\n </span>\n <span>\n <strong className=\"text-lg font-semibold text-foreground\">\n {imageTotal}\n </strong>{\" \"}\n {imageTotal === 1 ? \"illustration\" : \"illustrations\"}\n </span>\n </p>\n ) : null}\n <IllustrationNotice className=\"mt-6 max-w-2xl\" />\n {cta ? <div className=\"mt-8 flex flex-wrap gap-3\">{cta}</div> : null}\n </div>\n </section>\n\n <div className=\"mx-auto max-w-6xl px-4 pb-20 sm:px-6 lg:px-8\">\n {hasConcepts ? (\n <>\n <div\n role=\"search\"\n data-concepts=\"filter\"\n className=\"flex flex-col gap-4 py-8\"\n >\n <div className=\"relative w-full max-w-md\">\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n />\n <label htmlFor={searchId} className=\"sr-only\">\n Search concepts\n </label>\n <input\n id={searchId}\n type=\"search\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"Search concepts\"\n autoComplete=\"off\"\n className=\"h-10 w-full rounded-lg border border-border bg-background pl-9 pr-3 text-sm text-foreground shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </div>\n <div\n role=\"group\"\n aria-label=\"Filter by category\"\n className=\"flex flex-wrap gap-2\"\n >\n <FilterChip\n label=\"All\"\n category=\"all\"\n count={searched.length}\n active={activeCategory === null}\n onSelect={() => setActiveCategory(null)}\n />\n {groups.map((group) => (\n <FilterChip\n key={group.anchor}\n label={group.name}\n category={group.name}\n count={countsByCategory.get(group.name) ?? 0}\n active={activeCategory === group.name}\n onSelect={() =>\n setActiveCategory((current) =>\n current === group.name ? null : group.name,\n )\n }\n />\n ))}\n </div>\n {/* Visible only while a filter is on; announced whenever the result set changes. */}\n <p\n aria-live=\"polite\"\n className={\n filtering ? \"text-sm text-muted-foreground\" : \"sr-only\"\n }\n >\n Showing {visibleTotal} of {ordered.length}{\" \"}\n {ordered.length === 1 ? \"concept\" : \"concepts\"}\n </p>\n </div>\n\n {visibleTotal === 0 ? (\n <div\n data-concepts=\"empty\"\n className=\"rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <Search\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n No concepts match your filters\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n Try a different search, or show every category.\n </p>\n <button\n type=\"button\"\n onClick={clearFilters}\n className=\"mt-6 inline-flex items-center rounded-full border border-border bg-card px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n Clear filters\n </button>\n </div>\n ) : (\n <div className=\"space-y-14\">\n {visibleGroups.map((group) => (\n <section key={group.anchor} aria-labelledby={group.anchor}>\n <div className=\"max-w-3xl\">\n <h2\n id={group.anchor}\n className=\"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\"\n >\n {group.name}\n </h2>\n {group.description ? (\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">\n {group.description}\n </p>\n ) : null}\n </div>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3\"\n >\n {group.concepts.map((concept) => (\n <li\n key={concept.slug}\n data-concepts=\"card\"\n data-slug={concept.slug}\n >\n <ConceptCard concept={concept} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n )}\n </>\n ) : (\n // Nothing published yet: no filter bar with an \"All 0\" chip, and no empty state\n // that blames filters the visitor never set.\n <div\n data-concepts=\"none\"\n className=\"mt-10 rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <ImageIcon\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n No concepts published yet\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {productName} concepts will appear here as they are published.\n </p>\n </div>\n )}\n\n {solutions && solutions.length > 0 ? (\n <SolutionsSection\n id=\"industry-solutions\"\n title={`${productName} in industry solutions`}\n lead={`See how ${productName} works with other Burdenoff products to solve real problems in specific industries — each solution walks through the challenges, the products involved and the concepts behind them.`}\n solutions={solutions}\n moreHref={solutionsUrl ?? DOMAINS_URL}\n moreLabel=\"Browse every industry solution\"\n className=\"mt-16 border-t border-border pt-14\"\n />\n ) : null}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Detail page\n// ============================================================================\n\nconst SECTION_HEADING =\n \"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\";\nconst CHIP =\n \"inline-flex items-center rounded-full border border-border bg-muted/50 px-3 py-1 text-sm text-foreground\";\n\nfunction IllustrationFigure({\n image,\n onOpen,\n}: {\n image: ConceptImage;\n onOpen: (trigger: HTMLElement) => void;\n}) {\n const portrait = isPortrait(image.width, image.height);\n return (\n // The block the llms extractor reads: title, image line, caption, description — in\n // that order and with nothing in between. The description sits outside <figure>\n // because a <figcaption> must be the figure's first or last child.\n <div className=\"space-y-4\">\n <figure id={`illustration-${image.key}`} className=\"scroll-mt-24\">\n <h3 className=\"text-lg font-semibold text-foreground\">{image.title}</h3>\n <button\n type=\"button\"\n onClick={(event) => onOpen(event.currentTarget)}\n data-concepts=\"illustration\"\n className={cn(\n \"group relative mt-3 block w-full overflow-hidden rounded-2xl border border-border shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n portrait ? \"bg-muted p-4 sm:p-6\" : \"bg-muted\",\n )}\n >\n <img\n data-llms-image=\"\"\n src={image.src}\n alt={image.alt}\n width={image.width}\n height={image.height}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"mx-auto block h-auto max-h-[80vh] w-auto max-w-full\"\n />\n <IllustrationBadge className=\"left-3 top-3\" />\n <span\n aria-hidden=\"true\"\n className=\"absolute bottom-3 right-3 inline-flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm transition-opacity group-hover:opacity-100 sm:opacity-80\"\n >\n <Maximize2 className=\"h-4 w-4\" />\n </span>\n <span className=\"sr-only\">Enlarge illustration</span>\n </button>\n <figcaption className=\"mt-3 text-sm font-medium text-foreground\">\n {image.caption}\n </figcaption>\n </figure>\n <p className=\"leading-relaxed text-muted-foreground\">\n {image.description}\n </p>\n </div>\n );\n}\n\n/**\n * `/concept/:slug` — one concept: hero illustration, the copy, every illustration with its\n * caption and description, related concepts and previous / next by `order`.\n */\nexport function ConceptDetailPage(props: ConceptDetailPageProps) {\n // Keyed by slug: a router reuses this component when the visitor moves from one concept\n // to another, and that is a new page — lightbox closed, no stale focus target — not an\n // update of the old one.\n return <ConceptDetail key={props.concept.slug} {...props} />;\n}\n\nfunction ConceptDetail({\n productName,\n siteUrl,\n concept,\n concepts,\n categories,\n cta,\n linkComponent,\n className,\n}: ConceptDetailPageProps) {\n const Link = linkComponent ?? DefaultConceptLink;\n const base = normaliseSiteUrl(siteUrl);\n const headingId = useId();\n\n const ordered = useMemo(() => sortByOrder(concepts), [concepts]);\n const position = ordered.findIndex((item) => item.slug === concept.slug);\n const previous = position > 0 ? ordered[position - 1] : undefined;\n const next =\n position >= 0 && position < ordered.length - 1\n ? ordered[position + 1]\n : undefined;\n\n // Curated related concepts first; the rest of the category when none resolve. A slug\n // listed twice (the generator accepts repeats) still shows one card.\n const related = useMemo(() => {\n const bySlug = new Map(ordered.map((item) => [item.slug, item]));\n const curated = [...new Set(concept.related)]\n .map((slug) => bySlug.get(slug))\n .filter(\n (item): item is Concept =>\n item !== undefined && item.slug !== concept.slug,\n );\n const list =\n curated.length > 0\n ? curated\n : ordered.filter(\n (item) =>\n item.category === concept.category && item.slug !== concept.slug,\n );\n return list.slice(0, RELATED_LIMIT);\n }, [concept, ordered]);\n const relatedIsCurated = concept.related.some((slug) =>\n related.some((item) => item.slug === slug),\n );\n const categoryDescription = categories?.find(\n (category) => category.name === concept.category,\n )?.description;\n\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n const openLightbox = useCallback((index: number, trigger: HTMLElement) => {\n triggerRef.current = trigger;\n setLightboxIndex(index);\n }, []);\n const closeLightbox = useCallback(() => setLightboxIndex(null), []);\n\n // Focus goes back to the control that opened the lightbox — not to the top of the page,\n // which would strand a keyboard user far from where they were reading.\n useEffect(() => {\n if (lightboxIndex !== null) return;\n const trigger = triggerRef.current;\n if (!trigger) return;\n triggerRef.current = null;\n if (trigger.isConnected) trigger.focus();\n }, [lightboxIndex]);\n\n const canonical = absoluteUrl(base, conceptPath(concept.slug));\n const hero = concept.images[0];\n const imageTotal = concept.images.length;\n const solutions = concept.solutions ?? [];\n const solutionCount = solutions.length;\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ImageGallery\",\n name: concept.title,\n description: concept.metaDescription,\n url: canonical,\n keywords: concept.keywords.join(\", \"),\n about: { \"@type\": \"Thing\", name: productName },\n image: concept.images.map((image) => ({\n \"@type\": \"ImageObject\",\n contentUrl: absoluteUrl(base, image.src),\n thumbnailUrl: absoluteUrl(base, image.thumb),\n name: image.title,\n caption: image.caption,\n description: image.description,\n width: image.width,\n height: image.height,\n })),\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n { \"@type\": \"ListItem\", position: 1, name: \"Home\", item: `${base}/` },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: \"Concepts\",\n item: `${base}${CONCEPTS_PATH}`,\n },\n {\n \"@type\": \"ListItem\",\n position: 3,\n name: concept.title,\n item: canonical,\n },\n ],\n },\n ],\n [base, canonical, concept, productName],\n );\n\n return (\n <article\n data-concepts=\"detail\"\n data-slug={concept.slug}\n aria-labelledby={headingId}\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title={`${concept.title} — Concept`}\n description={concept.metaDescription}\n productName={productName}\n keywords={concept.keywords.join(\", \")}\n image={hero ? absoluteUrl(base, hero.src) : undefined}\n url={canonical}\n structuredData={structuredData}\n />\n\n <header className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-6xl px-4 pb-10 pt-8 sm:px-6 lg:px-8\">\n <nav aria-label=\"Breadcrumb\">\n <ol className=\"flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground\">\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href=\"/\"\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n Home\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href={CONCEPTS_PATH}\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n Concepts\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li\n aria-current=\"page\"\n className=\"min-w-0 truncate text-foreground\"\n >\n {concept.title}\n </li>\n </ol>\n </nav>\n\n <div className=\"mt-6 flex flex-wrap items-center gap-2\">\n <span\n data-concepts=\"category\"\n title={categoryDescription}\n className=\"inline-flex items-center rounded-full border border-primary/30 bg-primary/10 px-3 py-1 text-xs font-semibold text-primary\"\n >\n {concept.category}\n </span>\n <span className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground\">\n <ImageIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {illustrationCount(imageTotal)}\n </span>\n {solutionCount > 0 ? (\n <a\n href=\"#concept-solutions\"\n data-concepts=\"solutions-chip\"\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {solutionCount === 1\n ? \"Part of 1 industry solution\"\n : `Part of ${solutionCount} industry solutions`}\n </a>\n ) : null}\n </div>\n <h1\n id={headingId}\n className=\"mt-4 max-w-4xl text-3xl font-bold tracking-tight text-foreground sm:text-4xl lg:text-5xl\"\n >\n {concept.title}\n </h1>\n <p className=\"mt-4 max-w-3xl text-lg leading-relaxed text-muted-foreground\">\n {concept.tagline}\n </p>\n <IllustrationNotice className=\"mt-6 max-w-3xl\" />\n </div>\n </header>\n\n {hero ? (\n <div className=\"mx-auto max-w-6xl px-4 pt-10 sm:px-6 lg:px-8\">\n {/* No data-llms-image and no caption: the gallery below carries this image, and\n the extractor must see it exactly once. */}\n <figure data-concepts=\"hero\">\n <button\n type=\"button\"\n onClick={(event) => openLightbox(0, event.currentTarget)}\n className={cn(\n \"group relative block w-full overflow-hidden rounded-2xl border border-border bg-muted shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n isPortrait(hero.width, hero.height) && \"p-4 sm:p-6\",\n )}\n >\n <img\n src={hero.src}\n alt={hero.alt}\n width={hero.width}\n height={hero.height}\n loading=\"eager\"\n {...HERO_FETCH_PRIORITY}\n className=\"mx-auto block h-auto max-h-[75vh] w-auto max-w-full\"\n />\n <IllustrationBadge className=\"left-3 top-3\" />\n <span\n aria-hidden=\"true\"\n className=\"absolute bottom-3 right-3 inline-flex items-center gap-1.5 rounded-full border border-border bg-background/90 px-3 py-1 text-xs font-medium text-foreground shadow-sm\"\n >\n <Maximize2 className=\"h-3.5 w-3.5\" />\n Enlarge\n </span>\n <span className=\"sr-only\">Enlarge illustration</span>\n </button>\n </figure>\n </div>\n ) : null}\n\n <div className=\"mx-auto max-w-6xl px-4 py-14 sm:px-6 lg:px-8\">\n <div className=\"max-w-3xl space-y-12\">\n {concept.overview.length > 0 ? (\n <section aria-labelledby={`${headingId}-overview`}>\n <h2 id={`${headingId}-overview`} className={SECTION_HEADING}>\n Overview\n </h2>\n <div className=\"mt-4 space-y-4 text-base leading-relaxed text-foreground\">\n {concept.overview.map((paragraph, index) => (\n <p key={copyKey(index, paragraph)}>{paragraph}</p>\n ))}\n </div>\n </section>\n ) : null}\n\n {concept.highlights.length > 0 ? (\n <section aria-labelledby={`${headingId}-highlights`}>\n <h2 id={`${headingId}-highlights`} className={SECTION_HEADING}>\n What this concept shows\n </h2>\n <ul role=\"list\" className=\"mt-4 space-y-3\">\n {concept.highlights.map((highlight, index) => (\n <li\n key={copyKey(index, highlight)}\n className=\"flex items-start gap-3 leading-relaxed text-foreground\"\n >\n <span\n aria-hidden=\"true\"\n className=\"mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\"\n >\n <Check className=\"h-3.5 w-3.5\" />\n </span>\n <span>{highlight}</span>\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {concept.workflow.length > 0 ? (\n <section aria-labelledby={`${headingId}-workflow`}>\n <h2 id={`${headingId}-workflow`} className={SECTION_HEADING}>\n How it works\n </h2>\n <WorkflowNotice />\n <ol role=\"list\" className=\"mt-4 space-y-4\">\n {concept.workflow.map((step, index) => (\n <li\n key={copyKey(index, step)}\n className=\"flex items-start gap-4\"\n >\n <span\n aria-hidden=\"true\"\n className=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border border-border bg-card text-sm font-semibold tabular-nums text-foreground\"\n >\n {index + 1}\n </span>\n <span className=\"pt-0.5 leading-relaxed text-foreground\">\n {step}\n </span>\n </li>\n ))}\n </ol>\n </section>\n ) : null}\n\n {concept.audience.length > 0 ? (\n <section aria-labelledby={`${headingId}-audience`}>\n <h2 id={`${headingId}-audience`} className={SECTION_HEADING}>\n {\"Who it's for\"}\n </h2>\n <ul role=\"list\" className=\"mt-4 flex flex-wrap gap-2\">\n {concept.audience.map((who, index) => (\n <li key={copyKey(index, who)} className={CHIP}>\n {who}\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n </div>\n\n {imageTotal > 0 ? (\n <section\n aria-labelledby={`${headingId}-illustrations`}\n className=\"mt-16\"\n >\n <div className=\"max-w-3xl\">\n <h2 id={`${headingId}-illustrations`} className={SECTION_HEADING}>\n Illustrations\n </h2>\n <p className=\"mt-2 text-muted-foreground\">\n {illustrationCount(imageTotal)} of this concept. Select one to\n view it full size.\n </p>\n </div>\n <div className=\"mt-8 space-y-14\">\n {concept.images.map((image, index) => (\n <IllustrationFigure\n key={image.key}\n image={image}\n onOpen={(trigger) => openLightbox(index, trigger)}\n />\n ))}\n </div>\n </section>\n ) : null}\n\n {concept.keywords.length > 0 ? (\n <section aria-labelledby={`${headingId}-topics`} className=\"mt-16\">\n <h2 id={`${headingId}-topics`} className={SECTION_HEADING}>\n Topics\n </h2>\n <ul role=\"list\" className=\"mt-4 flex flex-wrap gap-2\">\n {concept.keywords.map((keyword, index) => (\n <li key={copyKey(index, keyword)} className={CHIP}>\n {keyword}\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {related.length > 0 ? (\n <section\n aria-labelledby={`${headingId}-related`}\n data-concepts=\"related\"\n className=\"mt-16\"\n >\n <h2 id={`${headingId}-related`} className={SECTION_HEADING}>\n {relatedIsCurated\n ? \"Related concepts\"\n : `More in ${concept.category}`}\n </h2>\n <ul\n role=\"list\"\n className={cn(\n \"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2\",\n related.length >= 4 ? \"lg:grid-cols-4\" : \"lg:grid-cols-3\",\n )}\n >\n {related.map((item) => (\n <li key={item.slug} data-concepts=\"card\" data-slug={item.slug}>\n <ConceptCard concept={item} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {solutionCount > 0 ? (\n <SolutionsSection\n id=\"concept-solutions\"\n title={\n solutionCount === 1\n ? \"Part of an industry solution\"\n : \"Part of industry solutions\"\n }\n lead={`This concept appears in ${solutionCount === 1 ? \"a cross-product solution\" : \"cross-product solutions\"} on burdenoff.com — see how it works alongside other Burdenoff products to solve a problem in that industry.`}\n solutions={solutions}\n className=\"mt-16\"\n />\n ) : null}\n\n {previous || next ? (\n <nav\n aria-label=\"Previous and next concepts\"\n data-concepts=\"pager\"\n className=\"mt-16 grid grid-cols-1 gap-4 sm:grid-cols-2\"\n >\n {previous ? (\n <Link\n href={conceptPath(previous.slug)}\n className=\"group flex items-center gap-3 rounded-2xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n Previous concept\n </span>\n <span className=\"block truncate font-semibold\">\n {previous.title}\n </span>\n </span>\n </Link>\n ) : (\n <span className=\"hidden sm:block\" />\n )}\n {next ? (\n <Link\n href={conceptPath(next.slug)}\n className=\"group flex items-center justify-end gap-3 rounded-2xl border border-border bg-card p-4 text-right text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n Next concept\n </span>\n <span className=\"block truncate font-semibold\">\n {next.title}\n </span>\n </span>\n <ArrowRight\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n </Link>\n ) : null}\n </nav>\n ) : null}\n\n <div className=\"mt-10\">\n <Link\n href={CONCEPTS_PATH}\n className=\"inline-flex items-center gap-2 rounded text-sm font-medium text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft aria-hidden=\"true\" className=\"h-4 w-4\" />\n All {productName} concepts\n </Link>\n </div>\n </div>\n\n {cta ? (\n <section\n data-concepts=\"cta\"\n className=\"border-t border-border bg-muted/30\"\n >\n <div className=\"mx-auto flex max-w-6xl flex-wrap items-center gap-4 px-4 py-12 sm:px-6 lg:px-8\">\n {cta}\n </div>\n </section>\n ) : null}\n\n {lightboxIndex !== null ? (\n <ConceptLightbox\n images={concept.images}\n index={lightboxIndex}\n conceptTitle={concept.title}\n onIndexChange={setLightboxIndex}\n onClose={closeLightbox}\n />\n ) : null}\n </article>\n );\n}\n","/**\n * Localisation for the published answer pages.\n *\n * Same arrangement, and the same reasons, as `explore-i18n.ts`: the strings are bundled\n * rather than fetched, because these pages are prerendered and a runtime translation request\n * in front of the first paint would defeat the point of prerendering them. The locale set,\n * the resolver and the `{placeholder}` filler are IMPORTED from there rather than repeated —\n * one locale list for the whole explore surface, so a seventh language is added in one place.\n *\n * ## What is localised, and what is not\n *\n * The chrome — headings, labels, the provenance note, the breadcrumb — is localised into the\n * six locales the products ship. **The answer itself is English**, because that is what the\n * harness produced for the curated English question; nothing here translates it, and nothing\n * here pretends it is translated.\n *\n * That split is also MARKED UP, not merely true: the pages carry `dir=\"rtl\"` on their own\n * subtree in Arabic (`isRtlLocale`, re-exported here so the pages have one locale module), and\n * put `lang=\"en\"` on the English content inside it. A page that declares itself Arabic and\n * then prints an English answer tells a screen reader to read English with Arabic phonemes,\n * and tells a crawler the answer is in a language it is not.\n *\n * ## The borrowed strings\n *\n * `answerTable`, `conceptIllustration`, `opensInNewTab` and the product-video card's and\n * player's words (`productVideo`, `productVideoTitle`, `playVideo`, `closeVideo`,\n * `enterFullScreen`, `exitFullScreen`, `videoUnavailable`) come straight from\n * `exploreStrings`. They are the\n * words the ANSWER BODY renders, and the answer body is the same component on both surfaces\n * — two phrasings for the same caveat read as two different caveats, which is the rule the\n * illustration badge already follows.\n */\n\nimport {\n type ExploreLocale,\n exploreStrings,\n fill,\n isRtlLocale,\n resolveExploreLocale,\n} from \"./explore-i18n\";\n\nimport type { AnswerRendererStrings } from \"./explore-answer\";\n\nexport { fill, isRtlLocale, resolveExploreLocale };\nexport type { ExploreLocale };\n\nexport interface AnswerStrings extends AnswerRendererStrings {\n breadcrumbHome: string;\n /** The section's own name: breadcrumb, nav item, back link. */\n answers: string;\n /** The index page's `<h1>`. Takes `{product}`. */\n indexHeading: string;\n /** The lead under it. Takes `{product}`. */\n indexLead: string;\n /** `<title>` of the index page; PageHead appends the product name itself. */\n seoIndexTitle: string;\n /** Its `<meta name=\"description\">`. Takes `{product}`. */\n seoIndexDescription: string;\n searchLabel: string;\n searchPlaceholder: string;\n filterByTopic: string;\n allTopics: string;\n /** Takes `{shown}` and `{total}`. */\n showingCount: string;\n noMatchesTitle: string;\n noMatchesBody: string;\n clearFilters: string;\n noneYetTitle: string;\n /** Takes `{product}`. */\n noneYetBody: string;\n questionCountOne: string;\n /** Takes `{count}`. */\n questionCountMany: string;\n sourceCountOne: string;\n /** Takes `{count}`. */\n sourceCountMany: string;\n answerHeading: string;\n sourcesHeading: string;\n sourcesLead: string;\n aboutTitle: string;\n /**\n * The honest description of what the reader is looking at. Takes `{date}`.\n *\n * Every clause is load-bearing, and the wording was chosen against the alternatives:\n *\n * - **\"Produced by our own assistant\"** — not \"written by our team\", which would be false,\n * and not \"AI-powered answers\", which is marketing language for a disclosure.\n * - **\"on {date}\"** — an answer is a snapshot of what the documentation said on a day. The\n * single genuinely misleading thing these pages could do is present a year-old answer as\n * current, so the date is in the sentence rather than in small print beside it.\n * - **\"The pages it drew on are linked under the answer\"** — it tells the reader where to\n * check, which is the only thing that makes the rest of the note actionable.\n * - **\"not a statement from a person\"** — the sentence people actually need. This is a\n * marketing surface, and a visitor who takes a generated paragraph for a commitment from\n * us has been misled by us.\n * - **\"where it and a linked page disagree, the page is right\"** — says which source wins,\n * instead of a hedge (\"may contain errors\") that tells nobody what to do about it.\n *\n * Deliberately NOT said: that the answers are \"frequently asked\" or \"the questions our\n * customers ask most\". They are a question set we chose. We have no measurement behind a\n * popularity claim — and the one table that could measure it is the visitor question log,\n * which this feature must never read (see `answers-types.ts`).\n */\n aboutBody: string;\n /** Takes `{date}`. */\n answeredOn: string;\n topicsHeading: string;\n relatedHeading: string;\n /** Takes `{topic}`. */\n moreInTopic: string;\n previousQuestion: string;\n nextQuestion: string;\n /** Takes `{product}`. */\n allAnswers: string;\n askYourOwn: string;\n}\n\n/** The chrome half — everything but the strings borrowed from `exploreStrings`. */\ntype AnswerChrome = Omit<AnswerStrings, keyof AnswerRendererStrings>;\n\n/**\n * English is the source of truth. Every other locale is a FULL object, so a missing key is a\n * type error at build time rather than a raw key on a live marketing page.\n */\nconst EN: AnswerChrome = {\n breadcrumbHome: \"Home\",\n answers: \"Answers\",\n indexHeading: \"{product} answers\",\n indexLead:\n \"Questions about {product}, each answered by our own assistant from our published documentation — with links to the pages the answer came from.\",\n seoIndexTitle: \"Answers\",\n seoIndexDescription:\n \"Questions about {product}, answered from our published documentation, each with links to the pages the answer came from.\",\n searchLabel: \"Search questions\",\n searchPlaceholder: \"Search questions\",\n filterByTopic: \"Filter by topic\",\n allTopics: \"All\",\n showingCount: \"Showing {shown} of {total} questions\",\n noMatchesTitle: \"No questions match your filters\",\n noMatchesBody: \"Try a different search, or show every topic.\",\n clearFilters: \"Clear filters\",\n noneYetTitle: \"No answers published yet\",\n noneYetBody: \"{product} answers will appear here as they are published.\",\n questionCountOne: \"1 question\",\n questionCountMany: \"{count} questions\",\n sourceCountOne: \"1 source\",\n sourceCountMany: \"{count} sources\",\n answerHeading: \"Answer\",\n sourcesHeading: \"Sources\",\n sourcesLead: \"The pages this answer was drawn from.\",\n aboutTitle: \"About this answer\",\n aboutBody:\n \"Produced by our own assistant on {date} from our published documentation. The pages it drew on are linked under the answer. It is generated text, not a statement from a person — where it and a linked page disagree, the page is right.\",\n answeredOn: \"Answered {date}\",\n topicsHeading: \"Topics\",\n relatedHeading: \"Related questions\",\n moreInTopic: \"More in {topic}\",\n previousQuestion: \"Previous question\",\n nextQuestion: \"Next question\",\n allAnswers: \"All {product} answers\",\n askYourOwn: \"Ask your own question\",\n};\n\nconst ZH: AnswerChrome = {\n breadcrumbHome: \"首页\",\n answers: \"问答\",\n indexHeading: \"{product} 问答\",\n indexLead:\n \"关于 {product} 的问题,每个回答都由我们自己的助手依据已公开的文档生成,并附上回答所依据页面的链接。\",\n seoIndexTitle: \"问答\",\n seoIndexDescription:\n \"关于 {product} 的问题,依据我们已公开的文档作答,每个回答都附有来源页面的链接。\",\n searchLabel: \"搜索问题\",\n searchPlaceholder: \"搜索问题\",\n filterByTopic: \"按主题筛选\",\n allTopics: \"全部\",\n showingCount: \"显示 {total} 个问题中的 {shown} 个\",\n noMatchesTitle: \"没有符合筛选条件的问题\",\n noMatchesBody: \"换个搜索词,或显示全部主题。\",\n clearFilters: \"清除筛选\",\n noneYetTitle: \"尚未发布问答\",\n noneYetBody: \"{product} 的问答发布后会显示在这里。\",\n questionCountOne: \"1 个问题\",\n questionCountMany: \"{count} 个问题\",\n sourceCountOne: \"1 个来源\",\n sourceCountMany: \"{count} 个来源\",\n answerHeading: \"回答\",\n sourcesHeading: \"来源\",\n sourcesLead: \"本回答所依据的页面。\",\n aboutTitle: \"关于这个回答\",\n aboutBody:\n \"本回答由我们自己的助手于 {date} 依据已公开的文档生成,所依据的页面列在回答下方。这是自动生成的文本,并非某位同事的说法——如果它与所链接的页面不一致,请以页面为准。\",\n answeredOn: \"回答于 {date}\",\n topicsHeading: \"主题\",\n relatedHeading: \"相关问题\",\n moreInTopic: \"更多「{topic}」问题\",\n previousQuestion: \"上一个问题\",\n nextQuestion: \"下一个问题\",\n allAnswers: \"全部 {product} 问答\",\n askYourOwn: \"提出你的问题\",\n};\n\nconst HI: AnswerChrome = {\n breadcrumbHome: \"होम\",\n answers: \"उत्तर\",\n indexHeading: \"{product} के उत्तर\",\n indexLead:\n \"{product} से जुड़े सवाल, जिनका उत्तर हमारा अपना सहायक हमारे प्रकाशित दस्तावेज़ों से देता है — और जिन पन्नों से उत्तर आया, उनके लिंक साथ में हैं।\",\n seoIndexTitle: \"उत्तर\",\n seoIndexDescription:\n \"{product} से जुड़े सवालों के उत्तर, हमारे प्रकाशित दस्तावेज़ों से — हर उत्तर के साथ स्रोत पन्नों के लिंक।\",\n searchLabel: \"सवाल खोजें\",\n searchPlaceholder: \"सवाल खोजें\",\n filterByTopic: \"विषय से छाँटें\",\n allTopics: \"सभी\",\n showingCount: \"{total} में से {shown} सवाल दिख रहे हैं\",\n noMatchesTitle: \"आपकी छँटाई से कोई सवाल मेल नहीं खाता\",\n noMatchesBody: \"कुछ और खोजें, या सभी विषय दिखाएँ।\",\n clearFilters: \"छँटाई हटाएँ\",\n noneYetTitle: \"अभी कोई उत्तर प्रकाशित नहीं हुआ\",\n noneYetBody: \"{product} के उत्तर प्रकाशित होते ही यहाँ दिखेंगे।\",\n questionCountOne: \"1 सवाल\",\n questionCountMany: \"{count} सवाल\",\n sourceCountOne: \"1 स्रोत\",\n sourceCountMany: \"{count} स्रोत\",\n answerHeading: \"उत्तर\",\n sourcesHeading: \"स्रोत\",\n sourcesLead: \"यह उत्तर जिन पन्नों से लिया गया है।\",\n aboutTitle: \"इस उत्तर के बारे में\",\n aboutBody:\n \"यह उत्तर {date} को हमारे अपने सहायक ने हमारे प्रकाशित दस्तावेज़ों से तैयार किया था। जिन पन्नों का उपयोग हुआ, वे उत्तर के नीचे दिए गए हैं। यह अपने-आप तैयार किया गया पाठ है, किसी व्यक्ति का कथन नहीं — अगर इसमें और लिंक किए गए पन्ने में फ़र्क़ हो, तो पन्ना सही है।\",\n answeredOn: \"{date} को उत्तर दिया गया\",\n topicsHeading: \"विषय\",\n relatedHeading: \"संबंधित सवाल\",\n moreInTopic: \"{topic} में और\",\n previousQuestion: \"पिछला सवाल\",\n nextQuestion: \"अगला सवाल\",\n allAnswers: \"{product} के सभी उत्तर\",\n askYourOwn: \"अपना सवाल पूछें\",\n};\n\nconst ES: AnswerChrome = {\n breadcrumbHome: \"Inicio\",\n answers: \"Respuestas\",\n indexHeading: \"Respuestas sobre {product}\",\n indexLead:\n \"Preguntas sobre {product}, respondidas por nuestro propio asistente a partir de nuestra documentación publicada, con enlaces a las páginas de las que salió cada respuesta.\",\n seoIndexTitle: \"Respuestas\",\n seoIndexDescription:\n \"Preguntas sobre {product} respondidas a partir de nuestra documentación publicada, cada una con enlaces a las páginas de origen.\",\n searchLabel: \"Buscar preguntas\",\n searchPlaceholder: \"Buscar preguntas\",\n filterByTopic: \"Filtrar por tema\",\n allTopics: \"Todas\",\n showingCount: \"Mostrando {shown} de {total} preguntas\",\n noMatchesTitle: \"Ninguna pregunta coincide con los filtros\",\n noMatchesBody: \"Prueba otra búsqueda o muestra todos los temas.\",\n clearFilters: \"Quitar filtros\",\n noneYetTitle: \"Todavía no hay respuestas publicadas\",\n noneYetBody:\n \"Las respuestas sobre {product} aparecerán aquí a medida que se publiquen.\",\n questionCountOne: \"1 pregunta\",\n questionCountMany: \"{count} preguntas\",\n sourceCountOne: \"1 fuente\",\n sourceCountMany: \"{count} fuentes\",\n answerHeading: \"Respuesta\",\n sourcesHeading: \"Fuentes\",\n sourcesLead: \"Las páginas de las que salió esta respuesta.\",\n aboutTitle: \"Sobre esta respuesta\",\n aboutBody:\n \"La preparó nuestro propio asistente el {date} a partir de nuestra documentación publicada. Las páginas que utilizó están enlazadas debajo de la respuesta. Es texto generado, no la palabra de una persona: si la respuesta y una página enlazada no coinciden, manda la página.\",\n answeredOn: \"Respondida el {date}\",\n topicsHeading: \"Temas\",\n relatedHeading: \"Preguntas relacionadas\",\n moreInTopic: \"Más de {topic}\",\n previousQuestion: \"Pregunta anterior\",\n nextQuestion: \"Pregunta siguiente\",\n allAnswers: \"Todas las respuestas sobre {product}\",\n askYourOwn: \"Haz tu propia pregunta\",\n};\n\nconst AR: AnswerChrome = {\n breadcrumbHome: \"الرئيسية\",\n answers: \"الإجابات\",\n indexHeading: \"إجابات {product}\",\n indexLead:\n \"أسئلة حول {product}، يجيب عنها مساعدنا اعتمادًا على وثائقنا المنشورة، مع روابط إلى الصفحات التي جاءت منها كل إجابة.\",\n seoIndexTitle: \"الإجابات\",\n seoIndexDescription:\n \"أسئلة حول {product} مُجاب عنها من وثائقنا المنشورة، مع روابط إلى صفحات المصدر لكل إجابة.\",\n searchLabel: \"ابحث في الأسئلة\",\n searchPlaceholder: \"ابحث في الأسئلة\",\n filterByTopic: \"تصفية حسب الموضوع\",\n allTopics: \"الكل\",\n showingCount: \"عرض {shown} من {total} سؤالًا\",\n noMatchesTitle: \"لا توجد أسئلة تطابق التصفية\",\n noMatchesBody: \"جرّب بحثًا آخر، أو اعرض كل المواضيع.\",\n clearFilters: \"مسح التصفية\",\n noneYetTitle: \"لم تُنشر إجابات بعد\",\n noneYetBody: \"ستظهر إجابات {product} هنا فور نشرها.\",\n questionCountOne: \"سؤال واحد\",\n questionCountMany: \"{count} أسئلة\",\n sourceCountOne: \"مصدر واحد\",\n sourceCountMany: \"{count} مصادر\",\n answerHeading: \"الإجابة\",\n sourcesHeading: \"المصادر\",\n sourcesLead: \"الصفحات التي استُمدت منها هذه الإجابة.\",\n aboutTitle: \"عن هذه الإجابة\",\n aboutBody:\n \"أعدّها مساعدنا في {date} اعتمادًا على وثائقنا المنشورة، والصفحات التي استند إليها مذكورة أسفل الإجابة. هذا نص مُولَّد آليًا وليس كلام شخص — وإذا اختلف مع صفحة مرتبطة، فالصفحة هي الصحيحة.\",\n answeredOn: \"أُجيب عنه في {date}\",\n topicsHeading: \"المواضيع\",\n relatedHeading: \"أسئلة ذات صلة\",\n moreInTopic: \"المزيد في {topic}\",\n previousQuestion: \"السؤال السابق\",\n nextQuestion: \"السؤال التالي\",\n allAnswers: \"كل إجابات {product}\",\n askYourOwn: \"اطرح سؤالك\",\n};\n\nconst TA: AnswerChrome = {\n breadcrumbHome: \"முகப்பு\",\n answers: \"பதில்கள்\",\n indexHeading: \"{product} பதில்கள்\",\n indexLead:\n \"{product} பற்றிய கேள்விகள் — ஒவ்வொன்றுக்கும் எங்கள் உதவியாளர் எங்கள் வெளியிடப்பட்ட ஆவணங்களிலிருந்து அளித்த பதில், பதில் வந்த பக்கங்களுக்கான இணைப்புகளுடன்.\",\n seoIndexTitle: \"பதில்கள்\",\n seoIndexDescription:\n \"{product} பற்றிய கேள்விகளுக்கு எங்கள் வெளியிடப்பட்ட ஆவணங்களிலிருந்து பதில்கள் — ஒவ்வொன்றிலும் மூலப் பக்கங்களுக்கான இணைப்புகளுடன்.\",\n searchLabel: \"கேள்விகளைத் தேடுங்கள்\",\n searchPlaceholder: \"கேள்விகளைத் தேடுங்கள்\",\n filterByTopic: \"தலைப்பின்படி வடிகட்டு\",\n allTopics: \"அனைத்தும்\",\n showingCount: \"{total} கேள்விகளில் {shown} காட்டப்படுகிறது\",\n noMatchesTitle: \"வடிகட்டலுக்குப் பொருந்தும் கேள்வி இல்லை\",\n noMatchesBody:\n \"வேறு ஒன்றைத் தேடுங்கள், அல்லது எல்லாத் தலைப்புகளையும் காட்டுங்கள்.\",\n clearFilters: \"வடிகட்டலை நீக்கு\",\n noneYetTitle: \"இதுவரை பதில்கள் வெளியிடப்படவில்லை\",\n noneYetBody: \"{product} பதில்கள் வெளியிடப்படும்போது இங்கே தோன்றும்.\",\n questionCountOne: \"1 கேள்வி\",\n questionCountMany: \"{count} கேள்விகள்\",\n sourceCountOne: \"1 மூலம்\",\n sourceCountMany: \"{count} மூலங்கள்\",\n answerHeading: \"பதில்\",\n sourcesHeading: \"மூலங்கள்\",\n sourcesLead: \"இந்தப் பதில் எடுக்கப்பட்ட பக்கங்கள்.\",\n aboutTitle: \"இந்தப் பதில் பற்றி\",\n aboutBody:\n \"இதை எங்கள் உதவியாளர் {date} அன்று எங்கள் வெளியிடப்பட்ட ஆவணங்களிலிருந்து உருவாக்கியது; பயன்படுத்திய பக்கங்கள் பதிலுக்குக் கீழே இணைக்கப்பட்டுள்ளன. இது தானாக உருவாக்கப்பட்ட உரை, ஒரு நபரின் கூற்று அல்ல — இதற்கும் இணைக்கப்பட்ட பக்கத்திற்கும் வேறுபாடு இருந்தால், பக்கமே சரி.\",\n answeredOn: \"{date} அன்று பதிலளிக்கப்பட்டது\",\n topicsHeading: \"தலைப்புகள்\",\n relatedHeading: \"தொடர்புடைய கேள்விகள்\",\n moreInTopic: \"{topic} இல் மேலும்\",\n previousQuestion: \"முந்தைய கேள்வி\",\n nextQuestion: \"அடுத்த கேள்வி\",\n allAnswers: \"{product} அனைத்துப் பதில்களும்\",\n askYourOwn: \"உங்கள் கேள்வியைக் கேளுங்கள்\",\n};\n\nconst CHROME: Record<ExploreLocale, AnswerChrome> = {\n en: EN,\n zh: ZH,\n hi: HI,\n es: ES,\n ar: AR,\n ta: TA,\n};\n\nexport function answerStrings(locale: ExploreLocale): AnswerStrings {\n const chrome = CHROME[locale] ?? EN;\n const explore = exploreStrings(locale);\n return {\n ...chrome,\n answerTable: explore.answerTable,\n conceptIllustration: explore.conceptIllustration,\n opensInNewTab: explore.opensInNewTab,\n productVideo: explore.productVideo,\n productVideoTitle: explore.productVideoTitle,\n playVideo: explore.playVideo,\n closeVideo: explore.closeVideo,\n enterFullScreen: explore.enterFullScreen,\n exitFullScreen: explore.exitFullScreen,\n videoUnavailable: explore.videoUnavailable,\n };\n}\n\n/**\n * The BCP-47 tag a date is formatted with.\n *\n * Deliberately NOT the speech tags `explore-i18n` uses: `ar-SA` selects the Umm al-Qura\n * calendar in ICU, so an answer dated 2026-09-22 would publish as a Hijri date nobody\n * intended and no other locale on the page agrees with. Plain `ar` keeps the Gregorian\n * calendar.\n *\n * English is `en-GB` for the day-month order; the month is spelled out either way, so the\n * date is unambiguous to every reader rather than only to one hemisphere.\n */\nconst DATE_TAGS: Record<ExploreLocale, string> = {\n en: \"en-GB\",\n zh: \"zh-CN\",\n hi: \"hi-IN\",\n es: \"es-ES\",\n ar: \"ar\",\n ta: \"ta-IN\",\n};\n\n/**\n * `answeredAt` as a date a person reads.\n *\n * Two things are pinned rather than left to the environment, because these pages are\n * serialised from the post-hydration DOM: the machine that prerenders them and the browser\n * that hydrates them must produce the SAME string, or React replaces the node on hydration.\n *\n * - **An explicit locale tag**, never the ambient default — the prerender runs in headless\n * Chromium on a server whose locale is nobody's.\n * - **An explicit numbering system.** CLDR has changed the default digits for `ar` before;\n * two engines on different CLDR versions would then render the same date differently, and\n * the text React hydrated would not be the text it prerendered. All six locales already\n * default to Latin digits, so this pins today's output rather than changing it.\n * - **`timeZone: \"UTC\"`**, because `new Date(\"2026-09-22\")` is UTC midnight and formatting it\n * in a negative-offset zone would print the 21st. A published date that moves by a day\n * depending on who looks at it is worse than no date.\n *\n * Returns `\"\"` for an unparseable value so a bad row loses its date line rather than printing\n * \"Invalid Date\" on a marketing page.\n */\nexport function formatAnswerDate(value: string, locale: ExploreLocale): string {\n const at = new Date(value);\n if (Number.isNaN(at.getTime())) return \"\";\n try {\n return new Intl.DateTimeFormat(DATE_TAGS[locale] ?? \"en-GB\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n timeZone: \"UTC\",\n numberingSystem: \"latn\",\n }).format(at);\n } catch {\n // An engine without the locale data still shows the day, in the form it was stored.\n return value.slice(0, 10);\n }\n}\n","/**\n * Published answers — the shared data contract.\n *\n * ## Where the questions come from, and where they must NEVER come from\n *\n * Every product website publishes a set of question-and-answer pages built from a **curated\n * question list**, answered by the live explore API against the baked corpus. The question\n * list is written by us; the answer is the harness's own output for that question.\n *\n * They are **never** built from stored visitor conversations. `explore_messages` holds every\n * question a real visitor has typed into `/explore`, and publishing those as indexed pages\n * would be a privacy breach. That the rows carry no name does not save it: a question is not\n * anonymous content. \"Our farm outside Coimbatore has three staff and we are being billed X\"\n * identifies a business with nobody's name attached, and the person who typed it consented to\n * being answered, not to being published. That table is an analytics and answer-quality input,\n * which is what it was built for.\n *\n * So: nothing in this module, in `answers.tsx`, or in whatever generates a site's\n * `src/data/answers.ts` may read `ExploreMessage`, `ExploreConversation` or `ExploreFeedback`\n * rows. A {@link PublishedAnswer} has no conversation id, no message id, no visitor field and\n * no free text that came from one — by construction, not by a denylist, because a denylist\n * leaks the first column nobody thought of.\n *\n * ## The same care downstream\n *\n * A published answer must not contain anything that is not already public on our own\n * websites. The harness only answers from the corpus, which is built from published pages, and\n * every source here is a public URL — {@link isPublishedSourceUrl} is the page's own last\n * check before it renders one as a link.\n *\n * ## Shape\n *\n * Each site ships a generated `src/data/answers.ts` exporting `ANSWERS`, `ANSWER_TOPICS` and\n * `ANSWERS_PRODUCT_NAME`, typed against these interfaces — the same arrangement the concept\n * pages use (`dev/platform/context/publishing/concepts/01-architecture.md`). A field renamed here changes\n * every site's generated data module, so change the generator and this file together.\n */\n\nimport type { ComponentType, ReactNode } from \"react\";\n\n/**\n * One page an answer cited.\n *\n * Always a public URL on one of our own sites: the harness strips every link whose origin is\n * not in its catalog before the answer is ever stored, and this is what the page renders as a\n * real, followable link under the answer.\n */\nexport interface PublishedAnswerSource {\n /** Absolute `https://` URL of the page. */\n url: string;\n /** The page's own title, as published. */\n title: string;\n /** Product display name, when the page belongs to one product. */\n product?: string;\n}\n\n/** A curated question, and the answer our assistant produced for it. */\nexport interface PublishedAnswer {\n /** Kebab-case, unique per site; the `/answer/<slug>` route. */\n slug: string;\n /** 1-based position across the site's answers; drives listing order and previous/next. */\n order: number;\n /** The question, as we wrote it. The page's `<h1>`. */\n question: string;\n /**\n * The answer, as GitHub-flavoured markdown — exactly what the harness returned.\n *\n * It can contain GFM tables (a comparison or a plan list comes back as one; see\n * `dev/platform/context/publishing/explore/CONTRACT.md` §7), links and concept illustrations, so it is\n * rendered by the SAME renderer the chat uses and not by a second one.\n */\n answer: string;\n /** Grouping on the index page; matches a {@link PublishedAnswerTopic} name. */\n topic: string;\n /** One line under the question, on the card and in the hero. */\n summary: string;\n /** The `<meta name=\"description\">` for this answer's page. */\n metaDescription: string;\n /** Search keywords, also used by the index page's filter. */\n keywords: string[];\n /** The pages the answer cited, in the order it cited them. */\n sources: PublishedAnswerSource[];\n /** Slugs of related answers on the same site. */\n related: string[];\n /**\n * When the answer was produced, ISO-8601 (`2026-09-22`, or a full timestamp).\n *\n * Shown on the page and put in the structured data. An answer is a snapshot of what the\n * documentation said on a day; publishing it without saying which day would be the one\n * genuinely misleading thing about these pages.\n */\n answeredAt: string;\n}\n\n/**\n * Every field a {@link PublishedAnswer} has, written out once.\n *\n * Typed as a TOTAL map of the interface's keys: adding a field to {@link PublishedAnswer}\n * does not compile until someone also writes it down here, and removing one does not compile\n * until someone deletes it here. That is the point — the field that would break this feature's\n * one rule is a conversation id, a message id or a visitor's own words, and nobody adds one of\n * those to a published contract by accident twice.\n *\n * It lives in this module, not in a test, because `tsconfig.json` excludes `**\\/*.test.ts(x)`\n * from the program: a totality constraint written in a test file is never compiled and can\n * therefore never fail. Here it is compiled by `bun run type-check`, which the PR gate and both\n * publish workflows run, so the constraint is enforced on every path that ships this package.\n *\n * `answers.ssr.test.tsx` then checks the runtime half: that this list still matches the\n * interface field for field, and that no name in it could hold a visitor's conversation. Sites\n * generating `src/data/answers.ts` can use it the same way, to assert a generated row carries\n * these keys and no others.\n */\nexport const PUBLISHED_ANSWER_FIELDS: Record<keyof PublishedAnswer, true> = {\n slug: true,\n order: true,\n question: true,\n answer: true,\n topic: true,\n summary: true,\n metaDescription: true,\n keywords: true,\n sources: true,\n related: true,\n answeredAt: true,\n};\n\nexport interface PublishedAnswerTopic {\n name: string;\n description: string;\n}\n\n/** Props the pages pass to a site's link adapter. */\nexport interface AnswerLinkProps {\n href: string;\n className?: string;\n children: ReactNode;\n \"aria-label\"?: string;\n}\n\n/**\n * The link the pages render for every internal URL. Sites pass a small adapter around their\n * router's `Link`, so moving between answers stays a client-side navigation; without one the\n * pages fall back to a plain `<a href>`.\n */\nexport type AnswerLinkComponent = ComponentType<AnswerLinkProps>;\n\n/** The index route. */\nexport const ANSWERS_PATH = \"/answers\";\n\n/** Prefix of every answer detail route: `/answer/<slug>`. */\nexport const ANSWER_PATH_PREFIX = \"/answer\";\n\n/** Site-relative URL of one answer's page. */\nexport function answerPath(slug: string): string {\n // Slugs are generated as [a-z0-9-], so this is a no-op for real data; it only keeps a\n // malformed slug from escaping its path segment.\n return `${ANSWER_PATH_PREFIX}/${encodeURIComponent(slug)}`;\n}\n\n/**\n * Resolve a route parameter to its answer. Returns `undefined` for an unknown slug — the site\n * then redirects to `/answers` rather than rendering a soft 404.\n */\nexport function getAnswerBySlug(\n answers: readonly PublishedAnswer[],\n slug: string | null | undefined,\n): PublishedAnswer | undefined {\n if (!slug) return undefined;\n const wanted = slug.trim().toLowerCase();\n if (!wanted) return undefined;\n return answers.find((answer) => answer.slug === wanted);\n}\n\n/**\n * True when a source URL is safe to publish as a link.\n *\n * `https` only, and a real host: these pages are prerendered and crawled, so a `javascript:`\n * or `data:` URL that reached the generated data would ship to every visitor as a live link,\n * and a relative one would resolve against whichever answer page happened to render it. The\n * ORIGIN allow-list belongs in the generator, which knows the catalog; this is the page's own\n * last check, in the same spirit as the inline-image guard in the chat.\n */\nexport function isPublishedSourceUrl(url: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return false;\n }\n return (\n parsed.protocol === \"https:\" &&\n parsed.hostname !== \"\" &&\n !parsed.username &&\n !parsed.password\n );\n}\n\n/**\n * The host shown beside a source, `www.` removed.\n *\n * Same normalisation the chat's reference cards apply, so a source reads the same way whether\n * a visitor met it in a conversation or on one of these pages. Returns `\"\"` for anything\n * unparseable — the label is decorative, and {@link isPublishedSourceUrl} has already decided\n * whether the link renders at all.\n */\nexport function answerSourceHost(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n return \"\";\n }\n}\n","/**\n * Published answers — `/answers` and `/answer/:slug` on every product website.\n *\n * A published answer is a CURATED question plus the answer our own explore assistant produced\n * for it against the baked corpus. The data is generated per site (`src/data/answers.ts`) and\n * passed in; nothing here fetches, so both pages prerender completely and make no runtime\n * third-party requests — the same arrangement as the concept pages next door.\n *\n * ## The rule this feature is built around\n *\n * These pages are NEVER built from stored visitor conversations. `explore_messages` holds\n * what real people typed into the chat, and publishing that as indexed pages would be a\n * privacy breach whether or not the rows carry a name. Nothing in this module reads\n * `ExploreMessage`, `ExploreConversation` or `ExploreFeedback`, and {@link PublishedAnswer}\n * has nowhere to put one. The long version, and why \"it is anonymous\" is not a defence, is in\n * `answers-types.ts`.\n *\n * ## Written against three readers, in this order of strictness\n *\n * - **Visitors.** The page says what it is: a dated, generated answer, with the pages it drew\n * on linked under it and a sentence saying the page wins when the two disagree. Colours are\n * semantic tokens only, so every product's palette is correct in light and dark mode.\n * - **Search engines.** One `<h1>` per page (the question), a self-canonical URL, a\n * per-answer description, and JSON-LD: `FAQPage` with a single `Question` and its\n * `acceptedAnswer` on a detail page, `CollectionPage` + `ItemList` on the index, and a\n * `BreadcrumbList` on both. `FAQPage` rather than `QAPage`: `QAPage` describes a forum\n * where members post competing answers, which would misdescribe a page we wrote.\n * - **The reader who cannot see the page.** Real heading order, real lists, a labelled\n * breadcrumb, a focusable named region around a wide table, and links that say where they\n * go. The chrome is localised into six locales and the English question and answer are\n * marked as English inside it ({@link ENGLISH_TEXT}), so the Arabic page reads right to left\n * without announcing an English paragraph in Arabic. Nothing here is fixed, sticky or\n * measured in pixels, because these pages are serialised from the POST-HYDRATION DOM:\n * anything measured at render becomes static HTML for every later visitor, whatever their\n * screen.\n *\n * ## One renderer\n *\n * The answer body is markdown from the same harness the chat renders, GFM tables and all, so\n * it goes through {@link ExploreAnswerBody} — the very component `/explore` uses. A second\n * renderer would pass review the day it was written and drift the first time either half was\n * fixed. The only addition is {@link ANSWER_HEADING_SHIFT}, which demotes the answer's own\n * headings so they nest under the page's; see the note there.\n *\n * ## One thing the site wiring must get right\n *\n * The explore corpus is built from each site's prerendered `llms-full.txt`. If these pages go\n * into it, the assistant starts grounding new answers in its own published output, and a\n * mistake in one answer becomes a source for the next. **Exclude `/answers` and `/answer/*`\n * from the llms files** when wiring a site, even though they are in the sitemap: they are for\n * search engines and readers, not for the corpus.\n *\n * @example\n * ```tsx\n * import { AnswersPage, AnswerDetailPage, getAnswerBySlug } from '@burdenoff/website-sdk'\n * import { ANSWERS, ANSWER_TOPICS } from '@/data/answers'\n *\n * <AnswersPage productName=\"VibeControls\" siteUrl=\"https://vibecontrols.com\"\n * answers={ANSWERS} topics={ANSWER_TOPICS} linkComponent={SiteLink} />\n * ```\n */\n\"use client\";\n\nimport { useCallback, useId, useMemo, useState } from \"react\";\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport {\n ArrowLeft,\n ArrowRight,\n BookOpenText,\n ChevronRight,\n ExternalLink,\n Info,\n Search,\n Sparkles,\n} from \"lucide-react\";\n\nimport {\n type AnswerStrings,\n answerStrings,\n fill,\n formatAnswerDate,\n isRtlLocale,\n resolveExploreLocale,\n} from \"./answers-i18n\";\nimport {\n ANSWERS_PATH,\n answerPath,\n answerSourceHost,\n isPublishedSourceUrl,\n} from \"./answers-types\";\nimport {\n ExploreAnswerBody,\n ExploreAnswerStyles,\n answerSpeechText,\n inlineImageOrigins,\n productSlugsByOrigin,\n} from \"./explore-answer\";\nimport { ProseStyles } from \"../content/prose-styles\";\nimport { ECOSYSTEM_PRODUCTS } from \"../data/products\";\nimport { PageHead } from \"../seo/page-head\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n AnswerLinkComponent,\n AnswerLinkProps,\n PublishedAnswer,\n PublishedAnswerSource,\n PublishedAnswerTopic,\n} from \"./answers-types\";\nimport type { Components, ExtraProps } from \"react-markdown\";\n\n// ============================================================================\n// Props\n// ============================================================================\n\nexport interface AnswersPageProps {\n /** Product display name, e.g. `\"VibeControls\"`. */\n productName: string;\n /** Public origin of the site, e.g. `\"https://vibecontrols.com\"`. Used for absolute URLs. */\n siteUrl: string;\n answers: readonly PublishedAnswer[];\n /** Section order and descriptions. Answers in an unlisted topic still render, last. */\n topics?: readonly PublishedAnswerTopic[];\n /** Call to action rendered in the hero (e.g. the site's primary buttons). */\n cta?: ReactNode;\n /** Router adapter for internal links. Defaults to a plain `<a href>`. */\n linkComponent?: AnswerLinkComponent;\n /** Overrides the `<h1>`. Default: the localised `\"<productName> answers\"`. */\n title?: string;\n /** Overrides the meta description and the hero lead. */\n description?: string;\n /**\n * BCP-47 locale for the page chrome. Defaults to the document's own `lang`, then the\n * browser. The ANSWERS themselves are English whatever this says — see `answers-i18n.ts`.\n */\n locale?: string;\n /** Extra classes for the page root. */\n className?: string;\n}\n\nexport interface AnswerDetailPageProps {\n productName: string;\n siteUrl: string;\n /** The answer to render. The site resolves the slug and redirects when it is unknown. */\n answer: PublishedAnswer;\n /** Every answer on the site — for related questions and previous / next. */\n answers: readonly PublishedAnswer[];\n topics?: readonly PublishedAnswerTopic[];\n /**\n * Extra origins an illustration embedded in the answer may load from.\n *\n * The site's own origin and the origins of this answer's sources are always allowed, which\n * covers every image the harness can legitimately have embedded. Pass more only when an\n * answer cites a page whose images live elsewhere in the catalog, and pass a stable array.\n */\n imageOrigins?: readonly string[];\n /**\n * Where \"Ask your own question\" goes. `null` removes the link — pass that on a site with no\n * `/explore` route, rather than shipping a link to a page that does not exist.\n */\n askHref?: string | null;\n /** Call to action rendered as a band at the end of the page. */\n cta?: ReactNode;\n linkComponent?: AnswerLinkComponent;\n locale?: string;\n className?: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst META_DESCRIPTION_LIMIT = 160;\nconst TITLE_LIMIT = 100;\nconst RELATED_LIMIT = 4;\n\n/** The origin without trailing slashes, so paths can be appended as-is. */\nfunction normaliseSiteUrl(siteUrl: string): string {\n return siteUrl.trim().replace(/\\/+$/, \"\");\n}\n\n/** Absolute form of a site-relative path; absolute URLs pass through. */\nfunction absoluteUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${base}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\n\nfunction sortByOrder(answers: readonly PublishedAnswer[]): PublishedAnswer[] {\n return [...answers].sort(\n (a, b) => a.order - b.order || a.slug.localeCompare(b.slug),\n );\n}\n\n/** Cut at a word boundary, so a title or description never ends mid-word. */\nfunction clampText(text: string, limit: number): string {\n if (text.length <= limit) return text;\n const cut = text.slice(0, limit - 1);\n const lastSpace = cut.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\\s,;:—–-]+$/, \"\")}…`;\n}\n\nfunction questionCount(T: AnswerStrings, count: number): string {\n return count === 1\n ? T.questionCountOne\n : fill(T.questionCountMany, { count: String(count) });\n}\n\nfunction sourceCount(T: AnswerStrings, count: number): string {\n return count === 1\n ? T.sourceCountOne\n : fill(T.sourceCountMany, { count: String(count) });\n}\n\nfunction slugifyAnchor(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\n/**\n * The sources safe to render as links, in the order the answer cited them, once each.\n *\n * Two filters, each for its own reason:\n *\n * - A source that fails {@link isPublishedSourceUrl} is DROPPED rather than rendered as plain\n * text: the section says \"the pages this answer was drawn from\", and a line there that\n * cannot be followed reads as a page we are hiding.\n * - A URL cited TWICE is listed once. An answer that draws on `/pricing` for two separate\n * claims legitimately cites it twice, and nothing upstream promises otherwise — the harness\n * strips off-catalog links but does not deduplicate what is left. Rendered as-is that is the\n * same card printed twice, \"4 sources\" over three pages, the same page twice in the JSON-LD\n * `citation`, and two React children under one key.\n *\n * The FIRST occurrence wins, so the order is the order the answer cited them in and the\n * retained title is the one the answer introduced the page with.\n */\nfunction publishableSources(\n sources: readonly PublishedAnswerSource[],\n): PublishedAnswerSource[] {\n const seen = new Set<string>();\n const kept: PublishedAnswerSource[] = [];\n for (const source of sources) {\n if (!isPublishedSourceUrl(source.url) || seen.has(source.url)) continue;\n seen.add(source.url);\n kept.push(source);\n }\n return kept;\n}\n\ninterface TopicGroup {\n name: string;\n description: string;\n /** DOM id of the section heading — unique even when two names slugify alike. */\n anchor: string;\n answers: PublishedAnswer[];\n}\n\n/**\n * Answers grouped in the order `topics` lists them. Empty topics are dropped, and an answer\n * whose topic is missing from the list still gets a section (after the listed ones) rather\n * than silently disappearing from the page.\n */\nfunction groupByTopic(\n ordered: readonly PublishedAnswer[],\n topics: readonly PublishedAnswerTopic[] | undefined,\n): TopicGroup[] {\n const byName = new Map<string, PublishedAnswer[]>();\n for (const answer of ordered) {\n const list = byName.get(answer.topic);\n if (list) list.push(answer);\n else byName.set(answer.topic, [answer]);\n }\n\n const described: Array<Omit<TopicGroup, \"anchor\">> = [];\n for (const topic of topics ?? []) {\n const list = byName.get(topic.name);\n if (!list) continue;\n described.push({\n name: topic.name,\n description: topic.description,\n answers: list,\n });\n byName.delete(topic.name);\n }\n for (const [name, list] of byName) {\n described.push({ name, description: \"\", answers: list });\n }\n\n const used = new Set<string>();\n return described.map((group) => {\n const base = `answers-${slugifyAnchor(group.name) || \"topic\"}`;\n let anchor = base;\n for (let n = 2; used.has(anchor); n += 1) anchor = `${base}-${n}`;\n used.add(anchor);\n return { ...group, anchor };\n });\n}\n\nfunction searchTokens(query: string): string[] {\n return query.toLowerCase().split(/\\s+/).filter(Boolean);\n}\n\nfunction matchesSearch(\n answer: PublishedAnswer,\n tokens: readonly string[],\n): boolean {\n if (tokens.length === 0) return true;\n const haystack = [\n answer.question,\n answer.summary,\n answer.topic,\n ...answer.keywords,\n ]\n .join(\" \")\n .toLowerCase();\n return tokens.every((token) => haystack.includes(token));\n}\n\n/**\n * Key for a list rendered from the copy. The text alone collides when a list repeats an\n * entry, so the position qualifies it; these lists never reorder, so that is stable.\n */\nfunction copyKey(index: number, text: string): string {\n return `${index}-${text}`;\n}\n\n// ============================================================================\n// The answer body's headings\n// ============================================================================\n\n/**\n * A heading inside an answer, rendered one or two levels lower than it was written.\n *\n * `node` is react-markdown's hast node, not a DOM attribute, so it is dropped rather than\n * spread onto the element — the same thing `MarkdownLink` does.\n */\nfunction demoteHeading(Tag: \"h3\" | \"h4\" | \"h5\" | \"h6\") {\n function DemotedHeading({\n node: _node,\n ...props\n }: ComponentProps<\"h2\"> & ExtraProps) {\n return <Tag {...props} />;\n }\n DemotedHeading.displayName = `DemotedHeading(${Tag})`;\n return DemotedHeading;\n}\n\n/**\n * Heading overrides for a PUBLISHED answer, merged over the shared answer components.\n *\n * In the chat an answer is one message in a stream and its `#` headings bother nobody. On a\n * crawled page the outline is the page's structure: the question is the `<h1>` and \"Answer\"\n * is an `<h2>`, so an answer that opens with `## Plans` would put a second `<h2>` inside a\n * section and an answer that opens with `#` would put a SECOND `<h1>` on the page. Both are\n * things a crawler reads as the page changing subject.\n *\n * So every heading the model wrote is pushed below the page's own: `#` and `##` become `<h3>`\n * (the first real level inside the answer section), and the rest follow, floored at `<h6>`.\n * The words are untouched — only the level moves.\n *\n * Module-level on purpose: react-markdown uses an override as the element TYPE, so rebuilding\n * this object during a render would remount everything under it.\n */\nexport const ANSWER_HEADING_SHIFT: Components = {\n h1: demoteHeading(\"h3\"),\n h2: demoteHeading(\"h3\"),\n h3: demoteHeading(\"h4\"),\n h4: demoteHeading(\"h5\"),\n h5: demoteHeading(\"h6\"),\n h6: demoteHeading(\"h6\"),\n};\n\n// ============================================================================\n// Shared pieces\n// ============================================================================\n\n/**\n * Marks an element whose text is the QUESTION or the ANSWER, and therefore English on every\n * locale's page.\n *\n * The chrome is translated into all six locales; the content is not, because the harness\n * answered a curated English question and nothing here pretends otherwise. Left unmarked\n * inside an `ar` page, that English prose is announced with Arabic phonemes and indexed as\n * Arabic — so the two things the brief names, the question and the answer, say what they are.\n *\n * Deliberately NOT applied to topic names, keywords or a source's title. Those are labels of a\n * word or two, where the cost of a mispronunciation is nothing like three paragraphs read in\n * the wrong language, and tagging every data-derived string would spread this across the file\n * until nobody could tell which ones mattered.\n */\nconst ENGLISH_TEXT = { lang: \"en\" } as const;\n\n/**\n * Every product site, as the answer body reads a catalog — the same list `/explore` falls back\n * on before its server catalog lands. A published page has no catalog of its own, and a\n * product video needs one twice:\n *\n * - **`data-product`** is the product's slug in the chat, and an e2e selector written for one\n * surface must match the other. Without a map the card would name the file's host, which is\n * not the slug for HealthyBowl (gethealthybowl.com) or Workspaces (burdenoff.com).\n * - **Where the video may come from.** The page's image list is this site plus the answer's\n * sources, and a video is never a source (§7) — so on a hub page, a question about another\n * product would lose its video unless that product's pages happened to be cited.\n */\nconst ECOSYSTEM_SITES = ECOSYSTEM_PRODUCTS.map((product) => ({\n slug: product.slug,\n website: product.websiteUrl,\n}));\nconst ECOSYSTEM_PRODUCT_SLUGS = productSlugsByOrigin(ECOSYSTEM_SITES);\nconst ECOSYSTEM_ORIGINS = inlineImageOrigins(ECOSYSTEM_SITES);\n\nfunction DefaultAnswerLink({\n href,\n className,\n children,\n \"aria-label\": ariaLabel,\n}: AnswerLinkProps) {\n return (\n <a href={href} className={className} aria-label={ariaLabel}>\n {children}\n </a>\n );\n}\n\n/**\n * One question on the index: the question itself, its one-line summary, and how many pages\n * back the answer. The whole card is the link.\n */\nfunction AnswerCard({\n answer,\n strings: T,\n Link,\n}: {\n answer: PublishedAnswer;\n strings: AnswerStrings;\n Link: AnswerLinkComponent;\n}) {\n const sources = publishableSources(answer.sources).length;\n return (\n <Link\n href={answerPath(answer.slug)}\n className=\"group flex h-full flex-col gap-2 rounded-2xl border border-border bg-card p-5 text-card-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transform-none motion-reduce:transition-none\"\n >\n <h3\n {...ENGLISH_TEXT}\n className=\"text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary\"\n >\n {answer.question}\n </h3>\n <p\n {...ENGLISH_TEXT}\n className=\"line-clamp-3 text-sm leading-relaxed text-muted-foreground\"\n >\n {answer.summary}\n </p>\n {sources > 0 ? (\n <span className=\"mt-auto inline-flex items-center gap-1.5 pt-2 text-xs font-medium text-muted-foreground\">\n <BookOpenText aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {sourceCount(T, sources)}\n </span>\n ) : null}\n </Link>\n );\n}\n\nfunction FilterChip({\n label,\n count,\n active,\n topic,\n onSelect,\n}: {\n label: string;\n count: number;\n active: boolean;\n topic: string;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-topic={topic}\n onClick={onSelect}\n className={cn(\n \"inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-card text-foreground hover:border-primary/40 hover:bg-muted\",\n )}\n >\n <span>{label}</span>\n <span\n className={cn(\n \"rounded-full px-1.5 text-xs tabular-nums\",\n active\n ? \"bg-primary-foreground text-primary\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {count}\n </span>\n </button>\n );\n}\n\n// ============================================================================\n// Index page\n// ============================================================================\n\n/**\n * `/answers` — every published answer on the site, grouped by topic, with a client-side\n * search and topic filter. Filters start at \"All\", so the prerendered page lists everything.\n */\nexport function AnswersPage({\n productName,\n siteUrl,\n answers,\n topics,\n cta,\n linkComponent,\n title,\n description,\n locale,\n className,\n}: AnswersPageProps) {\n const Link = linkComponent ?? DefaultAnswerLink;\n const base = normaliseSiteUrl(siteUrl);\n const searchId = useId();\n const activeLocale = useMemo(() => resolveExploreLocale(locale), [locale]);\n const T = useMemo(() => answerStrings(activeLocale), [activeLocale]);\n const rtl = isRtlLocale(activeLocale);\n\n const ordered = useMemo(() => sortByOrder(answers), [answers]);\n const groups = useMemo(\n () => groupByTopic(ordered, topics),\n [ordered, topics],\n );\n\n const [query, setQuery] = useState(\"\");\n const [activeTopic, setActiveTopic] = useState<string | null>(null);\n\n const hasAnswers = ordered.length > 0;\n const tokens = useMemo(() => searchTokens(query), [query]);\n const searched = useMemo(\n () => ordered.filter((answer) => matchesSearch(answer, tokens)),\n [ordered, tokens],\n );\n // Chip counts follow the search, so each chip says how many results it would show.\n const countsByTopic = useMemo(() => {\n const counts = new Map<string, number>();\n for (const answer of searched) {\n counts.set(answer.topic, (counts.get(answer.topic) ?? 0) + 1);\n }\n return counts;\n }, [searched]);\n const visibleGroups = useMemo(() => {\n const visible = new Set(\n searched.filter(\n (answer) => activeTopic === null || answer.topic === activeTopic,\n ),\n );\n return groups\n .map((group) => ({\n ...group,\n answers: group.answers.filter((answer) => visible.has(answer)),\n }))\n .filter((group) => group.answers.length > 0);\n }, [groups, searched, activeTopic]);\n const visibleTotal = visibleGroups.reduce(\n (sum, group) => sum + group.answers.length,\n 0,\n );\n const filtering = tokens.length > 0 || activeTopic !== null;\n\n const clearFilters = useCallback(() => {\n setQuery(\"\");\n setActiveTopic(null);\n }, []);\n\n const heading = title ?? fill(T.indexHeading, { product: productName });\n const metaDescription =\n description ??\n clampText(\n fill(T.seoIndexDescription, { product: productName }),\n META_DESCRIPTION_LIMIT,\n );\n const lead = description ?? fill(T.indexLead, { product: productName });\n const canonical = `${base}${ANSWERS_PATH}`;\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"CollectionPage\",\n name: heading,\n description: metaDescription,\n url: canonical,\n isPartOf: { \"@type\": \"WebSite\", name: productName, url: `${base}/` },\n mainEntity: {\n \"@type\": \"ItemList\",\n numberOfItems: ordered.length,\n itemListElement: ordered.map((answer, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n url: absoluteUrl(base, answerPath(answer.slug)),\n name: answer.question,\n })),\n },\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n {\n \"@type\": \"ListItem\",\n position: 1,\n name: T.breadcrumbHome,\n item: `${base}/`,\n },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: T.answers,\n item: canonical,\n },\n ],\n },\n ],\n [base, canonical, heading, metaDescription, ordered, productName, T],\n );\n\n return (\n <div\n data-answers=\"landing\"\n data-locale={activeLocale}\n /* Arabic is the one RTL locale in the product set. Scoped to this subtree rather than\n set on <html>, exactly as the chat does it, because the SDK is a guest on someone\n else's page. */\n dir={rtl ? \"rtl\" : undefined}\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title={T.seoIndexTitle}\n description={metaDescription}\n productName={productName}\n keywords={[\n fill(T.indexHeading, { product: productName }),\n ...groups.map((group) => group.name),\n ].join(\", \")}\n url={canonical}\n structuredData={structuredData}\n />\n\n <section className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-6xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8\">\n <p className=\"text-xs font-semibold uppercase tracking-[0.2em] text-primary\">\n {T.answers}\n </p>\n <h1 className=\"mt-3 max-w-3xl text-4xl font-bold tracking-tight text-foreground sm:text-5xl\">\n {heading}\n </h1>\n <p className=\"mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground\">\n {lead}\n </p>\n {hasAnswers ? (\n <p className=\"mt-6 text-sm text-muted-foreground\">\n <strong className=\"text-lg font-semibold text-foreground\">\n {ordered.length}\n </strong>{\" \"}\n {questionCount(T, ordered.length)}\n </p>\n ) : null}\n {cta ? <div className=\"mt-8 flex flex-wrap gap-3\">{cta}</div> : null}\n </div>\n </section>\n\n <div className=\"mx-auto max-w-6xl px-4 pb-20 sm:px-6 lg:px-8\">\n {hasAnswers ? (\n <>\n <div\n role=\"search\"\n data-answers=\"filter\"\n className=\"flex flex-col gap-4 py-8\"\n >\n <div className=\"relative w-full max-w-md\">\n <Search\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\"\n />\n <label htmlFor={searchId} className=\"sr-only\">\n {T.searchLabel}\n </label>\n <input\n id={searchId}\n type=\"search\"\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder={T.searchPlaceholder}\n autoComplete=\"off\"\n className=\"h-10 w-full rounded-lg border border-border bg-background pl-9 pr-3 text-sm text-foreground shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </div>\n <div\n role=\"group\"\n aria-label={T.filterByTopic}\n className=\"flex flex-wrap gap-2\"\n >\n <FilterChip\n label={T.allTopics}\n topic=\"all\"\n count={searched.length}\n active={activeTopic === null}\n onSelect={() => setActiveTopic(null)}\n />\n {groups.map((group) => (\n <FilterChip\n key={group.anchor}\n label={group.name}\n topic={group.name}\n count={countsByTopic.get(group.name) ?? 0}\n active={activeTopic === group.name}\n onSelect={() =>\n setActiveTopic((current) =>\n current === group.name ? null : group.name,\n )\n }\n />\n ))}\n </div>\n {/* Visible only while a filter is on; announced whenever the result set changes. */}\n <p\n aria-live=\"polite\"\n className={\n filtering ? \"text-sm text-muted-foreground\" : \"sr-only\"\n }\n >\n {fill(T.showingCount, {\n shown: String(visibleTotal),\n total: String(ordered.length),\n })}\n </p>\n </div>\n\n {visibleTotal === 0 ? (\n <div\n data-answers=\"empty\"\n className=\"rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <Search\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n {T.noMatchesTitle}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {T.noMatchesBody}\n </p>\n <button\n type=\"button\"\n onClick={clearFilters}\n className=\"mt-6 inline-flex items-center rounded-full border border-border bg-card px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {T.clearFilters}\n </button>\n </div>\n ) : (\n <div className=\"space-y-14\">\n {visibleGroups.map((group) => (\n <section key={group.anchor} aria-labelledby={group.anchor}>\n <div className=\"max-w-3xl\">\n <h2\n id={group.anchor}\n className=\"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\"\n >\n {group.name}\n </h2>\n {group.description ? (\n <p className=\"mt-2 leading-relaxed text-muted-foreground\">\n {group.description}\n </p>\n ) : null}\n </div>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3\"\n >\n {group.answers.map((answer) => (\n <li\n key={answer.slug}\n data-answers=\"card\"\n data-slug={answer.slug}\n >\n <AnswerCard answer={answer} strings={T} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ))}\n </div>\n )}\n </>\n ) : (\n // Nothing published yet: no filter bar with an \"All 0\" chip, and no empty state\n // that blames filters the visitor never set.\n <div\n data-answers=\"none\"\n className=\"mt-10 rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center\"\n >\n <Sparkles\n aria-hidden=\"true\"\n className=\"mx-auto h-8 w-8 text-muted-foreground\"\n />\n <h2 className=\"mt-4 text-lg font-semibold text-foreground\">\n {T.noneYetTitle}\n </h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {fill(T.noneYetBody, { product: productName })}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Detail page\n// ============================================================================\n\nconst SECTION_HEADING =\n \"scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground\";\nconst CHIP =\n \"inline-flex items-center rounded-full border border-border bg-muted/50 px-3 py-1 text-sm text-foreground\";\n\n/**\n * The note that says what this page is: generated, dated, and second to the pages it links.\n *\n * A callout with `role=\"note\"` rather than a line of body copy, because on a marketing page a\n * disclosure set in the same type as the sales copy is a disclosure nobody reads. The wording\n * itself, and what was deliberately not claimed, is documented on `aboutBody` in\n * `answers-i18n.ts`.\n */\nfunction ProvenanceNote({\n strings: T,\n date,\n className,\n}: {\n strings: AnswerStrings;\n date: string;\n className?: string;\n}) {\n return (\n <div\n role=\"note\"\n aria-label={T.aboutTitle}\n data-answers=\"provenance\"\n className={cn(\n \"flex items-start gap-3 rounded-xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm leading-relaxed text-foreground\",\n className,\n )}\n >\n <Info\n aria-hidden=\"true\"\n className=\"mt-0.5 h-4 w-4 shrink-0 text-primary\"\n />\n <p>\n <span className=\"font-semibold\">{T.aboutTitle}</span>\n {\" — \"}\n {fill(T.aboutBody, { date })}\n </p>\n </div>\n );\n}\n\n/** One cited page, as a real link. */\nfunction SourceLink({\n source,\n strings: T,\n}: {\n source: PublishedAnswerSource;\n strings: AnswerStrings;\n}) {\n const host = answerSourceHost(source.url);\n return (\n <a\n data-answers=\"source\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"group flex h-full flex-col gap-1.5 rounded-xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <span className=\"text-sm font-semibold leading-snug transition-colors group-hover:text-primary\">\n {source.title || host || source.url}\n </span>\n <span className=\"mt-auto flex items-center gap-2 pt-1 text-xs text-muted-foreground\">\n {source.product ? (\n <span className=\"rounded-full bg-secondary px-2 py-0.5 font-medium text-secondary-foreground\">\n {source.product}\n </span>\n ) : null}\n <span className=\"inline-flex min-w-0 items-center gap-1\">\n <ExternalLink aria-hidden=\"true\" className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">{host}</span>\n </span>\n </span>\n <span className=\"sr-only\">({T.opensInNewTab})</span>\n </a>\n );\n}\n\n/**\n * `/answer/:slug` — one question, the answer, and the pages it came from.\n */\nexport function AnswerDetailPage(props: AnswerDetailPageProps) {\n // Keyed by slug: a router reuses this component when the visitor moves from one answer to\n // another, and that is a new page — not an update of the old one.\n return <AnswerDetail key={props.answer.slug} {...props} />;\n}\n\nfunction AnswerDetail({\n productName,\n siteUrl,\n answer,\n answers,\n topics,\n imageOrigins,\n askHref = \"/explore\",\n cta,\n linkComponent,\n locale,\n className,\n}: AnswerDetailPageProps) {\n const Link = linkComponent ?? DefaultAnswerLink;\n const base = normaliseSiteUrl(siteUrl);\n const headingId = useId();\n const activeLocale = useMemo(() => resolveExploreLocale(locale), [locale]);\n const T = useMemo(() => answerStrings(activeLocale), [activeLocale]);\n const rtl = isRtlLocale(activeLocale);\n const dateLabel = useMemo(\n () => formatAnswerDate(answer.answeredAt, activeLocale),\n [answer.answeredAt, activeLocale],\n );\n\n const ordered = useMemo(() => sortByOrder(answers), [answers]);\n const position = ordered.findIndex((item) => item.slug === answer.slug);\n const previous = position > 0 ? ordered[position - 1] : undefined;\n const next =\n position >= 0 && position < ordered.length - 1\n ? ordered[position + 1]\n : undefined;\n\n // Curated related answers first; the rest of the topic when none resolve. A slug listed\n // twice still shows one card.\n const related = useMemo(() => {\n const bySlug = new Map(ordered.map((item) => [item.slug, item]));\n const curated = [...new Set(answer.related)]\n .map((slug) => bySlug.get(slug))\n .filter(\n (item): item is PublishedAnswer =>\n item !== undefined && item.slug !== answer.slug,\n );\n const list =\n curated.length > 0\n ? curated\n : ordered.filter(\n (item) => item.topic === answer.topic && item.slug !== answer.slug,\n );\n return list.slice(0, RELATED_LIMIT);\n }, [answer, ordered]);\n const relatedIsCurated = answer.related.some((slug) =>\n related.some((item) => item.slug === slug),\n );\n const topicDescription = topics?.find(\n (topic) => topic.name === answer.topic,\n )?.description;\n\n const sources = useMemo(\n () => publishableSources(answer.sources),\n [answer.sources],\n );\n\n /**\n * Origins an illustration inside the answer may load from: this site, every site the answer\n * cited, and anything the caller adds. The harness has already removed every image it did\n * not put there; this is the browser's own second check, exactly as in the chat.\n */\n const answerImageOrigins = useMemo(\n () =>\n inlineImageOrigins([\n { website: base },\n ...sources.map((source) => ({ website: source.url })),\n ...(imageOrigins ?? []).map((origin) => ({ website: origin })),\n ]),\n [base, sources, imageOrigins],\n );\n /** Those, and every product site — see `ECOSYSTEM_SITES`. */\n const answerVideoOrigins = useMemo(\n () => new Set([...answerImageOrigins, ...ECOSYSTEM_ORIGINS]),\n [answerImageOrigins],\n );\n\n const canonical = absoluteUrl(base, answerPath(answer.slug));\n\n /**\n * The answer as plain text for the structured data.\n *\n * The SPEECH stripper, not the clipboard one, and the difference matters in exactly the\n * place this feature cares about. `acceptedAnswer.text` is consumed by machines that read\n * it out; the clipboard form keeps a table as pipes (right for a paste into a README,\n * unreadable said aloud) and spells every URL out mid-sentence. The speech form reads each\n * row with its cells under their own column headings and a link as its label — and the URLs\n * are not lost, because `citation` below carries them as data.\n */\n const answerText = useMemo(\n () => answerSpeechText(answer.answer),\n [answer.answer],\n );\n\n const structuredData = useMemo(\n () => [\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"FAQPage\",\n name: answer.question,\n description: answer.metaDescription,\n url: canonical,\n inLanguage: \"en\",\n isPartOf: { \"@type\": \"WebSite\", name: productName, url: `${base}/` },\n mainEntity: {\n \"@type\": \"Question\",\n name: answer.question,\n text: answer.question,\n answerCount: 1,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: answerText,\n url: canonical,\n dateCreated: answer.answeredAt,\n // The organisation published it. Naming a person would be the one outright\n // false claim these pages could make.\n author: { \"@type\": \"Organization\", name: productName },\n ...(sources.length > 0\n ? {\n citation: sources.map((source) => ({\n \"@type\": \"WebPage\",\n name: source.title,\n url: source.url,\n })),\n }\n : {}),\n },\n },\n },\n {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: [\n {\n \"@type\": \"ListItem\",\n position: 1,\n name: T.breadcrumbHome,\n item: `${base}/`,\n },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: T.answers,\n item: `${base}${ANSWERS_PATH}`,\n },\n {\n \"@type\": \"ListItem\",\n position: 3,\n name: answer.question,\n item: canonical,\n },\n ],\n },\n ],\n [answer, answerText, base, canonical, productName, sources, T],\n );\n\n return (\n <article\n data-answers=\"detail\"\n data-slug={answer.slug}\n data-locale={activeLocale}\n aria-labelledby={headingId}\n /* Arabic is the one RTL locale in the product set. Scoped to this subtree rather than\n set on <html>, exactly as the chat does it, because the SDK is a guest on someone\n else's page. */\n dir={rtl ? \"rtl\" : undefined}\n className={cn(\"bg-background text-foreground\", className)}\n >\n <PageHead\n title={clampText(answer.question, TITLE_LIMIT)}\n description={answer.metaDescription}\n productName={productName}\n keywords={answer.keywords.join(\", \")}\n url={canonical}\n structuredData={structuredData}\n />\n {/* The answer body's own stylesheets. Both are scoped and idempotent, and without them\n a wide table has nothing holding it inside the page. */}\n <ProseStyles />\n <ExploreAnswerStyles />\n\n <header className=\"border-b border-border bg-muted/30\">\n <div className=\"mx-auto max-w-4xl px-4 pb-10 pt-8 sm:px-6 lg:px-8\">\n <nav aria-label=\"Breadcrumb\">\n <ol className=\"flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground\">\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href=\"/\"\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {T.breadcrumbHome}\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li className=\"inline-flex items-center gap-1.5\">\n <Link\n href={ANSWERS_PATH}\n className=\"rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {T.answers}\n </Link>\n <ChevronRight aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n </li>\n <li\n aria-current=\"page\"\n {...ENGLISH_TEXT}\n className=\"min-w-0 truncate text-foreground\"\n >\n {answer.question}\n </li>\n </ol>\n </nav>\n\n <div className=\"mt-6 flex flex-wrap items-center gap-2\">\n <span\n data-answers=\"topic\"\n title={topicDescription}\n className=\"inline-flex items-center rounded-full border border-primary/30 bg-primary/10 px-3 py-1 text-xs font-semibold text-primary\"\n >\n {answer.topic}\n </span>\n {dateLabel ? (\n <span className=\"inline-flex items-center rounded-full border border-border bg-background px-3 py-1 text-xs font-medium text-muted-foreground\">\n {/* A machine-readable date beside the words, so \"when\" survives being\n scraped, quoted or read by an assistant. */}\n <time dateTime={answer.answeredAt}>\n {fill(T.answeredOn, { date: dateLabel })}\n </time>\n </span>\n ) : null}\n </div>\n <h1\n id={headingId}\n {...ENGLISH_TEXT}\n className=\"mt-4 text-3xl font-bold tracking-tight text-foreground sm:text-4xl\"\n >\n {answer.question}\n </h1>\n {answer.summary ? (\n <p\n {...ENGLISH_TEXT}\n className=\"mt-4 text-lg leading-relaxed text-muted-foreground\"\n >\n {answer.summary}\n </p>\n ) : null}\n <ProvenanceNote strings={T} date={dateLabel} className=\"mt-6\" />\n </div>\n </header>\n\n <div className=\"mx-auto max-w-4xl px-4 py-12 sm:px-6 lg:px-8\">\n <section aria-labelledby={`${headingId}-answer`}>\n <h2 id={`${headingId}-answer`} className={SECTION_HEADING}>\n {T.answerHeading}\n </h2>\n {/* `dir=\"ltr\"` as well as `lang`, and only here. The answer is English prose with\n lists, fenced code and GFM tables in it; inherited RTL would right-align every\n line of it and start each table at the wrong edge, which the table's own\n `text-align: start` would faithfully follow. A question, by contrast, is one line\n that can sit with the rest of an RTL page's text. */}\n <div data-answers=\"body\" {...ENGLISH_TEXT} dir=\"ltr\">\n {/* The chat's renderer, unchanged apart from the heading levels: same GFM tables,\n same contained scroller, same card-per-row layout under 30rem. */}\n <ExploreAnswerBody\n strings={T}\n imageOrigins={answerImageOrigins}\n videoOrigins={answerVideoOrigins}\n productSlugs={ECOSYSTEM_PRODUCT_SLUGS}\n components={ANSWER_HEADING_SHIFT}\n className=\"mt-4\"\n >\n {answer.answer}\n </ExploreAnswerBody>\n </div>\n </section>\n\n {sources.length > 0 ? (\n <section\n aria-labelledby={`${headingId}-sources`}\n data-answers=\"sources\"\n className=\"mt-14\"\n >\n <h2 id={`${headingId}-sources`} className={SECTION_HEADING}>\n {T.sourcesHeading}\n </h2>\n <p className=\"mt-2 text-muted-foreground\">{T.sourcesLead}</p>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2\"\n >\n {sources.map((source) => (\n <li key={source.url}>\n <SourceLink source={source} strings={T} />\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {answer.keywords.length > 0 ? (\n <section aria-labelledby={`${headingId}-topics`} className=\"mt-14\">\n <h2 id={`${headingId}-topics`} className={SECTION_HEADING}>\n {T.topicsHeading}\n </h2>\n <ul role=\"list\" className=\"mt-4 flex flex-wrap gap-2\">\n {answer.keywords.map((keyword, index) => (\n <li key={copyKey(index, keyword)} className={CHIP}>\n {keyword}\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {related.length > 0 ? (\n <section\n aria-labelledby={`${headingId}-related`}\n data-answers=\"related\"\n className=\"mt-14\"\n >\n <h2 id={`${headingId}-related`} className={SECTION_HEADING}>\n {relatedIsCurated\n ? T.relatedHeading\n : fill(T.moreInTopic, { topic: answer.topic })}\n </h2>\n <ul\n role=\"list\"\n className=\"mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2\"\n >\n {related.map((item) => (\n <li key={item.slug} data-answers=\"card\" data-slug={item.slug}>\n <AnswerCard answer={item} strings={T} Link={Link} />\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {previous || next ? (\n <nav\n aria-label={`${T.previousQuestion} / ${T.nextQuestion}`}\n data-answers=\"pager\"\n /* `minmax(0,1fr)`, not the implicit `auto` track. A grid track's automatic\n minimum is the item's MIN-CONTENT size, and `min-w-0` on the inner span\n caps the flex item's shrink floor without reducing that contribution — so\n a long question title blew the single-column track out to ~803px inside a\n 288px nav and scrolled the whole document sideways on a phone. Measured at\n 320px before this: documentElement.scrollWidth 596-902 across the fleet,\n each matching the anchor's width to within the page gutter. */\n className=\"mt-14 grid grid-cols-[minmax(0,1fr)] gap-4 sm:grid-cols-2\"\n >\n {previous ? (\n <Link\n href={answerPath(previous.slug)}\n className=\"group flex min-w-0 items-center gap-3 rounded-2xl border border-border bg-card p-4 text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {T.previousQuestion}\n </span>\n <span\n {...ENGLISH_TEXT}\n className=\"block truncate font-semibold\"\n >\n {previous.question}\n </span>\n </span>\n </Link>\n ) : (\n <span className=\"hidden sm:block\" />\n )}\n {next ? (\n <Link\n href={answerPath(next.slug)}\n className=\"group flex min-w-0 items-center justify-end gap-3 rounded-2xl border border-border bg-card p-4 text-right text-card-foreground transition-colors hover:border-primary/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <span className=\"min-w-0\">\n <span className=\"block text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {T.nextQuestion}\n </span>\n <span\n {...ENGLISH_TEXT}\n className=\"block truncate font-semibold\"\n >\n {next.question}\n </span>\n </span>\n <ArrowRight\n aria-hidden=\"true\"\n className=\"h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary\"\n />\n </Link>\n ) : null}\n </nav>\n ) : null}\n\n <div className=\"mt-10 flex flex-wrap items-center gap-x-6 gap-y-3\">\n <Link\n href={ANSWERS_PATH}\n className=\"inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowLeft aria-hidden=\"true\" className=\"h-4 w-4\" />\n {fill(T.allAnswers, { product: productName })}\n </Link>\n {askHref ? (\n <Link\n href={askHref}\n className=\"inline-flex items-center gap-2 rounded text-sm font-medium text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Sparkles aria-hidden=\"true\" className=\"h-4 w-4\" />\n {T.askYourOwn}\n </Link>\n ) : null}\n </div>\n </div>\n\n {cta ? (\n <section\n data-answers=\"cta\"\n className=\"border-t border-border bg-muted/30\"\n >\n <div className=\"mx-auto flex max-w-4xl flex-wrap items-center gap-4 px-4 py-12 sm:px-6 lg:px-8\">\n {cta}\n </div>\n </section>\n ) : null}\n </article>\n );\n}\n","/**\n * ExploreAvatarLive — the Avatar tab's live avatar (BOFF-9797), opt-in: the part of it that lives in the package root.\n *\n * `ExplorePanel` renders this only when its host passes `avatar.live`. Without it the Avatar tab is exactly what it\n * was: the approved still, \"Live avatar coming soon\" and \"Continue in Chat\".\n *\n * This is deliberately small. The live avatar itself (the view, its state machine, its requests, its words in six\n * locales and the bot check, in `explore-avatar-live-view.tsx`) weighs about 12 KB gzipped, a tenth of what a site that\n * uses the panel already carries, and a site that does not use it must not pay for it. So that is a chunk of its own,\n * which this component loads the first time the Avatar view is opened with the live avatar switched on, and not\n * before: not on page load, not when the panel opens, not for a site that never passes `avatar.live`. What stays here\n * is what has to be known without it:\n *\n * - whether the live avatar can run on this page at all (a complete config, a gateway, the panel's conversation, a\n * locale with reviewed words). When it cannot, the Avatar tab is shown as it was and the chunk is never loaded;\n * - what the Avatar tab shows until the chunk is there: the picture, as the view's own first step, so the server's\n * markup, a prerendered page and the first client render are the same as they have always been;\n * - the page's React contexts. The package builds each entry on its own, so the chunk cannot read the page's\n * `WebSDKProvider` or the panel's conversation itself (it would get a second, empty copy of each). It is handed\n * what it reads as props instead.\n *\n * A chunk that cannot be loaded (offline, or a deploy that has replaced it), or that has not arrived within\n * `VIEW_LOAD_TIMEOUT_MS`, leaves the tab as it was, and is asked for again each time the Avatar view is opened. Whether\n * that fetches it again is the browser's to say, not this component's: Safari and Firefox fetch a module that failed\n * again, but Chromium-based browsers keep the failed fetch for as long as the page lives, so there the tab stays as it\n * was until the page is reloaded. Until a load has succeeded, the tab keeps showing what it was before the live avatar,\n * also while a later attempt is under way, so a visitor does not see it flicker back to the bare picture.\n */\n\"use client\";\n\nimport {\n useContext,\n useEffect,\n useMemo,\n useState,\n type ComponentType,\n type ReactNode,\n} from \"react\";\n\nimport {\n avatarApiBase,\n isAvatarLiveLocaleReviewed,\n liveConfigComplete,\n type ExplorePanelAvatarLive,\n} from \"./explore-avatar-live-config\";\nimport { ExploreConversationContext } from \"./explore-conversation\";\nimport { exploreStrings, type ExploreLocale } from \"./explore-i18n\";\nimport { useWebSDKConfig } from \"../client/provider\";\nimport { cfAccessHeaders } from \"../client/security\";\n\nimport type { AvatarLiveViewProps } from \"./explore-avatar-live-view\";\n\nexport type { ExplorePanelAvatarLive };\n\n/** The live avatar's view, once its chunk is loaded. */\ntype AvatarLiveViewComponent = ComponentType<AvatarLiveViewProps>;\n\n/**\n * How long the Avatar view waits for the view's chunk before it shows the tab as it was before the live avatar (a\n * stalled connection would otherwise leave the bare picture up for good). The same patience as the availability\n * request that follows the chunk.\n */\nconst VIEW_LOAD_TIMEOUT_MS = 8_000;\n\n/**\n * Load the view's chunk. The package build leaves this `import()` as it is, pointing at the file it builds beside this\n * one (`tsup.config.ts`), so a site's bundler splits it into a chunk of its own; `scripts/validate-avatar-live.mjs`\n * checks that it did.\n */\nexport function loadAvatarLiveView(): Promise<AvatarLiveViewComponent> {\n return import(\"./explore-avatar-live-view\").then(\n (loaded) => loaded.AvatarLiveView,\n );\n}\n\nexport interface ExploreAvatarLiveProps {\n live: ExplorePanelAvatarLive;\n /** The Avatar view is showing: the panel is open and its Avatar tab is selected. */\n active: boolean;\n locale: ExploreLocale;\n /** The product the panel speaks for, when it is one product's own; null on the portfolio's. */\n productName: string | null;\n /** The approved still picture. */\n still: { src: string; alt: string };\n /** The Avatar tab as it was before the live avatar: shown whenever the live avatar is not offered or not reachable. */\n fallback: ReactNode;\n /** Back to the Chat tab. Leaving the Avatar tab ends a session, like any other way out of it. */\n onContinueInChat: () => void;\n /**\n * How the view's chunk is loaded. For a test that needs it to fail or to wait; the panel never passes it. Keep it\n * stable between renders: a new function is a new load.\n */\n loadView?: () => Promise<AvatarLiveViewComponent>;\n}\n\nexport function ExploreAvatarLive({\n live,\n active,\n locale,\n productName,\n still,\n fallback,\n onContinueInChat,\n loadView = loadAvatarLiveView,\n}: ExploreAvatarLiveProps) {\n const T = exploreStrings(locale);\n const config = useWebSDKConfig();\n const conversation = useContext(ExploreConversationContext);\n\n const base = avatarApiBase(config.gatewayUrl);\n const headers = useMemo(\n () => cfAccessHeaders(config.gatewayUrl, config.cfAccess),\n [config.gatewayUrl, config.cfAccess],\n );\n const complete = liveConfigComplete(live);\n // Nothing to ask the server about: an incomplete config, no gateway, no shared conversation to read (no provider, or a\n // read-only shared one), or a locale whose strings have not been reviewed. The tab stays as it was.\n const off =\n !complete ||\n base === null ||\n conversation === null ||\n conversation.isSharedView ||\n !isAvatarLiveLocaleReviewed(locale);\n\n useEffect(() => {\n if (!complete) {\n console.warn(\n \"[WebSDK] ExplorePanel: avatar.live needs site, load and manifestVersion, and turnstileSiteKey and allowTestSiteKey of a valid shape when set; the live avatar stays off.\",\n );\n }\n }, [complete]);\n\n const [View, setView] = useState<AvatarLiveViewComponent | null>(null);\n // The chunk could not be had, or not in time, and has not come since. It stays set until a load succeeds, including\n // while the next attempt is under way: the tab is then the one it was before the live avatar, and not the bare picture\n // the view starts from.\n const [failed, setFailed] = useState(false);\n\n // The chunk is wanted from the moment the Avatar view shows with the live avatar on, and asked for again each time it\n // shows until it is there. Once it is loaded it stays: the view decides for itself what to do when the live avatar\n // goes off (see `AvatarLiveView`).\n const wanted = active && !off;\n useEffect(() => {\n if (!wanted || View !== null) return;\n let cancelled = false;\n let loading: Promise<AvatarLiveViewComponent>;\n try {\n loading = loadView();\n } catch (error) {\n loading = Promise.reject(error);\n }\n // A chunk that neither arrives nor fails would leave the bare picture up with no way on. Past the limit the tab is\n // the one it was before the live avatar; a chunk that arrives later is used all the same, if the visitor is still\n // on the Avatar view.\n const patience = setTimeout(() => {\n if (!cancelled) setFailed(true);\n }, VIEW_LOAD_TIMEOUT_MS);\n loading.then(\n (component) => {\n // A component is a function: `setView(component)` would call it as an updater. (The view being set runs this\n // effect's cleanup, which stops the clock.)\n if (!cancelled) setView(() => component);\n },\n () => {\n clearTimeout(patience);\n if (!cancelled) setFailed(true);\n },\n );\n return () => {\n cancelled = true;\n clearTimeout(patience);\n };\n }, [wanted, View, loadView]);\n\n if (View !== null) {\n return (\n <View\n live={live}\n active={active}\n locale={locale}\n productName={productName}\n still={still}\n fallback={fallback}\n onContinueInChat={onContinueInChat}\n continueInChat={T.continueInChat}\n off={off}\n base={base}\n headers={headers}\n conversation={conversation}\n />\n );\n }\n\n if (off || failed) {\n return (\n // `display: contents`: the earlier Avatar view's picture, line and button lay out in the pane exactly as before.\n <div\n style={{ display: \"contents\" }}\n data-boff-explore=\"avatar-live\"\n data-phase={off ? \"off\" : \"inert\"}\n >\n {fallback}\n </div>\n );\n }\n\n // Until the view is there: what it shows before it has asked anything (its `idle` step), so that what the server\n // renders, what a prerendered page holds and what the first client render shows are all the same picture.\n return (\n <div\n data-boff-explore=\"avatar-live\"\n data-phase=\"idle\"\n className=\"flex max-h-full w-full flex-col items-center gap-4 overflow-y-auto\"\n >\n <img\n src={still.src}\n alt={still.alt}\n decoding=\"async\"\n width={128}\n height={128}\n className=\"shrink-0 rounded-full border border-border object-cover shadow-sm h-32 w-32\"\n />\n <p\n role=\"status\"\n data-boff-explore=\"avatar-live-status\"\n className=\"text-sm text-muted-foreground\"\n />\n <div data-boff-explore=\"avatar-live-bot-check\" />\n </div>\n );\n}\n","/**\n * ExplorePanel — the site-wide assistant panel (BOFF-9697).\n *\n * The site's Explore conversation in a compact panel over whatever page is showing, with Chat and Avatar views, and\n * an Expand control that grows the SAME panel to the full window (Restore shrinks it back). Opt-in: a site renders it\n * under an `ExploreChatProvider` (above its routes, inside its router) and lets its floating `ExploreCta` open it.\n * Every other site is unchanged.\n *\n * - **One conversation, never remounted.** The chat view is `ExplorePage presentation=\"panel\"`. It mounts on the\n * first open and stays mounted: Expand, Restore, the tabs and closing change only CSS, so the draft, the transcript,\n * its scroll position and an answer still on its way all survive. Closed, it is hidden but stays laid out\n * (`visibility`/`content-visibility`), which is what keeps the transcript's scroll position.\n * - **Non-modal, and never over the host's bottom bar.** `bottomOffset` (a consent banner's height, say) is kept clear\n * in both sizes, so the banner stays visible and usable, and the page behind stays scrollable. Render the panel after\n * the site header and before the banner: at the same `zIndex` the later element paints on top, so the expanded panel\n * covers the header and never the banner.\n * - **Escape and the phone's Back step back:** expanded, then compact, then closed. Back works through history\n * entries the panel adds for its own steps (the same URL, so the host's router stays where it is), and the page\n * keeps its scroll position through them. Closing by any route takes those entries off again.\n * - **The on-screen keyboard** never covers the composer: while open, the panel follows the visual viewport.\n * - **Closing, or the Avatar view, stops listening and reading aloud** (`active`); the conversation is kept.\n * - **The avatar:** by default the Avatar view shows the host's approved picture, labelled \"Live avatar coming soon\",\n * and a \"Continue in Chat\" action. No session, no animation, no call to any avatar service.\n * - **The live avatar (BOFF-9797), opt-in:** a host that passes `avatar.live` gets the receive-only live avatar in that\n * view instead (`ExploreAvatarLive`): nothing is asked until the view opens, and nothing loaded until the visitor\n * agrees. The live avatar's own code is a chunk of its own, fetched when the view first opens, so a panel without\n * `avatar.live` carries a few lines of it and no more. Without `avatar.live`, the panel renders exactly what it did\n * before.\n *\n * Import from the package ROOT (tsup `splitting: false`), like `ExplorePage` and `ExploreChatProvider`.\n */\n\"use client\";\n\nimport {\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type RefObject,\n} from \"react\";\n\nimport { Maximize2, Minimize2, X } from \"lucide-react\";\n\nimport { ExplorePage } from \"./explore\";\nimport {\n ExploreAvatarLive,\n type ExplorePanelAvatarLive,\n} from \"./explore-avatar-live\";\nimport { ExploreCatalogProductsContext } from \"./explore-conversation\";\nimport {\n exploreStrings,\n fill,\n isRtlLocale,\n resolveExploreLocale,\n} from \"./explore-i18n\";\nimport {\n pinnedProductSlug,\n productNameFor,\n type ExploreScope,\n} from \"./explore-scope\";\nimport { ECOSYSTEM_PRODUCTS } from \"../data/products\";\nimport { cn } from \"../utils/cn\";\n\n/**\n * The keys this panel keeps in `history.state`, beside the host router's own:\n *\n * boffExplorePanel \"open\" | \"expanded\" on the panel's own entries (the same URL as the entry below them)\n * boffExplorePanelPos every entry the panel has seen, its own and the host's, in the order it saw them, so a\n * traversal can tell Back from Forward\n * boffExplorePanelDoc the page load that wrote them: anything an earlier page load left is the old panel's\n */\nconst MARK_KEY = \"boffExplorePanel\";\nconst POS_KEY = \"boffExplorePanelPos\";\nconst DOC_KEY = \"boffExplorePanelDoc\";\n\n/** This page load. */\nconst DOC_ID = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n\n/** The last position handed out in this page load; module-wide, so a remounted panel carries on from it. */\nlet lastPos = 0;\n\n/**\n * The host's own `scrollRestoration`, for the entries the panel leaves as \"manual\" (`pushMark`). Module-wide too: an\n * entry a panel left as \"manual\" still gets its mode back after that panel has remounted.\n */\nlet hostMode: ScrollRestoration | null = null;\n\n/** The phone layout (a bottom sheet): the stylesheet's breakpoint. */\nconst NARROW_QUERY = \"(max-width: 639px)\";\n\n/** No precise pointer: focusing the composer there would raise the keyboard over the panel before it was asked for. */\nconst TOUCH_FIRST_QUERY = \"(hover: none) and (pointer: coarse)\";\n\n/** Frames to keep trying the composer's focus: past its 150 ms transition at 60 Hz, with room to spare. */\nconst COMPOSER_FOCUS_TRIES = 15;\n\ntype PanelMark = \"open\" | \"expanded\";\ntype PanelSize = \"compact\" | \"expanded\";\ntype PanelView = \"chat\" | \"avatar\";\n\nexport type { ExplorePanelAvatarLive };\n\nexport interface ExplorePanelAvatar {\n /** The approved picture: a URL the page may load. */\n src: string;\n /** The avatar's name, for the picture's text alternative. */\n name?: string;\n /**\n * BOFF-9797. Opt in to the receive-only live avatar in the Avatar view, for this site. Absent (the default): the\n * Avatar view is the picture, \"Live avatar coming soon\" and \"Continue in Chat\", exactly as before, and nothing is\n * asked of any server. Needs the panel under an `ExploreChatProvider`. See the README's \"Live avatar\".\n */\n live?: ExplorePanelAvatarLive;\n}\n\nexport interface ExplorePanelProps {\n /** Whether the panel shows. The host owns it (its floating button opens the panel). */\n open: boolean;\n /**\n * Called with `false` when the visitor closes the panel: the close button, Escape, the phone's Back, or following a\n * link from the conversation on a phone.\n */\n onOpenChange: (open: boolean) => void;\n /** The panel's id, for the button's `controls`. Default `boff-explore-panel`. */\n id?: string;\n /** Passed to the chat view (`ExplorePage`). */\n productSlug?: string;\n locale?: string;\n /**\n * BOFF-9796. Passed to the chat view: see `ExplorePageProps.scope`. `product` (with `productSlug`) makes the panel\n * one product's own assistant and titles it \"{product} assistant\"; given `examplePrompts`, those are then its only\n * example prompts. Default `portfolio`: the panel as it was.\n */\n scope?: ExploreScope;\n /**\n * BOFF-9796. Passed to the chat view: see `ExplorePageProps.productName`. In the `product` scope it is also the\n * panel's title, at once, before any catalog. Default: the catalog's name for `productSlug`.\n */\n productName?: string;\n /**\n * BOFF-9796. Passed to the chat view: see `ExplorePageProps.examplePrompts`. In the `product` scope they are the only\n * prompts the panel shows, whatever the catalog has; without them it falls back to the catalog's, less any that name\n * another product and the SDK's portfolio prompt. A product site should pass its own.\n */\n examplePrompts?: string[];\n /**\n * The host router's navigate, for links in the conversation. On a phone the panel closes first (the sheet would\n * cover the page); on a wider screen it stays open beside the page. Absent: links load the page normally.\n */\n onNavigate?: (path: string) => void;\n welcomeTitle?: string;\n welcomeBody?: string;\n /** The site's Explore route, for share links made in the panel. Default `/explore`. */\n explorePath?: string;\n /** The Avatar view's picture. Absent: the panel has no Avatar view and no tabs. */\n avatar?: ExplorePanelAvatar;\n /**\n * A CSS length the panel keeps clear at the bottom of the window in both sizes: the host's own bottom bar, such as a\n * consent banner (`var(--site-consent-banner-height, 0px)`). Default `0px`.\n */\n bottomOffset?: string;\n /** The panel's `z-index`. Default 50: with the header and the banner both at 50, DOM order decides (see above). */\n zIndex?: number;\n /** Where focus goes back when the panel closes: the button that opened it. */\n returnFocusRef?: RefObject<HTMLElement | null>;\n /** Extra classes for the panel. */\n className?: string;\n}\n\ntype CssVars = Record<`--${string}`, string>;\n\n/*\n * Layout only: colours, the border's colour and the shadow come from the host's theme, through utility classes.\n *\n * --boff-explore-shell-bottom the host's bottom bar (`bottomOffset`)\n * --boff-explore-shell-lift set while the visible area differs from the page's (the on-screen keyboard, or iOS\n * panning): the slice of the page hidden below it. The panel keeps clear of the larger\n * of that and the bottom bar (a keyboard covers the bar too; a pan can leave it showing)\n * --boff-explore-shell-room set with it: the visible height left for the panel, which `dvh` does not follow\n * --boff-explore-shell-top set with it: the visible area's top, for the expanded panel\n */\nconst PANEL_CSS = `\n.boff-explore-shell {\n --boff-explore-shell-lift-at: max(var(--boff-explore-shell-lift, 0px), var(--boff-explore-shell-bottom, 0px));\n --boff-explore-shell-room-at: var(--boff-explore-shell-room, calc(100vh - var(--boff-explore-shell-bottom, 0px)));\n position: fixed;\n z-index: var(--boff-explore-shell-z, 50);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n overscroll-behavior: contain;\n inset-inline-end: 1rem;\n bottom: calc(1rem + var(--boff-explore-shell-lift-at));\n width: min(26rem, calc(100vw - 2rem));\n height: min(40rem, calc(var(--boff-explore-shell-room-at) - 6rem));\n border-width: 1px;\n border-style: solid;\n border-radius: 1rem;\n}\n@supports (height: 100dvh) {\n .boff-explore-shell {\n --boff-explore-shell-room-at: var(--boff-explore-shell-room, calc(100dvh - var(--boff-explore-shell-bottom, 0px)));\n }\n}\n@media (max-width: 639px) {\n .boff-explore-shell[data-size=\"compact\"] {\n inset-inline: 0;\n bottom: var(--boff-explore-shell-lift-at);\n width: auto;\n height: min(75vh, calc(var(--boff-explore-shell-room-at) - 4rem));\n border-width: 1px 0 0;\n border-radius: 1rem 1rem 0 0;\n }\n @supports (height: 100dvh) {\n .boff-explore-shell[data-size=\"compact\"] {\n height: min(75dvh, calc(var(--boff-explore-shell-room-at) - 4rem));\n }\n }\n}\n.boff-explore-shell[data-size=\"expanded\"] {\n inset: var(--boff-explore-shell-top, 0px) 0 var(--boff-explore-shell-lift-at) 0;\n width: auto;\n height: auto;\n border-width: 0;\n border-radius: 0;\n box-shadow: none;\n}\n.boff-explore-shell[data-open=\"false\"] {\n visibility: hidden;\n content-visibility: hidden;\n}\n.boff-explore-shell:focus { outline: none; }\n`;\n\n/**\n * BOFF-9796: the title of one product's own panel (\"Healthy Bowl assistant\", 157px on one line) is longer than the room\n * a phone leaves it beside the tabs and the buttons: 78px at 320px and 118px at 360px, in English.\n *\n * So it wraps rather than being cut short on one line: to at most two lines, on 18px lines, which makes two lines exactly\n * as tall as the 36px controls beside it, so the header keeps its height and the controls their place. Where its box is\n * too narrow to hold the product's name on one 14px line (under 6rem: English at 320px, and Tamil, whose tabs are\n * wider, at 360px), it steps down to 12px on 16px lines. A container query on the title's own box rather than a media\n * query, because its room is whatever the locale's tabs leave, not the viewport's width.\n *\n * Two lines hold the whole title in English and most locales at 320px and wider. A narrower box can still clamp it,\n * with an ellipsis at the end of its second line: Tamil's at 320px, where its wider tabs leave the title under 4rem, and\n * English's, among others, on a screen narrower than 320px. A further step down for those is left for later.\n *\n * A stylesheet of its own, rendered in the product scope only, so the portfolio's panel renders exactly what it always\n * has. Two classes deep, like the page's rules, so a host's own Tailwind (v3 or v4) never outranks it.\n */\nconst PRODUCT_TITLE_CSS = `\n.boff-explore-shell .boff-explore-shell-title { container-type: inline-size; }\n.boff-explore-shell .boff-explore-shell-title-text {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow: hidden;\n overflow-wrap: break-word;\n line-height: 1.125rem;\n}\n@container (max-width: 6rem) {\n .boff-explore-shell .boff-explore-shell-title-text { font-size: 0.75rem; line-height: 1rem; }\n}\n`;\n\nfunction stateRecord(): Record<string, unknown> {\n const state: unknown = window.history.state;\n return state !== null && typeof state === \"object\"\n ? (state as Record<string, unknown>)\n : {};\n}\n\n/** The current entry carries keys this page load wrote. */\nfunction stampedHere(): boolean {\n return stateRecord()[DOC_KEY] === DOC_ID;\n}\n\n/** The panel's mark on the current history entry, when the entry is one of the panel's own. */\nfunction readMark(): PanelMark | null {\n if (typeof window === \"undefined\" || !stampedHere()) return null;\n const mark = stateRecord()[MARK_KEY];\n return mark === \"open\" || mark === \"expanded\" ? mark : null;\n}\n\n/** Where the current entry stands among the entries the panel has seen, or null for one it has not. */\nfunction readPos(): number | null {\n if (typeof window === \"undefined\" || !stampedHere()) return null;\n const pos = stateRecord()[POS_KEY];\n return typeof pos === \"number\" ? pos : null;\n}\n\n/**\n * Give the current entry its place (a host entry the panel sees for the first time). Keys an earlier page load left\n * here (a reload, a restored tab) go: that panel is gone, and its \"open\" would make Back close a panel that is not\n * there. A refusal (Safari caps history calls per window of time) only costs that entry its place.\n */\nfunction stamp(): void {\n if (typeof window === \"undefined\" || readPos() !== null) return;\n const rest = { ...stateRecord() };\n delete rest[MARK_KEY];\n delete rest[POS_KEY];\n delete rest[DOC_KEY];\n lastPos += 1;\n try {\n window.history.replaceState(\n { ...rest, [POS_KEY]: lastPos, [DOC_KEY]: DOC_ID },\n \"\",\n );\n } catch {\n /* refused: see above */\n }\n}\n\n/**\n * A history entry for one of the panel's steps: the same URL, the host router's state kept as it is. False when the\n * browser refused it (Safari's cap): the panel then works without that Back step.\n *\n * The entry being left is switched to `scrollRestoration: \"manual\"` first. Every entry remembers the scroll position\n * it was left at, and on \"auto\" the browser puts it back on Back, which would jump a page the visitor has scrolled\n * since the panel opened. Chromium and Firefox take that mode from the entry as it was left (a change made during\n * `popstate` is ignored; measured on all three engines), so it has to be set before the push. The new entry gets the\n * host's own mode at once, and the left one gets it back when Back lands on it (`restoreScrollMode`).\n */\nfunction pushMark(mark: PanelMark): boolean {\n const { history } = window;\n const mode =\n \"scrollRestoration\" in history ? history.scrollRestoration : null;\n try {\n if (mode !== null) history.scrollRestoration = \"manual\";\n lastPos += 1;\n history.pushState(\n {\n ...stateRecord(),\n [MARK_KEY]: mark,\n [POS_KEY]: lastPos,\n [DOC_KEY]: DOC_ID,\n },\n \"\",\n );\n return true;\n } catch {\n return false;\n } finally {\n if (mode !== null) history.scrollRestoration = mode;\n }\n}\n\n/**\n * Give an entry the panel left as \"manual\" (see `pushMark`) the host's own mode back once the engine's restore window\n * has passed (two frames after `popstate` is past it on Chromium, Firefox and WebKit alike), then run `then`.\n */\nfunction restoreScrollMode(mode: ScrollRestoration, then?: () => void): void {\n const { history } = window;\n const put = () => {\n if (history.scrollRestoration === \"manual\")\n history.scrollRestoration = mode;\n then?.();\n };\n if (typeof window.requestAnimationFrame !== \"function\") {\n window.setTimeout(put, 50);\n return;\n }\n window.requestAnimationFrame(() => window.requestAnimationFrame(put));\n}\n\n/**\n * Close what the conversation opened over itself: the product-video player (a modal `<dialog>`, portalled to\n * `<body>`, so it is looked for there) and the disclaimer (its backdrop closes it). True when something was open.\n */\nfunction closeInnerDialogs(shell: HTMLElement | null): boolean {\n let closed = false;\n document\n .querySelectorAll<HTMLDialogElement>(\n 'dialog[data-boff-explore=\"video-dialog\"]',\n )\n .forEach((dialog) => {\n if (!dialog.open) return;\n dialog.close();\n closed = true;\n });\n const disclaimer = shell?.querySelector<HTMLElement>(\n '[data-boff-explore=\"disclaimer-dialog\"]',\n );\n if (disclaimer) {\n disclaimer.click();\n closed = true;\n }\n return closed;\n}\n\n/** How many of the panel's own entries are on top of the stack: an \"expanded\" one always sits on an \"open\" one. */\nfunction marksOnTop(mark: PanelMark | null): number {\n if (mark === \"expanded\") return 2;\n return mark === \"open\" ? 1 : 0;\n}\n\nfunction matches(query: string): boolean {\n return (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(query).matches\n );\n}\n\nexport function ExplorePanel({\n open,\n onOpenChange,\n id = \"boff-explore-panel\",\n productSlug,\n locale,\n scope,\n productName,\n examplePrompts,\n onNavigate,\n welcomeTitle,\n welcomeBody,\n explorePath,\n avatar,\n bottomOffset,\n zIndex,\n returnFocusRef,\n className,\n}: ExplorePanelProps) {\n const resolvedLocale = resolveExploreLocale(locale);\n const T = useMemo(() => exploreStrings(resolvedLocale), [resolvedLocale]);\n const rtl = isRtlLocale(resolvedLocale);\n // BOFF-9796: one product's own assistant is titled with its name: the host's, else the catalog's (the provider's, or,\n // with none, the SDK's own list, which every fallback catalog starts from). The generic title when neither knows it,\n // and always in the portfolio scope.\n const catalogProducts = useContext(ExploreCatalogProductsContext);\n const pinnedSlug = pinnedProductSlug(scope, productSlug);\n const pinnedName = useMemo(\n () =>\n pinnedSlug === null\n ? null\n : productNameFor(\n catalogProducts ?? ECOSYSTEM_PRODUCTS,\n pinnedSlug,\n productName,\n ),\n [catalogProducts, pinnedSlug, productName],\n );\n const title =\n pinnedName === null\n ? T.panelTitle\n : fill(T.panelTitleProduct, { product: pinnedName });\n const uid = useId();\n const titleId = `${uid}-title`;\n const chatTabId = `${uid}-chat-tab`;\n const avatarTabId = `${uid}-avatar-tab`;\n const chatPaneId = `${uid}-chat`;\n const avatarPaneId = `${uid}-avatar`;\n\n const [mounted, setMounted] = useState(open);\n const [size, setSize] = useState<PanelSize>(\"compact\");\n const [view, setView] = useState<PanelView>(\"chat\");\n const [focusRequest, setFocusRequest] = useState<\"in\" | \"back\" | null>(\n open ? \"in\" : null,\n );\n // Opening and closing, seen during render (React's pattern for state that follows a prop change): the panel mounts\n // on its first opening and stays mounted, and every close comes back compact.\n const [wasOpen, setWasOpen] = useState(open);\n if (open !== wasOpen) {\n setWasOpen(open);\n if (open) {\n setMounted(true);\n setFocusRequest(\"in\");\n } else {\n setSize(\"compact\");\n setFocusRequest(\"back\");\n }\n }\n\n const shellRef = useRef<HTMLDivElement>(null);\n const chatPaneRef = useRef<HTMLDivElement>(null);\n const chatTabRef = useRef<HTMLButtonElement>(null);\n const avatarTabRef = useRef<HTMLButtonElement>(null);\n /** Traversals the panel started itself: their `popstate` is not the visitor's Back. */\n const ownPopsRef = useRef(0);\n /** Set from the panel's own traversal landing until the entry it left as \"manual\" has its mode back. */\n const settlingRef = useRef(false);\n /** Work held until the panel's own traversal has settled (a push before it would be undone by it). */\n const afterPopRef = useRef<Array<() => void>>([]);\n /** The current entry as the panel last saw it: its mark, and its place. */\n const markRef = useRef<PanelMark | null>(null);\n const posRef = useRef<number | null>(null);\n /** The page the panel last saw as current, to tell a page change from a step of the panel's own. */\n const hrefRef = useRef<string | null>(null);\n /**\n * The latest `open` and `onOpenChange`. The `popstate` listener reads them here instead of being added again when\n * they change: a router can re-render the page (and flip `open`) from its own `popstate` listener, before the\n * panel's runs, and a listener removed and re-added during that dispatch is never called for it.\n */\n const openRef = useRef(open);\n const onOpenChangeRef = useRef(onOpenChange);\n /** The panel has taken its first look at the current entry. */\n const lookedRef = useRef(false);\n\n const traverse = useCallback((delta: number) => {\n ownPopsRef.current += 1;\n window.history.go(delta);\n }, []);\n\n const push = useCallback((mark: PanelMark): boolean => {\n const { history } = window;\n if (\n \"scrollRestoration\" in history &&\n history.scrollRestoration !== \"manual\"\n ) {\n hostMode = history.scrollRestoration;\n }\n stamp();\n if (!pushMark(mark)) return false;\n markRef.current = mark;\n posRef.current = readPos();\n hrefRef.current = window.location.href;\n return true;\n }, []);\n\n const whenSettled = useCallback((work: () => void) => {\n if (ownPopsRef.current > 0 || settlingRef.current) {\n afterPopRef.current.push(work);\n } else {\n work();\n }\n }, []);\n\n /** Run the held work, in order; a piece of it that starts another traversal holds the rest again. */\n const flush = useCallback(() => {\n settlingRef.current = false;\n while (\n afterPopRef.current.length > 0 &&\n ownPopsRef.current === 0 &&\n !settlingRef.current\n ) {\n afterPopRef.current.shift()?.();\n }\n }, []);\n\n useEffect(() => {\n openRef.current = open;\n onOpenChangeRef.current = onOpenChange;\n });\n\n // Every render (the host's router re-renders the panel on a page change): a page the panel has not seen yet gets its\n // place, and becomes where the panel stands. An entry it HAS seen, current now without the panel having moved there,\n // is a Back or Forward whose `popstate` the panel has not had yet: a router's own `popstate` listener can re-render\n // the page before the panel's runs (measured in Chromium, where listeners on `window` run in the order they were\n // added). That handler needs the entry being left, so the picture is left to it. Skipped as well while the panel's\n // own traversal is under way: its `popstate` does it.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (ownPopsRef.current > 0 || settlingRef.current) return;\n const pos = readPos();\n if (lookedRef.current && pos !== null && pos !== posRef.current) return;\n lookedRef.current = true;\n stamp();\n markRef.current = readMark();\n posRef.current = readPos();\n hrefRef.current = window.location.href;\n });\n\n // Opened: an entry for \"open\", so the phone's Back closes the panel. Closed by any route: what the conversation\n // opened over itself closes too, and the panel's own entries come off again, unless the visitor's Back already took\n // them (or a page change now sits on top of them). After any traversal still under way, either way.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n whenSettled(() => {\n if (openRef.current) {\n if (readMark() === null) push(\"open\");\n return;\n }\n closeInnerDialogs(shellRef.current);\n const count = marksOnTop(readMark());\n if (count > 0) traverse(-count);\n });\n }, [open, push, traverse, whenSettled]);\n\n // The phone's (and the browser's) Back and Forward. Added once, for the panel's lifetime (see `openRef`).\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onPopState = () => {\n const open = openRef.current;\n const onOpenChange = onOpenChangeRef.current;\n const leftMark = markRef.current;\n const leftPos = posRef.current;\n const leftHref = hrefRef.current;\n const mark = readMark();\n const pos = readPos();\n markRef.current = mark;\n posRef.current = pos;\n hrefRef.current = window.location.href;\n const forward = pos !== null && leftPos !== null && pos > leftPos;\n const mode = hostMode;\n // Leaving one of the panel's entries lands on the entry it left as \"manual\" (`pushMark`): its mode goes back.\n const restoring = leftMark !== null && mode !== null;\n\n if (ownPopsRef.current > 0) {\n ownPopsRef.current -= 1;\n if (ownPopsRef.current > 0) return;\n if (restoring) {\n settlingRef.current = true;\n restoreScrollMode(mode, flush);\n } else {\n flush();\n }\n return;\n }\n if (restoring) restoreScrollMode(mode);\n\n if (leftMark !== null && !forward) {\n // Back off one of the panel's steps. What the conversation opened over itself (the video player, the\n // disclaimer) is what that Back closes; the panel's step comes back under it.\n if (open && closeInnerDialogs(shellRef.current)) {\n if (readMark() === null) push(\"open\");\n if (leftMark === \"expanded\" && readMark() === \"open\") {\n push(\"expanded\");\n }\n return;\n }\n setSize(\"compact\");\n if (mark === null && open) onOpenChange(false);\n return;\n }\n // A page change: what the conversation opened over itself (a playing video) does not outlive the page.\n if (leftHref !== null && window.location.href !== leftHref) {\n closeInnerDialogs(shellRef.current);\n }\n // Between the host's own pages, or Forward off the panel's steps onto one: the panel stays as it is.\n if (mark === null) return;\n if (forward) {\n // Forward onto one of the panel's steps redoes it.\n setSize(mark === \"expanded\" ? \"expanded\" : \"compact\");\n if (!open) onOpenChange(true);\n return;\n }\n // Back onto the panel's steps from a later page. Closed there: they are stale, so Back steps over them rather\n // than stopping on a press that shows nothing.\n if (!open) {\n traverse(-marksOnTop(mark));\n return;\n }\n setSize(mark === \"expanded\" ? \"expanded\" : \"compact\");\n };\n window.addEventListener(\"popstate\", onPopState);\n return () => window.removeEventListener(\"popstate\", onPopState);\n }, [flush, push, traverse]);\n\n // While open, follow the visual viewport, so the on-screen keyboard never covers the composer. Written straight to\n // the element: it changes on every keyboard frame, and nothing else in the tree reads it.\n useEffect(() => {\n if (!open || typeof window === \"undefined\") return;\n const viewport = window.visualViewport;\n const shell = shellRef.current;\n if (!viewport || !shell) return;\n const clear = () => {\n shell.style.removeProperty(\"--boff-explore-shell-lift\");\n shell.style.removeProperty(\"--boff-explore-shell-room\");\n shell.style.removeProperty(\"--boff-explore-shell-top\");\n };\n const apply = () => {\n const covered = Math.max(\n 0,\n Math.round(window.innerHeight - viewport.height - viewport.offsetTop),\n );\n // iOS can also pan the visible area down the page, so nothing looks covered at the bottom while the top has\n // moved: the panel follows the visible area whenever it differs from the page's, not only when the bottom does.\n const panned = viewport.offsetTop > 1;\n if (covered <= 1 && !panned) {\n clear();\n return;\n }\n shell.style.setProperty(\"--boff-explore-shell-lift\", `${covered}px`);\n // The visible height, less whatever of the bottom bar still shows inside it (none once a keyboard covers it).\n shell.style.setProperty(\n \"--boff-explore-shell-room\",\n `calc(${Math.round(viewport.height)}px - max(0px, var(--boff-explore-shell-bottom, 0px) - ${covered}px))`,\n );\n shell.style.setProperty(\n \"--boff-explore-shell-top\",\n `${Math.max(0, Math.round(viewport.offsetTop))}px`,\n );\n };\n apply();\n viewport.addEventListener(\"resize\", apply);\n viewport.addEventListener(\"scroll\", apply);\n return () => {\n viewport.removeEventListener(\"resize\", apply);\n viewport.removeEventListener(\"scroll\", apply);\n clear();\n };\n }, [open]);\n\n /**\n * The composer, as soon as it can take focus, while focus is still where `from` put it. The composer sits in a box\n * with a CSS transition on every property, `visibility` included, so after the panel (or the chat) stops being\n * invisible it stays computed as hidden until that transition has actually started, which can be a frame or two\n * later, and a browser will not focus it until then (measured on Chromium and Firefox). So: one try per frame, for\n * at most the transition's length. A composer that never can (Explore unavailable) leaves focus on `from`.\n */\n const focusComposerSoon = useCallback((from: HTMLElement | null) => {\n let tries = 0;\n const next = (attempt: () => void) => {\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(attempt);\n } else {\n window.setTimeout(attempt, 16);\n }\n };\n const attempt = () => {\n if (document.activeElement !== from) return;\n const composer = chatPaneRef.current?.querySelector<HTMLTextAreaElement>(\n \"textarea:not(:disabled)\",\n );\n if (!composer) return;\n composer.focus();\n tries += 1;\n if (document.activeElement !== composer && tries < COMPOSER_FOCUS_TRIES) {\n next(attempt);\n }\n };\n next(attempt);\n }, []);\n\n // Focus into the panel when it opens: the panel itself at once, then the composer (not on a touch-first device,\n // where that would raise the keyboard over the panel unasked). Back to the button when it closes, unless the visitor\n // has already moved on to something else on the page.\n useEffect(() => {\n if (focusRequest === null) return;\n setFocusRequest(null);\n const shell = shellRef.current;\n if (focusRequest === \"back\") {\n const active = document.activeElement;\n if (\n active === null ||\n active === document.body ||\n shell?.contains(active)\n ) {\n returnFocusRef?.current?.focus();\n }\n return;\n }\n if (!shell) return;\n shell.focus();\n if (view === \"chat\" && !matches(TOUCH_FIRST_QUERY)) {\n focusComposerSoon(shell);\n }\n }, [focusComposerSoon, focusRequest, returnFocusRef, view]);\n\n const close = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n const expand = useCallback(() => {\n setSize(\"expanded\");\n whenSettled(() => {\n if (!openRef.current) return;\n if (readMark() === null) push(\"open\");\n if (readMark() === \"open\") push(\"expanded\");\n });\n }, [push, whenSettled]);\n\n const restore = useCallback(() => {\n setSize(\"compact\");\n whenSettled(() => {\n if (readMark() === \"expanded\") traverse(-1);\n });\n }, [traverse, whenSettled]);\n\n const onKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.key !== \"Escape\" || event.defaultPrevented) return;\n // Escape that only cancels an input method's candidate (Chinese, Japanese, …) is the input method's.\n if (event.nativeEvent.isComposing || event.keyCode === 229) return;\n const shell = shellRef.current;\n // Only Escape from inside the panel's own DOM: a portal below it in the React tree (the video player) closes\n // itself.\n if (\n !shell ||\n !(event.target instanceof Node) ||\n !shell.contains(event.target)\n ) {\n return;\n }\n // A dialog inside the conversation (the disclaimer) closes first, on its own.\n if (\n shell.querySelector('dialog[open], [role=\"dialog\"][aria-modal=\"true\"]')\n ) {\n return;\n }\n event.preventDefault();\n if (size === \"expanded\") restore();\n else close();\n },\n [close, restore, size],\n );\n\n // A link followed from the conversation. The panel's own entries come off first, so they are never left buried under\n // the new page (a Back that then shows nothing). On a phone the sheet would cover that page, so the panel closes;\n // wider, it stays open beside the page, compact, with its step on top of the new page so Back closes it first.\n const navigate = useCallback(\n (path: string) => {\n if (!onNavigate) return;\n setSize(\"compact\");\n const stayOpen = !matches(NARROW_QUERY);\n if (!stayOpen) onOpenChange(false);\n whenSettled(() => {\n const go = () => {\n onNavigate(path);\n if (stayOpen && openRef.current && readMark() === null) {\n push(\"open\");\n }\n };\n const count = marksOnTop(readMark());\n if (count === 0) {\n go();\n return;\n }\n afterPopRef.current.push(go);\n traverse(-count);\n });\n },\n [onNavigate, onOpenChange, push, traverse, whenSettled],\n );\n\n // A selected tab takes focus however it was chosen: Safari does not focus a clicked button, and the composer the\n // visitor may have been in is about to be covered.\n const selectView = useCallback((next: PanelView) => {\n setView(next);\n (next === \"chat\" ? chatTabRef : avatarTabRef).current?.focus();\n }, []);\n\n const continueInChat = useCallback(() => {\n setView(\"chat\");\n // The Chat tab at once (the button pressed here is about to be hidden, which would leave focus nowhere), then the\n // composer as soon as it can take focus. A composer that cannot (Explore unavailable) leaves it on the tab.\n const tab = chatTabRef.current;\n tab?.focus();\n focusComposerSoon(tab);\n }, [focusComposerSoon]);\n\n const onTabKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n // Two tabs: either arrow moves to the other one, in either reading direction.\n const other: PanelView = view === \"chat\" ? \"avatar\" : \"chat\";\n const next: Partial<Record<string, PanelView>> = {\n ArrowLeft: other,\n ArrowRight: other,\n Home: \"chat\",\n End: \"avatar\",\n };\n const target = next[event.key];\n if (!target) return;\n event.preventDefault();\n selectView(target);\n },\n [selectView, view],\n );\n\n if (!mounted) return null;\n\n const style: CSSProperties & CssVars = {\n \"--boff-explore-shell-bottom\": bottomOffset ?? \"0px\",\n ...(zIndex === undefined\n ? {}\n : { \"--boff-explore-shell-z\": String(zIndex) }),\n };\n const iconButton =\n \"inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n const tabButton =\n \"rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n const expanded = size === \"expanded\";\n const sizeLabel = expanded ? T.exitFullScreen : T.enterFullScreen;\n const avatarAlt = avatar?.name\n ? `${avatar.name}, ${T.liveAvatar}`\n : T.liveAvatar;\n // The Avatar view as it has always been: the picture, \"Live avatar coming soon\" and \"Continue in Chat\". The live\n // avatar falls back to exactly this wherever it is not offered or not reachable.\n const comingSoon = avatar ? (\n <>\n <img\n src={avatar.src}\n alt={avatarAlt}\n loading=\"lazy\"\n decoding=\"async\"\n width={128}\n height={128}\n className=\"h-32 w-32 rounded-full border border-border object-cover shadow-sm\"\n />\n <p className=\"text-base font-semibold\">{T.avatarComingSoon}</p>\n <button\n type=\"button\"\n data-boff-explore=\"panel-continue-chat\"\n className=\"inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n onClick={continueInChat}\n >\n {T.continueInChat}\n </button>\n </>\n ) : null;\n const tabs: Array<{\n key: PanelView;\n id: string;\n pane: string;\n label: string;\n }> = [\n { key: \"chat\", id: chatTabId, pane: chatPaneId, label: T.tabChat },\n { key: \"avatar\", id: avatarTabId, pane: avatarPaneId, label: T.tabAvatar },\n ];\n\n return (\n <div\n ref={shellRef}\n id={id}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={titleId}\n tabIndex={-1}\n data-boff-explore=\"panel-shell\"\n data-open={open ? \"true\" : \"false\"}\n data-size={size}\n dir={rtl ? \"rtl\" : undefined}\n className={cn(\n \"boff-explore-shell border-border bg-background text-foreground shadow-2xl\",\n className,\n )}\n style={style}\n onKeyDown={onKeyDown}\n >\n <style>{PANEL_CSS}</style>\n {pinnedSlug === null ? null : (\n <style dangerouslySetInnerHTML={{ __html: PRODUCT_TITLE_CSS }} />\n )}\n <div className=\"flex shrink-0 items-center gap-2 border-b border-border px-3 py-2\">\n {/* The portfolio's short title keeps its one line, and its markup, exactly as they were. One product's own\n wraps (see PRODUCT_TITLE_CSS): its text sits in a box of its own inside the title's, whose width the\n stylesheet's container query reads. */}\n {pinnedSlug === null ? (\n <span\n id={titleId}\n className=\"min-w-0 flex-1 truncate text-sm font-semibold\"\n >\n {title}\n </span>\n ) : (\n <span\n id={titleId}\n className=\"boff-explore-shell-title min-w-0 flex-1\"\n >\n <span className=\"boff-explore-shell-title-text text-sm font-semibold\">\n {title}\n </span>\n </span>\n )}\n {avatar ? (\n <div\n role=\"tablist\"\n aria-label={T.panelViews}\n className=\"inline-flex shrink-0 rounded-lg bg-muted p-0.5\"\n >\n {tabs.map((tab) => (\n <button\n key={tab.key}\n ref={tab.key === \"chat\" ? chatTabRef : avatarTabRef}\n type=\"button\"\n role=\"tab\"\n id={tab.id}\n aria-selected={view === tab.key}\n aria-controls={tab.pane}\n tabIndex={view === tab.key ? 0 : -1}\n data-boff-explore={`panel-tab-${tab.key}`}\n className={cn(\n tabButton,\n view === tab.key\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground hover:text-foreground\",\n )}\n onClick={() => selectView(tab.key)}\n onKeyDown={onTabKeyDown}\n >\n {tab.label}\n </button>\n ))}\n </div>\n ) : null}\n <div className=\"flex shrink-0 items-center gap-1\">\n <button\n type=\"button\"\n data-boff-explore={expanded ? \"panel-restore\" : \"panel-expand\"}\n aria-label={sizeLabel}\n title={sizeLabel}\n className={iconButton}\n onClick={expanded ? restore : expand}\n >\n {expanded ? (\n <Minimize2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <Maximize2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n </button>\n <button\n type=\"button\"\n data-boff-explore=\"panel-close\"\n aria-label={T.closePanel}\n title={T.closePanel}\n className={iconButton}\n onClick={close}\n >\n <X className=\"h-4 w-4\" aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n {/* Laid out even under the Avatar view (only made invisible), so the transcript keeps its scroll position. */}\n <div\n ref={chatPaneRef}\n id={chatPaneId}\n role={avatar ? \"tabpanel\" : undefined}\n aria-labelledby={avatar ? chatTabId : undefined}\n data-boff-explore=\"panel-chat\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col\",\n view === \"avatar\" && \"invisible\",\n )}\n >\n <ExplorePage\n presentation=\"panel\"\n active={open && view === \"chat\"}\n productSlug={productSlug}\n locale={locale}\n scope={scope}\n productName={productName}\n examplePrompts={examplePrompts}\n onNavigate={onNavigate ? navigate : undefined}\n welcomeTitle={welcomeTitle}\n welcomeBody={welcomeBody}\n explorePath={explorePath}\n />\n </div>\n {avatar ? (\n <div\n id={avatarPaneId}\n role=\"tabpanel\"\n aria-labelledby={avatarTabId}\n data-boff-explore=\"panel-avatar\"\n className={cn(\n \"absolute inset-0 flex-col items-center justify-center gap-4 overflow-y-auto bg-background p-6 text-center\",\n view === \"avatar\" ? \"flex\" : \"hidden\",\n )}\n >\n {avatar.live ? (\n <ExploreAvatarLive\n live={avatar.live}\n active={open && view === \"avatar\"}\n locale={resolvedLocale}\n productName={pinnedName}\n still={{ src: avatar.src, alt: avatarAlt }}\n fallback={comingSoon}\n onContinueInChat={continueInChat}\n />\n ) : (\n comingSoon\n )}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n","/**\n * SiteAssistantDock — the site-wide assistant in one component (BOFF-9797).\n *\n * What HealthyBowl built by hand for its website (BOFF-9697, BOFF-9796), so every product site gets it with a few\n * lines: the floating `ExploreCta`, which opens an `ExplorePanel` over the current page instead of navigating, and\n * that panel, with the site's product scope and its avatar (the still picture, and the live avatar when the site passes\n * `avatar.live`).\n *\n * - **Still a link.** The button is a real `<a href=\"/explore\">`: a modified click (new tab, new window) and a visitor\n * without JavaScript reach the page; a plain click opens the panel in place.\n * - **One conversation.** The panel shows the `ExploreChatProvider`'s conversation, the same one `/explore` shows, so\n * Expand and Restore, closing and reopening, and going to `/explore` and back all keep it. The dock starts the\n * provider's conversation on the visitor's first opening, so nothing is asked of a server before that.\n * - **Escape and the phone's Back** go expanded, then compact, then closed, through the panel's own history entries\n * (the same URL, so the host's router stays where it is). Closing stops the microphone and reading aloud. Focus goes\n * back to the button, which says which panel it opens (`aria-controls`) and whether it is open (`aria-expanded`).\n * - **Hidden on `/explore`** (`explorePath`), where the page itself is the assistant: no button, and the panel hidden.\n * An open panel shows again when the visitor leaves `/explore`.\n * - **Never under or over the host's bottom bar:** `bottomOffset` (a cookie banner's height) is kept clear by the panel,\n * and the button rides that much higher, so a banner still on screen covers neither.\n *\n * Needs an `ExploreChatProvider` above it (inside the router, around the routes). Without one a development build\n * throws; a production build logs an error and renders the plain floating link to `/explore` that sites had before.\n * Render ONE dock per page: in the layout every route shares, or beside the routes. A second dock mounted while one is\n * already there renders nothing, in every build (a development build also logs an error), so a page never has two\n * panels with the same id or two sets of history steps; if the first one unmounts, the second takes over.\n *\n * @example\n * ```tsx\n * import { SiteAssistantDock } from '@burdenoff/website-sdk'\n *\n * <SiteAssistantDock\n * productSlug=\"healthybowl\"\n * scope=\"product\"\n * productName=\"Healthy Bowl\"\n * examplePrompts={prompts}\n * avatar={{ src: '/avatar-faces/av_stock_001.webp', live: AVATAR_LIVE }}\n * currentPath={pathname}\n * onNavigate={(path) => navigate(path)}\n * bottomOffset=\"var(--hb-cookie-banner-height, 0px)\"\n * />\n * ```\n */\n\"use client\";\n\nimport {\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { ExploreConversationStartContext } from \"./explore-conversation\";\nimport { ExploreCta } from \"./explore-cta\";\nimport { ExplorePanel, type ExplorePanelAvatar } from \"./explore-panel\";\nimport { useCurrentPath } from \"./explore-route\";\nimport { isDevelopmentBuild, type ExploreScope } from \"./explore-scope\";\nimport { normalizeRoutePath } from \"../utils/site-chrome\";\n\nexport interface SiteAssistantDockProps {\n /** The site's product, as the platform knows it (`healthybowl`). Passed to the panel's chat. */\n productSlug?: string;\n /** `product` (with `productSlug`) makes the panel this product's own assistant. See `ExplorePanelProps.scope`. */\n scope?: ExploreScope;\n /** The product's display name in the `product` scope (\"Healthy Bowl\"). See `ExplorePanelProps.productName`. */\n productName?: string;\n /** The panel's example prompts; in the `product` scope the only ones it shows. See `ExplorePanelProps`. */\n examplePrompts?: string[];\n /** The assistant's locale. Default: the SDK's own resolution, as on `ExplorePanel`. */\n locale?: string;\n /**\n * The Avatar view: the approved still picture, plus `live` to opt in to the live avatar (see `websiteAvatarLive`).\n * Absent: the panel has no Avatar view and no tabs.\n */\n avatar?: ExplorePanelAvatar;\n /**\n * The host router's navigate, for links in the conversation (and, without a provider in production, for the\n * button's link to `/explore`). Absent: links load the page normally.\n */\n onNavigate?: (path: string) => void;\n /**\n * A CSS length kept clear at the bottom of the window: the site's own cookie banner's height, from the CSS variable\n * that banner publishes (HealthyBowl's is `var(--hb-cookie-banner-height, 0px)`; there is no SDK-wide variable). The\n * panel keeps it clear and the floating button sits that much higher, so a banner still on screen covers neither.\n * Default `0px`: the button at its usual place.\n */\n bottomOffset?: string;\n /** Extra classes for the floating button (the launcher). */\n className?: string;\n /** Extra classes for the panel. */\n panelClassName?: string;\n /**\n * The current route, from the host's router (`useLocation().pathname`). Falls back to `window.location.pathname`,\n * which cannot see a router's `pushState` navigations: pass it.\n */\n currentPath?: string;\n /**\n * The site's Explore route. Default `/explore`. The button links there, the dock hides on it (matched as the router\n * does: ignoring case and a trailing slash), and the panel makes its share links to it.\n */\n explorePath?: string;\n /** The button's visible label and accessible name. Default `Ask AI`. */\n label?: string;\n /** The panel's id, for the button's `aria-controls`. Default `boff-explore-panel`. */\n id?: string;\n /** The panel's `z-index`. Default 50 (see `ExplorePanelProps.zIndex`). */\n zIndex?: number;\n}\n\n/** Said once per page load, in a production build, when the dock has no provider. */\nlet reportedMissingProvider = false;\n\n/**\n * The docks mounted now, in mount order. Only the first renders: a second would be a second panel with the same id and\n * its own history steps. The others render nothing, and the next in line takes over when the first unmounts.\n */\nconst mountedDocks: string[] = [];\nconst dockListeners = new Set<() => void>();\n\n/** The dock that renders, or `null` when none is mounted (yet). */\nfunction activeDock(): string | null {\n return mountedDocks[0] ?? null;\n}\n\nfunction announceActiveDock(): void {\n for (const listener of dockListeners) listener();\n}\n\n/** A layout effect in the browser, so a second dock is gone before the first paint; nothing runs on a server. */\nconst useBrowserLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\n/** Said in a development build when a dock mounts while another is already mounted. */\nexport const SITE_ASSISTANT_DOCK_MORE_THAN_ONE =\n \"[WebSDK] More than one SiteAssistantDock is mounted: only the first renders, the others render nothing. \" +\n \"Render one, in the layout every route shares.\";\n\n/**\n * Whether this dock is the one that renders. A dock mounted while another is there renders nothing from its first\n * render; docks mounted in the same commit (or hydrated from a server render, where every dock renders) settle in the\n * layout effect, before the browser paints.\n */\nfunction useIsActiveDock(): boolean {\n const id = useId();\n const [active, setActive] = useState<string | null>(activeDock);\n useBrowserLayoutEffect(() => {\n const listener = () => setActive(activeDock());\n dockListeners.add(listener);\n mountedDocks.push(id);\n if (mountedDocks.length > 1 && isDevelopmentBuild()) {\n console.error(SITE_ASSISTANT_DOCK_MORE_THAN_ONE);\n }\n announceActiveDock();\n return () => {\n dockListeners.delete(listener);\n const at = mountedDocks.indexOf(id);\n if (at !== -1) mountedDocks.splice(at, 1);\n announceActiveDock();\n };\n }, [id]);\n return active === null || active === id;\n}\n\n/** What a missing provider is told, in a development build (thrown) and in production (logged). */\nexport const SITE_ASSISTANT_DOCK_NEEDS_PROVIDER =\n \"[WebSDK] SiteAssistantDock must be rendered under an ExploreChatProvider (inside the router, around the routes). \" +\n \"Without one the panel cannot share the /explore conversation, and the live avatar cannot run.\";\n\nexport function SiteAssistantDock(props: SiteAssistantDockProps) {\n const start = useContext(ExploreConversationStartContext);\n const active = useIsActiveDock();\n if (start === null) {\n if (isDevelopmentBuild())\n throw new Error(SITE_ASSISTANT_DOCK_NEEDS_PROVIDER);\n return active ? <DockWithoutProvider {...props} /> : null;\n }\n if (!active) return null;\n return <Dock {...props} start={start} />;\n}\n\n/** Production without a provider: the plain link to `/explore` every site had before the dock, and an error logged. */\nfunction DockWithoutProvider({\n className,\n currentPath,\n explorePath = \"/explore\",\n label,\n onNavigate,\n bottomOffset,\n}: SiteAssistantDockProps) {\n useEffect(() => {\n if (reportedMissingProvider) return;\n reportedMissingProvider = true;\n console.error(SITE_ASSISTANT_DOCK_NEEDS_PROVIDER);\n }, []);\n return (\n <ExploreCta\n variant=\"floating\"\n href={explorePath}\n label={label}\n currentPath={currentPath}\n onNavigate={onNavigate}\n bottomOffset={bottomOffset}\n className={className}\n />\n );\n}\n\nfunction Dock({\n start,\n productSlug,\n scope,\n productName,\n examplePrompts,\n locale,\n avatar,\n onNavigate,\n bottomOffset,\n className,\n panelClassName,\n currentPath,\n explorePath = \"/explore\",\n label,\n id = \"boff-explore-panel\",\n zIndex,\n}: SiteAssistantDockProps & { start: () => void }) {\n // The router's path when the host passes it (at once, on the render that changes it); otherwise the window's, which\n // is read after the first render so a server render and a prerender match the first client render.\n const observedPath = useCurrentPath(currentPath);\n const path = currentPath ?? observedPath;\n const onExplore =\n path !== null &&\n normalizeRoutePath(path) === normalizeRoutePath(explorePath);\n\n const [open, setOpen] = useState(false);\n const launcherRef = useRef<HTMLAnchorElement>(null);\n\n const changeOpen = useCallback(\n (next: boolean) => {\n // The provider's latch: the conversation starts on the first opening and stays live after it.\n if (next) start();\n setOpen(next);\n },\n [start],\n );\n const openPanel = useCallback(() => changeOpen(true), [changeOpen]);\n\n // On /explore the page is the assistant: the panel hides (and shows again on the way out), and the button goes.\n const showing = open && !onExplore;\n\n return (\n <>\n {onExplore ? null : (\n <ExploreCta\n ref={launcherRef}\n variant=\"floating\"\n href={explorePath}\n label={label}\n currentPath={path ?? undefined}\n onNavigate={openPanel}\n expanded={showing}\n controls={id}\n bottomOffset={bottomOffset}\n className={className}\n />\n )}\n <ExplorePanel\n id={id}\n open={showing}\n onOpenChange={changeOpen}\n productSlug={productSlug}\n scope={scope}\n productName={productName}\n examplePrompts={examplePrompts}\n locale={locale}\n onNavigate={onNavigate}\n explorePath={explorePath}\n avatar={avatar}\n bottomOffset={bottomOffset}\n zIndex={zIndex}\n returnFocusRef={launcherRef}\n className={panelClassName}\n />\n </>\n );\n}\n","/**\n * BOFF-9797. A product website's live-avatar opt-in (`avatar.live` on `ExplorePanel` / `SiteAssistantDock`), decided\n * from its build: which environment it is built for, and the Cloudflare Turnstile site key it was given.\n *\n * Pure: no React, no network, no globals. A site calls it once, at module scope, with its build's values:\n *\n * ```ts\n * export const AVATAR_LIVE = websiteAvatarLive({\n * deployEnv: import.meta.env.VITE_DEPLOY_ENV,\n * siteKey: import.meta.env.VITE_AVATAR_TURNSTILE_SITE_KEY,\n * site: 'healthybowl',\n * manifestVersion: manifest.version,\n * load: () => import('@burdenoff/website-sdk/avatar-live'),\n * })\n * ```\n *\n * The server decides whether the live avatar is offered on the site (its reviewed site list, its pause and its caps),\n * and whether it checks for bots (its availability's `botCheck`, contract v1.2). The key matters only when it does. The\n * rule, so that a misconfigured build shows the still picture instead of a live avatar whose bot check can never pass,\n * or always passes:\n *\n * - `enabled: false`: `undefined` (the still picture, \"Live avatar coming soon\"), whatever else is set.\n * - No key, or an empty one: the live config without a key. The server decides: a server that runs no bot check offers\n * the live avatar, one that checks for bots (or a site it does not list) leaves the still picture.\n * - Alpha (`deployEnv` `alpha`): Cloudflare's always-pass test key `1x00000000000000000000AA` (the alpha gateway runs\n * Turnstile in dummy mode with the matching test secret), or a real-looking key.\n * - Every other environment, production included, and an unset one: a real-looking key only. Cloudflare's test keys\n * (`1x…AA`, `2x…AB`, `1x…BB`, `2x…BB`, `3x…FF`, and anything of their shape) are refused.\n * - A key that is set but refused: `undefined`, the still picture, never a live avatar without the key it was given.\n */\nimport {\n isRealTurnstileSiteKey,\n type ExplorePanelAvatarLive,\n} from \"./explore-avatar-live-config\";\n\nexport interface WebsiteAvatarLiveOptions {\n /** The environment the site is built for: `import.meta.env.VITE_DEPLOY_ENV` (`alpha`, `production`, …). */\n deployEnv: string | null | undefined;\n /**\n * The site's Turnstile site key: `import.meta.env.VITE_AVATAR_TURNSTILE_SITE_KEY`. Unset or empty: no key, and the\n * live avatar runs only where the server runs no bot check.\n */\n siteKey: string | null | undefined;\n /** The site, as the live avatar service knows it (`healthybowl`). */\n site: string;\n /** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */\n manifestVersion: string;\n /** Loads the live avatar's room module: `() => import('@burdenoff/website-sdk/avatar-live')`. */\n load: ExplorePanelAvatarLive[\"load\"];\n /** False keeps the still picture on this build, whatever the server offers. Default true. */\n enabled?: boolean;\n}\n\n/**\n * Cloudflare's always-pass, visible test site key. Accepted on alpha only.\n * https://developers.cloudflare.com/turnstile/troubleshooting/testing/\n */\nconst ALPHA_TEST_SITE_KEY = \"1x00000000000000000000AA\";\n\n/** The `avatar.live` prop for this build, or `undefined` for the still picture only. */\nexport function websiteAvatarLive({\n deployEnv,\n siteKey,\n site,\n manifestVersion,\n load,\n enabled,\n}: WebsiteAvatarLiveOptions): ExplorePanelAvatarLive | undefined {\n if (enabled === false) return undefined;\n const alpha =\n typeof deployEnv === \"string\" && deployEnv.trim().toLowerCase() === \"alpha\";\n const live: ExplorePanelAvatarLive = {\n site,\n load,\n manifestVersion,\n allowTestSiteKey: alpha,\n };\n const key = typeof siteKey === \"string\" ? siteKey.trim() : \"\";\n if (key === \"\") return live;\n const accepted = alpha\n ? key === ALPHA_TEST_SITE_KEY || isRealTurnstileSiteKey(key)\n : isRealTurnstileSiteKey(key);\n if (!accepted) return undefined;\n return { ...live, turnstileSiteKey: key };\n}\n"]}