@opensite/ui 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/hero-adaptable-product-grid.cjs +11 -8
  2. package/dist/hero-adaptable-product-grid.d.cts +1 -1
  3. package/dist/hero-adaptable-product-grid.d.ts +1 -1
  4. package/dist/hero-adaptable-product-grid.js +11 -8
  5. package/dist/hero-business-operations-mosaic.cjs +542 -22
  6. package/dist/hero-business-operations-mosaic.d.cts +20 -8
  7. package/dist/hero-business-operations-mosaic.d.ts +20 -8
  8. package/dist/hero-business-operations-mosaic.js +542 -19
  9. package/dist/hero-centered-gradient-cta.cjs +3 -3
  10. package/dist/hero-centered-gradient-cta.js +3 -3
  11. package/dist/hero-community-survey-cta.cjs +3 -2
  12. package/dist/hero-community-survey-cta.js +3 -2
  13. package/dist/hero-conversion-video-play.cjs +1 -1
  14. package/dist/hero-conversion-video-play.js +1 -1
  15. package/dist/hero-crm-streamlined.cjs +4 -4
  16. package/dist/hero-crm-streamlined.js +4 -4
  17. package/dist/hero-design-showcase-logos.cjs +4 -1
  18. package/dist/hero-design-showcase-logos.js +4 -1
  19. package/dist/hero-design-system-3d.cjs +1 -1
  20. package/dist/hero-design-system-3d.js +1 -1
  21. package/dist/hero-feature-cards-grid.cjs +2 -2
  22. package/dist/hero-feature-cards-grid.js +2 -2
  23. package/dist/hero-fullscreen-background-image.cjs +4 -3
  24. package/dist/hero-fullscreen-background-image.js +4 -3
  25. package/dist/hero-fullscreen-logo-cta.cjs +7 -5
  26. package/dist/hero-fullscreen-logo-cta.js +7 -5
  27. package/dist/hero-gradient-avatars-rating.cjs +3 -3
  28. package/dist/hero-gradient-avatars-rating.js +3 -3
  29. package/dist/hero-gradient-client-focused.cjs +2 -2
  30. package/dist/hero-gradient-client-focused.js +2 -2
  31. package/dist/hero-grid-pattern-solutions.cjs +2 -2
  32. package/dist/hero-grid-pattern-solutions.d.cts +1 -1
  33. package/dist/hero-grid-pattern-solutions.d.ts +1 -1
  34. package/dist/hero-grid-pattern-solutions.js +2 -2
  35. package/dist/hero-innovation-image-grid.cjs +48 -42
  36. package/dist/hero-innovation-image-grid.js +48 -42
  37. package/dist/hero-mental-health-team.cjs +633 -89
  38. package/dist/hero-mental-health-team.d.cts +26 -6
  39. package/dist/hero-mental-health-team.d.ts +26 -6
  40. package/dist/hero-mental-health-team.js +614 -85
  41. package/dist/hero-minimal-centered-dark.cjs +841 -807
  42. package/dist/hero-minimal-centered-dark.d.cts +1 -1
  43. package/dist/hero-minimal-centered-dark.d.ts +1 -1
  44. package/dist/hero-minimal-centered-dark.js +840 -806
  45. package/dist/hero-presentation-platform-video.cjs +8 -2
  46. package/dist/hero-presentation-platform-video.js +8 -2
  47. package/dist/hero-product-showcase-floating.cjs +715 -612
  48. package/dist/hero-product-showcase-floating.d.cts +5 -1
  49. package/dist/hero-product-showcase-floating.d.ts +5 -1
  50. package/dist/hero-product-showcase-floating.js +712 -609
  51. package/dist/hero-saas-dashboard-preview.cjs +82 -107
  52. package/dist/hero-saas-dashboard-preview.d.cts +1 -1
  53. package/dist/hero-saas-dashboard-preview.d.ts +1 -1
  54. package/dist/hero-saas-dashboard-preview.js +82 -107
  55. package/dist/hero-software-growth-video-dialog.cjs +5 -5
  56. package/dist/hero-software-growth-video-dialog.js +5 -5
  57. package/dist/hero-split-image-newsletter.cjs +41 -32
  58. package/dist/hero-split-image-newsletter.js +41 -32
  59. package/dist/hero-stats-social-proof.cjs +1 -1
  60. package/dist/hero-stats-social-proof.js +1 -1
  61. package/dist/hero-testimonial-image-grid.cjs +2 -2
  62. package/dist/hero-testimonial-image-grid.js +2 -2
  63. package/dist/hero-therapy-testimonial-grid.cjs +682 -638
  64. package/dist/hero-therapy-testimonial-grid.d.cts +5 -1
  65. package/dist/hero-therapy-testimonial-grid.d.ts +5 -1
  66. package/dist/hero-therapy-testimonial-grid.js +671 -627
  67. package/dist/hero-ui-library-showcase.cjs +51 -42
  68. package/dist/hero-ui-library-showcase.js +51 -42
  69. package/dist/hero-video-dialog-gradient.cjs +2 -2
  70. package/dist/hero-video-dialog-gradient.js +2 -2
  71. package/dist/hero-video-overlay-stars.cjs +7 -15
  72. package/dist/hero-video-overlay-stars.js +7 -15
  73. package/dist/registry.cjs +608 -438
  74. package/dist/registry.js +608 -438
  75. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React = require('react');
4
+ var React3 = require('react');
5
5
  var clsx = require('clsx');
6
6
  var tailwindMerge = require('tailwind-merge');
7
- var classVarianceAuthority = require('class-variance-authority');
8
- var jsxRuntime = require('react/jsx-runtime');
9
7
  var icon = require('@page-speed/icon');
8
+ var jsxRuntime = require('react/jsx-runtime');
10
9
  var img = require('@page-speed/img');
10
+ var classVarianceAuthority = require('class-variance-authority');
11
11
 
