@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
package/dist/index.mjs
CHANGED
|
@@ -9004,6 +9004,45 @@ function buildFallbackCatalog(examplePrompts, welcome) {
|
|
|
9004
9004
|
conceptHighlights: []
|
|
9005
9005
|
};
|
|
9006
9006
|
}
|
|
9007
|
+
var BAKED_CATALOG_ELEMENT_ID = "boff-explore-catalog";
|
|
9008
|
+
function bakedCatalogLocale() {
|
|
9009
|
+
if (typeof navigator === "undefined") return "";
|
|
9010
|
+
return (navigator.language || "").toLowerCase().split("-")[0] ?? "";
|
|
9011
|
+
}
|
|
9012
|
+
function snapshotBakedElement() {
|
|
9013
|
+
if (typeof document === "undefined") return null;
|
|
9014
|
+
const el = document.getElementById(BAKED_CATALOG_ELEMENT_ID);
|
|
9015
|
+
if (!el || el.tagName !== "SCRIPT" || el.getAttribute("type") !== "application/json")
|
|
9016
|
+
return null;
|
|
9017
|
+
return {
|
|
9018
|
+
product: el.getAttribute("data-product") ?? "",
|
|
9019
|
+
locale: el.getAttribute("data-locale") ?? "",
|
|
9020
|
+
text: el.textContent ?? ""
|
|
9021
|
+
};
|
|
9022
|
+
}
|
|
9023
|
+
var BAKED_AT_LOAD = snapshotBakedElement();
|
|
9024
|
+
function isCatalogShape(value) {
|
|
9025
|
+
if (!value || typeof value !== "object") return false;
|
|
9026
|
+
const c = value;
|
|
9027
|
+
const listOrAbsent = (v) => v === void 0 || v === null || Array.isArray(v);
|
|
9028
|
+
const textOrAbsent = (v) => v === void 0 || v === null || typeof v === "string";
|
|
9029
|
+
return (c["enabled"] === void 0 || typeof c["enabled"] === "boolean") && listOrAbsent(c["products"]) && listOrAbsent(c["examplePrompts"]) && listOrAbsent(c["conceptHighlights"]) && textOrAbsent(c["welcomeTitle"]) && textOrAbsent(c["welcomeBody"]);
|
|
9030
|
+
}
|
|
9031
|
+
function readBakedCatalog(productSlug) {
|
|
9032
|
+
const baked = snapshotBakedElement() ?? BAKED_AT_LOAD;
|
|
9033
|
+
if (!baked) return null;
|
|
9034
|
+
if (baked.product !== (productSlug ?? "")) return null;
|
|
9035
|
+
if (baked.locale && baked.locale !== bakedCatalogLocale()) return null;
|
|
9036
|
+
try {
|
|
9037
|
+
const parsed = JSON.parse(baked.text);
|
|
9038
|
+
return isCatalogShape(parsed) ? parsed : null;
|
|
9039
|
+
} catch {
|
|
9040
|
+
return null;
|
|
9041
|
+
}
|
|
9042
|
+
}
|
|
9043
|
+
function serializeBakedCatalog(raw) {
|
|
9044
|
+
return JSON.stringify(raw).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
9045
|
+
}
|
|
9007
9046
|
function normalizeCatalog(raw, fallback) {
|
|
9008
9047
|
return {
|
|
9009
9048
|
enabled: raw.enabled !== false,
|
|
@@ -9253,9 +9292,17 @@ function useExploreChat(options = {}) {
|
|
|
9253
9292
|
),
|
|
9254
9293
|
[promptKey, welcomeKey]
|
|
9255
9294
|
);
|
|
9256
|
-
const [
|
|
9295
|
+
const [bakedRaw] = useState(
|
|
9296
|
+
() => readBakedCatalog(productSlug)
|
|
9297
|
+
);
|
|
9298
|
+
const [catalog, setCatalog] = useState(
|
|
9299
|
+
() => bakedRaw ? normalizeCatalog(bakedRaw, fallbackCatalog) : fallbackCatalog
|
|
9300
|
+
);
|
|
9301
|
+
const [serverCatalogRaw, setServerCatalogRaw] = useState(bakedRaw);
|
|
9257
9302
|
const [messages, setMessages] = useState([]);
|
|
9258
|
-
const [phase, setPhase] = useState(
|
|
9303
|
+
const [phase, setPhase] = useState(
|
|
9304
|
+
() => bakedRaw ? bakedRaw.enabled === false ? "disabled" : "ready" : "loading"
|
|
9305
|
+
);
|
|
9259
9306
|
const [error, setError] = useState(null);
|
|
9260
9307
|
const [remainingToday, setRemainingToday] = useState(null);
|
|
9261
9308
|
const [focusProduct, setFocusProductState] = useState(null);
|
|
@@ -9273,7 +9320,7 @@ function useExploreChat(options = {}) {
|
|
|
9273
9320
|
shareTokenRef.current = readShareToken();
|
|
9274
9321
|
}
|
|
9275
9322
|
const isSharedView = shareTokenRef.current !== null;
|
|
9276
|
-
const catalogRef = useRef(
|
|
9323
|
+
const catalogRef = useRef(catalog);
|
|
9277
9324
|
const turnCountRef = useRef(0);
|
|
9278
9325
|
const focusProductRef = useRef(null);
|
|
9279
9326
|
const lastSentTextRef = useRef(null);
|
|
@@ -9419,25 +9466,29 @@ function useExploreChat(options = {}) {
|
|
|
9419
9466
|
const raw = res.data?.exploreCatalog;
|
|
9420
9467
|
if (res.errors?.length || !raw) {
|
|
9421
9468
|
console.warn(
|
|
9422
|
-
"[WebSDK] exploreCatalog unavailable \u2014
|
|
9469
|
+
"[WebSDK] exploreCatalog unavailable \u2014 keeping the catalog the page started with",
|
|
9423
9470
|
res.errors?.[0]?.message
|
|
9424
9471
|
);
|
|
9425
9472
|
setPhase((prev) => prev === "loading" ? "ready" : prev);
|
|
9426
9473
|
return;
|
|
9427
9474
|
}
|
|
9428
|
-
const next = normalizeCatalog(
|
|
9475
|
+
const next = normalizeCatalog(
|
|
9476
|
+
raw,
|
|
9477
|
+
bakedRaw ? normalizeCatalog(bakedRaw, fallbackCatalog) : fallbackCatalog
|
|
9478
|
+
);
|
|
9429
9479
|
setCatalog(next);
|
|
9480
|
+
setServerCatalogRaw(raw);
|
|
9430
9481
|
catalogRef.current = next;
|
|
9431
9482
|
setPhase((prev) => {
|
|
9432
9483
|
if (!next.enabled) return "disabled";
|
|
9433
|
-
return prev === "loading" ? "ready" : prev;
|
|
9484
|
+
return prev === "loading" || prev === "disabled" ? "ready" : prev;
|
|
9434
9485
|
});
|
|
9435
9486
|
};
|
|
9436
9487
|
void load();
|
|
9437
9488
|
return () => {
|
|
9438
9489
|
cancelled = true;
|
|
9439
9490
|
};
|
|
9440
|
-
}, [client, productSlug, fallbackCatalog]);
|
|
9491
|
+
}, [client, productSlug, fallbackCatalog, bakedRaw]);
|
|
9441
9492
|
const startPolling = useCallback(
|
|
9442
9493
|
(conversationToken, messageId) => {
|
|
9443
9494
|
pollGenerationRef.current += 1;
|
|
@@ -9905,6 +9956,7 @@ function useExploreChat(options = {}) {
|
|
|
9905
9956
|
return {
|
|
9906
9957
|
phase,
|
|
9907
9958
|
catalog,
|
|
9959
|
+
serverCatalogRaw,
|
|
9908
9960
|
messages,
|
|
9909
9961
|
activity,
|
|
9910
9962
|
remainingToday,
|
|
@@ -10738,6 +10790,48 @@ var EXPLORE_CSS = `
|
|
|
10738
10790
|
}
|
|
10739
10791
|
.boff-explore-strip::-webkit-scrollbar { display: none; }
|
|
10740
10792
|
|
|
10793
|
+
/* The product chips run past the edge of their row (there are 38). A hard edge sliced the
|
|
10794
|
+
last visible chip mid-word ("Bi", "BigC") right beside "All 38"; a short fade says "there
|
|
10795
|
+
is more this way" instead. A mask carries only alpha, so the gradient's colour is a token
|
|
10796
|
+
that never shows. Mirrored for right-to-left locales, whose row runs the other way. */
|
|
10797
|
+
.boff-explore-chips-fade {
|
|
10798
|
+
/* Focus scrolling honours scroll-padding, so a tabbed-to chip is brought clear of the fade
|
|
10799
|
+
rather than left half-hidden under it. */
|
|
10800
|
+
scroll-padding-inline-end: 2rem;
|
|
10801
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
10802
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
10803
|
+
}
|
|
10804
|
+
/* A fade over a fixed edge would leave the LAST chip under it once the row is scrolled to
|
|
10805
|
+
the end \u2014 the visitor could never read it. A trailing spacer the width of the fade lets
|
|
10806
|
+
the final chip scroll clear of it. A pseudo-element rather than padding: trailing padding
|
|
10807
|
+
on a flex scroll container is not reliably part of its scrollable overflow. */
|
|
10808
|
+
.boff-explore-chips-fade::after {
|
|
10809
|
+
content: "";
|
|
10810
|
+
flex: 0 0 2rem;
|
|
10811
|
+
}
|
|
10812
|
+
[dir="rtl"] .boff-explore-chips-fade {
|
|
10813
|
+
-webkit-mask-image: linear-gradient(to left, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
10814
|
+
mask-image: linear-gradient(to left, hsl(var(--foreground)) calc(100% - 2rem), hsl(var(--foreground) / 0));
|
|
10815
|
+
}
|
|
10816
|
+
|
|
10817
|
+
/* The concept rail had the chip row's problem: the card at its edge was cut hard mid-word
|
|
10818
|
+
("Apparatus Rig", "CONCEPT ILLUST") on a dozen sites. It fades an edge only while there are
|
|
10819
|
+
more cards beyond it \u2014 the same state that lights the arrow on that side \u2014 so a rail
|
|
10820
|
+
scrolled to its end shows its last card whole. Physical edges, because that state is
|
|
10821
|
+
physical: it is measured from the left in either reading direction. */
|
|
10822
|
+
.boff-explore-rail-fade-left {
|
|
10823
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem);
|
|
10824
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem);
|
|
10825
|
+
}
|
|
10826
|
+
.boff-explore-rail-fade-right {
|
|
10827
|
+
-webkit-mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
10828
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
10829
|
+
}
|
|
10830
|
+
.boff-explore-rail-fade-left.boff-explore-rail-fade-right {
|
|
10831
|
+
-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));
|
|
10832
|
+
mask-image: linear-gradient(to right, hsl(var(--foreground) / 0), hsl(var(--foreground)) 3rem, hsl(var(--foreground)) calc(100% - 3rem), hsl(var(--foreground) / 0));
|
|
10833
|
+
}
|
|
10834
|
+
|
|
10741
10835
|
@keyframes boff-explore-fade-in {
|
|
10742
10836
|
from { opacity: 0; transform: translateY(2px); }
|
|
10743
10837
|
to { opacity: 1; transform: none; }
|
|
@@ -10814,10 +10908,10 @@ var EXPLORE_CSS = `
|
|
|
10814
10908
|
Colour comes from the product's --primary token, so it is whatever that site's palette
|
|
10815
10909
|
already is, never a colour chosen here. */
|
|
10816
10910
|
.boff-explore-invite {
|
|
10817
|
-
border-color: hsl(var(--primary) / 0.
|
|
10911
|
+
border-color: hsl(var(--primary) / 0.6);
|
|
10818
10912
|
box-shadow:
|
|
10819
|
-
0 0 0 4px hsl(var(--primary) / 0.
|
|
10820
|
-
0 8px 24px -12px hsl(var(--primary) / 0.
|
|
10913
|
+
0 0 0 4px hsl(var(--primary) / 0.12),
|
|
10914
|
+
0 8px 24px -12px hsl(var(--primary) / 0.55);
|
|
10821
10915
|
animation: boff-explore-breathe 3.2s ease-in-out infinite;
|
|
10822
10916
|
}
|
|
10823
10917
|
/* Focus and typing both mean "I have found it", and the hint has done its job. */
|
|
@@ -10827,8 +10921,8 @@ var EXPLORE_CSS = `
|
|
|
10827
10921
|
box-shadow: 0 0 0 4px hsl(var(--primary) / 0.10);
|
|
10828
10922
|
}
|
|
10829
10923
|
@keyframes boff-explore-breathe {
|
|
10830
|
-
0%, 100% { box-shadow: 0 0 0 4px hsl(var(--primary) / 0.
|
|
10831
|
-
50% { box-shadow: 0 0 0 7px hsl(var(--primary) / 0.
|
|
10924
|
+
0%, 100% { box-shadow: 0 0 0 4px hsl(var(--primary) / 0.10), 0 8px 24px -12px hsl(var(--primary) / 0.50); }
|
|
10925
|
+
50% { box-shadow: 0 0 0 7px hsl(var(--primary) / 0.18), 0 8px 28px -12px hsl(var(--primary) / 0.65); }
|
|
10832
10926
|
}
|
|
10833
10927
|
|
|
10834
10928
|
/* Every one of the above is decoration. Reduced motion removes the movement and keeps the
|
|
@@ -10916,8 +11010,18 @@ var EXPLORE_CSS = `
|
|
|
10916
11010
|
.boff-explore-scroll .boff-explore-capabilities { display: none; }
|
|
10917
11011
|
}
|
|
10918
11012
|
@container boff-explore-pane (min-width: ${toRem(WELCOME_FIT_MIN_WIDTH_PX)}) and (max-height: ${toRem(WELCOME_FIT_STEP_PX[1])}) {
|
|
10919
|
-
/* Step 2.
|
|
11013
|
+
/* Step 2. At a 4:1 crop the picture is ~44px tall, and the full-size caveat badge covered
|
|
11014
|
+
half of it \u2014 on ten sites, every card, whenever the consent banner was up. It stays (the
|
|
11015
|
+
picture is still a mockup), just smaller and tucked into the corner. */
|
|
10920
11016
|
.boff-explore-scroll .boff-explore-concept-media { aspect-ratio: 4 / 1; }
|
|
11017
|
+
.boff-explore-scroll .boff-explore-concept-badge {
|
|
11018
|
+
top: 0.25rem;
|
|
11019
|
+
left: 0.25rem;
|
|
11020
|
+
padding: 0 0.3125rem;
|
|
11021
|
+
font-size: 0.5rem;
|
|
11022
|
+
line-height: 0.75rem;
|
|
11023
|
+
letter-spacing: 0.02em;
|
|
11024
|
+
}
|
|
10921
11025
|
}
|
|
10922
11026
|
@container boff-explore-pane (min-width: ${toRem(WELCOME_FIT_MIN_WIDTH_PX)}) and (max-height: ${toRem(WELCOME_FIT_STEP_PX[2])}) {
|
|
10923
11027
|
/* Step 3. Title-only cards. The "concept illustration" caveat lives on the picture, so it
|
|
@@ -12076,6 +12180,7 @@ function ErrorBanner({
|
|
|
12076
12180
|
}
|
|
12077
12181
|
function PromptCarousel({
|
|
12078
12182
|
strings: T,
|
|
12183
|
+
label,
|
|
12079
12184
|
prompts,
|
|
12080
12185
|
onPrompt,
|
|
12081
12186
|
disabled
|
|
@@ -12107,7 +12212,7 @@ function PromptCarousel({
|
|
|
12107
12212
|
return /* @__PURE__ */ jsxs(
|
|
12108
12213
|
"div",
|
|
12109
12214
|
{
|
|
12110
|
-
className: "
|
|
12215
|
+
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]",
|
|
12111
12216
|
role: "group",
|
|
12112
12217
|
"aria-roledescription": "carousel",
|
|
12113
12218
|
"aria-label": "Example questions",
|
|
@@ -12117,13 +12222,14 @@ function PromptCarousel({
|
|
|
12117
12222
|
onBlurCapture: () => setPaused(false),
|
|
12118
12223
|
...swipe,
|
|
12119
12224
|
children: [
|
|
12225
|
+
/* @__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 }),
|
|
12120
12226
|
count > 1 ? /* @__PURE__ */ jsx(
|
|
12121
12227
|
"button",
|
|
12122
12228
|
{
|
|
12123
12229
|
type: "button",
|
|
12124
12230
|
"aria-label": T.prevSuggestion,
|
|
12125
12231
|
onClick: () => go(-1),
|
|
12126
|
-
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",
|
|
12232
|
+
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",
|
|
12127
12233
|
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
12128
12234
|
}
|
|
12129
12235
|
) : null,
|
|
@@ -12137,14 +12243,23 @@ function PromptCarousel({
|
|
|
12137
12243
|
"aria-label": `Ask: ${current}`,
|
|
12138
12244
|
"aria-live": paused ? "polite" : "off",
|
|
12139
12245
|
onClick: () => onPrompt(current),
|
|
12140
|
-
className:
|
|
12246
|
+
className: cn(
|
|
12247
|
+
"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",
|
|
12248
|
+
count > 1 ? "sm:col-span-1 sm:col-start-2" : "sm:col-span-3"
|
|
12249
|
+
),
|
|
12141
12250
|
children: [
|
|
12142
12251
|
/* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
12143
|
-
/* @__PURE__ */ jsx(
|
|
12144
|
-
|
|
12252
|
+
/* @__PURE__ */ jsx(
|
|
12253
|
+
"span",
|
|
12254
|
+
{
|
|
12255
|
+
className: "boff-explore-fade min-w-0 max-sm:line-clamp-3 sm:truncate",
|
|
12256
|
+
children: current
|
|
12257
|
+
},
|
|
12258
|
+
current
|
|
12259
|
+
),
|
|
12260
|
+
/* @__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" })
|
|
12145
12261
|
]
|
|
12146
|
-
}
|
|
12147
|
-
current
|
|
12262
|
+
}
|
|
12148
12263
|
),
|
|
12149
12264
|
count > 1 ? /* @__PURE__ */ jsx(
|
|
12150
12265
|
"button",
|
|
@@ -12152,7 +12267,7 @@ function PromptCarousel({
|
|
|
12152
12267
|
type: "button",
|
|
12153
12268
|
"aria-label": T.nextSuggestion,
|
|
12154
12269
|
onClick: () => go(1),
|
|
12155
|
-
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",
|
|
12270
|
+
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",
|
|
12156
12271
|
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
12157
12272
|
}
|
|
12158
12273
|
) : null
|
|
@@ -12183,7 +12298,7 @@ function ProductStrip({
|
|
|
12183
12298
|
{
|
|
12184
12299
|
className: cn(
|
|
12185
12300
|
"boff-explore-strip flex min-w-0 flex-1 gap-2",
|
|
12186
|
-
expanded ? "flex-wrap" : "flex-nowrap overflow-x-auto"
|
|
12301
|
+
expanded ? "flex-wrap" : "boff-explore-chips-fade flex-nowrap overflow-x-auto"
|
|
12187
12302
|
),
|
|
12188
12303
|
children: [
|
|
12189
12304
|
/* @__PURE__ */ jsx(
|
|
@@ -12251,8 +12366,11 @@ function ConceptStrip({
|
|
|
12251
12366
|
const measureRail = useCallback(() => {
|
|
12252
12367
|
const el = railRef.current;
|
|
12253
12368
|
if (!el) return;
|
|
12254
|
-
|
|
12255
|
-
|
|
12369
|
+
const max = el.scrollWidth - el.clientWidth;
|
|
12370
|
+
const rtl = typeof getComputedStyle === "function" && getComputedStyle(el).direction === "rtl";
|
|
12371
|
+
const fromLeft = rtl ? max + el.scrollLeft : el.scrollLeft;
|
|
12372
|
+
setCanLeft(fromLeft > 1);
|
|
12373
|
+
setCanRight(fromLeft < max - 1);
|
|
12256
12374
|
}, []);
|
|
12257
12375
|
useEffect(() => {
|
|
12258
12376
|
const el = railRef.current;
|
|
@@ -12321,11 +12439,15 @@ function ConceptStrip({
|
|
|
12321
12439
|
onScroll: measureRail,
|
|
12322
12440
|
"data-boff-explore": "concept-strip",
|
|
12323
12441
|
"aria-label": T.conceptStripLabel,
|
|
12324
|
-
className:
|
|
12442
|
+
className: cn(
|
|
12443
|
+
"boff-explore-strip flex min-w-0 snap-x gap-3 overflow-x-auto pb-1 sm:mx-10",
|
|
12444
|
+
canLeft && "boff-explore-rail-fade-left",
|
|
12445
|
+
canRight && "boff-explore-rail-fade-right"
|
|
12446
|
+
),
|
|
12325
12447
|
children: visible.map((highlight) => /* @__PURE__ */ jsx(
|
|
12326
12448
|
"li",
|
|
12327
12449
|
{
|
|
12328
|
-
className: "shrink-0 snap-start",
|
|
12450
|
+
className: "flex shrink-0 snap-start",
|
|
12329
12451
|
children: /* @__PURE__ */ jsxs(
|
|
12330
12452
|
"button",
|
|
12331
12453
|
{
|
|
@@ -12361,14 +12483,14 @@ function ConceptStrip({
|
|
|
12361
12483
|
"span",
|
|
12362
12484
|
{
|
|
12363
12485
|
"aria-hidden": "true",
|
|
12364
|
-
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",
|
|
12486
|
+
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",
|
|
12365
12487
|
children: T.conceptIllustration
|
|
12366
12488
|
}
|
|
12367
12489
|
)
|
|
12368
12490
|
] }),
|
|
12369
|
-
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col gap-0.5 p-2.5", children: [
|
|
12491
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5 p-2.5", children: [
|
|
12370
12492
|
/* @__PURE__ */ jsx("span", { className: "line-clamp-2 text-xs font-semibold leading-snug text-card-foreground", children: highlight.title }),
|
|
12371
|
-
/* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: highlight.productName })
|
|
12493
|
+
/* @__PURE__ */ jsx("span", { className: "mt-auto truncate text-[11px] text-muted-foreground", children: highlight.productName })
|
|
12372
12494
|
] })
|
|
12373
12495
|
]
|
|
12374
12496
|
}
|
|
@@ -12516,18 +12638,16 @@ function WelcomeState({
|
|
|
12516
12638
|
},
|
|
12517
12639
|
i
|
|
12518
12640
|
)) }),
|
|
12519
|
-
prompts.length > 0 ? /* @__PURE__ */
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
)
|
|
12530
|
-
] }) : null,
|
|
12641
|
+
prompts.length > 0 ? /* @__PURE__ */ jsx("div", { className: "boff-explore-rise boff-explore-rise-2 mt-4", children: /* @__PURE__ */ jsx(
|
|
12642
|
+
PromptCarousel,
|
|
12643
|
+
{
|
|
12644
|
+
strings: T,
|
|
12645
|
+
label: T.tryAsking,
|
|
12646
|
+
prompts,
|
|
12647
|
+
onPrompt,
|
|
12648
|
+
disabled
|
|
12649
|
+
}
|
|
12650
|
+
) }) : null,
|
|
12531
12651
|
products.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "boff-explore-rise boff-explore-rise-3 mt-4", children: [
|
|
12532
12652
|
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: T.focusProduct }),
|
|
12533
12653
|
/* @__PURE__ */ jsx(
|
|
@@ -12585,6 +12705,7 @@ function ExplorePage({
|
|
|
12585
12705
|
const {
|
|
12586
12706
|
phase,
|
|
12587
12707
|
catalog,
|
|
12708
|
+
serverCatalogRaw,
|
|
12588
12709
|
messages,
|
|
12589
12710
|
activity,
|
|
12590
12711
|
remainingToday,
|
|
@@ -13016,6 +13137,10 @@ function ExplorePage({
|
|
|
13016
13137
|
const captchaOn = Boolean(
|
|
13017
13138
|
catalog.captchaRequired && catalog.recaptchaSiteKey
|
|
13018
13139
|
);
|
|
13140
|
+
const bakedCatalogJson = useMemo(
|
|
13141
|
+
() => serverCatalogRaw && serverCatalogRaw.enabled !== false ? serializeBakedCatalog(serverCatalogRaw) : null,
|
|
13142
|
+
[serverCatalogRaw]
|
|
13143
|
+
);
|
|
13019
13144
|
const rootStyle = {};
|
|
13020
13145
|
if (heightMode === "viewport") {
|
|
13021
13146
|
rootStyle["--boff-explore-offset"] = paneOffset === null ? normalizeOffset(viewportOffset) : `${paneOffset}px`;
|
|
@@ -13055,6 +13180,16 @@ function ExplorePage({
|
|
|
13055
13180
|
),
|
|
13056
13181
|
/* @__PURE__ */ jsx(ProseStyles, {}),
|
|
13057
13182
|
/* @__PURE__ */ jsx(ExploreStyles, {}),
|
|
13183
|
+
bakedCatalogJson ? /* @__PURE__ */ jsx(
|
|
13184
|
+
"script",
|
|
13185
|
+
{
|
|
13186
|
+
id: BAKED_CATALOG_ELEMENT_ID,
|
|
13187
|
+
type: "application/json",
|
|
13188
|
+
"data-product": productSlug ?? "",
|
|
13189
|
+
"data-locale": bakedCatalogLocale(),
|
|
13190
|
+
dangerouslySetInnerHTML: { __html: bakedCatalogJson }
|
|
13191
|
+
}
|
|
13192
|
+
) : null,
|
|
13058
13193
|
/* @__PURE__ */ jsx(ExploreAnswerStyles, {}),
|
|
13059
13194
|
!showWelcome ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 border-b border-border px-4 py-2.5", children: [
|
|
13060
13195
|
/* @__PURE__ */ jsx(
|
|
@@ -13529,7 +13664,7 @@ function ExplorePage({
|
|
|
13529
13664
|
)
|
|
13530
13665
|
] }) : null,
|
|
13531
13666
|
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
13532
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: T.disclaimerShort }),
|
|
13667
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 sm:truncate", children: T.disclaimerShort }),
|
|
13533
13668
|
/* @__PURE__ */ jsx(
|
|
13534
13669
|
"button",
|
|
13535
13670
|
{
|