@burdenoff/website-sdk 2026.829.8 → 2026.921.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 (60) hide show
  1. package/README.md +112 -1
  2. package/dist/components/contact.js +4 -1
  3. package/dist/components/contact.js.map +1 -1
  4. package/dist/components/contact.mjs +4 -1
  5. package/dist/components/contact.mjs.map +1 -1
  6. package/dist/components/explore.d.mts +14 -1
  7. package/dist/components/explore.d.ts +14 -1
  8. package/dist/components/explore.js +217 -43
  9. package/dist/components/explore.js.map +1 -1
  10. package/dist/components/explore.mjs +217 -45
  11. package/dist/components/explore.mjs.map +1 -1
  12. package/dist/components/newsletter.js +4 -1
  13. package/dist/components/newsletter.js.map +1 -1
  14. package/dist/components/newsletter.mjs +4 -1
  15. package/dist/components/newsletter.mjs.map +1 -1
  16. package/dist/components/partners.js +23 -13
  17. package/dist/components/partners.js.map +1 -1
  18. package/dist/components/partners.mjs +23 -13
  19. package/dist/components/partners.mjs.map +1 -1
  20. package/dist/components/pricing.js +4 -1
  21. package/dist/components/pricing.js.map +1 -1
  22. package/dist/components/pricing.mjs +4 -1
  23. package/dist/components/pricing.mjs.map +1 -1
  24. package/dist/components/unsubscribe.js +4 -1
  25. package/dist/components/unsubscribe.js.map +1 -1
  26. package/dist/components/unsubscribe.mjs +4 -1
  27. package/dist/components/unsubscribe.mjs.map +1 -1
  28. package/dist/components/waitlist.js +4 -1
  29. package/dist/components/waitlist.js.map +1 -1
  30. package/dist/components/waitlist.mjs +4 -1
  31. package/dist/components/waitlist.mjs.map +1 -1
  32. package/dist/content/index.js +23 -13
  33. package/dist/content/index.js.map +1 -1
  34. package/dist/content/index.mjs +23 -13
  35. package/dist/content/index.mjs.map +1 -1
  36. package/dist/{use-explore-chat-BzXCz2UM.d.mts → explore-types-CLw19R76.d.mts} +1 -131
  37. package/dist/{use-explore-chat-BzXCz2UM.d.ts → explore-types-CLw19R76.d.ts} +1 -131
  38. package/dist/hooks/index.d.mts +2 -1
  39. package/dist/hooks/index.d.ts +2 -1
  40. package/dist/hooks/index.js +23 -7
  41. package/dist/hooks/index.js.map +1 -1
  42. package/dist/hooks/index.mjs +23 -7
  43. package/dist/hooks/index.mjs.map +1 -1
  44. package/dist/index.d.mts +143 -3
  45. package/dist/index.d.ts +143 -3
  46. package/dist/index.js +1552 -207
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +1548 -210
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/seo/index.js +4 -1
  51. package/dist/seo/index.js.map +1 -1
  52. package/dist/seo/index.mjs +4 -1
  53. package/dist/seo/index.mjs.map +1 -1
  54. package/dist/store/index.js +23 -13
  55. package/dist/store/index.js.map +1 -1
  56. package/dist/store/index.mjs +23 -13
  57. package/dist/store/index.mjs.map +1 -1
  58. package/dist/use-explore-chat-CvW-kyIm.d.mts +145 -0
  59. package/dist/use-explore-chat-DdGBimiz.d.ts +145 -0
  60. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -507,6 +507,9 @@ function resolveImageUrl(image, base) {
507
507
  return image;
508
508
  }
509
509
  }
510
+ function serializeJsonLd(data) {
511
+ return JSON.stringify(data).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
512
+ }
510
513
  function PageHead({
511
514
  title,
512
515
  description,
@@ -548,7 +551,7 @@ function PageHead({
548
551
  fullImageUrl && /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:image", content: fullImageUrl }),
549
552
  twitterHandle && /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "twitter:creator", content: twitterHandle }),
550
553
  /* @__PURE__ */ jsxRuntime.jsx("meta", { name: "theme-color", content: themeColor }),
551
- structuredDataItems.map((data, index) => /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: JSON.stringify(data) }, `ld-${index}`)),
554
+ structuredDataItems.map((data, index) => /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: serializeJsonLd(data) }, `ld-${index}`)),
552
555
  additionalMeta?.map((meta, index) => /* @__PURE__ */ jsxRuntime.jsx(
553
556
  "meta",
554
557
  {
@@ -1108,19 +1111,26 @@ function ContactPage({
1108
1111
  ] }) })
1109
1112
  ] });
1110
1113
  }
1114
+ function MarkdownLink({
1115
+ href,
1116
+ children,
1117
+ // react-markdown passes the hast node to every override; it is not a DOM attribute.
1118
+ node: _node,
1119
+ ...props
1120
+ }) {
1121
+ const isExternal = typeof href === "string" && (href.startsWith("http://") || href.startsWith("https://"));
1122
+ return /* @__PURE__ */ jsxRuntime.jsx(
1123
+ "a",
1124
+ {
1125
+ href,
1126
+ ...props,
1127
+ ...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : { rel: "noopener noreferrer" },
1128
+ children
1129
+ }
1130
+ );
1131
+ }
1111
1132
  var defaultComponents = {
1112
- a: ({ href, children, ...props }) => {
1113
- const isExternal = typeof href === "string" && (href.startsWith("http://") || href.startsWith("https://"));
1114
- return /* @__PURE__ */ jsxRuntime.jsx(
1115
- "a",
1116
- {
1117
- href,
1118
- ...props,
1119
- ...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : { rel: "noopener noreferrer" },
1120
- children
1121
- }
1122
- );
1123
- }
1133
+ a: MarkdownLink
1124
1134
  };
1125
1135
  function Markdown({
1126
1136
  children,
@@ -4766,171 +4776,1346 @@ function ElectronDownloadLink({
4766
4776
  );
4767
4777
  }
4768
4778
 
4769
- // src/components/explore-i18n.ts
4770
- var EXPLORE_LOCALES = ["en", "zh", "hi", "es", "ar", "ta"];
4771
- var RTL_LOCALES = /* @__PURE__ */ new Set(["ar"]);
4772
- function isRtlLocale(locale) {
4773
- return RTL_LOCALES.has(locale);
4779
+ // src/components/concepts-types.ts
4780
+ var CONCEPT_ILLUSTRATION_NOTICE = "These images are illustrations of the concept, not screenshots of the actual product.";
4781
+ var CONCEPTS_PATH = "/concepts";
4782
+ var CONCEPT_PATH_PREFIX = "/concept";
4783
+ function conceptPath(slug) {
4784
+ return `${CONCEPT_PATH_PREFIX}/${encodeURIComponent(slug)}`;
4785
+ }
4786
+ function getConceptBySlug(concepts, slug) {
4787
+ if (!slug) return void 0;
4788
+ const wanted = slug.trim().toLowerCase();
4789
+ if (!wanted) return void 0;
4790
+ return concepts.find((concept) => concept.slug === wanted);
4791
+ }
4792
+ var NAV_BUTTON = "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";
4793
+ function ConceptLightbox({
4794
+ images,
4795
+ index,
4796
+ conceptTitle,
4797
+ onIndexChange,
4798
+ onClose
4799
+ }) {
4800
+ const dialogRef = React.useRef(null);
4801
+ const closeRef = React.useRef(null);
4802
+ const nativeModalRef = React.useRef(false);
4803
+ const titleId = React.useId();
4804
+ const count = images.length;
4805
+ const position = count > 0 ? (index % count + count) % count : 0;
4806
+ const image = images[position];
4807
+ React.useEffect(() => {
4808
+ const dialog = dialogRef.current;
4809
+ if (!dialog) return;
4810
+ if (typeof dialog.showModal === "function") {
4811
+ if (!dialog.open) dialog.showModal();
4812
+ nativeModalRef.current = true;
4813
+ } else {
4814
+ dialog.setAttribute("open", "");
4815
+ nativeModalRef.current = false;
4816
+ }
4817
+ closeRef.current?.focus();
4818
+ return () => {
4819
+ if (dialog.open && typeof dialog.close === "function") dialog.close();
4820
+ };
4821
+ }, []);
4822
+ const go = React.useCallback(
4823
+ (delta) => {
4824
+ if (count < 2) return;
4825
+ onIndexChange((position + delta + count) % count);
4826
+ },
4827
+ [count, onIndexChange, position]
4828
+ );
4829
+ const handleClose = React.useCallback(
4830
+ (event) => {
4831
+ if (event.currentTarget.open) return;
4832
+ onClose();
4833
+ },
4834
+ [onClose]
4835
+ );
4836
+ const handleKeyDown = React.useCallback(
4837
+ (event) => {
4838
+ if (event.key === "ArrowRight") {
4839
+ event.preventDefault();
4840
+ go(1);
4841
+ } else if (event.key === "ArrowLeft") {
4842
+ event.preventDefault();
4843
+ go(-1);
4844
+ } else if (event.key === "Escape" && !nativeModalRef.current) {
4845
+ event.preventDefault();
4846
+ onClose();
4847
+ }
4848
+ },
4849
+ [go, onClose]
4850
+ );
4851
+ const handleStageClick = React.useCallback(
4852
+ (event) => {
4853
+ if (event.target === event.currentTarget) onClose();
4854
+ },
4855
+ [onClose]
4856
+ );
4857
+ if (!image) return null;
4858
+ return /* @__PURE__ */ jsxRuntime.jsx(
4859
+ "dialog",
4860
+ {
4861
+ ref: dialogRef,
4862
+ "data-concepts": "lightbox",
4863
+ "aria-labelledby": titleId,
4864
+ onClose: handleClose,
4865
+ onKeyDown: handleKeyDown,
4866
+ 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",
4867
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-full flex-col", children: [
4868
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-border px-4 py-3 sm:px-6", children: [
4869
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
4870
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "truncate text-xs font-medium uppercase tracking-wide text-muted-foreground", children: [
4871
+ conceptTitle,
4872
+ count > 1 ? ` \xB7 ${position + 1} / ${count}` : null
4873
+ ] }),
4874
+ /* @__PURE__ */ jsxRuntime.jsx(
4875
+ "h2",
4876
+ {
4877
+ id: titleId,
4878
+ className: "truncate text-base font-semibold text-foreground sm:text-lg",
4879
+ children: image.title
4880
+ }
4881
+ )
4882
+ ] }),
4883
+ /* @__PURE__ */ jsxRuntime.jsx(
4884
+ "button",
4885
+ {
4886
+ ref: closeRef,
4887
+ type: "button",
4888
+ onClick: onClose,
4889
+ "aria-label": "Close",
4890
+ "data-concepts": "lightbox-close",
4891
+ 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",
4892
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true", className: "h-5 w-5" })
4893
+ }
4894
+ )
4895
+ ] }),
4896
+ /* @__PURE__ */ jsxRuntime.jsxs(
4897
+ "div",
4898
+ {
4899
+ className: "relative flex flex-1 items-center justify-center px-4 py-4 sm:px-20",
4900
+ onClick: handleStageClick,
4901
+ children: [
4902
+ /* @__PURE__ */ jsxRuntime.jsx(
4903
+ "img",
4904
+ {
4905
+ src: image.src,
4906
+ alt: image.alt,
4907
+ width: image.width,
4908
+ height: image.height,
4909
+ decoding: "async",
4910
+ className: "h-auto max-h-[calc(100vh-14rem)] w-auto max-w-full rounded-lg border border-border bg-muted object-contain shadow-lg"
4911
+ },
4912
+ image.key
4913
+ ),
4914
+ count > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4915
+ /* @__PURE__ */ jsxRuntime.jsx(
4916
+ "button",
4917
+ {
4918
+ type: "button",
4919
+ onClick: () => go(-1),
4920
+ "aria-label": "Previous illustration",
4921
+ "data-concepts": "lightbox-prev",
4922
+ className: `absolute left-2 top-1/2 -translate-y-1/2 sm:left-4 ${NAV_BUTTON}`,
4923
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "h-5 w-5" })
4924
+ }
4925
+ ),
4926
+ /* @__PURE__ */ jsxRuntime.jsx(
4927
+ "button",
4928
+ {
4929
+ type: "button",
4930
+ onClick: () => go(1),
4931
+ "aria-label": "Next illustration",
4932
+ "data-concepts": "lightbox-next",
4933
+ className: `absolute right-2 top-1/2 -translate-y-1/2 sm:right-4 ${NAV_BUTTON}`,
4934
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-5 w-5" })
4935
+ }
4936
+ )
4937
+ ] }) : null
4938
+ ]
4939
+ }
4940
+ ),
4941
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border px-4 py-3 sm:px-6", children: [
4942
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed text-foreground", children: image.caption }),
4943
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1.5 flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground", children: [
4944
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { "aria-hidden": "true", className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
4945
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: CONCEPT_ILLUSTRATION_NOTICE })
4946
+ ] })
4947
+ ] })
4948
+ ] })
4949
+ }
4950
+ );
4774
4951
  }
