@burdenoff/website-sdk 2026.924.10 → 2026.924.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/explore.js +177 -42
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +177 -42
- package/dist/components/explore.mjs.map +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +56 -7
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +56 -7
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +177 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -42
- package/dist/index.mjs.map +1 -1
- package/dist/{use-progressive-reveal-Cmy8bA7L.d.mts → use-progressive-reveal-BBLRAnbU.d.mts} +6 -1
- package/dist/{use-progressive-reveal-DHPGGxZu.d.ts → use-progressive-reveal-myNKWb6S.d.ts} +6 -1
- package/package.json +1 -1
|
@@ -2033,6 +2033,45 @@ function buildFallbackCatalog(examplePrompts, welcome) {
|
|
|
2033
2033
|
conceptHighlights: []
|
|
2034
2034
|
};
|
|
2035
2035
|
}
|
|
2036
|
+
var BAKED_CATALOG_ELEMENT_ID = "boff-explore-catalog";
|
|
2037
|
+
function bakedCatalogLocale() {
|
|
2038
|
+
if (typeof navigator === "undefined") return "";
|
|
2039
|
+
return (navigator.language || "").toLowerCase().split("-")[0] ?? "";
|
|
2040
|
+
}
|
|
2041
|
+
function snapshotBakedElement() {
|
|
2042
|
+
if (typeof document === "undefined") return null;
|
|
2043
|
+
const el = document.getElementById(BAKED_CATALOG_ELEMENT_ID);
|
|
2044
|
+
if (!el || el.tagName !== "SCRIPT" || el.getAttribute("type") !== "application/json")
|
|
2045
|
+
return null;
|
|
2046
|
+
return {
|
|
2047
|
+
product: el.getAttribute("data-product") ?? "",
|
|
2048
|
+
locale: el.getAttribute("data-locale") ?? "",
|
|
2049
|
+
text: el.textContent ?? ""
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
2052
|
+
var BAKED_AT_LOAD = snapshotBakedElement();
|
|
2053
|
+
function isCatalogShape(value) {
|
|
2054
|
+
if (!value || typeof value !== "object") return false;
|
|
2055
|
+
const c = value;
|
|
2056
|
+
const listOrAbsent = (v) => v === void 0 || v === null || Array.isArray(v);
|
|
2057
|
+
const textOrAbsent = (v) => v === void 0 || v === null || typeof v === "string";
|
|
2058
|
+
return (c["enabled"] === void 0 || typeof c["enabled"] === "boolean") && listOrAbsent(c["products"]) && listOrAbsent(c["examplePrompts"]) && listOrAbsent(c["conceptHighlights"]) && textOrAbsent(c["welcomeTitle"]) && textOrAbsent(c["welcomeBody"]);
|
|
2059
|
+
}
|
|
2060
|
+
function readBakedCatalog(productSlug) {
|
|
2061
|
+
const baked = snapshotBakedElement() ?? BAKED_AT_LOAD;
|
|
2062
|
+
if (!baked) return null;
|
|
2063
|
+
if (baked.product !== (productSlug ?? "")) return null;
|
|
2064
|
+
if (baked.locale && baked.locale !== bakedCatalogLocale()) return null;
|
|
2065
|
+
try {
|
|
2066
|
+
const parsed = JSON.parse(baked.text);
|
|
2067
|
+
return isCatalogShape(parsed) ? parsed : null;
|
|
2068
|
+
} catch {
|
|
2069
|
+
return null;
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
function serializeBakedCatalog(raw) {
|
|
2073
|
+
return JSON.stringify(raw).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
2074
|
+
}
|
|
2036
2075
|
function normalizeCatalog(raw, fallback) {
|
|
2037
2076
|
return {
|
|
2038
2077
|
enabled: raw.enabled !== false,
|
|
@@ -2282,9 +2321,17 @@ function useExploreChat(options = {}) {
|
|
|
2282
2321
|
),
|
|
2283
2322
|
[promptKey, welcomeKey]
|
|
2284
2323
|
);
|
|
2285
|
-
const [
|
|
2324
|
+
const [bakedRaw] = useState(
|
|
2325
|
+
() => readBakedCatalog(productSlug)
|
|
2326
|
+
);
|
|
2327
|
+
const [catalog, setCatalog] = useState(
|
|
2328
|
+
() => bakedRaw ? normalizeCatalog(bakedRaw, fallbackCatalog) : fallbackCatalog
|
|
2329
|
+
);
|
|
2330
|
+
const [serverCatalogRaw, setServerCatalogRaw] = useState(bakedRaw);
|
|
2286
2331
|
const [messages, setMessages] = useState([]);
|
|
2287
|
-
const [phase, setPhase] = useState(
|
|
2332
|
+
const [phase, setPhase] = useState(
|
|
2333
|
+
() => bakedRaw ? bakedRaw.enabled === false ? "disabled" : "ready" : "loading"
|
|
2334
|
+
);
|
|
2288
2335
|
const [error, setError] = useState(null);
|
|
2289
2336
|
const [remainingToday, setRemainingToday] = useState(null);
|
|
2290
2337
|
const [focusProduct, setFocusProductState] = useState(null);
|
|
@@ -2302,7 +2349,7 @@ function useExploreChat(options = {}) {
|
|
|
2302
2349
|
shareTokenRef.current = readShareToken();
|
|
2303
2350
|
}
|
|
2304
2351
|
const isSharedView = shareTokenRef.current !== null;
|
|
2305
|
-
const catalogRef = useRef(
|
|
2352
|
+
const catalogRef = useRef(catalog);
|
|
2306
2353
|
const turnCountRef = useRef(0);
|
|
2307
2354
|
const focusProductRef = useRef(null);
|
|
2308
2355
|
const lastSentTextRef = useRef(null);
|
|
@@ -2448,25 +2495,29 @@ function useExploreChat(options = {}) {
|
|
|
2448
2495
|
const raw = res.data?.exploreCatalog;
|
|
2449
2496
|
if (res.errors?.length || !raw) {
|
|
2450
2497
|
console.warn(
|
|
2451
|
-
"[WebSDK] exploreCatalog unavailable \u2014
|
|
2498
|
+
"[WebSDK] exploreCatalog unavailable \u2014 keeping the catalog the page started with",
|
|
2452
2499
|
res.errors?.[0]?.message
|
|
2453
2500
|
);
|
|
2454
2501
|
setPhase((prev) => prev === "loading" ? "ready" : prev);
|
|
2455
2502
|
return;
|
|
2456
2503
|
}
|
|
2457
|
-
const next = normalizeCatalog(
|
|
2504
|
+
const next = normalizeCatalog(
|
|
2505
|
+
raw,
|
|
2506
|
+
bakedRaw ? normalizeCatalog(bakedRaw, fallbackCatalog) : fallbackCatalog
|
|
2507
|
+
);
|
|
2458
2508
|
setCatalog(next);
|
|
2509
|
+
setServerCatalogRaw(raw);
|
|
2459
2510
|
catalogRef.current = next;
|
|
2460
2511
|
setPhase((prev) => {
|
|
2461
2512
|
if (!next.enabled) return "disabled";
|
|
2462
|
-
return prev === "loading" ? "ready" : prev;
|
|
2513
|
+
return prev === "loading" || prev === "disabled" ? "ready" : prev;
|
|
2463
2514
|
});
|
|
2464
2515
|
};
|
|
2465
2516
|
void load();
|
|
2466
2517
|
return () => {
|
|
2467
2518
|
cancelled = true;
|
|
2468
2519
|
};
|
|
2469
|
-
}, [client, productSlug, fallbackCatalog]);
|
|
2520
|
+
}, [client, productSlug, fallbackCatalog, bakedRaw]);
|
|
2470
2521
|
const startPolling = useCallback(
|
|
2471
2522
|
(conversationToken, messageId) => {
|
|
2472
2523
|
pollGenerationRef.current += 1;
|
|
@@ -2934,6 +2985,7 @@ function useExploreChat(options = {}) {
|
|
|
2934
2985
|
return {
|
|
2935
2986
|
phase,
|
|
2936
2987
|
catalog,
|
|
2988
|
+
serverCatalogRaw,
|
|
2937
2989
|
messages,
|
|
2938
2990
|
activity,
|
|
2939
2991
|
remainingToday,
|
|
@@ -3892,6 +3944,48 @@ var EXPLORE_CSS = `
|
|
|
3892
3944
|
}
|
|
3893
3945
|
.boff-explore-strip::-webkit-scrollbar { display: none; }
|
|
3894
3946
|
|
|
3947
|
+
/* The product chips run past the edge of their row (there are 38). A hard edge sliced the
|
|
3948
|
+
last visible chip mid-word ("Bi", "BigC") right beside "All 38"; a short fade says "there
|
|
3949
|
+
is more this way" instead. A mask carries only alpha, so the gradient's colour is a token
|
|
3950
|
+
that never shows. Mirrored for right-to-left locales, whose row runs the other way. */
|
|
3951
|
+
.boff-explore-chips-fade {
|
|
3952
|
+
/* Focus scrolling honours scroll-padding, so a tabbed-to chip is brought clear of the fade
|
|
3953
|
+
rather than left half-hidden under it. */
|
|
3954
|
+
scroll-padding-inline-end: 2rem;
|
|
3955
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3956
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3957
|
+
}
|
|
3958
|
+
/* A fade over a fixed edge would leave the LAST chip under it once the row is scrolled to
|
|
3959
|
+
the end \u2014 the visitor could never read it. A trailing spacer the width of the fade lets
|
|
3960
|
+
the final chip scroll clear of it. A pseudo-element rather than padding: trailing padding
|
|
3961
|
+
on a flex scroll container is not reliably part of its scrollable overflow. */
|
|
3962
|
+
.boff-explore-chips-fade::after {
|
|
3963
|
+
content: "";
|
|
3964
|
+
flex: 0 0 2rem;
|
|
3965
|
+
}
|
|
3966
|
+
[dir="rtl"] .boff-explore-chips-fade {
|
|
3967
|
+
-webkit-mask-image: linear-gradient(to left, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3968
|
+
mask-image: linear-gradient(to left, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
3969
|
+
}
|
|
3970
|
+
|
|
3971
|
+
/* The concept rail had the chip row's problem: the card at its edge was cut hard mid-word
|
|
3972
|
+
("Apparatus Rig", "CONCEPT ILLUST") on a dozen sites. It fades an edge only while there are
|
|
3973
|
+
more cards beyond it \u2014 the same state that lights the arrow on that side \u2014 so a rail
|
|
3974
|
+
scrolled to its end shows its last card whole. Physical edges, because that state is
|
|
3975
|
+
physical: it is measured from the left in either reading direction. */
|
|
3976
|
+
.boff-explore-rail-fade-left {
|
|
3977
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem);
|
|
3978
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem);
|
|
3979
|
+
}
|
|
3980
|
+
.boff-explore-rail-fade-right {
|
|
3981
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
3982
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
3983
|
+
}
|
|
3984
|
+
.boff-explore-rail-fade-left.boff-explore-rail-fade-right {
|
|
3985
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
3986
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3895
3989
|
@keyframes boff-explore-fade-in {
|
|
3896
3990
|
from { opacity: 0; transform: translateY(2px); }
|
|
3897
3991
|
to { opacity: 1; transform: none; }
|
|
@@ -3968,10 +4062,10 @@ var EXPLORE_CSS = `
|
|
|
3968
4062
|
Colour comes from the product's --primary token, so it is whatever that site's palette
|
|
3969
4063
|
already is, never a colour chosen here. */
|
|
3970
4064
|
.boff-explore-invite {
|
|
3971
|
-
border-color: hsl(var(--primary) / 0.
|
|
4065
|
+
border-color: hsl(var(--primary) / 0.6);
|
|
3972
4066
|
box-shadow:
|
|
3973
|
-
0 0 0 4px hsl(var(--primary) / 0.
|
|
3974
|
-
0 8px 24px -12px hsl(var(--primary) / 0.
|
|
4067
|
+
0 0 0 4px hsl(var(--primary) / 0.12),
|
|
4068
|
+
0 8px 24px -12px hsl(var(--primary) / 0.55);
|
|
3975
4069
|
animation: boff-explore-breathe 3.2s ease-in-out infinite;
|
|
3976
4070
|
}
|
|
3977
4071
|
/* Focus and typing both mean "I have found it", and the hint has done its job. */
|
|
@@ -3981,8 +4075,8 @@ var EXPLORE_CSS = `
|
|
|
3981
4075
|
box-shadow: 0 0 0 4px hsl(var(--primary) / 0.10);
|
|
3982
4076
|
}
|
|
3983
4077
|
@keyframes boff-explore-breathe {
|
|
3984
|
-
0%, 100% { box-shadow: 0 0 0 4px hsl(var(--primary) / 0.
|
|
3985
|
-
50% { box-shadow: 0 0 0 7px hsl(var(--primary) / 0.
|
|
4078
|
+
0%, 100% { box-shadow: 0 0 0 4px hsl(var(--primary) / 0.10), 0 8px 24px -12px hsl(var(--primary) / 0.50); }
|
|
4079
|
+
50% { box-shadow: 0 0 0 7px hsl(var(--primary) / 0.18), 0 8px 28px -12px hsl(var(--primary) / 0.65); }
|
|
3986
4080
|
}
|
|
3987
4081
|
|
|
3988
4082
|
/* Every one of the above is decoration. Reduced motion removes the movement and keeps the
|
|
@@ -4070,8 +4164,18 @@ var EXPLORE_CSS = `
|
|
|
4070
4164
|
.boff-explore-scroll .boff-explore-capabilities { display: none; }
|
|
4071
4165
|
}
|
|
4072
4166
|
@container boff-explore-pane (min-width: ${toRem(WELCOME_FIT_MIN_WIDTH_PX)}) and (max-height: ${toRem(WELCOME_FIT_STEP_PX[1])}) {
|
|
4073
|
-
/* Step 2.
|
|
4167
|
+
/* Step 2. At a 4:1 crop the picture is ~44px tall, and the full-size caveat badge covered
|
|
4168
|
+
half of it \u2014 on ten sites, every card, whenever the consent banner was up. It stays (the
|
|
4169
|
+
picture is still a mockup), just smaller and tucked into the corner. */
|
|
4074
4170
|
.boff-explore-scroll .boff-explore-concept-media { aspect-ratio: 4 / 1; }
|
|
4171
|
+
.boff-explore-scroll .boff-explore-concept-badge {
|
|
4172
|
+
top: 0.25rem;
|
|
4173
|
+
left: 0.25rem;
|
|
4174
|
+
padding: 0 0.3125rem;
|
|
4175
|
+
font-size: 0.5rem;
|
|
4176
|
+
line-height: 0.75rem;
|
|
4177
|
+
letter-spacing: 0.02em;
|
|
4178
|
+
}
|
|
4075
4179
|
}
|
|
4076
4180
|
@container boff-explore-pane (min-width: ${toRem(WELCOME_FIT_MIN_WIDTH_PX)}) and (max-height: ${toRem(WELCOME_FIT_STEP_PX[2])}) {
|
|
4077
4181
|
/* Step 3. Title-only cards. The "concept illustration" caveat lives on the picture, so it
|
|
@@ -5230,6 +5334,7 @@ function ErrorBanner({
|
|
|
5230
5334
|
}
|
|
5231
5335
|
function PromptCarousel({
|
|
5232
5336
|
strings: T,
|
|
5337
|
+
label,
|
|
5233
5338
|
prompts,
|
|
5234
5339
|
onPrompt,
|
|
5235
5340
|
disabled
|
|
@@ -5261,7 +5366,7 @@ function PromptCarousel({
|
|
|
5261
5366
|
return /* @__PURE__ */ jsxs(
|
|
5262
5367
|
"div",
|
|
5263
5368
|
{
|
|
5264
|
-
className: "
|
|
5369
|
+
className: "grid min-w-0 touch-pan-y grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-x-1.5 gap-y-1.5 sm:grid-cols-[auto_minmax(0,1fr)_auto]",
|
|
5265
5370
|
role: "group",
|
|
5266
5371
|
"aria-roledescription": "carousel",
|
|
5267
5372
|
"aria-label": "Example questions",
|
|
@@ -5271,13 +5376,14 @@ function PromptCarousel({
|
|
|
5271
5376
|
onBlurCapture: () => setPaused(false),
|
|
5272
5377
|
...swipe,
|
|
5273
5378
|
children: [
|
|
5379
|
+
/* @__PURE__ */ jsx("p", { className: "col-start-1 row-start-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground sm:col-span-3", children: label }),
|
|
5274
5380
|
count > 1 ? /* @__PURE__ */ jsx(
|
|
5275
5381
|
"button",
|
|
5276
5382
|
{
|
|
5277
5383
|
type: "button",
|
|
5278
5384
|
"aria-label": T.prevSuggestion,
|
|
5279
5385
|
onClick: () => go(-1),
|
|
5280
|
-
className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
5386
|
+
className: "col-start-2 row-start-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:col-start-1 sm:row-start-2",
|
|
5281
5387
|
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
5282
5388
|
}
|
|
5283
5389
|
) : null,
|
|
@@ -5291,14 +5397,23 @@ function PromptCarousel({
|
|
|
5291
5397
|
"aria-label": `Ask: ${current}`,
|
|
5292
5398
|
"aria-live": paused ? "polite" : "off",
|
|
5293
5399
|
onClick: () => onPrompt(current),
|
|
5294
|
-
className:
|
|
5400
|
+
className: cn(
|
|
5401
|
+
"group col-span-3 row-start-2 flex min-w-0 items-center gap-2 rounded-full border border-border bg-card px-4 py-2 max-sm:min-h-[3.625rem] max-sm:rounded-2xl text-left text-sm text-card-foreground shadow-sm transition-colors hover:border-primary/50 hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
5402
|
+
count > 1 ? "sm:col-span-1 sm:col-start-2" : "sm:col-span-3"
|
|
5403
|
+
),
|
|
5295
5404
|
children: [
|
|
5296
5405
|
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
5297
|
-
/* @__PURE__ */ jsx(
|
|
5298
|
-
|
|
5406
|
+
/* @__PURE__ */ jsx(
|
|
5407
|
+
"span",
|
|
5408
|
+
{
|
|
5409
|
+
className: "boff-explore-fade min-w-0 max-sm:line-clamp-3 sm:truncate",
|
|
5410
|
+
children: current
|
|
5411
|
+
},
|
|
5412
|
+
current
|
|
5413
|
+
),
|
|
5414
|
+
/* @__PURE__ */ jsx(ArrowUp, { className: "ml-auto h-3.5 w-3.5 shrink-0 rotate-45 text-muted-foreground transition-colors group-hover:text-primary max-sm:hidden" })
|
|
5299
5415
|
]
|
|
5300
|
-
}
|
|
5301
|
-
current
|
|
5416
|
+
}
|
|
5302
5417
|
),
|
|
5303
5418
|
count > 1 ? /* @__PURE__ */ jsx(
|
|
5304
5419
|
"button",
|
|
@@ -5306,7 +5421,7 @@ function PromptCarousel({
|
|
|
5306
5421
|
type: "button",
|
|
5307
5422
|
"aria-label": T.nextSuggestion,
|
|
5308
5423
|
onClick: () => go(1),
|
|
5309
|
-
className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
5424
|
+
className: "col-start-3 row-start-1 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:row-start-2",
|
|
5310
5425
|
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
5311
5426
|
}
|
|
5312
5427
|
) : null
|
|
@@ -5337,7 +5452,7 @@ function ProductStrip({
|
|
|
5337
5452
|
{
|
|
5338
5453
|
className: cn(
|
|
5339
5454
|
"boff-explore-strip flex min-w-0 flex-1 gap-2",
|
|
5340
|
-
expanded ? "flex-wrap" : "flex-nowrap overflow-x-auto"
|
|
5455
|
+
expanded ? "flex-wrap" : "boff-explore-chips-fade flex-nowrap overflow-x-auto"
|
|
5341
5456
|
),
|
|
5342
5457
|
children: [
|
|
5343
5458
|
/* @__PURE__ */ jsx(
|
|
@@ -5405,8 +5520,11 @@ function ConceptStrip({
|
|
|
5405
5520
|
const measureRail = useCallback(() => {
|
|
5406
5521
|
const el = railRef.current;
|
|
5407
5522
|
if (!el) return;
|
|
5408
|
-
|
|
5409
|
-
|
|
5523
|
+
const max = el.scrollWidth - el.clientWidth;
|
|
5524
|
+
const rtl = typeof getComputedStyle === "function" && getComputedStyle(el).direction === "rtl";
|
|
5525
|
+
const fromLeft = rtl ? max + el.scrollLeft : el.scrollLeft;
|
|
5526
|
+
setCanLeft(fromLeft > 1);
|
|
5527
|
+
setCanRight(fromLeft < max - 1);
|
|
5410
5528
|
}, []);
|
|
5411
5529
|
useEffect(() => {
|
|
5412
5530
|
const el = railRef.current;
|
|
@@ -5475,11 +5593,15 @@ function ConceptStrip({
|
|
|
5475
5593
|
onScroll: measureRail,
|
|
5476
5594
|
"data-boff-explore": "concept-strip",
|
|
5477
5595
|
"aria-label": T.conceptStripLabel,
|
|
5478
|
-
className:
|
|
5596
|
+
className: cn(
|
|
5597
|
+
"boff-explore-strip flex min-w-0 snap-x gap-3 overflow-x-auto pb-1 sm:mx-10",
|
|
5598
|
+
canLeft && "boff-explore-rail-fade-left",
|
|
5599
|
+
canRight && "boff-explore-rail-fade-right"
|
|
5600
|
+
),
|
|
5479
5601
|
children: visible.map((highlight) => /* @__PURE__ */ jsx(
|
|
5480
5602
|
"li",
|
|
5481
5603
|
{
|
|
5482
|
-
className: "shrink-0 snap-start",
|
|
5604
|
+
className: "flex shrink-0 snap-start",
|
|
5483
5605
|
children: /* @__PURE__ */ jsxs(
|
|
5484
5606
|
"button",
|
|
5485
5607
|
{
|
|
@@ -5515,14 +5637,14 @@ function ConceptStrip({
|
|
|
5515
5637
|
"span",
|
|
5516
5638
|
{
|
|
5517
5639
|
"aria-hidden": "true",
|
|
5518
|
-
className: "pointer-events-none absolute left-1.5 top-1.5 rounded-full border border-border bg-background/90 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-foreground",
|
|
5640
|
+
className: "boff-explore-concept-badge pointer-events-none absolute left-1.5 top-1.5 rounded-full border border-border bg-background/90 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-foreground",
|
|
5519
5641
|
children: T.conceptIllustration
|
|
5520
5642
|
}
|
|
5521
5643
|
)
|
|
5522
5644
|
] }),
|
|
5523
|
-
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col gap-0.5 p-2.5", children: [
|
|
5645
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5 p-2.5", children: [
|
|
5524
5646
|
/* @__PURE__ */ jsx("span", { className: "line-clamp-2 text-xs font-semibold leading-snug text-card-foreground", children: highlight.title }),
|
|
5525
|
-
/* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: highlight.productName })
|
|
5647
|
+
/* @__PURE__ */ jsx("span", { className: "mt-auto truncate text-[11px] text-muted-foreground", children: highlight.productName })
|
|
5526
5648
|
] })
|
|
5527
5649
|
]
|
|
5528
5650
|
}
|
|
@@ -5670,18 +5792,16 @@ function WelcomeState({
|
|
|
5670
5792
|
},
|
|
5671
5793
|
i
|
|
5672
5794
|
)) }),
|
|
5673
|
-
prompts.length > 0 ? /* @__PURE__ */
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
)
|
|
5684
|
-
] }) : null,
|
|
5795
|
+
prompts.length > 0 ? /* @__PURE__ */ jsx("div", { className: "boff-explore-rise boff-explore-rise-2 mt-4", children: /* @__PURE__ */ jsx(
|
|
5796
|
+
PromptCarousel,
|
|
5797
|
+
{
|
|
5798
|
+
strings: T,
|
|
5799
|
+
label: T.tryAsking,
|
|
5800
|
+
prompts,
|
|
5801
|
+
onPrompt,
|
|
5802
|
+
disabled
|
|
5803
|
+
}
|
|
5804
|
+
) }) : null,
|
|
5685
5805
|
products.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "boff-explore-rise boff-explore-rise-3 mt-4", children: [
|
|
5686
5806
|
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: T.focusProduct }),
|
|
5687
5807
|
/* @__PURE__ */ jsx(
|
|
@@ -5739,6 +5859,7 @@ function ExplorePage({
|
|
|
5739
5859
|
const {
|
|
5740
5860
|
phase,
|
|
5741
5861
|
catalog,
|
|
5862
|
+
serverCatalogRaw,
|
|
5742
5863
|
messages,
|
|
5743
5864
|
activity,
|
|
5744
5865
|
remainingToday,
|
|
@@ -6170,6 +6291,10 @@ function ExplorePage({
|
|
|
6170
6291
|
const captchaOn = Boolean(
|
|
6171
6292
|
catalog.captchaRequired && catalog.recaptchaSiteKey
|
|
6172
6293
|
);
|
|
6294
|
+
const bakedCatalogJson = useMemo(
|
|
6295
|
+
() => serverCatalogRaw && serverCatalogRaw.enabled !== false ? serializeBakedCatalog(serverCatalogRaw) : null,
|
|
6296
|
+
[serverCatalogRaw]
|
|
6297
|
+
);
|
|
6173
6298
|
const rootStyle = {};
|
|
6174
6299
|
if (heightMode === "viewport") {
|
|
6175
6300
|
rootStyle["--boff-explore-offset"] = paneOffset === null ? normalizeOffset(viewportOffset) : `${paneOffset}px`;
|
|
@@ -6209,6 +6334,16 @@ function ExplorePage({
|
|
|
6209
6334
|
),
|
|
6210
6335
|
/* @__PURE__ */ jsx(ProseStyles, {}),
|
|
6211
6336
|
/* @__PURE__ */ jsx(ExploreStyles, {}),
|
|
6337
|
+
bakedCatalogJson ? /* @__PURE__ */ jsx(
|
|
6338
|
+
"script",
|
|
6339
|
+
{
|
|
6340
|
+
id: BAKED_CATALOG_ELEMENT_ID,
|
|
6341
|
+
type: "application/json",
|
|
6342
|
+
"data-product": productSlug ?? "",
|
|
6343
|
+
"data-locale": bakedCatalogLocale(),
|
|
6344
|
+
dangerouslySetInnerHTML: { __html: bakedCatalogJson }
|
|
6345
|
+
}
|
|
6346
|
+
) : null,
|
|
6212
6347
|
/* @__PURE__ */ jsx(ExploreAnswerStyles, {}),
|
|
6213
6348
|
!showWelcome ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 border-b border-border px-4 py-2.5", children: [
|
|
6214
6349
|
/* @__PURE__ */ jsx(
|
|
@@ -6683,7 +6818,7 @@ function ExplorePage({
|
|
|
6683
6818
|
)
|
|
6684
6819
|
] }) : null,
|
|
6685
6820
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
6686
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: T.disclaimerShort }),
|
|
6821
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 sm:truncate", children: T.disclaimerShort }),
|
|
6687
6822
|
/* @__PURE__ */ jsx(
|
|
6688
6823
|
"button",
|
|
6689
6824
|
{
|