@opensite/ui 2.3.7 → 2.3.9

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,253 +1,511 @@
1
1
  "use client";
2
- import * as React from 'react';
3
- import React__default, { useCallback, useMemo } from 'react';
2
+ import * as React3 from 'react';
3
+ import React3__default, { useCallback, 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 { cva } from 'class-variance-authority';
8
- import { jsx, jsxs } from 'react/jsx-runtime';
9
7
  import { Icon } from '@page-speed/icon';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
9
  import * as TabsPrimitive from '@radix-ui/react-tabs';
11
10
  import { Slot } from '@radix-ui/react-slot';
11
+ import { cva } from 'class-variance-authority';
12
12
 
13
13
  // components/blocks/about/community-initiatives.tsx
14
14
  function cn(...inputs) {
15
15
  return twMerge(clsx(inputs));
16
16
  }
17
- function getNestedCardBg(parentBg, variant = "muted", options) {
18
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
19
- if (isDark) {
20
- switch (variant) {
21
- case "muted":
22
- return "bg-background";
23
- case "card":
24
- return "bg-card";
25
- case "accent":
26
- return "bg-accent";
27
- case "subtle":
28
- return "bg-background/50";
29
- }
30
- } else {
31
- switch (variant) {
32
- case "muted":
33
- return "bg-muted";
34
- case "card":
35
- return "bg-card";
36
- case "accent":
37
- return "bg-accent";
38
- case "subtle":
39
- return "bg-muted/50";
40
- }
41
- }
17
+ var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
18
+ function DynamicIcon({ apiKey, ...props }) {
19
+ return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
42
20
  }
43
- function getTextColor(parentBg, variant = "default", options) {
44
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
45
- if (isDark) {
46
- switch (variant) {
47
- case "default":
48
- return "text-foreground";
49
- case "muted":
50
- return "text-foreground/80";
51
- case "subtle":
52
- return "text-foreground/60";
53
- case "accent":
54
- return "text-accent-foreground";
55
- }
56
- } else {
57
- switch (variant) {
58
- case "default":
59
- return "text-foreground";
60
- case "muted":
61
- return "text-muted-foreground";
62
- case "subtle":
63
- return "text-muted-foreground/70";
64
- case "accent":
65
- return "text-primary";
21
+ function Tabs({
22
+ className,
23
+ ...props
24
+ }) {
25
+ return /* @__PURE__ */ jsx(
26
+ TabsPrimitive.Root,
27
+ {
28
+ "data-slot": "tabs",
29
+ className: cn("flex flex-col gap-2", className),
30
+ ...props
66
31
  }
67
- }
32
+ );
68
33
  }
69
- function getAccentColor(parentBg, options) {
70
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
71
- return isDark ? "text-accent-foreground" : "text-primary";
34
+ function TabsList({
35
+ className,
36
+ ...props
37
+ }) {
38
+ return /* @__PURE__ */ jsx(
39
+ TabsPrimitive.List,
40
+ {
41
+ "data-slot": "tabs-list",
42
+ className: cn(
43
+ "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
44
+ className
45
+ ),
46
+ ...props
47
+ }
48
+ );
72
49
  }
73
- function normalizePhoneNumber(input) {
74
- const trimmed = input.trim();
75
- if (trimmed.toLowerCase().startsWith("tel:")) {
76
- return trimmed;
77
- }
78
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
79
- if (match) {
80
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
81
- const extension = match[3];
82
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
83
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
84
- return `tel:${withExtension}`;
85
- }
86
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
87
- return `tel:${cleaned}`;
50
+ function TabsTrigger({
51
+ className,
52
+ ...props
53
+ }) {
54
+ return /* @__PURE__ */ jsx(
55
+ TabsPrimitive.Trigger,
56
+ {
57
+ "data-slot": "tabs-trigger",
58
+ className: cn(
59
+ "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
60
+ className
61
+ ),
62
+ ...props
63
+ }
64
+ );
88
65
  }
89
- function normalizeEmail(input) {
90
- const trimmed = input.trim();
91
- if (trimmed.toLowerCase().startsWith("mailto:")) {
92
- return trimmed;
93
- }
94
- return `mailto:${trimmed}`;
66
+ function TabsContent({
67
+ className,
68
+ ...props
69
+ }) {
70
+ return /* @__PURE__ */ jsx(
71
+ TabsPrimitive.Content,
72
+ {
73
+ "data-slot": "tabs-content",
74
+ className: cn("flex-1 outline-none", className),
75
+ ...props
76
+ }
77
+ );
95
78
  }
96
- function isEmail(input) {
97
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
98
- return emailRegex.test(input.trim());
79
+ function Card({ className, ...props }) {
80
+ return /* @__PURE__ */ jsx(
81
+ "div",
82
+ {
83
+ "data-slot": "card",
84
+ className: cn(
85
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
86
+ className
87
+ ),
88
+ ...props
89
+ }
90
+ );
99
91
  }
100
- function isPhoneNumber(input) {
101
- const trimmed = input.trim();
102
- if (trimmed.toLowerCase().startsWith("tel:")) {
103
- return true;
104
- }
105
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
106
- return phoneRegex.test(trimmed);
92
+ function CardContent({ className, ...props }) {
93
+ return /* @__PURE__ */ jsx(
94
+ "div",
95
+ {
96
+ "data-slot": "card-content",
97
+ className: cn("px-6", className),
98
+ ...props
99
+ }
100
+ );
107
101
  }
108
- function isInternalUrl(href) {
109
- if (typeof window === "undefined") {
110
- return href.startsWith("/") && !href.startsWith("//");
111
- }
112
- const trimmed = href.trim();
113
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
114
- return true;
115
- }
116
- try {
117
- const url = new URL(trimmed, window.location.href);
118
- const currentOrigin = window.location.origin;
119
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
120
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
121
- } catch {
122
- return false;
102
+ var badgeVariants = cva(
103
+ "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
104
+ {
105
+ variants: {
106
+ variant: {
107
+ default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
108
+ secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
109
+ destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
110
+ outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
111
+ }
112
+ },
113
+ defaultVariants: {
114
+ variant: "default"
115
+ }
123
116
  }
117
+ );
118
+ function Badge({
119
+ className,
120
+ variant,
121
+ asChild = false,
122
+ ...props
123
+ }) {
124
+ const Comp = asChild ? Slot : "span";
125
+ return /* @__PURE__ */ jsx(
126
+ Comp,
127
+ {
128
+ "data-slot": "badge",
129
+ className: cn(badgeVariants({ variant }), className),
130
+ ...props
131
+ }
132
+ );
124
133
  }
125
- function toRelativePath(href) {
126
- if (typeof window === "undefined") {
127
- return href;
134
+ var maxWidthStyles = {
135
+ sm: "max-w-screen-sm",
136
+ md: "max-w-screen-md",
137
+ lg: "max-w-screen-lg",
138
+ xl: "max-w-7xl",
139
+ "2xl": "max-w-screen-2xl",
140
+ "4xl": "max-w-[1536px]",
141
+ full: "max-w-full"
142
+ };
143
+ var Container = React3__default.forwardRef(
144
+ ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
145
+ const Component = as;
146
+ return /* @__PURE__ */ jsx(
147
+ Component,
148
+ {
149
+ ref,
150
+ className: cn(
151
+ "mx-auto w-full px-2 sm:px-4 lg:px-8",
152
+ maxWidthStyles[maxWidth],
153
+ className
154
+ ),
155
+ ...props,
156
+ children
157
+ }
158
+ );
128
159
  }
129
- const trimmed = href.trim();
130
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
131
- return trimmed;
160
+ );
161
+ Container.displayName = "Container";
162
+
163
+ // lib/patternSvgs.ts
164
+ var patternSvgs = {
165
+ squareAltGrid: "https://cdn.ing/assets/files/record/286187/4gpn0yq2ptra8iwlvmwwv860ggwv",
166
+ grid1: "https://cdn.ing/assets/files/record/286186/nbdflpgp4ostrno079hygibsflp3",
167
+ noise: "https://cdn.ing/assets/i/r/286188/zrqcp9hynh3j7p2laihwzfbujgrl/noise.png",
168
+ dots: "https://cdn.ing/assets/files/record/286198/yfsjx9thvtxzhl2qtshxyhkrm524",
169
+ dotPattern: "https://cdn.ing/assets/files/record/286192/7ig0cku8aqbboiza8nuk6hw0nnsr",
170
+ dotPattern2: "https://cdn.ing/assets/files/record/286189/arez6gd2s7isn9i1o6c7sexdq7bl",
171
+ circles: "https://cdn.ing/assets/files/record/286190/gtmia3sncjtzetdshc20zf1d3c17",
172
+ waves: "https://cdn.ing/assets/files/record/286191/mqlb33fzxz9cdth1bx7if0wmpkp1",
173
+ crossPattern: "https://cdn.ing/assets/files/record/286193/9yfqwdbnqaipbp7fsb3wbzzmq472",
174
+ architect: "https://cdn.ing/assets/files/record/286194/vgs88ugpvyhxu13wqgy0acvae6re",
175
+ tinyCheckers: "https://cdn.ing/assets/files/record/286195/65efaknsw8kcpf9o3c2gybytsl5b",
176
+ p6: "https://cdn.ing/assets/i/r/286196/6kl0rqnd6mjk8j7e525fo8fo0vkc/p6.webp"
177
+ };
178
+ var maskTop = "radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%)";
179
+ var maskBottom = "radial-gradient(ellipse 100% 80% at 50% 100%, #000 50%, transparent 90%)";
180
+ var maskCenter = "radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 70%)";
181
+ var maskTopLeft = "radial-gradient(ellipse 80% 80% at 0% 0%, #000 50%, transparent 90%)";
182
+ var maskTopRight = "radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)";
183
+ var maskBottomLeft = "radial-gradient(ellipse 80% 80% at 0% 100%, #000 50%, transparent 90%)";
184
+ var maskBottomRight = "radial-gradient(ellipse 80% 80% at 100% 100%, #000 50%, transparent 90%)";
185
+ var circuitBoardPattern = (id, mask) => /* @__PURE__ */ jsxs(
186
+ "svg",
187
+ {
188
+ className: "h-full w-full",
189
+ xmlns: "http://www.w3.org/2000/svg",
190
+ style: mask ? {
191
+ maskImage: mask,
192
+ WebkitMaskImage: mask
193
+ } : void 0,
194
+ children: [
195
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
196
+ "pattern",
197
+ {
198
+ id,
199
+ x: "0",
200
+ y: "0",
201
+ width: "100",
202
+ height: "100",
203
+ patternUnits: "userSpaceOnUse",
204
+ children: [
205
+ /* @__PURE__ */ jsx(
206
+ "path",
207
+ {
208
+ d: "M0 50h40M60 50h40M50 0v40M50 60v40",
209
+ stroke: "hsl(var(--muted))",
210
+ strokeWidth: "1",
211
+ fill: "none"
212
+ }
213
+ ),
214
+ /* @__PURE__ */ jsx("circle", { cx: "50", cy: "50", r: "3", fill: "hsl(var(--muted))" }),
215
+ /* @__PURE__ */ jsx("circle", { cx: "0", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
216
+ /* @__PURE__ */ jsx("circle", { cx: "100", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
217
+ /* @__PURE__ */ jsx("circle", { cx: "50", cy: "0", r: "2", fill: "hsl(var(--muted))" }),
218
+ /* @__PURE__ */ jsx("circle", { cx: "50", cy: "100", r: "2", fill: "hsl(var(--muted))" })
219
+ ]
220
+ }
221
+ ) }),
222
+ /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
223
+ ]
132
224
  }
133
- try {
134
- const url = new URL(trimmed, window.location.href);
135
- const currentOrigin = window.location.origin;
136
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
137
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
138
- return url.pathname + url.search + url.hash;
139
- }
140
- } catch {
225
+ );
226
+ var gridDotsPattern = (id, mask) => /* @__PURE__ */ jsxs(
227
+ "svg",
228
+ {
229
+ className: "h-full w-full",
230
+ xmlns: "http://www.w3.org/2000/svg",
231
+ style: mask ? {
232
+ maskImage: mask,
233
+ WebkitMaskImage: mask
234
+ } : void 0,
235
+ children: [
236
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
237
+ "pattern",
238
+ {
239
+ id,
240
+ x: "0",
241
+ y: "0",
242
+ width: "40",
243
+ height: "40",
244
+ patternUnits: "userSpaceOnUse",
245
+ children: [
246
+ /* @__PURE__ */ jsx(
247
+ "path",
248
+ {
249
+ d: "M0 20h40M20 0v40",
250
+ stroke: "hsl(var(--muted))",
251
+ strokeWidth: "0.5",
252
+ fill: "none"
253
+ }
254
+ ),
255
+ /* @__PURE__ */ jsx("circle", { cx: "20", cy: "20", r: "2", fill: "hsl(var(--muted))" })
256
+ ]
257
+ }
258
+ ) }),
259
+ /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
260
+ ]
141
261
  }
142
- return trimmed;
143
- }
144
- function useNavigation({
145
- href,
146
- onClick
147
- } = {}) {
148
- const linkType = React.useMemo(() => {
149
- if (!href || href.trim() === "") {
150
- return onClick ? "none" : "none";
151
- }
152
- const trimmed = href.trim();
153
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
154
- return "mailto";
155
- }
156
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
157
- return "tel";
158
- }
159
- if (isInternalUrl(trimmed)) {
160
- return "internal";
161
- }
162
- try {
163
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
164
- return "external";
165
- } catch {
166
- return "internal";
262
+ );
263
+ var gridPattern = (size, mask) => /* @__PURE__ */ jsx(
264
+ "div",
265
+ {
266
+ 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)]",
267
+ style: {
268
+ backgroundSize: `${size}px ${size}px`,
269
+ ...mask ? {
270
+ maskImage: mask,
271
+ WebkitMaskImage: mask
272
+ } : {}
167
273
  }
168
- }, [href, onClick]);
169
- const normalizedHref = React.useMemo(() => {
170
- if (!href || href.trim() === "") {
171
- return void 0;
274
+ }
275
+ );
276
+ var diagonalCrossPattern = (mask) => /* @__PURE__ */ jsx(
277
+ "div",
278
+ {
279
+ className: "h-full w-full",
280
+ style: {
281
+ 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)",
282
+ ...mask ? {
283
+ maskImage: mask,
284
+ WebkitMaskImage: mask
285
+ } : {}
172
286
  }
173
- const trimmed = href.trim();
174
- switch (linkType) {
175
- case "tel":
176
- return normalizePhoneNumber(trimmed);
177
- case "mailto":
178
- return normalizeEmail(trimmed);
179
- case "internal":
180
- return toRelativePath(trimmed);
181
- case "external":
182
- return trimmed;
183
- default:
184
- return trimmed;
287
+ }
288
+ );
289
+ 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)";
290
+ var dashedGridPattern = (fadeMask) => {
291
+ const mask = fadeMask ? `${dashedGridMaskBase}, ${fadeMask}` : dashedGridMaskBase;
292
+ return /* @__PURE__ */ jsx(
293
+ "div",
294
+ {
295
+ className: "h-full w-full",
296
+ style: {
297
+ backgroundImage: "linear-gradient(to right, hsl(var(--muted)) 1px, transparent 1px), linear-gradient(to bottom, hsl(var(--muted)) 1px, transparent 1px)",
298
+ backgroundSize: "20px 20px",
299
+ backgroundPosition: "0 0, 0 0",
300
+ maskImage: mask,
301
+ WebkitMaskImage: mask,
302
+ maskComposite: "intersect",
303
+ WebkitMaskComposite: "source-in"
304
+ }
185
305
  }
186
- }, [href, linkType]);
187
- const target = React.useMemo(() => {
188
- switch (linkType) {
189
- case "external":
190
- return "_blank";
191
- case "internal":
192
- return "_self";
193
- case "mailto":
194
- case "tel":
195
- return void 0;
196
- default:
197
- return void 0;
306
+ );
307
+ };
308
+ var gradientGlow = (position) => /* @__PURE__ */ jsx(
309
+ "div",
310
+ {
311
+ className: cn(
312
+ "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
313
+ position === "top" ? "-top-1/4" : "-bottom-1/4"
314
+ ),
315
+ style: {
316
+ background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
198
317
  }
199
- }, [linkType]);
200
- const rel = React.useMemo(() => {
201
- if (linkType === "external") {
202
- return "noopener noreferrer";
318
+ }
319
+ );
320
+ var spotlight = (position) => /* @__PURE__ */ jsx(
321
+ "div",
322
+ {
323
+ className: cn(
324
+ "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
325
+ position === "left" ? "-left-1/4" : "-right-1/4"
326
+ ),
327
+ style: {
328
+ background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
203
329
  }
204
- return void 0;
205
- }, [linkType]);
206
- const isExternal = linkType === "external";
207
- const isInternal = linkType === "internal";
208
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
209
- const handleClick = React.useCallback(
210
- (event) => {
211
- if (onClick) {
212
- try {
213
- onClick(event);
214
- } catch (error) {
215
- console.error("Error in user onClick handler:", error);
216
- }
330
+ }
331
+ );
332
+ var patternOverlays = {
333
+ circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
334
+ circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
335
+ circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
336
+ circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
337
+ circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
338
+ circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
339
+ circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
340
+ circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
341
+ dashedGridBasic: () => dashedGridPattern(),
342
+ dashedGridFadeTop: () => dashedGridPattern(maskTop),
343
+ dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
344
+ dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
345
+ dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
346
+ dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
347
+ dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
348
+ dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
349
+ diagonalCrossBasic: () => diagonalCrossPattern(),
350
+ diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
351
+ diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
352
+ diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
353
+ diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
354
+ diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
355
+ diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
356
+ diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
357
+ gridBasic: () => gridPattern(40),
358
+ gridFadeTop: () => gridPattern(32, maskTop),
359
+ gridFadeBottom: () => gridPattern(32, maskBottom),
360
+ gridFadeCenter: () => gridPattern(40, maskCenter),
361
+ gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
362
+ gridFadeTopRight: () => gridPattern(32, maskTopRight),
363
+ gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
364
+ gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
365
+ gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
366
+ gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
367
+ gradientGlowTop: () => gradientGlow("top"),
368
+ gradientGlowBottom: () => gradientGlow("bottom"),
369
+ spotlightLeft: () => spotlight("left"),
370
+ spotlightRight: () => spotlight("right")
371
+ };
372
+ var inlinePatternStyles = {
373
+ radialGradientTop: {
374
+ background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
375
+ },
376
+ radialGradientBottom: {
377
+ background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
378
+ }
379
+ };
380
+ function PatternBackground({
381
+ pattern,
382
+ opacity = 0.08,
383
+ className,
384
+ style
385
+ }) {
386
+ if (!pattern) {
387
+ return null;
388
+ }
389
+ if (pattern in inlinePatternStyles) {
390
+ const inlineStyle = inlinePatternStyles[pattern];
391
+ return /* @__PURE__ */ jsx(
392
+ "div",
393
+ {
394
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
395
+ style: { ...inlineStyle, opacity, ...style },
396
+ "aria-hidden": "true"
217
397
  }
218
- if (event.defaultPrevented) {
219
- return;
398
+ );
399
+ }
400
+ if (pattern in patternOverlays) {
401
+ const Overlay = patternOverlays[pattern];
402
+ return /* @__PURE__ */ jsx(
403
+ "div",
404
+ {
405
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
406
+ style: { opacity, ...style },
407
+ "aria-hidden": "true",
408
+ children: Overlay()
220
409
  }
221
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
222
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
223
- if (typeof window !== "undefined") {
224
- const handler = window.__opensiteNavigationHandler;
225
- if (typeof handler === "function") {
226
- try {
227
- const handled = handler(normalizedHref, event.nativeEvent || event);
228
- if (handled !== false) {
229
- event.preventDefault();
230
- }
231
- } catch (error) {
232
- console.error("Error in navigation handler:", error);
233
- }
234
- }
235
- }
236
- }
237
- },
238
- [onClick, shouldUseRouter, normalizedHref]
410
+ );
411
+ }
412
+ const patternUrl = pattern in patternSvgs ? patternSvgs[pattern] : pattern;
413
+ return /* @__PURE__ */ jsx(
414
+ "div",
415
+ {
416
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
417
+ style: {
418
+ backgroundImage: `url(${patternUrl})`,
419
+ backgroundRepeat: "repeat",
420
+ backgroundSize: "auto",
421
+ opacity,
422
+ ...style
423
+ },
424
+ "aria-hidden": "true"
425
+ }
239
426
  );
240
- return {
241
- linkType,
242
- normalizedHref,
243
- target,
244
- rel,
245
- isExternal,
246
- isInternal,
247
- shouldUseRouter,
248
- handleClick
249
- };
250
427
  }
428
+ var backgroundStyles = {
429
+ default: "bg-background text-foreground",
430
+ white: "bg-white text-dark",
431
+ gray: "bg-muted/30 text-foreground",
432
+ dark: "bg-foreground text-background",
433
+ transparent: "bg-transparent text-foreground",
434
+ gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
435
+ primary: "bg-primary text-primary-foreground",
436
+ secondary: "bg-secondary text-secondary-foreground",
437
+ muted: "bg-muted text-muted-foreground"
438
+ };
439
+ var spacingStyles = {
440
+ none: "py-0 md:py-0",
441
+ sm: "py-12 md:py-16",
442
+ md: "py-16 md:py-24",
443
+ lg: "py-20 md:py-32",
444
+ xl: "py-24 md:py-40"
445
+ };
446
+ var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
447
+ var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
448
+ var Section = React3__default.forwardRef(
449
+ ({
450
+ id,
451
+ title,
452
+ subtitle,
453
+ children,
454
+ className,
455
+ style,
456
+ background = "default",
457
+ spacing = "lg",
458
+ pattern,
459
+ patternOpacity,
460
+ patternClassName,
461
+ containerClassName,
462
+ containerMaxWidth = "xl",
463
+ ...props
464
+ }, ref) => {
465
+ const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
466
+ return /* @__PURE__ */ jsxs(
467
+ "section",
468
+ {
469
+ ref,
470
+ id,
471
+ className: cn(
472
+ "relative",
473
+ pattern ? "overflow-hidden" : null,
474
+ backgroundStyles[background],
475
+ isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
476
+ className
477
+ ),
478
+ style,
479
+ ...props,
480
+ children: [
481
+ /* @__PURE__ */ jsx(
482
+ PatternBackground,
483
+ {
484
+ pattern,
485
+ opacity: effectivePatternOpacity,
486
+ className: patternClassName
487
+ }
488
+ ),
489
+ /* @__PURE__ */ jsxs(
490
+ Container,
491
+ {
492
+ maxWidth: containerMaxWidth,
493
+ className: cn("relative z-10", containerClassName),
494
+ children: [
495
+ (title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
496
+ subtitle && /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
497
+ title && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
498
+ ] }),
499
+ children
500
+ ]
501
+ }
502
+ )
503
+ ]
504
+ }
505
+ );
506
+ }
507
+ );
508
+ Section.displayName = "Section";
251
509
  var baseStyles = [
252
510
  // Layout
253
511
  "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
@@ -390,596 +648,346 @@ var buttonVariants = cva(baseStyles, {
390
648
  size: "default"
391
649
  }
392
650
  });
393
- var Pressable = React.forwardRef(
394
- ({
395
- children,
396
- className,
397
- href,
398
- onClick,
399
- variant,
400
- size,
401
- asButton = false,
402
- fallbackComponentType = "span",
403
- componentType,
404
- "aria-label": ariaLabel,
405
- "aria-describedby": ariaDescribedby,
406
- id,
407
- ...props
408
- }, ref) => {
409
- const navigation = useNavigation({ href, onClick });
410
- const {
411
- normalizedHref,
412
- target,
413
- rel,
414
- linkType,
415
- isInternal,
416
- handleClick
417
- } = navigation;
418
- const shouldRenderLink = normalizedHref && linkType !== "none";
419
- const shouldRenderButton = !shouldRenderLink && onClick;
420
- const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
421
- const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
422
- const shouldApplyButtonStyles = asButton || variant || size;
423
- const combinedClassName = cn(
424
- shouldApplyButtonStyles && buttonVariants({ variant, size }),
425
- className
426
- );
427
- const dataProps = Object.fromEntries(
428
- Object.entries(props).filter(([key]) => key.startsWith("data-"))
429
- );
430
- const buttonDataAttributes = shouldApplyButtonStyles ? {
431
- "data-slot": "button",
432
- "data-variant": variant ?? "default",
433
- "data-size": size ?? "default"
434
- } : {};
435
- const commonProps = {
436
- className: combinedClassName,
437
- onClick: handleClick,
438
- "aria-label": ariaLabel,
439
- "aria-describedby": ariaDescribedby,
440
- id,
441
- ...dataProps,
442
- ...buttonDataAttributes
443
- };
444
- if (finalComponentType === "a" && shouldRenderLink) {
445
- return /* @__PURE__ */ jsx(
446
- "a",
447
- {
448
- ref,
449
- href: normalizedHref,
450
- target,
451
- rel,
452
- ...commonProps,
453
- ...props,
454
- children
455
- }
456
- );
457
- }
458
- if (finalComponentType === "button") {
459
- return /* @__PURE__ */ jsx(
460
- "button",
461
- {
462
- ref,
463
- type: props.type || "button",
464
- ...commonProps,
465
- ...props,
466
- children
467
- }
468
- );
469
- }
470
- if (finalComponentType === "div") {
471
- return /* @__PURE__ */ jsx(
472
- "div",
473
- {
474
- ref,
475
- ...commonProps,
476
- children
477
- }
478
- );
479
- }
480
- return /* @__PURE__ */ jsx(
481
- "span",
482
- {
483
- ref,
484
- ...commonProps,
485
- children
486
- }
487
- );
651
+ function normalizePhoneNumber(input) {
652
+ const trimmed = input.trim();
653
+ if (trimmed.toLowerCase().startsWith("tel:")) {
654
+ return trimmed;
488
655
  }
489
- );
490
- Pressable.displayName = "Pressable";
491
- var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
492
- function DynamicIcon({ apiKey, ...props }) {
493
- return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
656
+ const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
657
+ if (match) {
658
+ const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
659
+ const extension = match[3];
660
+ const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
661
+ const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
662
+ return `tel:${withExtension}`;
663
+ }
664
+ const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
665
+ return `tel:${cleaned}`;
494
666
  }
495
- function Tabs({
496
- className,
497
- ...props
498
- }) {
499
- return /* @__PURE__ */ jsx(
500
- TabsPrimitive.Root,
501
- {
502
- "data-slot": "tabs",
503
- className: cn("flex flex-col gap-2", className),
504
- ...props
505
- }
506
- );
667
+ function normalizeEmail(input) {
668
+ const trimmed = input.trim();
669
+ if (trimmed.toLowerCase().startsWith("mailto:")) {
670
+ return trimmed;
671
+ }
672
+ return `mailto:${trimmed}`;
507
673
  }
508
- function TabsList({
509
- className,
510
- ...props
511
- }) {
512
- return /* @__PURE__ */ jsx(
513
- TabsPrimitive.List,
514
- {
515
- "data-slot": "tabs-list",
516
- className: cn(
517
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
518
- className
519
- ),
520
- ...props
521
- }
522
- );
674
+ function isEmail(input) {
675
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
676
+ return emailRegex.test(input.trim());
523
677
  }
524
- function TabsTrigger({
525
- className,
526
- ...props
527
- }) {
528
- return /* @__PURE__ */ jsx(
529
- TabsPrimitive.Trigger,
530
- {
531
- "data-slot": "tabs-trigger",
532
- className: cn(
533
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
534
- className
535
- ),
536
- ...props
537
- }
538
- );
678
+ function isPhoneNumber(input) {
679
+ const trimmed = input.trim();
680
+ if (trimmed.toLowerCase().startsWith("tel:")) {
681
+ return true;
682
+ }
683
+ const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
684
+ return phoneRegex.test(trimmed);
539
685
  }
540
- function TabsContent({
541
- className,
542
- ...props
543
- }) {
544
- return /* @__PURE__ */ jsx(
545
- TabsPrimitive.Content,
546
- {
547
- "data-slot": "tabs-content",
548
- className: cn("flex-1 outline-none", className),
549
- ...props
550
- }
551
- );
686
+ function isInternalUrl(href) {
687
+ if (typeof window === "undefined") {
688
+ return href.startsWith("/") && !href.startsWith("//");
689
+ }
690
+ const trimmed = href.trim();
691
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
692
+ return true;
693
+ }
694
+ try {
695
+ const url = new URL(trimmed, window.location.href);
696
+ const currentOrigin = window.location.origin;
697
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
698
+ return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
699
+ } catch {
700
+ return false;
701
+ }
552
702
  }
553
- function Card({ className, ...props }) {
554
- return /* @__PURE__ */ jsx(
555
- "div",
556
- {
557
- "data-slot": "card",
558
- className: cn(
559
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
560
- className
561
- ),
562
- ...props
703
+ function toRelativePath(href) {
704
+ if (typeof window === "undefined") {
705
+ return href;
706
+ }
707
+ const trimmed = href.trim();
708
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
709
+ return trimmed;
710
+ }
711
+ try {
712
+ const url = new URL(trimmed, window.location.href);
713
+ const currentOrigin = window.location.origin;
714
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
715
+ if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
716
+ return url.pathname + url.search + url.hash;
563
717
  }
564
- );
718
+ } catch {
719
+ }
720
+ return trimmed;
565
721
  }
566
- function CardContent({ className, ...props }) {
567
- return /* @__PURE__ */ jsx(
568
- "div",
569
- {
570
- "data-slot": "card-content",
571
- className: cn("px-6", className),
572
- ...props
722
+ function useNavigation({
723
+ href,
724
+ onClick
725
+ } = {}) {
726
+ const linkType = React3.useMemo(() => {
727
+ if (!href || href.trim() === "") {
728
+ return onClick ? "none" : "none";
573
729
  }
574
- );
575
- }
576
- var badgeVariants = cva(
577
- "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
578
- {
579
- variants: {
580
- variant: {
581
- default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
582
- secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
583
- destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
584
- outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
585
- }
586
- },
587
- defaultVariants: {
588
- variant: "default"
730
+ const trimmed = href.trim();
731
+ if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
732
+ return "mailto";
589
733
  }
590
- }
591
- );
592
- function Badge({
593
- className,
594
- variant,
595
- asChild = false,
596
- ...props
597
- }) {
598
- const Comp = asChild ? Slot : "span";
599
- return /* @__PURE__ */ jsx(
600
- Comp,
601
- {
602
- "data-slot": "badge",
603
- className: cn(badgeVariants({ variant }), className),
604
- ...props
734
+ if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
735
+ return "tel";
605
736
  }
606
- );
607
- }
608
- var maxWidthStyles = {
609
- sm: "max-w-screen-sm",
610
- md: "max-w-screen-md",
611
- lg: "max-w-screen-lg",
612
- xl: "max-w-7xl",
613
- "2xl": "max-w-screen-2xl",
614
- "4xl": "max-w-[1536px]",
615
- full: "max-w-full"
616
- };
617
- var Container = React__default.forwardRef(
618
- ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
619
- const Component = as;
620
- return /* @__PURE__ */ jsx(
621
- Component,
622
- {
623
- ref,
624
- className: cn(
625
- "mx-auto w-full px-2 sm:px-4 lg:px-8",
626
- maxWidthStyles[maxWidth],
627
- className
628
- ),
629
- ...props,
630
- children
737
+ if (isInternalUrl(trimmed)) {
738
+ return "internal";
739
+ }
740
+ try {
741
+ new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
742
+ return "external";
743
+ } catch {
744
+ return "internal";
745
+ }
746
+ }, [href, onClick]);
747
+ const normalizedHref = React3.useMemo(() => {
748
+ if (!href || href.trim() === "") {
749
+ return void 0;
750
+ }
751
+ const trimmed = href.trim();
752
+ switch (linkType) {
753
+ case "tel":
754
+ return normalizePhoneNumber(trimmed);
755
+ case "mailto":
756
+ return normalizeEmail(trimmed);
757
+ case "internal":
758
+ return toRelativePath(trimmed);
759
+ case "external":
760
+ return trimmed;
761
+ default:
762
+ return trimmed;
763
+ }
764
+ }, [href, linkType]);
765
+ const target = React3.useMemo(() => {
766
+ switch (linkType) {
767
+ case "external":
768
+ return "_blank";
769
+ case "internal":
770
+ return "_self";
771
+ case "mailto":
772
+ case "tel":
773
+ return void 0;
774
+ default:
775
+ return void 0;
776
+ }
777
+ }, [linkType]);
778
+ const rel = React3.useMemo(() => {
779
+ if (linkType === "external") {
780
+ return "noopener noreferrer";
781
+ }
782
+ return void 0;
783
+ }, [linkType]);
784
+ const isExternal = linkType === "external";
785
+ const isInternal = linkType === "internal";
786
+ const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
787
+ const handleClick = React3.useCallback(
788
+ (event) => {
789
+ if (onClick) {
790
+ try {
791
+ onClick(event);
792
+ } catch (error) {
793
+ console.error("Error in user onClick handler:", error);
794
+ }
631
795
  }
632
- );
633
- }
634
- );
635
- Container.displayName = "Container";
636
-
637
- // lib/patternSvgs.ts
638
- var patternSvgs = {
639
- squareAltGrid: "https://cdn.ing/assets/files/record/286187/4gpn0yq2ptra8iwlvmwwv860ggwv",
640
- grid1: "https://cdn.ing/assets/files/record/286186/nbdflpgp4ostrno079hygibsflp3",
641
- noise: "https://cdn.ing/assets/i/r/286188/zrqcp9hynh3j7p2laihwzfbujgrl/noise.png",
642
- dots: "https://cdn.ing/assets/files/record/286198/yfsjx9thvtxzhl2qtshxyhkrm524",
643
- dotPattern: "https://cdn.ing/assets/files/record/286192/7ig0cku8aqbboiza8nuk6hw0nnsr",
644
- dotPattern2: "https://cdn.ing/assets/files/record/286189/arez6gd2s7isn9i1o6c7sexdq7bl",
645
- circles: "https://cdn.ing/assets/files/record/286190/gtmia3sncjtzetdshc20zf1d3c17",
646
- waves: "https://cdn.ing/assets/files/record/286191/mqlb33fzxz9cdth1bx7if0wmpkp1",
647
- crossPattern: "https://cdn.ing/assets/files/record/286193/9yfqwdbnqaipbp7fsb3wbzzmq472",
648
- architect: "https://cdn.ing/assets/files/record/286194/vgs88ugpvyhxu13wqgy0acvae6re",
649
- tinyCheckers: "https://cdn.ing/assets/files/record/286195/65efaknsw8kcpf9o3c2gybytsl5b",
650
- p6: "https://cdn.ing/assets/i/r/286196/6kl0rqnd6mjk8j7e525fo8fo0vkc/p6.webp"
651
- };
652
- var maskTop = "radial-gradient(ellipse 70% 60% at 50% 0%, #000 60%, transparent 100%)";
653
- var maskBottom = "radial-gradient(ellipse 100% 80% at 50% 100%, #000 50%, transparent 90%)";
654
- var maskCenter = "radial-gradient(ellipse 60% 60% at 50% 50%, #000 30%, transparent 70%)";
655
- var maskTopLeft = "radial-gradient(ellipse 80% 80% at 0% 0%, #000 50%, transparent 90%)";
656
- var maskTopRight = "radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)";
657
- var maskBottomLeft = "radial-gradient(ellipse 80% 80% at 0% 100%, #000 50%, transparent 90%)";
658
- var maskBottomRight = "radial-gradient(ellipse 80% 80% at 100% 100%, #000 50%, transparent 90%)";
659
- var circuitBoardPattern = (id, mask) => /* @__PURE__ */ jsxs(
660
- "svg",
661
- {
662
- className: "h-full w-full",
663
- xmlns: "http://www.w3.org/2000/svg",
664
- style: mask ? {
665
- maskImage: mask,
666
- WebkitMaskImage: mask
667
- } : void 0,
668
- children: [
669
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
670
- "pattern",
671
- {
672
- id,
673
- x: "0",
674
- y: "0",
675
- width: "100",
676
- height: "100",
677
- patternUnits: "userSpaceOnUse",
678
- children: [
679
- /* @__PURE__ */ jsx(
680
- "path",
681
- {
682
- d: "M0 50h40M60 50h40M50 0v40M50 60v40",
683
- stroke: "hsl(var(--muted))",
684
- strokeWidth: "1",
685
- fill: "none"
796
+ if (event.defaultPrevented) {
797
+ return;
798
+ }
799
+ if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
800
+ !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
801
+ if (typeof window !== "undefined") {
802
+ const handler = window.__opensiteNavigationHandler;
803
+ if (typeof handler === "function") {
804
+ try {
805
+ const handled = handler(normalizedHref, event.nativeEvent || event);
806
+ if (handled !== false) {
807
+ event.preventDefault();
686
808
  }
687
- ),
688
- /* @__PURE__ */ jsx("circle", { cx: "50", cy: "50", r: "3", fill: "hsl(var(--muted))" }),
689
- /* @__PURE__ */ jsx("circle", { cx: "0", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
690
- /* @__PURE__ */ jsx("circle", { cx: "100", cy: "50", r: "2", fill: "hsl(var(--muted))" }),
691
- /* @__PURE__ */ jsx("circle", { cx: "50", cy: "0", r: "2", fill: "hsl(var(--muted))" }),
692
- /* @__PURE__ */ jsx("circle", { cx: "50", cy: "100", r: "2", fill: "hsl(var(--muted))" })
693
- ]
809
+ } catch (error) {
810
+ console.error("Error in navigation handler:", error);
811
+ }
812
+ }
694
813
  }
695
- ) }),
696
- /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
697
- ]
698
- }
699
- );
700
- var gridDotsPattern = (id, mask) => /* @__PURE__ */ jsxs(
701
- "svg",
702
- {
703
- className: "h-full w-full",
704
- xmlns: "http://www.w3.org/2000/svg",
705
- style: mask ? {
706
- maskImage: mask,
707
- WebkitMaskImage: mask
708
- } : void 0,
709
- children: [
710
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
711
- "pattern",
814
+ }
815
+ },
816
+ [onClick, shouldUseRouter, normalizedHref]
817
+ );
818
+ return {
819
+ linkType,
820
+ normalizedHref,
821
+ target,
822
+ rel,
823
+ isExternal,
824
+ isInternal,
825
+ shouldUseRouter,
826
+ handleClick
827
+ };
828
+ }
829
+ var Pressable = React3.forwardRef(
830
+ ({
831
+ children,
832
+ className,
833
+ href,
834
+ onClick,
835
+ variant,
836
+ size,
837
+ asButton = false,
838
+ fallbackComponentType = "span",
839
+ componentType,
840
+ "aria-label": ariaLabel,
841
+ "aria-describedby": ariaDescribedby,
842
+ id,
843
+ ...props
844
+ }, ref) => {
845
+ const navigation = useNavigation({ href, onClick });
846
+ const {
847
+ normalizedHref,
848
+ target,
849
+ rel,
850
+ linkType,
851
+ isInternal,
852
+ handleClick
853
+ } = navigation;
854
+ const shouldRenderLink = normalizedHref && linkType !== "none";
855
+ const shouldRenderButton = !shouldRenderLink && onClick;
856
+ const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
857
+ const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
858
+ const shouldApplyButtonStyles = asButton || variant || size;
859
+ const combinedClassName = cn(
860
+ shouldApplyButtonStyles && buttonVariants({ variant, size }),
861
+ className
862
+ );
863
+ const dataProps = Object.fromEntries(
864
+ Object.entries(props).filter(([key]) => key.startsWith("data-"))
865
+ );
866
+ const buttonDataAttributes = shouldApplyButtonStyles ? {
867
+ "data-slot": "button",
868
+ "data-variant": variant ?? "default",
869
+ "data-size": size ?? "default"
870
+ } : {};
871
+ const commonProps = {
872
+ className: combinedClassName,
873
+ onClick: handleClick,
874
+ "aria-label": ariaLabel,
875
+ "aria-describedby": ariaDescribedby,
876
+ id,
877
+ ...dataProps,
878
+ ...buttonDataAttributes
879
+ };
880
+ if (finalComponentType === "a" && shouldRenderLink) {
881
+ return /* @__PURE__ */ jsx(
882
+ "a",
712
883
  {
713
- id,
714
- x: "0",
715
- y: "0",
716
- width: "40",
717
- height: "40",
718
- patternUnits: "userSpaceOnUse",
719
- children: [
720
- /* @__PURE__ */ jsx(
721
- "path",
722
- {
723
- d: "M0 20h40M20 0v40",
724
- stroke: "hsl(var(--muted))",
725
- strokeWidth: "0.5",
726
- fill: "none"
727
- }
728
- ),
729
- /* @__PURE__ */ jsx("circle", { cx: "20", cy: "20", r: "2", fill: "hsl(var(--muted))" })
730
- ]
884
+ ref,
885
+ href: normalizedHref,
886
+ target,
887
+ rel,
888
+ ...commonProps,
889
+ ...props,
890
+ children
731
891
  }
732
- ) }),
733
- /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id})` })
734
- ]
735
- }
736
- );
737
- var gridPattern = (size, mask) => /* @__PURE__ */ jsx(
738
- "div",
739
- {
740
- 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)]",
741
- style: {
742
- backgroundSize: `${size}px ${size}px`,
743
- ...mask ? {
744
- maskImage: mask,
745
- WebkitMaskImage: mask
746
- } : {}
747
- }
748
- }
749
- );
750
- var diagonalCrossPattern = (mask) => /* @__PURE__ */ jsx(
751
- "div",
752
- {
753
- className: "h-full w-full",
754
- style: {
755
- 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)",
756
- ...mask ? {
757
- maskImage: mask,
758
- WebkitMaskImage: mask
759
- } : {}
760
- }
761
- }
762
- );
763
- 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)";
764
- var dashedGridPattern = (fadeMask) => {
765
- const mask = fadeMask ? `${dashedGridMaskBase}, ${fadeMask}` : dashedGridMaskBase;
766
- return /* @__PURE__ */ jsx(
767
- "div",
768
- {
769
- className: "h-full w-full",
770
- style: {
771
- backgroundImage: "linear-gradient(to right, hsl(var(--muted)) 1px, transparent 1px), linear-gradient(to bottom, hsl(var(--muted)) 1px, transparent 1px)",
772
- backgroundSize: "20px 20px",
773
- backgroundPosition: "0 0, 0 0",
774
- maskImage: mask,
775
- WebkitMaskImage: mask,
776
- maskComposite: "intersect",
777
- WebkitMaskComposite: "source-in"
778
- }
892
+ );
779
893
  }
780
- );
781
- };
782
- var gradientGlow = (position) => /* @__PURE__ */ jsx(
783
- "div",
784
- {
785
- className: cn(
786
- "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
787
- position === "top" ? "-top-1/4" : "-bottom-1/4"
788
- ),
789
- style: {
790
- background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
894
+ if (finalComponentType === "button") {
895
+ return /* @__PURE__ */ jsx(
896
+ "button",
897
+ {
898
+ ref,
899
+ type: props.type || "button",
900
+ ...commonProps,
901
+ ...props,
902
+ children
903
+ }
904
+ );
791
905
  }
792
- }
793
- );
794
- var spotlight = (position) => /* @__PURE__ */ jsx(
795
- "div",
796
- {
797
- className: cn(
798
- "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
799
- position === "left" ? "-left-1/4" : "-right-1/4"
800
- ),
801
- style: {
802
- background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
906
+ if (finalComponentType === "div") {
907
+ return /* @__PURE__ */ jsx(
908
+ "div",
909
+ {
910
+ ref,
911
+ ...commonProps,
912
+ children
913
+ }
914
+ );
803
915
  }
804
- }
805
- );
806
- var patternOverlays = {
807
- circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
808
- circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
809
- circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
810
- circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
811
- circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
812
- circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
813
- circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
814
- circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
815
- dashedGridBasic: () => dashedGridPattern(),
816
- dashedGridFadeTop: () => dashedGridPattern(maskTop),
817
- dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
818
- dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
819
- dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
820
- dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
821
- dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
822
- dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
823
- diagonalCrossBasic: () => diagonalCrossPattern(),
824
- diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
825
- diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
826
- diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
827
- diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
828
- diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
829
- diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
830
- diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
831
- gridBasic: () => gridPattern(40),
832
- gridFadeTop: () => gridPattern(32, maskTop),
833
- gridFadeBottom: () => gridPattern(32, maskBottom),
834
- gridFadeCenter: () => gridPattern(40, maskCenter),
835
- gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
836
- gridFadeTopRight: () => gridPattern(32, maskTopRight),
837
- gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
838
- gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
839
- gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
840
- gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
841
- gradientGlowTop: () => gradientGlow("top"),
842
- gradientGlowBottom: () => gradientGlow("bottom"),
843
- spotlightLeft: () => spotlight("left"),
844
- spotlightRight: () => spotlight("right")
845
- };
846
- var inlinePatternStyles = {
847
- radialGradientTop: {
848
- background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
849
- },
850
- radialGradientBottom: {
851
- background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
852
- }
853
- };
854
- function PatternBackground({
855
- pattern,
856
- opacity = 0.08,
857
- className,
858
- style
859
- }) {
860
- if (!pattern) {
861
- return null;
862
- }
863
- if (pattern in inlinePatternStyles) {
864
- const inlineStyle = inlinePatternStyles[pattern];
865
916
  return /* @__PURE__ */ jsx(
866
- "div",
917
+ "span",
867
918
  {
868
- className: cn("pointer-events-none absolute inset-0 z-0", className),
869
- style: { ...inlineStyle, opacity, ...style },
870
- "aria-hidden": "true"
919
+ ref,
920
+ ...commonProps,
921
+ children
871
922
  }
872
923
  );
873
924
  }
874
- if (pattern in patternOverlays) {
875
- const Overlay = patternOverlays[pattern];
925
+ );
926
+ Pressable.displayName = "Pressable";
927
+ var MOBILE_CLASSES = {
928
+ "fit-left": "items-start md:items-center",
929
+ "fit-center": "items-center",
930
+ "fit-right": "items-end md:items-center",
931
+ "full-left": "items-stretch md:items-center",
932
+ "full-center": "items-stretch md:items-center",
933
+ "full-right": "items-stretch md:items-center"
934
+ };
935
+ function BlockActions({
936
+ mobileConfig,
937
+ actionsClassName,
938
+ verticalSpacing = "mt-4 md:mt-8",
939
+ actions,
940
+ actionsSlot
941
+ }) {
942
+ const width = mobileConfig?.width ?? "full";
943
+ const position = mobileConfig?.position ?? "center";
944
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
945
+ if (actionsSlot) {
946
+ return /* @__PURE__ */ jsx("div", { children: actionsSlot });
947
+ } else if (actions && actions?.length > 0) {
876
948
  return /* @__PURE__ */ jsx(
877
949
  "div",
878
950
  {
879
- className: cn("pointer-events-none absolute inset-0 z-0", className),
880
- style: { opacity, ...style },
881
- "aria-hidden": "true",
882
- children: Overlay()
951
+ className: cn(
952
+ "flex flex-col md:flex-row flex-wrap gap-4",
953
+ mobileLayoutClass,
954
+ actionsClassName,
955
+ verticalSpacing
956
+ ),
957
+ children: actions.map((action, index) => /* @__PURE__ */ jsx(ActionComponent, { action }, index))
883
958
  }
884
959
  );
960
+ } else {
961
+ return null;
885
962
  }
886
- const patternUrl = pattern in patternSvgs ? patternSvgs[pattern] : pattern;
963
+ }
964
+ function ActionComponent({ action }) {
965
+ const {
966
+ label,
967
+ icon,
968
+ iconAfter,
969
+ children,
970
+ href,
971
+ onClick,
972
+ className: actionClassName,
973
+ ...pressableProps
974
+ } = action;
887
975
  return /* @__PURE__ */ jsx(
888
- "div",
976
+ Pressable,
889
977
  {
890
- className: cn("pointer-events-none absolute inset-0 z-0", className),
891
- style: {
892
- backgroundImage: `url(${patternUrl})`,
893
- backgroundRepeat: "repeat",
894
- backgroundSize: "auto",
895
- opacity,
896
- ...style
897
- },
898
- "aria-hidden": "true"
978
+ href,
979
+ onClick,
980
+ asButton: action.asButton ?? true,
981
+ className: actionClassName,
982
+ ...pressableProps,
983
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
984
+ icon,
985
+ label,
986
+ iconAfter
987
+ ] })
899
988
  }
900
989
  );
901
990
  }
902
- var backgroundStyles = {
903
- default: "bg-background text-foreground",
904
- white: "bg-white text-dark",
905
- gray: "bg-muted/30 text-foreground",
906
- dark: "bg-foreground text-background",
907
- transparent: "bg-transparent text-foreground",
908
- gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
909
- primary: "bg-primary text-primary-foreground",
910
- secondary: "bg-secondary text-secondary-foreground",
911
- muted: "bg-muted text-muted-foreground"
912
- };
913
- var spacingStyles = {
914
- none: "py-0 md:py-0",
915
- sm: "py-12 md:py-16",
916
- md: "py-16 md:py-24",
917
- lg: "py-20 md:py-32",
918
- xl: "py-24 md:py-40"
919
- };
920
- var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
921
- var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
922
- var Section = React__default.forwardRef(
923
- ({
924
- id,
925
- title,
926
- subtitle,
927
- children,
928
- className,
929
- style,
930
- background = "default",
931
- spacing = "lg",
932
- pattern,
933
- patternOpacity,
934
- patternClassName,
935
- containerClassName,
936
- containerMaxWidth = "xl",
937
- ...props
938
- }, ref) => {
939
- const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
940
- return /* @__PURE__ */ jsxs(
941
- "section",
942
- {
943
- ref,
944
- id,
945
- className: cn(
946
- "relative",
947
- pattern ? "overflow-hidden" : null,
948
- backgroundStyles[background],
949
- isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
950
- className
951
- ),
952
- style,
953
- ...props,
954
- children: [
955
- /* @__PURE__ */ jsx(
956
- PatternBackground,
957
- {
958
- pattern,
959
- opacity: effectivePatternOpacity,
960
- className: patternClassName
961
- }
962
- ),
963
- /* @__PURE__ */ jsxs(
964
- Container,
965
- {
966
- maxWidth: containerMaxWidth,
967
- className: cn("relative z-10", containerClassName),
968
- children: [
969
- (title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
970
- subtitle && /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
971
- title && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
972
- ] }),
973
- children
974
- ]
975
- }
976
- )
977
- ]
978
- }
979
- );
980
- }
981
- );
982
- Section.displayName = "Section";
983
991
  function CommunityInitiatives({
984
992
  badgeText,
985
993
  heading,
@@ -1008,7 +1016,7 @@ function CommunityInitiatives({
1008
1016
  pattern,
1009
1017
  patternOpacity
1010
1018
  }) {
1011
- const [activeCategory, setActiveCategory] = React.useState(
1019
+ const [activeCategory, setActiveCategory] = React3.useState(
1012
1020
  categories?.[0]?.id || ""
1013
1021
  );
1014
1022
  const currentCategory = categories?.find((category) => category.id === activeCategory) || categories?.[0];
@@ -1018,28 +1026,6 @@ function CommunityInitiatives({
1018
1026
  },
1019
1027
  []
1020
1028
  );
1021
- const actionsContent = useMemo(() => {
1022
- if (actionsSlot) return actionsSlot;
1023
- if (!actions || actions.length === 0) return null;
1024
- return /* @__PURE__ */ jsx(
1025
- "div",
1026
- {
1027
- className: cn("flex flex-wrap justify-center gap-4", actionsClassName),
1028
- children: actions.map((action, idx) => /* @__PURE__ */ jsx(
1029
- Pressable,
1030
- {
1031
- href: action.href,
1032
- onClick: action.onClick,
1033
- variant: action.variant || "default",
1034
- size: action.size || "lg",
1035
- asButton: true,
1036
- children: action.label
1037
- },
1038
- idx
1039
- ))
1040
- }
1041
- );
1042
- }, [actionsSlot, actions, actionsClassName]);
1043
1029
  const categoriesContent = useMemo(() => {
1044
1030
  if (categoriesSlot) return categoriesSlot;
1045
1031
  if (!categories || categories.length === 0) return null;
@@ -1061,22 +1047,27 @@ function CommunityInitiatives({
1061
1047
  children: categories.map((category) => /* @__PURE__ */ jsx("option", { value: category.id, children: category.title }, category.id))
1062
1048
  }
1063
1049
  ) }),
1064
- /* @__PURE__ */ jsx(TabsList, { className: "hidden h-auto grid-cols-4 p-1 md:grid", children: categories.map((category) => /* @__PURE__ */ jsx(
1050
+ /* @__PURE__ */ jsx(TabsList, { className: "hidden h-auto grid-cols-4 p-1 md:grid ring-2 ring-primary", children: categories.map((category) => /* @__PURE__ */ jsx(
1065
1051
  TabsTrigger,
1066
1052
  {
1067
1053
  value: category.id,
1068
- className: "px-3 py-2.5 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground",
1054
+ className: cn(
1055
+ "px-3 py-2.5 cursor-pointer",
1056
+ "data-[state=active]:bg-primary data-[state=active]:text-primary-foreground",
1057
+ "hover:bg-muted hover:text-muted-foreground",
1058
+ "transition-all duration-500"
1059
+ ),
1069
1060
  children: category.title
1070
1061
  },
1071
1062
  category.id
1072
1063
  )) })
1073
1064
  ] }),
1074
- /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-2xl text-left md:text-center", children: /* @__PURE__ */ jsx("p", { className: cn(getTextColor(background, "muted")), children: currentCategory?.description }) }),
1065
+ /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-2xl text-left md:text-center", children: /* @__PURE__ */ jsx("p", { className: "relative", children: currentCategory?.description }) }),
1075
1066
  categories.map((category) => /* @__PURE__ */ jsx(
1076
1067
  TabsContent,
1077
1068
  {
1078
1069
  value: category.id,
1079
- className: "space-y-12",
1070
+ className: "space-y-12 md:space-y-24",
1080
1071
  children: category.initiatives.map((initiative, index) => {
1081
1072
  const isEven = index % 2 === 0;
1082
1073
  return /* @__PURE__ */ jsxs(
@@ -1093,47 +1084,13 @@ function CommunityInitiatives({
1093
1084
  ),
1094
1085
  children: [
1095
1086
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1096
- /* @__PURE__ */ jsx(
1097
- "div",
1098
- {
1099
- className: cn(
1100
- "rounded-md p-2",
1101
- getNestedCardBg(background, "muted")
1102
- ),
1103
- children: /* @__PURE__ */ jsx(
1104
- DynamicIcon,
1105
- {
1106
- name: initiative.icon,
1107
- size: 24,
1108
- className: cn(getAccentColor(background))
1109
- }
1110
- )
1111
- }
1112
- ),
1087
+ /* @__PURE__ */ jsx("div", { className: cn("rounded-md p-2"), children: /* @__PURE__ */ jsx(DynamicIcon, { name: initiative.icon, size: 24 }) }),
1113
1088
  /* @__PURE__ */ jsx("h3", { className: "text-2xl font-bold", children: initiative.title })
1114
1089
  ] }),
1115
- /* @__PURE__ */ jsx("p", { className: cn(getTextColor(background, "muted")), children: initiative.description }),
1090
+ /* @__PURE__ */ jsx("p", { className: "relative", children: initiative.description }),
1116
1091
  initiative.metrics && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-4 pt-2", children: initiative.metrics.map((metric, i) => /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
1117
- /* @__PURE__ */ jsx(
1118
- "div",
1119
- {
1120
- className: cn(
1121
- "text-2xl font-bold",
1122
- getAccentColor(background)
1123
- ),
1124
- children: metric.value
1125
- }
1126
- ),
1127
- /* @__PURE__ */ jsx(
1128
- "div",
1129
- {
1130
- className: cn(
1131
- "mt-1 text-xs",
1132
- getTextColor(background, "muted")
1133
- ),
1134
- children: metric.label
1135
- }
1136
- )
1092
+ /* @__PURE__ */ jsx("div", { className: cn("text-2xl font-bold"), children: metric.value }),
1093
+ /* @__PURE__ */ jsx("div", { className: cn("mt-1 text-xs"), children: metric.label })
1137
1094
  ] }, i)) })
1138
1095
  ]
1139
1096
  }
@@ -1145,7 +1102,7 @@ function CommunityInitiatives({
1145
1102
  "md:col-span-5",
1146
1103
  isEven ? "md:order-2" : "md:order-1"
1147
1104
  ),
1148
- children: /* @__PURE__ */ jsx("div", { className: "relative aspect-4/3 overflow-hidden rounded-xl", children: /* @__PURE__ */ jsx(
1105
+ children: /* @__PURE__ */ jsx("div", { className: "relative aspect-video overflow-hidden rounded-xl shadow-xl", children: /* @__PURE__ */ jsx(
1149
1106
  Img,
1150
1107
  {
1151
1108
  src: initiative.image,
@@ -1166,28 +1123,21 @@ function CommunityInitiatives({
1166
1123
  Card,
1167
1124
  {
1168
1125
  className: cn(
1169
- "flex h-full min-h-[280px] w-full items-center justify-center",
1170
- getNestedCardBg(background, "subtle")
1126
+ "flex h-full min-h-[280px] w-full items-center justify-center"
1171
1127
  ),
1172
- children: /* @__PURE__ */ jsxs(CardContent, { className: "p-6 text-center", children: [
1128
+ children: /* @__PURE__ */ jsxs(CardContent, { className: "p-6 text-center flex flex-col items-center gap-4", children: [
1173
1129
  /* @__PURE__ */ jsx(
1174
1130
  DynamicIcon,
1175
1131
  {
1176
1132
  name: initiative.icon,
1177
1133
  size: 64,
1178
1134
  className: cn(
1179
- "mx-auto mb-4",
1180
- getTextColor(background, "muted"),
1135
+ "mx-auto text-card-foreground",
1181
1136
  "opacity-50"
1182
1137
  )
1183
1138
  }
1184
1139
  ),
1185
- /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "mx-auto", children: [
1186
- "Learn more about our",
1187
- " ",
1188
- initiative.title.toLowerCase(),
1189
- " initiative"
1190
- ] })
1140
+ /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "mx-auto", children: initiative.title })
1191
1141
  ] })
1192
1142
  }
1193
1143
  )
@@ -1228,7 +1178,7 @@ function CommunityInitiatives({
1228
1178
  "div",
1229
1179
  {
1230
1180
  className: cn(
1231
- "mx-auto mb-8 md:mb-16 max-w-3xl space-y-4 text-center",
1181
+ "mx-auto mb-8 md:mb-16 max-w-3xl space-y-4 flex flex-col items-center",
1232
1182
  headerClassName
1233
1183
  ),
1234
1184
  children: [
@@ -1237,41 +1187,65 @@ function CommunityInitiatives({
1237
1187
  "h2",
1238
1188
  {
1239
1189
  className: cn(
1240
- "text-3xl font-bold tracking-tight md:text-4xl",
1190
+ "text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl text-balance text-center",
1241
1191
  headingClassName
1242
1192
  ),
1243
1193
  children: heading
1244
1194
  }
1245
1195
  ) : heading),
1246
- description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn(descriptionClassName), children: description }) : description)
1196
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx(
1197
+ "p",
1198
+ {
1199
+ className: cn(
1200
+ "text-lg text-balance text-center",
1201
+ descriptionClassName
1202
+ ),
1203
+ children: description
1204
+ }
1205
+ ) : description)
1247
1206
  ]
1248
1207
  }
1249
1208
  ),
1250
1209
  categoriesContent,
1251
- /* @__PURE__ */ jsxs("div", { className: cn("mt-20 text-center", ctaClassName), children: [
1252
- ctaBadgeText && /* @__PURE__ */ jsx(
1253
- "div",
1254
- {
1255
- className: cn(
1256
- "mb-8 inline-flex items-center justify-center rounded-full p-1"
1257
- ),
1258
- children: /* @__PURE__ */ jsx(Badge, { className: "rounded-full bg-primary px-4 py-1 text-primary-foreground", children: ctaBadgeText })
1259
- }
1260
- ),
1261
- ctaHeading && (typeof ctaHeading === "string" ? /* @__PURE__ */ jsx("h3", { className: cn("mb-4 text-2xl font-bold", ctaHeadingClassName), children: ctaHeading }) : ctaHeading),
1262
- ctaDescription && (typeof ctaDescription === "string" ? /* @__PURE__ */ jsx(
1263
- "p",
1264
- {
1265
- className: cn(
1266
- "mx-auto mb-8 max-w-2xl",
1267
- getTextColor(background, "muted"),
1268
- ctaDescriptionClassName
1210
+ /* @__PURE__ */ jsxs(
1211
+ "div",
1212
+ {
1213
+ className: cn(
1214
+ "mt-10 md:mt-24 p-6 md:p-16",
1215
+ "text-center flex flex-col items-center",
1216
+ "bg-muted text-muted-foreground",
1217
+ "rounded-2xl shadow-lg",
1218
+ ctaClassName
1219
+ ),
1220
+ children: [
1221
+ ctaBadgeText && /* @__PURE__ */ jsx(
1222
+ "div",
1223
+ {
1224
+ className: cn(
1225
+ "mb-8 inline-flex items-center justify-center rounded-full p-1"
1226
+ ),
1227
+ children: /* @__PURE__ */ jsx(Badge, { className: "rounded-full bg-primary px-4 py-1 text-primary-foreground", children: ctaBadgeText })
1228
+ }
1269
1229
  ),
1270
- children: ctaDescription
1271
- }
1272
- ) : ctaDescription),
1273
- actionsContent
1274
- ] })
1230
+ ctaHeading && (typeof ctaHeading === "string" ? /* @__PURE__ */ jsx("h3", { className: cn("mb-4 text-2xl font-bold", ctaHeadingClassName), children: ctaHeading }) : ctaHeading),
1231
+ ctaDescription && (typeof ctaDescription === "string" ? /* @__PURE__ */ jsx(
1232
+ "p",
1233
+ {
1234
+ className: cn("mx-auto mb-8 max-w-2xl", ctaDescriptionClassName),
1235
+ children: ctaDescription
1236
+ }
1237
+ ) : ctaDescription),
1238
+ /* @__PURE__ */ jsx(
1239
+ BlockActions,
1240
+ {
1241
+ actions,
1242
+ actionsSlot,
1243
+ actionsClassName
1244
+ }
1245
+ )
1246
+ ]
1247
+ }
1248
+ )
1275
1249
  ]
1276
1250
  }
1277
1251
  );