@burdenoff/website-sdk 2026.716.3 → 2026.719.2

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.
@@ -7,6 +7,196 @@ var reactHelmetAsync = require('react-helmet-async');
7
7
  var __defProp = Object.defineProperty;
8
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
9
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
+ function formatPrice(price, currency, pricingModel) {
11
+ if (pricingModel === "FREE" || !price || price === 0) return "Free";
12
+ const curr = currency || "USD";
13
+ try {
14
+ return new Intl.NumberFormat("en-US", {
15
+ style: "currency",
16
+ currency: curr
17
+ }).format(price);
18
+ } catch {
19
+ return `${curr} ${price.toFixed(2)}`;
20
+ }
21
+ }
22
+ function formatDownloads(n) {
23
+ if (!n) return "0";
24
+ if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
25
+ if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
26
+ return n.toString();
27
+ }
28
+ function StarRating({ rating }) {
29
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsxRuntime.jsx(
30
+ "svg",
31
+ {
32
+ viewBox: "0 0 12 12",
33
+ className: `w-3 h-3 ${star <= Math.round(rating) ? "text-amber-400 fill-current" : "text-muted-foreground/30 fill-current"}`,
34
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 1l1.545 3.09L11 4.59l-2.5 2.41.59 3.41L6 8.79l-3.09 1.61L3.5 7 1 4.59l3.455-.5L6 1z" })
35
+ },
36
+ star
37
+ )) });
38
+ }
39
+ function TypeBadge({ type }) {
40
+ const labels = {
41
+ APP: "App",
42
+ NODE: "Node",
43
+ WORKFLOW: "Workflow",
44
+ TEMPLATE: "Template",
45
+ INTEGRATION: "Integration",
46
+ EXTENSION: "Extension",
47
+ THEME: "Theme"
48
+ };
49
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary font-medium", children: labels[type] ?? type });
50
+ }
51
+ function ProductCard({ product, onClick, href }) {
52
+ const priceLabel = formatPrice(
53
+ product.price,
54
+ product.currency,
55
+ product.pricingModel
56
+ );
57
+ const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group bg-card border border-border rounded-xl p-4 flex flex-col gap-3 transition-all duration-200 hover:shadow-md hover:border-primary/30 cursor-pointer h-full", children: [
58
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-lg bg-muted flex-shrink-0 overflow-hidden", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
60
+ "img",
61
+ {
62
+ src: product.icon,
63
+ alt: "",
64
+ "aria-hidden": "true",
65
+ className: "w-full h-full object-cover"
66
+ }
67
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center bg-gradient-to-br from-primary/15 to-primary/5", children: /* @__PURE__ */ jsxRuntime.jsxs(
68
+ "svg",
69
+ {
70
+ viewBox: "0 0 32 32",
71
+ className: "w-8 h-8",
72
+ fill: "none",
73
+ xmlns: "http://www.w3.org/2000/svg",
74
+ "aria-hidden": "true",
75
+ children: [
76
+ /* @__PURE__ */ jsxRuntime.jsx(
77
+ "polygon",
78
+ {
79
+ points: "16,4 28,10 16,16 4,10",
80
+ className: "fill-primary/30",
81
+ stroke: "currentColor",
82
+ strokeWidth: "0.6",
83
+ strokeOpacity: "0.35"
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsxRuntime.jsx(
87
+ "polygon",
88
+ {
89
+ points: "4,10 16,16 16,28 4,22",
90
+ className: "fill-primary/15",
91
+ stroke: "currentColor",
92
+ strokeWidth: "0.6",
93
+ strokeOpacity: "0.35"
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsxRuntime.jsx(
97
+ "polygon",
98
+ {
99
+ points: "28,10 16,16 16,28 28,22",
100
+ className: "fill-primary/20",
101
+ stroke: "currentColor",
102
+ strokeWidth: "0.6",
103
+ strokeOpacity: "0.35"
104
+ }
105
+ )
106
+ ]
107
+ }
108
+ ) }) }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { type: product.type })
110
+ ] }),
111
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
112
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-foreground text-sm leading-snug line-clamp-1 group-hover:text-primary transition-colors", children: product.name }),
113
+ product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs mt-1 line-clamp-2 leading-relaxed", children: product.description })
114
+ ] }),
115
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
116
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: product.rating != null && product.rating > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
117
+ /* @__PURE__ */ jsxRuntime.jsx(StarRating, { rating: product.rating }),
118
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: product.rating.toFixed(1) })
119
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "No reviews yet" }) }),
120
+ /* @__PURE__ */ jsxRuntime.jsx(
121
+ "span",
122
+ {
123
+ className: `text-xs font-semibold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
124
+ children: priceLabel
125
+ }
126
+ )
127
+ ] })
128
+ ] });
129
+ if (href) {
130
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, onClick, className: "block h-full no-underline", children: inner });
131
+ }
132
+ return /* @__PURE__ */ jsxRuntime.jsx(
133
+ "button",
134
+ {
135
+ type: "button",
136
+ onClick,
137
+ className: "block w-full text-left h-full",
138
+ children: inner
139
+ }
140
+ );
141
+ }
142
+
143
+ // src/store/queries.ts
144
+ var STORE_PRODUCT_FIELDS = `
145
+ fragment StoreProductFields on StoreProduct {
146
+ id name slug type subType nature status pricingModel
147
+ price currency description icon bannerUrl screenshots
148
+ category tags featured downloads viewCount rating reviewCount
149
+ publisherId authorName license compatibleProducts
150
+ }
151
+ `;
152
+ var HOME_GROUPED_PRODUCTS_QUERY = `
153
+ ${STORE_PRODUCT_FIELDS}
154
+ query HomeGroupedProducts($compatibleWith: String) {
155
+ homeGroupedProducts(compatibleWith: $compatibleWith) {
156
+ featured { ...StoreProductFields }
157
+ mostDownloaded { ...StoreProductFields }
158
+ recentlyAdded { ...StoreProductFields }
159
+ freeItems { ...StoreProductFields }
160
+ }
161
+ }
162
+ `;
163
+ var BROWSE_STORE_QUERY = `
164
+ ${STORE_PRODUCT_FIELDS}
165
+ query BrowseStore($input: BrowseStoreInput!) {
166
+ browseStore(input: $input) {
167
+ products { ...StoreProductFields }
168
+ totalCount
169
+ hasMore
170
+ nextCursor
171
+ facets {
172
+ types { value count }
173
+ categories { value count }
174
+ pricingModels { value count }
175
+ priceRange { min max }
176
+ }
177
+ }
178
+ }
179
+ `;
180
+ var STORE_PRODUCT_DETAILS_QUERY = `
181
+ ${STORE_PRODUCT_FIELDS}
182
+ query StoreProductDetails($input: StoreProductDetailsInput!) {
183
+ storeProductDetails(input: $input) {
184
+ product { ...StoreProductFields longDescription videoUrls minPlatformVersion }
185
+ publisher { id name email websiteUrl logoUrl bio isVerified tier }
186
+ reviews { id rating title comment verifiedPurchase helpful createdAt }
187
+ reviewsCount
188
+ relatedProducts { ...StoreProductFields }
189
+ ratingDistribution { fiveStars fourStars threeStars twoStars oneStar }
190
+ }
191
+ }
192
+ `;
193
+ var CATEGORIES_QUERY = `
194
+ query Categories {
195
+ categories {
196
+ id name slug description icon parentId
197
+ }
198
+ }
199
+ `;
10
200
 
11
201
  // src/client/security.ts
12
202
  var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
@@ -204,155 +394,6 @@ function PageHead({
204
394
  ))
205
395
  ] });
206
396
  }
207
- function formatPrice(price, currency, pricingModel) {
208
- if (pricingModel === "FREE" || !price || price === 0) return "Free";
209
- const curr = currency || "USD";
210
- try {
211
- return new Intl.NumberFormat("en-US", {
212
- style: "currency",
213
- currency: curr
214
- }).format(price);
215
- } catch {
216
- return `${curr} ${price.toFixed(2)}`;
217
- }
218
- }
219
- function formatDownloads(n) {
220
- if (!n) return "0";
221
- if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
222
- if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
223
- return n.toString();
224
- }
225
- function StarRating({ rating }) {
226
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsxRuntime.jsx(
227
- "svg",
228
- {
229
- viewBox: "0 0 12 12",
230
- className: `w-3 h-3 ${star <= Math.round(rating) ? "text-amber-400 fill-current" : "text-muted-foreground/30 fill-current"}`,
231
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 1l1.545 3.09L11 4.59l-2.5 2.41.59 3.41L6 8.79l-3.09 1.61L3.5 7 1 4.59l3.455-.5L6 1z" })
232
- },
233
- star
234
- )) });
235
- }
236
- function TypeBadge({ type }) {
237
- const labels = {
238
- APP: "App",
239
- NODE: "Node",
240
- WORKFLOW: "Workflow",
241
- TEMPLATE: "Template",
242
- INTEGRATION: "Integration",
243
- EXTENSION: "Extension",
244
- THEME: "Theme"
245
- };
246
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary font-medium", children: labels[type] ?? type });
247
- }
248
- function ProductCard({ product, onClick, href }) {
249
- const priceLabel = formatPrice(product.price, product.currency, product.pricingModel);
250
- const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group bg-card border border-border rounded-xl p-4 flex flex-col gap-3 transition-all duration-200 hover:shadow-md hover:border-primary/30 cursor-pointer h-full", children: [
251
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
252
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-lg bg-muted flex-shrink-0 overflow-hidden", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
253
- "img",
254
- {
255
- src: product.icon,
256
- alt: "",
257
- "aria-hidden": "true",
258
- className: "w-full h-full object-cover"
259
- }
260
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center bg-gradient-to-br from-primary/15 to-primary/5", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 32 32", className: "w-8 h-8", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
261
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "16,4 28,10 16,16 4,10", className: "fill-primary/30", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.35" }),
262
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "4,10 16,16 16,28 4,22", className: "fill-primary/15", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.35" }),
263
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "28,10 16,16 16,28 28,22", className: "fill-primary/20", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.35" })
264
- ] }) }) }),
265
- /* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { type: product.type })
266
- ] }),
267
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
268
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-foreground text-sm leading-snug line-clamp-1 group-hover:text-primary transition-colors", children: product.name }),
269
- product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs mt-1 line-clamp-2 leading-relaxed", children: product.description })
270
- ] }),
271
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
272
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: product.rating != null && product.rating > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
273
- /* @__PURE__ */ jsxRuntime.jsx(StarRating, { rating: product.rating }),
274
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: product.rating.toFixed(1) })
275
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "No reviews yet" }) }),
276
- /* @__PURE__ */ jsxRuntime.jsx(
277
- "span",
278
- {
279
- className: `text-xs font-semibold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
280
- children: priceLabel
281
- }
282
- )
283
- ] })
284
- ] });
285
- if (href) {
286
- return /* @__PURE__ */ jsxRuntime.jsx("a", { href, onClick, className: "block h-full no-underline", children: inner });
287
- }
288
- return /* @__PURE__ */ jsxRuntime.jsx(
289
- "button",
290
- {
291
- type: "button",
292
- onClick,
293
- className: "block w-full text-left h-full",
294
- children: inner
295
- }
296
- );
297
- }
298
-
299
- // src/store/queries.ts
300
- var STORE_PRODUCT_FIELDS = `
301
- fragment StoreProductFields on StoreProduct {
302
- id name slug type subType nature status pricingModel
303
- price currency description icon bannerUrl screenshots
304
- category tags featured downloads viewCount rating reviewCount
305
- publisherId authorName license compatibleProducts
306
- }
307
- `;
308
- var HOME_GROUPED_PRODUCTS_QUERY = `
309
- ${STORE_PRODUCT_FIELDS}
310
- query HomeGroupedProducts($compatibleWith: String) {
311
- homeGroupedProducts(compatibleWith: $compatibleWith) {
312
- featured { ...StoreProductFields }
313
- mostDownloaded { ...StoreProductFields }
314
- recentlyAdded { ...StoreProductFields }
315
- freeItems { ...StoreProductFields }
316
- }
317
- }
318
- `;
319
- var BROWSE_STORE_QUERY = `
320
- ${STORE_PRODUCT_FIELDS}
321
- query BrowseStore($input: BrowseStoreInput!) {
322
- browseStore(input: $input) {
323
- products { ...StoreProductFields }
324
- totalCount
325
- hasMore
326
- nextCursor
327
- facets {
328
- types { value count }
329
- categories { value count }
330
- pricingModels { value count }
331
- priceRange { min max }
332
- }
333
- }
334
- }
335
- `;
336
- var STORE_PRODUCT_DETAILS_QUERY = `
337
- ${STORE_PRODUCT_FIELDS}
338
- query StoreProductDetails($input: StoreProductDetailsInput!) {
339
- storeProductDetails(input: $input) {
340
- product { ...StoreProductFields longDescription videoUrls minPlatformVersion }
341
- publisher { id name email websiteUrl logoUrl bio isVerified tier }
342
- reviews { id rating title comment verifiedPurchase helpful createdAt }
343
- reviewsCount
344
- relatedProducts { ...StoreProductFields }
345
- ratingDistribution { fiveStars fourStars threeStars twoStars oneStar }
346
- }
347
- }
348
- `;
349
- var CATEGORIES_QUERY = `
350
- query Categories {
351
- categories {
352
- id name slug description icon parentId
353
- }
354
- }
355
- `;
356
397
  function dedupAcross(lists) {
357
398
  const seen = /* @__PURE__ */ new Set();
358
399
  return lists.map((list) => {
@@ -370,7 +411,11 @@ function FeaturedHeroCard({
370
411
  product,
371
412
  onNavigate
372
413
  }) {
373
- const priceLabel = formatPrice(product.price, product.currency, product.pricingModel);
414
+ const priceLabel = formatPrice(
415
+ product.price,
416
+ product.currency,
417
+ product.pricingModel
418
+ );
374
419
  return /* @__PURE__ */ jsxRuntime.jsxs(
375
420
  "button",
376
421
  {
@@ -379,28 +424,155 @@ function FeaturedHeroCard({
379
424
  className: "group w-full text-left h-full rounded-2xl border border-border bg-card overflow-hidden hover:border-primary/40 transition-all duration-300 hover:shadow-xl hover:shadow-primary/10 flex flex-col",
380
425
  children: [
381
426
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-44 sm:h-52 bg-gradient-to-br from-primary/20 via-primary/8 to-background overflow-hidden flex-shrink-0", children: [
382
- product.bannerUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: product.bannerUrl, alt: "", "aria-hidden": "true", className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
383
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "absolute inset-0 w-full h-full opacity-[0.07]", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
384
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("pattern", { id: "fg-hero-grid", width: "36", height: "36", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 36 0 L 0 0 0 36", fill: "none", stroke: "currentColor", strokeWidth: "1" }) }) }),
385
- /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#fg-hero-grid)" })
386
- ] }),
387
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 64 64", className: "w-20 h-20 opacity-25", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
388
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "32,8 56,20 32,32 8,20", className: "fill-primary/40", stroke: "currentColor", strokeWidth: "1", strokeOpacity: "0.5" }),
389
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "8,20 32,32 32,56 8,44", className: "fill-primary/20", stroke: "currentColor", strokeWidth: "1", strokeOpacity: "0.5" }),
390
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "56,20 32,32 32,56 56,44", className: "fill-primary/30", stroke: "currentColor", strokeWidth: "1", strokeOpacity: "0.5" })
391
- ] }) })
427
+ product.bannerUrl ? /* @__PURE__ */ jsxRuntime.jsx(
428
+ "img",
429
+ {
430
+ src: product.bannerUrl,
431
+ alt: "",
432
+ "aria-hidden": "true",
433
+ className: "w-full h-full object-cover"
434
+ }
435
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
436
+ /* @__PURE__ */ jsxRuntime.jsxs(
437
+ "svg",
438
+ {
439
+ className: "absolute inset-0 w-full h-full opacity-[0.07]",
440
+ xmlns: "http://www.w3.org/2000/svg",
441
+ "aria-hidden": "true",
442
+ children: [
443
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
444
+ "pattern",
445
+ {
446
+ id: "fg-hero-grid",
447
+ width: "36",
448
+ height: "36",
449
+ patternUnits: "userSpaceOnUse",
450
+ children: /* @__PURE__ */ jsxRuntime.jsx(
451
+ "path",
452
+ {
453
+ d: "M 36 0 L 0 0 0 36",
454
+ fill: "none",
455
+ stroke: "currentColor",
456
+ strokeWidth: "1"
457
+ }
458
+ )
459
+ }
460
+ ) }),
461
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#fg-hero-grid)" })
462
+ ]
463
+ }
464
+ ),
465
+ /* @__PURE__ */ jsxRuntime.jsx(
466
+ "div",
467
+ {
468
+ className: "absolute inset-0 flex items-center justify-center",
469
+ "aria-hidden": "true",
470
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
471
+ "svg",
472
+ {
473
+ viewBox: "0 0 64 64",
474
+ className: "w-20 h-20 opacity-25",
475
+ fill: "none",
476
+ xmlns: "http://www.w3.org/2000/svg",
477
+ children: [
478
+ /* @__PURE__ */ jsxRuntime.jsx(
479
+ "polygon",
480
+ {
481
+ points: "32,8 56,20 32,32 8,20",
482
+ className: "fill-primary/40",
483
+ stroke: "currentColor",
484
+ strokeWidth: "1",
485
+ strokeOpacity: "0.5"
486
+ }
487
+ ),
488
+ /* @__PURE__ */ jsxRuntime.jsx(
489
+ "polygon",
490
+ {
491
+ points: "8,20 32,32 32,56 8,44",
492
+ className: "fill-primary/20",
493
+ stroke: "currentColor",
494
+ strokeWidth: "1",
495
+ strokeOpacity: "0.5"
496
+ }
497
+ ),
498
+ /* @__PURE__ */ jsxRuntime.jsx(
499
+ "polygon",
500
+ {
501
+ points: "56,20 32,32 32,56 56,44",
502
+ className: "fill-primary/30",
503
+ stroke: "currentColor",
504
+ strokeWidth: "1",
505
+ strokeOpacity: "0.5"
506
+ }
507
+ )
508
+ ]
509
+ }
510
+ )
511
+ }
512
+ )
392
513
  ] }),
