@opensite/ui 2.0.6 → 2.0.8

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