@sonordev/agency-site-kit 0.1.0 → 0.1.2

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 (89) hide show
  1. package/dist/{BeforeAfterSection-6QUJOBO2.js → BeforeAfterSection-6BHFLY4Y.js} +6 -6
  2. package/dist/BeforeAfterSection-6BHFLY4Y.js.map +1 -0
  3. package/dist/{BeforeAfterSection-DVAWWE4K.cjs → BeforeAfterSection-JTORBR3A.cjs} +6 -6
  4. package/dist/BeforeAfterSection-JTORBR3A.cjs.map +1 -0
  5. package/dist/DesignSystemSection-2R5BRBGO.js +172 -0
  6. package/dist/DesignSystemSection-2R5BRBGO.js.map +1 -0
  7. package/dist/DesignSystemSection-KXIQXITF.cjs +174 -0
  8. package/dist/DesignSystemSection-KXIQXITF.cjs.map +1 -0
  9. package/dist/{DetailsSection-FB763FS7.js → DetailsSection-A6PZQUQL.js} +14 -5
  10. package/dist/DetailsSection-A6PZQUQL.js.map +1 -0
  11. package/dist/{DetailsSection-OACJFGH7.cjs → DetailsSection-TTUZAPZZ.cjs} +14 -5
  12. package/dist/DetailsSection-TTUZAPZZ.cjs.map +1 -0
  13. package/dist/PerformanceSection-24TVVFZA.cjs +356 -0
  14. package/dist/PerformanceSection-24TVVFZA.cjs.map +1 -0
  15. package/dist/PerformanceSection-MGCEIXDX.js +351 -0
  16. package/dist/PerformanceSection-MGCEIXDX.js.map +1 -0
  17. package/dist/SiteArchitectureSection-EE6VQSXM.cjs +349 -0
  18. package/dist/SiteArchitectureSection-EE6VQSXM.cjs.map +1 -0
  19. package/dist/SiteArchitectureSection-PBBRTARV.js +344 -0
  20. package/dist/SiteArchitectureSection-PBBRTARV.js.map +1 -0
  21. package/dist/SpeedComparisonSection-EZKFQVGW.cjs +174 -0
  22. package/dist/SpeedComparisonSection-EZKFQVGW.cjs.map +1 -0
  23. package/dist/SpeedComparisonSection-Y3K7OFZQ.js +172 -0
  24. package/dist/SpeedComparisonSection-Y3K7OFZQ.js.map +1 -0
  25. package/dist/{StrategySection-3ED3QW4R.cjs → StrategySection-CJ7Y6OFQ.cjs} +18 -24
  26. package/dist/StrategySection-CJ7Y6OFQ.cjs.map +1 -0
  27. package/dist/{StrategySection-VUWMIYYP.js → StrategySection-DI5RSCJU.js} +18 -24
  28. package/dist/StrategySection-DI5RSCJU.js.map +1 -0
  29. package/dist/TechStackSection-2AQ7RGY3.js +93 -0
  30. package/dist/TechStackSection-2AQ7RGY3.js.map +1 -0
  31. package/dist/TechStackSection-VTNNZR5V.cjs +95 -0
  32. package/dist/TechStackSection-VTNNZR5V.cjs.map +1 -0
  33. package/dist/{chunk-XMC4DN6G.js → chunk-APG2QSMB.js} +8 -8
  34. package/dist/chunk-APG2QSMB.js.map +1 -0
  35. package/dist/chunk-JTI3F3QY.cjs +619 -0
  36. package/dist/chunk-JTI3F3QY.cjs.map +1 -0
  37. package/dist/{chunk-NAS4K5UR.cjs → chunk-OA5ZM4OA.cjs} +8 -8
  38. package/dist/chunk-OA5ZM4OA.cjs.map +1 -0
  39. package/dist/{chunk-QIC6JFFD.js → chunk-OMOF4VR5.js} +14 -14
  40. package/dist/chunk-OMOF4VR5.js.map +1 -0
  41. package/dist/chunk-RLVW7WEK.js +612 -0
  42. package/dist/chunk-RLVW7WEK.js.map +1 -0
  43. package/dist/{chunk-5FKOLIV6.cjs → chunk-XM2QD3AK.cjs} +14 -14
  44. package/dist/chunk-XM2QD3AK.cjs.map +1 -0
  45. package/dist/index.cjs +13 -13
  46. package/dist/index.d.cts +2 -2
  47. package/dist/index.d.ts +2 -2
  48. package/dist/index.js +3 -3
  49. package/dist/layout/index.cjs +2 -2
  50. package/dist/layout/index.d.cts +1 -1
  51. package/dist/layout/index.d.ts +1 -1
  52. package/dist/layout/index.js +1 -1
  53. package/dist/portfolio/client.cjs +3 -3
  54. package/dist/portfolio/client.d.cts +7 -3
  55. package/dist/portfolio/client.d.ts +7 -3
  56. package/dist/portfolio/client.js +1 -1
  57. package/dist/portfolio/index.cjs +6 -6
  58. package/dist/portfolio/index.d.cts +2 -2
  59. package/dist/portfolio/index.d.ts +2 -2
  60. package/dist/portfolio/index.js +2 -2
  61. package/dist/portfolio/sections.d.cts +1 -1
  62. package/dist/portfolio/sections.d.ts +1 -1
  63. package/dist/portfolio/server.cjs +1 -0
  64. package/dist/portfolio/server.cjs.map +1 -1
  65. package/dist/portfolio/server.d.cts +1 -1
  66. package/dist/portfolio/server.d.ts +1 -1
  67. package/dist/portfolio/server.js +1 -0
  68. package/dist/portfolio/server.js.map +1 -1
  69. package/dist/{types-BMUhBhWx.d.cts → types-DL4t_Cfa.d.cts} +3 -1
  70. package/dist/{types-BMUhBhWx.d.ts → types-DL4t_Cfa.d.ts} +3 -1
  71. package/package.json +1 -1
  72. package/dist/BeforeAfterSection-6QUJOBO2.js.map +0 -1
  73. package/dist/BeforeAfterSection-DVAWWE4K.cjs.map +0 -1
  74. package/dist/DetailsSection-FB763FS7.js.map +0 -1
  75. package/dist/DetailsSection-OACJFGH7.cjs.map +0 -1
  76. package/dist/StrategySection-3ED3QW4R.cjs.map +0 -1
  77. package/dist/StrategySection-VUWMIYYP.js.map +0 -1
  78. package/dist/TechStackSection-OCUYG4XT.js +0 -90
  79. package/dist/TechStackSection-OCUYG4XT.js.map +0 -1
  80. package/dist/TechStackSection-VKJK4KQB.cjs +0 -91
  81. package/dist/TechStackSection-VKJK4KQB.cjs.map +0 -1
  82. package/dist/chunk-2VNNFAG6.js +0 -415
  83. package/dist/chunk-2VNNFAG6.js.map +0 -1
  84. package/dist/chunk-5FKOLIV6.cjs.map +0 -1
  85. package/dist/chunk-NAS4K5UR.cjs.map +0 -1
  86. package/dist/chunk-QIC6JFFD.js.map +0 -1
  87. package/dist/chunk-TAPNXT7X.cjs +0 -422
  88. package/dist/chunk-TAPNXT7X.cjs.map +0 -1
  89. package/dist/chunk-XMC4DN6G.js.map +0 -1
