@sonordev/agency-site-kit 0.3.1 → 0.4.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 (369) hide show
  1. package/README.md +302 -0
  2. package/bin/setup.mjs +79 -0
  3. package/dist/{chunk-RXBK2EOE.js → chunk-4IES23GV.js} +3 -3
  4. package/dist/{chunk-RXBK2EOE.js.map → chunk-4IES23GV.js.map} +1 -1
  5. package/dist/chunk-4N7ENJ7L.cjs +108 -0
  6. package/dist/chunk-4N7ENJ7L.cjs.map +1 -0
  7. package/dist/{chunk-WNR4KNG4.cjs → chunk-5MEZU3OG.cjs} +4 -4
  8. package/dist/{chunk-WNR4KNG4.cjs.map → chunk-5MEZU3OG.cjs.map} +1 -1
  9. package/dist/chunk-7ZHRMWJU.cjs +306 -0
  10. package/dist/chunk-7ZHRMWJU.cjs.map +1 -0
  11. package/dist/chunk-CVT7I5BQ.js +71 -0
  12. package/dist/chunk-CVT7I5BQ.js.map +1 -0
  13. package/dist/chunk-HQGAX2LI.cjs +8 -0
  14. package/dist/chunk-HQGAX2LI.cjs.map +1 -0
  15. package/dist/chunk-KXLROAO5.js +291 -0
  16. package/dist/chunk-KXLROAO5.js.map +1 -0
  17. package/dist/chunk-L4EOQVRJ.js +6 -0
  18. package/dist/chunk-L4EOQVRJ.js.map +1 -0
  19. package/dist/chunk-L7E3UHQC.cjs +535 -0
  20. package/dist/chunk-L7E3UHQC.cjs.map +1 -0
  21. package/dist/chunk-NI4FVCLS.cjs +32 -0
  22. package/dist/chunk-NI4FVCLS.cjs.map +1 -0
  23. package/dist/chunk-NIZJLONK.js +106 -0
  24. package/dist/chunk-NIZJLONK.js.map +1 -0
  25. package/dist/chunk-QDXZ27R7.js +33 -0
  26. package/dist/chunk-QDXZ27R7.js.map +1 -0
  27. package/dist/{chunk-TVFXN6W6.js → chunk-QL6KVIFR.js} +8 -4
  28. package/dist/chunk-QL6KVIFR.js.map +1 -0
  29. package/dist/chunk-UNTOEWQL.js +504 -0
  30. package/dist/chunk-UNTOEWQL.js.map +1 -0
  31. package/dist/chunk-XJ434N7I.js +30 -0
  32. package/dist/chunk-XJ434N7I.js.map +1 -0
  33. package/dist/chunk-XLK77USA.js +45 -0
  34. package/dist/chunk-XLK77USA.js.map +1 -0
  35. package/dist/{chunk-EE75WRCM.cjs → chunk-XOWSXZYW.cjs} +8 -4
  36. package/dist/chunk-XOWSXZYW.cjs.map +1 -0
  37. package/dist/chunk-ZINKVJQU.js +67 -0
  38. package/dist/chunk-ZINKVJQU.js.map +1 -0
  39. package/dist/index.cjs +29 -31
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +17 -9
  42. package/dist/index.d.ts +17 -9
  43. package/dist/index.js +7 -9
  44. package/dist/index.js.map +1 -1
  45. package/dist/layout/index.cjs +3 -3
  46. package/dist/layout/index.d.cts +1 -1
  47. package/dist/layout/index.d.ts +1 -1
  48. package/dist/layout/index.js +2 -2
  49. package/dist/portfolio/client.cjs +342 -12
  50. package/dist/portfolio/client.cjs.map +1 -1
  51. package/dist/portfolio/client.d.cts +11 -88
  52. package/dist/portfolio/client.d.ts +11 -88
  53. package/dist/portfolio/client.js +150 -4
  54. package/dist/portfolio/client.js.map +1 -1
  55. package/dist/portfolio/components/PortfolioAnalytics.cjs +87 -0
  56. package/dist/portfolio/components/PortfolioAnalytics.cjs.map +1 -0
  57. package/dist/portfolio/components/PortfolioAnalytics.d.cts +5 -0
  58. package/dist/portfolio/components/PortfolioAnalytics.d.ts +5 -0
  59. package/dist/portfolio/components/PortfolioAnalytics.js +9 -0
  60. package/dist/portfolio/components/PortfolioAnalytics.js.map +1 -0
  61. package/dist/portfolio/components/PortfolioErrorFallback.cjs +65 -0
  62. package/dist/portfolio/components/PortfolioErrorFallback.cjs.map +1 -0
  63. package/dist/portfolio/components/PortfolioErrorFallback.d.cts +22 -0
  64. package/dist/portfolio/components/PortfolioErrorFallback.d.ts +22 -0
  65. package/dist/portfolio/components/PortfolioErrorFallback.js +9 -0
  66. package/dist/portfolio/components/PortfolioErrorFallback.js.map +1 -0
  67. package/dist/portfolio/components/PortfolioLeadCTA.cjs +91 -0
  68. package/dist/portfolio/components/PortfolioLeadCTA.cjs.map +1 -0
  69. package/dist/portfolio/components/PortfolioLeadCTA.d.cts +34 -0
  70. package/dist/portfolio/components/PortfolioLeadCTA.d.ts +34 -0
  71. package/dist/portfolio/components/PortfolioLeadCTA.js +9 -0
  72. package/dist/portfolio/components/PortfolioLeadCTA.js.map +1 -0
  73. package/dist/portfolio/index.cjs +19 -20
  74. package/dist/portfolio/index.d.cts +133 -7
  75. package/dist/portfolio/index.d.ts +133 -7
  76. package/dist/portfolio/index.js +6 -7
  77. package/dist/portfolio/primitives/AnimatedCounter.cjs +88 -0
  78. package/dist/portfolio/primitives/AnimatedCounter.cjs.map +1 -0
  79. package/dist/portfolio/primitives/AnimatedCounter.d.cts +22 -0
  80. package/dist/portfolio/primitives/AnimatedCounter.d.ts +22 -0
  81. package/dist/portfolio/primitives/AnimatedCounter.js +68 -0
  82. package/dist/portfolio/primitives/AnimatedCounter.js.map +1 -0
  83. package/dist/portfolio/primitives/AnnotatedImage.cjs +320 -0
  84. package/dist/portfolio/primitives/AnnotatedImage.cjs.map +1 -0
  85. package/dist/portfolio/primitives/AnnotatedImage.d.cts +18 -0
  86. package/dist/portfolio/primitives/AnnotatedImage.d.ts +18 -0
  87. package/dist/portfolio/primitives/AnnotatedImage.js +264 -0
  88. package/dist/portfolio/primitives/AnnotatedImage.js.map +1 -0
  89. package/dist/portfolio/primitives/BeforeAfterSlider.cjs +348 -0
  90. package/dist/portfolio/primitives/BeforeAfterSlider.cjs.map +1 -0
  91. package/dist/portfolio/primitives/BeforeAfterSlider.d.cts +13 -0
  92. package/dist/portfolio/primitives/BeforeAfterSlider.d.ts +13 -0
  93. package/dist/portfolio/primitives/BeforeAfterSlider.js +292 -0
  94. package/dist/portfolio/primitives/BeforeAfterSlider.js.map +1 -0
  95. package/dist/portfolio/primitives/DeviceTrifolio.cjs +298 -0
  96. package/dist/portfolio/primitives/DeviceTrifolio.cjs.map +1 -0
  97. package/dist/portfolio/primitives/DeviceTrifolio.d.cts +14 -0
  98. package/dist/portfolio/primitives/DeviceTrifolio.d.ts +14 -0
  99. package/dist/portfolio/primitives/DeviceTrifolio.js +242 -0
  100. package/dist/portfolio/primitives/DeviceTrifolio.js.map +1 -0
  101. package/dist/portfolio/primitives/FrequencyBarSkeleton.cjs +88 -0
  102. package/dist/portfolio/primitives/FrequencyBarSkeleton.cjs.map +1 -0
  103. package/dist/portfolio/primitives/FrequencyBarSkeleton.d.cts +10 -0
  104. package/dist/portfolio/primitives/FrequencyBarSkeleton.d.ts +10 -0
  105. package/dist/portfolio/primitives/FrequencyBarSkeleton.js +68 -0
  106. package/dist/portfolio/primitives/FrequencyBarSkeleton.js.map +1 -0
  107. package/dist/portfolio/primitives/GlassCard.cjs +45 -0
  108. package/dist/portfolio/primitives/GlassCard.cjs.map +1 -0
  109. package/dist/portfolio/primitives/GlassCard.d.cts +11 -0
  110. package/dist/portfolio/primitives/GlassCard.d.ts +11 -0
  111. package/dist/portfolio/primitives/GlassCard.js +43 -0
  112. package/dist/portfolio/primitives/GlassCard.js.map +1 -0
  113. package/dist/portfolio/primitives/MetricBadge.cjs +74 -0
  114. package/dist/portfolio/primitives/MetricBadge.cjs.map +1 -0
  115. package/dist/portfolio/primitives/MetricBadge.d.cts +9 -0
  116. package/dist/portfolio/primitives/MetricBadge.d.ts +9 -0
  117. package/dist/portfolio/primitives/MetricBadge.js +54 -0
  118. package/dist/portfolio/primitives/MetricBadge.js.map +1 -0
  119. package/dist/portfolio/primitives/SVGChart.cjs +316 -0
  120. package/dist/portfolio/primitives/SVGChart.cjs.map +1 -0
  121. package/dist/portfolio/primitives/SVGChart.d.cts +18 -0
  122. package/dist/portfolio/primitives/SVGChart.d.ts +18 -0
  123. package/dist/portfolio/primitives/SVGChart.js +296 -0
  124. package/dist/portfolio/primitives/SVGChart.js.map +1 -0
  125. package/dist/portfolio/primitives/ScrollReveal.cjs +97 -0
  126. package/dist/portfolio/primitives/ScrollReveal.cjs.map +1 -0
  127. package/dist/portfolio/primitives/ScrollReveal.d.cts +27 -0
  128. package/dist/portfolio/primitives/ScrollReveal.d.ts +27 -0
  129. package/dist/portfolio/primitives/ScrollReveal.js +77 -0
  130. package/dist/portfolio/primitives/ScrollReveal.js.map +1 -0
  131. package/dist/portfolio/primitives/SplitHeadline.cjs +107 -0
  132. package/dist/portfolio/primitives/SplitHeadline.cjs.map +1 -0
  133. package/dist/portfolio/primitives/SplitHeadline.d.cts +24 -0
  134. package/dist/portfolio/primitives/SplitHeadline.d.ts +24 -0
  135. package/dist/portfolio/primitives/SplitHeadline.js +87 -0
  136. package/dist/portfolio/primitives/SplitHeadline.js.map +1 -0
  137. package/dist/portfolio/sections/BeforeAfterSection.cjs +271 -0
  138. package/dist/portfolio/sections/BeforeAfterSection.cjs.map +1 -0
  139. package/dist/portfolio/sections/BeforeAfterSection.d.cts +9 -0
  140. package/dist/portfolio/sections/BeforeAfterSection.d.ts +9 -0
  141. package/dist/{BeforeAfterSection-6BHFLY4Y.js → portfolio/sections/BeforeAfterSection.js} +66 -27
  142. package/dist/portfolio/sections/BeforeAfterSection.js.map +1 -0
  143. package/dist/portfolio/sections/CTASection.cjs +123 -0
  144. package/dist/portfolio/sections/CTASection.cjs.map +1 -0
  145. package/dist/portfolio/sections/CTASection.d.cts +9 -0
  146. package/dist/portfolio/sections/CTASection.d.ts +9 -0
  147. package/dist/portfolio/sections/CTASection.js +93 -0
  148. package/dist/portfolio/sections/CTASection.js.map +1 -0
  149. package/dist/{ChallengesSection-IZ3DHECS.cjs → portfolio/sections/ChallengesSection.cjs} +12 -6
  150. package/dist/portfolio/sections/ChallengesSection.cjs.map +1 -0
  151. package/dist/portfolio/sections/ChallengesSection.d.cts +9 -0
  152. package/dist/portfolio/sections/ChallengesSection.d.ts +9 -0
  153. package/dist/{ChallengesSection-GEQGVSJN.js → portfolio/sections/ChallengesSection.js} +5 -4
  154. package/dist/portfolio/sections/ChallengesSection.js.map +1 -0
  155. package/dist/portfolio/sections/ConversionFunnelSection.cjs +263 -0
  156. package/dist/portfolio/sections/ConversionFunnelSection.cjs.map +1 -0
  157. package/dist/portfolio/sections/ConversionFunnelSection.d.cts +9 -0
  158. package/dist/portfolio/sections/ConversionFunnelSection.d.ts +9 -0
  159. package/dist/{ConversionFunnelSection-D3GE4NKE.js → portfolio/sections/ConversionFunnelSection.js} +60 -56
  160. package/dist/portfolio/sections/ConversionFunnelSection.js.map +1 -0
  161. package/dist/{DesignSystemSection-KXIQXITF.cjs → portfolio/sections/DesignSystemSection.cjs} +13 -7
  162. package/dist/portfolio/sections/DesignSystemSection.cjs.map +1 -0
  163. package/dist/portfolio/sections/DesignSystemSection.d.cts +32 -0
  164. package/dist/portfolio/sections/DesignSystemSection.d.ts +32 -0
  165. package/dist/{DesignSystemSection-2R5BRBGO.js → portfolio/sections/DesignSystemSection.js} +5 -4
  166. package/dist/portfolio/sections/DesignSystemSection.js.map +1 -0
  167. package/dist/{DetailsSection-TTUZAPZZ.cjs → portfolio/sections/DetailsSection.cjs} +12 -6
  168. package/dist/portfolio/sections/DetailsSection.cjs.map +1 -0
  169. package/dist/portfolio/sections/DetailsSection.d.cts +9 -0
  170. package/dist/portfolio/sections/DetailsSection.d.ts +9 -0
  171. package/dist/{DetailsSection-A6PZQUQL.js → portfolio/sections/DetailsSection.js} +5 -4
  172. package/dist/portfolio/sections/DetailsSection.js.map +1 -0
  173. package/dist/portfolio/sections/FeatureSpotlightSection.cjs +267 -0
  174. package/dist/portfolio/sections/FeatureSpotlightSection.cjs.map +1 -0
  175. package/dist/portfolio/sections/FeatureSpotlightSection.d.cts +9 -0
  176. package/dist/portfolio/sections/FeatureSpotlightSection.d.ts +9 -0
  177. package/dist/{FeatureSpotlightSection-B7P3JGNL.js → portfolio/sections/FeatureSpotlightSection.js} +39 -33
  178. package/dist/portfolio/sections/FeatureSpotlightSection.js.map +1 -0
  179. package/dist/portfolio/sections/GallerySection.cjs +321 -0
  180. package/dist/portfolio/sections/GallerySection.cjs.map +1 -0
  181. package/dist/portfolio/sections/GallerySection.d.cts +9 -0
  182. package/dist/portfolio/sections/GallerySection.d.ts +9 -0
  183. package/dist/{GallerySection-VMKORC47.js → portfolio/sections/GallerySection.js} +65 -18
  184. package/dist/portfolio/sections/GallerySection.js.map +1 -0
  185. package/dist/portfolio/sections/HeroSection.cjs +180 -0
  186. package/dist/portfolio/sections/HeroSection.cjs.map +1 -0
  187. package/dist/portfolio/sections/HeroSection.d.cts +15 -0
  188. package/dist/portfolio/sections/HeroSection.d.ts +15 -0
  189. package/dist/portfolio/sections/HeroSection.js +171 -0
  190. package/dist/portfolio/sections/HeroSection.js.map +1 -0
  191. package/dist/{MetricsTimelineSection-4L6DUHJ5.cjs → portfolio/sections/MetricsTimelineSection.cjs} +102 -61
  192. package/dist/portfolio/sections/MetricsTimelineSection.cjs.map +1 -0
  193. package/dist/portfolio/sections/MetricsTimelineSection.d.cts +9 -0
  194. package/dist/portfolio/sections/MetricsTimelineSection.d.ts +9 -0
  195. package/dist/{MetricsTimelineSection-6BT5GNFV.js → portfolio/sections/MetricsTimelineSection.js} +45 -29
  196. package/dist/portfolio/sections/MetricsTimelineSection.js.map +1 -0
  197. package/dist/{PerformanceSection-24TVVFZA.cjs → portfolio/sections/PerformanceSection.cjs} +136 -93
  198. package/dist/portfolio/sections/PerformanceSection.cjs.map +1 -0
  199. package/dist/portfolio/sections/PerformanceSection.d.cts +22 -0
  200. package/dist/portfolio/sections/PerformanceSection.d.ts +22 -0
  201. package/dist/{PerformanceSection-MGCEIXDX.js → portfolio/sections/PerformanceSection.js} +58 -40
  202. package/dist/portfolio/sections/PerformanceSection.js.map +1 -0
  203. package/dist/{ResultsSection-XLGMMQKY.cjs → portfolio/sections/ResultsSection.cjs} +22 -10
  204. package/dist/portfolio/sections/ResultsSection.cjs.map +1 -0
  205. package/dist/portfolio/sections/ResultsSection.d.cts +13 -0
  206. package/dist/portfolio/sections/ResultsSection.d.ts +13 -0
  207. package/dist/{ResultsSection-DFUJ5U6M.js → portfolio/sections/ResultsSection.js} +13 -7
  208. package/dist/portfolio/sections/ResultsSection.js.map +1 -0
  209. package/dist/portfolio/sections/ServicesSection.cjs +129 -0
  210. package/dist/portfolio/sections/ServicesSection.cjs.map +1 -0
  211. package/dist/portfolio/sections/ServicesSection.d.cts +9 -0
  212. package/dist/portfolio/sections/ServicesSection.d.ts +9 -0
  213. package/dist/portfolio/sections/ServicesSection.js +122 -0
  214. package/dist/portfolio/sections/ServicesSection.js.map +1 -0
  215. package/dist/{SiteArchitectureSection-J7BPBERH.cjs → portfolio/sections/SiteArchitectureSection.cjs} +116 -92
  216. package/dist/portfolio/sections/SiteArchitectureSection.cjs.map +1 -0
  217. package/dist/portfolio/sections/SiteArchitectureSection.d.cts +21 -0
  218. package/dist/portfolio/sections/SiteArchitectureSection.d.ts +21 -0
  219. package/dist/{SiteArchitectureSection-TE22OAWV.js → portfolio/sections/SiteArchitectureSection.js} +46 -47
  220. package/dist/portfolio/sections/SiteArchitectureSection.js.map +1 -0
  221. package/dist/{SpeedComparisonSection-EZKFQVGW.cjs → portfolio/sections/SpeedComparisonSection.cjs} +12 -6
  222. package/dist/portfolio/sections/SpeedComparisonSection.cjs.map +1 -0
  223. package/dist/portfolio/sections/SpeedComparisonSection.d.cts +20 -0
  224. package/dist/portfolio/sections/SpeedComparisonSection.d.ts +20 -0
  225. package/dist/{SpeedComparisonSection-Y3K7OFZQ.js → portfolio/sections/SpeedComparisonSection.js} +5 -4
  226. package/dist/portfolio/sections/SpeedComparisonSection.js.map +1 -0
  227. package/dist/portfolio/sections/StrategySection.cjs +233 -0
  228. package/dist/portfolio/sections/StrategySection.cjs.map +1 -0
  229. package/dist/portfolio/sections/StrategySection.d.cts +9 -0
  230. package/dist/portfolio/sections/StrategySection.d.ts +9 -0
  231. package/dist/{StrategySection-DI5RSCJU.js → portfolio/sections/StrategySection.js} +60 -26
  232. package/dist/portfolio/sections/StrategySection.js.map +1 -0
  233. package/dist/portfolio/sections/TeamSection.cjs +162 -0
  234. package/dist/portfolio/sections/TeamSection.cjs.map +1 -0
  235. package/dist/portfolio/sections/TeamSection.d.cts +9 -0
  236. package/dist/portfolio/sections/TeamSection.d.ts +9 -0
  237. package/dist/portfolio/sections/TeamSection.js +106 -0
  238. package/dist/portfolio/sections/TeamSection.js.map +1 -0
  239. package/dist/portfolio/sections/TechStackSection.cjs +106 -0
  240. package/dist/portfolio/sections/TechStackSection.cjs.map +1 -0
  241. package/dist/portfolio/sections/TechStackSection.d.cts +9 -0
  242. package/dist/portfolio/sections/TechStackSection.d.ts +9 -0
  243. package/dist/portfolio/sections/TechStackSection.js +99 -0
  244. package/dist/portfolio/sections/TechStackSection.js.map +1 -0
  245. package/dist/{TestimonialSection-XPTFUQIN.cjs → portfolio/sections/TestimonialSection.cjs} +47 -28
  246. package/dist/portfolio/sections/TestimonialSection.cjs.map +1 -0
  247. package/dist/portfolio/sections/TestimonialSection.d.cts +9 -0
  248. package/dist/portfolio/sections/TestimonialSection.d.ts +9 -0
  249. package/dist/{TestimonialSection-6RGSMXQB.js → portfolio/sections/TestimonialSection.js} +40 -27
  250. package/dist/portfolio/sections/TestimonialSection.js.map +1 -0
  251. package/dist/portfolio/sections/VideoSection.cjs +181 -0
  252. package/dist/portfolio/sections/VideoSection.cjs.map +1 -0
  253. package/dist/portfolio/sections/VideoSection.d.cts +9 -0
  254. package/dist/portfolio/sections/VideoSection.d.ts +9 -0
  255. package/dist/{VideoSection-4A2HC6K6.js → portfolio/sections/VideoSection.js} +21 -13
  256. package/dist/portfolio/sections/VideoSection.js.map +1 -0
  257. package/dist/portfolio/server.cjs +56 -144
  258. package/dist/portfolio/server.cjs.map +1 -1
  259. package/dist/portfolio/server.d.cts +157 -7
  260. package/dist/portfolio/server.d.ts +157 -7
  261. package/dist/portfolio/server.js +3 -142
  262. package/dist/portfolio/server.js.map +1 -1
  263. package/dist/preview.cjs +56 -0
  264. package/dist/preview.cjs.map +1 -0
  265. package/dist/preview.d.cts +31 -0
  266. package/dist/preview.d.ts +31 -0
  267. package/dist/preview.js +54 -0
  268. package/dist/preview.js.map +1 -0
  269. package/dist/{types-DL4t_Cfa.d.ts → types-0tVPy4pU.d.cts} +7 -1
  270. package/dist/{types-DL4t_Cfa.d.cts → types-0tVPy4pU.d.ts} +7 -1
  271. package/dist/types-D0nb6KAx.d.cts +299 -0
  272. package/dist/types-D0nb6KAx.d.ts +299 -0
  273. package/package.json +38 -14
  274. package/templates/api-portfolio-preview.ts +6 -0
  275. package/templates/api-revalidate.ts +5 -0
  276. package/templates/work-category-page.tsx +40 -0
  277. package/templates/work-error.tsx +3 -0
  278. package/templates/work-loading.tsx +1 -0
  279. package/templates/work-page.tsx +37 -0
  280. package/templates/work-slug-loading.tsx +1 -0
  281. package/templates/work-slug-page.tsx +41 -0
  282. package/dist/BeforeAfterSection-6BHFLY4Y.js.map +0 -1
  283. package/dist/BeforeAfterSection-JTORBR3A.cjs +0 -181
  284. package/dist/BeforeAfterSection-JTORBR3A.cjs.map +0 -1
  285. package/dist/CTASection-4JKLXEUF.cjs +0 -111
  286. package/dist/CTASection-4JKLXEUF.cjs.map +0 -1
  287. package/dist/CTASection-BJA72XIL.js +0 -106
  288. package/dist/CTASection-BJA72XIL.js.map +0 -1
  289. package/dist/ChallengesSection-GEQGVSJN.js.map +0 -1
  290. package/dist/ChallengesSection-IZ3DHECS.cjs.map +0 -1
  291. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs +0 -209
  292. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs.map +0 -1
  293. package/dist/ConversionFunnelSection-D3GE4NKE.js.map +0 -1
  294. package/dist/DesignSystemSection-2R5BRBGO.js.map +0 -1
  295. package/dist/DesignSystemSection-KXIQXITF.cjs.map +0 -1
  296. package/dist/DetailsSection-A6PZQUQL.js.map +0 -1
  297. package/dist/DetailsSection-TTUZAPZZ.cjs.map +0 -1
  298. package/dist/FeatureSpotlightSection-B7P3JGNL.js.map +0 -1
  299. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs +0 -210
  300. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs.map +0 -1
  301. package/dist/GallerySection-VMKORC47.js.map +0 -1
  302. package/dist/GallerySection-WJ4PQDBI.cjs +0 -219
  303. package/dist/GallerySection-WJ4PQDBI.cjs.map +0 -1
  304. package/dist/MetricsTimelineSection-4L6DUHJ5.cjs.map +0 -1
  305. package/dist/MetricsTimelineSection-6BT5GNFV.js.map +0 -1
  306. package/dist/PerformanceSection-24TVVFZA.cjs.map +0 -1
  307. package/dist/PerformanceSection-MGCEIXDX.js.map +0 -1
  308. package/dist/ResultsSection-DFUJ5U6M.js.map +0 -1
  309. package/dist/ResultsSection-XLGMMQKY.cjs.map +0 -1
  310. package/dist/ServicesSection-D5V3Q4GR.js +0 -118
  311. package/dist/ServicesSection-D5V3Q4GR.js.map +0 -1
  312. package/dist/ServicesSection-WJMGK2MF.cjs +0 -120
  313. package/dist/ServicesSection-WJMGK2MF.cjs.map +0 -1
  314. package/dist/SiteArchitectureSection-J7BPBERH.cjs.map +0 -1
  315. package/dist/SiteArchitectureSection-TE22OAWV.js.map +0 -1
  316. package/dist/SpeedComparisonSection-EZKFQVGW.cjs.map +0 -1
  317. package/dist/SpeedComparisonSection-Y3K7OFZQ.js.map +0 -1
  318. package/dist/StrategySection-CJ7Y6OFQ.cjs +0 -174
  319. package/dist/StrategySection-CJ7Y6OFQ.cjs.map +0 -1
  320. package/dist/StrategySection-DI5RSCJU.js.map +0 -1
  321. package/dist/TeamSection-DZVSNZE6.cjs +0 -112
  322. package/dist/TeamSection-DZVSNZE6.cjs.map +0 -1
  323. package/dist/TeamSection-HGKFW6PQ.js +0 -107
  324. package/dist/TeamSection-HGKFW6PQ.js.map +0 -1
  325. package/dist/TechStackSection-2AQ7RGY3.js +0 -93
  326. package/dist/TechStackSection-2AQ7RGY3.js.map +0 -1
  327. package/dist/TechStackSection-VTNNZR5V.cjs +0 -95
  328. package/dist/TechStackSection-VTNNZR5V.cjs.map +0 -1
  329. package/dist/TestimonialSection-6RGSMXQB.js.map +0 -1
  330. package/dist/TestimonialSection-XPTFUQIN.cjs.map +0 -1
  331. package/dist/VideoSection-4A2HC6K6.js.map +0 -1
  332. package/dist/VideoSection-G3DFS7UH.cjs +0 -118
  333. package/dist/VideoSection-G3DFS7UH.cjs.map +0 -1
  334. package/dist/chunk-2Y4O3LWM.js +0 -53
  335. package/dist/chunk-2Y4O3LWM.js.map +0 -1
  336. package/dist/chunk-633UMQQH.cjs +0 -31
  337. package/dist/chunk-633UMQQH.cjs.map +0 -1
  338. package/dist/chunk-7CFFAKDM.js +0 -74
  339. package/dist/chunk-7CFFAKDM.js.map +0 -1
  340. package/dist/chunk-APG2QSMB.js +0 -131
  341. package/dist/chunk-APG2QSMB.js.map +0 -1
  342. package/dist/chunk-AVCH4LMG.cjs +0 -620
  343. package/dist/chunk-AVCH4LMG.cjs.map +0 -1
  344. package/dist/chunk-AYBUHRFS.js +0 -613
  345. package/dist/chunk-AYBUHRFS.js.map +0 -1
  346. package/dist/chunk-EE75WRCM.cjs.map +0 -1
  347. package/dist/chunk-IKBK7HYX.cjs +0 -79
  348. package/dist/chunk-IKBK7HYX.cjs.map +0 -1
  349. package/dist/chunk-KEOHORIH.cjs +0 -79
  350. package/dist/chunk-KEOHORIH.cjs.map +0 -1
  351. package/dist/chunk-OA5ZM4OA.cjs +0 -139
  352. package/dist/chunk-OA5ZM4OA.cjs.map +0 -1
  353. package/dist/chunk-TVFXN6W6.js.map +0 -1
  354. package/dist/chunk-VVTK4OL6.js +0 -28
  355. package/dist/chunk-VVTK4OL6.js.map +0 -1
  356. package/dist/chunk-XCKXHK44.js +0 -15
  357. package/dist/chunk-XCKXHK44.js.map +0 -1
  358. package/dist/chunk-XONXEFJY.cjs +0 -58
  359. package/dist/chunk-XONXEFJY.cjs.map +0 -1
  360. package/dist/chunk-XQNJED46.cjs +0 -19
  361. package/dist/chunk-XQNJED46.cjs.map +0 -1
  362. package/dist/chunk-YB4B3OMC.js +0 -74
  363. package/dist/chunk-YB4B3OMC.js.map +0 -1
  364. package/dist/portfolio/sections.cjs +0 -20
  365. package/dist/portfolio/sections.cjs.map +0 -1
  366. package/dist/portfolio/sections.d.cts +0 -42
  367. package/dist/portfolio/sections.d.ts +0 -42
  368. package/dist/portfolio/sections.js +0 -4
  369. package/dist/portfolio/sections.js.map +0 -1
