@opensite/ui 2.0.6 → 2.0.8

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