@sonordev/agency-site-kit 0.1.0

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 (131) hide show
  1. package/dist/BeforeAfterSection-6QUJOBO2.js +176 -0
  2. package/dist/BeforeAfterSection-6QUJOBO2.js.map +1 -0
  3. package/dist/BeforeAfterSection-DVAWWE4K.cjs +181 -0
  4. package/dist/BeforeAfterSection-DVAWWE4K.cjs.map +1 -0
  5. package/dist/CTASection-4JKLXEUF.cjs +111 -0
  6. package/dist/CTASection-4JKLXEUF.cjs.map +1 -0
  7. package/dist/CTASection-BJA72XIL.js +106 -0
  8. package/dist/CTASection-BJA72XIL.js.map +1 -0
  9. package/dist/ChallengesSection-GEQGVSJN.js +180 -0
  10. package/dist/ChallengesSection-GEQGVSJN.js.map +1 -0
  11. package/dist/ChallengesSection-IZ3DHECS.cjs +182 -0
  12. package/dist/ChallengesSection-IZ3DHECS.cjs.map +1 -0
  13. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs +209 -0
  14. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs.map +1 -0
  15. package/dist/ConversionFunnelSection-D3GE4NKE.js +203 -0
  16. package/dist/ConversionFunnelSection-D3GE4NKE.js.map +1 -0
  17. package/dist/DetailsSection-FB763FS7.js +135 -0
  18. package/dist/DetailsSection-FB763FS7.js.map +1 -0
  19. package/dist/DetailsSection-OACJFGH7.cjs +137 -0
  20. package/dist/DetailsSection-OACJFGH7.cjs.map +1 -0
  21. package/dist/FeatureSpotlightSection-B7P3JGNL.js +205 -0
  22. package/dist/FeatureSpotlightSection-B7P3JGNL.js.map +1 -0
  23. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs +210 -0
  24. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs.map +1 -0
  25. package/dist/GallerySection-VMKORC47.js +218 -0
  26. package/dist/GallerySection-VMKORC47.js.map +1 -0
  27. package/dist/GallerySection-WJ4PQDBI.cjs +219 -0
  28. package/dist/GallerySection-WJ4PQDBI.cjs.map +1 -0
  29. package/dist/MetricsTimelineSection-4L6DUHJ5.cjs +258 -0
  30. package/dist/MetricsTimelineSection-4L6DUHJ5.cjs.map +1 -0
  31. package/dist/MetricsTimelineSection-6BT5GNFV.js +253 -0
  32. package/dist/MetricsTimelineSection-6BT5GNFV.js.map +1 -0
  33. package/dist/ResultsSection-DFUJ5U6M.js +93 -0
  34. package/dist/ResultsSection-DFUJ5U6M.js.map +1 -0
  35. package/dist/ResultsSection-XLGMMQKY.cjs +95 -0
  36. package/dist/ResultsSection-XLGMMQKY.cjs.map +1 -0
  37. package/dist/ServicesSection-D5V3Q4GR.js +118 -0
  38. package/dist/ServicesSection-D5V3Q4GR.js.map +1 -0
  39. package/dist/ServicesSection-WJMGK2MF.cjs +120 -0
  40. package/dist/ServicesSection-WJMGK2MF.cjs.map +1 -0
  41. package/dist/StrategySection-3ED3QW4R.cjs +180 -0
  42. package/dist/StrategySection-3ED3QW4R.cjs.map +1 -0
  43. package/dist/StrategySection-VUWMIYYP.js +175 -0
  44. package/dist/StrategySection-VUWMIYYP.js.map +1 -0
  45. package/dist/TeamSection-DZVSNZE6.cjs +112 -0
  46. package/dist/TeamSection-DZVSNZE6.cjs.map +1 -0
  47. package/dist/TeamSection-HGKFW6PQ.js +107 -0
  48. package/dist/TeamSection-HGKFW6PQ.js.map +1 -0
  49. package/dist/TechStackSection-OCUYG4XT.js +90 -0
  50. package/dist/TechStackSection-OCUYG4XT.js.map +1 -0
  51. package/dist/TechStackSection-VKJK4KQB.cjs +91 -0
  52. package/dist/TechStackSection-VKJK4KQB.cjs.map +1 -0
  53. package/dist/TestimonialSection-6RGSMXQB.js +122 -0
  54. package/dist/TestimonialSection-6RGSMXQB.js.map +1 -0
  55. package/dist/TestimonialSection-XPTFUQIN.cjs +124 -0
  56. package/dist/TestimonialSection-XPTFUQIN.cjs.map +1 -0
  57. package/dist/VideoSection-4A2HC6K6.js +117 -0
  58. package/dist/VideoSection-4A2HC6K6.js.map +1 -0
  59. package/dist/VideoSection-G3DFS7UH.cjs +118 -0
  60. package/dist/VideoSection-G3DFS7UH.cjs.map +1 -0
  61. package/dist/chunk-2VNNFAG6.js +415 -0
  62. package/dist/chunk-2VNNFAG6.js.map +1 -0
  63. package/dist/chunk-2Y4O3LWM.js +53 -0
  64. package/dist/chunk-2Y4O3LWM.js.map +1 -0
  65. package/dist/chunk-5FKOLIV6.cjs +221 -0
  66. package/dist/chunk-5FKOLIV6.cjs.map +1 -0
  67. package/dist/chunk-7CFFAKDM.js +74 -0
  68. package/dist/chunk-7CFFAKDM.js.map +1 -0
  69. package/dist/chunk-A4I4IK7V.js +69 -0
  70. package/dist/chunk-A4I4IK7V.js.map +1 -0
  71. package/dist/chunk-IKBK7HYX.cjs +79 -0
  72. package/dist/chunk-IKBK7HYX.cjs.map +1 -0
  73. package/dist/chunk-KEOHORIH.cjs +79 -0
  74. package/dist/chunk-KEOHORIH.cjs.map +1 -0
  75. package/dist/chunk-NAS4K5UR.cjs +139 -0
  76. package/dist/chunk-NAS4K5UR.cjs.map +1 -0
  77. package/dist/chunk-QBLWP25X.cjs +73 -0
  78. package/dist/chunk-QBLWP25X.cjs.map +1 -0
  79. package/dist/chunk-QIC6JFFD.js +210 -0
  80. package/dist/chunk-QIC6JFFD.js.map +1 -0
  81. package/dist/chunk-TAPNXT7X.cjs +422 -0
  82. package/dist/chunk-TAPNXT7X.cjs.map +1 -0
  83. package/dist/chunk-XCKXHK44.js +15 -0
  84. package/dist/chunk-XCKXHK44.js.map +1 -0
  85. package/dist/chunk-XMC4DN6G.js +131 -0
  86. package/dist/chunk-XMC4DN6G.js.map +1 -0
  87. package/dist/chunk-XONXEFJY.cjs +58 -0
  88. package/dist/chunk-XONXEFJY.cjs.map +1 -0
  89. package/dist/chunk-XQNJED46.cjs +19 -0
  90. package/dist/chunk-XQNJED46.cjs.map +1 -0
  91. package/dist/chunk-YB4B3OMC.js +74 -0
  92. package/dist/chunk-YB4B3OMC.js.map +1 -0
  93. package/dist/index.cjs +271 -0
  94. package/dist/index.cjs.map +1 -0
  95. package/dist/index.d.cts +137 -0
  96. package/dist/index.d.ts +137 -0
  97. package/dist/index.js +197 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/layout/index.cjs +13 -0
  100. package/dist/layout/index.cjs.map +1 -0
  101. package/dist/layout/index.d.cts +54 -0
  102. package/dist/layout/index.d.ts +54 -0
  103. package/dist/layout/index.js +4 -0
  104. package/dist/layout/index.js.map +1 -0
  105. package/dist/portfolio/client.cjs +18 -0
  106. package/dist/portfolio/client.cjs.map +1 -0
  107. package/dist/portfolio/client.d.cts +97 -0
  108. package/dist/portfolio/client.d.ts +97 -0
  109. package/dist/portfolio/client.js +6 -0
  110. package/dist/portfolio/client.js.map +1 -0
  111. package/dist/portfolio/index.cjs +41 -0
  112. package/dist/portfolio/index.cjs.map +1 -0
  113. package/dist/portfolio/index.d.cts +12 -0
  114. package/dist/portfolio/index.d.ts +12 -0
  115. package/dist/portfolio/index.js +8 -0
  116. package/dist/portfolio/index.js.map +1 -0
  117. package/dist/portfolio/sections.cjs +20 -0
  118. package/dist/portfolio/sections.cjs.map +1 -0
  119. package/dist/portfolio/sections.d.cts +42 -0
  120. package/dist/portfolio/sections.d.ts +42 -0
  121. package/dist/portfolio/sections.js +4 -0
  122. package/dist/portfolio/sections.js.map +1 -0
  123. package/dist/portfolio/server.cjs +141 -0
  124. package/dist/portfolio/server.cjs.map +1 -0
  125. package/dist/portfolio/server.d.cts +68 -0
  126. package/dist/portfolio/server.d.ts +68 -0
  127. package/dist/portfolio/server.js +134 -0
  128. package/dist/portfolio/server.js.map +1 -0
  129. package/dist/types-BMUhBhWx.d.cts +346 -0
  130. package/dist/types-BMUhBhWx.d.ts +346 -0
  131. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/VideoSection.tsx"],"names":[],"mappings":"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","file":"VideoSection-4A2HC6K6.js","sourcesContent":["'use client';\n\nimport React, { useState, useCallback } from 'react';\nimport type { PortfolioVideoData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface VideoSectionProps {\n data: PortfolioVideoData;\n}\n\nfunction getEmbedUrl(data: PortfolioVideoData): string {\n if (data.embedUrl) return data.embedUrl;\n if (!data.url) return '';\n\n // Parse YouTube URLs\n const ytMatch = data.url.match(\n /(?:youtube\\.com\\/(?:watch\\?v=|embed\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/,\n );\n if (ytMatch) return `https://www.youtube.com/embed/${ytMatch[1]}?autoplay=1`;\n\n // Parse Vimeo URLs\n const vimeoMatch = data.url.match(/vimeo\\.com\\/(\\d+)/);\n if (vimeoMatch) return `https://player.vimeo.com/video/${vimeoMatch[1]}?autoplay=1`;\n\n return data.url;\n}\n\nexport default function VideoSection({ data }: VideoSectionProps) {\n const [playing, setPlaying] = useState(false);\n\n const thumbnailUrl = data.thumbnail?.asset?._ref || '';\n const embedUrl = getEmbedUrl(data);\n\n const handlePlay = useCallback(() => {\n if (embedUrl) setPlaying(true);\n }, [embedUrl]);\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n {data.title}\n </h2>\n </ScrollReveal>\n\n <ScrollReveal y={40} delay={0.15}>\n <GlassCard padding=\"sm\" hover={false}>\n <div className=\"relative w-full overflow-hidden rounded-xl\" style={{ aspectRatio: '16/9' }}>\n {playing ? (\n <iframe\n src={embedUrl}\n className=\"absolute inset-0 w-full h-full\"\n allow=\"autoplay; fullscreen; picture-in-picture\"\n allowFullScreen\n title={data.title}\n style={{ border: 'none' }}\n />\n ) : (\n <button\n onClick={handlePlay}\n className=\"absolute inset-0 w-full h-full group cursor-pointer\"\n aria-label={`Play ${data.title}`}\n >\n {/* Thumbnail */}\n {thumbnailUrl && (\n <img\n src={thumbnailUrl}\n alt={data.title}\n className=\"w-full h-full object-cover\"\n />\n )}\n\n {/* Dark overlay */}\n <div\n className=\"absolute inset-0 transition-opacity duration-300 group-hover:opacity-60\"\n style={{ background: 'rgba(0,0,0,0.4)', opacity: 0.5 }}\n />\n\n {/* Play button */}\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div\n className=\"flex items-center justify-center w-20 h-20 rounded-full transition-transform duration-300 group-hover:scale-110\"\n style={{\n background: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 8px 32px color-mix(in srgb, var(--sk-primary, #6366f1) 40%, transparent)',\n }}\n >\n <svg\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M12 8l14 8-14 8V8z\" fill=\"#ffffff\" />\n </svg>\n </div>\n </div>\n\n {/* Duration badge */}\n {data.duration && (\n <span\n className=\"absolute bottom-4 right-4 px-3 py-1 rounded-lg text-xs font-medium\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n {data.duration}\n </span>\n )}\n </button>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,118 @@
1
+ 'use strict';
2
+
3
+ var chunkKEOHORIH_cjs = require('./chunk-KEOHORIH.cjs');
4
+ var chunkIKBK7HYX_cjs = require('./chunk-IKBK7HYX.cjs');
5
+ var react = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function getEmbedUrl(data) {
9
+ if (data.embedUrl) return data.embedUrl;
10
+ if (!data.url) return "";
11
+ const ytMatch = data.url.match(
12
+ /(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/
13
+ );
14
+ if (ytMatch) return `https://www.youtube.com/embed/${ytMatch[1]}?autoplay=1`;
15
+ const vimeoMatch = data.url.match(/vimeo\.com\/(\d+)/);
16
+ if (vimeoMatch) return `https://player.vimeo.com/video/${vimeoMatch[1]}?autoplay=1`;
17
+ return data.url;
18
+ }
19
+ function VideoSection({ data }) {
20
+ const [playing, setPlaying] = react.useState(false);
21
+ const thumbnailUrl = data.thumbnail?.asset?._ref || "";
22
+ const embedUrl = getEmbedUrl(data);
23
+ const handlePlay = react.useCallback(() => {
24
+ if (embedUrl) setPlaying(true);
25
+ }, [embedUrl]);
26
+ return /* @__PURE__ */ jsxRuntime.jsx(
27
+ "section",
28
+ {
29
+ className: "w-full py-20 md:py-28",
30
+ style: { background: "var(--sk-bg, #0a0a0a)" },
31
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
32
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: /* @__PURE__ */ jsxRuntime.jsx(
33
+ "h2",
34
+ {
35
+ className: "text-3xl md:text-4xl font-bold mb-4",
36
+ style: {
37
+ color: "var(--sk-text-primary, #ffffff)",
38
+ fontFamily: "var(--sk-font-heading, inherit)"
39
+ },
40
+ children: data.title
41
+ }
42
+ ) }),
43
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 40, delay: 0.15, children: /* @__PURE__ */ jsxRuntime.jsx(chunkKEOHORIH_cjs.GlassCard, { padding: "sm", hover: false, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full overflow-hidden rounded-xl", style: { aspectRatio: "16/9" }, children: playing ? /* @__PURE__ */ jsxRuntime.jsx(
44
+ "iframe",
45
+ {
46
+ src: embedUrl,
47
+ className: "absolute inset-0 w-full h-full",
48
+ allow: "autoplay; fullscreen; picture-in-picture",
49
+ allowFullScreen: true,
50
+ title: data.title,
51
+ style: { border: "none" }
52
+ }
53
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
54
+ "button",
55
+ {
56
+ onClick: handlePlay,
57
+ className: "absolute inset-0 w-full h-full group cursor-pointer",
58
+ "aria-label": `Play ${data.title}`,
59
+ children: [
60
+ thumbnailUrl && /* @__PURE__ */ jsxRuntime.jsx(
61
+ "img",
62
+ {
63
+ src: thumbnailUrl,
64
+ alt: data.title,
65
+ className: "w-full h-full object-cover"
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsxRuntime.jsx(
69
+ "div",
70
+ {
71
+ className: "absolute inset-0 transition-opacity duration-300 group-hover:opacity-60",
72
+ style: { background: "rgba(0,0,0,0.4)", opacity: 0.5 }
73
+ }
74
+ ),
75
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
76
+ "div",
77
+ {
78
+ className: "flex items-center justify-center w-20 h-20 rounded-full transition-transform duration-300 group-hover:scale-110",
79
+ style: {
80
+ background: "var(--sk-primary, #6366f1)",
81
+ boxShadow: "0 8px 32px color-mix(in srgb, var(--sk-primary, #6366f1) 40%, transparent)"
82
+ },
83
+ children: /* @__PURE__ */ jsxRuntime.jsx(
84
+ "svg",
85
+ {
86
+ width: "32",
87
+ height: "32",
88
+ viewBox: "0 0 32 32",
89
+ fill: "none",
90
+ xmlns: "http://www.w3.org/2000/svg",
91
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 8l14 8-14 8V8z", fill: "#ffffff" })
92
+ }
93
+ )
94
+ }
95
+ ) }),
96
+ data.duration && /* @__PURE__ */ jsxRuntime.jsx(
97
+ "span",
98
+ {
99
+ className: "absolute bottom-4 right-4 px-3 py-1 rounded-lg text-xs font-medium",
100
+ style: {
101
+ background: "rgba(0,0,0,0.6)",
102
+ color: "#ffffff",
103
+ backdropFilter: "blur(4px)"
104
+ },
105
+ children: data.duration
106
+ }
107
+ )
108
+ ]
109
+ }
110
+ ) }) }) })
111
+ ] })
112
+ }
113
+ );
114
+ }
115
+
116
+ module.exports = VideoSection;
117
+ //# sourceMappingURL=VideoSection-G3DFS7UH.cjs.map
118
+ //# sourceMappingURL=VideoSection-G3DFS7UH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/VideoSection.tsx"],"names":["useState","useCallback","jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"VideoSection-G3DFS7UH.cjs","sourcesContent":["'use client';\n\nimport React, { useState, useCallback } from 'react';\nimport type { PortfolioVideoData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface VideoSectionProps {\n data: PortfolioVideoData;\n}\n\nfunction getEmbedUrl(data: PortfolioVideoData): string {\n if (data.embedUrl) return data.embedUrl;\n if (!data.url) return '';\n\n // Parse YouTube URLs\n const ytMatch = data.url.match(\n /(?:youtube\\.com\\/(?:watch\\?v=|embed\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/,\n );\n if (ytMatch) return `https://www.youtube.com/embed/${ytMatch[1]}?autoplay=1`;\n\n // Parse Vimeo URLs\n const vimeoMatch = data.url.match(/vimeo\\.com\\/(\\d+)/);\n if (vimeoMatch) return `https://player.vimeo.com/video/${vimeoMatch[1]}?autoplay=1`;\n\n return data.url;\n}\n\nexport default function VideoSection({ data }: VideoSectionProps) {\n const [playing, setPlaying] = useState(false);\n\n const thumbnailUrl = data.thumbnail?.asset?._ref || '';\n const embedUrl = getEmbedUrl(data);\n\n const handlePlay = useCallback(() => {\n if (embedUrl) setPlaying(true);\n }, [embedUrl]);\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n {data.title}\n </h2>\n </ScrollReveal>\n\n <ScrollReveal y={40} delay={0.15}>\n <GlassCard padding=\"sm\" hover={false}>\n <div className=\"relative w-full overflow-hidden rounded-xl\" style={{ aspectRatio: '16/9' }}>\n {playing ? (\n <iframe\n src={embedUrl}\n className=\"absolute inset-0 w-full h-full\"\n allow=\"autoplay; fullscreen; picture-in-picture\"\n allowFullScreen\n title={data.title}\n style={{ border: 'none' }}\n />\n ) : (\n <button\n onClick={handlePlay}\n className=\"absolute inset-0 w-full h-full group cursor-pointer\"\n aria-label={`Play ${data.title}`}\n >\n {/* Thumbnail */}\n {thumbnailUrl && (\n <img\n src={thumbnailUrl}\n alt={data.title}\n className=\"w-full h-full object-cover\"\n />\n )}\n\n {/* Dark overlay */}\n <div\n className=\"absolute inset-0 transition-opacity duration-300 group-hover:opacity-60\"\n style={{ background: 'rgba(0,0,0,0.4)', opacity: 0.5 }}\n />\n\n {/* Play button */}\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div\n className=\"flex items-center justify-center w-20 h-20 rounded-full transition-transform duration-300 group-hover:scale-110\"\n style={{\n background: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 8px 32px color-mix(in srgb, var(--sk-primary, #6366f1) 40%, transparent)',\n }}\n >\n <svg\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M12 8l14 8-14 8V8z\" fill=\"#ffffff\" />\n </svg>\n </div>\n </div>\n\n {/* Duration badge */}\n {data.duration && (\n <span\n className=\"absolute bottom-4 right-4 px-3 py-1 rounded-lg text-xs font-medium\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n {data.duration}\n </span>\n )}\n </button>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,415 @@
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 } from 'react';
7
+ import gsap 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
+ gsap.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
+ gsap.set(el.querySelectorAll(".split-char"), { opacity: 1, y: 0 });
43
+ return;
44
+ }
45
+ const chars = el.querySelectorAll(".split-char");
46
+ const ctx = gsap.context(() => {
47
+ gsap.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 HeroSection({ data, screenshots, liveUrl }) {
81
+ const bgRef = useRef(null);
82
+ const deviceRef = useRef(null);
83
+ const shots = screenshots || data.screenshots;
84
+ const url = liveUrl || data.liveUrl;
85
+ useEffect(() => {
86
+ gsap.registerPlugin(ScrollTrigger);
87
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
88
+ if (prefersReducedMotion) return;
89
+ const ctx = gsap.context(() => {
90
+ if (bgRef.current) {
91
+ gsap.to(bgRef.current, {
92
+ yPercent: 30,
93
+ ease: "none",
94
+ scrollTrigger: {
95
+ trigger: bgRef.current.parentElement,
96
+ start: "top top",
97
+ end: "bottom top",
98
+ scrub: true
99
+ }
100
+ });
101
+ }
102
+ if (deviceRef.current) {
103
+ const devices = deviceRef.current.children;
104
+ gsap.fromTo(
105
+ devices,
106
+ { y: 60, opacity: 0, scale: 0.95 },
107
+ {
108
+ y: 0,
109
+ opacity: 1,
110
+ scale: 1,
111
+ duration: 1,
112
+ stagger: 0.15,
113
+ ease: "power3.out",
114
+ delay: 0.6
115
+ }
116
+ );
117
+ }
118
+ });
119
+ return () => ctx.revert();
120
+ }, []);
121
+ return /* @__PURE__ */ jsxs(
122
+ "section",
123
+ {
124
+ className: "relative overflow-hidden w-full",
125
+ style: {
126
+ minHeight: "90vh",
127
+ display: "flex",
128
+ flexDirection: "column",
129
+ justifyContent: "center",
130
+ background: "var(--sk-bg, #0a0a0a)"
131
+ },
132
+ children: [
133
+ /* @__PURE__ */ jsx(
134
+ "div",
135
+ {
136
+ ref: bgRef,
137
+ className: "absolute inset-0 pointer-events-none",
138
+ style: {
139
+ background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,
140
+ willChange: "transform"
141
+ }
142
+ }
143
+ ),
144
+ /* @__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-center", children: [
145
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
146
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, duration: 0.6, children: /* @__PURE__ */ jsx(
147
+ "span",
148
+ {
149
+ className: "inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium",
150
+ style: {
151
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
152
+ color: "var(--sk-primary, #6366f1)",
153
+ border: "1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)"
154
+ },
155
+ children: data.category
156
+ }
157
+ ) }),
158
+ /* @__PURE__ */ jsx(
159
+ SplitHeadline,
160
+ {
161
+ tag: "h1",
162
+ className: "text-4xl md:text-5xl lg:text-6xl font-bold leading-tight",
163
+ style: {
164
+ color: "var(--sk-text-primary, #ffffff)",
165
+ fontFamily: "var(--sk-font-heading, inherit)"
166
+ },
167
+ children: data.headline
168
+ }
169
+ ),
170
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.2, children: /* @__PURE__ */ jsx(
171
+ "p",
172
+ {
173
+ className: "text-xl md:text-2xl font-medium",
174
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
175
+ children: data.subheadline
176
+ }
177
+ ) }),
178
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.3, children: /* @__PURE__ */ jsx(
179
+ "p",
180
+ {
181
+ className: "text-base md:text-lg leading-relaxed",
182
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
183
+ children: data.description
184
+ }
185
+ ) }),
186
+ 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(
187
+ "span",
188
+ {
189
+ className: "px-3 py-1 rounded-full text-xs font-medium",
190
+ style: {
191
+ background: "var(--sk-surface, rgba(255,255,255,0.05))",
192
+ color: "var(--sk-text-secondary, #a1a1aa)",
193
+ border: "1px solid var(--sk-border, rgba(255,255,255,0.1))"
194
+ },
195
+ children: service
196
+ },
197
+ service
198
+ )) }) }),
199
+ url && /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.5, children: /* @__PURE__ */ jsxs(
200
+ "a",
201
+ {
202
+ href: url,
203
+ target: "_blank",
204
+ rel: "noopener noreferrer",
205
+ className: "inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90",
206
+ style: {
207
+ background: "var(--sk-primary, #6366f1)",
208
+ color: "#ffffff"
209
+ },
210
+ children: [
211
+ "View Live Site",
212
+ /* @__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" }) })
213
+ ]
214
+ }
215
+ ) }),
216
+ data.kpis.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 30, delay: 0.6, stagger: 0.1, children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 mt-4", children: data.kpis.map((kpi, i) => /* @__PURE__ */ jsxs(GlassCard, { padding: "sm", hover: false, className: "text-center", children: [
217
+ /* @__PURE__ */ jsx(
218
+ "div",
219
+ {
220
+ className: "text-2xl md:text-3xl font-bold",
221
+ style: { color: "var(--sk-primary, #6366f1)" },
222
+ children: /* @__PURE__ */ jsx(
223
+ AnimatedCounter,
224
+ {
225
+ value: kpi.value,
226
+ suffix: kpi.suffix,
227
+ prefix: kpi.prefix,
228
+ duration: 2.5
229
+ }
230
+ )
231
+ }
232
+ ),
233
+ /* @__PURE__ */ jsx(
234
+ "div",
235
+ {
236
+ className: "text-xs mt-1 font-medium",
237
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
238
+ children: kpi.label
239
+ }
240
+ ),
241
+ /* @__PURE__ */ jsx(
242
+ "span",
243
+ {
244
+ className: "inline-block mt-1.5 px-2 py-0.5 rounded text-[10px] uppercase tracking-wider font-medium",
245
+ style: {
246
+ background: kpi.source === "measured" ? "color-mix(in srgb, #10b981 15%, transparent)" : "color-mix(in srgb, #f59e0b 15%, transparent)",
247
+ color: kpi.source === "measured" ? "#10b981" : "#f59e0b"
248
+ },
249
+ children: kpi.source
250
+ }
251
+ )
252
+ ] }, i)) }) })
253
+ ] }),
254
+ (shots?.desktop || shots?.tablet || shots?.mobile) && /* @__PURE__ */ jsxs("div", { ref: deviceRef, className: "relative flex items-end justify-center gap-3 lg:gap-4 min-h-[400px]", children: [
255
+ shots.desktop && /* @__PURE__ */ jsx(
256
+ "div",
257
+ {
258
+ className: "relative w-full max-w-[480px] rounded-lg overflow-hidden shadow-2xl",
259
+ style: {
260
+ border: "2px solid var(--sk-border, rgba(255,255,255,0.1))",
261
+ aspectRatio: "16/10"
262
+ },
263
+ children: /* @__PURE__ */ jsx(
264
+ "img",
265
+ {
266
+ src: shots.desktop,
267
+ alt: "Desktop screenshot",
268
+ className: "w-full h-full object-cover object-top",
269
+ loading: "eager"
270
+ }
271
+ )
272
+ }
273
+ ),
274
+ shots.tablet && /* @__PURE__ */ jsx(
275
+ "div",
276
+ {
277
+ className: "absolute bottom-0 right-0 w-[45%] max-w-[220px] rounded-lg overflow-hidden shadow-2xl z-10",
278
+ style: {
279
+ border: "2px solid var(--sk-border, rgba(255,255,255,0.1))",
280
+ aspectRatio: "3/4",
281
+ transform: "translateX(10%) translateY(5%)"
282
+ },
283
+ children: /* @__PURE__ */ jsx(
284
+ "img",
285
+ {
286
+ src: shots.tablet,
287
+ alt: "Tablet screenshot",
288
+ className: "w-full h-full object-cover object-top",
289
+ loading: "eager"
290
+ }
291
+ )
292
+ }
293
+ ),
294
+ shots.mobile && /* @__PURE__ */ jsx(
295
+ "div",
296
+ {
297
+ className: "absolute bottom-0 right-[15%] w-[25%] max-w-[120px] rounded-xl overflow-hidden shadow-2xl z-20",
298
+ style: {
299
+ border: "2px solid var(--sk-border, rgba(255,255,255,0.1))",
300
+ aspectRatio: "9/19",
301
+ transform: "translateY(10%)"
302
+ },
303
+ children: /* @__PURE__ */ jsx(
304
+ "img",
305
+ {
306
+ src: shots.mobile,
307
+ alt: "Mobile screenshot",
308
+ className: "w-full h-full object-cover object-top",
309
+ loading: "eager"
310
+ }
311
+ )
312
+ }
313
+ )
314
+ ] })
315
+ ] }) })
316
+ ]
317
+ }
318
+ );
319
+ }
320
+ var ChallengesSection = dynamic(() => import('./ChallengesSection-GEQGVSJN.js'), { ssr: true });
321
+ var StrategySection = dynamic(() => import('./StrategySection-VUWMIYYP.js'), { ssr: true });
322
+ var ResultsSection = dynamic(() => import('./ResultsSection-DFUJ5U6M.js'), { ssr: true });
323
+ var TechStackSection = dynamic(() => import('./TechStackSection-OCUYG4XT.js'), { ssr: true });
324
+ var ServicesSection = dynamic(() => import('./ServicesSection-D5V3Q4GR.js'), { ssr: true });
325
+ var TestimonialSection = dynamic(() => import('./TestimonialSection-6RGSMXQB.js'), { ssr: true });
326
+ var GallerySection = dynamic(() => import('./GallerySection-VMKORC47.js'), { ssr: true });
327
+ var VideoSection = dynamic(() => import('./VideoSection-4A2HC6K6.js'), { ssr: true });
328
+ var TeamSection = dynamic(() => import('./TeamSection-HGKFW6PQ.js'), { ssr: true });
329
+ var FeatureSpotlightSection = dynamic(() => import('./FeatureSpotlightSection-B7P3JGNL.js'), { ssr: true });
330
+ var BeforeAfterSection = dynamic(() => import('./BeforeAfterSection-6QUJOBO2.js'), { ssr: true });
331
+ var MetricsTimelineSection = dynamic(() => import('./MetricsTimelineSection-6BT5GNFV.js'), { ssr: true });
332
+ var ConversionFunnelSection = dynamic(() => import('./ConversionFunnelSection-D3GE4NKE.js'), { ssr: true });
333
+ var DetailsSection = dynamic(() => import('./DetailsSection-FB763FS7.js'), { ssr: true });
334
+ var CTASection = dynamic(() => import('./CTASection-BJA72XIL.js'), { ssr: true });
335
+ function renderSection(section, item, index) {
336
+ const key = `${section.sectionType}-${index}`;
337
+ switch (section.sectionType) {
338
+ case "portfolioHero":
339
+ return /* @__PURE__ */ jsx(
340
+ HeroSection,
341
+ {
342
+ data: section.data,
343
+ screenshots: item.hero_screenshots ?? void 0,
344
+ liveUrl: item.live_url ?? void 0
345
+ },
346
+ key
347
+ );
348
+ case "portfolioChallenges":
349
+ return /* @__PURE__ */ jsx(ChallengesSection, { data: section.data }, key);
350
+ case "portfolioStrategy":
351
+ return /* @__PURE__ */ jsx(StrategySection, { data: section.data }, key);
352
+ case "portfolioResults":
353
+ return /* @__PURE__ */ jsx(ResultsSection, { data: section.data }, key);
354
+ case "portfolioTechStack":
355
+ return /* @__PURE__ */ jsx(TechStackSection, { data: section.data }, key);
356
+ case "portfolioServices":
357
+ return /* @__PURE__ */ jsx(ServicesSection, { data: section.data }, key);
358
+ case "portfolioTestimonial":
359
+ return /* @__PURE__ */ jsx(TestimonialSection, { data: section.data }, key);
360
+ case "portfolioGallery":
361
+ return /* @__PURE__ */ jsx(GallerySection, { data: section.data }, key);
362
+ case "portfolioVideo":
363
+ return /* @__PURE__ */ jsx(VideoSection, { data: section.data }, key);
364
+ case "portfolioTeam":
365
+ return /* @__PURE__ */ jsx(TeamSection, { data: section.data }, key);
366
+ case "portfolioFeatureSpotlight":
367
+ return /* @__PURE__ */ jsx(FeatureSpotlightSection, { data: section.data }, key);
368
+ case "portfolioBeforeAfter":
369
+ return /* @__PURE__ */ jsx(BeforeAfterSection, { data: section.data }, key);
370
+ case "portfolioMetricsTimeline":
371
+ return /* @__PURE__ */ jsx(MetricsTimelineSection, { data: section.data }, key);
372
+ case "portfolioConversionFunnel":
373
+ return /* @__PURE__ */ jsx(ConversionFunnelSection, { data: section.data }, key);
374
+ case "portfolioDetails":
375
+ return /* @__PURE__ */ jsx(DetailsSection, { data: section.data }, key);
376
+ case "portfolioCTA":
377
+ return /* @__PURE__ */ jsx(CTASection, { data: section.data }, key);
378
+ case "portfolioSeo":
379
+ return null;
380
+ default:
381
+ return null;
382
+ }
383
+ }
384
+ function PortfolioPage({ item }) {
385
+ return /* @__PURE__ */ jsx("article", { className: "w-full flex flex-col", children: item.sections.map((section, index) => {
386
+ const rendered = renderSection(section, item, index);
387
+ if (!rendered) return null;
388
+ return /* @__PURE__ */ jsx("div", { className: "w-full", children: rendered }, `wrapper-${section.sectionType}-${index}`);
389
+ }) });
390
+ }
391
+
392
+ // src/types.ts
393
+ var PORTFOLIO_SECTION_TYPES = [
394
+ "portfolioHero",
395
+ "portfolioChallenges",
396
+ "portfolioStrategy",
397
+ "portfolioResults",
398
+ "portfolioTechStack",
399
+ "portfolioServices",
400
+ "portfolioTestimonial",
401
+ "portfolioGallery",
402
+ "portfolioVideo",
403
+ "portfolioTeam",
404
+ "portfolioFeatureSpotlight",
405
+ "portfolioBeforeAfter",
406
+ "portfolioMetricsTimeline",
407
+ "portfolioConversionFunnel",
408
+ "portfolioDetails",
409
+ "portfolioSeo",
410
+ "portfolioCTA"
411
+ ];
412
+
413
+ export { PORTFOLIO_SECTION_TYPES, PortfolioPage };
414
+ //# sourceMappingURL=chunk-2VNNFAG6.js.map
415
+ //# sourceMappingURL=chunk-2VNNFAG6.js.map