@opensite/ui 2.1.3 → 2.1.5

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,573 +1,126 @@
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 { cva } from 'class-variance-authority';
8
- import { jsx, jsxs, Fragment } 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';
10
+ import { cva } from 'class-variance-authority';
11
+ import { Slot } from '@radix-ui/react-slot';
11
12
 
12
13
  // components/blocks/about/about-culture-tabs.tsx
13
14
  function cn(...inputs) {
14
15
  return twMerge(clsx(inputs));
15
16
  }
16
- function getTextColor(parentBg, variant = "default", options) {
17
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
18
- if (isDark) {
19
- switch (variant) {
20
- case "default":
21
- return "text-foreground";
22
- case "muted":
23
- return "text-foreground/80";
24
- case "subtle":
25
- return "text-foreground/60";
26
- case "accent":
27
- return "text-accent-foreground";
28
- }
29
- } else {
30
- switch (variant) {
31
- case "default":
32
- return "text-foreground";
33
- case "muted":
34
- return "text-muted-foreground";
35
- case "subtle":
36
- return "text-muted-foreground/70";
37
- case "accent":
38
- return "text-primary";
39
- }
40
- }
41
- }
42
- function getAccentColor(parentBg, options) {
43
- const isDark = parentBg === "dark" || parentBg === "secondary" || parentBg === "primary";
44
- return isDark ? "text-accent-foreground" : "text-primary";
45
- }
46
- function normalizePhoneNumber(input) {
47
- const trimmed = input.trim();
48
- if (trimmed.toLowerCase().startsWith("tel:")) {
49
- return trimmed;
50
- }
51
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
52
- if (match) {
53
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
54
- const extension = match[3];
55
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
56
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
57
- return `tel:${withExtension}`;
58
- }
59
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
60
- return `tel:${cleaned}`;
61
- }
62
- function normalizeEmail(input) {
63
- const trimmed = input.trim();
64
- if (trimmed.toLowerCase().startsWith("mailto:")) {
65
- return trimmed;
66
- }
67
- return `mailto:${trimmed}`;
68
- }
69
- function isEmail(input) {
70
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
71
- return emailRegex.test(input.trim());
72
- }
73
- function isPhoneNumber(input) {
74
- const trimmed = input.trim();
75
- if (trimmed.toLowerCase().startsWith("tel:")) {
76
- return true;
77
- }
78
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
79
- return phoneRegex.test(trimmed);
80
- }
81
- function isInternalUrl(href) {
82
- if (typeof window === "undefined") {
83
- return href.startsWith("/") && !href.startsWith("//");
84
- }
85
- const trimmed = href.trim();
86
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
87
- return true;
88
- }
89
- try {
90
- const url = new URL(trimmed, window.location.href);
91
- const currentOrigin = window.location.origin;
92
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
93
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
94
- } catch {
95
- return false;
96
- }
17
+ var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
18
+ function DynamicIcon({ apiKey, ...props }) {
19
+ return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
97
20
  }
98
- function toRelativePath(href) {
99
- if (typeof window === "undefined") {
100
- return href;
101
- }
102
- const trimmed = href.trim();
103
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
104
- return trimmed;
105
- }
106
- try {
107
- const url = new URL(trimmed, window.location.href);
108
- const currentOrigin = window.location.origin;
109
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
110
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
111
- return url.pathname + url.search + url.hash;
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
112
31
  }
113
- } catch {
114
- }
115
- return trimmed;
32
+ );
116
33
  }
117
- function useNavigation({
118
- href,
119
- onClick
120
- } = {}) {
121
- const linkType = React.useMemo(() => {
122
- if (!href || href.trim() === "") {
123
- return onClick ? "none" : "none";
124
- }
125
- const trimmed = href.trim();
126
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
127
- return "mailto";
128
- }
129
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
130
- return "tel";
131
- }
132
- if (isInternalUrl(trimmed)) {
133
- return "internal";
134
- }
135
- try {
136
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
137
- return "external";
138
- } catch {
139
- return "internal";
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
140
47
  }
141
- }, [href, onClick]);
142
- const normalizedHref = React.useMemo(() => {
143
- if (!href || href.trim() === "") {
144
- return void 0;
48
+ );
49
+ }
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
145
63
  }
146
- const trimmed = href.trim();
147
- switch (linkType) {
148
- case "tel":
149
- return normalizePhoneNumber(trimmed);
150
- case "mailto":
151
- return normalizeEmail(trimmed);
152
- case "internal":
153
- return toRelativePath(trimmed);
154
- case "external":
155
- return trimmed;
156
- default:
157
- return trimmed;
64
+ );
65
+ }
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
158
76
  }
159
- }, [href, linkType]);
160
- const target = React.useMemo(() => {
161
- switch (linkType) {
162
- case "external":
163
- return "_blank";
164
- case "internal":
165
- return "_self";
166
- case "mailto":
167
- case "tel":
168
- return void 0;
169
- default:
170
- return void 0;
77
+ );
78
+ }
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
171
89
  }
172
- }, [linkType]);
173
- const rel = React.useMemo(() => {
174
- if (linkType === "external") {
175
- return "noopener noreferrer";
90
+ );
91
+ }
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
176
99
  }
177
- return void 0;
178
- }, [linkType]);
179
- const isExternal = linkType === "external";
180
- const isInternal = linkType === "internal";
181
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
182
- const handleClick = React.useCallback(
183
- (event) => {
184
- if (onClick) {
185
- try {
186
- onClick(event);
187
- } catch (error) {
188
- console.error("Error in user onClick handler:", error);
189
- }
190
- }
191
- if (event.defaultPrevented) {
192
- return;
193
- }
194
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
195
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
196
- if (typeof window !== "undefined") {
197
- const handler = window.__opensiteNavigationHandler;
198
- if (typeof handler === "function") {
199
- try {
200
- const handled = handler(normalizedHref, event.nativeEvent || event);
201
- if (handled !== false) {
202
- event.preventDefault();
203
- }
204
- } catch (error) {
205
- console.error("Error in navigation handler:", error);
206
- }
207
- }
208
- }
209
- }
210
- },
211
- [onClick, shouldUseRouter, normalizedHref]
212
100
  );
213
- return {
214
- linkType,
215
- normalizedHref,
216
- target,
217
- rel,
218
- isExternal,
219
- isInternal,
220
- shouldUseRouter,
221
- handleClick
222
- };
223
101
  }
