@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,209 @@
1
+ 'use strict';
2
+
3
+ var chunkXONXEFJY_cjs = require('./chunk-XONXEFJY.cjs');
4
+ var chunkKEOHORIH_cjs = require('./chunk-KEOHORIH.cjs');
5
+ var chunkIKBK7HYX_cjs = require('./chunk-IKBK7HYX.cjs');
6
+ var React = require('react');
7
+ var gsap = require('gsap');
8
+ var ScrollTrigger = require('gsap/ScrollTrigger');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var React__default = /*#__PURE__*/_interopDefault(React);
14
+ var gsap__default = /*#__PURE__*/_interopDefault(gsap);
15
+
16
+ function ConversionFunnelSection({ data }) {
17
+ const funnelRef = React.useRef(null);
18
+ const flowLinesRef = React.useRef(null);
19
+ React.useEffect(() => {
20
+ gsap__default.default.registerPlugin(ScrollTrigger.ScrollTrigger);
21
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
22
+ if (prefersReducedMotion) return;
23
+ const ctx = gsap__default.default.context(() => {
24
+ const stages = funnelRef.current?.querySelectorAll(".funnel-stage-fill");
25
+ if (stages && stages.length > 0) {
26
+ gsap__default.default.fromTo(
27
+ stages,
28
+ { scaleX: 0 },
29
+ {
30
+ scaleX: 1,
31
+ duration: 0.8,
32
+ stagger: 0.2,
33
+ ease: "power2.out",
34
+ transformOrigin: "left center",
35
+ scrollTrigger: {
36
+ trigger: funnelRef.current,
37
+ start: "top 70%",
38
+ toggleActions: "play none none none"
39
+ }
40
+ }
41
+ );
42
+ }
43
+ const flowLines = flowLinesRef.current?.querySelectorAll(".flow-connector");
44
+ if (flowLines && flowLines.length > 0) {
45
+ gsap__default.default.fromTo(
46
+ flowLines,
47
+ { scaleX: 0, opacity: 0 },
48
+ {
49
+ scaleX: 1,
50
+ opacity: 1,
51
+ duration: 0.5,
52
+ stagger: 0.15,
53
+ delay: 0.3,
54
+ ease: "power2.out",
55
+ transformOrigin: "left center",
56
+ scrollTrigger: {
57
+ trigger: funnelRef.current,
58
+ start: "top 70%",
59
+ toggleActions: "play none none none"
60
+ }
61
+ }
62
+ );
63
+ }
64
+ });
65
+ return () => ctx.revert();
66
+ }, [data.stages.length]);
67
+ const maxValue = Math.max(...data.stages.map((s) => s.value), 1);
68
+ return /* @__PURE__ */ jsxRuntime.jsx(
69
+ "section",
70
+ {
71
+ className: "w-full py-20 md:py-28",
72
+ style: { background: "var(--sk-bg, #0a0a0a)" },
73
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-6xl mx-auto px-6", children: [
74
+ (data.title || data.description) && /* @__PURE__ */ jsxRuntime.jsxs(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: [
75
+ data.title && /* @__PURE__ */ jsxRuntime.jsx(
76
+ "h2",
77
+ {
78
+ className: "text-3xl md:text-4xl font-bold mb-4",
79
+ style: {
80
+ color: "var(--sk-text-primary, #ffffff)",
81
+ fontFamily: "var(--sk-font-heading, inherit)"
82
+ },
83
+ children: data.title
84
+ }
85
+ ),
86
+ data.description && /* @__PURE__ */ jsxRuntime.jsx(
87
+ "p",
88
+ {
89
+ className: "text-lg mb-12 max-w-2xl",
90
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
91
+ children: data.description
92
+ }
93
+ )
94
+ ] }),
95
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: funnelRef, className: "hidden md:block", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end gap-0 relative", ref: flowLinesRef, children: data.stages.map((stage, index) => {
96
+ const widthPercent = 60 + stage.value / maxValue * 40;
97
+ const stageColor = stage.color || "var(--sk-primary, #6366f1)";
98
+ const dropOff = index > 0 ? Math.round(
99
+ (data.stages[index - 1].value - stage.value) / data.stages[index - 1].value * 100
100
+ ) : null;
101
+ return /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
102
+ dropOff !== null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center px-2 shrink-0", style: { minWidth: 48 }, children: [
103
+ /* @__PURE__ */ jsxRuntime.jsx(
104
+ "div",
105
+ {
106
+ className: "flow-connector h-0.5 w-full mb-1",
107
+ style: {
108
+ background: `linear-gradient(to right, ${data.stages[index - 1].color || "var(--sk-primary, #6366f1)"}, ${stageColor})`,
109
+ willChange: "transform"
110
+ }
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsxRuntime.jsxs(
114
+ "span",
115
+ {
116
+ className: "text-xs font-medium whitespace-nowrap",
117
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
118
+ children: [
119
+ "-",
120
+ dropOff,
121
+ "%"
122
+ ]
123
+ }
124
+ )
125
+ ] }),
126
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", style: { maxWidth: `${widthPercent}%` }, children: /* @__PURE__ */ jsxRuntime.jsx(chunkKEOHORIH_cjs.GlassCard, { padding: "md", hover: false, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden rounded-lg", children: [
127
+ /* @__PURE__ */ jsxRuntime.jsx(
128
+ "div",
129
+ {
130
+ className: "funnel-stage-fill absolute inset-0 rounded-lg opacity-15",
131
+ style: {
132
+ background: stageColor,
133
+ willChange: "transform"
134
+ }
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col items-center gap-2 py-4", children: [
138
+ stage.icon && /* @__PURE__ */ jsxRuntime.jsx("img", { src: stage.icon, alt: "", width: 24, height: 24, className: "w-6 h-6 object-contain" }),
139
+ /* @__PURE__ */ jsxRuntime.jsx(
140
+ "span",
141
+ {
142
+ className: "text-xs font-semibold uppercase tracking-wider text-center",
143
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
144
+ children: stage.label
145
+ }
146
+ ),
147
+ /* @__PURE__ */ jsxRuntime.jsx(
148
+ "div",
149
+ {
150
+ className: "text-2xl font-bold",
151
+ style: { color: stageColor },
152
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkXONXEFJY_cjs.AnimatedCounter, { value: stage.value, duration: 2 })
153
+ }
154
+ )
155
+ ] })
156
+ ] }) }) })
157
+ ] }, index);
158
+ }) }) }),
159
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden flex flex-col gap-3", children: data.stages.map((stage, index) => {
160
+ const widthPercent = 60 + stage.value / maxValue * 40;
161
+ const stageColor = stage.color || "var(--sk-primary, #6366f1)";
162
+ const dropOff = index > 0 ? Math.round(
163
+ (data.stages[index - 1].value - stage.value) / data.stages[index - 1].value * 100
164
+ ) : null;
165
+ return /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
166
+ dropOff !== null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center py-1", children: [
167
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 4v12M6 12l4 4 4-4", stroke: "var(--sk-text-tertiary, #71717a)", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
168
+ /* @__PURE__ */ jsxRuntime.jsxs(
169
+ "span",
170
+ {
171
+ className: "text-xs font-medium ml-2",
172
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
173
+ children: [
174
+ "-",
175
+ dropOff,
176
+ "% drop-off"
177
+ ]
178
+ }
179
+ )
180
+ ] }),
181
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 20, delay: index * 0.1, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: `${widthPercent}%`, marginLeft: "auto", marginRight: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(chunkKEOHORIH_cjs.GlassCard, { padding: "md", hover: false, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
182
+ stage.icon && /* @__PURE__ */ jsxRuntime.jsx("img", { src: stage.icon, alt: "", width: 24, height: 24, className: "w-6 h-6 object-contain shrink-0" }),
183
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
184
+ "span",
185
+ {
186
+ className: "text-xs font-semibold uppercase tracking-wider",
187
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
188
+ children: stage.label
189
+ }
190
+ ) }),
191
+ /* @__PURE__ */ jsxRuntime.jsx(
192
+ "div",
193
+ {
194
+ className: "text-xl font-bold",
195
+ style: { color: stageColor },
196
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkXONXEFJY_cjs.AnimatedCounter, { value: stage.value, duration: 2 })
197
+ }
198
+ )
199
+ ] }) }) }) })
200
+ ] }, index);
201
+ }) })
202
+ ] })
203
+ }
204
+ );
205
+ }
206
+
207
+ module.exports = ConversionFunnelSection;
208
+ //# sourceMappingURL=ConversionFunnelSection-AUUSJ5HQ.cjs.map
209
+ //# sourceMappingURL=ConversionFunnelSection-AUUSJ5HQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/ConversionFunnelSection.tsx"],"names":["useRef","useEffect","gsap","ScrollTrigger","jsx","jsxs","ScrollReveal","React","GlassCard","AnimatedCounter"],"mappings":"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","file":"ConversionFunnelSection-AUUSJ5HQ.cjs","sourcesContent":["'use client';\n\nimport React, { useRef, useEffect } from 'react';\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\nimport type { PortfolioConversionFunnelData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport AnimatedCounter from '../primitives/AnimatedCounter';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface ConversionFunnelSectionProps {\n data: PortfolioConversionFunnelData;\n}\n\nexport default function ConversionFunnelSection({ data }: ConversionFunnelSectionProps) {\n const funnelRef = useRef<HTMLDivElement>(null);\n const flowLinesRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n gsap.registerPlugin(ScrollTrigger);\n\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n const ctx = gsap.context(() => {\n // Fill stages left-to-right with color\n const stages = funnelRef.current?.querySelectorAll('.funnel-stage-fill');\n if (stages && stages.length > 0) {\n gsap.fromTo(\n stages,\n { scaleX: 0 },\n {\n scaleX: 1,\n duration: 0.8,\n stagger: 0.2,\n ease: 'power2.out',\n transformOrigin: 'left center',\n scrollTrigger: {\n trigger: funnelRef.current,\n start: 'top 70%',\n toggleActions: 'play none none none',\n },\n },\n );\n }\n\n // Animate flow line connectors\n const flowLines = flowLinesRef.current?.querySelectorAll('.flow-connector');\n if (flowLines && flowLines.length > 0) {\n gsap.fromTo(\n flowLines,\n { scaleX: 0, opacity: 0 },\n {\n scaleX: 1,\n opacity: 1,\n duration: 0.5,\n stagger: 0.15,\n delay: 0.3,\n ease: 'power2.out',\n transformOrigin: 'left center',\n scrollTrigger: {\n trigger: funnelRef.current,\n start: 'top 70%',\n toggleActions: 'play none none none',\n },\n },\n );\n }\n });\n\n return () => ctx.revert();\n }, [data.stages.length]);\n\n const maxValue = Math.max(...data.stages.map((s) => s.value), 1);\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-6xl mx-auto px-6\">\n {(data.title || data.description) && (\n <ScrollReveal y={30}>\n {data.title && (\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 )}\n {data.description && (\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.description}\n </p>\n )}\n </ScrollReveal>\n )}\n\n {/* Desktop: horizontal funnel */}\n <div ref={funnelRef} className=\"hidden md:block\">\n <div className=\"flex items-end gap-0 relative\" ref={flowLinesRef}>\n {data.stages.map((stage, index) => {\n const widthPercent = 60 + (stage.value / maxValue) * 40;\n const stageColor = stage.color || 'var(--sk-primary, #6366f1)';\n const dropOff =\n index > 0\n ? Math.round(\n ((data.stages[index - 1].value - stage.value) /\n data.stages[index - 1].value) *\n 100,\n )\n : null;\n\n return (\n <React.Fragment key={index}>\n {/* Drop-off connector */}\n {dropOff !== null && (\n <div className=\"flex flex-col items-center justify-center px-2 shrink-0\" style={{ minWidth: 48 }}>\n <div\n className=\"flow-connector h-0.5 w-full mb-1\"\n style={{\n background: `linear-gradient(to right, ${data.stages[index - 1].color || 'var(--sk-primary, #6366f1)'}, ${stageColor})`,\n willChange: 'transform',\n }}\n />\n <span\n className=\"text-xs font-medium whitespace-nowrap\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n -{dropOff}%\n </span>\n </div>\n )}\n\n {/* Stage card */}\n <div className=\"flex-1\" style={{ maxWidth: `${widthPercent}%` }}>\n <GlassCard padding=\"md\" hover={false}>\n <div className=\"relative overflow-hidden rounded-lg\">\n {/* Animated fill bar */}\n <div\n className=\"funnel-stage-fill absolute inset-0 rounded-lg opacity-15\"\n style={{\n background: stageColor,\n willChange: 'transform',\n }}\n />\n <div className=\"relative flex flex-col items-center gap-2 py-4\">\n {/* Icon */}\n {stage.icon && (\n <img src={stage.icon} alt=\"\" width={24} height={24} className=\"w-6 h-6 object-contain\" />\n )}\n <span\n className=\"text-xs font-semibold uppercase tracking-wider text-center\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {stage.label}\n </span>\n <div\n className=\"text-2xl font-bold\"\n style={{ color: stageColor }}\n >\n <AnimatedCounter value={stage.value} duration={2} />\n </div>\n </div>\n </div>\n </GlassCard>\n </div>\n </React.Fragment>\n );\n })}\n </div>\n </div>\n\n {/* Mobile: vertical funnel */}\n <div className=\"md:hidden flex flex-col gap-3\">\n {data.stages.map((stage, index) => {\n const widthPercent = 60 + (stage.value / maxValue) * 40;\n const stageColor = stage.color || 'var(--sk-primary, #6366f1)';\n const dropOff =\n index > 0\n ? Math.round(\n ((data.stages[index - 1].value - stage.value) /\n data.stages[index - 1].value) *\n 100,\n )\n : null;\n\n return (\n <React.Fragment key={index}>\n {dropOff !== null && (\n <div className=\"flex items-center justify-center py-1\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M10 4v12M6 12l4 4 4-4\" stroke=\"var(--sk-text-tertiary, #71717a)\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n <span\n className=\"text-xs font-medium ml-2\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n -{dropOff}% drop-off\n </span>\n </div>\n )}\n <ScrollReveal y={20} delay={index * 0.1}>\n <div style={{ width: `${widthPercent}%`, marginLeft: 'auto', marginRight: 'auto' }}>\n <GlassCard padding=\"md\" hover={false}>\n <div className=\"flex items-center gap-4\">\n {stage.icon && (\n <img src={stage.icon} alt=\"\" width={24} height={24} className=\"w-6 h-6 object-contain shrink-0\" />\n )}\n <div className=\"flex-1\">\n <span\n className=\"text-xs font-semibold uppercase tracking-wider\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {stage.label}\n </span>\n </div>\n <div\n className=\"text-xl font-bold\"\n style={{ color: stageColor }}\n >\n <AnimatedCounter value={stage.value} duration={2} />\n </div>\n </div>\n </GlassCard>\n </div>\n </ScrollReveal>\n </React.Fragment>\n );\n })}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,203 @@
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 React, { useRef, useEffect } from 'react';
6
+ import gsap from 'gsap';
7
+ import { ScrollTrigger } from 'gsap/ScrollTrigger';
8
+ import { jsx, jsxs } from 'react/jsx-runtime';
9
+
10
+ function ConversionFunnelSection({ data }) {
11
+ const funnelRef = useRef(null);
12
+ const flowLinesRef = useRef(null);
13
+ useEffect(() => {
14
+ gsap.registerPlugin(ScrollTrigger);
15
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
16
+ if (prefersReducedMotion) return;
17
+ const ctx = gsap.context(() => {
18
+ const stages = funnelRef.current?.querySelectorAll(".funnel-stage-fill");
19
+ if (stages && stages.length > 0) {
20
+ gsap.fromTo(
21
+ stages,
22
+ { scaleX: 0 },
23
+ {
24
+ scaleX: 1,
25
+ duration: 0.8,
26
+ stagger: 0.2,
27
+ ease: "power2.out",
28
+ transformOrigin: "left center",
29
+ scrollTrigger: {
30
+ trigger: funnelRef.current,
31
+ start: "top 70%",
32
+ toggleActions: "play none none none"
33
+ }
34
+ }
35
+ );
36
+ }
37
+ const flowLines = flowLinesRef.current?.querySelectorAll(".flow-connector");
38
+ if (flowLines && flowLines.length > 0) {
39
+ gsap.fromTo(
40
+ flowLines,
41
+ { scaleX: 0, opacity: 0 },
42
+ {
43
+ scaleX: 1,
44
+ opacity: 1,
45
+ duration: 0.5,
46
+ stagger: 0.15,
47
+ delay: 0.3,
48
+ ease: "power2.out",
49
+ transformOrigin: "left center",
50
+ scrollTrigger: {
51
+ trigger: funnelRef.current,
52
+ start: "top 70%",
53
+ toggleActions: "play none none none"
54
+ }
55
+ }
56
+ );
57
+ }
58
+ });
59
+ return () => ctx.revert();
60
+ }, [data.stages.length]);
61
+ const maxValue = Math.max(...data.stages.map((s) => s.value), 1);
62
+ return /* @__PURE__ */ jsx(
63
+ "section",
64
+ {
65
+ className: "w-full py-20 md:py-28",
66
+ style: { background: "var(--sk-bg, #0a0a0a)" },
67
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-6xl mx-auto px-6", children: [
68
+ (data.title || data.description) && /* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
69
+ data.title && /* @__PURE__ */ jsx(
70
+ "h2",
71
+ {
72
+ className: "text-3xl md:text-4xl font-bold mb-4",
73
+ style: {
74
+ color: "var(--sk-text-primary, #ffffff)",
75
+ fontFamily: "var(--sk-font-heading, inherit)"
76
+ },
77
+ children: data.title
78
+ }
79
+ ),
80
+ data.description && /* @__PURE__ */ jsx(
81
+ "p",
82
+ {
83
+ className: "text-lg mb-12 max-w-2xl",
84
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
85
+ children: data.description
86
+ }
87
+ )
88
+ ] }),
89
+ /* @__PURE__ */ jsx("div", { ref: funnelRef, className: "hidden md:block", children: /* @__PURE__ */ jsx("div", { className: "flex items-end gap-0 relative", ref: flowLinesRef, children: data.stages.map((stage, index) => {
90
+ const widthPercent = 60 + stage.value / maxValue * 40;
91
+ const stageColor = stage.color || "var(--sk-primary, #6366f1)";
92
+ const dropOff = index > 0 ? Math.round(
93
+ (data.stages[index - 1].value - stage.value) / data.stages[index - 1].value * 100
94
+ ) : null;
95
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
96
+ dropOff !== null && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center px-2 shrink-0", style: { minWidth: 48 }, children: [
97
+ /* @__PURE__ */ jsx(
98
+ "div",
99
+ {
100
+ className: "flow-connector h-0.5 w-full mb-1",
101
+ style: {
102
+ background: `linear-gradient(to right, ${data.stages[index - 1].color || "var(--sk-primary, #6366f1)"}, ${stageColor})`,
103
+ willChange: "transform"
104
+ }
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsxs(
108
+ "span",
109
+ {
110
+ className: "text-xs font-medium whitespace-nowrap",
111
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
112
+ children: [
113
+ "-",
114
+ dropOff,
115
+ "%"
116
+ ]
117
+ }
118
+ )
119
+ ] }),
120
+ /* @__PURE__ */ jsx("div", { className: "flex-1", style: { maxWidth: `${widthPercent}%` }, children: /* @__PURE__ */ jsx(GlassCard, { padding: "md", hover: false, children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-lg", children: [
121
+ /* @__PURE__ */ jsx(
122
+ "div",
123
+ {
124
+ className: "funnel-stage-fill absolute inset-0 rounded-lg opacity-15",
125
+ style: {
126
+ background: stageColor,
127
+ willChange: "transform"
128
+ }
129
+ }
130
+ ),
131
+ /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col items-center gap-2 py-4", children: [
132
+ stage.icon && /* @__PURE__ */ jsx("img", { src: stage.icon, alt: "", width: 24, height: 24, className: "w-6 h-6 object-contain" }),
133
+ /* @__PURE__ */ jsx(
134
+ "span",
135
+ {
136
+ className: "text-xs font-semibold uppercase tracking-wider text-center",
137
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
138
+ children: stage.label
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsx(
142
+ "div",
143
+ {
144
+ className: "text-2xl font-bold",
145
+ style: { color: stageColor },
146
+ children: /* @__PURE__ */ jsx(AnimatedCounter, { value: stage.value, duration: 2 })
147
+ }
148
+ )
149
+ ] })
150
+ ] }) }) })
151
+ ] }, index);
152
+ }) }) }),
153
+ /* @__PURE__ */ jsx("div", { className: "md:hidden flex flex-col gap-3", children: data.stages.map((stage, index) => {
154
+ const widthPercent = 60 + stage.value / maxValue * 40;
155
+ const stageColor = stage.color || "var(--sk-primary, #6366f1)";
156
+ const dropOff = index > 0 ? Math.round(
157
+ (data.stages[index - 1].value - stage.value) / data.stages[index - 1].value * 100
158
+ ) : null;
159
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
160
+ dropOff !== null && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-1", children: [
161
+ /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M10 4v12M6 12l4 4 4-4", stroke: "var(--sk-text-tertiary, #71717a)", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
162
+ /* @__PURE__ */ jsxs(
163
+ "span",
164
+ {
165
+ className: "text-xs font-medium ml-2",
166
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
167
+ children: [
168
+ "-",
169
+ dropOff,
170
+ "% drop-off"
171
+ ]
172
+ }
173
+ )
174
+ ] }),
175
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: index * 0.1, children: /* @__PURE__ */ jsx("div", { style: { width: `${widthPercent}%`, marginLeft: "auto", marginRight: "auto" }, children: /* @__PURE__ */ jsx(GlassCard, { padding: "md", hover: false, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
176
+ stage.icon && /* @__PURE__ */ jsx("img", { src: stage.icon, alt: "", width: 24, height: 24, className: "w-6 h-6 object-contain shrink-0" }),
177
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
178
+ "span",
179
+ {
180
+ className: "text-xs font-semibold uppercase tracking-wider",
181
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
182
+ children: stage.label
183
+ }
184
+ ) }),
185
+ /* @__PURE__ */ jsx(
186
+ "div",
187
+ {
188
+ className: "text-xl font-bold",
189
+ style: { color: stageColor },
190
+ children: /* @__PURE__ */ jsx(AnimatedCounter, { value: stage.value, duration: 2 })
191
+ }
192
+ )
193
+ ] }) }) }) })
194
+ ] }, index);
195
+ }) })
196
+ ] })
197
+ }
198
+ );
199
+ }
200
+
201
+ export { ConversionFunnelSection as default };
202
+ //# sourceMappingURL=ConversionFunnelSection-D3GE4NKE.js.map
203
+ //# sourceMappingURL=ConversionFunnelSection-D3GE4NKE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/ConversionFunnelSection.tsx"],"names":[],"mappings":"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","file":"ConversionFunnelSection-D3GE4NKE.js","sourcesContent":["'use client';\n\nimport React, { useRef, useEffect } from 'react';\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\nimport type { PortfolioConversionFunnelData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport AnimatedCounter from '../primitives/AnimatedCounter';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface ConversionFunnelSectionProps {\n data: PortfolioConversionFunnelData;\n}\n\nexport default function ConversionFunnelSection({ data }: ConversionFunnelSectionProps) {\n const funnelRef = useRef<HTMLDivElement>(null);\n const flowLinesRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n gsap.registerPlugin(ScrollTrigger);\n\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n const ctx = gsap.context(() => {\n // Fill stages left-to-right with color\n const stages = funnelRef.current?.querySelectorAll('.funnel-stage-fill');\n if (stages && stages.length > 0) {\n gsap.fromTo(\n stages,\n { scaleX: 0 },\n {\n scaleX: 1,\n duration: 0.8,\n stagger: 0.2,\n ease: 'power2.out',\n transformOrigin: 'left center',\n scrollTrigger: {\n trigger: funnelRef.current,\n start: 'top 70%',\n toggleActions: 'play none none none',\n },\n },\n );\n }\n\n // Animate flow line connectors\n const flowLines = flowLinesRef.current?.querySelectorAll('.flow-connector');\n if (flowLines && flowLines.length > 0) {\n gsap.fromTo(\n flowLines,\n { scaleX: 0, opacity: 0 },\n {\n scaleX: 1,\n opacity: 1,\n duration: 0.5,\n stagger: 0.15,\n delay: 0.3,\n ease: 'power2.out',\n transformOrigin: 'left center',\n scrollTrigger: {\n trigger: funnelRef.current,\n start: 'top 70%',\n toggleActions: 'play none none none',\n },\n },\n );\n }\n });\n\n return () => ctx.revert();\n }, [data.stages.length]);\n\n const maxValue = Math.max(...data.stages.map((s) => s.value), 1);\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-6xl mx-auto px-6\">\n {(data.title || data.description) && (\n <ScrollReveal y={30}>\n {data.title && (\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 )}\n {data.description && (\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.description}\n </p>\n )}\n </ScrollReveal>\n )}\n\n {/* Desktop: horizontal funnel */}\n <div ref={funnelRef} className=\"hidden md:block\">\n <div className=\"flex items-end gap-0 relative\" ref={flowLinesRef}>\n {data.stages.map((stage, index) => {\n const widthPercent = 60 + (stage.value / maxValue) * 40;\n const stageColor = stage.color || 'var(--sk-primary, #6366f1)';\n const dropOff =\n index > 0\n ? Math.round(\n ((data.stages[index - 1].value - stage.value) /\n data.stages[index - 1].value) *\n 100,\n )\n : null;\n\n return (\n <React.Fragment key={index}>\n {/* Drop-off connector */}\n {dropOff !== null && (\n <div className=\"flex flex-col items-center justify-center px-2 shrink-0\" style={{ minWidth: 48 }}>\n <div\n className=\"flow-connector h-0.5 w-full mb-1\"\n style={{\n background: `linear-gradient(to right, ${data.stages[index - 1].color || 'var(--sk-primary, #6366f1)'}, ${stageColor})`,\n willChange: 'transform',\n }}\n />\n <span\n className=\"text-xs font-medium whitespace-nowrap\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n -{dropOff}%\n </span>\n </div>\n )}\n\n {/* Stage card */}\n <div className=\"flex-1\" style={{ maxWidth: `${widthPercent}%` }}>\n <GlassCard padding=\"md\" hover={false}>\n <div className=\"relative overflow-hidden rounded-lg\">\n {/* Animated fill bar */}\n <div\n className=\"funnel-stage-fill absolute inset-0 rounded-lg opacity-15\"\n style={{\n background: stageColor,\n willChange: 'transform',\n }}\n />\n <div className=\"relative flex flex-col items-center gap-2 py-4\">\n {/* Icon */}\n {stage.icon && (\n <img src={stage.icon} alt=\"\" width={24} height={24} className=\"w-6 h-6 object-contain\" />\n )}\n <span\n className=\"text-xs font-semibold uppercase tracking-wider text-center\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {stage.label}\n </span>\n <div\n className=\"text-2xl font-bold\"\n style={{ color: stageColor }}\n >\n <AnimatedCounter value={stage.value} duration={2} />\n </div>\n </div>\n </div>\n </GlassCard>\n </div>\n </React.Fragment>\n );\n })}\n </div>\n </div>\n\n {/* Mobile: vertical funnel */}\n <div className=\"md:hidden flex flex-col gap-3\">\n {data.stages.map((stage, index) => {\n const widthPercent = 60 + (stage.value / maxValue) * 40;\n const stageColor = stage.color || 'var(--sk-primary, #6366f1)';\n const dropOff =\n index > 0\n ? Math.round(\n ((data.stages[index - 1].value - stage.value) /\n data.stages[index - 1].value) *\n 100,\n )\n : null;\n\n return (\n <React.Fragment key={index}>\n {dropOff !== null && (\n <div className=\"flex items-center justify-center py-1\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M10 4v12M6 12l4 4 4-4\" stroke=\"var(--sk-text-tertiary, #71717a)\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n <span\n className=\"text-xs font-medium ml-2\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n -{dropOff}% drop-off\n </span>\n </div>\n )}\n <ScrollReveal y={20} delay={index * 0.1}>\n <div style={{ width: `${widthPercent}%`, marginLeft: 'auto', marginRight: 'auto' }}>\n <GlassCard padding=\"md\" hover={false}>\n <div className=\"flex items-center gap-4\">\n {stage.icon && (\n <img src={stage.icon} alt=\"\" width={24} height={24} className=\"w-6 h-6 object-contain shrink-0\" />\n )}\n <div className=\"flex-1\">\n <span\n className=\"text-xs font-semibold uppercase tracking-wider\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {stage.label}\n </span>\n </div>\n <div\n className=\"text-xl font-bold\"\n style={{ color: stageColor }}\n >\n <AnimatedCounter value={stage.value} duration={2} />\n </div>\n </div>\n </GlassCard>\n </div>\n </ScrollReveal>\n </React.Fragment>\n );\n })}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,135 @@
1
+ import { GlassCard } from './chunk-YB4B3OMC.js';
2
+ import { ScrollReveal } from './chunk-7CFFAKDM.js';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ function DetailsSection({ data }) {
6
+ const rows = [];
7
+ if (data.industry) {
8
+ rows.push({
9
+ label: "Industry",
10
+ value: data.industry,
11
+ icon: /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M3 16.5h12M4.5 1.5h9l1.5 6H3l1.5-6zM6 7.5v9M12 7.5v9M9 7.5v9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
12
+ });
13
+ }
14
+ if (data.location) {
15
+ rows.push({
16
+ label: "Location",
17
+ value: data.location,
18
+ icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
19
+ /* @__PURE__ */ jsx("path", { d: "M15 7.5c0 4.5-6 9-6 9s-6-4.5-6-9a6 6 0 1112 0z", stroke: "currentColor", strokeWidth: "1.5" }),
20
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "7.5", r: "2", stroke: "currentColor", strokeWidth: "1.5" })
21
+ ] })
22
+ });
23
+ }
24
+ if (data.website) {
25
+ rows.push({
26
+ label: "Website",
27
+ value: data.website,
28
+ icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
29
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
30
+ /* @__PURE__ */ jsx("path", { d: "M1.5 9h15M9 1.5a11.25 11.25 0 013 7.5 11.25 11.25 0 01-3 7.5 11.25 11.25 0 01-3-7.5 11.25 11.25 0 013-7.5z", stroke: "currentColor", strokeWidth: "1.5" })
31
+ ] })
32
+ });
33
+ }
34
+ if (data.timeline) {
35
+ rows.push({
36
+ label: "Timeline",
37
+ value: data.timeline,
38
+ icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
39
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
40
+ /* @__PURE__ */ jsx("path", { d: "M9 4.5V9l3 1.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
41
+ ] })
42
+ });
43
+ }
44
+ if (data.launchDate) {
45
+ rows.push({
46
+ label: "Launch Date",
47
+ value: data.launchDate,
48
+ icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
49
+ /* @__PURE__ */ jsx("rect", { x: "2.25", y: "3", width: "13.5", height: "12.75", rx: "2", stroke: "currentColor", strokeWidth: "1.5" }),
50
+ /* @__PURE__ */ jsx("path", { d: "M12 1.5v3M6 1.5v3M2.25 7.5h13.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
51
+ ] })
52
+ });
53
+ }
54
+ if (data.budgetRange) {
55
+ rows.push({
56
+ label: "Budget Range",
57
+ value: data.budgetRange,
58
+ icon: /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M9 1.5v15M13.5 4.5H6.75a2.625 2.625 0 000 5.25h4.5a2.625 2.625 0 010 5.25H4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
59
+ });
60
+ }
61
+ if (rows.length === 0) return null;
62
+ return /* @__PURE__ */ jsx(
63
+ "section",
64
+ {
65
+ className: "w-full py-20 md:py-28",
66
+ style: { background: "var(--sk-bg, #0a0a0a)" },
67
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-4xl mx-auto px-6", children: [
68
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 30, children: /* @__PURE__ */ jsx(
69
+ "h2",
70
+ {
71
+ className: "text-3xl md:text-4xl font-bold mb-8",
72
+ style: {
73
+ color: "var(--sk-text-primary, #ffffff)",
74
+ fontFamily: "var(--sk-font-heading, inherit)"
75
+ },
76
+ children: "Project Details"
77
+ }
78
+ ) }),
79
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 40, delay: 0.1, children: /* @__PURE__ */ jsx(GlassCard, { padding: "lg", hover: false, children: /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y", style: { borderColor: "var(--sk-border, rgba(255,255,255,0.1))" }, children: rows.map((row, index) => /* @__PURE__ */ jsxs(
80
+ "div",
81
+ {
82
+ className: "flex items-center gap-4 py-4 first:pt-0 last:pb-0",
83
+ style: {
84
+ borderColor: "var(--sk-border, rgba(255,255,255,0.1))"
85
+ },
86
+ children: [
87
+ /* @__PURE__ */ jsx(
88
+ "span",
89
+ {
90
+ className: "flex items-center justify-center w-9 h-9 rounded-lg shrink-0",
91
+ style: {
92
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 12%, transparent)",
93
+ color: "var(--sk-primary, #6366f1)"
94
+ },
95
+ children: row.icon
96
+ }
97
+ ),
98
+ /* @__PURE__ */ jsx(
99
+ "span",
100
+ {
101
+ className: "text-sm font-medium w-32 shrink-0",
102
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
103
+ children: row.label
104
+ }
105
+ ),
106
+ row.label === "Website" ? /* @__PURE__ */ jsx(
107
+ "a",
108
+ {
109
+ href: row.value.startsWith("http") ? row.value : `https://${row.value}`,
110
+ target: "_blank",
111
+ rel: "noopener noreferrer",
112
+ className: "text-sm font-medium hover:underline",
113
+ style: { color: "var(--sk-primary, #6366f1)" },
114
+ children: row.value
115
+ }
116
+ ) : /* @__PURE__ */ jsx(
117
+ "span",
118
+ {
119
+ className: "text-sm font-medium",
120
+ style: { color: "var(--sk-text-primary, #ffffff)" },
121
+ children: row.value
122
+ }
123
+ )
124
+ ]
125
+ },
126
+ index
127
+ )) }) }) })
128
+ ] })
129
+ }
130
+ );
131
+ }
132
+
133
+ export { DetailsSection as default };
134
+ //# sourceMappingURL=DetailsSection-FB763FS7.js.map
135
+ //# sourceMappingURL=DetailsSection-FB763FS7.js.map