@@ -0,0 +1,612 @@
1
+ 'use client';
2
+ import { AnimatedCounter } from './chunk-2Y4O3LWM.js';
3
+ import { GlassCard } from './chunk-YB4B3OMC.js';
4
+ import { ScrollReveal } from './chunk-7CFFAKDM.js';
5
+ import dynamic from 'next/dynamic';
6
+ import { useRef, useEffect, useMemo, useState, useCallback } from 'react';
7
+ import gsap2 from 'gsap';
8
+ import { ScrollTrigger } from 'gsap/ScrollTrigger';
9
+ import { jsx, jsxs } from 'react/jsx-runtime';
10
+
11
+ function SplitHeadline({
12
+ children,
13
+ tag: Tag = "h2",
14
+ className,
15
+ style,
16
+ delay = 0,
17
+ duration = 0.8,
18
+ staggerAmount = 0.02
19
+ }) {
20
+ const ref = useRef(null);
21
+ const splitContent = useMemo(() => {
22
+ const words = children.split(" ");
23
+ return words.map((word, wi) => /* @__PURE__ */ jsxs("span", { style: { display: "inline-block", whiteSpace: "nowrap" }, children: [
24
+ word.split("").map((char, ci) => /* @__PURE__ */ jsx(
25
+ "span",
26
+ {
27
+ className: "split-char",
28
+ style: { display: "inline-block" },
29
+ children: char
30
+ },
31
+ ci
32
+ )),
33
+ wi < words.length - 1 && /* @__PURE__ */ jsx("span", { style: { display: "inline-block" }, children: "\xA0" })
34
+ ] }, wi));
35
+ }, [children]);
36
+ useEffect(() => {
37
+ gsap2.registerPlugin(ScrollTrigger);
38
+ const el = ref.current;
39
+ if (!el) return;
40
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
41
+ if (prefersReducedMotion) {
42
+ gsap2.set(el.querySelectorAll(".split-char"), { opacity: 1, y: 0 });
43
+ return;
44
+ }
45
+ const chars = el.querySelectorAll(".split-char");
46
+ const ctx = gsap2.context(() => {
47
+ gsap2.fromTo(
48
+ chars,
49
+ {
50
+ opacity: 0,
51
+ y: 20
52
+ },
53
+ {
54
+ opacity: 1,
55
+ y: 0,
56
+ duration,
57
+ delay,
58
+ stagger: staggerAmount,
59
+ ease: "power2.out",
60
+ scrollTrigger: {
61
+ trigger: el,
62
+ start: "top 85%",
63
+ toggleActions: "play none none none"
64
+ }
65
+ }
66
+ );
67
+ }, el);
68
+ return () => ctx.revert();
69
+ }, [delay, duration, staggerAmount]);
70
+ return /* @__PURE__ */ jsx(
71
+ Tag,
72
+ {
73
+ ref,
74
+ className,
75
+ style: {
76
+ overflowX: "clip",
77
+ overflowY: "hidden",
78
+ overflowWrap: "break-word",
79
+ wordBreak: "break-word",
80
+ ...style
81
+ },
82
+ children: splitContent
83
+ }
84
+ );
85
+ }
86
+ function useScaledIframe(viewportWidth) {
87
+ const containerRef = useRef(null);
88
+ const [scale, setScale] = useState(1);
89
+ useEffect(() => {
90
+ const container = containerRef.current;
91
+ if (!container) return;
92
+ const updateScale = () => {
93
+ const containerWidth = container.offsetWidth;
94
+ setScale(containerWidth / viewportWidth);
95
+ };
96
+ updateScale();
97
+ const resizeObserver = new ResizeObserver(updateScale);
98
+ resizeObserver.observe(container);
99
+ return () => resizeObserver.disconnect();
100
+ }, [viewportWidth]);
101
+ return { containerRef, scale };
102
+ }
103
+ function useIframeLoadDetection() {
104
+ const [loaded, setLoaded] = useState(false);
105
+ const iframeRef = useRef(null);
106
+ const onLoad = useCallback(() => {
107
+ const iframe = iframeRef.current;
108
+ if (!iframe) return;
109
+ setTimeout(() => {
110
+ try {
111
+ const doc = iframe.contentDocument;
112
+ if (!doc?.body) {
113
+ return;
114
+ }
115
+ const numElements = doc.querySelectorAll("*").length;
116
+ if (numElements > 20) setLoaded(true);
117
+ } catch {
118
+ setLoaded(true);
119
+ }
120
+ }, 1500);
121
+ }, []);
122
+ return { iframeRef, loaded, onLoad };
123
+ }
124
+ function MacBookFrame({ url, screenshot }) {
125
+ const viewportWidth = 1440;
126
+ const viewportHeight = 900;
127
+ const { containerRef, scale } = useScaledIframe(viewportWidth);
128
+ const { iframeRef, loaded: iframeLoaded, onLoad: onIframeLoad } = useIframeLoadDetection();
129
+ return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
130
+ /* @__PURE__ */ jsx(
131
+ "div",
132
+ {
133
+ className: "relative rounded-t-[10px] p-[4px] pb-0",
134
+ style: {
135
+ background: "linear-gradient(135deg, #e8e8ed 0%, #d1d1d6 100%)",
136
+ boxShadow: "0 -4px 30px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.9)"
137
+ },
138
+ children: /* @__PURE__ */ jsxs(
139
+ "div",
140
+ {
141
+ className: "relative rounded-t-[7px] px-[8px] pt-[8px] pb-0",
142
+ style: { background: "#0a0a0a" },
143
+ children: [
144
+ /* @__PURE__ */ jsx(
145
+ "div",
146
+ {
147
+ className: "absolute top-0 left-1/2 -translate-x-1/2 w-[70px] h-[18px] flex items-center justify-center z-10",
148
+ style: { background: "#0a0a0a", borderRadius: "0 0 10px 10px" },
149
+ children: /* @__PURE__ */ jsx("div", { className: "w-[5px] h-[5px] rounded-full", style: { background: "#2a3a2a", boxShadow: "0 0 0 1px #1a1a1a" } })
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative overflow-hidden rounded-t-[3px]", style: { aspectRatio: `${viewportWidth}/${viewportHeight}`, background: "#0a0a0a" }, children: [
153
+ screenshot && /* @__PURE__ */ jsx("img", { src: screenshot, alt: "Desktop preview", style: { width: "100%", height: "100%", objectFit: "cover", objectPosition: "top center", display: "block", position: "absolute", inset: 0, zIndex: 2, opacity: iframeLoaded ? 0 : 1, transition: "opacity 0.8s ease", pointerEvents: "none" } }),
154
+ url && /* @__PURE__ */ jsx("iframe", { src: url, title: "Desktop", loading: "eager", scrolling: "no", tabIndex: -1, sandbox: "allow-scripts allow-same-origin", ref: iframeRef, onLoad: onIframeLoad, className: "border-0 pointer-events-none", style: { position: "absolute", top: 0, left: 0, width: `${viewportWidth}px`, height: `${viewportHeight}px`, transformOrigin: "top left", transform: `scale(${scale})` } })
155
+ ] })
156
+ ]
157
+ }
158
+ )
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsx("div", { className: "h-[8px]", style: { background: "#0a0a0a", boxShadow: "0 1px 4px rgba(0,0,0,0.3)" } }),
162
+ /* @__PURE__ */ jsx(
163
+ "div",
164
+ {
165
+ className: "relative h-[12px] rounded-b-[10px]",
166
+ style: {
167
+ background: "linear-gradient(to bottom, #e0e0e5, #c8c8cd 20%, #b0b0b5 80%, #a0a0a5)",
168
+ boxShadow: "0 4px 15px rgba(0,0,0,0.3)"
169
+ },
170
+ children: /* @__PURE__ */ jsx(
171
+ "div",
172
+ {
173
+ className: "absolute top-0 left-1/2 -translate-x-1/2 w-[25%] h-[4px] rounded-b-[4px]",
174
+ style: { background: "linear-gradient(to bottom, #909095, #a8a8ad)" }
175
+ }
176
+ )
177
+ }
178
+ )
179
+ ] });
180
+ }
181
+ function IPadFrame({ url, screenshot }) {
182
+ const viewportWidth = 768;
183
+ const viewportHeight = 1024;
184
+ const { containerRef, scale } = useScaledIframe(viewportWidth);
185
+ const { iframeRef, loaded: iframeLoaded, onLoad: onIframeLoad } = useIframeLoadDetection();
186
+ return /* @__PURE__ */ jsx("div", { className: "relative p-[1.5%]", style: { background: "linear-gradient(135deg, #e8e8ed 0%, #d1d1d6 100%)", borderRadius: "8% / 6%", boxShadow: "0 30px 60px -15px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.9) inset, inset 0 1px 0 rgba(255,255,255,0.8)" }, children: /* @__PURE__ */ jsxs("div", { className: "relative p-[2%]", style: { background: "#0a0a0a", borderRadius: "6% / 4.5%" }, children: [
187
+ /* @__PURE__ */ jsx("div", { className: "absolute top-[1.2%] left-1/2 -translate-x-1/2 w-[1.8%] aspect-square rounded-full z-10", style: { background: "#1a1a1f" } }),
188
+ /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative overflow-hidden", style: { borderRadius: "2%", aspectRatio: `${viewportWidth}/${viewportHeight}`, background: "#0a0a0a" }, children: [
189
+ screenshot && /* @__PURE__ */ jsx("img", { src: screenshot, alt: "Tablet preview", style: { width: "100%", height: "100%", objectFit: "cover", objectPosition: "top center", display: "block", position: "absolute", inset: 0, zIndex: 2, opacity: iframeLoaded ? 0 : 1, transition: "opacity 0.8s ease", pointerEvents: "none" } }),
190
+ url && /* @__PURE__ */ jsx("iframe", { src: url, title: "Tablet", loading: "eager", scrolling: "no", tabIndex: -1, sandbox: "allow-scripts allow-same-origin", ref: iframeRef, onLoad: onIframeLoad, className: "border-0 pointer-events-none", style: { position: "absolute", top: 0, left: 0, width: `${viewportWidth}px`, height: `${viewportHeight}px`, transformOrigin: "top left", transform: `scale(${scale})` } })
191
+ ] })
192
+ ] }) });
193
+ }
194
+ function IPhoneFrame({ url, screenshot }) {
195
+ const viewportWidth = 393;
196
+ const viewportHeight = 852;
197
+ const { containerRef, scale } = useScaledIframe(viewportWidth);
198
+ const { iframeRef, loaded: iframeLoaded, onLoad: onIframeLoad } = useIframeLoadDetection();
199
+ return /* @__PURE__ */ jsxs(
200
+ "div",
201
+ {
202
+ className: "relative p-[2.5%]",
203
+ style: {
204
+ background: "linear-gradient(135deg, #e8e8ed 0%, #d1d1d6 100%)",
205
+ borderRadius: "18% / 8%",
206
+ boxShadow: "0 30px 60px -15px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.9) inset, inset 0 1px 0 rgba(255,255,255,0.8)"
207
+ },
208
+ children: [
209
+ /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-[18%] w-[1%] h-[6%] rounded-l-sm", style: { background: "#c8c8cd" } }),
210
+ /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-[26%] w-[1%] h-[10%] rounded-l-sm", style: { background: "#c8c8cd" } }),
211
+ /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-[38%] w-[1%] h-[10%] rounded-l-sm", style: { background: "#c8c8cd" } }),
212
+ /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-[22%] w-[1%] h-[12%] rounded-r-sm", style: { background: "#c8c8cd" } }),
213
+ /* @__PURE__ */ jsxs(
214
+ "div",
215
+ {
216
+ className: "relative p-[3%]",
217
+ style: { background: "#0a0a0a", borderRadius: "14% / 6%" },
218
+ children: [
219
+ /* @__PURE__ */ jsx(
220
+ "div",
221
+ {
222
+ className: "absolute top-[2.5%] left-1/2 -translate-x-1/2 w-[28%] h-[3.5%] rounded-full z-10",
223
+ style: { background: "#1a1a1a" }
224
+ }
225
+ ),
226
+ /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative overflow-hidden", style: { borderRadius: "8% / 4%", aspectRatio: `${viewportWidth}/${viewportHeight}`, background: "#0a0a0a" }, children: [
227
+ screenshot && /* @__PURE__ */ jsx("img", { src: screenshot, alt: "Mobile preview", style: { width: "100%", height: "100%", objectFit: "cover", objectPosition: "top center", display: "block", position: "absolute", inset: 0, zIndex: 2, opacity: iframeLoaded ? 0 : 1, transition: "opacity 0.8s ease", pointerEvents: "none" } }),
228
+ url && /* @__PURE__ */ jsx("iframe", { src: url, title: "Mobile", loading: "eager", scrolling: "no", tabIndex: -1, sandbox: "allow-scripts allow-same-origin", ref: iframeRef, onLoad: onIframeLoad, className: "border-0 pointer-events-none", style: { position: "absolute", top: 0, left: 0, width: `${viewportWidth}px`, height: `${viewportHeight}px`, transformOrigin: "top left", transform: `scale(${scale})` } })
229
+ ] }),
230
+ /* @__PURE__ */ jsx(
231
+ "div",
232
+ {
233
+ className: "absolute bottom-[2%] left-1/2 -translate-x-1/2 w-[34%] h-[1%] rounded-full",
234
+ style: { background: "rgba(255,255,255,0.25)" }
235
+ }
236
+ )
237
+ ]
238
+ }
239
+ )
240
+ ]
241
+ }
242
+ );
243
+ }
244
+ function DeviceTrifolio({
245
+ url,
246
+ screenshots,
247
+ className = "",
248
+ disableAnimation = false
249
+ }) {
250
+ const trifolioRef = useRef(null);
251
+ const frameUrl = url || "";
252
+ useEffect(() => {
253
+ gsap2.registerPlugin(ScrollTrigger);
254
+ const container = trifolioRef.current;
255
+ if (!container || disableAnimation) return;
256
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
257
+ if (prefersReducedMotion) return;
258
+ const macbook = container.querySelector('[data-device="macbook"]');
259
+ const ipad = container.querySelector('[data-device="ipad"]');
260
+ const iphone = container.querySelector('[data-device="iphone"]');
261
+ if (!macbook || !ipad || !iphone) return;
262
+ const ctx = gsap2.context(() => {
263
+ gsap2.set(container, { opacity: 0 });
264
+ gsap2.set(macbook, { opacity: 0, y: 40 });
265
+ gsap2.set(ipad, { opacity: 0, x: -60, y: 30 });
266
+ gsap2.set(iphone, { opacity: 0, x: 60, y: 30 });
267
+ const tl = gsap2.timeline({
268
+ scrollTrigger: {
269
+ trigger: container,
270
+ start: "top bottom",
271
+ toggleActions: "play none none none"
272
+ }
273
+ });
274
+ tl.to(container, { opacity: 1, duration: 0.3 }).to(macbook, { opacity: 1, y: 0, duration: 0.7, ease: "power2.out" }, 0.1).to(ipad, { opacity: 1, x: 0, y: 0, duration: 0.6, ease: "power2.out" }, 0.25).to(iphone, { opacity: 1, x: 0, y: 0, duration: 0.6, ease: "power2.out" }, 0.4);
275
+ }, container);
276
+ return () => ctx.revert();
277
+ }, [disableAnimation]);
278
+ return /* @__PURE__ */ jsxs(
279
+ "div",
280
+ {
281
+ ref: trifolioRef,
282
+ "data-screenshot-target": "device-trifolio",
283
+ className: `relative w-full min-w-0 max-w-full overflow-x-clip ${className}`,
284
+ style: { aspectRatio: "11/5", minHeight: "200px" },
285
+ children: [
286
+ /* @__PURE__ */ jsx(
287
+ "div",
288
+ {
289
+ "data-device": "macbook",
290
+ className: "absolute left-1/2 -translate-x-1/2 bottom-0 w-[65%] z-10",
291
+ children: /* @__PURE__ */ jsx(MacBookFrame, { url: frameUrl, screenshot: screenshots?.desktop })
292
+ }
293
+ ),
294
+ /* @__PURE__ */ jsx(
295
+ "div",
296
+ {
297
+ "data-device": "ipad",
298
+ className: "absolute left-[8%] bottom-0 w-[28%] z-20",
299
+ children: /* @__PURE__ */ jsx(IPadFrame, { url: frameUrl, screenshot: screenshots?.tablet })
300
+ }
301
+ ),
302
+ /* @__PURE__ */ jsx(
303
+ "div",
304
+ {
305
+ "data-device": "iphone",
306
+ className: "absolute right-[10%] bottom-0 w-[14%] z-30",
307
+ children: /* @__PURE__ */ jsx(IPhoneFrame, { url: frameUrl, screenshot: screenshots?.mobile })
308
+ }
309
+ )
310
+ ]
311
+ }
312
+ );
313
+ }
314
+ function HeroSection({ data, screenshots, liveUrl }) {
315
+ const bgRef = useRef(null);
316
+ const deviceRef = useRef(null);
317
+ const shots = screenshots || data.screenshots;
318
+ const url = liveUrl || data.liveUrl;
319
+ useEffect(() => {
320
+ gsap2.registerPlugin(ScrollTrigger);
321
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
322
+ if (prefersReducedMotion) return;
323
+ const ctx = gsap2.context(() => {
324
+ if (bgRef.current) {
325
+ gsap2.to(bgRef.current, {
326
+ yPercent: 30,
327
+ ease: "none",
328
+ scrollTrigger: {
329
+ trigger: bgRef.current.parentElement,
330
+ start: "top top",
331
+ end: "bottom top",
332
+ scrub: true
333
+ }
334
+ });
335
+ }
336
+ });
337
+ return () => ctx.revert();
338
+ }, []);
339
+ return /* @__PURE__ */ jsxs(
340
+ "section",
341
+ {
342
+ className: "relative overflow-hidden w-full",
343
+ style: {
344
+ minHeight: "90vh",
345
+ display: "flex",
346
+ flexDirection: "column",
347
+ justifyContent: "center",
348
+ background: "var(--sk-bg, #0a0a0a)"
349
+ },
350
+ children: [
351
+ /* @__PURE__ */ jsx(
352
+ "div",
353
+ {
354
+ ref: bgRef,
355
+ className: "absolute inset-0 pointer-events-none",
356
+ style: {
357
+ background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,
358
+ willChange: "transform"
359
+ }
360
+ }
361
+ ),
362
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start", children: [
363
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-6", children: [
364
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, duration: 0.6, children: /* @__PURE__ */ jsx(
365
+ "span",
366
+ {
367
+ className: "inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium",
368
+ style: {
369
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
370
+ color: "var(--sk-primary, #6366f1)",
371
+ border: "1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)"
372
+ },
373
+ children: data.category?.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
374
+ }
375
+ ) }),
376
+ /* @__PURE__ */ jsx(
377
+ SplitHeadline,
378
+ {
379
+ tag: "h1",
380
+ className: "text-4xl md:text-5xl lg:text-6xl font-bold leading-tight",
381
+ style: {
382
+ color: "var(--sk-text-primary, #ffffff)",
383
+ fontFamily: "var(--sk-font-heading, inherit)"
384
+ },
385
+ children: data.headline
386
+ }
387
+ ),
388
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.2, children: /* @__PURE__ */ jsx(
389
+ "p",
390
+ {
391
+ className: "text-xl md:text-2xl font-medium",
392
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
393
+ children: data.subheadline
394
+ }
395
+ ) }),
396
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.3, children: /* @__PURE__ */ jsx(
397
+ "p",
398
+ {
399
+ className: "text-base md:text-lg leading-relaxed",
400
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
401
+ children: data.description
402
+ }
403
+ ) }),
404
+ data.services.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.4, stagger: 0.05, children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: data.services.map((service) => /* @__PURE__ */ jsx(
405
+ "span",
406
+ {
407
+ className: "px-3 py-1 rounded-full text-xs font-medium",
408
+ style: {
409
+ background: "var(--sk-surface, rgba(255,255,255,0.05))",
410
+ color: "var(--sk-text-secondary, #a1a1aa)",
411
+ border: "1px solid var(--sk-border, rgba(255,255,255,0.1))"
412
+ },
413
+ children: service
414
+ },
415
+ service
416
+ )) }) }),
417
+ url && /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.5, children: /* @__PURE__ */ jsxs(
418
+ "a",
419
+ {
420
+ href: url,
421
+ target: "_blank",
422
+ rel: "noopener noreferrer",
423
+ className: "inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90",
424
+ style: {
425
+ background: "var(--sk-primary, #6366f1)",
426
+ color: "#ffffff"
427
+ },
428
+ children: [
429
+ "View Live Site",
430
+ /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M6 3h7v7M13 3L3 13", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
431
+ ]
432
+ }
433
+ ) })
434
+ ] }),
435
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-10 lg:pt-8", children: [
436
+ (url || shots?.desktop || shots?.tablet || shots?.mobile) && /* @__PURE__ */ jsx("div", { ref: deviceRef, className: "min-w-0 max-w-full", children: /* @__PURE__ */ jsx(
437
+ DeviceTrifolio,
438
+ {
439
+ screenshots: {
440
+ desktop: shots?.desktop,
441
+ tablet: shots?.tablet,
442
+ mobile: shots?.mobile
443
+ },
444
+ url
445
+ }
446
+ ) }),
447
+ data.kpis.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 30, delay: 0.6, stagger: 0.1, children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: data.kpis.map((kpi, i) => /* @__PURE__ */ jsxs(GlassCard, { padding: "sm", hover: false, className: "text-center", children: [
448
+ /* @__PURE__ */ jsx(
449
+ "div",
450
+ {
451
+ className: "text-2xl md:text-3xl font-bold",
452
+ style: { color: "var(--sk-primary, #6366f1)" },
453
+ children: /* @__PURE__ */ jsx(
454
+ AnimatedCounter,
455
+ {
456
+ value: kpi.value,
457
+ suffix: kpi.suffix,
458
+ prefix: kpi.prefix,
459
+ duration: 2.5
460
+ }
461
+ )
462
+ }
463
+ ),
464
+ /* @__PURE__ */ jsx(
465
+ "div",
466
+ {
467
+ className: "text-xs mt-1 font-medium",
468
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
469
+ children: kpi.label
470
+ }
471
+ )
472
+ ] }, i)) }) })
473
+ ] })
474
+ ] }) })
475
+ ]
476
+ }
477
+ );
478
+ }
479
+ var ChallengesSection = dynamic(() => import('./ChallengesSection-GEQGVSJN.js'), { ssr: true });
480
+ var StrategySection = dynamic(() => import('./StrategySection-DI5RSCJU.js'), { ssr: true });
481
+ var ResultsSection = dynamic(() => import('./ResultsSection-DFUJ5U6M.js'), { ssr: true });
482
+ var TechStackSection = dynamic(() => import('./TechStackSection-2AQ7RGY3.js'), { ssr: true });
483
+ var ServicesSection = dynamic(() => import('./ServicesSection-D5V3Q4GR.js'), { ssr: true });
484
+ var TestimonialSection = dynamic(() => import('./TestimonialSection-6RGSMXQB.js'), { ssr: true });
485
+ var GallerySection = dynamic(() => import('./GallerySection-VMKORC47.js'), { ssr: true });
486
+ var VideoSection = dynamic(() => import('./VideoSection-4A2HC6K6.js'), { ssr: true });
487
+ var TeamSection = dynamic(() => import('./TeamSection-HGKFW6PQ.js'), { ssr: true });
488
+ var FeatureSpotlightSection = dynamic(() => import('./FeatureSpotlightSection-B7P3JGNL.js'), { ssr: true });
489
+ var BeforeAfterSection = dynamic(() => import('./BeforeAfterSection-6BHFLY4Y.js'), { ssr: true });
490
+ var MetricsTimelineSection = dynamic(() => import('./MetricsTimelineSection-6BT5GNFV.js'), { ssr: true });
491
+ var ConversionFunnelSection = dynamic(() => import('./ConversionFunnelSection-D3GE4NKE.js'), { ssr: true });
492
+ var PerformanceSection = dynamic(() => import('./PerformanceSection-MGCEIXDX.js'), { ssr: true });
493
+ var SiteArchitectureSection = dynamic(() => import('./SiteArchitectureSection-PBBRTARV.js'), { ssr: true });
494
+ var SpeedComparisonSection = dynamic(() => import('./SpeedComparisonSection-Y3K7OFZQ.js'), { ssr: true });
495
+ var DesignSystemSection = dynamic(() => import('./DesignSystemSection-2R5BRBGO.js'), { ssr: true });
496
+ var DetailsSection = dynamic(() => import('./DetailsSection-A6PZQUQL.js'), { ssr: true });
497
+ var CTASection = dynamic(() => import('./CTASection-BJA72XIL.js'), { ssr: true });
498
+ function renderSection(section, item, index) {
499
+ const key = `${section.sectionType}-${index}`;
500
+ switch (section.sectionType) {
501
+ case "portfolioHero":
502
+ return /* @__PURE__ */ jsx(
503
+ HeroSection,
504
+ {
505
+ data: section.data,
506
+ screenshots: item.hero_screenshots ?? void 0,
507
+ liveUrl: item.live_url ?? void 0
508
+ },
509
+ key
510
+ );
511
+ case "portfolioChallenges":
512
+ return /* @__PURE__ */ jsx(ChallengesSection, { data: section.data }, key);
513
+ case "portfolioStrategy":
514
+ return /* @__PURE__ */ jsx(StrategySection, { data: section.data }, key);
515
+ case "portfolioResults":
516
+ return /* @__PURE__ */ jsx(ResultsSection, { data: section.data }, key);
517
+ case "portfolioTechStack":
518
+ return /* @__PURE__ */ jsx(TechStackSection, { data: section.data }, key);
519
+ case "portfolioServices":
520
+ return /* @__PURE__ */ jsx(ServicesSection, { data: section.data }, key);
521
+ case "portfolioTestimonial":
522
+ return /* @__PURE__ */ jsx(TestimonialSection, { data: section.data }, key);
523
+ case "portfolioGallery":
524
+ return /* @__PURE__ */ jsx(GallerySection, { data: section.data }, key);
525
+ case "portfolioVideo":
526
+ return /* @__PURE__ */ jsx(VideoSection, { data: section.data }, key);
527
+ case "portfolioTeam":
528
+ return /* @__PURE__ */ jsx(TeamSection, { data: section.data }, key);
529
+ case "portfolioFeatureSpotlight":
530
+ return /* @__PURE__ */ jsx(FeatureSpotlightSection, { data: section.data }, key);
531
+ case "portfolioBeforeAfter":
532
+ return /* @__PURE__ */ jsx(BeforeAfterSection, { data: section.data }, key);
533
+ case "portfolioMetricsTimeline":
534
+ return /* @__PURE__ */ jsx(MetricsTimelineSection, { data: section.data }, key);
535
+ case "portfolioConversionFunnel":
536
+ return /* @__PURE__ */ jsx(ConversionFunnelSection, { data: section.data }, key);
537
+ case "portfolioPerformance":
538
+ return /* @__PURE__ */ jsx(PerformanceSection, { data: section.data }, key);
539
+ case "portfolioSpeedComparison":
540
+ return /* @__PURE__ */ jsx(SpeedComparisonSection, { data: section.data }, key);
541
+ case "portfolioSiteArchitecture":
542
+ return /* @__PURE__ */ jsx(SiteArchitectureSection, { data: section.data }, key);
543
+ case "portfolioDesignSystem":
544
+ return /* @__PURE__ */ jsx(DesignSystemSection, { data: section.data }, key);
545
+ case "portfolioDetails":
546
+ return /* @__PURE__ */ jsx(DetailsSection, { data: section.data }, key);
547
+ case "portfolioCTA":
548
+ return /* @__PURE__ */ jsx(CTASection, { data: section.data }, key);
549
+ case "portfolioSeo":
550
+ return null;
551
+ default:
552
+ return null;
553
+ }
554
+ }
555
+ var SECTION_ORDER = {
556
+ portfolioHero: 0,
557
+ portfolioChallenges: 1,
558
+ portfolioStrategy: 2,
559
+ portfolioResults: 3,
560
+ portfolioPerformance: 4,
561
+ portfolioSpeedComparison: 5,
562
+ portfolioSiteArchitecture: 6,
563
+ portfolioTechStack: 7,
564
+ portfolioDesignSystem: 8,
565
+ portfolioServices: 9,
566
+ portfolioBeforeAfter: 10,
567
+ portfolioTestimonial: 11,
568
+ portfolioMetricsTimeline: 12,
569
+ portfolioConversionFunnel: 13,
570
+ portfolioDetails: 11,
571
+ portfolioSeo: 12,
572
+ portfolioCta: 13
573
+ };
574
+ function PortfolioPage({ item }) {
575
+ const sortedSections = [...item.sections].sort(
576
+ (a, b) => (SECTION_ORDER[a.sectionType] ?? 99) - (SECTION_ORDER[b.sectionType] ?? 99)
577
+ );
578
+ return /* @__PURE__ */ jsx("article", { className: "flex w-full min-w-0 max-w-full flex-col overflow-x-clip", children: sortedSections.map((section, index) => {
579
+ const rendered = renderSection(section, item, index);
580
+ if (!rendered) return null;
581
+ return /* @__PURE__ */ jsx("div", { className: "w-full", children: rendered }, `wrapper-${section.sectionType}-${index}`);
582
+ }) });
583
+ }
584
+
585
+ // src/types.ts
586
+ var PORTFOLIO_SECTION_TYPES = [
587
+ "portfolioHero",
588
+ "portfolioChallenges",
589
+ "portfolioStrategy",
590
+ "portfolioResults",
591
+ "portfolioTechStack",
592
+ "portfolioServices",
593
+ "portfolioTestimonial",
594
+ "portfolioGallery",
595
+ "portfolioVideo",
596
+ "portfolioTeam",
597
+ "portfolioFeatureSpotlight",
598
+ "portfolioBeforeAfter",
599
+ "portfolioMetricsTimeline",
600
+ "portfolioConversionFunnel",
601
+ "portfolioPerformance",
602
+ "portfolioSpeedComparison",
603
+ "portfolioSiteArchitecture",
604
+ "portfolioDesignSystem",
605
+ "portfolioDetails",
606
+ "portfolioSeo",
607
+ "portfolioCTA"
608
+ ];
609
+
610
+ export { PORTFOLIO_SECTION_TYPES, PortfolioPage };
611
+ //# sourceMappingURL=chunk-RLVW7WEK.js.map
612
+ //# sourceMappingURL=chunk-RLVW7WEK.js.map