393
514
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-3 left-3 text-xs font-semibold px-2.5 py-1 rounded-full bg-primary text-primary-foreground shadow-sm", children: "Featured" }),
394
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-4 left-4 w-14 h-14 rounded-xl shadow-lg overflow-hidden border-2 border-background", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: product.icon, alt: "", "aria-hidden": "true", className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-gradient-to-br from-primary/25 to-primary/10 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 32 32", className: "w-8 h-8", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
395
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "16,4 28,10 16,16 4,10", className: "fill-primary/40", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.4" }),
396
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "4,10 16,16 16,28 4,22", className: "fill-primary/20", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.4" }),
397
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "28,10 16,16 16,28 28,22", className: "fill-primary/30", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.4" })
398
- ] }) }) })
515
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-4 left-4 w-14 h-14 rounded-xl shadow-lg overflow-hidden border-2 border-background", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
516
+ "img",
517
+ {
518
+ src: product.icon,
519
+ alt: "",
520
+ "aria-hidden": "true",
521
+ className: "w-full h-full object-cover"
522
+ }
523
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-gradient-to-br from-primary/25 to-primary/10 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
524
+ "svg",
525
+ {
526
+ viewBox: "0 0 32 32",
527
+ className: "w-8 h-8",
528
+ fill: "none",
529
+ xmlns: "http://www.w3.org/2000/svg",
530
+ "aria-hidden": "true",
531
+ children: [
532
+ /* @__PURE__ */ jsxRuntime.jsx(
533
+ "polygon",
534
+ {
535
+ points: "16,4 28,10 16,16 4,10",
536
+ className: "fill-primary/40",
537
+ stroke: "currentColor",
538
+ strokeWidth: "0.6",
539
+ strokeOpacity: "0.4"
540
+ }
541
+ ),
542
+ /* @__PURE__ */ jsxRuntime.jsx(
543
+ "polygon",
544
+ {
545
+ points: "4,10 16,16 16,28 4,22",
546
+ className: "fill-primary/20",
547
+ stroke: "currentColor",
548
+ strokeWidth: "0.6",
549
+ strokeOpacity: "0.4"
550
+ }
551
+ ),
552
+ /* @__PURE__ */ jsxRuntime.jsx(
553
+ "polygon",
554
+ {
555
+ points: "28,10 16,16 16,28 28,22",
556
+ className: "fill-primary/30",
557
+ stroke: "currentColor",
558
+ strokeWidth: "0.6",
559
+ strokeOpacity: "0.4"
560
+ }
561
+ )
562
+ ]
563
+ }
564
+ ) }) })
399
565
  ] }),