12
12
  function _interopNamespace(e) {
13
13
  if (e && e.__esModule) return e;
@@ -27,7 +27,7 @@ function _interopNamespace(e) {
27
27
  return Object.freeze(n);
28
28
  }
29
29
 
30
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
30
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
31
31
 
32
32
  // components/blocks/hero/hero-product-showcase-floating.tsx
33
33
  function cn(...inputs) {
@@ -63,184 +63,385 @@ function getAccentColor(parentBg, options) {
63
63
  const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
64
64
  return isDark ? "text-accent-foreground" : "text-primary";
65
65
  }
66
- function normalizePhoneNumber(input) {
67
- const trimmed = input.trim();
68
- if (trimmed.toLowerCase().startsWith("tel:")) {
69
- return trimmed;
70
- }
71
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
72
- if (match) {
73
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
74
- const extension = match[3];
75
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
76
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
77
- return `tel:${withExtension}`;
78
- }
79
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
80
- return `tel:${cleaned}`;
81
- }
82
- function normalizeEmail(input) {
83
- const trimmed = input.trim();
84
- if (trimmed.toLowerCase().startsWith("mailto:")) {
85
- return trimmed;
86
- }
87
- return `mailto:${trimmed}`;
88
- }
89
- function isEmail(input) {
90
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
91
- return emailRegex.test(input.trim());
92
- }
93
- function isPhoneNumber(input) {
94
- const trimmed = input.trim();
95
- if (trimmed.toLowerCase().startsWith("tel:")) {
96
- return true;
97
- }
98
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
99
- return phoneRegex.test(trimmed);
66
+ var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
67
+ function DynamicIcon({ apiKey, ...props }) {
68
+ return /* @__PURE__ */ jsxRuntime.jsx(icon.Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
100
69
  }
101
- function isInternalUrl(href) {
102
- if (typeof window === "undefined") {
103
- return href.startsWith("/") && !href.startsWith("//");
104
- }
105
- const trimmed = href.trim();
106
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
107
- return true;
70
+ var maxWidthStyles = {
71
+ sm: "max-w-screen-sm",
72
+ md: "max-w-screen-md",
73
+ lg: "max-w-screen-lg",
74
+ xl: "max-w-7xl",
75
+ "2xl": "max-w-screen-2xl",
76
+ "4xl": "max-w-[1536px]",
77
+ full: "max-w-full"
78
+ };
79
+ var Container = React3__namespace.default.forwardRef(
80
+ ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
81
+ const Component = as;
82
+ return /* @__PURE__ */ jsxRuntime.jsx(
83
+ Component,
84
+ {
85
+ ref,
86
+ className: cn(
87
+ "mx-auto w-full px-2 sm:px-4 lg:px-8",
88
+ maxWidthStyles[maxWidth],
89
+ className
90
+ ),
91
+ ...props,
92
+ children
93
+ }
94
+ );
108
95
  }
109
- try {
110
- const url = new URL(trimmed, window.location.href);
111
- const currentOrigin = window.location.origin;
112
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
113
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
114
- } catch {
115
- return false;
96
+ );
97
+ Container.displayName = "Container";
98
+
99
+ // lib/patternSvgs.ts
100
+ var patternSvgs = {
101
+ squareAltGrid: "https://cdn.ing/assets/files/record/286187/4gpn0yq2ptra8iwlvmwwv860ggwv",
102
+ grid1: "https://cdn.ing/assets/files/record/286186/nbdflpgp4ostrno079hygibsflp3",
103
+ noise: "https://cdn.ing/assets/i/r/286188/zrqcp9hynh3j7p2laihwzfbujgrl/noise.png",
104
+ dots: "https://cdn.ing/assets/files/record/286198/yfsjx9thvtxzhl2qtshxyhkrm524",
105
+ dotPattern: "https://cdn.ing/assets/files/record/286192/7ig0cku8aqbboiza8nuk6hw0nnsr",
106
+ dotPattern2: "https://cdn.ing/assets/files/record/286189/arez6gd2s7isn9i1o6c7sexdq7bl",
107
+ circles: "https://cdn.ing/assets/files/record/286190/gtmia3sncjtzetdshc20zf1d3c17",
108
+ waves: "https://cdn.ing/assets/files/record/286191/mqlb33fzxz9cdth1bx7if0wmpkp1",
109
+ crossPattern: "https://cdn.ing/assets/files/record/286193/9yfqwdbnqaipbp7fsb3wbzzmq472",
110
+ architect: "https://cdn.ing/assets/files/record/286194/vgs88ugpvyhxu13wqgy0acvae6re",
111
+ tinyCheckers: "https://cdn.ing/assets/files/record/286195/65efaknsw8kcpf9o3c2gybytsl5b",
112
+ p6: "https://cdn.ing/assets/i/r/286196/6kl0rqnd6mjk8j7e525fo8fo0vkc/p6.webp"
113
+ };
114
+ var maskTop = "radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%)";
115
+ var maskBottom = "radial-gradient(ellipse 100% 80% at 50% 100%, #000 50%, transparent 90%)";
116
+ var maskCenter = "radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 70%)";
117
+ var maskTopLeft = "radial-gradient(ellipse 80% 80% at 0% 0%, #000 50%, transparent 90%)";
118
+ var maskTopRight = "radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)";
119
+ var maskBottomLeft = "radial-gradient(ellipse 80% 80% at 0% 100%, #000 50%, transparent 90%)";
120
+ var maskBottomRight = "radial-gradient(ellipse 80% 80% at 100% 100%, #000 50%, transparent 90%)";
121
+ var circuitBoardPattern = (id, mask) => /* @__PURE__ */ jsxRuntime.jsxs(
122
+ "svg",
123
+ {
124
+ className: "h-full w-full",
125
+ xmlns: "http://www.w3.org/2000/svg",
126
+ style: mask ? {
127
+ maskImage: mask,
128
+ WebkitMaskImage: mask
129
+ } : void 0,
130
+ children: [
131
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
132
+ "pattern",
133
+ {
134
+ id,
135
+ x: "0",
136
+ y: "0",
137
+ width: "100",
138
+ height: "100",
139
+ patternUnits: "userSpaceOnUse",
140
+ children: [
141
+ /* @__PURE__ */ jsxRuntime.jsx(
142
+ "path",
143
+ {
144
+ d: "M0 50h40M60 50h40M50 0v40M50 60v40",
145
+ stroke: "hsl(var(--muted))",
146
+ strokeWidth: "1",
147
+ fill: "none"
148
+ }
149
+ ),
150
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "50", r: "3", fill: "hsl(var(--muted))" }),
151
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "0", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
152
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "100", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
153
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "0", r: "2", fill: "hsl(var(--muted))" }),
154
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "100", r: "2", fill: "hsl(var(--muted))" })
155
+ ]
156
+ }
157
+ ) }),
158
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
159
+ ]
116
160
  }
117
- }
118
- function toRelativePath(href) {
119
- if (typeof window === "undefined") {
120
- return href;
161
+ );
162
+ var gridDotsPattern = (id, mask) => /* @__PURE__ */ jsxRuntime.jsxs(
163
+ "svg",
164
+ {
165
+ className: "h-full w-full",
166
+ xmlns: "http://www.w3.org/2000/svg",
167
+ style: mask ? {
168
+ maskImage: mask,
169
+ WebkitMaskImage: mask
170
+ } : void 0,
171
+ children: [
172
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
173
+ "pattern",
174
+ {
175
+ id,
176
+ x: "0",
177
+ y: "0",
178
+ width: "40",
179
+ height: "40",
180
+ patternUnits: "userSpaceOnUse",
181
+ children: [
182
+ /* @__PURE__ */ jsxRuntime.jsx(
183
+ "path",
184
+ {
185
+ d: "M0 20h40M20 0v40",
186
+ stroke: "hsl(var(--muted))",
187
+ strokeWidth: "0.5",
188
+ fill: "none"
189
+ }
190
+ ),
191
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "20", cy: "20", r: "2", fill: "hsl(var(--muted))" })
192
+ ]
193
+ }
194
+ ) }),
195
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
196
+ ]
121
197
  }
