@opensite/ui 2.0.2 → 2.0.4

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