400
566
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 flex flex-col flex-1", children: [
401
567
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 mb-2", children: [
402
568
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground group-hover:text-primary transition-colors line-clamp-1", children: product.name }),
403
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm font-bold flex-shrink-0 ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`, children: priceLabel })
569
+ /* @__PURE__ */ jsxRuntime.jsx(
570
+ "span",
571
+ {
572
+ className: `text-sm font-bold flex-shrink-0 ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
573
+ children: priceLabel
574
+ }
575
+ )
404
576
  ] }),
405
577
  product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground line-clamp-2 leading-relaxed flex-1", children: product.description }),
406
578
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex items-center gap-2", children: [
@@ -421,7 +593,10 @@ function ScrollRow({
421
593
  }) {
422
594
  const ref = react.useRef(null);
423
595
  function scroll(dir) {
424
- ref.current?.scrollBy({ left: dir === "r" ? 272 : -272, behavior: "smooth" });
596
+ ref.current?.scrollBy({
597
+ left: dir === "r" ? 272 : -272,
598
+ behavior: "smooth"
599
+ });
425
600
  }
426
601
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group/row", children: [
427
602
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -431,7 +606,19 @@ function ScrollRow({
431
606
  onClick: () => scroll("l"),
432
607
  "aria-label": "Scroll left",
433
608
  className: "absolute left-0 top-1/2 -translate-y-1/2 -translate-x-4 z-10 w-8 h-8 rounded-full bg-background border border-border shadow-md items-center justify-center text-muted-foreground hover:text-primary hover:border-primary/40 transition-all hidden sm:flex opacity-0 group-hover/row:opacity-100",
434
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 16 16", className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 3L6 8l4 5" }) })
609
+ children: /* @__PURE__ */ jsxRuntime.jsx(
610
+ "svg",
611
+ {
612
+ viewBox: "0 0 16 16",
613
+ className: "w-4 h-4",
614
+ fill: "none",
615
+ stroke: "currentColor",
616
+ strokeWidth: "1.5",
617
+ strokeLinecap: "round",
618
+ strokeLinejoin: "round",
619
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 3L6 8l4 5" })
620
+ }
621
+ )
435
622
  }
