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