4775
- var EN = {
4776
- badge: "AI answers, grounded in our documentation",
4777
- welcomeTitle: "Ask anything about our products",
4778
- welcomeBody: "Describe what you are trying to do and I will point you at the product, the page and the next step.",
4779
- tryAsking: "Try asking",
4780
- focusProduct: "Focus on a product",
4781
- allProducts: "All products",
4782
- showAll: "All",
4783
- showLess: "Show less",
4784
- sources: "Sources",
4785
- nextYouCouldAsk: "Next you could ask",
4786
- placeholder: "Ask anything about our products\u2026",
4787
- placeholderProduct: "Ask about {product}\u2026",
4788
- send: "Send",
4789
- stop: "Stop",
4790
- newChat: "New chat",
4791
- history: "History",
4792
- clearHistory: "Clear history",
4793
- share: "Share",
4794
- copied: "Copied",
4795
- copying: "Copying\u2026",
4796
- shareUnavailable: "Unavailable",
4797
- disclaimer: "Disclaimer",
4798
- disclaimerShort: "Grounded in our docs \u2014 check anything important.",
4799
- dictate: "Dictate your question",
4800
- stopDictating: "Stop dictating",
4801
- attach: "Attach files",
4802
- attachHint: "Up to {{max}} files, {{size}} MB each",
4803
- removeAttachment: "Remove {{name}}",
4804
- attachmentNameOnly: "name and type only",
4805
- attachmentTooLarge: "{{name}} is larger than {{size}} MB and was not attached.",
4806
- attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
4807
- noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
4808
- askHuman: "ask a human",
4809
- prevSuggestion: "Previous suggestion",
4810
- nextSuggestion: "Next suggestion",
4811
- capabilities: [
4812
- "Grounded in our own docs",
4813
- "Compare across the ecosystem",
4814
- "Straight to the right page"
4815
- ],
4816
- prompts: [
4817
- "What does this product actually do?",
4818
- "Which product fits my team?",
4819
- "How do I get started, step by step?",
4820
- "How much does it cost?"
4821
- ]
4822
- };
4823
- var ZH = {
4824
- badge: "\u57FA\u4E8E\u6211\u4EEC\u6587\u6863\u7684 AI \u56DE\u7B54",
4825
- welcomeTitle: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE",
4826
- welcomeBody: "\u63CF\u8FF0\u4F60\u60F3\u505A\u7684\u4E8B\uFF0C\u6211\u4F1A\u4E3A\u4F60\u6307\u51FA\u5BF9\u5E94\u7684\u4EA7\u54C1\u3001\u9875\u9762\u548C\u4E0B\u4E00\u6B65\u3002",
4827
- tryAsking: "\u8BD5\u7740\u95EE",
4828
- focusProduct: "\u805A\u7126\u67D0\u4E2A\u4EA7\u54C1",
4829
- allProducts: "\u5168\u90E8\u4EA7\u54C1",
4830
- showAll: "\u5168\u90E8",
4831
- showLess: "\u6536\u8D77",
4832
- sources: "\u6765\u6E90",
4833
- nextYouCouldAsk: "\u4F60\u8FD8\u53EF\u4EE5\u95EE",
4834
- placeholder: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE\u2026",
4835
- placeholderProduct: "\u8BE2\u95EE\u5173\u4E8E {product} \u7684\u95EE\u9898\u2026",
4836
- send: "\u53D1\u9001",
4837
- stop: "\u505C\u6B62",
4838
- newChat: "\u65B0\u5BF9\u8BDD",
4839
- history: "\u5386\u53F2",
4840
- clearHistory: "\u6E05\u9664\u5386\u53F2",
4841
- share: "\u5206\u4EAB",
4842
- copied: "\u5DF2\u590D\u5236",
4843
- copying: "\u590D\u5236\u4E2D\u2026",
4844
- shareUnavailable: "\u4E0D\u53EF\u7528",
4845
- disclaimer: "\u514D\u8D23\u58F0\u660E",
4846
- disclaimerShort: "\u5185\u5BB9\u57FA\u4E8E\u6211\u4EEC\u7684\u6587\u6863\uFF0C\u91CD\u8981\u4FE1\u606F\u8BF7\u81EA\u884C\u6838\u5BF9\u3002",
4847
- dictate: "\u8BED\u97F3\u8F93\u5165",
4848
- stopDictating: "\u505C\u6B62\u8BED\u97F3\u8F93\u5165",
4849
- attach: "\u6DFB\u52A0\u6587\u4EF6",
4850
- attachHint: "\u6700\u591A {{max}} \u4E2A\u6587\u4EF6\uFF0C\u6BCF\u4E2A\u4E0D\u8D85\u8FC7 {{size}} MB",
4851
- removeAttachment: "\u79FB\u9664 {{name}}",
4852
- attachmentNameOnly: "\u4EC5\u6587\u4EF6\u540D\u548C\u7C7B\u578B",
4853
- attachmentTooLarge: "{{name}} \u8D85\u8FC7 {{size}} MB\uFF0C\u672A\u80FD\u6DFB\u52A0\u3002",
4854
- attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
4855
- noAnswer: "\u6211\u5728\u6587\u6863\u4E2D\u6CA1\u6709\u627E\u5230\u76F8\u5173\u5185\u5BB9\uFF0C\u4E0B\u9762\u7684\u56DE\u7B54\u6CA1\u6709\u6765\u6E90\u652F\u6301\u3002\u8BF7\u6362\u4E2A\u8BF4\u6CD5\uFF0C\u6216",
4856
- askHuman: "\u8054\u7CFB\u6211\u4EEC",
4857
- prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
4858
- nextSuggestion: "\u4E0B\u4E00\u4E2A\u5EFA\u8BAE",
4859
- capabilities: ["\u57FA\u4E8E\u6211\u4EEC\u81EA\u5DF1\u7684\u6587\u6863", "\u8DE8\u4EA7\u54C1\u5BF9\u6BD4", "\u76F4\u8FBE\u6B63\u786E\u7684\u9875\u9762"],
4860
- prompts: [
4861
- "\u8FD9\u4E2A\u4EA7\u54C1\u5230\u5E95\u80FD\u505A\u4EC0\u4E48\uFF1F",
4862
- "\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u7684\u56E2\u961F\uFF1F",
4863
- "\u5982\u4F55\u4E00\u6B65\u6B65\u5F00\u59CB\u4F7F\u7528\uFF1F",
4864
- "\u4EF7\u683C\u662F\u591A\u5C11\uFF1F"
4865
- ]
4866
- };
4867
- var HI = {
4868
- badge: "\u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 AI \u0909\u0924\u094D\u0924\u0930",
4869
- welcomeTitle: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902",
4870
- welcomeBody: "\u092C\u0924\u093E\u0907\u090F \u0906\u092A \u0915\u094D\u092F\u093E \u0915\u0930\u0928\u093E \u091A\u093E\u0939\u0924\u0947 \u0939\u0948\u0902, \u0914\u0930 \u092E\u0948\u0902 \u0906\u092A\u0915\u094B \u0938\u0939\u0940 \u0909\u0924\u094D\u092A\u093E\u0926, \u092A\u0947\u091C \u0914\u0930 \u0905\u0917\u0932\u093E \u0915\u0926\u092E \u092C\u0924\u093E\u090A\u0901\u0917\u093E\u0964",
4871
- tryAsking: "\u092F\u0939 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902",
4872
- focusProduct: "\u0915\u093F\u0938\u0940 \u0909\u0924\u094D\u092A\u093E\u0926 \u092A\u0930 \u0927\u094D\u092F\u093E\u0928 \u0926\u0947\u0902",
4873
- allProducts: "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926",
4874
- showAll: "\u0938\u092D\u0940",
4875
- showLess: "\u0915\u092E \u0926\u093F\u0916\u093E\u090F\u0901",
4876
- sources: "\u0938\u094D\u0930\u094B\u0924",
4877
- nextYouCouldAsk: "\u0906\u0917\u0947 \u0906\u092A \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902",
4878
- placeholder: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902\u2026",
4879
- placeholderProduct: "{product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
4880
- send: "\u092D\u0947\u091C\u0947\u0902",
4881
- stop: "\u0930\u094B\u0915\u0947\u0902",
4882
- newChat: "\u0928\u0908 \u092C\u093E\u0924\u091A\u0940\u0924",
4883
- history: "\u0907\u0924\u093F\u0939\u093E\u0938",
4884
- clearHistory: "\u0907\u0924\u093F\u0939\u093E\u0938 \u092E\u093F\u091F\u093E\u090F\u0901",
4885
- share: "\u0938\u093E\u091D\u093E \u0915\u0930\u0947\u0902",
4886
- copied: "\u0915\u0949\u092A\u0940 \u0939\u094B \u0917\u092F\u093E",
4887
- copying: "\u0915\u0949\u092A\u0940 \u0939\u094B \u0930\u0939\u093E \u0939\u0948\u2026",
4888
- shareUnavailable: "\u0909\u092A\u0932\u092C\u094D\u0927 \u0928\u0939\u0940\u0902",
4889
- disclaimer: "\u0905\u0938\u094D\u0935\u0940\u0915\u0930\u0923",
4890
- disclaimerShort: "\u092F\u0939 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948 \u2014 \u092E\u0939\u0924\u094D\u0935\u092A\u0942\u0930\u094D\u0923 \u092C\u093E\u0924\u0947\u0902 \u091C\u093C\u0930\u0942\u0930 \u091C\u093E\u0901\u091A \u0932\u0947\u0902\u0964",
4891
- dictate: "\u092C\u094B\u0932\u0915\u0930 \u092A\u0942\u091B\u0947\u0902",
4892
- stopDictating: "\u092C\u094B\u0932\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
4893
- attach: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0947\u0902",
4894
- attachHint: "\u0905\u0927\u093F\u0915\u0924\u092E {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902, \u092A\u094D\u0930\u0924\u094D\u092F\u0947\u0915 {{size}} MB \u0924\u0915",
4895
- removeAttachment: "{{name}} \u0939\u091F\u093E\u090F\u0901",
4896
- attachmentNameOnly: "\u0915\u0947\u0935\u0932 \u0928\u093E\u092E \u0914\u0930 \u092A\u094D\u0930\u0915\u093E\u0930",
4897
- attachmentTooLarge: "{{name}} {{size}} MB \u0938\u0947 \u092C\u0921\u093C\u0940 \u0939\u0948, \u0907\u0938\u0932\u093F\u090F \u091C\u094B\u0921\u093C\u0940 \u0928\u0939\u0940\u0902 \u0917\u0908\u0964",
4898
- attachmentTooMany: "\u0915\u0947\u0935\u0932 {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0940 \u091C\u093E \u0938\u0915\u0924\u0940 \u0939\u0948\u0902, \u0907\u0938\u0932\u093F\u090F {{name}} \u091B\u094B\u0921\u093C \u0926\u0940 \u0917\u0908\u0964",
4899
- noAnswer: "\u092F\u0939 \u092E\u0941\u091D\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092E\u0947\u0902 \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E, \u0907\u0938\u0932\u093F\u090F \u0928\u0940\u091A\u0947 \u0926\u093F\u092F\u093E \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938\u0940 \u0938\u094D\u0930\u094B\u0924 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964 \u0926\u0942\u0938\u0930\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902, \u092F\u093E",
4900
- askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
4901
- prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
4902
- nextSuggestion: "\u0905\u0917\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
4903
- capabilities: [
4904
- "\u0939\u092E\u093E\u0930\u0947 \u0905\u092A\u0928\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924",
4905
- "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930\u0947\u0902",
4906
- "\u0938\u0940\u0927\u0947 \u0938\u0939\u0940 \u092A\u0947\u091C \u092A\u0930"
4907
- ],
4908
- prompts: [
4909
- "\u092F\u0939 \u0909\u0924\u094D\u092A\u093E\u0926 \u0905\u0938\u0932 \u092E\u0947\u0902 \u0915\u094D\u092F\u093E \u0915\u0930\u0924\u093E \u0939\u0948?",
4910
- "\u092E\u0947\u0930\u0940 \u091F\u0940\u092E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?",
4911
- "\u0936\u0941\u0930\u0941\u0906\u0924 \u0915\u0948\u0938\u0947 \u0915\u0930\u0947\u0902, \u091A\u0930\u0923 \u0926\u0930 \u091A\u0930\u0923?",
4912
- "\u0907\u0938\u0915\u0940 \u0915\u0940\u092E\u0924 \u0915\u093F\u0924\u0928\u0940 \u0939\u0948?"
4913
- ]
4914
- };
4915
- var ES = {
4916
- badge: "Respuestas de IA basadas en nuestra documentaci\xF3n",
4917
- welcomeTitle: "Pregunta lo que quieras sobre nuestros productos",
4918
- welcomeBody: "Cu\xE9ntame qu\xE9 necesitas hacer y te indicar\xE9 el producto, la p\xE1gina y el siguiente paso.",
4919
- tryAsking: "Prueba a preguntar",
4920
- focusProduct: "Centrarse en un producto",
4921
- allProducts: "Todos los productos",
4922
- showAll: "Todos",
4923
- showLess: "Ver menos",
4924
- sources: "Fuentes",
4925
- nextYouCouldAsk: "Tambi\xE9n puedes preguntar",
4926
- placeholder: "Pregunta lo que quieras sobre nuestros productos\u2026",
4927
- placeholderProduct: "Pregunta sobre {product}\u2026",
4928
- send: "Enviar",
4929
- stop: "Detener",
4930
- newChat: "Nueva conversaci\xF3n",
4931
- history: "Historial",
4932
- clearHistory: "Borrar historial",
4933
- share: "Compartir",
4952
+ var META_DESCRIPTION_LIMIT = 160;
4953
+ var RELATED_LIMIT = 4;
4954
+ var HERO_FETCH_PRIORITY = Number.parseInt(React.version, 10) >= 19 ? { fetchPriority: "high" } : { fetchpriority: "high" };
4955
+ function normaliseSiteUrl(siteUrl) {
4956
+ return siteUrl.trim().replace(/\/+$/, "");
4957
+ }
4958
+ function absoluteUrl(base, path) {
4959
+ if (/^https?:\/\//i.test(path)) return path;
4960
+ return `${base}${path.startsWith("/") ? path : `/${path}`}`;
4961
+ }
4962
+ function sortByOrder(concepts) {
4963
+ return [...concepts].sort(
4964
+ (a, b) => a.order - b.order || a.slug.localeCompare(b.slug)
4965
+ );
4966
+ }
4967
+ function plural(count, singular, pluralForm) {
4968
+ return `${count} ${count === 1 ? singular : pluralForm}`;
4969
+ }
4970
+ function illustrationCount(count) {
4971
+ return plural(count, "illustration", "illustrations");
4972
+ }
4973
+ function listSentence(items) {
4974
+ if (items.length <= 1) return items.join("");
4975
+ return `${items.slice(0, -1).join(", ")} and ${items[items.length - 1]}`;
4976
+ }
4977
+ function clampText(text, limit) {
4978
+ if (text.length <= limit) return text;
4979
+ const cut = text.slice(0, limit - 1);
4980
+ const lastSpace = cut.lastIndexOf(" ");
4981
+ return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—–-]+$/, "")}\u2026`;
4982
+ }
4983
+ function defaultLandingDescription(productName, conceptTotal, imageTotal, categoryNames) {
4984
+ if (conceptTotal === 0) {
4985
+ return clampText(
4986
+ `Concepts of how ${productName} works, each a feature or flow explained with illustrations.`,
4987
+ META_DESCRIPTION_LIMIT
4988
+ );
4989
+ }
4990
+ const head = `Explore ${plural(conceptTotal, `${productName} concept`, `${productName} concepts`)} with ${illustrationCount(imageTotal)}`;
4991
+ for (let take = Math.min(categoryNames.length, 4); take >= 1; take -= 1) {
4992
+ const more = categoryNames.length > take ? " and more" : "";
4993
+ const text = `${head} across ${listSentence(categoryNames.slice(0, take))}${more}.`;
4994
+ if (text.length <= META_DESCRIPTION_LIMIT) return text;
4995
+ }
4996
+ return clampText(`${head} of how the product works.`, META_DESCRIPTION_LIMIT);
4997
+ }
4998
+ function slugifyAnchor(value) {
4999
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
5000
+ }
5001
+ function groupByCategory(ordered, categories) {
5002
+ const byName = /* @__PURE__ */ new Map();
5003
+ for (const concept of ordered) {
5004
+ const list = byName.get(concept.category);
5005
+ if (list) list.push(concept);
5006
+ else byName.set(concept.category, [concept]);
5007
+ }
5008
+ const described = [];
5009
+ for (const category of categories ?? []) {
5010
+ const list = byName.get(category.name);
5011
+ if (!list) continue;
5012
+ described.push({
5013
+ name: category.name,
5014
+ description: category.description,
5015
+ concepts: list
5016
+ });
5017
+ byName.delete(category.name);
5018
+ }
5019
+ for (const [name, list] of byName) {
5020
+ described.push({ name, description: "", concepts: list });
5021
+ }
5022
+ const used = /* @__PURE__ */ new Set();
5023
+ return described.map((group) => {
5024
+ const base = `concepts-${slugifyAnchor(group.name) || "category"}`;
5025
+ let anchor = base;
5026
+ for (let n = 2; used.has(anchor); n += 1) anchor = `${base}-${n}`;
5027
+ used.add(anchor);
5028
+ return { ...group, anchor };
5029
+ });
5030
+ }
5031
+ function searchTokens(query) {
5032
+ return query.toLowerCase().split(/\s+/).filter(Boolean);
5033
+ }
5034
+ function matchesSearch(concept, tokens) {
5035
+ if (tokens.length === 0) return true;
5036
+ const haystack = [
5037
+ concept.title,
5038
+ concept.tagline,
5039
+ concept.category,
5040
+ ...concept.keywords
5041
+ ].join(" ").toLowerCase();
5042
+ return tokens.every((token) => haystack.includes(token));
5043
+ }
5044
+ function isPortrait(width, height) {
5045
+ return height > width;
5046
+ }
5047
+ function copyKey(index, text) {
5048
+ return `${index}-${text}`;
5049
+ }
5050
+ function DefaultConceptLink({
5051
+ href,
5052
+ className,
5053
+ children,
5054
+ "aria-label": ariaLabel
5055
+ }) {
5056
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className, "aria-label": ariaLabel, children });
5057
+ }
5058
+ function IllustrationNotice({ className }) {
5059
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5060
+ "div",
5061
+ {
5062
+ role: "note",
5063
+ "data-concepts": "notice",
5064
+ "data-concepts-notice": "",
5065
+ className: cn(
5066
+ "flex items-start gap-3 rounded-xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm leading-relaxed text-foreground",
5067
+ className
5068
+ ),
5069
+ children: [
5070
+ /* @__PURE__ */ jsxRuntime.jsx(
5071
+ lucideReact.Info,
5072
+ {
5073
+ "aria-hidden": "true",
5074
+ className: "mt-0.5 h-4 w-4 shrink-0 text-primary"
5075
+ }
5076
+ ),
5077
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: CONCEPT_ILLUSTRATION_NOTICE })
5078
+ ]
5079
+ }
5080
+ );
5081
+ }
5082
+ function IllustrationBadge({ className }) {
5083
+ return /* @__PURE__ */ jsxRuntime.jsx(
5084
+ "span",
5085
+ {
5086
+ "aria-hidden": "true",
5087
+ className: cn(
5088
+ "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",
5089
+ className
5090
+ ),
5091
+ children: "Illustration"
5092
+ }
5093
+ );
5094
+ }
5095
+ function ConceptCard({
5096
+ concept,
5097
+ Link
5098
+ }) {
5099
+ const image = concept.images[0];
5100
+ const portrait = image ? isPortrait(image.thumbWidth, image.thumbHeight) : false;
5101
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5102
+ Link,
5103
+ {
5104
+ href: conceptPath(concept.slug),
5105
+ 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",
5106
+ children: [
5107
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-[16/10] overflow-hidden border-b border-border bg-muted", children: [
5108
+ image ? /* @__PURE__ */ jsxRuntime.jsx(
5109
+ "img",
5110
+ {
5111
+ src: image.thumb,
5112
+ alt: "",
5113
+ width: image.thumbWidth,
5114
+ height: image.thumbHeight,
5115
+ loading: "lazy",
5116
+ decoding: "async",
5117
+ className: cn(
5118
+ "h-full w-full",
5119
+ portrait ? "object-contain p-3" : "object-cover object-top"
5120
+ )
5121
+ }
5122
+ ) : null,
5123
+ /* @__PURE__ */ jsxRuntime.jsx(IllustrationBadge, {})
5124
+ ] }),
5125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
5126
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold leading-snug text-card-foreground transition-colors group-hover:text-primary", children: concept.title }),
5127
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-muted-foreground", children: concept.tagline }),
5128
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-auto inline-flex items-center gap-1.5 pt-1 text-xs font-medium text-muted-foreground", children: [
5129
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5130
+ illustrationCount(concept.images.length)
5131
+ ] })
5132
+ ] })
5133
+ ]
5134
+ }
5135
+ );
5136
+ }
5137
+ function FilterChip({
5138
+ label,
5139
+ count,
5140
+ active,
5141
+ category,
5142
+ onSelect
5143
+ }) {
5144
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5145
+ "button",
5146
+ {
5147
+ type: "button",
5148
+ "aria-pressed": active,
5149
+ "data-category": category,
5150
+ onClick: onSelect,
5151
+ className: cn(
5152
+ "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",
5153
+ active ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-foreground hover:border-primary/40 hover:bg-muted"
5154
+ ),
5155
+ children: [
5156
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
5157
+ /* @__PURE__ */ jsxRuntime.jsx(
5158
+ "span",
5159
+ {
5160
+ className: cn(
5161
+ "rounded-full px-1.5 text-xs tabular-nums",
5162
+ active ? "bg-primary-foreground/20 text-primary-foreground" : "bg-muted text-muted-foreground"
5163
+ ),
5164
+ children: count
5165
+ }
5166
+ )
5167
+ ]
5168
+ }
5169
+ );
5170
+ }
5171
+ function ConceptsPage({
5172
+ productName,
5173
+ siteUrl,
5174
+ concepts,
5175
+ categories,
5176
+ cta,
5177
+ linkComponent,
5178
+ title,
5179
+ description,
5180
+ className
5181
+ }) {
5182
+ const Link = linkComponent ?? DefaultConceptLink;
5183
+ const base = normaliseSiteUrl(siteUrl);
5184
+ const searchId = React.useId();
5185
+ const ordered = React.useMemo(() => sortByOrder(concepts), [concepts]);
5186
+ const groups = React.useMemo(
5187
+ () => groupByCategory(ordered, categories),
5188
+ [ordered, categories]
5189
+ );
5190
+ const imageTotal = React.useMemo(
5191
+ () => ordered.reduce((sum, concept) => sum + concept.images.length, 0),
5192
+ [ordered]
5193
+ );
5194
+ const [query, setQuery] = React.useState("");
5195
+ const [activeCategory, setActiveCategory] = React.useState(null);
5196
+ const hasConcepts = ordered.length > 0;
5197
+ const tokens = React.useMemo(() => searchTokens(query), [query]);
5198
+ const searched = React.useMemo(
5199
+ () => ordered.filter((concept) => matchesSearch(concept, tokens)),
5200
+ [ordered, tokens]
5201
+ );
5202
+ const countsByCategory = React.useMemo(() => {
5203
+ const counts = /* @__PURE__ */ new Map();
5204
+ for (const concept of searched) {
5205
+ counts.set(concept.category, (counts.get(concept.category) ?? 0) + 1);
5206
+ }
5207
+ return counts;
5208
+ }, [searched]);
5209
+ const visibleGroups = React.useMemo(() => {
5210
+ const visible = new Set(
5211
+ searched.filter(
5212
+ (concept) => activeCategory === null || concept.category === activeCategory
5213
+ )
5214
+ );
5215
+ return groups.map((group) => ({
5216
+ ...group,
5217
+ concepts: group.concepts.filter((concept) => visible.has(concept))
5218
+ })).filter((group) => group.concepts.length > 0);
5219
+ }, [groups, searched, activeCategory]);
5220
+ const visibleTotal = visibleGroups.reduce(
5221
+ (sum, group) => sum + group.concepts.length,
5222
+ 0
5223
+ );
5224
+ const filtering = tokens.length > 0 || activeCategory !== null;
5225
+ const clearFilters = React.useCallback(() => {
5226
+ setQuery("");
5227
+ setActiveCategory(null);
5228
+ }, []);
5229
+ const heading = title ?? `${productName} concepts`;
5230
+ const metaDescription = description ?? defaultLandingDescription(
5231
+ productName,
5232
+ ordered.length,
5233
+ imageTotal,
5234
+ groups.map((group) => group.name)
5235
+ );
5236
+ const lead = description ?? `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.`;
5237
+ const canonical = `${base}${CONCEPTS_PATH}`;
5238
+ const firstImage = ordered.find((concept) => concept.images[0])?.images[0];
5239
+ const structuredData = React.useMemo(
5240
+ () => [
5241
+ {
5242
+ "@context": "https://schema.org",
5243
+ "@type": "CollectionPage",
5244
+ name: heading,
5245
+ description: metaDescription,
5246
+ url: canonical,
5247
+ isPartOf: { "@type": "WebSite", name: productName, url: `${base}/` },
5248
+ mainEntity: {
5249
+ "@type": "ItemList",
5250
+ numberOfItems: ordered.length,
5251
+ itemListElement: ordered.map((concept, index) => {
5252
+ const image = concept.images[0];
5253
+ return {
5254
+ "@type": "ListItem",
5255
+ position: index + 1,
5256
+ url: absoluteUrl(base, conceptPath(concept.slug)),
5257
+ name: concept.title,
5258
+ ...image ? { image: absoluteUrl(base, image.src) } : {}
5259
+ };
5260
+ })
5261
+ }
5262
+ },
5263
+ {
5264
+ "@context": "https://schema.org",
5265
+ "@type": "BreadcrumbList",
5266
+ itemListElement: [
5267
+ { "@type": "ListItem", position: 1, name: "Home", item: `${base}/` },
5268
+ {
5269
+ "@type": "ListItem",
5270
+ position: 2,
5271
+ name: "Concepts",
5272
+ item: canonical
5273
+ }
5274
+ ]
5275
+ }
5276
+ ],
5277
+ [base, canonical, heading, metaDescription, ordered, productName]
5278
+ );
5279
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5280
+ "div",
5281
+ {
5282
+ "data-concepts": "landing",
5283
+ className: cn("bg-background text-foreground", className),
5284
+ children: [
5285
+ /* @__PURE__ */ jsxRuntime.jsx(
5286
+ PageHead,
5287
+ {
5288
+ title: "Concepts",
5289
+ description: metaDescription,
5290
+ productName,
5291
+ keywords: [
5292
+ `${productName} concepts`,
5293
+ `${productName} illustrations`,
5294
+ ...groups.map((group) => group.name)
5295
+ ].join(", "),
5296
+ image: firstImage ? absoluteUrl(base, firstImage.src) : void 0,
5297
+ url: canonical,
5298
+ structuredData
5299
+ }
5300
+ ),
5301
+ /* @__PURE__ */ jsxRuntime.jsx("section", { className: "border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-6xl px-4 py-14 sm:px-6 sm:py-20 lg:px-8", children: [
5302
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-primary", children: "Concepts" }),
5303
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-3 max-w-3xl text-4xl font-bold tracking-tight text-foreground sm:text-5xl", children: heading }),
5304
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 max-w-2xl text-lg leading-relaxed text-muted-foreground", children: lead }),
5305
+ hasConcepts ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-6 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground", children: [
5306
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5307
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-lg font-semibold text-foreground", children: ordered.length }),
5308
+ " ",
5309
+ ordered.length === 1 ? "concept" : "concepts"
5310
+ ] }),
5311
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5312
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "text-lg font-semibold text-foreground", children: imageTotal }),
5313
+ " ",
5314
+ imageTotal === 1 ? "illustration" : "illustrations"
5315
+ ] })
5316
+ ] }) : null,
5317
+ /* @__PURE__ */ jsxRuntime.jsx(IllustrationNotice, { className: "mt-6 max-w-2xl" }),
5318
+ cta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 flex flex-wrap gap-3", children: cta }) : null
5319
+ ] }) }),
5320
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-6xl px-4 pb-20 sm:px-6 lg:px-8", children: hasConcepts ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5321
+ /* @__PURE__ */ jsxRuntime.jsxs(
5322
+ "div",
5323
+ {
5324
+ role: "search",
5325
+ "data-concepts": "filter",
5326
+ className: "flex flex-col gap-4 py-8",
5327
+ children: [
5328
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-md", children: [
5329
+ /* @__PURE__ */ jsxRuntime.jsx(
5330
+ lucideReact.Search,
5331
+ {
5332
+ "aria-hidden": "true",
5333
+ className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
5334
+ }
5335
+ ),
5336
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: searchId, className: "sr-only", children: "Search concepts" }),
5337
+ /* @__PURE__ */ jsxRuntime.jsx(
5338
+ "input",
5339
+ {
5340
+ id: searchId,
5341
+ type: "search",
5342
+ value: query,
5343
+ onChange: (event) => setQuery(event.target.value),
5344
+ placeholder: "Search concepts",
5345
+ autoComplete: "off",
5346
+ 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"
5347
+ }
5348
+ )
5349
+ ] }),
5350
+ /* @__PURE__ */ jsxRuntime.jsxs(
5351
+ "div",
5352
+ {
5353
+ role: "group",
5354
+ "aria-label": "Filter by category",
5355
+ className: "flex flex-wrap gap-2",
5356
+ children: [
5357
+ /* @__PURE__ */ jsxRuntime.jsx(
5358
+ FilterChip,
5359
+ {
5360
+ label: "All",
5361
+ category: "all",
5362
+ count: searched.length,
5363
+ active: activeCategory === null,
5364
+ onSelect: () => setActiveCategory(null)
5365
+ }
5366
+ ),
5367
+ groups.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
5368
+ FilterChip,
5369
+ {
5370
+ label: group.name,
5371
+ category: group.name,
5372
+ count: countsByCategory.get(group.name) ?? 0,
5373
+ active: activeCategory === group.name,
5374
+ onSelect: () => setActiveCategory(
5375
+ (current) => current === group.name ? null : group.name
5376
+ )
5377
+ },
5378
+ group.anchor
5379
+ ))
5380
+ ]
5381
+ }
5382
+ ),
5383
+ /* @__PURE__ */ jsxRuntime.jsxs(
5384
+ "p",
5385
+ {
5386
+ "aria-live": "polite",
5387
+ className: filtering ? "text-sm text-muted-foreground" : "sr-only",
5388
+ children: [
5389
+ "Showing ",
5390
+ visibleTotal,
5391
+ " of ",
5392
+ ordered.length,
5393
+ " ",
5394
+ ordered.length === 1 ? "concept" : "concepts"
5395
+ ]
5396
+ }
5397
+ )
5398
+ ]
5399
+ }
5400
+ ),
5401
+ visibleTotal === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
5402
+ "div",
5403
+ {
5404
+ "data-concepts": "empty",
5405
+ className: "rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center",
5406
+ children: [
5407
+ /* @__PURE__ */ jsxRuntime.jsx(
5408
+ lucideReact.Search,
5409
+ {
5410
+ "aria-hidden": "true",
5411
+ className: "mx-auto h-8 w-8 text-muted-foreground"
5412
+ }
5413
+ ),
5414
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-4 text-lg font-semibold text-foreground", children: "No concepts match your filters" }),
5415
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Try a different search, or show every category." }),
5416
+ /* @__PURE__ */ jsxRuntime.jsx(
5417
+ "button",
5418
+ {
5419
+ type: "button",
5420
+ onClick: clearFilters,
5421
+ 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",
5422
+ children: "Clear filters"
5423
+ }
5424
+ )
5425
+ ]
5426
+ }
5427
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-14", children: visibleGroups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": group.anchor, children: [
5428
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl", children: [
5429
+ /* @__PURE__ */ jsxRuntime.jsx(
5430
+ "h2",
5431
+ {
5432
+ id: group.anchor,
5433
+ className: "scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground",
5434
+ children: group.name
5435
+ }
5436
+ ),
5437
+ group.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 leading-relaxed text-muted-foreground", children: group.description }) : null
5438
+ ] }),
5439
+ /* @__PURE__ */ jsxRuntime.jsx(
5440
+ "ul",
5441
+ {
5442
+ role: "list",
5443
+ className: "mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3",
5444
+ children: group.concepts.map((concept) => /* @__PURE__ */ jsxRuntime.jsx(
5445
+ "li",
5446
+ {
5447
+ "data-concepts": "card",
5448
+ "data-slug": concept.slug,
5449
+ children: /* @__PURE__ */ jsxRuntime.jsx(ConceptCard, { concept, Link })
5450
+ },
5451
+ concept.slug
5452
+ ))
5453
+ }
5454
+ )
5455
+ ] }, group.anchor)) })
5456
+ ] }) : (
5457
+ // Nothing published yet: no filter bar with an "All 0" chip, and no empty state
5458
+ // that blames filters the visitor never set.
5459
+ /* @__PURE__ */ jsxRuntime.jsxs(
5460
+ "div",
5461
+ {
5462
+ "data-concepts": "none",
5463
+ className: "mt-10 rounded-2xl border border-dashed border-border bg-muted/30 px-6 py-14 text-center",
5464
+ children: [
5465
+ /* @__PURE__ */ jsxRuntime.jsx(
5466
+ lucideReact.ImageIcon,
5467
+ {
5468
+ "aria-hidden": "true",
5469
+ className: "mx-auto h-8 w-8 text-muted-foreground"
5470
+ }
5471
+ ),
5472
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-4 text-lg font-semibold text-foreground", children: "No concepts published yet" }),
5473
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-sm text-muted-foreground", children: [
5474
+ productName,
5475
+ " concepts will appear here as they are published."
5476
+ ] })
5477
+ ]
5478
+ }
5479
+ )
5480
+ ) })
5481
+ ]
5482
+ }
5483
+ );
5484
+ }
5485
+ var SECTION_HEADING = "scroll-mt-24 text-2xl font-semibold tracking-tight text-foreground";
5486
+ var CHIP = "inline-flex items-center rounded-full border border-border bg-muted/50 px-3 py-1 text-sm text-foreground";
5487
+ function IllustrationFigure({
5488
+ image,
5489
+ onOpen
5490
+ }) {
5491
+ const portrait = isPortrait(image.width, image.height);
5492
+ return (
5493
+ // The block the llms extractor reads: title, image line, caption, description — in
5494
+ // that order and with nothing in between. The description sits outside <figure>
5495
+ // because a <figcaption> must be the figure's first or last child.
5496
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
5497
+ /* @__PURE__ */ jsxRuntime.jsxs("figure", { id: `illustration-${image.key}`, className: "scroll-mt-24", children: [
5498
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground", children: image.title }),
5499
+ /* @__PURE__ */ jsxRuntime.jsxs(
5500
+ "button",
5501
+ {
5502
+ type: "button",
5503
+ onClick: (event) => onOpen(event.currentTarget),
5504
+ "data-concepts": "illustration",
5505
+ className: cn(
5506
+ "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",
5507
+ portrait ? "bg-muted p-4 sm:p-6" : "bg-muted"
5508
+ ),
5509
+ children: [
5510
+ /* @__PURE__ */ jsxRuntime.jsx(
5511
+ "img",
5512
+ {
5513
+ "data-llms-image": "",
5514
+ src: image.src,
5515
+ alt: image.alt,
5516
+ width: image.width,
5517
+ height: image.height,
5518
+ loading: "lazy",
5519
+ decoding: "async",
5520
+ className: "mx-auto block h-auto max-h-[80vh] w-auto max-w-full"
5521
+ }
5522
+ ),
5523
+ /* @__PURE__ */ jsxRuntime.jsx(IllustrationBadge, { className: "left-3 top-3" }),
5524
+ /* @__PURE__ */ jsxRuntime.jsx(
5525
+ "span",
5526
+ {
5527
+ "aria-hidden": "true",
5528
+ 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",
5529
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { className: "h-4 w-4" })
5530
+ }
5531
+ ),
5532
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Enlarge illustration" })
5533
+ ]
5534
+ }
5535
+ ),
5536
+ /* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: "mt-3 text-sm font-medium text-foreground", children: image.caption })
5537
+ ] }),
5538
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "leading-relaxed text-muted-foreground", children: image.description })
5539
+ ] })
5540
+ );
5541
+ }
5542
+ function ConceptDetailPage(props) {
5543
+ return /* @__PURE__ */ jsxRuntime.jsx(ConceptDetail, { ...props }, props.concept.slug);
5544
+ }
5545
+ function ConceptDetail({
5546
+ productName,
5547
+ siteUrl,
5548
+ concept,
5549
+ concepts,
5550
+ categories,
5551
+ cta,
5552
+ linkComponent,
5553
+ className
5554
+ }) {
5555
+ const Link = linkComponent ?? DefaultConceptLink;
5556
+ const base = normaliseSiteUrl(siteUrl);
5557
+ const headingId = React.useId();
5558
+ const ordered = React.useMemo(() => sortByOrder(concepts), [concepts]);
5559
+ const position = ordered.findIndex((item) => item.slug === concept.slug);
5560
+ const previous = position > 0 ? ordered[position - 1] : void 0;
5561
+ const next = position >= 0 && position < ordered.length - 1 ? ordered[position + 1] : void 0;
5562
+ const related = React.useMemo(() => {
5563
+ const bySlug = new Map(ordered.map((item) => [item.slug, item]));
5564
+ const curated = [...new Set(concept.related)].map((slug) => bySlug.get(slug)).filter(
5565
+ (item) => item !== void 0 && item.slug !== concept.slug
5566
+ );
5567
+ const list = curated.length > 0 ? curated : ordered.filter(
5568
+ (item) => item.category === concept.category && item.slug !== concept.slug
5569
+ );
5570
+ return list.slice(0, RELATED_LIMIT);
5571
+ }, [concept, ordered]);
5572
+ const relatedIsCurated = concept.related.some(
5573
+ (slug) => related.some((item) => item.slug === slug)
5574
+ );
5575
+ const categoryDescription = categories?.find(
5576
+ (category) => category.name === concept.category
5577
+ )?.description;
5578
+ const [lightboxIndex, setLightboxIndex] = React.useState(null);
5579
+ const triggerRef = React.useRef(null);
5580
+ const openLightbox = React.useCallback((index, trigger) => {
5581
+ triggerRef.current = trigger;
5582
+ setLightboxIndex(index);
5583
+ }, []);
5584
+ const closeLightbox = React.useCallback(() => setLightboxIndex(null), []);
5585
+ React.useEffect(() => {
5586
+ if (lightboxIndex !== null) return;
5587
+ const trigger = triggerRef.current;
5588
+ if (!trigger) return;
5589
+ triggerRef.current = null;
5590
+ if (trigger.isConnected) trigger.focus();
5591
+ }, [lightboxIndex]);
5592
+ const canonical = absoluteUrl(base, conceptPath(concept.slug));
5593
+ const hero = concept.images[0];
5594
+ const imageTotal = concept.images.length;
5595
+ const structuredData = React.useMemo(
5596
+ () => [
5597
+ {
5598
+ "@context": "https://schema.org",
5599
+ "@type": "ImageGallery",
5600
+ name: concept.title,
5601
+ description: concept.metaDescription,
5602
+ url: canonical,
5603
+ keywords: concept.keywords.join(", "),
5604
+ about: { "@type": "Thing", name: productName },
5605
+ image: concept.images.map((image) => ({
5606
+ "@type": "ImageObject",
5607
+ contentUrl: absoluteUrl(base, image.src),
5608
+ thumbnailUrl: absoluteUrl(base, image.thumb),
5609
+ name: image.title,
5610
+ caption: image.caption,
5611
+ description: image.description,
5612
+ width: image.width,
5613
+ height: image.height
5614
+ }))
5615
+ },
5616
+ {
5617
+ "@context": "https://schema.org",
5618
+ "@type": "BreadcrumbList",
5619
+ itemListElement: [
5620
+ { "@type": "ListItem", position: 1, name: "Home", item: `${base}/` },
5621
+ {
5622
+ "@type": "ListItem",
5623
+ position: 2,
5624
+ name: "Concepts",
5625
+ item: `${base}${CONCEPTS_PATH}`
5626
+ },
5627
+ {
5628
+ "@type": "ListItem",
5629
+ position: 3,
5630
+ name: concept.title,
5631
+ item: canonical
5632
+ }
5633
+ ]
5634
+ }
5635
+ ],
5636
+ [base, canonical, concept, productName]
5637
+ );
5638
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5639
+ "article",
5640
+ {
5641
+ "data-concepts": "detail",
5642
+ "data-slug": concept.slug,
5643
+ "aria-labelledby": headingId,
5644
+ className: cn("bg-background text-foreground", className),
5645
+ children: [
5646
+ /* @__PURE__ */ jsxRuntime.jsx(
5647
+ PageHead,
5648
+ {
5649
+ title: `${concept.title} \u2014 Concept`,
5650
+ description: concept.metaDescription,
5651
+ productName,
5652
+ keywords: concept.keywords.join(", "),
5653
+ image: hero ? absoluteUrl(base, hero.src) : void 0,
5654
+ url: canonical,
5655
+ structuredData
5656
+ }
5657
+ ),
5658
+ /* @__PURE__ */ jsxRuntime.jsx("header", { className: "border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-6xl px-4 pb-10 pt-8 sm:px-6 lg:px-8", children: [
5659
+ /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsxRuntime.jsxs("ol", { className: "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground", children: [
5660
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "inline-flex items-center gap-1.5", children: [
5661
+ /* @__PURE__ */ jsxRuntime.jsx(
5662
+ Link,
5663
+ {
5664
+ href: "/",
5665
+ className: "rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
5666
+ children: "Home"
5667
+ }
5668
+ ),
5669
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
5670
+ ] }),
5671
+ /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "inline-flex items-center gap-1.5", children: [
5672
+ /* @__PURE__ */ jsxRuntime.jsx(
5673
+ Link,
5674
+ {
5675
+ href: CONCEPTS_PATH,
5676
+ className: "rounded hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
5677
+ children: "Concepts"
5678
+ }
5679
+ ),
5680
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
5681
+ ] }),
5682
+ /* @__PURE__ */ jsxRuntime.jsx(
5683
+ "li",
5684
+ {
5685
+ "aria-current": "page",
5686
+ className: "min-w-0 truncate text-foreground",
5687
+ children: concept.title
5688
+ }
5689
+ )
5690
+ ] }) }),
5691
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex flex-wrap items-center gap-2", children: [
5692
+ /* @__PURE__ */ jsxRuntime.jsx(
5693
+ "span",
5694
+ {
5695
+ "data-concepts": "category",
5696
+ title: categoryDescription,
5697
+ className: "inline-flex items-center rounded-full border border-primary/30 bg-primary/10 px-3 py-1 text-xs font-semibold text-primary",
5698
+ children: concept.category
5699
+ }
5700
+ ),
5701
+ /* @__PURE__ */ jsxRuntime.jsxs("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", children: [
5702
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
5703
+ illustrationCount(imageTotal)
5704
+ ] })
5705
+ ] }),
5706
+ /* @__PURE__ */ jsxRuntime.jsx(
5707
+ "h1",
5708
+ {
5709
+ id: headingId,
5710
+ className: "mt-4 max-w-4xl text-3xl font-bold tracking-tight text-foreground sm:text-4xl lg:text-5xl",
5711
+ children: concept.title
5712
+ }
5713
+ ),
5714
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 max-w-3xl text-lg leading-relaxed text-muted-foreground", children: concept.tagline }),
5715
+ /* @__PURE__ */ jsxRuntime.jsx(IllustrationNotice, { className: "mt-6 max-w-3xl" })
5716
+ ] }) }),
5717
+ hero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-6xl px-4 pt-10 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsx("figure", { "data-concepts": "hero", children: /* @__PURE__ */ jsxRuntime.jsxs(
5718
+ "button",
5719
+ {
5720
+ type: "button",
5721
+ onClick: (event) => openLightbox(0, event.currentTarget),
5722
+ className: cn(
5723
+ "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",
5724
+ isPortrait(hero.width, hero.height) && "p-4 sm:p-6"
5725
+ ),
5726
+ children: [
5727
+ /* @__PURE__ */ jsxRuntime.jsx(
5728
+ "img",
5729
+ {
5730
+ src: hero.src,
5731
+ alt: hero.alt,
5732
+ width: hero.width,
5733
+ height: hero.height,
5734
+ loading: "eager",
5735
+ ...HERO_FETCH_PRIORITY,
5736
+ className: "mx-auto block h-auto max-h-[75vh] w-auto max-w-full"
5737
+ }
5738
+ ),
5739
+ /* @__PURE__ */ jsxRuntime.jsx(IllustrationBadge, { className: "left-3 top-3" }),
5740
+ /* @__PURE__ */ jsxRuntime.jsxs(
5741
+ "span",
5742
+ {
5743
+ "aria-hidden": "true",
5744
+ 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",
5745
+ children: [
5746
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { className: "h-3.5 w-3.5" }),
5747
+ "Enlarge"
5748
+ ]
5749
+ }
5750
+ ),
5751
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Enlarge illustration" })
5752
+ ]
5753
+ }
5754
+ ) }) }) : null,
5755
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-6xl px-4 py-14 sm:px-6 lg:px-8", children: [
5756
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl space-y-12", children: [
5757
+ concept.overview.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-overview`, children: [
5758
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-overview`, className: SECTION_HEADING, children: "Overview" }),
5759
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 space-y-4 text-base leading-relaxed text-foreground", children: concept.overview.map((paragraph, index) => /* @__PURE__ */ jsxRuntime.jsx("p", { children: paragraph }, copyKey(index, paragraph))) })
5760
+ ] }) : null,
5761
+ concept.highlights.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-highlights`, children: [
5762
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-highlights`, className: SECTION_HEADING, children: "What this concept shows" }),
5763
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", className: "mt-4 space-y-3", children: concept.highlights.map((highlight, index) => /* @__PURE__ */ jsxRuntime.jsxs(
5764
+ "li",
5765
+ {
5766
+ className: "flex items-start gap-3 leading-relaxed text-foreground",
5767
+ children: [
5768
+ /* @__PURE__ */ jsxRuntime.jsx(
5769
+ "span",
5770
+ {
5771
+ "aria-hidden": "true",
5772
+ className: "mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary",
5773
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" })
5774
+ }
5775
+ ),
5776
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: highlight })
5777
+ ]
5778
+ },
5779
+ copyKey(index, highlight)
5780
+ )) })
5781
+ ] }) : null,
5782
+ concept.workflow.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-workflow`, children: [
5783
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-workflow`, className: SECTION_HEADING, children: "How it works" }),
5784
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { role: "list", className: "mt-4 space-y-4", children: concept.workflow.map((step, index) => /* @__PURE__ */ jsxRuntime.jsxs(
5785
+ "li",
5786
+ {
5787
+ className: "flex items-start gap-4",
5788
+ children: [
5789
+ /* @__PURE__ */ jsxRuntime.jsx(
5790
+ "span",
5791
+ {
5792
+ "aria-hidden": "true",
5793
+ 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",
5794
+ children: index + 1
5795
+ }
5796
+ ),
5797
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pt-0.5 leading-relaxed text-foreground", children: step })
5798
+ ]
5799
+ },
5800
+ copyKey(index, step)
5801
+ )) })
5802
+ ] }) : null,
5803
+ concept.audience.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-audience`, children: [
5804
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-audience`, className: SECTION_HEADING, children: "Who it's for" }),
5805
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", className: "mt-4 flex flex-wrap gap-2", children: concept.audience.map((who, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: CHIP, children: who }, copyKey(index, who))) })
5806
+ ] }) : null
5807
+ ] }),
5808
+ imageTotal > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
5809
+ "section",
5810
+ {
5811
+ "aria-labelledby": `${headingId}-illustrations`,
5812
+ className: "mt-16",
5813
+ children: [
5814
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl", children: [
5815
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-illustrations`, className: SECTION_HEADING, children: "Illustrations" }),
5816
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-muted-foreground", children: [
5817
+ illustrationCount(imageTotal),
5818
+ " of this concept. Select one to view it full size."
5819
+ ] })
5820
+ ] }),
5821
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 space-y-14", children: concept.images.map((image, index) => /* @__PURE__ */ jsxRuntime.jsx(
5822
+ IllustrationFigure,
5823
+ {
5824
+ image,
5825
+ onOpen: (trigger) => openLightbox(index, trigger)
5826
+ },
5827
+ image.key
5828
+ )) })
5829
+ ]
5830
+ }
5831
+ ) : null,
5832
+ concept.keywords.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": `${headingId}-topics`, className: "mt-16", children: [
5833
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-topics`, className: SECTION_HEADING, children: "Topics" }),
5834
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", className: "mt-4 flex flex-wrap gap-2", children: concept.keywords.map((keyword, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: CHIP, children: keyword }, copyKey(index, keyword))) })
5835
+ ] }) : null,
5836
+ related.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
5837
+ "section",
5838
+ {
5839
+ "aria-labelledby": `${headingId}-related`,
5840
+ "data-concepts": "related",
5841
+ className: "mt-16",
5842
+ children: [
5843
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${headingId}-related`, className: SECTION_HEADING, children: relatedIsCurated ? "Related concepts" : `More in ${concept.category}` }),
5844
+ /* @__PURE__ */ jsxRuntime.jsx(
5845
+ "ul",
5846
+ {
5847
+ role: "list",
5848
+ className: cn(
5849
+ "mt-6 grid grid-cols-1 gap-5 sm:grid-cols-2",
5850
+ related.length >= 4 ? "lg:grid-cols-4" : "lg:grid-cols-3"
5851
+ ),
5852
+ children: related.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { "data-concepts": "card", "data-slug": item.slug, children: /* @__PURE__ */ jsxRuntime.jsx(ConceptCard, { concept: item, Link }) }, item.slug))
5853
+ }
5854
+ )
5855
+ ]
5856
+ }
5857
+ ) : null,
5858
+ previous || next ? /* @__PURE__ */ jsxRuntime.jsxs(
5859
+ "nav",
5860
+ {
5861
+ "aria-label": "Previous and next concepts",
5862
+ "data-concepts": "pager",
5863
+ className: "mt-16 grid gap-4 sm:grid-cols-2",
5864
+ children: [
5865
+ previous ? /* @__PURE__ */ jsxRuntime.jsxs(
5866
+ Link,
5867
+ {
5868
+ href: conceptPath(previous.slug),
5869
+ 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",
5870
+ children: [
5871
+ /* @__PURE__ */ jsxRuntime.jsx(
5872
+ lucideReact.ArrowLeft,
5873
+ {
5874
+ "aria-hidden": "true",
5875
+ className: "h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary"
5876
+ }
5877
+ ),
5878
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0", children: [
5879
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Previous concept" }),
5880
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate font-semibold", children: previous.title })
5881
+ ] })
5882
+ ]
5883
+ }
5884
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:block" }),
5885
+ next ? /* @__PURE__ */ jsxRuntime.jsxs(
5886
+ Link,
5887
+ {
5888
+ href: conceptPath(next.slug),
5889
+ 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",
5890
+ children: [
5891
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0", children: [
5892
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Next concept" }),
5893
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate font-semibold", children: next.title })
5894
+ ] }),
5895
+ /* @__PURE__ */ jsxRuntime.jsx(
5896
+ lucideReact.ArrowRight,
5897
+ {
5898
+ "aria-hidden": "true",
5899
+ className: "h-5 w-5 shrink-0 text-muted-foreground transition-colors group-hover:text-primary"
5900
+ }
5901
+ )
5902
+ ]
5903
+ }
5904
+ ) : null
5905
+ ]
5906
+ }
5907
+ ) : null,
5908
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-10", children: /* @__PURE__ */ jsxRuntime.jsxs(
5909
+ Link,
5910
+ {
5911
+ href: CONCEPTS_PATH,
5912
+ 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",
5913
+ children: [
5914
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
5915
+ "All ",
5916
+ productName,
5917
+ " concepts"
5918
+ ]
5919
+ }
5920
+ ) })
5921
+ ] }),
5922
+ cta ? /* @__PURE__ */ jsxRuntime.jsx(
5923
+ "section",
5924
+ {
5925
+ "data-concepts": "cta",
5926
+ className: "border-t border-border bg-muted/30",
5927
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto flex max-w-6xl flex-wrap items-center gap-4 px-4 py-12 sm:px-6 lg:px-8", children: cta })
5928
+ }
5929
+ ) : null,
5930
+ lightboxIndex !== null ? /* @__PURE__ */ jsxRuntime.jsx(
5931
+ ConceptLightbox,
5932
+ {
5933
+ images: concept.images,
5934
+ index: lightboxIndex,
5935
+ conceptTitle: concept.title,
5936
+ onIndexChange: setLightboxIndex,
5937
+ onClose: closeLightbox
5938
+ }
5939
+ ) : null
5940
+ ]
5941
+ }
5942
+ );
5943
+ }
5944
+
5945
+ // src/components/explore-i18n.ts
5946
+ var EXPLORE_LOCALES = ["en", "zh", "hi", "es", "ar", "ta"];
5947
+ var RTL_LOCALES = /* @__PURE__ */ new Set(["ar"]);
5948
+ function isRtlLocale(locale) {
5949
+ return RTL_LOCALES.has(locale);
5950
+ }
5951
+ var EN = {
5952
+ badge: "AI answers, grounded in our documentation",
5953
+ welcomeTitle: "Ask anything about our products",
5954
+ welcomeBody: "Describe what you are trying to do and I will point you at the product, the page and the next step.",
5955
+ tryAsking: "Try asking",
5956
+ focusProduct: "Focus on a product",
5957
+ allProducts: "All products",
5958
+ showAll: "All",
5959
+ showLess: "Show less",
5960
+ sources: "Sources",
5961
+ nextYouCouldAsk: "Next you could ask",
5962
+ placeholder: "Ask anything about our products\u2026",
5963
+ placeholderProduct: "Ask about {product}\u2026",
5964
+ send: "Send",
5965
+ stop: "Stop",
5966
+ newChat: "New chat",
5967
+ history: "History",
5968
+ clearHistory: "Clear history",
5969
+ share: "Share",
5970
+ copied: "Copied",
5971
+ copying: "Copying\u2026",
5972
+ shareUnavailable: "Unavailable",
5973
+ disclaimer: "Disclaimer",
5974
+ disclaimerShort: "Grounded in our docs \u2014 check anything important.",
5975
+ dictate: "Dictate your question",
5976
+ stopDictating: "Stop dictating",
5977
+ attach: "Attach files",
5978
+ attachHint: "Up to {{max}} files, {{size}} MB each",
5979
+ removeAttachment: "Remove {{name}}",
5980
+ attachmentNameOnly: "name and type only",
5981
+ attachmentTooLarge: "{{name}} is larger than {{size}} MB and was not attached.",
5982
+ attachmentTooMany: "Only {{max}} files can be attached, so {{name}} was skipped.",
5983
+ noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
5984
+ answerDidNotArrive: "That answer didn't come through. Try asking again.",
5985
+ askHuman: "ask a human",
5986
+ prevSuggestion: "Previous suggestion",
5987
+ nextSuggestion: "Next suggestion",
5988
+ conceptIllustration: "Concept illustration",
5989
+ opensInNewTab: "opens in a new tab",
5990
+ capabilities: [
5991
+ "Grounded in our own docs",
5992
+ "Compare across the ecosystem",
5993
+ "Straight to the right page"
5994
+ ],
5995
+ prompts: [
5996
+ "What does this product actually do?",
5997
+ "Which product fits my team?",
5998
+ "How do I get started, step by step?",
5999
+ "How much does it cost?"
6000
+ ]
6001
+ };
6002
+ var ZH = {
6003
+ badge: "\u57FA\u4E8E\u6211\u4EEC\u6587\u6863\u7684 AI \u56DE\u7B54",
6004
+ welcomeTitle: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE",
6005
+ welcomeBody: "\u63CF\u8FF0\u4F60\u60F3\u505A\u7684\u4E8B\uFF0C\u6211\u4F1A\u4E3A\u4F60\u6307\u51FA\u5BF9\u5E94\u7684\u4EA7\u54C1\u3001\u9875\u9762\u548C\u4E0B\u4E00\u6B65\u3002",
6006
+ tryAsking: "\u8BD5\u7740\u95EE",
6007
+ focusProduct: "\u805A\u7126\u67D0\u4E2A\u4EA7\u54C1",
6008
+ allProducts: "\u5168\u90E8\u4EA7\u54C1",
6009
+ showAll: "\u5168\u90E8",
6010
+ showLess: "\u6536\u8D77",
6011
+ sources: "\u6765\u6E90",
6012
+ nextYouCouldAsk: "\u4F60\u8FD8\u53EF\u4EE5\u95EE",
6013
+ placeholder: "\u5173\u4E8E\u6211\u4EEC\u7684\u4EA7\u54C1\uFF0C\u968F\u4FBF\u95EE\u2026",
6014
+ placeholderProduct: "\u8BE2\u95EE\u5173\u4E8E {product} \u7684\u95EE\u9898\u2026",
6015
+ send: "\u53D1\u9001",
6016
+ stop: "\u505C\u6B62",
6017
+ newChat: "\u65B0\u5BF9\u8BDD",
6018
+ history: "\u5386\u53F2",
6019
+ clearHistory: "\u6E05\u9664\u5386\u53F2",
6020
+ share: "\u5206\u4EAB",
6021
+ copied: "\u5DF2\u590D\u5236",
6022
+ copying: "\u590D\u5236\u4E2D\u2026",
6023
+ shareUnavailable: "\u4E0D\u53EF\u7528",
6024
+ disclaimer: "\u514D\u8D23\u58F0\u660E",
6025
+ disclaimerShort: "\u5185\u5BB9\u57FA\u4E8E\u6211\u4EEC\u7684\u6587\u6863\uFF0C\u91CD\u8981\u4FE1\u606F\u8BF7\u81EA\u884C\u6838\u5BF9\u3002",
6026
+ dictate: "\u8BED\u97F3\u8F93\u5165",
6027
+ stopDictating: "\u505C\u6B62\u8BED\u97F3\u8F93\u5165",
6028
+ attach: "\u6DFB\u52A0\u6587\u4EF6",
6029
+ attachHint: "\u6700\u591A {{max}} \u4E2A\u6587\u4EF6\uFF0C\u6BCF\u4E2A\u4E0D\u8D85\u8FC7 {{size}} MB",
6030
+ removeAttachment: "\u79FB\u9664 {{name}}",
6031
+ attachmentNameOnly: "\u4EC5\u6587\u4EF6\u540D\u548C\u7C7B\u578B",
6032
+ attachmentTooLarge: "{{name}} \u8D85\u8FC7 {{size}} MB\uFF0C\u672A\u80FD\u6DFB\u52A0\u3002",
6033
+ attachmentTooMany: "\u6700\u591A\u53EA\u80FD\u6DFB\u52A0 {{max}} \u4E2A\u6587\u4EF6\uFF0C\u5DF2\u8DF3\u8FC7 {{name}}\u3002",
6034
+ noAnswer: "\u6211\u5728\u6587\u6863\u4E2D\u6CA1\u6709\u627E\u5230\u76F8\u5173\u5185\u5BB9\uFF0C\u4E0B\u9762\u7684\u56DE\u7B54\u6CA1\u6709\u6765\u6E90\u652F\u6301\u3002\u8BF7\u6362\u4E2A\u8BF4\u6CD5\uFF0C\u6216",
6035
+ answerDidNotArrive: "\u8FD9\u6761\u56DE\u7B54\u6CA1\u6709\u8FD4\u56DE\u3002\u8BF7\u518D\u95EE\u4E00\u6B21\u3002",
6036
+ askHuman: "\u8054\u7CFB\u6211\u4EEC",
6037
+ prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
6038
+ nextSuggestion: "\u4E0B\u4E00\u4E2A\u5EFA\u8BAE",
6039
+ conceptIllustration: "\u6982\u5FF5\u793A\u610F\u56FE",
6040
+ opensInNewTab: "\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00",
6041
+ capabilities: ["\u57FA\u4E8E\u6211\u4EEC\u81EA\u5DF1\u7684\u6587\u6863", "\u8DE8\u4EA7\u54C1\u5BF9\u6BD4", "\u76F4\u8FBE\u6B63\u786E\u7684\u9875\u9762"],
6042
+ prompts: [
6043
+ "\u8FD9\u4E2A\u4EA7\u54C1\u5230\u5E95\u80FD\u505A\u4EC0\u4E48\uFF1F",
6044
+ "\u54EA\u4E2A\u4EA7\u54C1\u9002\u5408\u6211\u7684\u56E2\u961F\uFF1F",
6045
+ "\u5982\u4F55\u4E00\u6B65\u6B65\u5F00\u59CB\u4F7F\u7528\uFF1F",
6046
+ "\u4EF7\u683C\u662F\u591A\u5C11\uFF1F"
6047
+ ]
6048
+ };
6049
+ var HI = {
6050
+ badge: "\u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 AI \u0909\u0924\u094D\u0924\u0930",
6051
+ welcomeTitle: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902",
6052
+ welcomeBody: "\u092C\u0924\u093E\u0907\u090F \u0906\u092A \u0915\u094D\u092F\u093E \u0915\u0930\u0928\u093E \u091A\u093E\u0939\u0924\u0947 \u0939\u0948\u0902, \u0914\u0930 \u092E\u0948\u0902 \u0906\u092A\u0915\u094B \u0938\u0939\u0940 \u0909\u0924\u094D\u092A\u093E\u0926, \u092A\u0947\u091C \u0914\u0930 \u0905\u0917\u0932\u093E \u0915\u0926\u092E \u092C\u0924\u093E\u090A\u0901\u0917\u093E\u0964",
6053
+ tryAsking: "\u092F\u0939 \u092A\u0942\u091B\u0915\u0930 \u0926\u0947\u0916\u0947\u0902",
6054
+ focusProduct: "\u0915\u093F\u0938\u0940 \u0909\u0924\u094D\u092A\u093E\u0926 \u092A\u0930 \u0927\u094D\u092F\u093E\u0928 \u0926\u0947\u0902",
6055
+ allProducts: "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926",
6056
+ showAll: "\u0938\u092D\u0940",
6057
+ showLess: "\u0915\u092E \u0926\u093F\u0916\u093E\u090F\u0901",
6058
+ sources: "\u0938\u094D\u0930\u094B\u0924",
6059
+ nextYouCouldAsk: "\u0906\u0917\u0947 \u0906\u092A \u092A\u0942\u091B \u0938\u0915\u0924\u0947 \u0939\u0948\u0902",
6060
+ placeholder: "\u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u0947\u0902\u2026",
6061
+ placeholderProduct: "{product} \u0915\u0947 \u092C\u093E\u0930\u0947 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902\u2026",
6062
+ send: "\u092D\u0947\u091C\u0947\u0902",
6063
+ stop: "\u0930\u094B\u0915\u0947\u0902",
6064
+ newChat: "\u0928\u0908 \u092C\u093E\u0924\u091A\u0940\u0924",
6065
+ history: "\u0907\u0924\u093F\u0939\u093E\u0938",
6066
+ clearHistory: "\u0907\u0924\u093F\u0939\u093E\u0938 \u092E\u093F\u091F\u093E\u090F\u0901",
6067
+ share: "\u0938\u093E\u091D\u093E \u0915\u0930\u0947\u0902",
6068
+ copied: "\u0915\u0949\u092A\u0940 \u0939\u094B \u0917\u092F\u093E",
6069
+ copying: "\u0915\u0949\u092A\u0940 \u0939\u094B \u0930\u0939\u093E \u0939\u0948\u2026",
6070
+ shareUnavailable: "\u0909\u092A\u0932\u092C\u094D\u0927 \u0928\u0939\u0940\u0902",
6071
+ disclaimer: "\u0905\u0938\u094D\u0935\u0940\u0915\u0930\u0923",
6072
+ disclaimerShort: "\u092F\u0939 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0939\u0948 \u2014 \u092E\u0939\u0924\u094D\u0935\u092A\u0942\u0930\u094D\u0923 \u092C\u093E\u0924\u0947\u0902 \u091C\u093C\u0930\u0942\u0930 \u091C\u093E\u0901\u091A \u0932\u0947\u0902\u0964",
6073
+ dictate: "\u092C\u094B\u0932\u0915\u0930 \u092A\u0942\u091B\u0947\u0902",
6074
+ stopDictating: "\u092C\u094B\u0932\u0928\u093E \u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
6075
+ attach: "\u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0947\u0902",
6076
+ attachHint: "\u0905\u0927\u093F\u0915\u0924\u092E {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902, \u092A\u094D\u0930\u0924\u094D\u092F\u0947\u0915 {{size}} MB \u0924\u0915",
6077
+ removeAttachment: "{{name}} \u0939\u091F\u093E\u090F\u0901",
6078
+ attachmentNameOnly: "\u0915\u0947\u0935\u0932 \u0928\u093E\u092E \u0914\u0930 \u092A\u094D\u0930\u0915\u093E\u0930",
6079
+ attachmentTooLarge: "{{name}} {{size}} MB \u0938\u0947 \u092C\u0921\u093C\u0940 \u0939\u0948, \u0907\u0938\u0932\u093F\u090F \u091C\u094B\u0921\u093C\u0940 \u0928\u0939\u0940\u0902 \u0917\u0908\u0964",
6080
+ attachmentTooMany: "\u0915\u0947\u0935\u0932 {{max}} \u092B\u093C\u093E\u0907\u0932\u0947\u0902 \u091C\u094B\u0921\u093C\u0940 \u091C\u093E \u0938\u0915\u0924\u0940 \u0939\u0948\u0902, \u0907\u0938\u0932\u093F\u090F {{name}} \u091B\u094B\u0921\u093C \u0926\u0940 \u0917\u0908\u0964",
6081
+ noAnswer: "\u092F\u0939 \u092E\u0941\u091D\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092E\u0947\u0902 \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E, \u0907\u0938\u0932\u093F\u090F \u0928\u0940\u091A\u0947 \u0926\u093F\u092F\u093E \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938\u0940 \u0938\u094D\u0930\u094B\u0924 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964 \u0926\u0942\u0938\u0930\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902, \u092F\u093E",
6082
+ answerDidNotArrive: "\u0935\u0939 \u0909\u0924\u094D\u0924\u0930 \u0928\u0939\u0940\u0902 \u0906 \u0938\u0915\u093E\u0964 \u0915\u0943\u092A\u092F\u093E \u0926\u094B\u092C\u093E\u0930\u093E \u092A\u0942\u091B\u0947\u0902\u0964",
6083
+ askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
6084
+ prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
6085
+ nextSuggestion: "\u0905\u0917\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
6086
+ conceptIllustration: "\u0905\u0935\u0927\u093E\u0930\u0923\u093E \u091A\u093F\u0924\u094D\u0930\u0923",
6087
+ opensInNewTab: "\u0928\u090F \u091F\u0948\u092C \u092E\u0947\u0902 \u0916\u0941\u0932\u0924\u093E \u0939\u0948",
6088
+ capabilities: [
6089
+ "\u0939\u092E\u093E\u0930\u0947 \u0905\u092A\u0928\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924",
6090
+ "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930\u0947\u0902",
6091
+ "\u0938\u0940\u0927\u0947 \u0938\u0939\u0940 \u092A\u0947\u091C \u092A\u0930"
6092
+ ],
6093
+ prompts: [
6094
+ "\u092F\u0939 \u0909\u0924\u094D\u092A\u093E\u0926 \u0905\u0938\u0932 \u092E\u0947\u0902 \u0915\u094D\u092F\u093E \u0915\u0930\u0924\u093E \u0939\u0948?",
6095
+ "\u092E\u0947\u0930\u0940 \u091F\u0940\u092E \u0915\u0947 \u0932\u093F\u090F \u0915\u094C\u0928 \u0938\u093E \u0909\u0924\u094D\u092A\u093E\u0926 \u0938\u0939\u0940 \u0939\u0948?",
6096
+ "\u0936\u0941\u0930\u0941\u0906\u0924 \u0915\u0948\u0938\u0947 \u0915\u0930\u0947\u0902, \u091A\u0930\u0923 \u0926\u0930 \u091A\u0930\u0923?",
6097
+ "\u0907\u0938\u0915\u0940 \u0915\u0940\u092E\u0924 \u0915\u093F\u0924\u0928\u0940 \u0939\u0948?"
6098
+ ]
6099
+ };
6100
+ var ES = {
6101
+ badge: "Respuestas de IA basadas en nuestra documentaci\xF3n",
6102
+ welcomeTitle: "Pregunta lo que quieras sobre nuestros productos",
6103
+ welcomeBody: "Cu\xE9ntame qu\xE9 necesitas hacer y te indicar\xE9 el producto, la p\xE1gina y el siguiente paso.",
6104
+ tryAsking: "Prueba a preguntar",
6105
+ focusProduct: "Centrarse en un producto",
6106
+ allProducts: "Todos los productos",
6107
+ showAll: "Todos",
6108
+ showLess: "Ver menos",
6109
+ sources: "Fuentes",
6110
+ nextYouCouldAsk: "Tambi\xE9n puedes preguntar",
6111
+ placeholder: "Pregunta lo que quieras sobre nuestros productos\u2026",
6112
+ placeholderProduct: "Pregunta sobre {product}\u2026",
6113
+ send: "Enviar",
6114
+ stop: "Detener",
6115
+ newChat: "Nueva conversaci\xF3n",
6116
+ history: "Historial",
6117
+ clearHistory: "Borrar historial",
6118
+ share: "Compartir",
4934
6119
  copied: "Copiado",
4935
6120
  copying: "Copiando\u2026",
4936
6121
  shareUnavailable: "No disponible",
@@ -4945,9 +6130,12 @@ var ES = {
4945
6130
  attachmentTooLarge: "{{name}} supera los {{size}} MB y no se adjunt\xF3.",
4946
6131
  attachmentTooMany: "Solo se pueden adjuntar {{max}} archivos, as\xED que se omiti\xF3 {{name}}.",
4947
6132
  noAnswer: "No he encontrado esto en nuestra documentaci\xF3n, as\xED que la respuesta de abajo no se apoya en ninguna fuente. Prueba a reformularla, o",
6133
+ answerDidNotArrive: "Esa respuesta no lleg\xF3. Int\xE9ntalo de nuevo.",
4948
6134
  askHuman: "habla con una persona",
4949
6135
  prevSuggestion: "Sugerencia anterior",
4950
6136
  nextSuggestion: "Sugerencia siguiente",
6137
+ conceptIllustration: "Ilustraci\xF3n del concepto",
6138
+ opensInNewTab: "se abre en una pesta\xF1a nueva",
4951
6139
  capabilities: [
4952
6140
  "Basado en nuestra documentaci\xF3n",
4953
6141
  "Compara todo el ecosistema",
@@ -4993,9 +6181,12 @@ var AR = {
4993
6181
  attachmentTooLarge: "{{name}} \u0623\u0643\u0628\u0631 \u0645\u0646 {{size}} \u0645\u064A\u063A\u0627\u0628\u0627\u064A\u062A \u0648\u0644\u0645 \u064A\u062A\u0645 \u0625\u0631\u0641\u0627\u0642\u0647.",
4994
6182
  attachmentTooMany: "\u064A\u0645\u0643\u0646 \u0625\u0631\u0641\u0627\u0642 {{max}} \u0645\u0644\u0641\u0627\u062A \u0641\u0642\u0637\u060C \u0644\u0630\u0627 \u062A\u0645 \u062A\u062E\u0637\u064A {{name}}.",
4995
6183
  noAnswer: "\u0644\u0645 \u0623\u062C\u062F \u0647\u0630\u0627 \u0641\u064A \u0648\u062B\u0627\u0626\u0642\u0646\u0627\u060C \u0644\u0630\u0627 \u0641\u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0623\u062F\u0646\u0627\u0647 \u063A\u064A\u0631 \u0645\u0633\u062A\u0646\u062F\u0629 \u0625\u0644\u0649 \u0645\u0635\u062F\u0631. \u062D\u0627\u0648\u0644 \u0625\u0639\u0627\u062F\u0629 \u0627\u0644\u0635\u064A\u0627\u063A\u0629\u060C \u0623\u0648",
6184
+ answerDidNotArrive: "\u0644\u0645 \u062A\u0635\u0644 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629. \u064A\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.",
4996
6185
  askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
4997
6186
  prevSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u0633\u0627\u0628\u0642",
4998
6187
  nextSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u062A\u0627\u0644\u064A",
6188
+ conceptIllustration: "\u0631\u0633\u0645 \u062A\u0648\u0636\u064A\u062D\u064A \u0644\u0644\u0645\u0641\u0647\u0648\u0645",
6189
+ opensInNewTab: "\u064A\u064F\u0641\u062A\u062D \u0641\u064A \u0639\u0644\u0627\u0645\u0629 \u062A\u0628\u0648\u064A\u0628 \u062C\u062F\u064A\u062F\u0629",
4999
6190
  capabilities: [
5000
6191
  "\u0645\u0628\u0646\u064A \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627",
5001
6192
  "\u0642\u0627\u0631\u0646 \u0639\u0628\u0631 \u0627\u0644\u0645\u0646\u0638\u0648\u0645\u0629",
@@ -5041,9 +6232,12 @@ var TA = {
5041
6232
  attachmentTooLarge: "{{name}} {{size}} MB-\u0B90 \u0BB5\u0BBF\u0B9F \u0BAA\u0BC6\u0BB0\u0BBF\u0BAF\u0BA4\u0BC1, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
5042
6233
  attachmentTooMany: "{{max}} \u0B95\u0BCB\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD \u0BAE\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BC7 \u0B87\u0BA3\u0BC8\u0B95\u0BCD\u0B95 \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BC1\u0BAE\u0BCD, \u0B8E\u0BA9\u0BB5\u0BC7 {{name}} \u0BA4\u0BB5\u0BBF\u0BB0\u0BCD\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1.",
5043
6234
  noAnswer: "\u0B87\u0BA4\u0BC1 \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B95\u0BC0\u0BB4\u0BC7 \u0B89\u0BB3\u0BCD\u0BB3 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BC1 \u0BAE\u0BC2\u0BB2\u0BAE\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8. \u0BB5\u0BC7\u0BB1\u0BC1 \u0BB5\u0B95\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1",
6235
+ answerDidNotArrive: "\u0B85\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BB5\u0BB0\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8. \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD.",
5044
6236
  askHuman: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0BB0\u0BCD\u0BAA\u0BC1 \u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
5045
6237
  prevSuggestion: "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA4\u0BC8\u0BAF \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
5046
6238
  nextSuggestion: "\u0B85\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4 \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
6239
+ conceptIllustration: "\u0B95\u0BB0\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1 \u0BB5\u0BBF\u0BB3\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BAE\u0BCD",
6240
+ opensInNewTab: "\u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0BA4\u0BBE\u0BB5\u0BB2\u0BBF\u0BB2\u0BCD \u0BA4\u0BBF\u0BB1\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD",
5047
6241
  capabilities: [
5048
6242
  "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD",
5049
6243
  "\u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B92\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
@@ -5402,10 +6596,13 @@ var ECOSYSTEM_PRODUCTS = [
5402
6596
  name: "VibeControls",
5403
6597
  websiteUrl: "https://vibecontrols.com"
5404
6598
  },
6599
+ // FluidGrids ships on www.fluidgrids.ai — fluidgrids.com only redirects there. The explore
6600
+ // catalog and the site's own sitemap use this origin, and so must the fallback catalog
6601
+ // built from this list, or /explore rejects FluidGrids concept images until it loads.
5405
6602
  {
5406
6603
  slug: "fluidgrids",
5407
6604
  name: "FluidGrids",
5408
- websiteUrl: "https://fluidgrids.com"
6605
+ websiteUrl: "https://www.fluidgrids.ai"
5409
6606
  },
5410
6607
  // Botlit ships on botlit.ai — botlit.com does not resolve.
5411
6608
  { slug: "botlit", name: "Botlit", websiteUrl: "https://www.botlit.ai" },
@@ -5656,7 +6853,7 @@ var DEFAULT_EXPLORE_EXAMPLE_PROMPTS = [
5656
6853
  ];
5657
6854
  var FALLBACK_WELCOME_TITLE = "Ask anything about our products";
5658
6855
  var FALLBACK_WELCOME_BODY = "Get straight answers drawn from our product documentation and public pages \u2014 with links back to the exact page each answer came from.";
5659
- function buildFallbackCatalog(examplePrompts) {
6856
+ function buildFallbackCatalog(examplePrompts, welcome) {
5660
6857
  return {
5661
6858
  enabled: true,
5662
6859
  products: ECOSYSTEM_PRODUCTS.map((p) => ({
@@ -5666,8 +6863,8 @@ function buildFallbackCatalog(examplePrompts) {
5666
6863
  website: p.websiteUrl
5667
6864
  })),
5668
6865
  examplePrompts: examplePrompts?.length ? examplePrompts : DEFAULT_EXPLORE_EXAMPLE_PROMPTS,
5669
- welcomeTitle: FALLBACK_WELCOME_TITLE,
5670
- welcomeBody: FALLBACK_WELCOME_BODY,
6866
+ welcomeTitle: welcome?.title ?? FALLBACK_WELCOME_TITLE,
6867
+ welcomeBody: welcome?.body ?? FALLBACK_WELCOME_BODY,
5671
6868
  limits: FALLBACK_EXPLORE_LIMITS,
5672
6869
  captchaRequired: false,
5673
6870
  recaptchaSiteKey: null
@@ -5727,7 +6924,15 @@ function classifyExploreError(code, serverMessage) {
5727
6924
  retryable: true
5728
6925
  };
5729
6926
  }
5730
- if (c === "TIMEOUT" || c === "TOOL_BUDGET") {
6927
+ if (c === "TOOL_BUDGET") {
6928
+ return {
6929
+ kind: "scope",
6930
+ code: c,
6931
+ message: "That question spans more of our products than I can look through in one go. Try asking about two or three specific products.",
6932
+ retryable: false
6933
+ };
6934
+ }
6935
+ if (c === "TIMEOUT") {
5731
6936
  return {
5732
6937
  kind: "timeout",
5733
6938
  code: c,
@@ -5859,6 +7064,7 @@ function useExploreChat(options = {}) {
5859
7064
  pageUrl,
5860
7065
  locale,
5861
7066
  examplePrompts,
7067
+ fallbackWelcome,
5862
7068
  pollIntervalMs = DEFAULT_POLL_INTERVAL_MS,
5863
7069
  pollTimeoutMs = DEFAULT_POLL_TIMEOUT_MS,
5864
7070
  storageKey = DEFAULT_STORAGE_KEY,
@@ -5867,9 +7073,13 @@ function useExploreChat(options = {}) {
5867
7073
  } = options;
5868
7074
  const client = useWebSDK();
5869
7075
  const promptKey = JSON.stringify(examplePrompts ?? []);
7076
+ const welcomeKey = JSON.stringify(fallbackWelcome ?? null);
5870
7077
  const fallbackCatalog = React.useMemo(
5871
- () => buildFallbackCatalog(JSON.parse(promptKey)),
5872
- [promptKey]
7078
+ () => buildFallbackCatalog(
7079
+ JSON.parse(promptKey),
7080
+ JSON.parse(welcomeKey) ?? void 0
7081
+ ),
7082
+ [promptKey, welcomeKey]
5873
7083
  );
5874
7084
  const [catalog, setCatalog] = React.useState(fallbackCatalog);
5875
7085
  const [messages, setMessages] = React.useState([]);
@@ -7029,6 +8239,93 @@ function logoUrlOf(url) {
7029
8239
  return null;
7030
8240
  }
7031
8241
  }
8242
+ function inlineImageOrigins(products) {
8243
+ const origins = /* @__PURE__ */ new Set();
8244
+ for (const product of products) {
8245
+ let url;
8246
+ try {
8247
+ url = new URL(product.website);
8248
+ } catch {
8249
+ continue;
8250
+ }
8251
+ if (url.protocol !== "https:") continue;
8252
+ const apex = url.hostname.replace(/^www\./, "");
8253
+ const port = url.port ? `:${url.port}` : "";
8254
+ origins.add(`https://${apex}${port}`);
8255
+ origins.add(`https://www.${apex}${port}`);
8256
+ }
8257
+ return origins;
8258
+ }
8259
+ function isInlineImageAllowed(src, origins) {
8260
+ if (typeof src !== "string" || src === "") return false;
8261
+ let url;
8262
+ try {
8263
+ url = new URL(src);
8264
+ } catch {
8265
+ return false;
8266
+ }
8267
+ if (url.protocol !== "https:" || url.username || url.password) return false;
8268
+ return origins.has(url.origin);
8269
+ }
8270
+ var InlineImageScopeContext = React.createContext(null);
8271
+ var InsideLinkContext = React.createContext(false);
8272
+ function AnswerLink(props) {
8273
+ return /* @__PURE__ */ jsxRuntime.jsx(InsideLinkContext.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownLink, { ...props }) });
8274
+ }
8275
+ var INLINE_IMAGE_FRAME = "relative inline-block max-w-full overflow-hidden rounded-xl border border-border bg-muted align-top shadow-sm";
8276
+ function InlineConceptImage({ src, alt }) {
8277
+ const scope = React.useContext(InlineImageScopeContext);
8278
+ const insideLink = React.useContext(InsideLinkContext);
8279
+ if (!scope || !scope.enabled || !isInlineImageAllowed(src, scope.origins) || scope.failed.has(src)) {
8280
+ return null;
8281
+ }
8282
+ const { strings: T, onFailed } = scope;
8283
+ const picture = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8284
+ /* @__PURE__ */ jsxRuntime.jsx(
8285
+ "img",
8286
+ {
8287
+ src,
8288
+ alt: alt ?? "",
8289
+ loading: "lazy",
8290
+ decoding: "async",
8291
+ onError: () => onFailed(src),
8292
+ className: "block h-auto max-h-80 w-auto max-w-full object-contain"
8293
+ }
8294
+ ),
8295
+ /* @__PURE__ */ jsxRuntime.jsx(
8296
+ "span",
8297
+ {
8298
+ "aria-hidden": "true",
8299
+ className: "pointer-events-none absolute left-2 top-2 rounded-full border border-border bg-background/90 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-foreground shadow-sm",
8300
+ children: T.conceptIllustration
8301
+ }
8302
+ )
8303
+ ] });
8304
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-boff-explore": "inline-image", className: "my-3 block", children: insideLink ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: INLINE_IMAGE_FRAME, children: picture }) : /* @__PURE__ */ jsxRuntime.jsxs(
8305
+ "a",
8306
+ {
8307
+ href: src,
8308
+ target: "_blank",
8309
+ rel: "noopener noreferrer",
8310
+ className: cn(
8311
+ INLINE_IMAGE_FRAME,
8312
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
8313
+ ),
8314
+ children: [
8315
+ picture,
8316
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sr-only", children: [
8317
+ "(",
8318
+ T.opensInNewTab,
8319
+ ")"
8320
+ ] })
8321
+ ]
8322
+ }
8323
+ ) });
8324
+ }
8325
+ var ANSWER_MARKDOWN_COMPONENTS = {
8326
+ a: AnswerLink,
8327
+ img: InlineConceptImage
8328
+ };
7032
8329
  function ReferenceCard({
7033
8330
  reference,
7034
8331
  onFollow
@@ -7211,6 +8508,7 @@ function AssistantBubble({
7211
8508
  strings: T,
7212
8509
  message,
7213
8510
  activity,
8511
+ imageOrigins,
7214
8512
  onNavigate,
7215
8513
  anchorRef,
7216
8514
  onFollow,
@@ -7219,6 +8517,25 @@ function AssistantBubble({
7219
8517
  const streaming = message.status === "PENDING" || message.status === "RUNNING";
7220
8518
  const body = message.content || message.partialContent || "";
7221
8519
  const failed = message.status === "FAILED";
8520
+ const completed = message.status === "COMPLETED";
8521
+ const [failedImages, setFailedImages] = React.useState(
8522
+ () => /* @__PURE__ */ new Set()
8523
+ );
8524
+ const markImageFailed = React.useCallback((src) => {
8525
+ setFailedImages(
8526
+ (current) => current.has(src) ? current : new Set(current).add(src)
8527
+ );
8528
+ }, []);
8529
+ const imageScope = React.useMemo(
8530
+ () => ({
8531
+ strings: T,
8532
+ enabled: completed,
8533
+ origins: imageOrigins,
8534
+ failed: failedImages,
8535
+ onFailed: markImageFailed
8536
+ }),
8537
+ [T, completed, imageOrigins, failedImages, markImageFailed]
8538
+ );
7222
8539
  return /* @__PURE__ */ jsxRuntime.jsxs(
7223
8540
  "div",
7224
8541
  {
@@ -7244,7 +8561,7 @@ function AssistantBubble({
7244
8561
  children: [
7245
8562
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TriangleAlert, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-amber-600 dark:text-amber-400" }),
7246
8563
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
7247
- "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
8564
+ T.noAnswer,
7248
8565
  " ",
7249
8566
  /* @__PURE__ */ jsxRuntime.jsx(
7250
8567
  "a",
@@ -7265,11 +8582,11 @@ function AssistantBubble({
7265
8582
  }
7266
8583
  ) : null,
7267
8584
  body ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl rounded-tl-md border border-border bg-card px-4 py-3 shadow-sm", children: [
7268
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: body }) }),
8585
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm boff-explore-body min-w-0 text-card-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(InlineImageScopeContext.Provider, { value: imageScope, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { components: ANSWER_MARKDOWN_COMPONENTS, children: body }) }) }),
7269
8586
  streaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "boff-explore-caret", "aria-hidden": "true" }) : null
7270
8587
  ] }) : null,
7271
8588
  streaming ? /* @__PURE__ */ jsxRuntime.jsx(ThinkingIndicator, { activity }) : null,
7272
- failed && !body ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-2xl rounded-tl-md border border-border bg-muted px-4 py-3 text-sm text-muted-foreground", children: "That answer didn't come through. Try asking again." }) : null,
8589
+ failed && !body ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-2xl rounded-tl-md border border-border bg-muted px-4 py-3 text-sm text-muted-foreground", children: T.answerDidNotArrive }) : null,
7273
8590
  message.references.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7274
8591
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: T.sources }),
7275
8592
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: message.references.map((reference) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -7685,6 +9002,12 @@ function ExplorePage({
7685
9002
  () => typeof window === "undefined" ? void 0 : window.location.href,
7686
9003
  []
7687
9004
  );
9005
+ const activeLocale = React.useMemo(
9006
+ () => resolveExploreLocale(locale),
9007
+ [locale]
9008
+ );
9009
+ const T = React.useMemo(() => exploreStrings(activeLocale), [activeLocale]);
9010
+ const rtl = isRtlLocale(activeLocale);
7688
9011
  const {
7689
9012
  phase,
7690
9013
  catalog,
@@ -7706,7 +9029,15 @@ function ExplorePage({
7706
9029
  recordClick,
7707
9030
  createShareLink,
7708
9031
  isSharedView
7709
- } = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
9032
+ } = useExploreChat({
9033
+ productSlug,
9034
+ pageUrl,
9035
+ onSend,
9036
+ // Locale-aware, so a catalog outage degrades to a translated welcome rather than an
9037
+ // English one. `T.prompts` seeds the chips the same way.
9038
+ examplePrompts: examplePrompts ?? T.prompts,
9039
+ fallbackWelcome: { title: T.welcomeTitle, body: T.welcomeBody }
9040
+ });
7710
9041
  const [draft, setDraft] = React.useState("");
7711
9042
  const textareaRef = React.useRef(null);
7712
9043
  const [historyOpen, setHistoryOpen] = React.useState(false);
@@ -7724,12 +9055,6 @@ function ExplorePage({
7724
9055
  }
7725
9056
  });
7726
9057
  speechStopRef.current = speech.stop;
7727
- const activeLocale = React.useMemo(
7728
- () => resolveExploreLocale(locale),
7729
- [locale]
7730
- );
7731
- const T = React.useMemo(() => exploreStrings(activeLocale), [activeLocale]);
7732
- const rtl = isRtlLocale(activeLocale);
7733
9058
  const [disclaimerOpen, setDisclaimerOpen] = React.useState(false);
7734
9059
  const [staged, setStaged] = React.useState([]);
7735
9060
  const [attachmentNotice, setAttachmentNotice] = React.useState(null);
@@ -7737,7 +9062,7 @@ function ExplorePage({
7737
9062
  const stagedRef = React.useRef([]);
7738
9063
  stagedRef.current = staged;
7739
9064
  const pickQueueRef = React.useRef(Promise.resolve());
7740
- const [shareLabel, setShareLabel] = React.useState("Share");
9065
+ const [shareLabel, setShareLabel] = React.useState(T.share);
7741
9066
  const [shareUrl, setShareUrl] = React.useState(null);
7742
9067
  const scrollRef = React.useRef(null);
7743
9068
  const latestAssistantRef = React.useRef(null);
@@ -7756,6 +9081,10 @@ function ExplorePage({
7756
9081
  () => catalog.products.find((p) => p.slug === focusProduct)?.name ?? null,
7757
9082
  [catalog.products, focusProduct]
7758
9083
  );
9084
+ const imageOrigins = React.useMemo(
9085
+ () => inlineImageOrigins(catalog.products),
9086
+ [catalog.products]
9087
+ );
7759
9088
  React.useEffect(() => {
7760
9089
  const el = textareaRef.current;
7761
9090
  if (!el) return;
@@ -7794,12 +9123,12 @@ function ExplorePage({
7794
9123
  el.scrollTop = el.scrollHeight;
7795
9124
  }, [activity, latestAssistantId, messages]);
7796
9125
  const handleShare = React.useCallback(async () => {
7797
- setShareLabel("Copying\u2026");
9126
+ setShareLabel(T.copying);
7798
9127
  setShareUrl(null);
7799
9128
  const token = await createShareLink();
7800
9129
  if (!token) {
7801
- setShareLabel("Unavailable");
7802
- setTimeout(() => setShareLabel("Share"), 2500);
9130
+ setShareLabel(T.shareUnavailable);
9131
+ setTimeout(() => setShareLabel(T.share), 2500);
7803
9132
  return;
7804
9133
  }
7805
9134
  const url = new URL(pageUrl ?? window.location.href);
@@ -7809,13 +9138,20 @@ function ExplorePage({
7809
9138
  const shareable = url.toString();
7810
9139
  try {
7811
9140
  await navigator.clipboard.writeText(shareable);
7812
- setShareLabel("Copied");
7813
- setTimeout(() => setShareLabel("Share"), 2500);
9141
+ setShareLabel(T.copied);
9142
+ setTimeout(() => setShareLabel(T.share), 2500);
7814
9143
  } catch {
7815
9144
  setShareUrl(shareable);
7816
- setShareLabel("Share");
9145
+ setShareLabel(T.share);
7817
9146
  }
7818
- }, [createShareLink, pageUrl]);
9147
+ }, [
9148
+ createShareLink,
9149
+ pageUrl,
9150
+ T.copied,
9151
+ T.copying,
9152
+ T.share,
9153
+ T.shareUnavailable
9154
+ ]);
7819
9155
  const handleFilesPicked = React.useCallback(
7820
9156
  (picked) => {
7821
9157
  if (!picked || picked.length === 0) return pickQueueRef.current;
@@ -7931,7 +9267,7 @@ function ExplorePage({
7931
9267
  onClick: reset,
7932
9268
  children: [
7933
9269
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "h-3.5 w-3.5" }),
7934
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "New chat" })
9270
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: T.newChat })
7935
9271
  ]
7936
9272
  }
7937
9273
  ),
@@ -7968,7 +9304,8 @@ function ExplorePage({
7968
9304
  children: [
7969
9305
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-3.5 w-3.5" }),
7970
9306
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "hidden sm:inline", children: [
7971
- "History (",
9307
+ T.history,
9308
+ " (",
7972
9309
  history.length,
7973
9310
  ")"
7974
9311
  ] })
@@ -7998,7 +9335,7 @@ function ExplorePage({
7998
9335
  },
7999
9336
  children: [
8000
9337
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }),
8001
- "Clear history"
9338
+ T.clearHistory
8002
9339
  ]
8003
9340
  }
8004
9341
  )
@@ -8078,6 +9415,7 @@ function ExplorePage({
8078
9415
  strings: T,
8079
9416
  message,
8080
9417
  activity,
9418
+ imageOrigins,
8081
9419
  onNavigate,
8082
9420
  anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0,
8083
9421
  onFollow: (kind, url) => recordClick(message.id, kind, url),
@@ -8264,7 +9602,7 @@ function ExplorePage({
8264
9602
  type: "button",
8265
9603
  size: "icon",
8266
9604
  variant: "secondary",
8267
- "aria-label": "Stop generating",
9605
+ "aria-label": T.stop,
8268
9606
  onClick: stop,
8269
9607
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, { className: "h-4 w-4" })
8270
9608
  }
@@ -8275,7 +9613,7 @@ function ExplorePage({
8275
9613
  type: "submit",
8276
9614
  size: "icon",
8277
9615
  disabled: !canSubmit,
8278
- "aria-label": "Send message",
9616
+ "aria-label": T.send,
8279
9617
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-4 w-4" })
8280
9618
  }
8281
9619
  )
@@ -13033,11 +14371,16 @@ function StoreProductDetailPage({
13033
14371
  exports.BlogListPage = BlogListPage;
13034
14372
  exports.BlogPostPage = BlogPostPage;
13035
14373
  exports.Button = Button;
14374
+ exports.CONCEPTS_PATH = CONCEPTS_PATH;
14375
+ exports.CONCEPT_ILLUSTRATION_NOTICE = CONCEPT_ILLUSTRATION_NOTICE;
14376
+ exports.CONCEPT_PATH_PREFIX = CONCEPT_PATH_PREFIX;
13036
14377
  exports.CareersApplyForm = CareersApplyForm;
13037
14378
  exports.CareersSubmissionForm = CareersSubmissionForm;
13038
14379
  exports.CaseStudiesListPage = CaseStudiesListPage;
13039
14380
  exports.CaseStudyPage = CaseStudyPage;
13040
14381
  exports.ChangelogPage = ChangelogPage;
14382
+ exports.ConceptDetailPage = ConceptDetailPage;
14383
+ exports.ConceptsPage = ConceptsPage;
13041
14384
  exports.ContactPage = ContactPage;
13042
14385
  exports.ContentRenderer = ContentRenderer;
13043
14386
  exports.ContractsPage = ContractsPage;
@@ -13086,12 +14429,14 @@ exports.WebsiteSwitcher = WebsiteSwitcher;
13086
14429
  exports.buttonVariants = buttonVariants;
13087
14430
  exports.classifyExploreError = classifyExploreError;
13088
14431
  exports.cn = cn;
14432
+ exports.conceptPath = conceptPath;
13089
14433
  exports.detectElectronPlatform = detectElectronPlatform;
13090
14434
  exports.fetchPublicJobPosting = fetchPublicJobPosting;
13091
14435
  exports.fetchPublicJobPostings = fetchPublicJobPostings;
13092
14436
  exports.fetchPublicJobPostingsForSubmission = fetchPublicJobPostingsForSubmission;
13093
14437
  exports.formatDownloads = formatDownloads;
13094
14438
  exports.formatPrice = formatPrice2;
14439
+ exports.getConceptBySlug = getConceptBySlug;
13095
14440
  exports.getRecaptchaV3Token = getRecaptchaV3Token;
13096
14441
  exports.isValidUrl = isValidUrl;
13097
14442
  exports.loadRecaptchaV3 = loadRecaptchaV3;