436
623
  ),
437
624
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -440,7 +627,13 @@ function ScrollRow({
440
627
  ref,
441
628
  className: "flex gap-3 overflow-x-auto pb-1 snap-x snap-mandatory",
442
629
  style: { scrollbarWidth: "none", msOverflowStyle: "none" },
443
- children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-56 snap-start", children: /* @__PURE__ */ jsxRuntime.jsx(ProductCard, { product, onClick: () => onProductClick(product) }) }, product.id))
630
+ children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-56 snap-start", children: /* @__PURE__ */ jsxRuntime.jsx(
631
+ ProductCard,
632
+ {
633
+ product,
634
+ onClick: () => onProductClick(product)
635
+ }
636
+ ) }, product.id))
444
637
  }
445
638
  ),
446
639
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -450,7 +643,19 @@ function ScrollRow({
450
643
  onClick: () => scroll("r"),
451
644
  "aria-label": "Scroll right",
452
645
  className: "absolute right-0 top-1/2 -translate-y-1/2 translate-x-4 z-10 w-8 h-8 rounded-full bg-background border border-border shadow-md items-center justify-center text-muted-foreground hover:text-primary hover:border-primary/40 transition-all hidden sm:flex opacity-0 group-hover/row:opacity-100",
453
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 16 16", className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 3l4 5-4 5" }) })
646
+ children: /* @__PURE__ */ jsxRuntime.jsx(
647
+ "svg",
648
+ {
649
+ viewBox: "0 0 16 16",
650
+ className: "w-4 h-4",
651
+ fill: "none",
652
+ stroke: "currentColor",
653
+ strokeWidth: "1.5",
654
+ strokeLinecap: "round",
655
+ strokeLinejoin: "round",
656
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 3l4 5-4 5" })
657
+ }
658
+ )
454
659
  }
455
660
  )
456
661
  ] });
@@ -553,10 +758,8 @@ function StoreHomePage({
553
758
  const [grouped, setGrouped] = react.useState(null);
554
759
  const [loading, setLoading] = react.useState(true);
555
760
  const [error, setError] = react.useState(null);
556
- const [retryKey, setRetryKey] = react.useState(0);
557
761
  react.useEffect(() => {
558
762
  let cancelled = false;
559
- let autoRetryTimer = null;
560
763
  async function load() {
561
764
  setLoading(true);
562
765
  try {
@@ -570,15 +773,7 @@ function StoreHomePage({
570
773
  setGrouped(res.data.homeGroupedProducts);
571
774
  setError(null);
572
775
  } catch {
573
- if (!cancelled) {
574
- if (retryKey < 1) {
575
- autoRetryTimer = setTimeout(() => {
576
- if (!cancelled) setRetryKey(1);
577
- }, 2e3);
578
- } else {
579
- setError("Failed to load store. Please try again.");
580
- }
581
- }
776
+ if (!cancelled) setError("Failed to load store. Please try again.");
582
777
  } finally {
583
778
  if (!cancelled) setLoading(false);
584
779
  }
@@ -586,9 +781,8 @@ function StoreHomePage({
586
781
  load();
587
782
  return () => {
588
783
  cancelled = true;
589
- if (autoRetryTimer) clearTimeout(autoRetryTimer);
590
784
  };
591
- }, [client, compatibleWith, retryKey]);
785
+ }, [client, compatibleWith]);
592
786
  function navigate(path) {
593
787
  if (onNavigate) {
594
788
  onNavigate(path);
@@ -616,16 +810,65 @@ function StoreHomePage({
616
810
  }
617
811
  ),
618
812
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "relative overflow-hidden pt-14 pb-12 sm:pt-20 sm:pb-16", children: [
619
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-b from-background via-primary/[0.06] to-background pointer-events-none", "aria-hidden": "true" }),
620
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "absolute inset-0 w-full h-full opacity-[0.035] pointer-events-none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
621
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("pattern", { id: "store-home-grid", width: "40", height: "40", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 40 0 L 0 0 0 40", fill: "none", stroke: "currentColor", strokeWidth: "1" }) }) }),
622
- /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#store-home-grid)" })
623
- ] }),
624
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-16 left-1/3 w-80 h-80 rounded-full bg-primary/10 blur-3xl pointer-events-none", "aria-hidden": "true" }),
625
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-8 right-1/4 w-56 h-56 rounded-full bg-primary/8 blur-2xl pointer-events-none", "aria-hidden": "true" }),
813
+ /* @__PURE__ */ jsxRuntime.jsx(
814
+ "div",
815
+ {
816
+ className: "absolute inset-0 bg-gradient-to-b from-background via-primary/[0.06] to-background pointer-events-none",
817
+ "aria-hidden": "true"
818
+ }
819
+ ),
820
+ /* @__PURE__ */ jsxRuntime.jsxs(
821
+ "svg",
822
+ {
823
+ className: "absolute inset-0 w-full h-full opacity-[0.035] pointer-events-none",
824
+ xmlns: "http://www.w3.org/2000/svg",
825
+ "aria-hidden": "true",
826
+ children: [
827
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
828
+ "pattern",
829
+ {
830
+ id: "store-home-grid",
831
+ width: "40",
832
+ height: "40",
833
+ patternUnits: "userSpaceOnUse",
834
+ children: /* @__PURE__ */ jsxRuntime.jsx(
835
+ "path",
836
+ {
837
+ d: "M 40 0 L 0 0 0 40",
838
+ fill: "none",
839
+ stroke: "currentColor",
840
+ strokeWidth: "1"
841
+ }
842
+ )
843
+ }
844
+ ) }),
845
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#store-home-grid)" })
846
+ ]
847
+ }
848
+ ),
849
+ /* @__PURE__ */ jsxRuntime.jsx(
850
+ "div",
851
+ {
852
+ className: "absolute -top-16 left-1/3 w-80 h-80 rounded-full bg-primary/10 blur-3xl pointer-events-none",
853
+ "aria-hidden": "true"
854
+ }
855
+ ),
856
+ /* @__PURE__ */ jsxRuntime.jsx(
857
+ "div",
858
+ {
859
+ className: "absolute top-8 right-1/4 w-56 h-56 rounded-full bg-primary/8 blur-2xl pointer-events-none",
860
+ "aria-hidden": "true"
861
+ }
862
+ ),
626
863
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center", children: [
627
864
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full border border-primary/30 bg-primary/10 text-xs font-semibold text-primary mb-5", children: [
628
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0", "aria-hidden": "true" }),
865
+ /* @__PURE__ */ jsxRuntime.jsx(
866
+ "span",
867
+ {
868
+ className: "w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0",
869
+ "aria-hidden": "true"
870
+ }
871
+ ),
629
872
  "Community Marketplace"
630
873
  ] }),
631
874
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl sm:text-5xl md:text-6xl font-extrabold tracking-tight text-foreground mb-4 leading-[1.08]", children: resolvedTitle }),
@@ -637,7 +880,9 @@ function StoreHomePage({
637
880
  onSubmit: (e) => {
638
881
  e.preventDefault();
639
882
  const q = new FormData(e.currentTarget).get("q");
640
- navigate(q.trim() ? `${browsePath}?q=${encodeURIComponent(q.trim())}` : browsePath);
883
+ navigate(
884
+ q.trim() ? `${browsePath}?q=${encodeURIComponent(q.trim())}` : browsePath
885
+ );
641
886
  },
642
887
  children: [
643
888
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -679,9 +924,23 @@ function StoreHomePage({
679
924
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [...Array(4)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(GridCardSkeleton, {}, i)) })
680
925
  ] }) : error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-16 text-center", children: [
681
926
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: error }),
682
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => setRetryKey((k) => k + 1), className: "text-sm text-primary hover:underline", children: "Retry" })
927
+ /* @__PURE__ */ jsxRuntime.jsx(
928
+ "button",
929
+ {
930
+ type: "button",
931
+ onClick: () => window.location.reload(),
932
+ className: "text-sm text-primary hover:underline",
933
+ children: "Retry"
934
+ }
935
+ )
683
936
  ] }) : featuredItems.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[1fr_2fr] gap-4 items-start", children: [