122
- const trimmed = href.trim();
123
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
124
- return trimmed;
198
+ );
199
+ var gridPattern = (size, mask) => /* @__PURE__ */ jsxRuntime.jsx(
200
+ "div",
201
+ {
202
+ className: "h-full w-full bg-[linear-gradient(to_right,_hsl(var(--muted))_1px,_transparent_1px),linear-gradient(to_bottom,_hsl(var(--muted))_1px,_transparent_1px)]",
203
+ style: {
204
+ backgroundSize: `${size}px ${size}px`,
205
+ ...mask ? {
206
+ maskImage: mask,
207
+ WebkitMaskImage: mask
208
+ } : {}
209
+ }
125
210
  }
126
- try {
127
- const url = new URL(trimmed, window.location.href);
128
- const currentOrigin = window.location.origin;
129
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
130
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
131
- return url.pathname + url.search + url.hash;
211
+ );
212
+ var diagonalCrossPattern = (mask) => /* @__PURE__ */ jsxRuntime.jsx(
213
+ "div",
214
+ {
215
+ className: "h-full w-full",
216
+ style: {
217
+ backgroundImage: "repeating-linear-gradient(45deg, transparent, transparent 32px, hsl(var(--muted)) 32px, hsl(var(--muted)) 33px), repeating-linear-gradient(135deg, transparent, transparent 32px, hsl(var(--muted)) 32px, hsl(var(--muted)) 33px)",
218
+ ...mask ? {
219
+ maskImage: mask,
220
+ WebkitMaskImage: mask
221
+ } : {}
132
222
  }
133
- } catch {
134
223
  }
135
- return trimmed;
136
- }
137
- function useNavigation({
138
- href,
139
- onClick
140
- } = {}) {
141
- const linkType = React__namespace.useMemo(() => {
142
- if (!href || href.trim() === "") {
143
- return onClick ? "none" : "none";
224
+ );
225
+ var dashedGridMaskBase = "repeating-linear-gradient(to right, black 0px, black 3px, transparent 3px, transparent 8px), repeating-linear-gradient(to bottom, black 0px, black 3px, transparent 3px, transparent 8px)";
226
+ var dashedGridPattern = (fadeMask) => {
227
+ const mask = fadeMask ? `${dashedGridMaskBase}, ${fadeMask}` : dashedGridMaskBase;
228
+ return /* @__PURE__ */ jsxRuntime.jsx(
229
+ "div",
230
+ {
231
+ className: "h-full w-full",
232
+ style: {
233
+ backgroundImage: "linear-gradient(to right, hsl(var(--muted)) 1px, transparent 1px), linear-gradient(to bottom, hsl(var(--muted)) 1px, transparent 1px)",
234
+ backgroundSize: "20px 20px",
235
+ backgroundPosition: "0 0, 0 0",
236
+ maskImage: mask,
237
+ WebkitMaskImage: mask,
238
+ maskComposite: "intersect",
239
+ WebkitMaskComposite: "source-in"
240
+ }
144
241
  }
145
- const trimmed = href.trim();
146
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
147
- return "mailto";
242
+ );
243
+ };
244
+ var gradientGlow = (position) => /* @__PURE__ */ jsxRuntime.jsx(
245
+ "div",
246
+ {
247
+ className: cn(
248
+ "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
249
+ position === "top" ? "-top-1/4" : "-bottom-1/4"
250
+ ),
251
+ style: {
252
+ background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
148
253
  }
149
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
150
- return "tel";
151
- }
152
- if (isInternalUrl(trimmed)) {
153
- return "internal";
154
- }
155
- try {
156
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
157
- return "external";
158
- } catch {
159
- return "internal";
160
- }
161
- }, [href, onClick]);
162
- const normalizedHref = React__namespace.useMemo(() => {
163
- if (!href || href.trim() === "") {
164
- return void 0;
165
- }
166
- const trimmed = href.trim();
167
- switch (linkType) {
168
- case "tel":
169
- return normalizePhoneNumber(trimmed);
170
- case "mailto":
171
- return normalizeEmail(trimmed);
172
- case "internal":
173
- return toRelativePath(trimmed);
174
- case "external":
175
- return trimmed;
176
- default:
177
- return trimmed;
178
- }
179
- }, [href, linkType]);
180
- const target = React__namespace.useMemo(() => {
181
- switch (linkType) {
182
- case "external":
183
- return "_blank";
184
- case "internal":
185
- return "_self";
186
- case "mailto":
187
- case "tel":
188
- return void 0;
189
- default:
190
- return void 0;
191
- }
192
- }, [linkType]);
193
- const rel = React__namespace.useMemo(() => {
194
- if (linkType === "external") {
195
- return "noopener noreferrer";
254
+ }
255
+ );
256
+ var spotlight = (position) => /* @__PURE__ */ jsxRuntime.jsx(
257
+ "div",
258
+ {
259
+ className: cn(
260
+ "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
261
+ position === "left" ? "-left-1/4" : "-right-1/4"
262
+ ),
263
+ style: {
264
+ background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
196
265
  }
197
- return void 0;
198
- }, [linkType]);
199
- const isExternal = linkType === "external";
200
- const isInternal = linkType === "internal";
201
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
202
- const handleClick = React__namespace.useCallback(
203
- (event) => {
204
- if (onClick) {
205
- try {
206
- onClick(event);
207
- } catch (error) {
208
- console.error("Error in user onClick handler:", error);
209
- }
210
- }
211
- if (event.defaultPrevented) {
212
- return;
266
+ }
267
+ );
268
+ var patternOverlays = {
269
+ circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
270
+ circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
271
+ circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
272
+ circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
273
+ circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
274
+ circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
275
+ circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
276
+ circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
277
+ dashedGridBasic: () => dashedGridPattern(),
278
+ dashedGridFadeTop: () => dashedGridPattern(maskTop),
279
+ dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
280
+ dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
281
+ dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
282
+ dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
283
+ dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
284
+ dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
285
+ diagonalCrossBasic: () => diagonalCrossPattern(),
286
+ diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
287
+ diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
288
+ diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
289
+ diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
290
+ diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
291
+ diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
292
+ diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
293
+ gridBasic: () => gridPattern(40),
294
+ gridFadeTop: () => gridPattern(32, maskTop),
295
+ gridFadeBottom: () => gridPattern(32, maskBottom),
296
+ gridFadeCenter: () => gridPattern(40, maskCenter),
297
+ gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
298
+ gridFadeTopRight: () => gridPattern(32, maskTopRight),
299
+ gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
300
+ gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
301
+ gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
302
+ gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
303
+ gradientGlowTop: () => gradientGlow("top"),
304
+ gradientGlowBottom: () => gradientGlow("bottom"),
305
+ spotlightLeft: () => spotlight("left"),
306
+ spotlightRight: () => spotlight("right")
307
+ };
308
+ var inlinePatternStyles = {
309
+ radialGradientTop: {
310
+ background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
311
+ },
312
+ radialGradientBottom: {
313
+ background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
314
+ }
315
+ };
316
+ function PatternBackground({
317
+ pattern,
318
+ opacity = 0.08,
319
+ className,
320
+ style
321
+ }) {
322
+ if (!pattern) {
323
+ return null;
324
+ }
325
+ if (pattern in inlinePatternStyles) {
326
+ const inlineStyle = inlinePatternStyles[pattern];
327
+ return /* @__PURE__ */ jsxRuntime.jsx(
328
+ "div",
329
+ {
330
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
331
+ style: { ...inlineStyle, opacity, ...style },
332
+ "aria-hidden": "true"
213
333
  }
214
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
215
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
216
- if (typeof window !== "undefined") {
217
- const handler = window.__opensiteNavigationHandler;
218
- if (typeof handler === "function") {
219
- try {
220
- const handled = handler(normalizedHref, event.nativeEvent || event);
221
- if (handled !== false) {
222
- event.preventDefault();
223
- }
224
- } catch (error) {
225
- console.error("Error in navigation handler:", error);
226
- }
227
- }
228
- }
334
+ );
335
+ }
336
+ if (pattern in patternOverlays) {
337
+ const Overlay = patternOverlays[pattern];
338
+ return /* @__PURE__ */ jsxRuntime.jsx(
339
+ "div",
340
+ {
341
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
342
+ style: { opacity, ...style },
343
+ "aria-hidden": "true",
344
+ children: Overlay()
229
345
  }
230
- },
231
- [onClick, shouldUseRouter, normalizedHref]
346
+ );
347
+ }
348
+ const patternUrl = pattern in patternSvgs ? patternSvgs[pattern] : pattern;
349
+ return /* @__PURE__ */ jsxRuntime.jsx(
350
+ "div",
351
+ {
352
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
353
+ style: {
354
+ backgroundImage: `url(${patternUrl})`,
355
+ backgroundRepeat: "repeat",
356
+ backgroundSize: "auto",
357
+ opacity,
358
+ ...style
359
+ },
360
+ "aria-hidden": "true"
361
+ }
232
362
  );
233
- return {
234
- linkType,
235
- normalizedHref,
236
- target,
237
- rel,
238
- isExternal,
239
- isInternal,
240
- shouldUseRouter,
241
- handleClick
242
- };
243
363
  }
364
+ var backgroundStyles = {
365
+ default: "bg-background text-foreground",
366
+ white: "bg-white text-dark",
367
+ gray: "bg-muted/30 text-foreground",
368
+ dark: "bg-foreground text-background",
369
+ transparent: "bg-transparent text-foreground",
370
+ gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
371
+ primary: "bg-primary text-primary-foreground",
372
+ secondary: "bg-secondary text-secondary-foreground",
373
+ muted: "bg-muted text-muted-foreground"
374
+ };
375
+ var spacingStyles = {
376
+ none: "py-0 md:py-0",
377
+ sm: "py-12 md:py-16",
378
+ md: "py-16 md:py-24",
379
+ lg: "py-20 md:py-32",
380
+ xl: "py-24 md:py-40"
381
+ };
382
+ var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
383
+ var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
384
+ var Section = React3__namespace.default.forwardRef(
385
+ ({
386
+ id,
387
+ title,
388
+ subtitle,
389
+ children,
390
+ className,
391
+ style,
392
+ background = "default",
393
+ spacing = "lg",
394
+ pattern,
395
+ patternOpacity,
396
+ patternClassName,
397
+ containerClassName,
398
+ containerMaxWidth = "xl",
399
+ ...props
400
+ }, ref) => {
401
+ const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
402
+ return /* @__PURE__ */ jsxRuntime.jsxs(
403
+ "section",
404
+ {
405
+ ref,
406
+ id,
407
+ className: cn(
408
+ "relative",
409
+ pattern ? "overflow-hidden" : null,
410
+ backgroundStyles[background],
411
+ isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
412
+ className
413
+ ),
414
+ style,
415
+ ...props,
416
+ children: [
417
+ /* @__PURE__ */ jsxRuntime.jsx(
418
+ PatternBackground,
419
+ {
420
+ pattern,
421
+ opacity: effectivePatternOpacity,
422
+ className: patternClassName
423
+ }
424
+ ),
425
+ /* @__PURE__ */ jsxRuntime.jsxs(
426
+ Container,
427
+ {
428
+ maxWidth: containerMaxWidth,
429
+ className: cn("relative z-10", containerClassName),
430
+ children: [
431
+ (title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
432
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
433
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
434
+ ] }),
435
+ children
436
+ ]
437
+ }
438
+ )
439
+ ]
440
+ }
441
+ );
442
+ }
443
+ );
444
+ Section.displayName = "Section";
244
445
  var baseStyles = [
245
446
  // Layout
246
447
  "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
@@ -383,7 +584,185 @@ var buttonVariants = classVarianceAuthority.cva(baseStyles, {
383
584
  size: "default"
384
585
  }
385
586
  });
386
- var Pressable = React__namespace.forwardRef(
587
+ function normalizePhoneNumber(input) {
588
+ const trimmed = input.trim();
589
+ if (trimmed.toLowerCase().startsWith("tel:")) {
590
+ return trimmed;
591
+ }
592
+ const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
593
+ if (match) {
594
+ const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
595
+ const extension = match[3];
596
+ const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
597
+ const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
598
+ return `tel:${withExtension}`;
599
+ }
600
+ const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
601
+ return `tel:${cleaned}`;
602
+ }
603
+ function normalizeEmail(input) {
604
+ const trimmed = input.trim();
605
+ if (trimmed.toLowerCase().startsWith("mailto:")) {
606
+ return trimmed;
607
+ }
608
+ return `mailto:${trimmed}`;
609
+ }
610
+ function isEmail(input) {
611
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
612
+ return emailRegex.test(input.trim());
613
+ }
614
+ function isPhoneNumber(input) {
615
+ const trimmed = input.trim();
616
+ if (trimmed.toLowerCase().startsWith("tel:")) {
617
+ return true;
618
+ }
619
+ const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
620
+ return phoneRegex.test(trimmed);
621
+ }
622
+ function isInternalUrl(href) {
623
+ if (typeof window === "undefined") {
624
+ return href.startsWith("/") && !href.startsWith("//");
625
+ }
626
+ const trimmed = href.trim();
627
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
628
+ return true;
629
+ }
630
+ try {
631
+ const url = new URL(trimmed, window.location.href);
632
+ const currentOrigin = window.location.origin;
633
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
634
+ return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
635
+ } catch {
636
+ return false;
637
+ }
638
+ }
639
+ function toRelativePath(href) {
640
+ if (typeof window === "undefined") {
641
+ return href;
642
+ }
643
+ const trimmed = href.trim();
644
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
645
+ return trimmed;
646
+ }
647
+ try {
648
+ const url = new URL(trimmed, window.location.href);
649
+ const currentOrigin = window.location.origin;
650
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
651
+ if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
652
+ return url.pathname + url.search + url.hash;
653
+ }
654
+ } catch {
655
+ }
656
+ return trimmed;
657
+ }
658
+ function useNavigation({
659
+ href,
660
+ onClick
661
+ } = {}) {
662
+ const linkType = React3__namespace.useMemo(() => {
663
+ if (!href || href.trim() === "") {
664
+ return onClick ? "none" : "none";
665
+ }
666
+ const trimmed = href.trim();
667
+ if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
668
+ return "mailto";
669
+ }
670
+ if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
671
+ return "tel";
672
+ }
673
+ if (isInternalUrl(trimmed)) {
674
+ return "internal";
675
+ }
676
+ try {
677
+ new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
678
+ return "external";
679
+ } catch {
680
+ return "internal";
681
+ }
682
+ }, [href, onClick]);
683
+ const normalizedHref = React3__namespace.useMemo(() => {
684
+ if (!href || href.trim() === "") {
685
+ return void 0;
686
+ }
687
+ const trimmed = href.trim();
688
+ switch (linkType) {
689
+ case "tel":
690
+ return normalizePhoneNumber(trimmed);
691
+ case "mailto":
692
+ return normalizeEmail(trimmed);
693
+ case "internal":
694
+ return toRelativePath(trimmed);
695
+ case "external":
696
+ return trimmed;
697
+ default:
698
+ return trimmed;
699
+ }
700
+ }, [href, linkType]);
701
+ const target = React3__namespace.useMemo(() => {
702
+ switch (linkType) {
703
+ case "external":
704
+ return "_blank";
705
+ case "internal":
706
+ return "_self";
707
+ case "mailto":
708
+ case "tel":
709
+ return void 0;
710
+ default:
711
+ return void 0;
712
+ }
713
+ }, [linkType]);
714
+ const rel = React3__namespace.useMemo(() => {
715
+ if (linkType === "external") {
716
+ return "noopener noreferrer";
717
+ }
718
+ return void 0;
719
+ }, [linkType]);
720
+ const isExternal = linkType === "external";
721
+ const isInternal = linkType === "internal";
722
+ const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
723
+ const handleClick = React3__namespace.useCallback(
724
+ (event) => {
725
+ if (onClick) {
726
+ try {
727
+ onClick(event);
728
+ } catch (error) {
729
+ console.error("Error in user onClick handler:", error);
730
+ }
731
+ }
732
+ if (event.defaultPrevented) {
733
+ return;
734
+ }
735
+ if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
736
+ !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
737
+ if (typeof window !== "undefined") {
738
+ const handler = window.__opensiteNavigationHandler;
739
+ if (typeof handler === "function") {
740
+ try {
741
+ const handled = handler(normalizedHref, event.nativeEvent || event);
742
+ if (handled !== false) {
743
+ event.preventDefault();
744
+ }
745
+ } catch (error) {
746
+ console.error("Error in navigation handler:", error);
747
+ }
748
+ }
749
+ }
750
+ }
751
+ },
752
+ [onClick, shouldUseRouter, normalizedHref]
753
+ );
754
+ return {
755
+ linkType,
756
+ normalizedHref,
757
+ target,
758
+ rel,
759
+ isExternal,
760
+ isInternal,
761
+ shouldUseRouter,
762
+ handleClick
763
+ };
764
+ }
765
+ var Pressable = React3__namespace.forwardRef(
387
766
  ({
388
767
  children,
389
768
  className,
@@ -438,428 +817,113 @@ var Pressable = React__namespace.forwardRef(
438
817
  return /* @__PURE__ */ jsxRuntime.jsx(
439
818
  "a",
440
819
  {
441
- ref,
442
- href: normalizedHref,
443
- target,
444
- rel,
445
- ...commonProps,
446
- ...props,
447
- children
448
- }
449
- );
450
- }
451
- if (finalComponentType === "button") {
452
- return /* @__PURE__ */ jsxRuntime.jsx(
453
- "button",
454
- {
455
- ref,
456
- type: props.type || "button",
457
- ...commonProps,
458
- ...props,
459
- children
460
- }
461
- );
462
- }
463
- if (finalComponentType === "div") {
464
- return /* @__PURE__ */ jsxRuntime.jsx(
465
- "div",
466
- {
467
- ref,
468
- ...commonProps,
469
- children
470
- }
471
- );
472
- }
473
- return /* @__PURE__ */ jsxRuntime.jsx(
474
- "span",
475
- {
476
- ref,
477
- ...commonProps,
478
- children
479
- }
480
- );
481
- }
482
- );
483
- Pressable.displayName = "Pressable";
484
- var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
485
- function DynamicIcon({ apiKey, ...props }) {
486
- return /* @__PURE__ */ jsxRuntime.jsx(icon.Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
487
- }
488
- var maxWidthStyles = {
489
- sm: "max-w-screen-sm",
490
- md: "max-w-screen-md",
491
- lg: "max-w-screen-lg",
492
- xl: "max-w-7xl",
493
- "2xl": "max-w-screen-2xl",
494
- "4xl": "max-w-[1536px]",
495
- full: "max-w-full"
496
- };
497
- var Container = React__namespace.default.forwardRef(
498
- ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
499
- const Component = as;
500
- return /* @__PURE__ */ jsxRuntime.jsx(
501
- Component,
502
- {
503
- ref,
504
- className: cn(
505
- "mx-auto w-full px-2 sm:px-4 lg:px-8",
506
- maxWidthStyles[maxWidth],
507
- className
508
- ),
509
- ...props,
510
- children
511
- }
512
- );
513
- }
514
- );
515
- Container.displayName = "Container";
516
-
517
- // lib/patternSvgs.ts
518
- var patternSvgs = {
519
- squareAltGrid: "https://cdn.ing/assets/files/record/286187/4gpn0yq2ptra8iwlvmwwv860ggwv",
520
- grid1: "https://cdn.ing/assets/files/record/286186/nbdflpgp4ostrno079hygibsflp3",
521
- noise: "https://cdn.ing/assets/i/r/286188/zrqcp9hynh3j7p2laihwzfbujgrl/noise.png",
522
- dots: "https://cdn.ing/assets/files/record/286198/yfsjx9thvtxzhl2qtshxyhkrm524",
523
- dotPattern: "https://cdn.ing/assets/files/record/286192/7ig0cku8aqbboiza8nuk6hw0nnsr",
524
- dotPattern2: "https://cdn.ing/assets/files/record/286189/arez6gd2s7isn9i1o6c7sexdq7bl",
525
- circles: "https://cdn.ing/assets/files/record/286190/gtmia3sncjtzetdshc20zf1d3c17",
526
- waves: "https://cdn.ing/assets/files/record/286191/mqlb33fzxz9cdth1bx7if0wmpkp1",
527
- crossPattern: "https://cdn.ing/assets/files/record/286193/9yfqwdbnqaipbp7fsb3wbzzmq472",
528
- architect: "https://cdn.ing/assets/files/record/286194/vgs88ugpvyhxu13wqgy0acvae6re",
529
- tinyCheckers: "https://cdn.ing/assets/files/record/286195/65efaknsw8kcpf9o3c2gybytsl5b",
530
- p6: "https://cdn.ing/assets/i/r/286196/6kl0rqnd6mjk8j7e525fo8fo0vkc/p6.webp"
531
- };
532
- var maskTop = "radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%)";
533
- var maskBottom = "radial-gradient(ellipse 100% 80% at 50% 100%, #000 50%, transparent 90%)";
534
- var maskCenter = "radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 70%)";
535
- var maskTopLeft = "radial-gradient(ellipse 80% 80% at 0% 0%, #000 50%, transparent 90%)";
536
- var maskTopRight = "radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)";
537
- var maskBottomLeft = "radial-gradient(ellipse 80% 80% at 0% 100%, #000 50%, transparent 90%)";
538
- var maskBottomRight = "radial-gradient(ellipse 80% 80% at 100% 100%, #000 50%, transparent 90%)";
539
- var circuitBoardPattern = (id, mask) => /* @__PURE__ */ jsxRuntime.jsxs(
540
- "svg",
541
- {
542
- className: "h-full w-full",
543
- xmlns: "http://www.w3.org/2000/svg",
544
- style: mask ? {
545
- maskImage: mask,
546
- WebkitMaskImage: mask
547
- } : void 0,
548
- children: [
549
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
550
- "pattern",
551
- {
552
- id,
553
- x: "0",
554
- y: "0",
555
- width: "100",
556
- height: "100",
557
- patternUnits: "userSpaceOnUse",
558
- children: [
559
- /* @__PURE__ */ jsxRuntime.jsx(
560
- "path",
561
- {
562
- d: "M0 50h40M60 50h40M50 0v40M50 60v40",
563
- stroke: "hsl(var(--muted))",
564
- strokeWidth: "1",
565
- fill: "none"
566
- }
567
- ),
568
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "50", r: "3", fill: "hsl(var(--muted))" }),
569
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "0", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
570
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "100", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
571
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "0", r: "2", fill: "hsl(var(--muted))" }),
572
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "50", cy: "100", r: "2", fill: "hsl(var(--muted))" })
573
- ]
574
- }
575
- ) }),
576
- /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
577
- ]
578
- }
579
- );
580
- var gridDotsPattern = (id, mask) => /* @__PURE__ */ jsxRuntime.jsxs(
581
- "svg",
582
- {
583
- className: "h-full w-full",
584
- xmlns: "http://www.w3.org/2000/svg",
585
- style: mask ? {
586
- maskImage: mask,
587
- WebkitMaskImage: mask
588
- } : void 0,
589
- children: [
590
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
591
- "pattern",
592
- {
593
- id,
594
- x: "0",
595
- y: "0",
596
- width: "40",
597
- height: "40",
598
- patternUnits: "userSpaceOnUse",
599
- children: [
600
- /* @__PURE__ */ jsxRuntime.jsx(
601
- "path",
602
- {
603
- d: "M0 20h40M20 0v40",
604
- stroke: "hsl(var(--muted))",
605
- strokeWidth: "0.5",
606
- fill: "none"
607
- }
608
- ),
609
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "20", cy: "20", r: "2", fill: "hsl(var(--muted))" })
610
- ]
611
- }
612
- ) }),
613
- /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
614
- ]
615
- }
616
- );
617
- var gridPattern = (size, mask) => /* @__PURE__ */ jsxRuntime.jsx(
618
- "div",
619
- {
620
- className: "h-full w-full bg-[linear-gradient(to_right,_hsl(var(--muted))_1px,_transparent_1px),linear-gradient(to_bottom,_hsl(var(--muted))_1px,_transparent_1px)]",
621
- style: {
622
- backgroundSize: `${size}px ${size}px`,
623
- ...mask ? {
624
- maskImage: mask,
625
- WebkitMaskImage: mask
626
- } : {}
627
- }
628
- }
629
- );
630
- var diagonalCrossPattern = (mask) => /* @__PURE__ */ jsxRuntime.jsx(
631
- "div",
632
- {
633
- className: "h-full w-full",
634
- style: {
635
- backgroundImage: "repeating-linear-gradient(45deg, transparent, transparent 32px, hsl(var(--muted)) 32px, hsl(var(--muted)) 33px), repeating-linear-gradient(135deg, transparent, transparent 32px, hsl(var(--muted)) 32px, hsl(var(--muted)) 33px)",
636
- ...mask ? {
637
- maskImage: mask,
638
- WebkitMaskImage: mask
639
- } : {}
640
- }
641
- }
642
- );
643
- var dashedGridMaskBase = "repeating-linear-gradient(to right, black 0px, black 3px, transparent 3px, transparent 8px), repeating-linear-gradient(to bottom, black 0px, black 3px, transparent 3px, transparent 8px)";
644
- var dashedGridPattern = (fadeMask) => {
645
- const mask = fadeMask ? `${dashedGridMaskBase}, ${fadeMask}` : dashedGridMaskBase;
646
- return /* @__PURE__ */ jsxRuntime.jsx(
647
- "div",
648
- {
649
- className: "h-full w-full",
650
- style: {
651
- backgroundImage: "linear-gradient(to right, hsl(var(--muted)) 1px, transparent 1px), linear-gradient(to bottom, hsl(var(--muted)) 1px, transparent 1px)",
652
- backgroundSize: "20px 20px",
653
- backgroundPosition: "0 0, 0 0",
654
- maskImage: mask,
655
- WebkitMaskImage: mask,
656
- maskComposite: "intersect",
657
- WebkitMaskComposite: "source-in"
658
- }
820
+ ref,
821
+ href: normalizedHref,
822
+ target,
823
+ rel,
824
+ ...commonProps,
825
+ ...props,
826
+ children
827
+ }
828
+ );
659
829
  }
