@opensite/ui 2.3.6 → 2.3.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.
@@ -1,251 +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, { useMemo } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { Img } from '@page-speed/img';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
8
  import { cva } from 'class-variance-authority';
8
- import { jsx, jsxs } from 'react/jsx-runtime';
9
- import { Icon } from '@page-speed/icon';
10
9
 
11
10
  // components/blocks/about/about-streamline-team.tsx
12
11
  function cn(...inputs) {
13
12
  return twMerge(clsx(inputs));
14
13
  }
15
- function getNestedCardBg(parentBg, variant = "muted", options) {
16
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
17
- if (isDark) {
18
- switch (variant) {
19
- case "muted":
20
- return "bg-background";
21
- case "card":
22
- return "bg-card";
23
- case "accent":
24
- return "bg-accent";
25
- case "subtle":
26
- return "bg-background/50";
27
- }
28
- } else {
29
- switch (variant) {
30
- case "muted":
31
- return "bg-muted";
32
- case "card":
33
- return "bg-card";
34
- case "accent":
35
- return "bg-accent";
36
- case "subtle":
37
- return "bg-muted/50";
38
- }
39
- }
40
- }
41
- function getNestedCardTextColor(parentBg, options) {
42
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
43
- return isDark ? "text-foreground" : "";
44
- }
45
- function getTextColor(parentBg, variant = "default", options) {
46
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
47
- if (isDark) {
48
- switch (variant) {
49
- case "default":
50
- return "text-foreground";
51
- case "muted":
52
- return "text-foreground/80";
53
- case "subtle":
54
- return "text-foreground/60";
55
- case "accent":
56
- return "text-accent-foreground";
57
- }
58
- } else {
59
- switch (variant) {
60
- case "default":
61
- return "text-foreground";
62
- case "muted":
63
- return "text-muted-foreground";
64
- case "subtle":
65
- return "text-muted-foreground/70";
66
- case "accent":
67
- return "text-primary";
68
- }
69
- }
70
- }
71
- function normalizePhoneNumber(input) {
72
- const trimmed = input.trim();
73
- if (trimmed.toLowerCase().startsWith("tel:")) {
74
- return trimmed;
75
- }
76
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
77
- if (match) {
78
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
79
- const extension = match[3];
80
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
81
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
82
- return `tel:${withExtension}`;
83
- }
84
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
85
- return `tel:${cleaned}`;
86
- }
87
- function normalizeEmail(input) {
88
- const trimmed = input.trim();
89
- if (trimmed.toLowerCase().startsWith("mailto:")) {
90
- return trimmed;
91
- }
92
- return `mailto:${trimmed}`;
93
- }
94
- function isEmail(input) {
95
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
96
- return emailRegex.test(input.trim());
97
- }
98
- function isPhoneNumber(input) {
99
- const trimmed = input.trim();
100
- if (trimmed.toLowerCase().startsWith("tel:")) {
101
- return true;
102
- }
103
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
104
- return phoneRegex.test(trimmed);
105
- }
106
- function isInternalUrl(href) {
107
- if (typeof window === "undefined") {
108
- return href.startsWith("/") && !href.startsWith("//");
109
- }
110
- const trimmed = href.trim();
111
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
112
- return true;
113
- }
114
- try {
115
- const url = new URL(trimmed, window.location.href);
116
- const currentOrigin = window.location.origin;
117
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
118
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
119
- } catch {
120
- 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
+ );
121
39
  }
122
- }
123
- function toRelativePath(href) {
124
- if (typeof window === "undefined") {
125
- 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
+ ]
126
104
  }
127
- const trimmed = href.trim();
128
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
129
- 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
+ ]
130
141
  }
131
- try {
132
- const url = new URL(trimmed, window.location.href);
133
- const currentOrigin = window.location.origin;
134
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
135
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
136
- 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
+ } : {}
137
153
  }
138
- } catch {
139
154
  }