684
- /* @__PURE__ */ jsxRuntime.jsx(FeaturedHeroCard, { product: featuredItems[0], onNavigate: navigate }),
937
+ /* @__PURE__ */ jsxRuntime.jsx(
938
+ FeaturedHeroCard,
939
+ {
940
+ product: featuredItems[0],
941
+ onNavigate: navigate
942
+ }
943
+ ),
685
944
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: featuredItems.slice(1, 5).map((product) => /* @__PURE__ */ jsxRuntime.jsx(
686
945
  ProductCard,
687
946
  {
@@ -702,7 +961,13 @@ function StoreHomePage({
702
961
  onNavigate: navigate
703
962
  }
704
963
  ),
705
- loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3 overflow-hidden", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ScrollCardSkeleton, {}, i)) }) : /* @__PURE__ */ jsxRuntime.jsx(ScrollRow, { products: popularItems, onProductClick: handleProductClick })
964
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3 overflow-hidden", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ScrollCardSkeleton, {}, i)) }) : /* @__PURE__ */ jsxRuntime.jsx(
965
+ ScrollRow,
966
+ {
967
+ products: popularItems,
968
+ onProductClick: handleProductClick
969
+ }
970
+ )
706
971
  ] }),
707
972
  (loading || freeItems.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("section", { children: [
708
973
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -725,16 +990,35 @@ function StoreHomePage({
725
990
  ] })
726
991
  ] }),
727
992
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "relative overflow-hidden border-t border-border", children: [
728
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-primary/8 via-background to-primary/5 pointer-events-none", "aria-hidden": "true" }),
729
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-40 rounded-full bg-primary/12 blur-3xl pointer-events-none", "aria-hidden": "true" }),
993
+ /* @__PURE__ */ jsxRuntime.jsx(
994
+ "div",
995
+ {
996
+ className: "absolute inset-0 bg-gradient-to-br from-primary/8 via-background to-primary/5 pointer-events-none",
997
+ "aria-hidden": "true"
998
+ }
999
+ ),
1000
+ /* @__PURE__ */ jsxRuntime.jsx(
1001
+ "div",
1002
+ {
1003
+ className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-40 rounded-full bg-primary/12 blur-3xl pointer-events-none",
1004
+ "aria-hidden": "true"
1005
+ }
1006
+ ),
730
1007
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative max-w-2xl mx-auto px-4 py-16 text-center", children: [
731
1008
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full border border-primary/30 bg-primary/10 text-xs font-semibold text-primary mb-5", children: [
732
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0", "aria-hidden": "true" }),
1009
+ /* @__PURE__ */ jsxRuntime.jsx(
1010
+ "span",
1011
+ {
1012
+ className: "w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0",
1013
+ "aria-hidden": "true"
1014
+ }
1015
+ ),
733
1016
  "Become a publisher"
734
1017
  ] }),
735
1018
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground mb-3", children: "Built something useful?" }),
736
1019
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground mb-8 max-w-lg mx-auto leading-relaxed", children: [
737
- "Share your workflows, nodes, and integrations with ",
1020
+ "Share your workflows, nodes, and integrations with",
1021
+ " ",
738
1022
  productName ?? "the",
739
1023
  " community. Earn from your work or contribute for free."
740
1024
  ] }),
@@ -790,7 +1074,14 @@ var PRICING_OPTIONS = [
790
1074
  ];
791
1075
  function parseUrlParams() {
792
1076
  if (typeof window === "undefined")
793
- return { q: "", type: "", pricingModel: "", category: "", sortBy: "RELEVANCE", featured: false };
1077
+ return {
1078
+ q: "",
1079
+ type: "",
1080
+ pricingModel: "",
1081
+ category: "",
1082
+ sortBy: "RELEVANCE",
1083
+ featured: false
1084
+ };
794
1085
  const p = new URLSearchParams(window.location.search);
795
1086
  return {
796
1087
  q: p.get("q") ?? "",
@@ -842,7 +1133,9 @@ function StoreBrowsePage({
842
1133
  const [featured, setFeatured] = react.useState(initial.featured);
843
1134
  const [offset, setOffset] = react.useState(0);
844
1135
  const [result, setResult] = react.useState(null);
845
- const [allProducts, setAllProducts] = react.useState([]);
1136
+ const [allProducts, setAllProducts] = react.useState(
1137
+ []
1138
+ );
846
1139
  const [categories, setCategories] = react.useState([]);
847
1140
  const [loading, setLoading] = react.useState(true);
848
1141
  const [loadingMore, setLoadingMore] = react.useState(false);
@@ -886,7 +1179,16 @@ function StoreBrowsePage({
886
1179
  return () => {
887
1180
  cancelled = true;
888
1181
  };
889
- }, [client, search, type, pricingModel, category, sortBy, compatibleWith, featured]);
1182
+ }, [
1183
+ client,
1184
+ search,
1185
+ type,
1186
+ pricingModel,
1187
+ category,
1188
+ sortBy,
1189
+ compatibleWith,
1190
+ featured
1191
+ ]);
890
1192
  function loadMore() {
891
1193
  const nextOffset = offset + PAGE_SIZE;
892
1194
  setLoadingMore(true);
@@ -1062,7 +1364,8 @@ function StoreBrowsePage({
1062
1364
  onClick: () => setFiltersOpen(!filtersOpen),
1063
1365
  className: "lg:hidden h-10 px-4 rounded-lg border border-border bg-background text-sm text-foreground hover:bg-muted/50 transition-colors",
1064
1366
  children: [
1065
- "Filters ",
1367
+ "Filters",
1368
+ " ",
1066
1369
  hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: "\u2022" })
1067
1370
  ]
1068
1371
  }
@@ -1076,14 +1379,32 @@ function StoreBrowsePage({
1076
1379
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4 flex-wrap", children: [
1077
1380
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: loading ? "Loading\u2026" : `${result?.totalCount ?? 0} results` }),
1078
1381
  hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
1079
- search && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: `"${search}"`, onRemove: () => {
1080
- setSearch("");
1081
- setInputValue("");
1082
- } }),
1382
+ search && /* @__PURE__ */ jsxRuntime.jsx(
1383
+ Chip,
1384
+ {
1385
+ label: `"${search}"`,
1386
+ onRemove: () => {
1387
+ setSearch("");
1388
+ setInputValue("");
1389
+ }
1390
+ }
1391
+ ),
1083
1392
  type && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: type, onRemove: () => setType("") }),
1084
- pricingModel && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: pricingModel, onRemove: () => setPricingModel("") }),
1393
+ pricingModel && /* @__PURE__ */ jsxRuntime.jsx(
1394
+ Chip,
1395
+ {
1396
+ label: pricingModel,
1397
+ onRemove: () => setPricingModel("")
1398
+ }
1399
+ ),
1085
1400
  category && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: category, onRemove: () => setCategory("") }),
1086
- featured && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: "Featured", onRemove: () => setFeatured(false) })
1401
+ featured && /* @__PURE__ */ jsxRuntime.jsx(
1402
+ Chip,
1403
+ {
1404
+ label: "Featured",
1405
+ onRemove: () => setFeatured(false)
1406
+ }
1407
+ )
1087
1408
  ] })