224
- var baseStyles = [
225
- // Layout
226
- "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
227
- // Typography - using CSS variables with sensible defaults
228
- "font-[var(--button-font-family,inherit)]",
229
- "font-[var(--button-font-weight,500)]",
230
- "tracking-[var(--button-letter-spacing,0)]",
231
- "leading-[var(--button-line-height,1.25)]",
232
- "[text-transform:var(--button-text-transform,none)]",
233
- "text-sm",
234
- // Border radius
235
- "rounded-[var(--button-radius,var(--radius,0.375rem))]",
236
- // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
237
- "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
238
- // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
239
- "[box-shadow:var(--button-shadow,none)]",
240
- "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
241
- // Disabled state
242
- "disabled:pointer-events-none disabled:opacity-50",
243
- // SVG handling
244
- "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
245
- // Focus styles
246
- "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
247
- // Invalid state
248
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
249
- ].join(" ");
250
- var buttonVariants = cva(baseStyles, {
251
- variants: {
252
- variant: {
253
- // Default (Primary) variant - full customization
254
- default: [
255
- "bg-[var(--button-default-bg,hsl(var(--primary)))]",
256
- "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
257
- "border-[length:var(--button-default-border-width,0px)]",
258
- "border-[color:var(--button-default-border,transparent)]",
259
- "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
260
- "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
261
- "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
262
- "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
263
- "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
264
- ].join(" "),
265
- // Destructive variant - full customization
266
- destructive: [
267
- "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
268
- "text-[var(--button-destructive-fg,white)]",
269
- "border-[length:var(--button-destructive-border-width,0px)]",
270
- "border-[color:var(--button-destructive-border,transparent)]",
271
- "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
272
- "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
273
- "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
274
- "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
275
- "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
276
- "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
277
- "dark:bg-destructive/60"
278
- ].join(" "),
279
- // Outline variant - full customization with proper border handling
280
- outline: [
281
- "bg-[var(--button-outline-bg,hsl(var(--background)))]",
282
- "text-[var(--button-outline-fg,inherit)]",
283
- "border-[length:var(--button-outline-border-width,1px)]",
284
- "border-[color:var(--button-outline-border,hsl(var(--border)))]",
285
- "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
286
- "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
287
- "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
288
- "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
289
- "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
290
- "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
291
- ].join(" "),
292
- // Secondary variant - full customization
293
- secondary: [
294
- "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
295
- "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
296
- "border-[length:var(--button-secondary-border-width,0px)]",
297
- "border-[color:var(--button-secondary-border,transparent)]",
298
- "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
299
- "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
300
- "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
301
- "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
302
- "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
303
- ].join(" "),
304
- // Ghost variant - full customization
305
- ghost: [
306
- "bg-[var(--button-ghost-bg,transparent)]",
307
- "text-[var(--button-ghost-fg,inherit)]",
308
- "border-[length:var(--button-ghost-border-width,0px)]",
309
- "border-[color:var(--button-ghost-border,transparent)]",
310
- "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
311
- "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
312
- "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
313
- "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
314
- "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
315
- "dark:hover:bg-accent/50"
316
- ].join(" "),
317
- // Link variant - full customization
318
- link: [
319
- "bg-[var(--button-link-bg,transparent)]",
320
- "text-[var(--button-link-fg,hsl(var(--primary)))]",
321
- "border-[length:var(--button-link-border-width,0px)]",
322
- "border-[color:var(--button-link-border,transparent)]",
323
- "[box-shadow:var(--button-link-shadow,none)]",
324
- "hover:bg-[var(--button-link-hover-bg,transparent)]",
325
- "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
326
- "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
327
- "underline-offset-4 hover:underline"
328
- ].join(" ")
329
- },
330
- size: {
331
- default: [
332
- "h-[var(--button-height-md,2.25rem)]",
333
- "px-[var(--button-padding-x-md,1rem)]",
334
- "py-[var(--button-padding-y-md,0.5rem)]",
335
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
336
- ].join(" "),
337
- sm: [
338
- "h-[var(--button-height-sm,2rem)]",
339
- "px-[var(--button-padding-x-sm,0.75rem)]",
340
- "py-[var(--button-padding-y-sm,0.25rem)]",
341
- "gap-1.5",
342
- "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
343
- ].join(" "),
344
- md: [
345
- "h-[var(--button-height-md,2.25rem)]",
346
- "px-[var(--button-padding-x-md,1rem)]",
347
- "py-[var(--button-padding-y-md,0.5rem)]",
348
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
349
- ].join(" "),
350
- lg: [
351
- "h-[var(--button-height-lg,2.5rem)]",
352
- "px-[var(--button-padding-x-lg,1.5rem)]",
353
- "py-[var(--button-padding-y-lg,0.5rem)]",
354
- "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
355
- ].join(" "),
356
- icon: "size-[var(--button-height-md,2.25rem)]",
357
- "icon-sm": "size-[var(--button-height-sm,2rem)]",
358
- "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
359
- }
360
- },
361
- defaultVariants: {
362
- variant: "default",
363
- size: "default"
364
- }
365
- });
366
- var Pressable = React.forwardRef(
367
- ({
368
- children,
369
- className,
370
- href,
371
- onClick,
372
- variant,
373
- size,
374
- asButton = false,
375
- fallbackComponentType = "span",
376
- componentType,
377
- "aria-label": ariaLabel,
378
- "aria-describedby": ariaDescribedby,
379
- id,
380
- ...props
381
- }, ref) => {
382
- const navigation = useNavigation({ href, onClick });
383
- const {
384
- normalizedHref,
385
- target,
386
- rel,
387
- linkType,
388
- isInternal,
389
- handleClick
390
- } = navigation;
391
- const shouldRenderLink = normalizedHref && linkType !== "none";
392
- const shouldRenderButton = !shouldRenderLink && onClick;
393
- const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
394
- const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
395
- const shouldApplyButtonStyles = asButton || variant || size;
396
- const combinedClassName = cn(
397
- shouldApplyButtonStyles && buttonVariants({ variant, size }),
398
- className
399
- );
400
- const dataProps = Object.fromEntries(
401
- Object.entries(props).filter(([key]) => key.startsWith("data-"))
402
- );
403
- const buttonDataAttributes = shouldApplyButtonStyles ? {
404
- "data-slot": "button",
405
- "data-variant": variant ?? "default",
406
- "data-size": size ?? "default"
407
- } : {};
408
- const commonProps = {
409
- className: combinedClassName,
410
- onClick: handleClick,
411
- "aria-label": ariaLabel,
412
- "aria-describedby": ariaDescribedby,
413
- id,
414
- ...dataProps,
415
- ...buttonDataAttributes
416
- };
417
- if (finalComponentType === "a" && shouldRenderLink) {
418
- return /* @__PURE__ */ jsx(
419
- "a",
420
- {
421
- ref,
422
- href: normalizedHref,
423
- target,
424
- rel,
425
- ...commonProps,
426
- ...props,
427
- children
428
- }
429
- );
430
- }
431
- if (finalComponentType === "button") {
432
- return /* @__PURE__ */ jsx(
433
- "button",
434
- {
435
- ref,
436
- type: props.type || "button",
437
- ...commonProps,
438
- ...props,
439
- children
440
- }
441
- );
442
- }
443
- if (finalComponentType === "div") {
444
- return /* @__PURE__ */ jsx(
445
- "div",
446
- {
447
- ref,
448
- ...commonProps,
449
- children
450
- }
451
- );
452
- }
102
+ var maxWidthStyles = {
103
+ sm: "max-w-screen-sm",
104
+ md: "max-w-screen-md",
105
+ lg: "max-w-screen-lg",
106
+ xl: "max-w-7xl",
107
+ "2xl": "max-w-screen-2xl",
108
+ "4xl": "max-w-[1536px]",
109
+ full: "max-w-full"
110
+ };
111
+ var Container = React3__default.forwardRef(
112
+ ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
113
+ const Component = as;
453
114
  return /* @__PURE__ */ jsx(
454
- "span",
115
+ Component,
455
116
  {
456
117
  ref,
457
- ...commonProps,
458
- children
459
- }
460
- );
461
- }
462
- );
463
- Pressable.displayName = "Pressable";
464
- var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
465
- function DynamicIcon({ apiKey, ...props }) {
466
- return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
467
- }
468
- function Tabs({
469
- className,
470
- ...props
471
- }) {
472
- return /* @__PURE__ */ jsx(
473
- TabsPrimitive.Root,
474
- {
475
- "data-slot": "tabs",
476
- className: cn("flex flex-col gap-2", className),
477
- ...props
478
- }
479
- );
480
- }
481
- function TabsList({
482
- className,
483
- ...props
484
- }) {
485
- return /* @__PURE__ */ jsx(
486
- TabsPrimitive.List,
487
- {
488
- "data-slot": "tabs-list",
489
- className: cn(
490
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
491
- className
492
- ),
493
- ...props
494
- }
495
- );
496
- }
497
- function TabsTrigger({
498
- className,
499
- ...props
500
- }) {
501
- return /* @__PURE__ */ jsx(
502
- TabsPrimitive.Trigger,
503
- {
504
- "data-slot": "tabs-trigger",
505
- className: cn(
506
- "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",
507
- className
508
- ),
509
- ...props
510
- }
511
- );
512
- }
513
- function TabsContent({
514
- className,
515
- ...props
516
- }) {
517
- return /* @__PURE__ */ jsx(
518
- TabsPrimitive.Content,
519
- {
520
- "data-slot": "tabs-content",
521
- className: cn("flex-1 outline-none", className),
522
- ...props
523
- }
524
- );
525
- }
526
- function Card({ className, ...props }) {
527
- return /* @__PURE__ */ jsx(
528
- "div",
529
- {
530
- "data-slot": "card",
531
- className: cn(
532
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
533
- className
534
- ),
535
- ...props
536
- }
537
- );
538
- }
539
- function CardContent({ className, ...props }) {
540
- return /* @__PURE__ */ jsx(
541
- "div",
542
- {
543
- "data-slot": "card-content",
544
- className: cn("px-6", className),
545
- ...props
546
- }
547
- );
548
- }
549
- var maxWidthStyles = {
550
- sm: "max-w-screen-sm",
551
- md: "max-w-screen-md",
552
- lg: "max-w-screen-lg",
553
- xl: "max-w-7xl",
554
- "2xl": "max-w-screen-2xl",
555
- "4xl": "max-w-[1536px]",
556
- full: "max-w-full"
557
- };
558
- var Container = React__default.forwardRef(
559
- ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
560
- const Component = as;
561
- return /* @__PURE__ */ jsx(
562
- Component,
563
- {
564
- ref,
565
- className: cn(
566
- "mx-auto w-full px-2 sm:px-4 lg:px-8",
567
- maxWidthStyles[maxWidth],
568
- className
569
- ),
570
- ...props,
118
+ className: cn(
119
+ "mx-auto w-full px-2 sm:px-4 lg:px-8",
120
+ maxWidthStyles[maxWidth],
121
+ className
122
+ ),
123
+ ...props,
571
124
  children
572
125
  }
573
126
  );
@@ -718,209 +271,723 @@ var dashedGridPattern = (fadeMask) => {
718
271
  WebkitMaskComposite: "source-in"
719
272
  }
720
273
  }
721
- );
722
- };
723
- var gradientGlow = (position) => /* @__PURE__ */ jsx(
724
- "div",
725
- {
726
- className: cn(
727
- "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
728
- position === "top" ? "-top-1/4" : "-bottom-1/4"
729
- ),
730
- style: {
731
- background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
274
+ );
275
+ };
276
+ var gradientGlow = (position) => /* @__PURE__ */ jsx(
277
+ "div",
278
+ {
279
+ className: cn(
280
+ "pointer-events-none absolute left-1/2 z-0 aspect-square w-3/4 -translate-x-1/2 rounded-full opacity-50 blur-3xl",
281
+ position === "top" ? "-top-1/4" : "-bottom-1/4"
282
+ ),
283
+ style: {
284
+ background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
285
+ }
286
+ }
287
+ );
288
+ var spotlight = (position) => /* @__PURE__ */ jsx(
289
+ "div",
290
+ {
291
+ className: cn(
292
+ "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
293
+ position === "left" ? "-left-1/4" : "-right-1/4"
294
+ ),
295
+ style: {
296
+ background: "radial-gradient(circle, hsl(var(--primary)) 0%, transparent 70%)"
297
+ }
298
+ }
299
+ );
300
+ var patternOverlays = {
301
+ circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
302
+ circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
303
+ circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
304
+ circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
305
+ circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
306
+ circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
307
+ circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
308
+ circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
309
+ dashedGridBasic: () => dashedGridPattern(),
310
+ dashedGridFadeTop: () => dashedGridPattern(maskTop),
311
+ dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
312
+ dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
313
+ dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
314
+ dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
315
+ dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
316
+ dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
317
+ diagonalCrossBasic: () => diagonalCrossPattern(),
318
+ diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
319
+ diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
320
+ diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
321
+ diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
322
+ diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
323
+ diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
324
+ diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
325
+ gridBasic: () => gridPattern(40),
326
+ gridFadeTop: () => gridPattern(32, maskTop),
327
+ gridFadeBottom: () => gridPattern(32, maskBottom),
328
+ gridFadeCenter: () => gridPattern(40, maskCenter),
329
+ gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
330
+ gridFadeTopRight: () => gridPattern(32, maskTopRight),
331
+ gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
332
+ gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
333
+ gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
334
+ gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
335
+ gradientGlowTop: () => gradientGlow("top"),
336
+ gradientGlowBottom: () => gradientGlow("bottom"),
337
+ spotlightLeft: () => spotlight("left"),
338
+ spotlightRight: () => spotlight("right")
339
+ };
340
+ var inlinePatternStyles = {
341
+ radialGradientTop: {
342
+ background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
343
+ },
344
+ radialGradientBottom: {
345
+ background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
346
+ }
347
+ };
348
+ function PatternBackground({
349
+ pattern,
350
+ opacity = 0.08,
351
+ className,
352
+ style
353
+ }) {
354
+ if (!pattern) {
355
+ return null;
356
+ }
357
+ if (pattern in inlinePatternStyles) {
358
+ const inlineStyle = inlinePatternStyles[pattern];
359
+ return /* @__PURE__ */ jsx(
360
+ "div",
361
+ {
362
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
363
+ style: { ...inlineStyle, opacity, ...style },
364
+ "aria-hidden": "true"
365
+ }
366
+ );
367
+ }
368
+ if (pattern in patternOverlays) {
369
+ const Overlay = patternOverlays[pattern];
370
+ return /* @__PURE__ */ jsx(
371
+ "div",
372
+ {
373
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
374
+ style: { opacity, ...style },
375
+ "aria-hidden": "true",
376
+ children: Overlay()
377
+ }
378
+ );
379
+ }
380
+ const patternUrl = pattern in patternSvgs ? patternSvgs[pattern] : pattern;
381
+ return /* @__PURE__ */ jsx(
382
+ "div",
383
+ {
384
+ className: cn("pointer-events-none absolute inset-0 z-0", className),
385
+ style: {
386
+ backgroundImage: `url(${patternUrl})`,
387
+ backgroundRepeat: "repeat",
388
+ backgroundSize: "auto",
389
+ opacity,
390
+ ...style
391
+ },
392
+ "aria-hidden": "true"
393
+ }
394
+ );
395
+ }
396
+ var backgroundStyles = {
397
+ default: "bg-background text-foreground",
398
+ white: "bg-white text-dark",
399
+ gray: "bg-muted/30 text-foreground",
400
+ dark: "bg-foreground text-background",
401
+ transparent: "bg-transparent text-foreground",
402
+ gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
403
+ primary: "bg-primary text-primary-foreground",
404
+ secondary: "bg-secondary text-secondary-foreground",
405
+ muted: "bg-muted text-muted-foreground"
406
+ };
407
+ var spacingStyles = {
408
+ none: "py-0 md:py-0",
409
+ sm: "py-12 md:py-16",
410
+ md: "py-16 md:py-24",
411
+ lg: "py-20 md:py-32",
412
+ xl: "py-24 md:py-40"
413
+ };
414
+ var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
415
+ var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
416
+ var Section = React3__default.forwardRef(
417
+ ({
418
+ id,
419
+ title,
420
+ subtitle,
421
+ children,
422
+ className,
423
+ style,
424
+ background = "default",
425
+ spacing = "lg",
426
+ pattern,
427
+ patternOpacity,
428
+ patternClassName,
429
+ containerClassName,
430
+ containerMaxWidth = "xl",
431
+ ...props
432
+ }, ref) => {
433
+ const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
434
+ return /* @__PURE__ */ jsxs(
435
+ "section",
436
+ {
437
+ ref,
438
+ id,
439
+ className: cn(
440
+ "relative",
441
+ pattern ? "overflow-hidden" : null,
442
+ backgroundStyles[background],
443
+ isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
444
+ className
445
+ ),
446
+ style,
447
+ ...props,
448
+ children: [
449
+ /* @__PURE__ */ jsx(
450
+ PatternBackground,
451
+ {
452
+ pattern,
453
+ opacity: effectivePatternOpacity,
454
+ className: patternClassName
455
+ }
456
+ ),
457
+ /* @__PURE__ */ jsxs(
458
+ Container,
459
+ {
460
+ maxWidth: containerMaxWidth,
461
+ className: cn("relative z-10", containerClassName),
462
+ children: [
463
+ (title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
464
+ subtitle && /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
465
+ title && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
466
+ ] }),
467
+ children
468
+ ]
469
+ }
470
+ )
471
+ ]
472
+ }
473
+ );
474
+ }
475
+ );
476
+ Section.displayName = "Section";
477
+ var baseStyles = [
478
+ // Layout
479
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
480
+ // Typography - using CSS variables with sensible defaults
481
+ "font-[var(--button-font-family,inherit)]",
482
+ "font-[var(--button-font-weight,500)]",
483
+ "tracking-[var(--button-letter-spacing,0)]",
484
+ "leading-[var(--button-line-height,1.25)]",
485
+ "[text-transform:var(--button-text-transform,none)]",
486
+ "text-sm",
487
+ // Border radius
488
+ "rounded-[var(--button-radius,var(--radius,0.375rem))]",
489
+ // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
490
+ "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
491
+ // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
492
+ "[box-shadow:var(--button-shadow,none)]",
493
+ "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
494
+ // Disabled state
495
+ "disabled:pointer-events-none disabled:opacity-50",
496
+ // SVG handling
497
+ "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
498
+ // Focus styles
499
+ "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
500
+ // Invalid state
501
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
502
+ ].join(" ");
503
+ var buttonVariants = cva(baseStyles, {
504
+ variants: {
505
+ variant: {
506
+ // Default (Primary) variant - full customization
507
+ default: [
508
+ "bg-[var(--button-default-bg,hsl(var(--primary)))]",
509
+ "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
510
+ "border-[length:var(--button-default-border-width,0px)]",
511
+ "border-[color:var(--button-default-border,transparent)]",
512
+ "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
513
+ "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
514
+ "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
515
+ "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
516
+ "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
517
+ ].join(" "),
518
+ // Destructive variant - full customization
519
+ destructive: [
520
+ "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
521
+ "text-[var(--button-destructive-fg,white)]",
522
+ "border-[length:var(--button-destructive-border-width,0px)]",
523
+ "border-[color:var(--button-destructive-border,transparent)]",
524
+ "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
525
+ "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
526
+ "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
527
+ "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
528
+ "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
529
+ "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
530
+ "dark:bg-destructive/60"
531
+ ].join(" "),
532
+ // Outline variant - full customization with proper border handling
533
+ outline: [
534
+ "bg-[var(--button-outline-bg,hsl(var(--background)))]",
535
+ "text-[var(--button-outline-fg,inherit)]",
536
+ "border-[length:var(--button-outline-border-width,1px)]",
537
+ "border-[color:var(--button-outline-border,hsl(var(--border)))]",
538
+ "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
539
+ "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
540
+ "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
541
+ "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
542
+ "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
543
+ "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
544
+ ].join(" "),
545
+ // Secondary variant - full customization
546
+ secondary: [
547
+ "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
548
+ "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
549
+ "border-[length:var(--button-secondary-border-width,0px)]",
550
+ "border-[color:var(--button-secondary-border,transparent)]",
551
+ "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
552
+ "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
553
+ "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
554
+ "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
555
+ "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
556
+ ].join(" "),
557
+ // Ghost variant - full customization
558
+ ghost: [
559
+ "bg-[var(--button-ghost-bg,transparent)]",
560
+ "text-[var(--button-ghost-fg,inherit)]",
561
+ "border-[length:var(--button-ghost-border-width,0px)]",
562
+ "border-[color:var(--button-ghost-border,transparent)]",
563
+ "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
564
+ "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
565
+ "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
566
+ "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
567
+ "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
568
+ "dark:hover:bg-accent/50"
569
+ ].join(" "),
570
+ // Link variant - full customization
571
+ link: [
572
+ "bg-[var(--button-link-bg,transparent)]",
573
+ "text-[var(--button-link-fg,hsl(var(--primary)))]",
574
+ "border-[length:var(--button-link-border-width,0px)]",
575
+ "border-[color:var(--button-link-border,transparent)]",
576
+ "[box-shadow:var(--button-link-shadow,none)]",
577
+ "hover:bg-[var(--button-link-hover-bg,transparent)]",
578
+ "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
579
+ "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
580
+ "underline-offset-4 hover:underline"
581
+ ].join(" ")
582
+ },
583
+ size: {
584
+ default: [
585
+ "h-[var(--button-height-md,2.25rem)]",
586
+ "px-[var(--button-padding-x-md,1rem)]",
587
+ "py-[var(--button-padding-y-md,0.5rem)]",
588
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
589
+ ].join(" "),
590
+ sm: [
591
+ "h-[var(--button-height-sm,2rem)]",
592
+ "px-[var(--button-padding-x-sm,0.75rem)]",
593
+ "py-[var(--button-padding-y-sm,0.25rem)]",
594
+ "gap-1.5",
595
+ "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
596
+ ].join(" "),
597
+ md: [
598
+ "h-[var(--button-height-md,2.25rem)]",
599
+ "px-[var(--button-padding-x-md,1rem)]",
600
+ "py-[var(--button-padding-y-md,0.5rem)]",
601
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
602
+ ].join(" "),
603
+ lg: [
604
+ "h-[var(--button-height-lg,2.5rem)]",
605
+ "px-[var(--button-padding-x-lg,1.5rem)]",
606
+ "py-[var(--button-padding-y-lg,0.5rem)]",
607
+ "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
608
+ ].join(" "),
609
+ icon: "size-[var(--button-height-md,2.25rem)]",
610
+ "icon-sm": "size-[var(--button-height-sm,2rem)]",
611
+ "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
612
+ }
613
+ },
614
+ defaultVariants: {
615
+ variant: "default",
616
+ size: "default"
617
+ }
618
+ });
619
+ var badgeVariants = cva(
620
+ "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",
621
+ {
622
+ variants: {
623
+ variant: {
624
+ default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
625
+ secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
626
+ 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",
627
+ outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
628
+ }
629
+ },
630
+ defaultVariants: {
631
+ variant: "default"
632
+ }
633
+ }
634
+ );
635
+ function Badge({
636
+ className,
637
+ variant,
638
+ asChild = false,
639
+ ...props
640
+ }) {
641
+ const Comp = asChild ? Slot : "span";
642
+ return /* @__PURE__ */ jsx(
643
+ Comp,
644
+ {
645
+ "data-slot": "badge",
646
+ className: cn(badgeVariants({ variant }), className),
647
+ ...props
648
+ }
649
+ );
650
+ }
651
+ function normalizePhoneNumber(input) {
652
+ const trimmed = input.trim();
653
+ if (trimmed.toLowerCase().startsWith("tel:")) {
654
+ return trimmed;
655
+ }
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}`;
666
+ }
667
+ function normalizeEmail(input) {
668
+ const trimmed = input.trim();
669
+ if (trimmed.toLowerCase().startsWith("mailto:")) {
670
+ return trimmed;
671
+ }
672
+ return `mailto:${trimmed}`;
673
+ }
674
+ function isEmail(input) {
675
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
676
+ return emailRegex.test(input.trim());
677
+ }
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);
685
+ }
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
+ }
702
+ }
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;
717
+ }
718
+ } catch {
719
+ }
720
+ return trimmed;
721
+ }
722
+ function useNavigation({
723
+ href,
724
+ onClick
725
+ } = {}) {
726
+ const linkType = React3.useMemo(() => {
727
+ if (!href || href.trim() === "") {
728
+ return onClick ? "none" : "none";
729
+ }
730
+ const trimmed = href.trim();
731
+ if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
732
+ return "mailto";
733
+ }
734
+ if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
735
+ return "tel";
736
+ }
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
+ }
795
+ }
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();
808
+ }
809
+ } catch (error) {
810
+ console.error("Error in navigation handler:", error);
811
+ }
812
+ }
813
+ }
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",
883
+ {
884
+ ref,
885
+ href: normalizedHref,
886
+ target,
887
+ rel,
888
+ ...commonProps,
889
+ ...props,
890
+ children
891
+ }
892
+ );
893
+ }
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
+ );
732
905
  }
733
- }
734
- );
735
- var spotlight = (position) => /* @__PURE__ */ jsx(
736
- "div",
737
- {
738
- className: cn(
739
- "pointer-events-none absolute top-1/2 z-0 aspect-square w-3/4 -translate-y-1/2 rounded-full opacity-40 blur-3xl",
740
- position === "left" ? "-left-1/4" : "-right-1/4"
741
- ),
742
- style: {
743
- 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
+ );
744
915
  }
745
- }
746
- );
747
- var patternOverlays = {
748
- circuitBoardBasic: () => circuitBoardPattern("circuit-board-basic"),
749
- circuitBoardFadeTop: () => circuitBoardPattern("circuit-board-fade-top", maskTop),
750
- circuitBoardFadeBottom: () => circuitBoardPattern("circuit-board-fade-bottom", maskBottom),
751
- circuitBoardFadeCenter: () => circuitBoardPattern("circuit-board-fade-center", maskCenter),
752
- circuitBoardFadeTopLeft: () => circuitBoardPattern("circuit-board-fade-top-left", maskTopLeft),
753
- circuitBoardFadeTopRight: () => circuitBoardPattern("circuit-board-fade-top-right", maskTopRight),
754
- circuitBoardFadeBottomLeft: () => circuitBoardPattern("circuit-board-fade-bottom-left", maskBottomLeft),
755
- circuitBoardFadeBottomRight: () => circuitBoardPattern("circuit-board-fade-bottom-right", maskBottomRight),
756
- dashedGridBasic: () => dashedGridPattern(),
757
- dashedGridFadeTop: () => dashedGridPattern(maskTop),
758
- dashedGridFadeBottom: () => dashedGridPattern(maskBottom),
759
- dashedGridFadeCenter: () => dashedGridPattern(maskCenter),
760
- dashedGridFadeTopLeft: () => dashedGridPattern(maskTopLeft),
761
- dashedGridFadeTopRight: () => dashedGridPattern(maskTopRight),
762
- dashedGridFadeBottomLeft: () => dashedGridPattern(maskBottomLeft),
763
- dashedGridFadeBottomRight: () => dashedGridPattern(maskBottomRight),
764
- diagonalCrossBasic: () => diagonalCrossPattern(),
765
- diagonalCrossFadeTop: () => diagonalCrossPattern(maskTop),
766
- diagonalCrossFadeBottom: () => diagonalCrossPattern(maskBottom),
767
- diagonalCrossFadeCenter: () => diagonalCrossPattern(maskCenter),
768
- diagonalCrossFadeTopLeft: () => diagonalCrossPattern(maskTopLeft),
769
- diagonalCrossFadeTopRight: () => diagonalCrossPattern(maskTopRight),
770
- diagonalCrossFadeBottomLeft: () => diagonalCrossPattern(maskBottomLeft),
771
- diagonalCrossFadeBottomRight: () => diagonalCrossPattern(maskBottomRight),
772
- gridBasic: () => gridPattern(40),
773
- gridFadeTop: () => gridPattern(32, maskTop),
774
- gridFadeBottom: () => gridPattern(32, maskBottom),
775
- gridFadeCenter: () => gridPattern(40, maskCenter),
776
- gridFadeTopLeft: () => gridPattern(32, maskTopLeft),
777
- gridFadeTopRight: () => gridPattern(32, maskTopRight),
778
- gridFadeBottomLeft: () => gridPattern(32, maskBottomLeft),
779
- gridFadeBottomRight: () => gridPattern(32, maskBottomRight),
780
- gridDotsBasic: () => gridDotsPattern("grid-dots-basic"),
781
- gridDotsFadeCenter: () => gridDotsPattern("grid-dots-fade-center", maskCenter),
782
- gradientGlowTop: () => gradientGlow("top"),
783
- gradientGlowBottom: () => gradientGlow("bottom"),
784
- spotlightLeft: () => spotlight("left"),
785
- spotlightRight: () => spotlight("right")
786
- };
787
- var inlinePatternStyles = {
788
- radialGradientTop: {
789
- background: "radial-gradient(125% 125% at 50% 10%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
790
- },
791
- radialGradientBottom: {
792
- background: "radial-gradient(125% 125% at 50% 90%, hsl(var(--background)) 40%, hsl(var(--primary)) 100%)"
793
- }
794
- };
795
- function PatternBackground({
796
- pattern,
797
- opacity = 0.08,
798
- className,
799
- style
800
- }) {
801
- if (!pattern) {
802
- return null;
803
- }
804
- if (pattern in inlinePatternStyles) {
805
- const inlineStyle = inlinePatternStyles[pattern];
806
916
  return /* @__PURE__ */ jsx(
807
- "div",
917
+ "span",
808
918
  {
809
- className: cn("pointer-events-none absolute inset-0 z-0", className),
810
- style: { ...inlineStyle, opacity, ...style },
811
- "aria-hidden": "true"
919
+ ref,
920
+ ...commonProps,
921
+ children
812
922
  }
813
923
  );
814
924
  }
815
- if (pattern in patternOverlays) {
816
- 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) {
817
948
  return /* @__PURE__ */ jsx(
818
949
  "div",
819
950
  {
820
- className: cn("pointer-events-none absolute inset-0 z-0", className),
821
- style: { opacity, ...style },
822
- "aria-hidden": "true",
823
- 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))
824
958
  }
825
959
  );
960
+ } else {
961
+ return null;
826
962
  }
827
- 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;
828
975
  return /* @__PURE__ */ jsx(
829
- "div",
976
+ Pressable,
830
977
  {
831
- className: cn("pointer-events-none absolute inset-0 z-0", className),
832
- style: {
833
- backgroundImage: `url(${patternUrl})`,
834
- backgroundRepeat: "repeat",
835
- backgroundSize: "auto",
836
- opacity,
837
- ...style
838
- },
839
- "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
+ ] })
840
988
  }
841
989
  );
842
990
  }
843
- var backgroundStyles = {
844
- default: "bg-background text-foreground",
845
- white: "bg-white text-dark",
846
- gray: "bg-muted/30 text-foreground",
847
- dark: "bg-foreground text-background",
848
- transparent: "bg-transparent text-foreground",
849
- gradient: "bg-linear-to-br from-primary via-primary/90 to-foreground text-primary-foreground",
850
- primary: "bg-primary text-primary-foreground",
851
- secondary: "bg-secondary text-secondary-foreground",
852
- muted: "bg-muted text-muted-foreground"
853
- };
854
- var spacingStyles = {
855
- none: "py-0 md:py-0",
856
- sm: "py-12 md:py-16",
857
- md: "py-16 md:py-24",
858
- lg: "py-20 md:py-32",
859
- xl: "py-24 md:py-40"
860
- };
861
- var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
862
- var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
863
- var Section = React__default.forwardRef(
864
- ({
865
- id,
866
- title,
867
- subtitle,
868
- children,
869
- className,
870
- style,
871
- background = "default",
872
- spacing = "lg",
873
- pattern,
874
- patternOpacity,
875
- patternClassName,
876
- containerClassName,
877
- containerMaxWidth = "xl",
878
- ...props
879
- }, ref) => {
880
- const effectivePatternOpacity = patternOpacity !== void 0 ? patternOpacity : pattern ? 1 : 0;
881
- return /* @__PURE__ */ jsxs(
882
- "section",
883
- {
884
- ref,
885
- id,
886
- className: cn(
887
- "relative",
888
- pattern ? "overflow-hidden" : null,
889
- backgroundStyles[background],
890
- isPredefinedSpacing(spacing) ? spacingStyles[spacing] : spacing,
891
- className
892
- ),
893
- style,
894
- ...props,
895
- children: [
896
- /* @__PURE__ */ jsx(
897
- PatternBackground,
898
- {
899
- pattern,
900
- opacity: effectivePatternOpacity,
901
- className: patternClassName
902
- }
903
- ),
904
- /* @__PURE__ */ jsxs(
905
- Container,
906
- {
907
- maxWidth: containerMaxWidth,
908
- className: cn("relative z-10", containerClassName),
909
- children: [
910
- (title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center md:mb-16", children: [
911
- subtitle && /* @__PURE__ */ jsx("p", { className: "mb-2 text-sm font-semibold uppercase tracking-wider", children: subtitle }),
912
- title && /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl", children: title })
913
- ] }),
914
- children
915
- ]
916
- }
917
- )
918
- ]
919
- }
920
- );
921
- }
922
- );
923
- Section.displayName = "Section";
924
991
  function AboutCultureTabs({
925
992
  badgeText,
926
993
  heading,
@@ -934,7 +1001,7 @@ function AboutCultureTabs({
934
1001
  ctaImages,
935
1002
  ctaImagesSlot,
936
1003
  className,
937
- containerClassName,
1004
+ containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
938
1005
  headerClassName,
939
1006
  badgeClassName,
940
1007
  headingClassName,
@@ -946,45 +1013,33 @@ function AboutCultureTabs({
946
1013
  actionsClassName,
947
1014
  optixFlowConfig,
948
1015
  background,
949
- spacing,
1016
+ spacing = "xl",
950
1017
  pattern,
951
1018
  patternOpacity
952
1019
  }) {
953
1020
  const resolvedAspects = aspects ?? [];
954
- const [activeTab, setActiveTab] = React.useState(resolvedAspects[0]?.id || "");
955
- const actionsContent = useMemo(() => {
956
- if (actionsSlot) return actionsSlot;
957
- if (!actions || actions.length === 0) return null;
958
- return actions.map((action, index) => {
959
- const { label, icon, iconAfter, children, className: actionClassName, ...pressableProps } = action;
960
- return /* @__PURE__ */ jsx(
961
- Pressable,
962
- {
963
- asButton: true,
964
- className: actionClassName,
965
- ...pressableProps,
966
- children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
967
- icon,
968
- label,
969
- iconAfter
970
- ] })
971
- },
972
- index
973
- );
974
- });
975
- }, [actionsSlot, actions]);
1021
+ const [activeTab, setActiveTab] = React3.useState(
1022
+ resolvedAspects[0]?.id || ""
1023
+ );
976
1024
  const ctaImagesContent = useMemo(() => {
977
1025
  if (ctaImagesSlot) return ctaImagesSlot;
978
1026
  if (!ctaImages || ctaImages.length === 0) return null;
979
- return ctaImages.map((src, i) => /* @__PURE__ */ jsx("div", { className: "relative aspect-square overflow-hidden rounded-md", children: /* @__PURE__ */ jsx(
980
- Img,
1027
+ return ctaImages.map((src, i) => /* @__PURE__ */ jsx(
1028
+ "div",
981
1029
  {
982
- src,
983
- alt: "Team culture",
984
- className: "h-full w-full object-cover",
985
- optixFlowConfig
986
- }
987
- ) }, i));
1030
+ className: "relative aspect-square overflow-hidden rounded-md",
1031
+ children: /* @__PURE__ */ jsx(
1032
+ Img,
1033
+ {
1034
+ src,
1035
+ alt: "Team culture",
1036
+ className: "h-full w-full object-cover",
1037
+ optixFlowConfig
1038
+ }
1039
+ )
1040
+ },
1041
+ i
1042
+ ));
988
1043
  }, [ctaImagesSlot, ctaImages, optixFlowConfig]);
989
1044
  return /* @__PURE__ */ jsxs(
990
1045
  Section,
@@ -993,14 +1048,32 @@ function AboutCultureTabs({
993
1048
  spacing,
994
1049
  pattern,
995
1050
  patternOpacity,
996
- className: cn(className),
1051
+ className,
997
1052
  containerClassName,
998
1053
  children: [
999
- /* @__PURE__ */ jsxs("div", { className: cn("mx-auto mb-12 max-w-3xl space-y-4 text-center", headerClassName), children: [
1000
- badgeText && (typeof badgeText === "string" ? /* @__PURE__ */ jsx("div", { className: cn("inline-block rounded-lg bg-primary/10 px-3 py-1 text-sm", getAccentColor(background), badgeClassName), children: badgeText }) : /* @__PURE__ */ jsx("div", { className: badgeClassName, children: badgeText })),
1001
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-3xl font-bold tracking-tight md:text-4xl", headingClassName), children: heading }) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
1002
- description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn(getTextColor(background, "muted"), descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
1003
- ] }),
1054
+ /* @__PURE__ */ jsxs(
1055
+ "div",
1056
+ {
1057
+ className: cn(
1058
+ "mx-auto mb-12 max-w-full md:max-w-md space-y-4 text-center flex flex-col items-center justify-center",
1059
+ headerClassName
1060
+ ),
1061
+ children: [
1062
+ badgeText && (typeof badgeText === "string" ? /* @__PURE__ */ jsx(Badge, { className: cn("px-3 py-1", badgeClassName), children: badgeText }) : badgeText),
1063
+ heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
1064
+ "h2",
1065
+ {
1066
+ className: cn(
1067
+ "text-3xl font-bold tracking-tight md:text-4xl text-pretty",
1068
+ headingClassName
1069
+ ),
1070
+ children: heading
1071
+ }
1072
+ ) : heading),
1073
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-balance", descriptionClassName), children: description }) : description)
1074
+ ]
1075
+ }
1076
+ ),
1004
1077
  aspectsSlot ? aspectsSlot : resolvedAspects.length > 0 ? /* @__PURE__ */ jsxs(
1005
1078
  Tabs,
1006
1079
  {
@@ -1013,80 +1086,103 @@ function AboutCultureTabs({
1013
1086
  TabsTrigger,
1014
1087
  {
1015
1088
  value: aspect.id,
1016
- className: cn("px-3 py-2.5", `data-[state=active]:${getAccentColor(background)}`, "data-[state=active]:text-primary-foreground"),
1089
+ className: cn("px-3 py-2.5"),
1017
1090
  children: aspect.title
1018
1091
  },
1019
1092
  aspect.id
1020
1093
  )) }) }),
1021
- resolvedAspects.map((aspect) => /* @__PURE__ */ jsxs(TabsContent, { value: aspect.id, className: "space-y-8", children: [
1022
- /* @__PURE__ */ jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
1023
- /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1024
- /* @__PURE__ */ jsx("h3", { className: "text-2xl font-bold tracking-tight", children: aspect.title }),
1025
- /* @__PURE__ */ jsx("p", { className: cn("leading-relaxed", getTextColor(background, "muted")), children: aspect.description })
1026
- ] }),
1027
- /* @__PURE__ */ jsx(Card, { className: "border-0 bg-gradient-to-br from-primary/5 to-primary/10 p-0", children: /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4 p-6 pt-6", children: [
1028
- /* @__PURE__ */ jsx(
1029
- DynamicIcon,
1030
- {
1031
- name: "lucide/quote",
1032
- size: 32,
1033
- className: cn(getAccentColor(background), "opacity-40")
1034
- }
1035
- ),
1036
- /* @__PURE__ */ jsxs("p", { className: cn("italic", getTextColor(background, "muted")), children: [
1037
- '"',
1038
- aspect.testimonial.quote,
1039
- '"'
1094
+ resolvedAspects.map((aspect) => /* @__PURE__ */ jsxs(
1095
+ TabsContent,
1096
+ {
1097
+ value: aspect.id,
1098
+ className: "space-y-8",
1099
+ children: [
1100
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
1101
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1102
+ /* @__PURE__ */ jsx("h3", { className: "text-2xl font-bold tracking-tight", children: aspect.title }),
1103
+ /* @__PURE__ */ jsx("p", { className: cn("leading-relaxed"), children: aspect.description })
1104
+ ] }),
1105
+ /* @__PURE__ */ jsx(Card, { className: "border-0 p-0", children: /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4 p-6 pt-6", children: [
1106
+ /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/quote", size: 32 }),
1107
+ /* @__PURE__ */ jsxs("p", { className: "italic", children: [
1108
+ '"',
1109
+ aspect.testimonial.quote,
1110
+ '"'
1111
+ ] }),
1112
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 pt-2", children: [
1113
+ /* @__PURE__ */ jsx("div", { className: "relative h-10 w-10 overflow-hidden rounded-full", children: /* @__PURE__ */ jsx(
1114
+ Img,
1115
+ {
1116
+ src: aspect.testimonial.avatar,
1117
+ alt: aspect.testimonial.author,
1118
+ className: "h-full w-full object-cover",
1119
+ optixFlowConfig
1120
+ }
1121
+ ) }),
1122
+ /* @__PURE__ */ jsxs("div", { children: [
1123
+ /* @__PURE__ */ jsx("h4", { className: "text-sm font-medium", children: aspect.testimonial.author }),
1124
+ /* @__PURE__ */ jsx("p", { className: "text-xs", children: aspect.testimonial.role })
1125
+ ] })
1126
+ ] })
1127
+ ] }) })
1040
1128
  ] }),
1041
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 pt-2", children: [
1042
- /* @__PURE__ */ jsx("div", { className: "relative h-10 w-10 overflow-hidden rounded-full", children: /* @__PURE__ */ jsx(
1043
- Img,
1044
- {
1045
- src: aspect.testimonial.avatar,
1046
- alt: aspect.testimonial.author,
1047
- className: "h-full w-full object-cover",
1048
- optixFlowConfig
1049
- }
1050
- ) }),
1051
- /* @__PURE__ */ jsxs("div", { children: [
1052
- /* @__PURE__ */ jsx("h4", { className: "text-sm font-medium", children: aspect.testimonial.author }),
1053
- /* @__PURE__ */ jsx("p", { className: cn("text-xs", getTextColor(background, "muted")), children: aspect.testimonial.role })
1054
- ] })
1055
- ] })
1056
- ] }) })
1057
- ] }),
1058
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-3", children: aspect.images.map((image, idx) => /* @__PURE__ */ jsx(
1059
- "div",
1060
- {
1061
- className: "relative aspect-[4/3] overflow-hidden rounded-lg",
1062
- children: /* @__PURE__ */ jsx(
1063
- Img,
1129
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-3", children: aspect.images.map((image, idx) => /* @__PURE__ */ jsx(
1130
+ "div",
1064
1131
  {
1065
- src: image,
1066
- alt: `${aspect.title} culture`,
1067
- className: "h-full w-full transform object-cover transition-transform duration-500 hover:scale-105",
1068
- optixFlowConfig
1069
- }
1070
- )
1071
- },
1072
- idx
1073
- )) })
1074
- ] }, aspect.id))
1132
+ className: "relative aspect-4/3 overflow-hidden rounded-lg",
1133
+ children: /* @__PURE__ */ jsx(
1134
+ Img,
1135
+ {
1136
+ src: image,
1137
+ alt: `${aspect.title} culture`,
1138
+ className: "h-full w-full transform object-cover transition-transform duration-500 hover:scale-105",
1139
+ optixFlowConfig
1140
+ }
1141
+ )
1142
+ },
1143
+ idx
1144
+ )) })
1145
+ ]
1146
+ },
1147
+ aspect.id
1148
+ ))
1075
1149
  ]
1076
1150
  }
1077
1151
  ) : null,
1078
- /* @__PURE__ */ jsxs("div", { className: cn("relative mt-16 rounded-xl border bg-background p-8 md:p-12", ctaClassName), children: [
1079
- /* @__PURE__ */ jsxs("div", { className: "grid items-center gap-8 md:grid-cols-2", children: [
1080
- /* @__PURE__ */ jsxs("div", { children: [
1081
- ctaHeading && (typeof ctaHeading === "string" ? /* @__PURE__ */ jsx("h3", { className: cn("mb-4 text-2xl font-bold", ctaHeadingClassName), children: ctaHeading }) : /* @__PURE__ */ jsx("div", { className: cn("mb-4", ctaHeadingClassName), children: ctaHeading })),
1082
- ctaDescription && (typeof ctaDescription === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mb-6", getTextColor(background, "muted"), ctaDescriptionClassName), children: ctaDescription }) : /* @__PURE__ */ jsx("div", { className: cn("mb-6", ctaDescriptionClassName), children: ctaDescription })),
1083
- (actionsSlot || actions && actions.length > 0) && /* @__PURE__ */ jsx("div", { className: cn("flex gap-4", actionsClassName), children: actionsContent })
1084
- ] }),
1085
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2", children: ctaImagesContent })
1086
- ] }),
1087
- /* @__PURE__ */ jsx("div", { className: "absolute -left-5 -top-5 h-10 w-10 rounded-full bg-primary/10" }),
1088
- /* @__PURE__ */ jsx("div", { className: "absolute -bottom-5 -right-5 h-10 w-10 rounded-full bg-primary/10" })
1089
- ] })
1152
+ /* @__PURE__ */ jsxs(
1153
+ "div",
1154
+ {
1155
+ className: cn(
1156
+ "relative mt-16 rounded-xl border p-8 md:p-12",
1157
+ ctaClassName
1158
+ ),
1159
+ children: [
1160
+ /* @__PURE__ */ jsxs("div", { className: "grid items-center gap-8 md:grid-cols-2", children: [
1161
+ /* @__PURE__ */ jsxs("div", { children: [
1162
+ ctaHeading && (typeof ctaHeading === "string" ? /* @__PURE__ */ jsx(
1163
+ "h3",
1164
+ {
1165
+ className: cn("mb-4 text-2xl font-bold", ctaHeadingClassName),
1166
+ children: ctaHeading
1167
+ }
1168
+ ) : ctaHeading),
1169
+ ctaDescription && (typeof ctaDescription === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mb-6", ctaDescriptionClassName), children: ctaDescription }) : ctaDescription),
1170
+ /* @__PURE__ */ jsx(
1171
+ BlockActions,
1172
+ {
1173
+ actions,
1174
+ actionsSlot,
1175
+ actionsClassName
1176
+ }
1177
+ )
1178
+ ] }),
1179
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2", children: ctaImagesContent })
1180
+ ] }),
1181
+ /* @__PURE__ */ jsx("div", { className: "absolute -left-5 -top-5 h-10 w-10 rounded-full bg-primary/10" }),
1182
+ /* @__PURE__ */ jsx("div", { className: "absolute -bottom-5 -right-5 h-10 w-10 rounded-full bg-primary/10" })
1183
+ ]
1184
+ }
1185
+ )
1090
1186
  ]
1091
1187
  }
1092
1188
  );