140
- return trimmed;
141
- }
142
- function useNavigation({
143
- href,
144
- onClick
145
- } = {}) {
146
- const linkType = React.useMemo(() => {
147
- if (!href || href.trim() === "") {
148
- return onClick ? "none" : "none";
149
- }
150
- const trimmed = href.trim();
151
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
152
- return "mailto";
153
- }
154
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
155
- return "tel";
156
- }
157
- if (isInternalUrl(trimmed)) {
158
- return "internal";
159
- }
160
- try {
161
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
162
- return "external";
163
- } catch {
164
- return "internal";
165
- }
166
- }, [href, onClick]);
167
- const normalizedHref = React.useMemo(() => {
168
- if (!href || href.trim() === "") {
169
- 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
+ } : {}
170
166
  }
171
- const trimmed = href.trim();
172
- switch (linkType) {
173
- case "tel":
174
- return normalizePhoneNumber(trimmed);
175
- case "mailto":
176
- return normalizeEmail(trimmed);
177
- case "internal":
178
- return toRelativePath(trimmed);
179
- case "external":
180
- return trimmed;
181
- default:
182
- 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
+ }
183
185
  }
184
- }, [href, linkType]);
185
- const target = React.useMemo(() => {
186
- switch (linkType) {
187
- case "external":
188
- return "_blank";
189
- case "internal":
190
- return "_self";
191
- case "mailto":
192
- case "tel":
193
- return void 0;
194
- default:
195
- 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%)"
196
197
  }
197
- }, [linkType]);
198
- const rel = React.useMemo(() => {
199
- if (linkType === "external") {
200
- 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%)"
201
209
  }
202
- return void 0;
203
- }, [linkType]);
204
- const isExternal = linkType === "external";
205
- const isInternal = linkType === "internal";
206
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
207
- const handleClick = React.useCallback(
208
- (event) => {
209
- if (onClick) {
210
- try {
211
- onClick(event);
212
- } catch (error) {
213
- console.error("Error in user onClick handler:", error);
214
- }
215
- }
216
- if (event.defaultPrevented) {
217
- 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"
218
277
  }
219
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
220
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
221
- if (typeof window !== "undefined") {
222
- const handler = window.__opensiteNavigationHandler;
223
- if (typeof handler === "function") {
224
- try {
225
- const handled = handler(normalizedHref, event.nativeEvent || event);
226
- if (handled !== false) {
227
- event.preventDefault();
228
- }
229
- } catch (error) {
230
- console.error("Error in navigation handler:", error);
231
- }
232
- }
233
- }
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()
234
289
  }
235
- },
236
- [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
+ }
237
306
  );
238
- return {
239
- linkType,
240
- normalizedHref,
241
- target,
242
- rel,
243
- isExternal,
244
- isInternal,
245
- shouldUseRouter,
246
- handleClick
247
- };
248
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";
249
389
  var baseStyles = [
250
390
  // Layout
251
391
  "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
@@ -388,7 +528,185 @@ var buttonVariants = cva(baseStyles, {
388
528
  size: "default"
389
529
  }
390
530
  });