1088
1409
  ] }),
1089
1410
  loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4", children: [...Array(12)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -1135,9 +1456,97 @@ function StoreBrowsePage({
1135
1456
  function Chip({ label, onRemove }) {
1136
1457
  return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-xs bg-primary/10 text-primary rounded-full px-2.5 py-0.5 font-medium", children: [
1137
1458
  label,
1138
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onRemove, "aria-label": `Remove ${label}`, className: "hover:opacity-70", children: "\xD7" })
1459
+ /* @__PURE__ */ jsxRuntime.jsx(
1460
+ "button",
1461
+ {
1462
+ type: "button",
1463
+ onClick: onRemove,
1464
+ "aria-label": `Remove ${label}`,
1465
+ className: "hover:opacity-70",
1466
+ children: "\xD7"
1467
+ }
1468
+ )
1139
1469
  ] });
1140
1470
  }
1471
+ function detectTheme() {
1472
+ if (typeof document === "undefined") return "light";
1473
+ const root = document.documentElement;
1474
+ return root.classList.contains("dark") || root.getAttribute("data-theme") === "dark" ? "dark" : "light";
1475
+ }
1476
+ function WorkflowEmbed({
1477
+ appUrl,
1478
+ productId,
1479
+ theme,
1480
+ clickToInteract = true,
1481
+ hideCta = false,
1482
+ className,
1483
+ onError
1484
+ }) {
1485
+ const iframeRef = react.useRef(null);
1486
+ const [status, setStatus] = react.useState("loading");
1487
+ const [interactive, setInteractive] = react.useState(!clickToInteract);
1488
+ const resolvedTheme = react.useMemo(() => theme ?? detectTheme(), [theme]);
1489
+ const src = react.useMemo(() => {
1490
+ const base = appUrl.replace(/\/+$/, "");
1491
+ const params = new URLSearchParams({
1492
+ productId,
1493
+ theme: resolvedTheme
1494
+ });
1495
+ if (hideCta) params.set("cta", "false");
1496
+ return `${base}/embed/workflow?${params.toString()}`;
1497
+ }, [appUrl, productId, resolvedTheme, hideCta]);
1498
+ react.useEffect(() => {
1499
+ const handler = (event) => {
1500
+ if (event.source !== iframeRef.current?.contentWindow) return;
1501
+ const data = event.data;
1502
+ if (data?.type === "fluidgrids:embed:loaded") setStatus("loaded");
1503
+ if (data?.type === "fluidgrids:embed:error") {
1504
+ setStatus("error");
1505
+ onError?.(data.message ?? "Failed to load workflow preview");
1506
+ }
1507
+ };
1508
+ window.addEventListener("message", handler);
1509
+ return () => window.removeEventListener("message", handler);
1510
+ }, [onError]);
1511
+ if (status === "error") return null;
1512
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1513
+ "div",
1514
+ {
1515
+ className: `relative w-full overflow-hidden rounded-xl border border-border bg-muted ${className ?? ""}`,
1516
+ style: { aspectRatio: "16 / 9" },
1517
+ children: [
1518
+ status === "loading" && /* @__PURE__ */ jsxRuntime.jsx(
1519
+ "div",
1520
+ {
1521
+ className: "absolute inset-0 animate-pulse bg-muted",
1522
+ "aria-hidden": "true"
1523
+ }
1524
+ ),
1525
+ /* @__PURE__ */ jsxRuntime.jsx(
1526
+ "iframe",
1527
+ {
1528
+ ref: iframeRef,
1529
+ src,
1530
+ title: "Workflow preview",
1531
+ loading: "lazy",
1532
+ className: "h-full w-full border-0",
1533
+ style: interactive ? void 0 : { pointerEvents: "none" }
1534
+ }
1535
+ ),
1536
+ clickToInteract && !interactive && status === "loaded" && /* @__PURE__ */ jsxRuntime.jsx(
1537
+ "button",
1538
+ {
1539
+ type: "button",
1540
+ onClick: () => setInteractive(true),
1541
+ className: "absolute inset-0 flex items-end justify-center bg-transparent pb-4",
1542
+ "aria-label": "Click to explore the workflow",
1543
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-border bg-background/90 px-4 py-1.5 text-xs font-medium text-foreground shadow-sm backdrop-blur transition-colors hover:bg-background", children: "Click to explore" })
1544
+ }
1545
+ )
1546
+ ]
1547
+ }
1548
+ );
1549
+ }
1141
1550
  var ANIM_STYLES = `
1142
1551
  @keyframes sdFadeUp {
1143
1552
  from { opacity: 0; transform: translateY(16px); }
@@ -1170,50 +1579,11 @@ var ANIM_STYLES = `
1170
1579
  .sd-d5 { animation-delay: 320ms; }
1171
1580
  .sd-d6 { animation-delay: 400ms; }
