@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,176 @@
1
+ 'use client';
2
+ import { GlassCard } from './chunk-YB4B3OMC.js';
3
+ import { ScrollReveal } from './chunk-7CFFAKDM.js';
4
+ import { useRef, useState, useEffect, useCallback } from 'react';
5
+ import gsap from 'gsap';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+
8
+ function BeforeAfterSection({ data }) {
9
+ const containerRef = useRef(null);
10
+ const sliderRef = useRef(null);
11
+ const [position, setPosition] = useState(data.defaultPosition ?? 50);
12
+ const isDragging = useRef(false);
13
+ const beforeUrl = data.before?.asset?._ref || "";
14
+ const afterUrl = data.after?.asset?._ref || "";
15
+ useEffect(() => {
16
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
17
+ if (prefersReducedMotion || !sliderRef.current) return;
18
+ gsap.fromTo(
19
+ sliderRef.current,
20
+ { opacity: 0, scale: 0.8 },
21
+ { opacity: 1, scale: 1, duration: 0.6, delay: 0.5, ease: "back.out(2)" }
22
+ );
23
+ }, []);
24
+ const updatePosition = useCallback((clientX) => {
25
+ const container = containerRef.current;
26
+ if (!container) return;
27
+ const rect = container.getBoundingClientRect();
28
+ const x = clientX - rect.left;
29
+ const percent = Math.max(0, Math.min(100, x / rect.width * 100));
30
+ setPosition(percent);
31
+ }, []);
32
+ const handlePointerDown = useCallback(
33
+ (e) => {
34
+ isDragging.current = true;
35
+ e.target.setPointerCapture(e.pointerId);
36
+ updatePosition(e.clientX);
37
+ },
38
+ [updatePosition]
39
+ );
40
+ const handlePointerMove = useCallback(
41
+ (e) => {
42
+ if (!isDragging.current) return;
43
+ updatePosition(e.clientX);
44
+ },
45
+ [updatePosition]
46
+ );
47
+ const handlePointerUp = useCallback(() => {
48
+ isDragging.current = false;
49
+ }, []);
50
+ return /* @__PURE__ */ jsx(
51
+ "section",
52
+ {
53
+ className: "w-full py-20 md:py-28",
54
+ style: { background: "var(--sk-bg, #0a0a0a)" },
55
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
56
+ (data.title || data.description) && /* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
57
+ data.title && /* @__PURE__ */ jsx(
58
+ "h2",
59
+ {
60
+ className: "text-3xl md:text-4xl font-bold mb-4",
61
+ style: {
62
+ color: "var(--sk-text-primary, #ffffff)",
63
+ fontFamily: "var(--sk-font-heading, inherit)"
64
+ },
65
+ children: data.title
66
+ }
67
+ ),
68
+ data.description && /* @__PURE__ */ jsx(
69
+ "p",
70
+ {
71
+ className: "text-lg mb-12 max-w-2xl",
72
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
73
+ children: data.description
74
+ }
75
+ )
76
+ ] }),
77
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 40, children: /* @__PURE__ */ jsx(GlassCard, { padding: "sm", hover: false, children: /* @__PURE__ */ jsxs(
78
+ "div",
79
+ {
80
+ ref: containerRef,
81
+ className: "relative w-full overflow-hidden rounded-xl cursor-col-resize select-none",
82
+ style: { aspectRatio: "16/10" },
83
+ onPointerDown: handlePointerDown,
84
+ onPointerMove: handlePointerMove,
85
+ onPointerUp: handlePointerUp,
86
+ onPointerCancel: handlePointerUp,
87
+ children: [
88
+ /* @__PURE__ */ jsx(
89
+ "img",
90
+ {
91
+ src: afterUrl,
92
+ alt: "After",
93
+ className: "absolute inset-0 w-full h-full object-cover",
94
+ draggable: false
95
+ }
96
+ ),
97
+ /* @__PURE__ */ jsx(
98
+ "div",
99
+ {
100
+ className: "absolute inset-0 overflow-hidden",
101
+ style: { width: `${position}%` },
102
+ children: /* @__PURE__ */ jsx(
103
+ "img",
104
+ {
105
+ src: beforeUrl,
106
+ alt: "Before",
107
+ className: "absolute inset-0 w-full h-full object-cover",
108
+ style: { minWidth: containerRef.current?.offsetWidth || "100%" },
109
+ draggable: false
110
+ }
111
+ )
112
+ }
113
+ ),
114
+ /* @__PURE__ */ jsx(
115
+ "div",
116
+ {
117
+ className: "absolute top-0 bottom-0 w-0.5",
118
+ style: {
119
+ left: `${position}%`,
120
+ transform: "translateX(-50%)",
121
+ background: "#ffffff",
122
+ boxShadow: "0 0 8px rgba(0,0,0,0.5)"
123
+ }
124
+ }
125
+ ),
126
+ /* @__PURE__ */ jsx(
127
+ "div",
128
+ {
129
+ ref: sliderRef,
130
+ className: "absolute top-1/2 flex items-center justify-center w-10 h-10 rounded-full",
131
+ style: {
132
+ left: `${position}%`,
133
+ transform: "translate(-50%, -50%)",
134
+ background: "var(--sk-primary, #6366f1)",
135
+ boxShadow: "0 4px 16px rgba(0,0,0,0.3)",
136
+ border: "3px solid #ffffff",
137
+ zIndex: 5
138
+ },
139
+ children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M5 3l-4 5 4 5M11 3l4 5-4 5", stroke: "#ffffff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
140
+ }
141
+ ),
142
+ /* @__PURE__ */ jsx(
143
+ "span",
144
+ {
145
+ className: "absolute top-4 left-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider",
146
+ style: {
147
+ background: "rgba(0,0,0,0.6)",
148
+ color: "#ffffff",
149
+ backdropFilter: "blur(4px)"
150
+ },
151
+ children: "Before"
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx(
155
+ "span",
156
+ {
157
+ className: "absolute top-4 right-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider",
158
+ style: {
159
+ background: "rgba(0,0,0,0.6)",
160
+ color: "#ffffff",
161
+ backdropFilter: "blur(4px)"
162
+ },
163
+ children: "After"
164
+ }
165
+ )
166
+ ]
167
+ }
168
+ ) }) })
169
+ ] })
170
+ }
171
+ );
172
+ }
173
+
174
+ export { BeforeAfterSection as default };
175
+ //# sourceMappingURL=BeforeAfterSection-6QUJOBO2.js.map
176
+ //# sourceMappingURL=BeforeAfterSection-6QUJOBO2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/BeforeAfterSection.tsx"],"names":[],"mappings":"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","file":"BeforeAfterSection-6QUJOBO2.js","sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect } from 'react';\nimport gsap from 'gsap';\nimport type { PortfolioBeforeAfterData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface BeforeAfterSectionProps {\n data: PortfolioBeforeAfterData;\n}\n\nexport default function BeforeAfterSection({ data }: BeforeAfterSectionProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState(data.defaultPosition ?? 50);\n const isDragging = useRef(false);\n\n const beforeUrl = data.before?.asset?._ref || '';\n const afterUrl = data.after?.asset?._ref || '';\n\n // Animate slider handle entrance\n useEffect(() => {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion || !sliderRef.current) return;\n\n gsap.fromTo(\n sliderRef.current,\n { opacity: 0, scale: 0.8 },\n { opacity: 1, scale: 1, duration: 0.6, delay: 0.5, ease: 'back.out(2)' },\n );\n }, []);\n\n const updatePosition = useCallback((clientX: number) => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const x = clientX - rect.left;\n const percent = Math.max(0, Math.min(100, (x / rect.width) * 100));\n setPosition(percent);\n }, []);\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n isDragging.current = true;\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (!isDragging.current) return;\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerUp = useCallback(() => {\n isDragging.current = false;\n }, []);\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 {(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 <ScrollReveal y={40}>\n <GlassCard padding=\"sm\" hover={false}>\n <div\n ref={containerRef}\n className=\"relative w-full overflow-hidden rounded-xl cursor-col-resize select-none\"\n style={{ aspectRatio: '16/10' }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {/* After image (full background) */}\n <img\n src={afterUrl}\n alt=\"After\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n draggable={false}\n />\n\n {/* Before image (clipped) */}\n <div\n className=\"absolute inset-0 overflow-hidden\"\n style={{ width: `${position}%` }}\n >\n <img\n src={beforeUrl}\n alt=\"Before\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n style={{ minWidth: containerRef.current?.offsetWidth || '100%' }}\n draggable={false}\n />\n </div>\n\n {/* Slider line */}\n <div\n className=\"absolute top-0 bottom-0 w-0.5\"\n style={{\n left: `${position}%`,\n transform: 'translateX(-50%)',\n background: '#ffffff',\n boxShadow: '0 0 8px rgba(0,0,0,0.5)',\n }}\n />\n\n {/* Slider handle */}\n <div\n ref={sliderRef}\n className=\"absolute top-1/2 flex items-center justify-center w-10 h-10 rounded-full\"\n style={{\n left: `${position}%`,\n transform: 'translate(-50%, -50%)',\n background: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 4px 16px rgba(0,0,0,0.3)',\n border: '3px solid #ffffff',\n zIndex: 5,\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 3l-4 5 4 5M11 3l4 5-4 5\" stroke=\"#ffffff\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n\n {/* Before / After labels */}\n <span\n className=\"absolute top-4 left-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n Before\n </span>\n <span\n className=\"absolute top-4 right-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n After\n </span>\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,181 @@
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 gsap = require('gsap');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var gsap__default = /*#__PURE__*/_interopDefault(gsap);
12
+
13
+ function BeforeAfterSection({ data }) {
14
+ const containerRef = react.useRef(null);
15
+ const sliderRef = react.useRef(null);
16
+ const [position, setPosition] = react.useState(data.defaultPosition ?? 50);
17
+ const isDragging = react.useRef(false);
18
+ const beforeUrl = data.before?.asset?._ref || "";
19
+ const afterUrl = data.after?.asset?._ref || "";
20
+ react.useEffect(() => {
21
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
22
+ if (prefersReducedMotion || !sliderRef.current) return;
23
+ gsap__default.default.fromTo(
24
+ sliderRef.current,
25
+ { opacity: 0, scale: 0.8 },
26
+ { opacity: 1, scale: 1, duration: 0.6, delay: 0.5, ease: "back.out(2)" }
27
+ );
28
+ }, []);
29
+ const updatePosition = react.useCallback((clientX) => {
30
+ const container = containerRef.current;
31
+ if (!container) return;
32
+ const rect = container.getBoundingClientRect();
33
+ const x = clientX - rect.left;
34
+ const percent = Math.max(0, Math.min(100, x / rect.width * 100));
35
+ setPosition(percent);
36
+ }, []);
37
+ const handlePointerDown = react.useCallback(
38
+ (e) => {
39
+ isDragging.current = true;
40
+ e.target.setPointerCapture(e.pointerId);
41
+ updatePosition(e.clientX);
42
+ },
43
+ [updatePosition]
44
+ );
45
+ const handlePointerMove = react.useCallback(
46
+ (e) => {
47
+ if (!isDragging.current) return;
48
+ updatePosition(e.clientX);
49
+ },
50
+ [updatePosition]
51
+ );
52
+ const handlePointerUp = react.useCallback(() => {
53
+ isDragging.current = false;
54
+ }, []);
55
+ return /* @__PURE__ */ jsxRuntime.jsx(
56
+ "section",
57
+ {
58
+ className: "w-full py-20 md:py-28",
59
+ style: { background: "var(--sk-bg, #0a0a0a)" },
60
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
61
+ (data.title || data.description) && /* @__PURE__ */ jsxRuntime.jsxs(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: [
62
+ data.title && /* @__PURE__ */ jsxRuntime.jsx(
63
+ "h2",
64
+ {
65
+ className: "text-3xl md:text-4xl font-bold mb-4",
66
+ style: {
67
+ color: "var(--sk-text-primary, #ffffff)",
68
+ fontFamily: "var(--sk-font-heading, inherit)"
69
+ },
70
+ children: data.title
71
+ }
72
+ ),
73
+ data.description && /* @__PURE__ */ jsxRuntime.jsx(
74
+ "p",
75
+ {
76
+ className: "text-lg mb-12 max-w-2xl",
77
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
78
+ children: data.description
79
+ }
80
+ )
81
+ ] }),
82
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 40, children: /* @__PURE__ */ jsxRuntime.jsx(chunkKEOHORIH_cjs.GlassCard, { padding: "sm", hover: false, children: /* @__PURE__ */ jsxRuntime.jsxs(
83
+ "div",
84
+ {
85
+ ref: containerRef,
86
+ className: "relative w-full overflow-hidden rounded-xl cursor-col-resize select-none",
87
+ style: { aspectRatio: "16/10" },
88
+ onPointerDown: handlePointerDown,
89
+ onPointerMove: handlePointerMove,
90
+ onPointerUp: handlePointerUp,
91
+ onPointerCancel: handlePointerUp,
92
+ children: [
93
+ /* @__PURE__ */ jsxRuntime.jsx(
94
+ "img",
95
+ {
96
+ src: afterUrl,
97
+ alt: "After",
98
+ className: "absolute inset-0 w-full h-full object-cover",
99
+ draggable: false
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsxRuntime.jsx(
103
+ "div",
104
+ {
105
+ className: "absolute inset-0 overflow-hidden",
106
+ style: { width: `${position}%` },
107
+ children: /* @__PURE__ */ jsxRuntime.jsx(
108
+ "img",
109
+ {
110
+ src: beforeUrl,
111
+ alt: "Before",
112
+ className: "absolute inset-0 w-full h-full object-cover",
113
+ style: { minWidth: containerRef.current?.offsetWidth || "100%" },
114
+ draggable: false
115
+ }
116
+ )
117
+ }
118
+ ),
119
+ /* @__PURE__ */ jsxRuntime.jsx(
120
+ "div",
121
+ {
122
+ className: "absolute top-0 bottom-0 w-0.5",
123
+ style: {
124
+ left: `${position}%`,
125
+ transform: "translateX(-50%)",
126
+ background: "#ffffff",
127
+ boxShadow: "0 0 8px rgba(0,0,0,0.5)"
128
+ }
129
+ }
130
+ ),
131
+ /* @__PURE__ */ jsxRuntime.jsx(
132
+ "div",
133
+ {
134
+ ref: sliderRef,
135
+ className: "absolute top-1/2 flex items-center justify-center w-10 h-10 rounded-full",
136
+ style: {
137
+ left: `${position}%`,
138
+ transform: "translate(-50%, -50%)",
139
+ background: "var(--sk-primary, #6366f1)",
140
+ boxShadow: "0 4px 16px rgba(0,0,0,0.3)",
141
+ border: "3px solid #ffffff",
142
+ zIndex: 5
143
+ },
144
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 3l-4 5 4 5M11 3l4 5-4 5", stroke: "#ffffff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
145
+ }
146
+ ),
147
+ /* @__PURE__ */ jsxRuntime.jsx(
148
+ "span",
149
+ {
150
+ className: "absolute top-4 left-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider",
151
+ style: {
152
+ background: "rgba(0,0,0,0.6)",
153
+ color: "#ffffff",
154
+ backdropFilter: "blur(4px)"
155
+ },
156
+ children: "Before"
157
+ }
158
+ ),
159
+ /* @__PURE__ */ jsxRuntime.jsx(
160
+ "span",
161
+ {
162
+ className: "absolute top-4 right-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider",
163
+ style: {
164
+ background: "rgba(0,0,0,0.6)",
165
+ color: "#ffffff",
166
+ backdropFilter: "blur(4px)"
167
+ },
168
+ children: "After"
169
+ }
170
+ )
171
+ ]
172
+ }
173
+ ) }) })
174
+ ] })
175
+ }
176
+ );
177
+ }
178
+
179
+ module.exports = BeforeAfterSection;
180
+ //# sourceMappingURL=BeforeAfterSection-DVAWWE4K.cjs.map
181
+ //# sourceMappingURL=BeforeAfterSection-DVAWWE4K.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/BeforeAfterSection.tsx"],"names":["useRef","useState","useEffect","gsap","useCallback","jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"BeforeAfterSection-DVAWWE4K.cjs","sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect } from 'react';\nimport gsap from 'gsap';\nimport type { PortfolioBeforeAfterData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface BeforeAfterSectionProps {\n data: PortfolioBeforeAfterData;\n}\n\nexport default function BeforeAfterSection({ data }: BeforeAfterSectionProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState(data.defaultPosition ?? 50);\n const isDragging = useRef(false);\n\n const beforeUrl = data.before?.asset?._ref || '';\n const afterUrl = data.after?.asset?._ref || '';\n\n // Animate slider handle entrance\n useEffect(() => {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion || !sliderRef.current) return;\n\n gsap.fromTo(\n sliderRef.current,\n { opacity: 0, scale: 0.8 },\n { opacity: 1, scale: 1, duration: 0.6, delay: 0.5, ease: 'back.out(2)' },\n );\n }, []);\n\n const updatePosition = useCallback((clientX: number) => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const x = clientX - rect.left;\n const percent = Math.max(0, Math.min(100, (x / rect.width) * 100));\n setPosition(percent);\n }, []);\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n isDragging.current = true;\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (!isDragging.current) return;\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerUp = useCallback(() => {\n isDragging.current = false;\n }, []);\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 {(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 <ScrollReveal y={40}>\n <GlassCard padding=\"sm\" hover={false}>\n <div\n ref={containerRef}\n className=\"relative w-full overflow-hidden rounded-xl cursor-col-resize select-none\"\n style={{ aspectRatio: '16/10' }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {/* After image (full background) */}\n <img\n src={afterUrl}\n alt=\"After\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n draggable={false}\n />\n\n {/* Before image (clipped) */}\n <div\n className=\"absolute inset-0 overflow-hidden\"\n style={{ width: `${position}%` }}\n >\n <img\n src={beforeUrl}\n alt=\"Before\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n style={{ minWidth: containerRef.current?.offsetWidth || '100%' }}\n draggable={false}\n />\n </div>\n\n {/* Slider line */}\n <div\n className=\"absolute top-0 bottom-0 w-0.5\"\n style={{\n left: `${position}%`,\n transform: 'translateX(-50%)',\n background: '#ffffff',\n boxShadow: '0 0 8px rgba(0,0,0,0.5)',\n }}\n />\n\n {/* Slider handle */}\n <div\n ref={sliderRef}\n className=\"absolute top-1/2 flex items-center justify-center w-10 h-10 rounded-full\"\n style={{\n left: `${position}%`,\n transform: 'translate(-50%, -50%)',\n background: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 4px 16px rgba(0,0,0,0.3)',\n border: '3px solid #ffffff',\n zIndex: 5,\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 3l-4 5 4 5M11 3l4 5-4 5\" stroke=\"#ffffff\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n\n {/* Before / After labels */}\n <span\n className=\"absolute top-4 left-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n Before\n </span>\n <span\n className=\"absolute top-4 right-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n After\n </span>\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,111 @@
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 gsap = require('gsap');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var gsap__default = /*#__PURE__*/_interopDefault(gsap);
12
+
13
+ function CTASection({ data }) {
14
+ const buttonRef = react.useRef(null);
15
+ const style = data.style || "primary";
16
+ const handleMouseEnter = react.useCallback(() => {
17
+ if (!buttonRef.current) return;
18
+ gsap__default.default.to(buttonRef.current, {
19
+ scale: 1.05,
20
+ y: -2,
21
+ duration: 0.25,
22
+ ease: "power2.out"
23
+ });
24
+ }, []);
25
+ const handleMouseLeave = react.useCallback(() => {
26
+ if (!buttonRef.current) return;
27
+ gsap__default.default.to(buttonRef.current, {
28
+ scale: 1,
29
+ y: 0,
30
+ duration: 0.25,
31
+ ease: "power2.out"
32
+ });
33
+ }, []);
34
+ const content = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center text-center gap-6 py-12 px-8 md:px-16", children: [
35
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: /* @__PURE__ */ jsxRuntime.jsx(
36
+ "h2",
37
+ {
38
+ className: "text-3xl md:text-4xl lg:text-5xl font-bold leading-tight",
39
+ style: {
40
+ color: style === "primary" ? "#ffffff" : "var(--sk-text-primary, #ffffff)",
41
+ fontFamily: "var(--sk-font-heading, inherit)"
42
+ },
43
+ children: data.headline
44
+ }
45
+ ) }),
46
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 20, delay: 0.15, children: /* @__PURE__ */ jsxRuntime.jsx(
47
+ "p",
48
+ {
49
+ className: "text-base md:text-lg max-w-xl leading-relaxed",
50
+ style: {
51
+ color: style === "primary" ? "rgba(255,255,255,0.85)" : "var(--sk-text-secondary, #a1a1aa)"
52
+ },
53
+ children: data.description
54
+ }
55
+ ) }),
56
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 20, delay: 0.3, children: /* @__PURE__ */ jsxRuntime.jsxs(
57
+ "a",
58
+ {
59
+ ref: buttonRef,
60
+ href: data.buttonUrl,
61
+ onMouseEnter: handleMouseEnter,
62
+ onMouseLeave: handleMouseLeave,
63
+ className: "inline-flex items-center gap-2 px-8 py-4 rounded-xl text-base font-semibold transition-colors",
64
+ style: {
65
+ background: style === "primary" ? "#ffffff" : "var(--sk-primary, #6366f1)",
66
+ color: style === "primary" ? "var(--sk-primary, #6366f1)" : "#ffffff",
67
+ boxShadow: "0 4px 20px rgba(0,0,0,0.2)",
68
+ willChange: "transform"
69
+ },
70
+ children: [
71
+ data.buttonText,
72
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3.75 9h10.5M9.75 4.5L14.25 9l-4.5 4.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
73
+ ]
74
+ }
75
+ ) })
76
+ ] });
77
+ return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "w-full py-20 md:py-28", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-5xl mx-auto px-6", children: style === "primary" ? /* @__PURE__ */ jsxRuntime.jsxs(
78
+ "div",
79
+ {
80
+ className: "relative overflow-hidden rounded-2xl",
81
+ style: {
82
+ background: `linear-gradient(135deg, var(--sk-primary, #6366f1) 0%, color-mix(in srgb, var(--sk-primary, #6366f1) 70%, #000000) 100%)`
83
+ },
84
+ children: [
85
+ /* @__PURE__ */ jsxRuntime.jsx(
86
+ "div",
87
+ {
88
+ className: "absolute -top-24 -right-24 w-64 h-64 rounded-full opacity-20",
89
+ style: {
90
+ background: "radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)"
91
+ }
92
+ }
93
+ ),
94
+ /* @__PURE__ */ jsxRuntime.jsx(
95
+ "div",
96
+ {
97
+ className: "absolute -bottom-16 -left-16 w-48 h-48 rounded-full opacity-15",
98
+ style: {
99
+ background: "radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)"
100
+ }
101
+ }
102
+ ),
103
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10", children: content })
104
+ ]
105
+ }
106
+ ) : /* @__PURE__ */ jsxRuntime.jsx(chunkKEOHORIH_cjs.GlassCard, { padding: "sm", hover: false, children: content }) }) });
107
+ }
108
+
109
+ module.exports = CTASection;
110
+ //# sourceMappingURL=CTASection-4JKLXEUF.cjs.map
111
+ //# sourceMappingURL=CTASection-4JKLXEUF.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/CTASection.tsx"],"names":["useRef","useCallback","gsap","jsxs","jsx","ScrollReveal","GlassCard"],"mappings":";;;;;;;;;;;;AAYe,SAAR,UAAA,CAA4B,EAAE,IAAA,EAAK,EAAoB;AAC5D,EAAA,MAAM,SAAA,GAAYA,aAA0B,IAAI,CAAA;AAChD,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,SAAA;AAE5B,EAAA,MAAM,gBAAA,GAAmBC,kBAAY,MAAM;AACzC,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AACxB,IAAAC,qBAAA,CAAK,EAAA,CAAG,UAAU,OAAA,EAAS;AAAA,MACzB,KAAA,EAAO,IAAA;AAAA,MACP,CAAA,EAAG,EAAA;AAAA,MACH,QAAA,EAAU,IAAA;AAAA,MACV,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,gBAAA,GAAmBD,kBAAY,MAAM;AACzC,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AACxB,IAAAC,qBAAA,CAAK,EAAA,CAAG,UAAU,OAAA,EAAS;AAAA,MACzB,KAAA,EAAO,CAAA;AAAA,MACP,CAAA,EAAG,CAAA;AAAA,MACH,QAAA,EAAU,IAAA;AAAA,MACV,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAA,mBACJC,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kEAAA,EACb,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAACC,8BAAA,EAAA,EAAa,GAAG,EAAA,EACf,QAAA,kBAAAD,cAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,0DAAA;AAAA,QACV,KAAA,EAAO;AAAA,UACL,KAAA,EAAO,KAAA,KAAU,SAAA,GAAY,SAAA,GAAY,iCAAA;AAAA,UACzC,UAAA,EAAY;AAAA,SACd;AAAA,QAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,KACR,EACF,CAAA;AAAA,oBAEAA,cAAA,CAACC,8BAAA,EAAA,EAAa,CAAA,EAAG,EAAA,EAAI,OAAO,IAAA,EAC1B,QAAA,kBAAAD,cAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,+CAAA;AAAA,QACV,KAAA,EAAO;AAAA,UACL,KAAA,EAAO,KAAA,KAAU,SAAA,GAAY,wBAAA,GAA2B;AAAA,SAC1D;AAAA,QAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,KACR,EACF,CAAA;AAAA,oBAEAA,cAAA,CAACC,8BAAA,EAAA,EAAa,CAAA,EAAG,EAAA,EAAI,OAAO,GAAA,EAC1B,QAAA,kBAAAF,eAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,SAAA;AAAA,QACL,MAAM,IAAA,CAAK,SAAA;AAAA,QACX,YAAA,EAAc,gBAAA;AAAA,QACd,YAAA,EAAc,gBAAA;AAAA,QACd,SAAA,EAAU,+FAAA;AAAA,QACV,KAAA,EAAO;AAAA,UACL,UAAA,EACE,KAAA,KAAU,SAAA,GACN,SAAA,GACA,4BAAA;AAAA,UACN,KAAA,EACE,KAAA,KAAU,SAAA,GACN,4BAAA,GACA,SAAA;AAAA,UACN,SAAA,EAAW,4BAAA;AAAA,UACX,UAAA,EAAY;AAAA,SACd;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,UAAA;AAAA,0BACNC,cAAA,CAAC,SAAI,KAAA,EAAM,IAAA,EAAK,QAAO,IAAA,EAAK,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EACnD,QAAA,kBAAAA,cAAA,CAAC,UAAK,CAAA,EAAE,wCAAA,EAAyC,QAAO,cAAA,EAAe,WAAA,EAAY,KAAI,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,CAAA,EACtI;AAAA;AAAA;AAAA,KACF,EACF;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,uBACEA,cAAA,CAAC,aAAQ,SAAA,EAAU,uBAAA,EACjB,yCAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACZ,QAAA,EAAA,KAAA,KAAU,SAAA,mBACTD,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,sCAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,UAAA,EAAY,CAAA,wHAAA;AAAA,OACd;AAAA,MAGA,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,8DAAA;AAAA,YACV,KAAA,EAAO;AAAA,cACL,UAAA,EAAY;AAAA;AACd;AAAA,SACF;AAAA,wBACAA,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,gEAAA;AAAA,YACV,KAAA,EAAO;AAAA,cACL,UAAA,EAAY;AAAA;AACd;AAAA,SACF;AAAA,wBACAA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EAAiB,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA;AAAA,GAC1C,kCAECE,2BAAA,EAAA,EAAU,OAAA,EAAQ,MAAK,KAAA,EAAO,KAAA,EAC5B,QAAA,EAAA,OAAA,EACH,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ","file":"CTASection-4JKLXEUF.cjs","sourcesContent":["'use client';\n\nimport React, { useRef, useCallback } from 'react';\nimport gsap from 'gsap';\nimport type { PortfolioCTAData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface CTASectionProps {\n data: PortfolioCTAData;\n}\n\nexport default function CTASection({ data }: CTASectionProps) {\n const buttonRef = useRef<HTMLAnchorElement>(null);\n const style = data.style || 'primary';\n\n const handleMouseEnter = useCallback(() => {\n if (!buttonRef.current) return;\n gsap.to(buttonRef.current, {\n scale: 1.05,\n y: -2,\n duration: 0.25,\n ease: 'power2.out',\n });\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n if (!buttonRef.current) return;\n gsap.to(buttonRef.current, {\n scale: 1,\n y: 0,\n duration: 0.25,\n ease: 'power2.out',\n });\n }, []);\n\n const content = (\n <div className=\"flex flex-col items-center text-center gap-6 py-12 px-8 md:px-16\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl lg:text-5xl font-bold leading-tight\"\n style={{\n color: style === 'primary' ? '#ffffff' : 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n {data.headline}\n </h2>\n </ScrollReveal>\n\n <ScrollReveal y={20} delay={0.15}>\n <p\n className=\"text-base md:text-lg max-w-xl leading-relaxed\"\n style={{\n color: style === 'primary' ? 'rgba(255,255,255,0.85)' : 'var(--sk-text-secondary, #a1a1aa)',\n }}\n >\n {data.description}\n </p>\n </ScrollReveal>\n\n <ScrollReveal y={20} delay={0.3}>\n <a\n ref={buttonRef}\n href={data.buttonUrl}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n className=\"inline-flex items-center gap-2 px-8 py-4 rounded-xl text-base font-semibold transition-colors\"\n style={{\n background:\n style === 'primary'\n ? '#ffffff'\n : 'var(--sk-primary, #6366f1)',\n color:\n style === 'primary'\n ? 'var(--sk-primary, #6366f1)'\n : '#ffffff',\n boxShadow: '0 4px 20px rgba(0,0,0,0.2)',\n willChange: 'transform',\n }}\n >\n {data.buttonText}\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M3.75 9h10.5M9.75 4.5L14.25 9l-4.5 4.5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </a>\n </ScrollReveal>\n </div>\n );\n\n return (\n <section className=\"w-full py-20 md:py-28\">\n <div className=\"max-w-5xl mx-auto px-6\">\n {style === 'primary' ? (\n <div\n className=\"relative overflow-hidden rounded-2xl\"\n style={{\n background: `linear-gradient(135deg, var(--sk-primary, #6366f1) 0%, color-mix(in srgb, var(--sk-primary, #6366f1) 70%, #000000) 100%)`,\n }}\n >\n {/* Background gradient decorations */}\n <div\n className=\"absolute -top-24 -right-24 w-64 h-64 rounded-full opacity-20\"\n style={{\n background: 'radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)',\n }}\n />\n <div\n className=\"absolute -bottom-16 -left-16 w-48 h-48 rounded-full opacity-15\"\n style={{\n background: 'radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)',\n }}\n />\n <div className=\"relative z-10\">{content}</div>\n </div>\n ) : (\n <GlassCard padding=\"sm\" hover={false}>\n {content}\n </GlassCard>\n )}\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,106 @@
1
+ 'use client';
2
+ import { GlassCard } from './chunk-YB4B3OMC.js';
3
+ import { ScrollReveal } from './chunk-7CFFAKDM.js';
4
+ import { useRef, useCallback } from 'react';
5
+ import gsap from 'gsap';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ function CTASection({ data }) {
9
+ const buttonRef = useRef(null);
10
+ const style = data.style || "primary";
11
+ const handleMouseEnter = useCallback(() => {
12
+ if (!buttonRef.current) return;
13
+ gsap.to(buttonRef.current, {
14
+ scale: 1.05,
15
+ y: -2,
16
+ duration: 0.25,
17
+ ease: "power2.out"
18
+ });
19
+ }, []);
20
+ const handleMouseLeave = useCallback(() => {
21
+ if (!buttonRef.current) return;
22
+ gsap.to(buttonRef.current, {
23
+ scale: 1,
24
+ y: 0,
25
+ duration: 0.25,
26
+ ease: "power2.out"
27
+ });
28
+ }, []);
29
+ const content = /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center text-center gap-6 py-12 px-8 md:px-16", children: [
30
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 30, children: /* @__PURE__ */ jsx(
31
+ "h2",
32
+ {
33
+ className: "text-3xl md:text-4xl lg:text-5xl font-bold leading-tight",
34
+ style: {
35
+ color: style === "primary" ? "#ffffff" : "var(--sk-text-primary, #ffffff)",
36
+ fontFamily: "var(--sk-font-heading, inherit)"
37
+ },
38
+ children: data.headline
39
+ }
40
+ ) }),
41
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.15, children: /* @__PURE__ */ jsx(
42
+ "p",
43
+ {
44
+ className: "text-base md:text-lg max-w-xl leading-relaxed",
45
+ style: {
46
+ color: style === "primary" ? "rgba(255,255,255,0.85)" : "var(--sk-text-secondary, #a1a1aa)"
47
+ },
48
+ children: data.description
49
+ }
50
+ ) }),
51
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.3, children: /* @__PURE__ */ jsxs(
52
+ "a",
53
+ {
54
+ ref: buttonRef,
55
+ href: data.buttonUrl,
56
+ onMouseEnter: handleMouseEnter,
57
+ onMouseLeave: handleMouseLeave,
58
+ className: "inline-flex items-center gap-2 px-8 py-4 rounded-xl text-base font-semibold transition-colors",
59
+ style: {
60
+ background: style === "primary" ? "#ffffff" : "var(--sk-primary, #6366f1)",
61
+ color: style === "primary" ? "var(--sk-primary, #6366f1)" : "#ffffff",
62
+ boxShadow: "0 4px 20px rgba(0,0,0,0.2)",
63
+ willChange: "transform"
64
+ },
65
+ children: [
66
+ data.buttonText,
67
+ /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M3.75 9h10.5M9.75 4.5L14.25 9l-4.5 4.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
68
+ ]
69
+ }
70
+ ) })
71
+ ] });
72
+ return /* @__PURE__ */ jsx("section", { className: "w-full py-20 md:py-28", children: /* @__PURE__ */ jsx("div", { className: "max-w-5xl mx-auto px-6", children: style === "primary" ? /* @__PURE__ */ jsxs(
73
+ "div",
74
+ {
75
+ className: "relative overflow-hidden rounded-2xl",
76
+ style: {
77
+ background: `linear-gradient(135deg, var(--sk-primary, #6366f1) 0%, color-mix(in srgb, var(--sk-primary, #6366f1) 70%, #000000) 100%)`
78
+ },
79
+ children: [
80
+ /* @__PURE__ */ jsx(
81
+ "div",
82
+ {
83
+ className: "absolute -top-24 -right-24 w-64 h-64 rounded-full opacity-20",
84
+ style: {
85
+ background: "radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)"
86
+ }
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsx(
90
+ "div",
91
+ {
92
+ className: "absolute -bottom-16 -left-16 w-48 h-48 rounded-full opacity-15",
93
+ style: {
94
+ background: "radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)"
95
+ }
96
+ }
97
+ ),
98
+ /* @__PURE__ */ jsx("div", { className: "relative z-10", children: content })
99
+ ]
100
+ }
101
+ ) : /* @__PURE__ */ jsx(GlassCard, { padding: "sm", hover: false, children: content }) }) });
102
+ }
103
+
104
+ export { CTASection as default };
105
+ //# sourceMappingURL=CTASection-BJA72XIL.js.map
106
+ //# sourceMappingURL=CTASection-BJA72XIL.js.map