391
- 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(
392
710
  ({
393
711
  children,
394
712
  className,
@@ -434,437 +752,122 @@ var Pressable = React.forwardRef(
434
752
  className: combinedClassName,
435
753
  onClick: handleClick,
436
754
  "aria-label": ariaLabel,
437
- "aria-describedby": ariaDescribedby,
438
- id,
439
- ...dataProps,
440
- ...buttonDataAttributes
441
- };
442
- if (finalComponentType === "a" && shouldRenderLink) {
443
- return /* @__PURE__ */ jsx(
444
- "a",
445
- {
446
- ref,
447
- href: normalizedHref,
448
- target,
449
- rel,
450
- ...commonProps,
451
- ...props,
452
- children
453
- }
454
- );
455
- }
456
- if (finalComponentType === "button") {
457
- return /* @__PURE__ */ jsx(
458
- "button",
459
- {
460
- ref,
461
- type: props.type || "button",
462
- ...commonProps,
463
- ...props,
464
- children
465
- }
466
- );
467
- }
468
- if (finalComponentType === "div") {
469
- return /* @__PURE__ */ jsx(
470
- "div",
471
- {
472
- ref,
473
- ...commonProps,
474
- children
475
- }
476
- );
477
- }
478
- return /* @__PURE__ */ jsx(
479
- "span",
480
- {
481
- ref,
482
- ...commonProps,
483
- children
484
- }
485
- );
486
- }
487
- );
488
- Pressable.displayName = "Pressable";
489
- var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
490
- function DynamicIcon({ apiKey, ...props }) {
491
- return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
492
- }
493
- var maxWidthStyles = {
494
- sm: "max-w-screen-sm",
495
- md: "max-w-screen-md",
496
- lg: "max-w-screen-lg",
497
- xl: "max-w-7xl",
498
- "2xl": "max-w-screen-2xl",
499
- "4xl": "max-w-[1536px]",
500
- full: "max-w-full"
501
- };
502
- var Container = React__default.forwardRef(
503
- ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
504
- const Component = as;
505
- return /* @__PURE__ */ jsx(
506
- Component,
507
- {
508
- ref,
509
- className: cn(
510
- "mx-auto w-full px-2 sm:px-4 lg:px-8",
511
- maxWidthStyles[maxWidth],
512
- className
513
- ),
514
- ...props,
515
- children
516
- }
517
- );
518
- }
519
- );
520
- Container.displayName = "Container";
521
-
522
- // lib/patternSvgs.ts
523
- var patternSvgs = {
524
- squareAltGrid: "https://cdn.ing/assets/files/record/286187/4gpn0yq2ptra8iwlvmwwv860ggwv",
525
- grid1: "https://cdn.ing/assets/files/record/286186/nbdflpgp4ostrno079hygibsflp3",
526
- noise: "https://cdn.ing/assets/i/r/286188/zrqcp9hynh3j7p2laihwzfbujgrl/noise.png",
527
- dots: "https://cdn.ing/assets/files/record/286198/yfsjx9thvtxzhl2qtshxyhkrm524",
528
- dotPattern: "https://cdn.ing/assets/files/record/286192/7ig0cku8aqbboiza8nuk6hw0nnsr",
529
- dotPattern2: "https://cdn.ing/assets/files/record/286189/arez6gd2s7isn9i1o6c7sexdq7bl",
530
- circles: "https://cdn.ing/assets/files/record/286190/gtmia3sncjtzetdshc20zf1d3c17",
531
- waves: "https://cdn.ing/assets/files/record/286191/mqlb33fzxz9cdth1bx7if0wmpkp1",
532
- crossPattern: "https://cdn.ing/assets/files/record/286193/9yfqwdbnqaipbp7fsb3wbzzmq472",
533
- architect: "https://cdn.ing/assets/files/record/286194/vgs88ugpvyhxu13wqgy0acvae6re",
534
- tinyCheckers: "https://cdn.ing/assets/files/record/286195/65efaknsw8kcpf9o3c2gybytsl5b",
535
- p6: "https://cdn.ing/assets/i/r/286196/6kl0rqnd6mjk8j7e525fo8fo0vkc/p6.webp"
536
- };
537
- var maskTop = "radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%)";
538
- var maskBottom = "radial-gradient(ellipse 100% 80% at 50% 100%, #000 50%, transparent 90%)";
539
- var maskCenter = "radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 70%)";
540
- var maskTopLeft = "radial-gradient(ellipse 80% 80% at 0% 0%, #000 50%, transparent 90%)";
541
- var maskTopRight = "radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)";
542
- var maskBottomLeft = "radial-gradient(ellipse 80% 80% at 0% 100%, #000 50%, transparent 90%)";
543
- var maskBottomRight = "radial-gradient(ellipse 80% 80% at 100% 100%, #000 50%, transparent 90%)";
544
- var circuitBoardPattern = (id, mask) => /* @__PURE__ */ jsxs(
545
- "svg",
546
- {
547
- className: "h-full w-full",
548
- xmlns: "http://www.w3.org/2000/svg",
549
- style: mask ? {
550
- maskImage: mask,
551
- WebkitMaskImage: mask
552
- } : void 0,
553
- children: [
554
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
555
- "pattern",
556
- {
557
- id,
558
- x: "0",
559
- y: "0",
560
- width: "100",
561
- height: "100",
562
- patternUnits: "userSpaceOnUse",
563
- children: [
564
- /* @__PURE__ */ jsx(
565
- "path",
566
- {
567
- d: "M0 50h40M60 50h40M50 0v40M50 60v40",
568
- stroke: "hsl(var(--muted))",
569
- strokeWidth: "1",
570
- fill: "none"
571
- }
572
- ),
573
- /* @__PURE__ */ jsx("circle", { cx: "50", cy: "50", r: "3", fill: "hsl(var(--muted))" }),
574
- /* @__PURE__ */ jsx("circle", { cx: "0", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
575
- /* @__PURE__ */ jsx("circle", { cx: "100", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
576
- /* @__PURE__ */ jsx("circle", { cx: "50", cy: "0", r: "2", fill: "hsl(var(--muted))" }),
577
- /* @__PURE__ */ jsx("circle", { cx: "50", cy: "100", r: "2", fill: "hsl(var(--muted))" })
578
- ]
579
- }
580
- ) }),
581
- /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
582
- ]
583
- }
584
- );
585
- var gridDotsPattern = (id, mask) => /* @__PURE__ */ jsxs(
586
- "svg",
587
- {
588
- className: "h-full w-full",
589
- xmlns: "http://www.w3.org/2000/svg",
590
- style: mask ? {
591
- maskImage: mask,
592
- WebkitMaskImage: mask
593
- } : void 0,
594
- children: [
595
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
596
- "pattern",
597
- {
598
- id,
599
- x: "0",
600
- y: "0",
601
- width: "40",
602
- height: "40",
603
- patternUnits: "userSpaceOnUse",
604
- children: [
605
- /* @__PURE__ */ jsx(
606
- "path",
607
- {
608
- d: "M0 20h40M20 0v40",
609
- stroke: "hsl(var(--muted))",
610
- strokeWidth: "0.5",
611
- fill: "none"
612
- }
613
- ),
614
- /* @__PURE__ */ jsx("circle", { cx: "20", cy: "20", r: "2", fill: "hsl(var(--muted))" })
615
- ]
616
- }
617
- ) }),
618
- /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
619
- ]
620
- }
621
- );
622
- var gridPattern = (size, mask) => /* @__PURE__ */ jsx(
623
- "div",
624
- {
625
- 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)]",
626
- style: {
627
- backgroundSize: `${size}px ${size}px`,
628
- ...mask ? {
629
- maskImage: mask,
630
- WebkitMaskImage: mask
631
- } : {}
632
- }
633
- }
634
- );
635
- var diagonalCrossPattern = (mask) => /* @__PURE__ */ jsx(
636
- "div",
637
- {
638
- className: "h-full w-full",
639
- style: {
640
- 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)",
641
- ...mask ? {
642
- maskImage: mask,
643
- WebkitMaskImage: mask
644
- } : {}
645
- }
646
- }
647
- );
648
- 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)";
649
- var dashedGridPattern = (fadeMask) => {
650
- const mask = fadeMask ? `${dashedGridMaskBase}, ${fadeMask}` : dashedGridMaskBase;
651
- return /* @__PURE__ */ jsx(
652
- "div",
653
- {
654
- className: "h-full w-full",
655
- style: {
656
- backgroundImage: "linear-gradient(to right, hsl(var(--muted)) 1px, transparent 1px), linear-gradient(to bottom, hsl(var(--muted)) 1px, transparent 1px)",
657
- backgroundSize: "20px 20px",
658
- backgroundPosition: "0 0, 0 0",
659
- maskImage: mask,
660
- WebkitMaskImage: mask,
661
- maskComposite: "intersect",
662
- WebkitMaskComposite: "source-in"
663
- }
755
+ "aria-describedby": ariaDescribedby,
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
+ );
664
773
  }
665
- );
666
- };
667
- var gradientGlow = (position) => /* @__PURE__ */ jsx(
668
- "div",
669
- {
670
- className: cn(
671
- "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
672
- position === "top" ? "-top-1/4" : "-bottom-1/4"
673
- ),
674
- style: {
675
- 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
+ );
676
785
  }
677
- }
678
- );
679
- var spotlight = (position) => /* @__PURE__ */ jsx(
680
- "div",
681
- {
682
- className: cn(
683
- "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
684
- position === "left" ? "-left-1/4" : "-right-1/4"
685
- ),
686
- style: {
687
- 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
+ );
688
795
  }
689
- }
690
- );
691
- var patternOverlays = {
692
- circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
693
- circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
694
- circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
695
- circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
696
- circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
697
- circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
698
- circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
699
- circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
700
- dashedGridBasic: () => dashedGridPattern(),
701
- dashedGridFadeTop: () => dashedGridPattern(maskTop),
702
- dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
703
- dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
704
- dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
705
- dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
706
- dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
707
- dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
708
- diagonalCrossBasic: () => diagonalCrossPattern(),
709
- diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
710
- diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
711
- diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
712
- diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
713
- diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
714
- diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
715
- diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
716
- gridBasic: () => gridPattern(40),
717
- gridFadeTop: () => gridPattern(32, maskTop),
718
- gridFadeBottom: () => gridPattern(32, maskBottom),
719
- gridFadeCenter: () => gridPattern(40, maskCenter),
720
- gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
721
- gridFadeTopRight: () => gridPattern(32, maskTopRight),
722
- gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
723
- gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
724
- gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
725
- gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
726
- gradientGlowTop: () => gradientGlow("top"),
727
- gradientGlowBottom: () => gradientGlow("bottom"),
728
- spotlightLeft: () => spotlight("left"),
729
- spotlightRight: () => spotlight("right")
730
- };
731
- var inlinePatternStyles = {
732
- radialGradientTop: {
733
- background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
734
- },
735
- radialGradientBottom: {
736
- background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
737
- }
738
- };
739
- function PatternBackground({
740
- pattern,
741
- opacity = 0.08,
742
- className,
743
- style
744
- }) {
745
- if (!pattern) {
746
- return null;
747
- }
748
- if (pattern in inlinePatternStyles) {
749
- const inlineStyle = inlinePatternStyles[pattern];
750
796
  return /* @__PURE__ */ jsx(
751
- "div",
797
+ "span",
752
798
  {
753
- className: cn("pointer-events-none absolute inset-0 z-0", className),
754
- style: { ...inlineStyle, opacity, ...style },
755
- "aria-hidden": "true"
799
+ ref,
800
+ ...commonProps,
801
+ children
756
802
  }
757
803
  );
758
804
  }
759
- if (pattern in patternOverlays) {
760
- 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) {
761
828
  return /* @__PURE__ */ jsx(
762
829
  "div",
763
830
  {
764
- className: cn("pointer-events-none absolute inset-0 z-0", className),
765
- style: { opacity, ...style },
766
- "aria-hidden": "true",
767
- 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))
768
838
  }
769
839
  );