660
- );
661
- };
662
- var gradientGlow = (position) => /* @__PURE__ */ jsxRuntime.jsx(
663
- "div",
664
- {
665
- className: cn(
666
- "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
667
- position === "top" ? "-top-1/4" : "-bottom-1/4"
668
- ),
669
- style: {
670
- background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
830
+ if (finalComponentType === "button") {
831
+ return /* @__PURE__ */ jsxRuntime.jsx(
832
+ "button",
833
+ {
834
+ ref,
835
+ type: props.type || "button",
836
+ ...commonProps,
837
+ ...props,
838
+ children
839
+ }
840
+ );
671
841
  }
672
- }
673
- );
674
- var spotlight = (position) => /* @__PURE__ */ jsxRuntime.jsx(
675
- "div",
676
- {
677
- className: cn(
678
- "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
679
- position === "left" ? "-left-1/4" : "-right-1/4"
680
- ),
681
- style: {
682
- background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
842
+ if (finalComponentType === "div") {
843
+ return /* @__PURE__ */ jsxRuntime.jsx(
844
+ "div",
845
+ {
846
+ ref,
847
+ ...commonProps,
848
+ children
849
+ }
850
+ );
683
851
  }
684
- }
685
- );
686
- var patternOverlays = {
687
- circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
688
- circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
689
- circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
690
- circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
691
- circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
692
- circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
693
- circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
694
- circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
695
- dashedGridBasic: () => dashedGridPattern(),
696
- dashedGridFadeTop: () => dashedGridPattern(maskTop),
697
- dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
698
- dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
699
- dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
700
- dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
701
- dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
702
- dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
703
- diagonalCrossBasic: () => diagonalCrossPattern(),
704
- diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
705
- diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
706
- diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
707
- diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
708
- diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
709
- diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
710
- diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
711
- gridBasic: () => gridPattern(40),
712
- gridFadeTop: () => gridPattern(32, maskTop),
713
- gridFadeBottom: () => gridPattern(32, maskBottom),
714
- gridFadeCenter: () => gridPattern(40, maskCenter),
715
- gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
716
- gridFadeTopRight: () => gridPattern(32, maskTopRight),
717
- gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
718
- gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
719
- gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
720
- gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
721
- gradientGlowTop: () => gradientGlow("top"),
722
- gradientGlowBottom: () => gradientGlow("bottom"),
723
- spotlightLeft: () => spotlight("left"),
724
- spotlightRight: () => spotlight("right")
725
- };
726
- var inlinePatternStyles = {
727
- radialGradientTop: {
728
- background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
729
- },
730
- radialGradientBottom: {
731
- background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
732
- }
733
- };
734
- function PatternBackground({
735
- pattern,
736
- opacity = 0.08,
737
- className,
738
- style
739
- }) {
740
- if (!pattern) {
741
- return null;
742
- }
743
- if (pattern in inlinePatternStyles) {
744
- const inlineStyle = inlinePatternStyles[pattern];
745
852
  return /* @__PURE__ */ jsxRuntime.jsx(
746
- "div",
853
+ "span",
747
854
  {
748
- className: cn("pointer-events-none absolute inset-0 z-0", className),
749
- style: { ...inlineStyle, opacity, ...style },
750
- "aria-hidden": "true"
855
+ ref,
856
+ ...commonProps,
857
+ children
751
858
  }
752
859
  );
753
860
  }
754
- if (pattern in patternOverlays) {
755
- const Overlay = patternOverlays[pattern];
861
+ );
862
+ Pressable.displayName = "Pressable";
863
+ var MOBILE_CLASSES = {
864
+ "fit-left": "items-start md:items-center",
865
+ "fit-center": "items-center",
866
+ "fit-right": "items-end md:items-center",
867
+ "full-left": "items-stretch md:items-center",
868
+ "full-center": "items-stretch md:items-center",
869
+ "full-right": "items-stretch md:items-center"
870
+ };
871
+ function BlockActions({
872
+ mobileConfig,
873
+ actionsClassName,
874
+ verticalSpacing = "mt-4 md:mt-8",
875
+ actions,
876
+ actionsSlot
877
+ }) {
878
+ const width = mobileConfig?.width ?? "full";
879
+ const position = mobileConfig?.position ?? "center";
880
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
881
+ if (actionsSlot) {
882
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: actionsSlot });
883
+ } else if (actions && actions?.length > 0) {
756
884
  return /* @__PURE__ */ jsxRuntime.jsx(
757
885
  "div",
758
886
  {
759
- className: cn("pointer-events-none absolute inset-0 z-0", className),
760
- style: { opacity, ...style },
761
- "aria-hidden": "true",
762
- children: Overlay()
887
+ className: cn(
888
+ "flex flex-col md:flex-row flex-wrap gap-4",
889
+ mobileLayoutClass,
890
+ actionsClassName,
891
+ verticalSpacing
892
+ ),
893
+ children: actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(ActionComponent, { action }, index))
763
894
  }
764
895
  );
896
+ } else {
897
+ return null;
765
898
  }
766
- const patternUrl = pattern in patternSvgs ? patternSvgs[pattern] : pattern;
899
+ }
900
+ function ActionComponent({ action }) {
901
+ const {
902
+ label,
903
+ icon,
904
+ iconAfter,
905
+ children,
906
+ href,
907
+ onClick,
908
+ className: actionClassName,
909
+ ...pressableProps
910
+ } = action;
767
911
  return /* @__PURE__ */ jsxRuntime.jsx(
768
- "div",
912
+ Pressable,
769
913
  {
770
- className: cn("pointer-events-none absolute inset-0 z-0", className),
771
- style: {
772
- backgroundImage: `url(${patternUrl})`,
773
- backgroundRepeat: "repeat",
774
- backgroundSize: "auto",
775
- opacity,
776
- ...style
777
- },
778
- "aria-hidden": "true"
914
+ href,
915
+ onClick,
916
+ asButton: action.asButton ?? true,
917
+ className: actionClassName,
918
+ ...pressableProps,
919
+ children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
920
+ icon,
921
+ label,
922
+ iconAfter
923
+ ] })
779
924
  }
