@sonordev/agency-site-kit 0.1.0 → 0.1.1

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