1172
1581
  `;
1173
- function mdInline(text) {
1174
- const parts = text.split(/(\*\*[^*]+\*\*)/g);
1175
- if (parts.length === 1) return text;
1176
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: parts.map(
1177
- (part, i) => part.startsWith("**") && part.endsWith("**") ? /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "font-semibold text-foreground", children: part.slice(2, -2) }, i) : part || null
1178
- ) });
1179
- }
1180
- function MdAbout({ content }) {
1181
- let key = 0;
1182
- const nodes = [];
1183
- let listItems = [];
1184
- const flushList = () => {
1185
- if (!listItems.length) return;
1186
- nodes.push(
1187
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside space-y-0.5 my-2", children: listItems.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-sm leading-relaxed", children: mdInline(item) }, i)) }, key++)
1188
- );
1189
- listItems = [];
1190
- };
1191
- for (const line of content.split("\n")) {
1192
- if (!line.trim()) {
1193
- flushList();
1194
- continue;
1195
- }
1196
- const hm = line.match(/^(#{1,3})\s+(.*)/);
1197
- if (hm) {
1198
- flushList();
1199
- nodes.push(
1200
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-foreground mt-4 first:mt-0 text-sm", children: mdInline(hm[2]) }, key++)
1201
- );
1202
- continue;
1203
- }
1204
- if (/^[-*]\s/.test(line)) {
1205
- listItems.push(line.replace(/^[-*]\s+/, ""));
1206
- continue;
1207
- }
1208
- flushList();
1209
- nodes.push(
1210
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed mb-1", children: mdInline(line) }, key++)
1211
- );
1212
- }
1213
- flushList();
1214
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: nodes });
1215
- }
1216
- function RatingBar({ label, count, total }) {
1582
+ function RatingBar({
1583
+ label,
1584
+ count,
1585
+ total
1586
+ }) {
1217
1587
  const pct = total > 0 ? Math.round(count / total * 100) : 0;
1218
1588
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
1219
1589
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-12 text-right shrink-0", children: label }),
@@ -1229,12 +1599,63 @@ function RatingBar({ label, count, total }) {
1229
1599
  }
1230
1600
  function IconBlock({ src }) {
1231
1601
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-shrink-0", children: [
1232
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sd-gp absolute -inset-1.5 rounded-2xl bg-primary/30 blur-md pointer-events-none", "aria-hidden": "true" }),
1233
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sd-si relative w-20 h-20 rounded-2xl overflow-hidden shadow-lg ring-1 ring-border", children: src ? /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: "", "aria-hidden": true, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-gradient-to-br from-primary/25 to-primary/8 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 40 40", className: "w-10 h-10", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
1234
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "20,4 34,11 20,18 6,11", className: "fill-primary/40", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.4" }),
1235
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "6,11 20,18 20,34 6,27", className: "fill-primary/20", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.4" }),
1236
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "34,11 20,18 20,34 34,27", className: "fill-primary/30", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.4" })
1237
- ] }) }) })
1602
+ /* @__PURE__ */ jsxRuntime.jsx(
1603
+ "div",
1604
+ {
1605
+ className: "sd-gp absolute -inset-1.5 rounded-2xl bg-primary/30 blur-md pointer-events-none",
1606
+ "aria-hidden": "true"
1607
+ }
1608
+ ),
1609
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sd-si relative w-20 h-20 rounded-2xl overflow-hidden shadow-lg ring-1 ring-border", children: src ? /* @__PURE__ */ jsxRuntime.jsx(
1610
+ "img",
1611
+ {
1612
+ src,
1613
+ alt: "",
1614
+ "aria-hidden": true,
1615
+ className: "w-full h-full object-cover"
1616
+ }
1617
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-gradient-to-br from-primary/25 to-primary/8 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
1618
+ "svg",
1619
+ {
1620
+ viewBox: "0 0 40 40",
1621
+ className: "w-10 h-10",
1622
+ fill: "none",
1623
+ xmlns: "http://www.w3.org/2000/svg",
1624
+ "aria-hidden": "true",
1625
+ children: [
1626
+ /* @__PURE__ */ jsxRuntime.jsx(
1627
+ "polygon",
1628
+ {
1629
+ points: "20,4 34,11 20,18 6,11",
1630
+ className: "fill-primary/40",
1631
+ stroke: "currentColor",
1632
+ strokeWidth: "0.6",
1633
+ strokeOpacity: "0.4"
1634
+ }
1635
+ ),
1636
+ /* @__PURE__ */ jsxRuntime.jsx(
1637
+ "polygon",
1638
+ {
1639
+ points: "6,11 20,18 20,34 6,27",
1640
+ className: "fill-primary/20",
1641
+ stroke: "currentColor",
1642
+ strokeWidth: "0.6",
1643
+ strokeOpacity: "0.4"
1644
+ }
1645
+ ),
1646
+ /* @__PURE__ */ jsxRuntime.jsx(
1647
+ "polygon",
1648
+ {
1649
+ points: "34,11 20,18 20,34 34,27",
1650
+ className: "fill-primary/30",
1651
+ stroke: "currentColor",
1652
+ strokeWidth: "0.6",
1653
+ strokeOpacity: "0.4"
1654
+ }
1655
+ )
1656
+ ]
1657
+ }
1658
+ ) }) })
1238
1659
  ] });
1239
1660
  }
1240
1661
  function StoreProductDetailPage({
@@ -1250,6 +1671,7 @@ function StoreProductDetailPage({
1250
1671
  const [error, setError] = react.useState(null);
1251
1672
  const [activeScreenshot, setActiveScreenshot] = react.useState(0);
1252
1673
  const [screenshotKey, setScreenshotKey] = react.useState(0);
1674
+ const [embedFailed, setEmbedFailed] = react.useState(false);
1253
1675
  react.useEffect(() => {
1254
1676
  if (!slug && !id) {
1255
1677
  setError("Product not found.");
@@ -1303,11 +1725,30 @@ function StoreProductDetailPage({
1303
1725
  if (error || !details) {
1304
1726
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 text-center", children: [
1305
1727
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: error ?? "Product not found." }),
1306
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => navigate("/store"), className: "text-sm text-primary hover:underline", children: "Back to Store" })
1728
+ /* @__PURE__ */ jsxRuntime.jsx(
1729
+ "button",
1730
+ {
1731
+ type: "button",
1732
+ onClick: () => navigate("/store"),
1733
+ className: "text-sm text-primary hover:underline",
1734
+ children: "Back to Store"
1735
+ }
1736
+ )
1307
1737
  ] });
1308
1738
  }
1309
- const { product, publisher, reviews, reviewsCount, relatedProducts, ratingDistribution } = details;
1310
- const priceLabel = formatPrice(product.price, product.currency, product.pricingModel);
1739
+ const {
1740
+ product,
1741
+ publisher,
1742
+ reviews,
1743
+ reviewsCount,
1744
+ relatedProducts,
1745
+ ratingDistribution
1746
+ } = details;
1747
+ const priceLabel = formatPrice(
1748
+ product.price,
1749
+ product.currency,
1750
+ product.pricingModel
1751
+ );
1311
1752
  const screenshots = product.screenshots ?? [];
1312
1753
  const totalRatings = ratingDistribution ? ratingDistribution.fiveStars + ratingDistribution.fourStars + ratingDistribution.threeStars + ratingDistribution.twoStars + ratingDistribution.oneStar : 0;
1313
1754
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
@@ -1321,15 +1762,60 @@ function StoreProductDetailPage({
1321
1762
  }
1322
1763
  ),
1323
1764
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden", children: [
1324
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-b from-primary/[0.07] via-background to-background pointer-events-none", "aria-hidden": "true" }),
1325
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "absolute inset-0 w-full h-full opacity-[0.04] pointer-events-none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
1326
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("pattern", { id: "sd-grid", width: "40", height: "40", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M 40 0 L 0 0 0 40", fill: "none", stroke: "currentColor", strokeWidth: "1" }) }) }),
1327
- /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#sd-grid)" })
1328
- ] }),
1329
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-12 -left-12 w-72 h-72 rounded-full bg-primary/10 blur-3xl pointer-events-none", "aria-hidden": "true" }),
1765
+ /* @__PURE__ */ jsxRuntime.jsx(
1766
+ "div",
1767
+ {
1768
+ className: "absolute inset-0 bg-gradient-to-b from-primary/[0.07] via-background to-background pointer-events-none",
1769
+ "aria-hidden": "true"
1770
+ }
1771
+ ),
1772
+ /* @__PURE__ */ jsxRuntime.jsxs(
1773
+ "svg",
1774
+ {
1775
+ className: "absolute inset-0 w-full h-full opacity-[0.04] pointer-events-none",
1776
+ xmlns: "http://www.w3.org/2000/svg",
1777
+ "aria-hidden": "true",
1778
+ children: [
1779
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
1780
+ "pattern",
1781
+ {
1782
+ id: "sd-grid",
1783
+ width: "40",
1784
+ height: "40",
1785
+ patternUnits: "userSpaceOnUse",
1786
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1787
+ "path",
1788
+ {
1789
+ d: "M 40 0 L 0 0 0 40",
1790
+ fill: "none",
1791
+ stroke: "currentColor",
1792
+ strokeWidth: "1"
1793
+ }
1794
+ )
1795
+ }
1796
+ ) }),
1797
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#sd-grid)" })
1798
+ ]
1799
+ }
1800
+ ),
1801
+ /* @__PURE__ */ jsxRuntime.jsx(
1802
+ "div",
1803
+ {
1804
+ className: "absolute -top-12 -left-12 w-72 h-72 rounded-full bg-primary/10 blur-3xl pointer-events-none",
1805
+ "aria-hidden": "true"
1806
+ }
1807
+ ),
1330
1808
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-6 pb-8", children: [
1331
1809
  /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "sd-fi text-sm text-muted-foreground mb-6 flex items-center gap-1.5 flex-wrap", children: [
1332
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => navigate("/store"), className: "hover:text-primary transition-colors", children: "Store" }),
1810
+ /* @__PURE__ */ jsxRuntime.jsx(
1811
+ "button",
1812
+ {
1813
+ type: "button",
1814
+ onClick: () => navigate("/store"),
1815
+ className: "hover:text-primary transition-colors",
1816
+ children: "Store"
1817
+ }
1818
+ ),
1333
1819
  /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u203A" }),
1334
1820
  product.category && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1335
1821
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1395,6 +1881,14 @@ function StoreProductDetailPage({
1395
1881
  }
1396
1882
  )
1397
1883
  ] }),
1884
+ product.type === "WORKFLOW" && !embedFailed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sd-fu sd-d3 mb-8", children: /* @__PURE__ */ jsxRuntime.jsx(
1885
+ WorkflowEmbed,
1886
+ {
1887
+ appUrl: appLoginUrl,
1888
+ productId: product.id,
1889
+ onError: () => setEmbedFailed(true)
1890
+ }
1891
+ ) }),
1398
1892
  screenshots.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d3 mb-8", children: [
1399
1893
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl overflow-hidden bg-muted aspect-video mb-3 shadow-md", children: /* @__PURE__ */ jsxRuntime.jsx(
1400
1894
  "img",
@@ -1411,19 +1905,33 @@ function StoreProductDetailPage({
1411
1905
  type: "button",
1412
1906
  onClick: () => switchScreenshot(i),
1413
1907
  className: `w-20 h-14 rounded-lg overflow-hidden flex-shrink-0 border-2 transition-all duration-200 ${i === activeScreenshot ? "border-primary shadow-sm shadow-primary/20" : "border-transparent opacity-50 hover:opacity-80"}`,
1414
- children: /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: `Thumbnail ${i + 1}`, className: "w-full h-full object-cover" })
1908
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1909
+ "img",
1910
+ {
1911
+ src,
1912
+ alt: `Thumbnail ${i + 1}`,
1913
+ className: "w-full h-full object-cover"
1914
+ }
1915
+ )
1415
1916
  },
1416
1917
  i
1417
1918
  )) })
1418
1919
  ] }),
1419
1920
  product.longDescription && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d4 mb-8", children: [
1420
1921
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-bold text-foreground mb-3", children: "About" }),
1421
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(MdAbout, { content: product.longDescription }) })
1922
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "prose prose-sm max-w-none text-muted-foreground leading-relaxed whitespace-pre-line", children: product.longDescription })
1422
1923
  ] }),
1423
1924
  publisher && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d5 mb-8 p-4 rounded-xl border border-border bg-card hover:border-primary/30 transition-colors duration-300", children: [
1424
1925
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground mb-3", children: "Publisher" }),
1425
1926
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1426
- publisher.logoUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: publisher.logoUrl, alt: publisher.name, className: "w-10 h-10 rounded-full object-cover" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary text-sm font-bold", children: publisher.name.charAt(0).toUpperCase() }),
1927
+ publisher.logoUrl ? /* @__PURE__ */ jsxRuntime.jsx(
1928
+ "img",
1929
+ {
1930
+ src: publisher.logoUrl,
1931
+ alt: publisher.name,
1932
+ className: "w-10 h-10 rounded-full object-cover"
1933
+ }
1934
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary text-sm font-bold", children: publisher.name.charAt(0).toUpperCase() }),
1427
1935
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1428
1936
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
1429
1937
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground text-sm", children: publisher.name }),
@@ -1449,11 +1957,46 @@ function StoreProductDetailPage({
1449
1957
  ] })
1450
1958
  ] }),
1451
1959
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-1.5 pt-1", children: [
1452
- /* @__PURE__ */ jsxRuntime.jsx(RatingBar, { label: "5 \u2605", count: ratingDistribution.fiveStars, total: totalRatings }),
1453
- /* @__PURE__ */ jsxRuntime.jsx(RatingBar, { label: "4 \u2605", count: ratingDistribution.fourStars, total: totalRatings }),
1454
- /* @__PURE__ */ jsxRuntime.jsx(RatingBar, { label: "3 \u2605", count: ratingDistribution.threeStars, total: totalRatings }),
1455
- /* @__PURE__ */ jsxRuntime.jsx(RatingBar, { label: "2 \u2605", count: ratingDistribution.twoStars, total: totalRatings }),
1456
- /* @__PURE__ */ jsxRuntime.jsx(RatingBar, { label: "1 \u2605", count: ratingDistribution.oneStar, total: totalRatings })
1960
+ /* @__PURE__ */ jsxRuntime.jsx(
1961
+ RatingBar,
1962
+ {
1963
+ label: "5 \u2605",
1964
+ count: ratingDistribution.fiveStars,
1965
+ total: totalRatings
1966
+ }
1967
+ ),
1968
+ /* @__PURE__ */ jsxRuntime.jsx(
1969
+ RatingBar,
1970
+ {
1971
+ label: "4 \u2605",
1972
+ count: ratingDistribution.fourStars,
1973
+ total: totalRatings
1974
+ }
1975
+ ),
1976
+ /* @__PURE__ */ jsxRuntime.jsx(
1977
+ RatingBar,
1978
+ {
1979
+ label: "3 \u2605",
1980
+ count: ratingDistribution.threeStars,
1981
+ total: totalRatings
1982
+ }
1983
+ ),
1984
+ /* @__PURE__ */ jsxRuntime.jsx(
1985
+ RatingBar,
1986
+ {
1987
+ label: "2 \u2605",
1988
+ count: ratingDistribution.twoStars,
1989
+ total: totalRatings
1990
+ }
1991
+ ),
1992
+ /* @__PURE__ */ jsxRuntime.jsx(
1993
+ RatingBar,
1994
+ {
1995
+ label: "1 \u2605",
1996
+ count: ratingDistribution.oneStar,
1997
+ total: totalRatings
1998
+ }
1999
+ )
1457
2000
  ] })
1458
2001
  ] }),
1459
2002
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: reviews.slice(0, 5).map((review, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1468,11 +2011,14 @@ function StoreProductDetailPage({
1468
2011
  ] }),
1469
2012
  review.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-sm text-foreground mb-1", children: review.title }),
1470
2013
  review.comment && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: review.comment }),
1471
- review.createdAt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-2", children: new Date(review.createdAt).toLocaleDateString("en-US", {
1472
- year: "numeric",
1473
- month: "short",
1474
- day: "numeric"
1475
- }) })
2014
+ review.createdAt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-2", children: new Date(review.createdAt).toLocaleDateString(
2015
+ "en-US",
2016
+ {
2017
+ year: "numeric",
2018
+ month: "short",
2019
+ day: "numeric"
2020
+ }
2021
+ ) })
1476
2022
  ]
1477
2023
  },
1478
2024
  review.id
@@ -1492,7 +2038,13 @@ function StoreProductDetailPage({
1492
2038
  ] }),
1493
2039
  /* @__PURE__ */ jsxRuntime.jsx("aside", { className: "lg:sticky lg:top-24 self-start", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d4 bg-card border border-border rounded-xl p-5 space-y-4 hover:border-primary/30 transition-colors duration-300 hover:shadow-lg hover:shadow-primary/5", children: [
1494
2040
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1495
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `text-3xl font-extrabold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`, children: priceLabel }),
2041
+ /* @__PURE__ */ jsxRuntime.jsx(
2042
+ "div",
2043
+ {
2044
+ className: `text-3xl font-extrabold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
2045
+ children: priceLabel
2046
+ }
2047
+ ),
1496
2048
  product.pricingModel === "SUBSCRIPTION" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: "per month" })
1497
2049
  ] }),
1498
2050
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1551,6 +2103,7 @@ exports.StoreBrowsePage = StoreBrowsePage;
1551
2103
  exports.StoreHomePage = StoreHomePage;
1552
2104
  exports.StoreProductDetailPage = StoreProductDetailPage;
1553
2105
  exports.TypeBadge = TypeBadge;
2106
+ exports.WorkflowEmbed = WorkflowEmbed;
1554
2107
  exports.formatDownloads = formatDownloads;
1555
2108
  exports.formatPrice = formatPrice;
1556
2109
  //# sourceMappingURL=index.js.map