840
+ } else {
841
+ return null;
770
842
  }
771
- 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;
772
855
  return /* @__PURE__ */ jsx(
773
- "div",
856
+ Pressable,
774
857
  {
775
- className: cn("pointer-events-none absolute inset-0 z-0", className),
776
- style: {
777
- backgroundImage: `url(${patternUrl})`,
778
- backgroundRepeat: "repeat",
779
- backgroundSize: "auto",
780
- opacity,
781
- ...style
782
- },
783
- "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
+ ] })
784
868
  }
785
869
  );
786
870
  }
787
- var backgroundStyles = {
788
- default: "bg-background text-foreground",
789
- white: "bg-white text-dark",
790
- gray: "bg-muted/30 text-foreground",
791
- dark: "bg-foreground text-background",
792
- transparent: "bg-transparent text-foreground",
793
- gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
794
- primary: "bg-primary text-primary-foreground",
795
- secondary: "bg-secondary text-secondary-foreground",
796
- muted: "bg-muted text-muted-foreground"
797
- };
798
- var spacingStyles = {
799
- none: "py-0 md:py-0",
800
- sm: "py-12 md:py-16",
801
- md: "py-16 md:py-24",
802
- lg: "py-20 md:py-32",
803
- xl: "py-24 md:py-40"
804
- };
805
- var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
806
- var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
807
- var Section = React__default.forwardRef(
808
- ({
809
- id,
810
- title,
811
- subtitle,
812
- children,
813
- className,
814
- style,
815
- background = "default",
816
- spacing = "lg",
817
- pattern,
818
- patternOpacity,
819
- patternClassName,
820
- containerClassName,
821
- containerMaxWidth = "xl",
822
- ...props
823
- }, ref) => {
824
- const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
825
- return /* @__PURE__ */ jsxs(
826
- "section",
827
- {
828
- ref,
829
- id,
830
- className: cn(
831
- "relative",
832
- pattern ? "overflow-hidden" : null,
833
- backgroundStyles[background],
834
- isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
835
- className
836
- ),
837
- style,
838
- ...props,
839
- children: [
840
- /* @__PURE__ */ jsx(
841
- PatternBackground,
842
- {
843
- pattern,
844
- opacity: effectivePatternOpacity,
845
- className: patternClassName
846
- }
847
- ),
848
- /* @__PURE__ */ jsxs(
849
- Container,
850
- {
851
- maxWidth: containerMaxWidth,
852
- className: cn("relative z-10", containerClassName),
853
- children: [
854
- (title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
855
- subtitle && /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
856
- title && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
857
- ] }),
858
- children
859
- ]
860
- }
861
- )
862
- ]
863
- }
864
- );
865
- }
866
- );
867
- Section.displayName = "Section";
868
871
  function AboutStreamlineTeam({
869
872
  className,
870
873
  title,
@@ -901,7 +904,9 @@ function AboutStreamlineTeam({
901
904
  "div",
902
905
  {
903
906
  className: cn(
904
- "flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-primary/10",
907
+ "flex shrink-0 items-center justify-center",
908
+ "size-12 rounded-lg",
909
+ "bg-primary text-primary-foreground",
905
910
  feature.iconBgClass
906
911
  ),
907
912
  children: feature.icon
@@ -909,35 +914,10 @@ function AboutStreamlineTeam({
909
914
  ),
910
915
  /* @__PURE__ */ jsxs("div", { children: [
911
916
  feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsx("h3", { className: "font-semibold", children: feature.title }) : feature.title),
912
- feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsx(
913
- "p",
914
- {
915
- className: cn("text-sm", getTextColor(background, "muted")),
916
- children: feature.description
917
- }
918
- ) : feature.description)
917
+ feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsx("p", { className: "text-sm", children: feature.description }) : feature.description)
919
918
  ] })
920
919
  ] }, idx)) });