@@ -1,8 +1,14 @@
1
1
  'use client';
2
- import { ScrollReveal } from './chunk-7CFFAKDM.js';
3
- import { useState, useCallback, useEffect } from 'react';
4
- import { jsxs, jsx } from 'react/jsx-runtime';
2
+ "use client";
3
+ import {
4
+ resolvePortfolioImage
5
+ } from "../../chunk-QDXZ27R7.js";
5
6
 
7
+ // src/portfolio/components/sections/GallerySection.tsx
8
+ import React, { useState, useCallback, useEffect } from "react";
9
+ import Image from "next/image";
10
+ import ScrollReveal from "@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
6
12
  var typeBadgeColors = {
7
13
  screenshot: {
8
14
  bg: "color-mix(in srgb, #6366f1 12%, transparent)",
@@ -27,6 +33,8 @@ var typeBadgeColors = {
27
33
  };
28
34
  function GallerySection({ data }) {
29
35
  const [lightboxIndex, setLightboxIndex] = useState(null);
36
+ const dialogRef = React.useRef(null);
37
+ const restoreFocusRef = React.useRef(null);
30
38
  const layout = data.layout || "grid";
31
39
  const openLightbox = useCallback((index) => {
32
40
  setLightboxIndex(index);
@@ -46,20 +54,40 @@ function GallerySection({ data }) {
46
54
  }, [data.images.length]);
47
55
  useEffect(() => {
48
56
  if (lightboxIndex === null) return;
57
+ restoreFocusRef.current = document.activeElement;
58
+ const dialog = dialogRef.current;
59
+ const focusables = () => dialog ? Array.from(
60
+ dialog.querySelectorAll('button, [href], [tabindex]:not([tabindex="-1"])')
61
+ ) : [];
62
+ focusables()[0]?.focus();
49
63
  function handleKeyDown(e) {
50
64
  if (e.key === "Escape") closeLightbox();
51
65
  if (e.key === "ArrowRight") goNext();
52
66
  if (e.key === "ArrowLeft") goPrev();
67
+ if (e.key === "Tab") {
68
+ const items = focusables();
69
+ if (items.length === 0) return;
70
+ const first = items[0];
71
+ const last = items[items.length - 1];
72
+ if (e.shiftKey && document.activeElement === first) {
73
+ e.preventDefault();
74
+ last.focus();
75
+ } else if (!e.shiftKey && document.activeElement === last) {
76
+ e.preventDefault();
77
+ first.focus();
78
+ }
79
+ }
53
80
  }
54
81
  document.addEventListener("keydown", handleKeyDown);
55
82
  document.body.style.overflow = "hidden";
56
83
  return () => {
57
84
  document.removeEventListener("keydown", handleKeyDown);
58
85
  document.body.style.overflow = "";
86
+ restoreFocusRef.current?.focus?.();
59
87
  };
60
- }, [lightboxIndex, closeLightbox, goNext, goPrev]);
61
- function getImageUrl(image) {
62
- return image.image.asset._ref || "";
88
+ }, [lightboxIndex !== null, closeLightbox, goNext, goPrev]);
89
+ function getImage(image) {
90
+ return resolvePortfolioImage(image.image);
63
91
  }
64
92
  return /* @__PURE__ */ jsxs(
65
93
  "section",
@@ -84,8 +112,11 @@ function GallerySection({ data }) {
84
112
  {
85
113
  className: layout === "masonry" ? "columns-1 md:columns-2 lg:columns-3 gap-4 space-y-4" : "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
86
114
  children: data.images.map((img, index) => {
87
- const url = getImageUrl(img);
115
+ const resolved = getImage(img);
116
+ if (!resolved) return null;
88
117
  const colors = typeBadgeColors[img.type || "screenshot"] || typeBadgeColors.screenshot;
118
+ const alt = img.caption || `Gallery image ${index + 1}`;
119
+ const imgClass = "w-full h-auto object-cover transition-transform duration-500 group-hover:scale-105";
89
120
  return /* @__PURE__ */ jsxs(
90
121
  "div",
91
122
  {
@@ -95,13 +126,24 @@ function GallerySection({ data }) {
95
126
  },
96
127
  onClick: () => openLightbox(index),
97
128
  children: [
98
- /* @__PURE__ */ jsx(
129
+ resolved.width && resolved.height ? /* @__PURE__ */ jsx(
130
+ Image,
131
+ {
132
+ src: resolved.url,
133
+ alt,
134
+ width: resolved.width,
135
+ height: resolved.height,
136
+ sizes: "(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw",
137
+ className: imgClass
138
+ }
139
+ ) : /* @__PURE__ */ jsx(
99
140
  "img",
100
141
  {
101
- src: url,
102
- alt: img.caption || `Gallery image ${index + 1}`,
103
- className: "w-full h-auto object-cover transition-transform duration-500 group-hover:scale-105",
104
- loading: "lazy"
142
+ src: resolved.url,
143
+ alt,
144
+ className: imgClass,
145
+ loading: "lazy",
146
+ decoding: "async"
105
147
  }
106
148
  ),
107
149
  /* @__PURE__ */ jsx(
@@ -138,6 +180,10 @@ function GallerySection({ data }) {
138
180
  lightboxIndex !== null && /* @__PURE__ */ jsxs(
139
181
  "div",
140
182
  {
183
+ ref: dialogRef,
184
+ role: "dialog",
185
+ "aria-modal": "true",
186
+ "aria-label": data.images[lightboxIndex].caption || `Gallery image ${lightboxIndex + 1} of ${data.images.length}`,
141
187
  className: "fixed inset-0 z-50 flex items-center justify-center",
142
188
  style: { background: "rgba(0,0,0,0.9)" },
143
189
  onClick: closeLightbox,
@@ -196,9 +242,10 @@ function GallerySection({ data }) {
196
242
  /* @__PURE__ */ jsx(
197
243
  "img",
198
244
  {
199
- src: getImageUrl(data.images[lightboxIndex]),
245
+ src: getImage(data.images[lightboxIndex])?.url,
200
246
  alt: data.images[lightboxIndex].caption || "",
201
- className: "max-w-full max-h-[80vh] object-contain rounded-lg"
247
+ className: "max-w-full max-h-[80vh] object-contain rounded-lg",
248
+ decoding: "async"
202
249
  }
203
250
  ),
204
251
  data.images[lightboxIndex].caption && /* @__PURE__ */ jsx("p", { className: "text-sm text-white/70 text-center", children: data.images[lightboxIndex].caption })
@@ -212,7 +259,7 @@ function GallerySection({ data }) {
212
259
  }
213
260
  );
214
261
  }
215
-
216
- export { GallerySection as default };
217
- //# sourceMappingURL=GallerySection-VMKORC47.js.map
218
- //# sourceMappingURL=GallerySection-VMKORC47.js.map
262
+ export {
263
+ GallerySection as default
264
+ };
265
+ //# sourceMappingURL=GallerySection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/GallerySection.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport Image from 'next/image';\nimport type { PortfolioGalleryData } from '../../../types';\nimport { resolvePortfolioImage } from '../../../shared/images';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\n\ninterface GallerySectionProps {\n data: PortfolioGalleryData;\n}\n\nconst typeBadgeColors: Record<string, { bg: string; text: string; border: string }> = {\n screenshot: {\n bg: 'color-mix(in srgb, #6366f1 12%, transparent)',\n text: '#6366f1',\n border: 'color-mix(in srgb, #6366f1 20%, transparent)',\n },\n before: {\n bg: 'color-mix(in srgb, #f59e0b 12%, transparent)',\n text: '#f59e0b',\n border: 'color-mix(in srgb, #f59e0b 20%, transparent)',\n },\n after: {\n bg: 'color-mix(in srgb, #10b981 12%, transparent)',\n text: '#10b981',\n border: 'color-mix(in srgb, #10b981 20%, transparent)',\n },\n design: {\n bg: 'color-mix(in srgb, #ec4899 12%, transparent)',\n text: '#ec4899',\n border: 'color-mix(in srgb, #ec4899 20%, transparent)',\n },\n};\n\nexport default function GallerySection({ data }: GallerySectionProps) {\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);\n const dialogRef = React.useRef<HTMLDivElement>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n const layout = data.layout || 'grid';\n\n const openLightbox = useCallback((index: number) => {\n setLightboxIndex(index);\n }, []);\n\n const closeLightbox = useCallback(() => {\n setLightboxIndex(null);\n }, []);\n\n const goNext = useCallback(() => {\n setLightboxIndex((prev) =>\n prev !== null ? (prev + 1) % data.images.length : null,\n );\n }, [data.images.length]);\n\n const goPrev = useCallback(() => {\n setLightboxIndex((prev) =>\n prev !== null ? (prev - 1 + data.images.length) % data.images.length : null,\n );\n }, [data.images.length]);\n\n // Keyboard navigation + dialog focus management\n useEffect(() => {\n if (lightboxIndex === null) return;\n\n // Move focus into the dialog; restore it to the trigger on close.\n restoreFocusRef.current = document.activeElement as HTMLElement | null;\n const dialog = dialogRef.current;\n const focusables = () =>\n dialog\n ? Array.from(\n dialog.querySelectorAll<HTMLElement>('button, [href], [tabindex]:not([tabindex=\"-1\"])'),\n )\n : [];\n focusables()[0]?.focus();\n\n function handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') closeLightbox();\n if (e.key === 'ArrowRight') goNext();\n if (e.key === 'ArrowLeft') goPrev();\n if (e.key === 'Tab') {\n // Trap Tab inside the dialog\n const items = focusables();\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n document.addEventListener('keydown', handleKeyDown);\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n document.body.style.overflow = '';\n restoreFocusRef.current?.focus?.();\n };\n }, [lightboxIndex !== null, closeLightbox, goNext, goPrev]); // eslint-disable-line react-hooks/exhaustive-deps\n\n function getImage(image: typeof data.images[0]) {\n // URL (+ intrinsic dims when derivable); raw Sanity refs resolve to null.\n return resolvePortfolioImage(image.image);\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-7xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-12\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Gallery\n </h2>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.08}>\n <div\n className={\n layout === 'masonry'\n ? 'columns-1 md:columns-2 lg:columns-3 gap-4 space-y-4'\n : 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'\n }\n >\n {data.images.map((img, index) => {\n const resolved = getImage(img);\n if (!resolved) return null;\n const colors = typeBadgeColors[img.type || 'screenshot'] || typeBadgeColors.screenshot;\n const alt = img.caption || `Gallery image ${index + 1}`;\n const imgClass =\n 'w-full h-auto object-cover transition-transform duration-500 group-hover:scale-105';\n\n return (\n <div\n key={index}\n className={`relative group cursor-pointer overflow-hidden rounded-xl ${\n layout === 'masonry' ? 'break-inside-avoid' : ''\n }`}\n style={{\n border: '1px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n onClick={() => openLightbox(index)}\n >\n {resolved.width && resolved.height ? (\n <Image\n src={resolved.url}\n alt={alt}\n width={resolved.width}\n height={resolved.height}\n sizes=\"(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw\"\n className={imgClass}\n />\n ) : (\n <img\n src={resolved.url}\n alt={alt}\n className={imgClass}\n loading=\"lazy\"\n decoding=\"async\"\n />\n )}\n\n {/* Overlay on hover */}\n <div\n className=\"absolute inset-0 flex flex-col justify-end p-4 opacity-0 group-hover:opacity-100 transition-opacity duration-300\"\n style={{\n background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%)',\n }}\n >\n {img.caption && (\n <p className=\"text-sm text-white font-medium\">{img.caption}</p>\n )}\n </div>\n\n {/* Type badge */}\n {img.type && (\n <span\n className=\"absolute top-3 left-3 px-2.5 py-1 rounded-full text-[11px] uppercase tracking-wider font-medium\"\n style={{\n background: colors.bg,\n color: colors.text,\n border: `1px solid ${colors.border}`,\n backdropFilter: 'blur(8px)',\n }}\n >\n {img.type}\n </span>\n )}\n </div>\n );\n })}\n </div>\n </ScrollReveal>\n </div>\n\n {/* Lightbox modal */}\n {lightboxIndex !== null && (\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={data.images[lightboxIndex].caption || `Gallery image ${lightboxIndex + 1} of ${data.images.length}`}\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n style={{ background: 'rgba(0,0,0,0.9)' }}\n onClick={closeLightbox}\n >\n {/* Close button */}\n <button\n onClick={closeLightbox}\n className=\"absolute top-6 right-6 w-10 h-10 flex items-center justify-center rounded-full transition-colors z-10\"\n style={{\n background: 'rgba(255,255,255,0.1)',\n color: '#ffffff',\n }}\n aria-label=\"Close lightbox\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M15 5L5 15M5 5l10 10\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n\n {/* Prev button */}\n <button\n onClick={(e) => { e.stopPropagation(); goPrev(); }}\n className=\"absolute left-4 md:left-8 w-12 h-12 flex items-center justify-center rounded-full transition-colors z-10\"\n style={{\n background: 'rgba(255,255,255,0.1)',\n color: '#ffffff',\n }}\n aria-label=\"Previous image\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M12.5 15l-5-5 5-5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n {/* Next button */}\n <button\n onClick={(e) => { e.stopPropagation(); goNext(); }}\n className=\"absolute right-4 md:right-8 w-12 h-12 flex items-center justify-center rounded-full transition-colors z-10\"\n style={{\n background: 'rgba(255,255,255,0.1)',\n color: '#ffffff',\n }}\n aria-label=\"Next image\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M7.5 5l5 5-5 5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n {/* Image */}\n <div\n className=\"max-w-[90vw] max-h-[85vh] flex flex-col items-center gap-4\"\n onClick={(e) => e.stopPropagation()}\n >\n <img\n src={getImage(data.images[lightboxIndex])?.url}\n alt={data.images[lightboxIndex].caption || ''}\n className=\"max-w-full max-h-[80vh] object-contain rounded-lg\"\n decoding=\"async\"\n />\n {data.images[lightboxIndex].caption && (\n <p className=\"text-sm text-white/70 text-center\">\n {data.images[lightboxIndex].caption}\n </p>\n )}\n </div>\n </div>\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,180 @@
1
+ 'use strict';
2
+
3
+ var ScrollReveal = require('@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal');
4
+ var AnimatedCounter = require('@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter');
5
+ var GlassCard = require('@sonordev/agency-site-kit/portfolio/primitives/GlassCard');
6
+ var DeviceTrifolio = require('@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var ScrollReveal__default = /*#__PURE__*/_interopDefault(ScrollReveal);
12
+ var AnimatedCounter__default = /*#__PURE__*/_interopDefault(AnimatedCounter);
13
+ var GlassCard__default = /*#__PURE__*/_interopDefault(GlassCard);
14
+ var DeviceTrifolio__default = /*#__PURE__*/_interopDefault(DeviceTrifolio);
15
+
16
+ // src/portfolio/components/sections/HeroSection.tsx
17
+ var HERO_PARALLAX_CSS = `
18
+ @supports (animation-timeline: view()) {
19
+ @media (prefers-reduced-motion: no-preference) {
20
+ .sk-hero-bg {
21
+ animation: sk-hero-drift linear both;
22
+ animation-timeline: view(block);
23
+ animation-range: exit 0% exit 100%;
24
+ }
25
+ @keyframes sk-hero-drift {
26
+ from { transform: translateY(0); }
27
+ to { transform: translateY(30%); }
28
+ }
29
+ }
30
+ }
31
+ `;
32
+ function HeroSection({ data, screenshots, liveUrl }) {
33
+ const shots = screenshots || data.screenshots;
34
+ const url = liveUrl || data.liveUrl;
35
+ return /* @__PURE__ */ jsxRuntime.jsxs(
36
+ "section",
37
+ {
38
+ className: "relative overflow-hidden w-full",
39
+ style: {
40
+ minHeight: "90vh",
41
+ display: "flex",
42
+ flexDirection: "column",
43
+ justifyContent: "center",
44
+ background: "var(--sk-bg, #0a0a0a)"
45
+ },
46
+ children: [
47
+ /* @__PURE__ */ jsxRuntime.jsx("style", { href: "sk-hero-parallax", precedence: "default", children: HERO_PARALLAX_CSS }),
48
+ /* @__PURE__ */ jsxRuntime.jsx(
49
+ "div",
50
+ {
51
+ className: "sk-hero-bg absolute inset-0 pointer-events-none",
52
+ style: {
53
+ background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,
54
+ willChange: "transform"
55
+ }
56
+ }
57
+ ),
58
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start", children: [
59
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-6", children: [
60
+ /* @__PURE__ */ jsxRuntime.jsx(
61
+ "span",
62
+ {
63
+ className: "inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium",
64
+ style: {
65
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
66
+ color: "var(--sk-primary, #6366f1)",
67
+ border: "1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)"
68
+ },
69
+ children: data.category?.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
70
+ }
71
+ ),
72
+ /* @__PURE__ */ jsxRuntime.jsx(
73
+ "h1",
74
+ {
75
+ className: "text-4xl md:text-5xl lg:text-6xl font-bold leading-tight",
76
+ style: {
77
+ color: "var(--sk-text-primary, #ffffff)",
78
+ fontFamily: "var(--sk-font-heading, inherit)",
79
+ overflowWrap: "break-word",
80
+ wordBreak: "break-word"
81
+ },
82
+ children: data.headline
83
+ }
84
+ ),
85
+ /* @__PURE__ */ jsxRuntime.jsx(
86
+ "p",
87
+ {
88
+ className: "text-xl md:text-2xl font-medium",
89
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
90
+ children: data.subheadline
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsxRuntime.jsx(
94
+ "p",
95
+ {
96
+ className: "text-base md:text-lg leading-relaxed",
97
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
98
+ children: data.description
99
+ }
100
+ ),
101
+ data.services.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: data.services.map((service) => /* @__PURE__ */ jsxRuntime.jsx(
102
+ "span",
103
+ {
104
+ className: "px-3 py-1 rounded-full text-xs font-medium",
105
+ style: {
106
+ background: "var(--sk-surface, rgba(255,255,255,0.05))",
107
+ color: "var(--sk-text-secondary, #a1a1aa)",
108
+ border: "1px solid var(--sk-border, rgba(255,255,255,0.1))"
109
+ },
110
+ children: service
111
+ },
112
+ service
113
+ )) }),
114
+ url && /* @__PURE__ */ jsxRuntime.jsxs(
115
+ "a",
116
+ {
117
+ href: url,
118
+ target: "_blank",
119
+ rel: "noopener noreferrer",
120
+ "data-portfolio-action": "live-site",
121
+ className: "inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90",
122
+ style: {
123
+ background: "var(--sk-primary, #6366f1)",
124
+ color: "#ffffff"
125
+ },
126
+ children: [
127
+ "View Live Site",
128
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 3h7v7M13 3L3 13", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
129
+ ]
130
+ }
131
+ )
132
+ ] }),
133
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-10 lg:pt-8", children: [
134
+ (url || shots?.desktop || shots?.tablet || shots?.mobile) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
135
+ DeviceTrifolio__default.default,
136
+ {
137
+ screenshots: {
138
+ desktop: shots?.desktop,
139
+ tablet: shots?.tablet,
140
+ mobile: shots?.mobile
141
+ },
142
+ url
143
+ }
144
+ ) }),
145
+ data.kpis.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ScrollReveal__default.default, { y: 30, delay: 0.6, stagger: 0.1, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: data.kpis.map((kpi, i) => /* @__PURE__ */ jsxRuntime.jsxs(GlassCard__default.default, { padding: "sm", hover: false, className: "text-center", children: [
146
+ /* @__PURE__ */ jsxRuntime.jsx(
147
+ "div",
148
+ {
149
+ className: "text-2xl md:text-3xl font-bold",
150
+ style: { color: "var(--sk-primary, #6366f1)" },
151
+ children: /* @__PURE__ */ jsxRuntime.jsx(
152
+ AnimatedCounter__default.default,
153
+ {
154
+ value: kpi.value,
155
+ suffix: kpi.suffix,
156
+ prefix: kpi.prefix,
157
+ duration: 2.5
158
+ }
159
+ )
160
+ }
161
+ ),
162
+ /* @__PURE__ */ jsxRuntime.jsx(
163
+ "div",
164
+ {
165
+ className: "text-xs mt-1 font-medium",
166
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
167
+ children: kpi.label
168
+ }
169
+ )
170
+ ] }, i)) }) })
171
+ ] })
172
+ ] }) })
173
+ ]
174
+ }
175
+ );
176
+ }
177
+
178
+ module.exports = HeroSection;
179
+ //# sourceMappingURL=HeroSection.cjs.map
180
+ //# sourceMappingURL=HeroSection.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/HeroSection.tsx"],"names":["jsxs","jsx","DeviceTrifolio","ScrollReveal","GlassCard","AnimatedCounter"],"mappings":"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","file":"HeroSection.cjs","sourcesContent":["// Server component — the entire hero renders on the server and ships zero\n// component JS. Client primitives (counter, reveal, trifolio) cross the RSC\n// boundary via package subpaths.\nimport React from 'react';\nimport type { PortfolioHeroData } from '../../../types';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\nimport DeviceTrifolio from '@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio';\n\n// LCP rule (monorepo CLAUDE.md, Performance): above-the-fold content renders\n// fully static — no entrance animation, no post-hydration re-hide. The text\n// column below must never be wrapped in ScrollReveal/SplitHeadline: hiding\n// the H1 after hydration moves LCP to the tween's end and tanks the mobile\n// Lighthouse score. Reveal animations are for the below-fold KPI cards only.\n\n// Background parallax as a CSS scroll-driven animation — progressive\n// enhancement: browsers without animation-timeline get a static gradient.\nconst HERO_PARALLAX_CSS = `\n@supports (animation-timeline: view()) {\n @media (prefers-reduced-motion: no-preference) {\n .sk-hero-bg {\n animation: sk-hero-drift linear both;\n animation-timeline: view(block);\n animation-range: exit 0% exit 100%;\n }\n @keyframes sk-hero-drift {\n from { transform: translateY(0); }\n to { transform: translateY(30%); }\n }\n }\n}\n`;\n\ninterface HeroSectionProps {\n data: PortfolioHeroData;\n screenshots?: { desktop?: string; tablet?: string; mobile?: string };\n liveUrl?: string;\n}\n\nexport default function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps) {\n const shots = screenshots || data.screenshots;\n const url = liveUrl || data.liveUrl;\n\n return (\n <section\n className=\"relative overflow-hidden w-full\"\n style={{\n minHeight: '90vh',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n background: 'var(--sk-bg, #0a0a0a)',\n }}\n >\n {/* Parallax background layer (CSS scroll-driven) */}\n <style href=\"sk-hero-parallax\" precedence=\"default\">\n {HERO_PARALLAX_CSS}\n </style>\n <div\n className=\"sk-hero-bg absolute inset-0 pointer-events-none\"\n style={{\n background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,\n willChange: 'transform',\n }}\n />\n\n <div className=\"relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32\">\n <div className=\"grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start\">\n {/* Text column — min-w-0 so grid track can shrink below content intrinsic width (mobile) */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-6\">\n {/* Category badge */}\n <span\n className=\"inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n }}\n >\n {data.category?.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (c: string) => c.toUpperCase())}\n </span>\n\n {/* Headline — static, this is usually the LCP element */}\n <h1\n className=\"text-4xl md:text-5xl lg:text-6xl font-bold leading-tight\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n overflowWrap: 'break-word',\n wordBreak: 'break-word',\n }}\n >\n {data.headline}\n </h1>\n\n {/* Subheadline */}\n <p\n className=\"text-xl md:text-2xl font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.subheadline}\n </p>\n\n {/* Description */}\n <p\n className=\"text-base md:text-lg leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {data.description}\n </p>\n\n {/* Services tags */}\n {data.services.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {data.services.map((service) => (\n <span\n key={service}\n className=\"px-3 py-1 rounded-full text-xs font-medium\"\n style={{\n background: 'var(--sk-surface, rgba(255,255,255,0.05))',\n color: 'var(--sk-text-secondary, #a1a1aa)',\n border: '1px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n >\n {service}\n </span>\n ))}\n </div>\n )}\n\n {/* CTA button */}\n {url && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-portfolio-action=\"live-site\"\n className=\"inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90\"\n style={{\n background: 'var(--sk-primary, #6366f1)',\n color: '#ffffff',\n }}\n >\n View Live Site\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 3h7v7M13 3L3 13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </a>\n )}\n\n </div>\n\n {/* Right column — trifolio + KPIs */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-10 lg:pt-8\">\n {/* Device trifolio — realistic device frames */}\n {(url || shots?.desktop || shots?.tablet || shots?.mobile) && (\n <div className=\"min-w-0 max-w-full\">\n <DeviceTrifolio\n screenshots={{\n desktop: shots?.desktop,\n tablet: shots?.tablet,\n mobile: shots?.mobile,\n }}\n url={url}\n />\n </div>\n )}\n\n {/* KPI cards — below trifolio in right column */}\n {data.kpis.length > 0 && (\n <ScrollReveal y={30} delay={0.6} stagger={0.1}>\n <div className=\"grid grid-cols-2 gap-3\">\n {data.kpis.map((kpi, i) => (\n <GlassCard key={i} padding=\"sm\" hover={false} className=\"text-center\">\n <div\n className=\"text-2xl md:text-3xl font-bold\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <AnimatedCounter\n value={kpi.value}\n suffix={kpi.suffix}\n prefix={kpi.prefix}\n duration={2.5}\n />\n </div>\n <div\n className=\"text-xs mt-1 font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {kpi.label}\n </div>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n )}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { e as PortfolioHeroData } from '../../types-0tVPy4pU.cjs';
3
+
4
+ interface HeroSectionProps {
5
+ data: PortfolioHeroData;
6
+ screenshots?: {
7
+ desktop?: string;
8
+ tablet?: string;
9
+ mobile?: string;
10
+ };
11
+ liveUrl?: string;
12
+ }
13
+ declare function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps): React.JSX.Element;
14
+
15
+ export { HeroSection as default };
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { e as PortfolioHeroData } from '../../types-0tVPy4pU.js';
3
+
4
+ interface HeroSectionProps {
5
+ data: PortfolioHeroData;
6
+ screenshots?: {
7
+ desktop?: string;
8
+ tablet?: string;
9
+ mobile?: string;
10
+ };
11
+ liveUrl?: string;
12
+ }
13
+ declare function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps): React.JSX.Element;
14
+
15
+ export { HeroSection as default };
@@ -0,0 +1,171 @@
1
+ import ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';
2
+ import AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';
3
+ import GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';
4
+ import DeviceTrifolio from '@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ // src/portfolio/components/sections/HeroSection.tsx
8
+ var HERO_PARALLAX_CSS = `
9
+ @supports (animation-timeline: view()) {
10
+ @media (prefers-reduced-motion: no-preference) {
11
+ .sk-hero-bg {
12
+ animation: sk-hero-drift linear both;
13
+ animation-timeline: view(block);
14
+ animation-range: exit 0% exit 100%;
15
+ }
16
+ @keyframes sk-hero-drift {
17
+ from { transform: translateY(0); }
18
+ to { transform: translateY(30%); }
19
+ }
20
+ }
21
+ }
22
+ `;
23
+ function HeroSection({ data, screenshots, liveUrl }) {
24
+ const shots = screenshots || data.screenshots;
25
+ const url = liveUrl || data.liveUrl;
26
+ return /* @__PURE__ */ jsxs(
27
+ "section",
28
+ {
29
+ className: "relative overflow-hidden w-full",
30
+ style: {
31
+ minHeight: "90vh",
32
+ display: "flex",
33
+ flexDirection: "column",
34
+ justifyContent: "center",
35
+ background: "var(--sk-bg, #0a0a0a)"
36
+ },
37
+ children: [
38
+ /* @__PURE__ */ jsx("style", { href: "sk-hero-parallax", precedence: "default", children: HERO_PARALLAX_CSS }),
39
+ /* @__PURE__ */ jsx(
40
+ "div",
41
+ {
42
+ className: "sk-hero-bg absolute inset-0 pointer-events-none",
43
+ style: {
44
+ background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,
45
+ willChange: "transform"
46
+ }
47
+ }
48
+ ),
49
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start", children: [
50
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-6", children: [
51
+ /* @__PURE__ */ jsx(
52
+ "span",
53
+ {
54
+ className: "inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium",
55
+ style: {
56
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
57
+ color: "var(--sk-primary, #6366f1)",
58
+ border: "1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)"
59
+ },
60
+ children: data.category?.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
61
+ }
62
+ ),
63
+ /* @__PURE__ */ jsx(
64
+ "h1",
65
+ {
66
+ className: "text-4xl md:text-5xl lg:text-6xl font-bold leading-tight",
67
+ style: {
68
+ color: "var(--sk-text-primary, #ffffff)",
69
+ fontFamily: "var(--sk-font-heading, inherit)",
70
+ overflowWrap: "break-word",
71
+ wordBreak: "break-word"
72
+ },
73
+ children: data.headline
74
+ }
75
+ ),
76
+ /* @__PURE__ */ jsx(
77
+ "p",
78
+ {
79
+ className: "text-xl md:text-2xl font-medium",
80
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
81
+ children: data.subheadline
82
+ }
83
+ ),
84
+ /* @__PURE__ */ jsx(
85
+ "p",
86
+ {
87
+ className: "text-base md:text-lg leading-relaxed",
88
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
89
+ children: data.description
90
+ }
91
+ ),
92
+ data.services.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: data.services.map((service) => /* @__PURE__ */ jsx(
93
+ "span",
94
+ {
95
+ className: "px-3 py-1 rounded-full text-xs font-medium",
96
+ style: {
97
+ background: "var(--sk-surface, rgba(255,255,255,0.05))",
98
+ color: "var(--sk-text-secondary, #a1a1aa)",
99
+ border: "1px solid var(--sk-border, rgba(255,255,255,0.1))"
100
+ },
101
+ children: service
102
+ },
103
+ service
104
+ )) }),
105
+ url && /* @__PURE__ */ jsxs(
106
+ "a",
107
+ {
108
+ href: url,
109
+ target: "_blank",
110
+ rel: "noopener noreferrer",
111
+ "data-portfolio-action": "live-site",
112
+ className: "inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90",
113
+ style: {
114
+ background: "var(--sk-primary, #6366f1)",
115
+ color: "#ffffff"
116
+ },
117
+ children: [
118
+ "View Live Site",
119
+ /* @__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" }) })
120
+ ]
121
+ }
122
+ )
123
+ ] }),
124
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-10 lg:pt-8", children: [
125
+ (url || shots?.desktop || shots?.tablet || shots?.mobile) && /* @__PURE__ */ jsx("div", { className: "min-w-0 max-w-full", children: /* @__PURE__ */ jsx(
126
+ DeviceTrifolio,
127
+ {
128
+ screenshots: {
129
+ desktop: shots?.desktop,
130
+ tablet: shots?.tablet,
131
+ mobile: shots?.mobile
132
+ },
133
+ url
134
+ }
135
+ ) }),
136
+ data.kpis.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 30, delay: 0.6, stagger: 0.1, children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: data.kpis.map((kpi, i) => /* @__PURE__ */ jsxs(GlassCard, { padding: "sm", hover: false, className: "text-center", children: [
137
+ /* @__PURE__ */ jsx(
138
+ "div",
139
+ {
140
+ className: "text-2xl md:text-3xl font-bold",
141
+ style: { color: "var(--sk-primary, #6366f1)" },
142
+ children: /* @__PURE__ */ jsx(
143
+ AnimatedCounter,
144
+ {
145
+ value: kpi.value,
146
+ suffix: kpi.suffix,
147
+ prefix: kpi.prefix,
148
+ duration: 2.5
149
+ }
150
+ )
151
+ }
152
+ ),
153
+ /* @__PURE__ */ jsx(
154
+ "div",
155
+ {
156
+ className: "text-xs mt-1 font-medium",
157
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
158
+ children: kpi.label
159
+ }
160
+ )
161
+ ] }, i)) }) })
162
+ ] })
163
+ ] }) })
164
+ ]
165
+ }
166
+ );
167
+ }
168
+
169
+ export { HeroSection as default };
170
+ //# sourceMappingURL=HeroSection.js.map
171
+ //# sourceMappingURL=HeroSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/HeroSection.tsx"],"names":[],"mappings":"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","file":"HeroSection.js","sourcesContent":["// Server component — the entire hero renders on the server and ships zero\n// component JS. Client primitives (counter, reveal, trifolio) cross the RSC\n// boundary via package subpaths.\nimport React from 'react';\nimport type { PortfolioHeroData } from '../../../types';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\nimport DeviceTrifolio from '@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio';\n\n// LCP rule (monorepo CLAUDE.md, Performance): above-the-fold content renders\n// fully static — no entrance animation, no post-hydration re-hide. The text\n// column below must never be wrapped in ScrollReveal/SplitHeadline: hiding\n// the H1 after hydration moves LCP to the tween's end and tanks the mobile\n// Lighthouse score. Reveal animations are for the below-fold KPI cards only.\n\n// Background parallax as a CSS scroll-driven animation — progressive\n// enhancement: browsers without animation-timeline get a static gradient.\nconst HERO_PARALLAX_CSS = `\n@supports (animation-timeline: view()) {\n @media (prefers-reduced-motion: no-preference) {\n .sk-hero-bg {\n animation: sk-hero-drift linear both;\n animation-timeline: view(block);\n animation-range: exit 0% exit 100%;\n }\n @keyframes sk-hero-drift {\n from { transform: translateY(0); }\n to { transform: translateY(30%); }\n }\n }\n}\n`;\n\ninterface HeroSectionProps {\n data: PortfolioHeroData;\n screenshots?: { desktop?: string; tablet?: string; mobile?: string };\n liveUrl?: string;\n}\n\nexport default function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps) {\n const shots = screenshots || data.screenshots;\n const url = liveUrl || data.liveUrl;\n\n return (\n <section\n className=\"relative overflow-hidden w-full\"\n style={{\n minHeight: '90vh',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n background: 'var(--sk-bg, #0a0a0a)',\n }}\n >\n {/* Parallax background layer (CSS scroll-driven) */}\n <style href=\"sk-hero-parallax\" precedence=\"default\">\n {HERO_PARALLAX_CSS}\n </style>\n <div\n className=\"sk-hero-bg absolute inset-0 pointer-events-none\"\n style={{\n background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,\n willChange: 'transform',\n }}\n />\n\n <div className=\"relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32\">\n <div className=\"grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start\">\n {/* Text column — min-w-0 so grid track can shrink below content intrinsic width (mobile) */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-6\">\n {/* Category badge */}\n <span\n className=\"inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n }}\n >\n {data.category?.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (c: string) => c.toUpperCase())}\n </span>\n\n {/* Headline — static, this is usually the LCP element */}\n <h1\n className=\"text-4xl md:text-5xl lg:text-6xl font-bold leading-tight\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n overflowWrap: 'break-word',\n wordBreak: 'break-word',\n }}\n >\n {data.headline}\n </h1>\n\n {/* Subheadline */}\n <p\n className=\"text-xl md:text-2xl font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.subheadline}\n </p>\n\n {/* Description */}\n <p\n className=\"text-base md:text-lg leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {data.description}\n </p>\n\n {/* Services tags */}\n {data.services.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {data.services.map((service) => (\n <span\n key={service}\n className=\"px-3 py-1 rounded-full text-xs font-medium\"\n style={{\n background: 'var(--sk-surface, rgba(255,255,255,0.05))',\n color: 'var(--sk-text-secondary, #a1a1aa)',\n border: '1px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n >\n {service}\n </span>\n ))}\n </div>\n )}\n\n {/* CTA button */}\n {url && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-portfolio-action=\"live-site\"\n className=\"inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90\"\n style={{\n background: 'var(--sk-primary, #6366f1)',\n color: '#ffffff',\n }}\n >\n View Live Site\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 3h7v7M13 3L3 13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </a>\n )}\n\n </div>\n\n {/* Right column — trifolio + KPIs */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-10 lg:pt-8\">\n {/* Device trifolio — realistic device frames */}\n {(url || shots?.desktop || shots?.tablet || shots?.mobile) && (\n <div className=\"min-w-0 max-w-full\">\n <DeviceTrifolio\n screenshots={{\n desktop: shots?.desktop,\n tablet: shots?.tablet,\n mobile: shots?.mobile,\n }}\n url={url}\n />\n </div>\n )}\n\n {/* KPI cards — below trifolio in right column */}\n {data.kpis.length > 0 && (\n <ScrollReveal y={30} delay={0.6} stagger={0.1}>\n <div className=\"grid grid-cols-2 gap-3\">\n {data.kpis.map((kpi, i) => (\n <GlassCard key={i} padding=\"sm\" hover={false} className=\"text-center\">\n <div\n className=\"text-2xl md:text-3xl font-bold\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <AnimatedCounter\n value={kpi.value}\n suffix={kpi.suffix}\n prefix={kpi.prefix}\n duration={2.5}\n />\n </div>\n <div\n className=\"text-xs mt-1 font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {kpi.label}\n </div>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n )}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}