780
925
  );
781
926
  }
782
- var backgroundStyles = {
783
- default: "bg-background text-foreground",
784
- white: "bg-white text-dark",
785
- gray: "bg-muted/30 text-foreground",
786
- dark: "bg-foreground text-background",
787
- transparent: "bg-transparent text-foreground",
788
- gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
789
- primary: "bg-primary text-primary-foreground",
790
- secondary: "bg-secondary text-secondary-foreground",
791
- muted: "bg-muted text-muted-foreground"
792
- };
793
- var spacingStyles = {
794
- none: "py-0 md:py-0",
795
- sm: "py-12 md:py-16",
796
- md: "py-16 md:py-24",
797
- lg: "py-20 md:py-32",
798
- xl: "py-24 md:py-40"
799
- };
800
- var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
801
- var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
802
- var Section = React__namespace.default.forwardRef(
803
- ({
804
- id,
805
- title,
806
- subtitle,
807
- children,
808
- className,
809
- style,
810
- background = "default",
811
- spacing = "lg",
812
- pattern,
813
- patternOpacity,
814
- patternClassName,
815
- containerClassName,
816
- containerMaxWidth = "xl",
817
- ...props
818
- }, ref) => {
819
- const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
820
- return /* @__PURE__ */ jsxRuntime.jsxs(
821
- "section",
822
- {
823
- ref,
824
- id,
825
- className: cn(
826
- "relative",
827
- pattern ? "overflow-hidden" : null,
828
- backgroundStyles[background],
829
- isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
830
- className
831
- ),
832
- style,
833
- ...props,
834
- children: [
835
- /* @__PURE__ */ jsxRuntime.jsx(
836
- PatternBackground,
837
- {
838
- pattern,
839
- opacity: effectivePatternOpacity,
840
- className: patternClassName
841
- }
842
- ),
843
- /* @__PURE__ */ jsxRuntime.jsxs(
844
- Container,
845
- {
846
- maxWidth: containerMaxWidth,
847
- className: cn("relative z-10", containerClassName),
848
- children: [
849
- (title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
850
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
851
- title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
852
- ] }),
853
- children
854
- ]
855
- }
856
- )
857
- ]
858
- }
859
- );
860
- }
861
- );
862
- Section.displayName = "Section";
863
927
  function HeroProductShowcaseFloating({
864
928
  badgeText,
865
929
  badgeIcon,
@@ -868,6 +932,7 @@ function HeroProductShowcaseFloating({
868
932
  description,
869
933
  actions,
870
934
  actionsSlot,
935
+ actionsClassName,
871
936
  productImage,
872
937
  productImageSlot,
873
938
  floatingStat,
@@ -875,46 +940,35 @@ function HeroProductShowcaseFloating({
875
940
  userCount,
876
941
  userCountSlot,
877
942
  background,
878
- spacing,
879
943
  pattern,
880
944
  patternOpacity,
881
945
  className,
882
- containerClassName,
946
+ containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
947
+ spacing = "xl",
883
948
  contentClassName,
884
949
  headingClassName,
885
950
  descriptionClassName,
886
951
  showcaseClassName,
887
952
  optixFlowConfig
888
953
  }) {
889
- const renderBadge = React.useMemo(() => {
954
+ const renderBadge = React3.useMemo(() => {
890
955
  if (badgeSlot) return badgeSlot;
891
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex w-fit items-center gap-2 rounded-full px-4 py-2 text-sm font-medium", `${getAccentColor(background)}/10`, getAccentColor(background)), children: [
892
- badgeIcon && /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: badgeIcon, size: 16 }),
893
- badgeText && /* @__PURE__ */ jsxRuntime.jsx("span", { children: badgeText })
894
- ] });
956
+ return /* @__PURE__ */ jsxRuntime.jsxs(
957
+ "div",
958
+ {
959
+ className: cn(
960
+ "inline-flex w-fit items-center gap-2 rounded-full px-4 py-2 text-sm font-medium",
961
+ `${getAccentColor(background)}/10`,
962
+ getAccentColor(background)
963
+ ),
964
+ children: [
965
+ badgeIcon && /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: badgeIcon, size: 16 }),
966
+ badgeText && /* @__PURE__ */ jsxRuntime.jsx("span", { children: badgeText })
967
+ ]
968
+ }
969
+ );
895
970
  }, [badgeSlot, badgeIcon, badgeText]);