921
920
  }, [featuresSlot, features, featuresClassName, background]);
922
- const actionsContent = useMemo(() => {
923
- if (actionsSlot) return actionsSlot;
924
- if (!actions || actions.length === 0) return null;
925
- return /* @__PURE__ */ jsx("div", { className: cn("mt-8", actionsClassName), children: actions.map((action, idx) => /* @__PURE__ */ jsxs(
926
- Pressable,
927
- {
928
- href: action.href,
929
- onClick: action.onClick,
930
- size: action.size || "lg",
931
- variant: action.variant || "default",
932
- asButton: true,
933
- children: [
934
- action.label,
935
- /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16, className: "ml-2" })
936
- ]
937
- },
938
- idx
939
- )) });
940
- }, [actionsSlot, actions, actionsClassName]);
941
921
  return /* @__PURE__ */ jsxs(
942
922
  Section,
943
923
  {
@@ -945,7 +925,7 @@ function AboutStreamlineTeam({
945
925
  spacing,
946
926
  pattern,
947
927
  patternOpacity,
948
- className: cn(className),
928
+ className,
949
929
  containerClassName,
950
930
  children: [
951
931
  /* @__PURE__ */ jsxs("div", { className: "grid gap-12 lg:grid-cols-2 lg:items-center", children: [
@@ -968,14 +948,17 @@ function AboutStreamlineTeam({
968
948
  src: secondaryImage.src,
969
949
  alt: secondaryImage.alt,
970
950
  className: cn(
971
- "absolute -bottom-8 -right-8 h-48 w-48 rounded-xl border-4 border-background object-cover shadow-lg",
951
+ "size-24 md:size-48",
952
+ "rounded-xl object-cover shadow-lg",
953
+ "border-4 border-background",
954
+ "absolute -bottom-8 -right-2 md:-right-8",
972
955
  secondaryImageClassName
973
956
  ),
974
957
  optixFlowConfig
975
958
  }
976
959
  )
977
960
  ] }),
978
- /* @__PURE__ */ jsxs("div", { children: [
961
+ /* @__PURE__ */ jsxs("div", { className: "pl-0 md:pl-8", children: [
979
962
  title && (typeof title === "string" ? /* @__PURE__ */ jsx(
980
963
  "h1",
981
964
  {
@@ -985,18 +968,8 @@ function AboutStreamlineTeam({
985
968
  ),
986
969
  children: title
987
970
  }
988
- ) : /* @__PURE__ */ jsx("div", { className: titleClassName, children: title })),
989
- description && (typeof description === "string" ? /* @__PURE__ */ jsx(
990
- "p",
991
- {
992
- className: cn(
993
- "mt-6 text-lg",
994
- getTextColor(background, "muted"),
995
- descriptionClassName
996
- ),
997
- children: description
998
- }
999
- ) : /* @__PURE__ */ jsx("div", { className: cn("mt-6", descriptionClassName), children: description })),
971
+ ) : title),
972
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mt-6 text-lg", descriptionClassName), children: description }) : description),
1000
973
  featuresContent
1001
974
  ] })
1002
975
  ] }),
@@ -1004,35 +977,44 @@ function AboutStreamlineTeam({
1004
977
  "div",
1005
978
  {
1006
979
  className: cn(
1007
- "mt-6 md:mt-32 rounded-2xl p-8 md:p-16",
1008
- getNestedCardBg(background),
1009
- getNestedCardTextColor(background),
980
+ "mt-10 md:mt-24 p-6 md:p-16",
981
+ "bg-muted text-muted-foreground",
982
+ "rounded-2xl shadow-lg",
1010
983
  teamSectionClassName
1011
984
  ),
1012
- children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-2xl text-center", children: [
1013
- teamTitle && (typeof teamTitle === "string" ? /* @__PURE__ */ jsx(
1014
- "h2",
1015
- {
1016
- className: cn(
1017
- "text-3xl font-bold md:text-4xl",
1018
- teamTitleClassName
1019
- ),
1020
- children: teamTitle
1021
- }
1022
- ) : /* @__PURE__ */ jsx("div", { className: teamTitleClassName, children: teamTitle })),
1023
- teamDescription && (typeof teamDescription === "string" ? /* @__PURE__ */ jsx(
1024
- "p",
1025
- {
1026
- className: cn(
1027
- "mt-4 text-lg",
1028
- getTextColor(background, "muted"),
1029
- teamDescriptionClassName
1030
- ),
1031
- children: teamDescription
1032
- }
1033
- ) : /* @__PURE__ */ jsx("div", { className: cn("mt-4", teamDescriptionClassName), children: teamDescription })),
1034
- actionsContent
1035
- ] })
985
+ children: /* @__PURE__ */ jsxs(
986
+ "div",
987
+ {
988
+ className: cn(
989
+ "flex flex-col md:flex-row",
990
+ "justify-center md:justify-between items-center md:items-start",
991
+ "gap-8 md:gap-24"
992
+ ),
993
+ children: [
994
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 md:gap-8 text-center md:text-left", children: [
995
+ teamTitle && (typeof teamTitle === "string" ? /* @__PURE__ */ jsx(
996
+ "h2",
997
+ {
998
+ className: cn(
999
+ "text-3xl font-bold md:text-4xl",
1000
+ teamTitleClassName
1001
+ ),
1002
+ children: teamTitle
1003
+ }
1004
+ ) : teamTitle),
1005
+ teamDescription && (typeof teamDescription === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-lg", teamDescriptionClassName), children: teamDescription }) : teamDescription)
1006
+ ] }),
1007
+ /* @__PURE__ */ jsx(
1008
+ BlockActions,
1009
+ {
1010
+ actions,
1011
+ actionsSlot,
1012
+ actionsClassName
1013
+ }
1014
+ )
1015
+ ]
1016
+ }
1017
+ )
1036
1018
  }
1037
1019
  )
1038
1020
  ]