896
- const renderActions = React.useMemo(() => {
897
- if (actionsSlot) return actionsSlot;
898
- if (!actions || actions.length === 0) return null;
899
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 sm:flex-row", children: actions.map((action, index) => {
900
- const { label, icon, iconAfter, children, className: actionClassName, ...pressableProps } = action;
901
- return /* @__PURE__ */ jsxRuntime.jsx(
902
- Pressable,
903
- {
904
- asButton: true,
905
- className: actionClassName,
906
- ...pressableProps,
907
- children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
908
- icon,
909
- label,
910
- iconAfter
911
- ] })
912
- },
913
- index
914
- );
915
- }) });
916
- }, [actionsSlot, actions]);
917
- const renderFloatingStat = React.useMemo(() => {
971
+ const renderFloatingStat = React3.useMemo(() => {
918
972
  if (floatingStatSlot) return floatingStatSlot;
919
973
  if (!floatingStat) return null;
920
974
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-4 -right-4 rounded-xl bg-background p-4 shadow-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -932,7 +986,7 @@ function HeroProductShowcaseFloating({
932
986
  ] })
933
987
  ] }) });
934
988
  }, [floatingStatSlot, floatingStat]);
935
- const renderUserCount = React.useMemo(() => {
989
+ const renderUserCount = React3.useMemo(() => {
936
990
  if (userCountSlot) return userCountSlot;
937
991
  if (!userCount) return null;
938
992
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -bottom-4 -left-4 rounded-xl bg-background p-4 shadow-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
@@ -941,7 +995,10 @@ function HeroProductShowcaseFloating({
941
995
  {
942
996
  src: avatar.src,
943
997
  alt: avatar.alt,
944
- className: cn("h-8 w-8 rounded-full border-2 border-background object-cover", avatar.className),
998
+ className: cn(
999
+ "h-8 w-8 rounded-full border-2 border-background object-cover",
1000
+ avatar.className
1001
+ ),
945
1002
  optixFlowConfig
946
1003
  },
947
1004
  idx
@@ -952,23 +1009,33 @@ function HeroProductShowcaseFloating({
952
1009
  ] })
953
1010
  ] }) });
954
1011
  }, [userCountSlot, userCount, optixFlowConfig]);
955
- const renderProductShowcase = React.useMemo(() => {
1012
+ const renderProductShowcase = React3.useMemo(() => {
956
1013
  if (productImageSlot) return productImageSlot;
957
1014
  if (!productImage) return null;
958
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("order-2 lg:order-1", showcaseClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1015
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("order-1", showcaseClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
959
1016
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-4/3 overflow-hidden rounded-2xl bg-linear-to-br from-primary/20 to-purple-500/20 p-8", children: /* @__PURE__ */ jsxRuntime.jsx(
960
1017
  img.Img,
961
1018
  {
962
1019
  src: productImage.src,
963
1020
  alt: productImage.alt,
964
- className: cn("h-full w-full rounded-lg object-cover shadow-2xl", productImage.className),
1021
+ className: cn(
1022
+ "h-full w-full rounded-lg object-cover shadow-2xl",
1023
+ productImage.className
1024
+ ),
965
1025
  optixFlowConfig
966
1026
  }
967
1027
  ) }),
968
1028
  renderFloatingStat,
969
1029
  renderUserCount
970
1030
  ] }) });
971
- }, [productImageSlot, productImage, showcaseClassName, optixFlowConfig, renderFloatingStat, renderUserCount]);
1031
+ }, [
1032
+ productImageSlot,
1033
+ productImage,
1034
+ showcaseClassName,
1035
+ optixFlowConfig,
1036
+ renderFloatingStat,
1037
+ renderUserCount
1038
+ ]);
972
1039
  return /* @__PURE__ */ jsxRuntime.jsx(
973
1040
  Section,
974
1041
  {
@@ -977,13 +1044,49 @@ function HeroProductShowcaseFloating({
977
1044
  pattern,
978
1045
  patternOpacity,
979
1046
  className: cn(className),
980
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("container", containerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid items-center gap-12 lg:grid-cols-2 lg:gap-20", children: [
1047
+ containerClassName,
1048
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-10 md:pt-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid items-center gap-12 lg:grid-cols-2 lg:gap-20", children: [
981
1049
  renderProductShowcase,
982
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("order-1 flex flex-col gap-8 lg:order-2", contentClassName), children: [
1050
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-8 order-2", contentClassName), children: [
983
1051
  renderBadge,
984
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl", headingClassName), children: heading }) : /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl", headingClassName), children: heading })),
985
- description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-lg", getTextColor(background, "muted"), descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: description })),
986
- renderActions
1052
+ heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1053
+ "h1",
1054
+ {
1055
+ className: cn(
1056
+ "text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl",
1057
+ headingClassName
1058
+ ),
1059
+ children: heading
1060
+ }
1061
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1062
+ "h1",
1063
+ {
1064
+ className: cn(
1065
+ "text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl",
1066
+ headingClassName
1067
+ ),
1068
+ children: heading
1069
+ }
1070
+ )),
1071
+ description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1072
+ "p",
1073
+ {
1074
+ className: cn(
1075
+ "text-lg",
1076
+ getTextColor(background, "muted"),
1077
+ descriptionClassName
1078
+ ),
1079
+ children: description
1080
+ }
1081
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: description })),
1082
+ /* @__PURE__ */ jsxRuntime.jsx(
1083
+ BlockActions,
1084
+ {
1085
+ actions,
1086
+ actionsSlot,
1087
+ actionsClassName
1088
+ }
1089
+ )
987
1090
  ] })
988
1091
  ] }) })
989
1092
  }