@sonordev/agency-site-kit 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) 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-WNR4KNG4.cjs → chunk-5MEZU3OG.cjs} +4 -4
  6. package/dist/{chunk-WNR4KNG4.cjs.map → chunk-5MEZU3OG.cjs.map} +1 -1
  7. package/dist/chunk-7D4H36UF.js +13 -0
  8. package/dist/chunk-7D4H36UF.js.map +1 -0
  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-K2BGTDSN.js +45 -0
  16. package/dist/chunk-K2BGTDSN.js.map +1 -0
  17. package/dist/chunk-KXLROAO5.js +291 -0
  18. package/dist/chunk-KXLROAO5.js.map +1 -0
  19. package/dist/chunk-L4EOQVRJ.js +6 -0
  20. package/dist/chunk-L4EOQVRJ.js.map +1 -0
  21. package/dist/chunk-NI4FVCLS.cjs +32 -0
  22. package/dist/chunk-NI4FVCLS.cjs.map +1 -0
  23. package/dist/chunk-NLGUPJZA.js +507 -0
  24. package/dist/chunk-NLGUPJZA.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-QGSW43TM.cjs +538 -0
  28. package/dist/chunk-QGSW43TM.cjs.map +1 -0
  29. package/dist/{chunk-TVFXN6W6.js → chunk-QL6KVIFR.js} +8 -4
  30. package/dist/chunk-QL6KVIFR.js.map +1 -0
  31. package/dist/chunk-RWQ675N6.js +165 -0
  32. package/dist/chunk-RWQ675N6.js.map +1 -0
  33. package/dist/chunk-UXUU7FVT.cjs +171 -0
  34. package/dist/chunk-UXUU7FVT.cjs.map +1 -0
  35. package/dist/chunk-XJ434N7I.js +30 -0
  36. package/dist/chunk-XJ434N7I.js.map +1 -0
  37. package/dist/{chunk-EE75WRCM.cjs → chunk-XOWSXZYW.cjs} +8 -4
  38. package/dist/chunk-XOWSXZYW.cjs.map +1 -0
  39. package/dist/chunk-ZBPF7TLZ.cjs +16 -0
  40. package/dist/chunk-ZBPF7TLZ.cjs.map +1 -0
  41. package/dist/chunk-ZINKVJQU.js +67 -0
  42. package/dist/chunk-ZINKVJQU.js.map +1 -0
  43. package/dist/index.cjs +53 -30
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts +17 -9
  46. package/dist/index.d.ts +17 -9
  47. package/dist/index.js +8 -9
  48. package/dist/index.js.map +1 -1
  49. package/dist/layout/index.cjs +3 -3
  50. package/dist/layout/index.d.cts +1 -1
  51. package/dist/layout/index.d.ts +1 -1
  52. package/dist/layout/index.js +2 -2
  53. package/dist/portfolio/client.cjs +376 -12
  54. package/dist/portfolio/client.cjs.map +1 -1
  55. package/dist/portfolio/client.d.cts +27 -85
  56. package/dist/portfolio/client.d.ts +27 -85
  57. package/dist/portfolio/client.js +182 -4
  58. package/dist/portfolio/client.js.map +1 -1
  59. package/dist/portfolio/components/PortfolioAnalytics.cjs +87 -0
  60. package/dist/portfolio/components/PortfolioAnalytics.cjs.map +1 -0
  61. package/dist/portfolio/components/PortfolioAnalytics.d.cts +5 -0
  62. package/dist/portfolio/components/PortfolioAnalytics.d.ts +5 -0
  63. package/dist/portfolio/components/PortfolioAnalytics.js +9 -0
  64. package/dist/portfolio/components/PortfolioAnalytics.js.map +1 -0
  65. package/dist/portfolio/components/PortfolioErrorFallback.cjs +65 -0
  66. package/dist/portfolio/components/PortfolioErrorFallback.cjs.map +1 -0
  67. package/dist/portfolio/components/PortfolioErrorFallback.d.cts +22 -0
  68. package/dist/portfolio/components/PortfolioErrorFallback.d.ts +22 -0
  69. package/dist/portfolio/components/PortfolioErrorFallback.js +9 -0
  70. package/dist/portfolio/components/PortfolioErrorFallback.js.map +1 -0
  71. package/dist/portfolio/components/PortfolioLeadCTA.cjs +91 -0
  72. package/dist/portfolio/components/PortfolioLeadCTA.cjs.map +1 -0
  73. package/dist/portfolio/components/PortfolioLeadCTA.d.cts +34 -0
  74. package/dist/portfolio/components/PortfolioLeadCTA.d.ts +34 -0
  75. package/dist/portfolio/components/PortfolioLeadCTA.js +9 -0
  76. package/dist/portfolio/components/PortfolioLeadCTA.js.map +1 -0
  77. package/dist/portfolio/index.cjs +43 -19
  78. package/dist/portfolio/index.d.cts +210 -7
  79. package/dist/portfolio/index.d.ts +210 -7
  80. package/dist/portfolio/index.js +7 -7
  81. package/dist/portfolio/primitives/AnimatedCounter.cjs +88 -0
  82. package/dist/portfolio/primitives/AnimatedCounter.cjs.map +1 -0
  83. package/dist/portfolio/primitives/AnimatedCounter.d.cts +22 -0
  84. package/dist/portfolio/primitives/AnimatedCounter.d.ts +22 -0
  85. package/dist/portfolio/primitives/AnimatedCounter.js +68 -0
  86. package/dist/portfolio/primitives/AnimatedCounter.js.map +1 -0
  87. package/dist/portfolio/primitives/AnnotatedImage.cjs +320 -0
  88. package/dist/portfolio/primitives/AnnotatedImage.cjs.map +1 -0
  89. package/dist/portfolio/primitives/AnnotatedImage.d.cts +18 -0
  90. package/dist/portfolio/primitives/AnnotatedImage.d.ts +18 -0
  91. package/dist/portfolio/primitives/AnnotatedImage.js +264 -0
  92. package/dist/portfolio/primitives/AnnotatedImage.js.map +1 -0
  93. package/dist/portfolio/primitives/BeforeAfterSlider.cjs +348 -0
  94. package/dist/portfolio/primitives/BeforeAfterSlider.cjs.map +1 -0
  95. package/dist/portfolio/primitives/BeforeAfterSlider.d.cts +13 -0
  96. package/dist/portfolio/primitives/BeforeAfterSlider.d.ts +13 -0
  97. package/dist/portfolio/primitives/BeforeAfterSlider.js +292 -0
  98. package/dist/portfolio/primitives/BeforeAfterSlider.js.map +1 -0
  99. package/dist/portfolio/primitives/DeviceTrifolio.cjs +298 -0
  100. package/dist/portfolio/primitives/DeviceTrifolio.cjs.map +1 -0
  101. package/dist/portfolio/primitives/DeviceTrifolio.d.cts +14 -0
  102. package/dist/portfolio/primitives/DeviceTrifolio.d.ts +14 -0
  103. package/dist/portfolio/primitives/DeviceTrifolio.js +242 -0
  104. package/dist/portfolio/primitives/DeviceTrifolio.js.map +1 -0
  105. package/dist/portfolio/primitives/FrequencyBarSkeleton.cjs +88 -0
  106. package/dist/portfolio/primitives/FrequencyBarSkeleton.cjs.map +1 -0
  107. package/dist/portfolio/primitives/FrequencyBarSkeleton.d.cts +10 -0
  108. package/dist/portfolio/primitives/FrequencyBarSkeleton.d.ts +10 -0
  109. package/dist/portfolio/primitives/FrequencyBarSkeleton.js +68 -0
  110. package/dist/portfolio/primitives/FrequencyBarSkeleton.js.map +1 -0
  111. package/dist/portfolio/primitives/GlassCard.cjs +45 -0
  112. package/dist/portfolio/primitives/GlassCard.cjs.map +1 -0
  113. package/dist/portfolio/primitives/GlassCard.d.cts +11 -0
  114. package/dist/portfolio/primitives/GlassCard.d.ts +11 -0
  115. package/dist/portfolio/primitives/GlassCard.js +43 -0
  116. package/dist/portfolio/primitives/GlassCard.js.map +1 -0
  117. package/dist/portfolio/primitives/MetricBadge.cjs +74 -0
  118. package/dist/portfolio/primitives/MetricBadge.cjs.map +1 -0
  119. package/dist/portfolio/primitives/MetricBadge.d.cts +9 -0
  120. package/dist/portfolio/primitives/MetricBadge.d.ts +9 -0
  121. package/dist/portfolio/primitives/MetricBadge.js +54 -0
  122. package/dist/portfolio/primitives/MetricBadge.js.map +1 -0
  123. package/dist/portfolio/primitives/SVGChart.cjs +316 -0
  124. package/dist/portfolio/primitives/SVGChart.cjs.map +1 -0
  125. package/dist/portfolio/primitives/SVGChart.d.cts +18 -0
  126. package/dist/portfolio/primitives/SVGChart.d.ts +18 -0
  127. package/dist/portfolio/primitives/SVGChart.js +296 -0
  128. package/dist/portfolio/primitives/SVGChart.js.map +1 -0
  129. package/dist/portfolio/primitives/ScrollReveal.cjs +97 -0
  130. package/dist/portfolio/primitives/ScrollReveal.cjs.map +1 -0
  131. package/dist/portfolio/primitives/ScrollReveal.d.cts +27 -0
  132. package/dist/portfolio/primitives/ScrollReveal.d.ts +27 -0
  133. package/dist/portfolio/primitives/ScrollReveal.js +77 -0
  134. package/dist/portfolio/primitives/ScrollReveal.js.map +1 -0
  135. package/dist/portfolio/primitives/SplitHeadline.cjs +107 -0
  136. package/dist/portfolio/primitives/SplitHeadline.cjs.map +1 -0
  137. package/dist/portfolio/primitives/SplitHeadline.d.cts +24 -0
  138. package/dist/portfolio/primitives/SplitHeadline.d.ts +24 -0
  139. package/dist/portfolio/primitives/SplitHeadline.js +87 -0
  140. package/dist/portfolio/primitives/SplitHeadline.js.map +1 -0
  141. package/dist/portfolio/sections/BeforeAfterSection.cjs +271 -0
  142. package/dist/portfolio/sections/BeforeAfterSection.cjs.map +1 -0
  143. package/dist/portfolio/sections/BeforeAfterSection.d.cts +9 -0
  144. package/dist/portfolio/sections/BeforeAfterSection.d.ts +9 -0
  145. package/dist/{BeforeAfterSection-6BHFLY4Y.js → portfolio/sections/BeforeAfterSection.js} +66 -27
  146. package/dist/portfolio/sections/BeforeAfterSection.js.map +1 -0
  147. package/dist/portfolio/sections/CTASection.cjs +123 -0
  148. package/dist/portfolio/sections/CTASection.cjs.map +1 -0
  149. package/dist/portfolio/sections/CTASection.d.cts +9 -0
  150. package/dist/portfolio/sections/CTASection.d.ts +9 -0
  151. package/dist/portfolio/sections/CTASection.js +93 -0
  152. package/dist/portfolio/sections/CTASection.js.map +1 -0
  153. package/dist/{ChallengesSection-IZ3DHECS.cjs → portfolio/sections/ChallengesSection.cjs} +13 -7
  154. package/dist/portfolio/sections/ChallengesSection.cjs.map +1 -0
  155. package/dist/portfolio/sections/ChallengesSection.d.cts +9 -0
  156. package/dist/portfolio/sections/ChallengesSection.d.ts +9 -0
  157. package/dist/{ChallengesSection-GEQGVSJN.js → portfolio/sections/ChallengesSection.js} +6 -5
  158. package/dist/portfolio/sections/ChallengesSection.js.map +1 -0
  159. package/dist/portfolio/sections/ConversionFunnelSection.cjs +263 -0
  160. package/dist/portfolio/sections/ConversionFunnelSection.cjs.map +1 -0
  161. package/dist/portfolio/sections/ConversionFunnelSection.d.cts +9 -0
  162. package/dist/portfolio/sections/ConversionFunnelSection.d.ts +9 -0
  163. package/dist/{ConversionFunnelSection-D3GE4NKE.js → portfolio/sections/ConversionFunnelSection.js} +60 -56
  164. package/dist/portfolio/sections/ConversionFunnelSection.js.map +1 -0
  165. package/dist/{DesignSystemSection-KXIQXITF.cjs → portfolio/sections/DesignSystemSection.cjs} +13 -7
  166. package/dist/portfolio/sections/DesignSystemSection.cjs.map +1 -0
  167. package/dist/portfolio/sections/DesignSystemSection.d.cts +32 -0
  168. package/dist/portfolio/sections/DesignSystemSection.d.ts +32 -0
  169. package/dist/{DesignSystemSection-2R5BRBGO.js → portfolio/sections/DesignSystemSection.js} +5 -4
  170. package/dist/portfolio/sections/DesignSystemSection.js.map +1 -0
  171. package/dist/{DetailsSection-TTUZAPZZ.cjs → portfolio/sections/DetailsSection.cjs} +12 -6
  172. package/dist/portfolio/sections/DetailsSection.cjs.map +1 -0
  173. package/dist/portfolio/sections/DetailsSection.d.cts +9 -0
  174. package/dist/portfolio/sections/DetailsSection.d.ts +9 -0
  175. package/dist/{DetailsSection-A6PZQUQL.js → portfolio/sections/DetailsSection.js} +5 -4
  176. package/dist/portfolio/sections/DetailsSection.js.map +1 -0
  177. package/dist/portfolio/sections/FeatureSpotlightSection.cjs +267 -0
  178. package/dist/portfolio/sections/FeatureSpotlightSection.cjs.map +1 -0
  179. package/dist/portfolio/sections/FeatureSpotlightSection.d.cts +9 -0
  180. package/dist/portfolio/sections/FeatureSpotlightSection.d.ts +9 -0
  181. package/dist/{FeatureSpotlightSection-B7P3JGNL.js → portfolio/sections/FeatureSpotlightSection.js} +39 -33
  182. package/dist/portfolio/sections/FeatureSpotlightSection.js.map +1 -0
  183. package/dist/portfolio/sections/GallerySection.cjs +321 -0
  184. package/dist/portfolio/sections/GallerySection.cjs.map +1 -0
  185. package/dist/portfolio/sections/GallerySection.d.cts +9 -0
  186. package/dist/portfolio/sections/GallerySection.d.ts +9 -0
  187. package/dist/{GallerySection-VMKORC47.js → portfolio/sections/GallerySection.js} +65 -18
  188. package/dist/portfolio/sections/GallerySection.js.map +1 -0
  189. package/dist/portfolio/sections/HeroSection.cjs +180 -0
  190. package/dist/portfolio/sections/HeroSection.cjs.map +1 -0
  191. package/dist/portfolio/sections/HeroSection.d.cts +15 -0
  192. package/dist/portfolio/sections/HeroSection.d.ts +15 -0
  193. package/dist/portfolio/sections/HeroSection.js +171 -0
  194. package/dist/portfolio/sections/HeroSection.js.map +1 -0
  195. package/dist/{MetricsTimelineSection-4L6DUHJ5.cjs → portfolio/sections/MetricsTimelineSection.cjs} +102 -61
  196. package/dist/portfolio/sections/MetricsTimelineSection.cjs.map +1 -0
  197. package/dist/portfolio/sections/MetricsTimelineSection.d.cts +9 -0
  198. package/dist/portfolio/sections/MetricsTimelineSection.d.ts +9 -0
  199. package/dist/{MetricsTimelineSection-6BT5GNFV.js → portfolio/sections/MetricsTimelineSection.js} +45 -29
  200. package/dist/portfolio/sections/MetricsTimelineSection.js.map +1 -0
  201. package/dist/portfolio/sections/PerformanceSection.cjs +336 -0
  202. package/dist/portfolio/sections/PerformanceSection.cjs.map +1 -0
  203. package/dist/portfolio/sections/PerformanceSection.d.cts +22 -0
  204. package/dist/portfolio/sections/PerformanceSection.d.ts +22 -0
  205. package/dist/{PerformanceSection-MGCEIXDX.js → portfolio/sections/PerformanceSection.js} +59 -104
  206. package/dist/portfolio/sections/PerformanceSection.js.map +1 -0
  207. package/dist/{ResultsSection-XLGMMQKY.cjs → portfolio/sections/ResultsSection.cjs} +23 -10
  208. package/dist/portfolio/sections/ResultsSection.cjs.map +1 -0
  209. package/dist/portfolio/sections/ResultsSection.d.cts +13 -0
  210. package/dist/portfolio/sections/ResultsSection.d.ts +13 -0
  211. package/dist/{ResultsSection-DFUJ5U6M.js → portfolio/sections/ResultsSection.js} +14 -7
  212. package/dist/portfolio/sections/ResultsSection.js.map +1 -0
  213. package/dist/portfolio/sections/ServicesSection.cjs +129 -0
  214. package/dist/portfolio/sections/ServicesSection.cjs.map +1 -0
  215. package/dist/portfolio/sections/ServicesSection.d.cts +9 -0
  216. package/dist/portfolio/sections/ServicesSection.d.ts +9 -0
  217. package/dist/portfolio/sections/ServicesSection.js +122 -0
  218. package/dist/portfolio/sections/ServicesSection.js.map +1 -0
  219. package/dist/{SiteArchitectureSection-J7BPBERH.cjs → portfolio/sections/SiteArchitectureSection.cjs} +117 -93
  220. package/dist/portfolio/sections/SiteArchitectureSection.cjs.map +1 -0
  221. package/dist/portfolio/sections/SiteArchitectureSection.d.cts +21 -0
  222. package/dist/portfolio/sections/SiteArchitectureSection.d.ts +21 -0
  223. package/dist/{SiteArchitectureSection-TE22OAWV.js → portfolio/sections/SiteArchitectureSection.js} +47 -48
  224. package/dist/portfolio/sections/SiteArchitectureSection.js.map +1 -0
  225. package/dist/{SpeedComparisonSection-EZKFQVGW.cjs → portfolio/sections/SpeedComparisonSection.cjs} +13 -7
  226. package/dist/portfolio/sections/SpeedComparisonSection.cjs.map +1 -0
  227. package/dist/portfolio/sections/SpeedComparisonSection.d.cts +20 -0
  228. package/dist/portfolio/sections/SpeedComparisonSection.d.ts +20 -0
  229. package/dist/{SpeedComparisonSection-Y3K7OFZQ.js → portfolio/sections/SpeedComparisonSection.js} +6 -5
  230. package/dist/portfolio/sections/SpeedComparisonSection.js.map +1 -0
  231. package/dist/portfolio/sections/StrategySection.cjs +233 -0
  232. package/dist/portfolio/sections/StrategySection.cjs.map +1 -0
  233. package/dist/portfolio/sections/StrategySection.d.cts +9 -0
  234. package/dist/portfolio/sections/StrategySection.d.ts +9 -0
  235. package/dist/{StrategySection-DI5RSCJU.js → portfolio/sections/StrategySection.js} +60 -26
  236. package/dist/portfolio/sections/StrategySection.js.map +1 -0
  237. package/dist/portfolio/sections/TeamSection.cjs +162 -0
  238. package/dist/portfolio/sections/TeamSection.cjs.map +1 -0
  239. package/dist/portfolio/sections/TeamSection.d.cts +9 -0
  240. package/dist/portfolio/sections/TeamSection.d.ts +9 -0
  241. package/dist/portfolio/sections/TeamSection.js +106 -0
  242. package/dist/portfolio/sections/TeamSection.js.map +1 -0
  243. package/dist/portfolio/sections/TechStackSection.cjs +106 -0
  244. package/dist/portfolio/sections/TechStackSection.cjs.map +1 -0
  245. package/dist/portfolio/sections/TechStackSection.d.cts +9 -0
  246. package/dist/portfolio/sections/TechStackSection.d.ts +9 -0
  247. package/dist/portfolio/sections/TechStackSection.js +99 -0
  248. package/dist/portfolio/sections/TechStackSection.js.map +1 -0
  249. package/dist/{TestimonialSection-XPTFUQIN.cjs → portfolio/sections/TestimonialSection.cjs} +47 -28
  250. package/dist/portfolio/sections/TestimonialSection.cjs.map +1 -0
  251. package/dist/portfolio/sections/TestimonialSection.d.cts +9 -0
  252. package/dist/portfolio/sections/TestimonialSection.d.ts +9 -0
  253. package/dist/{TestimonialSection-6RGSMXQB.js → portfolio/sections/TestimonialSection.js} +40 -27
  254. package/dist/portfolio/sections/TestimonialSection.js.map +1 -0
  255. package/dist/portfolio/sections/VideoSection.cjs +181 -0
  256. package/dist/portfolio/sections/VideoSection.cjs.map +1 -0
  257. package/dist/portfolio/sections/VideoSection.d.cts +9 -0
  258. package/dist/portfolio/sections/VideoSection.d.ts +9 -0
  259. package/dist/{VideoSection-4A2HC6K6.js → portfolio/sections/VideoSection.js} +21 -13
  260. package/dist/portfolio/sections/VideoSection.js.map +1 -0
  261. package/dist/portfolio/server.cjs +56 -144
  262. package/dist/portfolio/server.cjs.map +1 -1
  263. package/dist/portfolio/server.d.cts +157 -7
  264. package/dist/portfolio/server.d.ts +157 -7
  265. package/dist/portfolio/server.js +3 -142
  266. package/dist/portfolio/server.js.map +1 -1
  267. package/dist/preview.cjs +56 -0
  268. package/dist/preview.cjs.map +1 -0
  269. package/dist/preview.d.cts +31 -0
  270. package/dist/preview.d.ts +31 -0
  271. package/dist/preview.js +54 -0
  272. package/dist/preview.js.map +1 -0
  273. package/dist/{types-DL4t_Cfa.d.ts → types-0tVPy4pU.d.cts} +7 -1
  274. package/dist/{types-DL4t_Cfa.d.cts → types-0tVPy4pU.d.ts} +7 -1
  275. package/dist/types-D0nb6KAx.d.cts +299 -0
  276. package/dist/types-D0nb6KAx.d.ts +299 -0
  277. package/package.json +38 -14
  278. package/templates/api-portfolio-preview.ts +6 -0
  279. package/templates/api-revalidate.ts +5 -0
  280. package/templates/work-category-page.tsx +40 -0
  281. package/templates/work-error.tsx +3 -0
  282. package/templates/work-loading.tsx +1 -0
  283. package/templates/work-page.tsx +37 -0
  284. package/templates/work-slug-loading.tsx +1 -0
  285. package/templates/work-slug-page.tsx +41 -0
  286. package/dist/BeforeAfterSection-6BHFLY4Y.js.map +0 -1
  287. package/dist/BeforeAfterSection-JTORBR3A.cjs +0 -181
  288. package/dist/BeforeAfterSection-JTORBR3A.cjs.map +0 -1
  289. package/dist/CTASection-4JKLXEUF.cjs +0 -111
  290. package/dist/CTASection-4JKLXEUF.cjs.map +0 -1
  291. package/dist/CTASection-BJA72XIL.js +0 -106
  292. package/dist/CTASection-BJA72XIL.js.map +0 -1
  293. package/dist/ChallengesSection-GEQGVSJN.js.map +0 -1
  294. package/dist/ChallengesSection-IZ3DHECS.cjs.map +0 -1
  295. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs +0 -209
  296. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs.map +0 -1
  297. package/dist/ConversionFunnelSection-D3GE4NKE.js.map +0 -1
  298. package/dist/DesignSystemSection-2R5BRBGO.js.map +0 -1
  299. package/dist/DesignSystemSection-KXIQXITF.cjs.map +0 -1
  300. package/dist/DetailsSection-A6PZQUQL.js.map +0 -1
  301. package/dist/DetailsSection-TTUZAPZZ.cjs.map +0 -1
  302. package/dist/FeatureSpotlightSection-B7P3JGNL.js.map +0 -1
  303. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs +0 -210
  304. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs.map +0 -1
  305. package/dist/GallerySection-VMKORC47.js.map +0 -1
  306. package/dist/GallerySection-WJ4PQDBI.cjs +0 -219
  307. package/dist/GallerySection-WJ4PQDBI.cjs.map +0 -1
  308. package/dist/MetricsTimelineSection-4L6DUHJ5.cjs.map +0 -1
  309. package/dist/MetricsTimelineSection-6BT5GNFV.js.map +0 -1
  310. package/dist/PerformanceSection-24TVVFZA.cjs +0 -356
  311. package/dist/PerformanceSection-24TVVFZA.cjs.map +0 -1
  312. package/dist/PerformanceSection-MGCEIXDX.js.map +0 -1
  313. package/dist/ResultsSection-DFUJ5U6M.js.map +0 -1
  314. package/dist/ResultsSection-XLGMMQKY.cjs.map +0 -1
  315. package/dist/ServicesSection-D5V3Q4GR.js +0 -118
  316. package/dist/ServicesSection-D5V3Q4GR.js.map +0 -1
  317. package/dist/ServicesSection-WJMGK2MF.cjs +0 -120
  318. package/dist/ServicesSection-WJMGK2MF.cjs.map +0 -1
  319. package/dist/SiteArchitectureSection-J7BPBERH.cjs.map +0 -1
  320. package/dist/SiteArchitectureSection-TE22OAWV.js.map +0 -1
  321. package/dist/SpeedComparisonSection-EZKFQVGW.cjs.map +0 -1
  322. package/dist/SpeedComparisonSection-Y3K7OFZQ.js.map +0 -1
  323. package/dist/StrategySection-CJ7Y6OFQ.cjs +0 -174
  324. package/dist/StrategySection-CJ7Y6OFQ.cjs.map +0 -1
  325. package/dist/StrategySection-DI5RSCJU.js.map +0 -1
  326. package/dist/TeamSection-DZVSNZE6.cjs +0 -112
  327. package/dist/TeamSection-DZVSNZE6.cjs.map +0 -1
  328. package/dist/TeamSection-HGKFW6PQ.js +0 -107
  329. package/dist/TeamSection-HGKFW6PQ.js.map +0 -1
  330. package/dist/TechStackSection-2AQ7RGY3.js +0 -93
  331. package/dist/TechStackSection-2AQ7RGY3.js.map +0 -1
  332. package/dist/TechStackSection-VTNNZR5V.cjs +0 -95
  333. package/dist/TechStackSection-VTNNZR5V.cjs.map +0 -1
  334. package/dist/TestimonialSection-6RGSMXQB.js.map +0 -1
  335. package/dist/TestimonialSection-XPTFUQIN.cjs.map +0 -1
  336. package/dist/VideoSection-4A2HC6K6.js.map +0 -1
  337. package/dist/VideoSection-G3DFS7UH.cjs +0 -118
  338. package/dist/VideoSection-G3DFS7UH.cjs.map +0 -1
  339. package/dist/chunk-2Y4O3LWM.js +0 -53
  340. package/dist/chunk-2Y4O3LWM.js.map +0 -1
  341. package/dist/chunk-633UMQQH.cjs +0 -31
  342. package/dist/chunk-633UMQQH.cjs.map +0 -1
  343. package/dist/chunk-7CFFAKDM.js +0 -74
  344. package/dist/chunk-7CFFAKDM.js.map +0 -1
  345. package/dist/chunk-APG2QSMB.js +0 -131
  346. package/dist/chunk-APG2QSMB.js.map +0 -1
  347. package/dist/chunk-AVCH4LMG.cjs +0 -620
  348. package/dist/chunk-AVCH4LMG.cjs.map +0 -1
  349. package/dist/chunk-AYBUHRFS.js +0 -613
  350. package/dist/chunk-AYBUHRFS.js.map +0 -1
  351. package/dist/chunk-EE75WRCM.cjs.map +0 -1
  352. package/dist/chunk-IKBK7HYX.cjs +0 -79
  353. package/dist/chunk-IKBK7HYX.cjs.map +0 -1
  354. package/dist/chunk-KEOHORIH.cjs +0 -79
  355. package/dist/chunk-KEOHORIH.cjs.map +0 -1
  356. package/dist/chunk-OA5ZM4OA.cjs +0 -139
  357. package/dist/chunk-OA5ZM4OA.cjs.map +0 -1
  358. package/dist/chunk-TVFXN6W6.js.map +0 -1
  359. package/dist/chunk-VVTK4OL6.js +0 -28
  360. package/dist/chunk-VVTK4OL6.js.map +0 -1
  361. package/dist/chunk-XCKXHK44.js +0 -15
  362. package/dist/chunk-XCKXHK44.js.map +0 -1
  363. package/dist/chunk-XONXEFJY.cjs +0 -58
  364. package/dist/chunk-XONXEFJY.cjs.map +0 -1
  365. package/dist/chunk-XQNJED46.cjs +0 -19
  366. package/dist/chunk-XQNJED46.cjs.map +0 -1
  367. package/dist/chunk-YB4B3OMC.js +0 -74
  368. package/dist/chunk-YB4B3OMC.js.map +0 -1
  369. package/dist/portfolio/sections.cjs +0 -20
  370. package/dist/portfolio/sections.cjs.map +0 -1
  371. package/dist/portfolio/sections.d.cts +0 -42
  372. package/dist/portfolio/sections.d.ts +0 -42
  373. package/dist/portfolio/sections.js +0 -4
  374. package/dist/portfolio/sections.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/StrategySection.tsx"],"sourcesContent":["'use client';\n\nimport React, { useRef, useEffect } from 'react';\nimport type { PortfolioStrategyData } from '../../../types';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\n\ninterface StrategySectionProps {\n data: PortfolioStrategyData;\n}\n\nexport default function StrategySection({ data }: StrategySectionProps) {\n const timelineRef = useRef<HTMLDivElement>(null);\n const sectionRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const line = timelineRef.current;\n const section = sectionRef.current;\n if (!line || !section) return;\n\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n // Scroll-scrubbed timeline line draw via scaleY: progress maps the range\n // \"section top at 60% of the viewport\" → \"section bottom at 40%\", with a\n // time-based catch-up (~1s to converge) matching the old scrubbed feel.\n const progressAt = () => {\n const rect = section.getBoundingClientRect();\n const vh = window.innerHeight;\n const scrolled = vh * 0.6 - rect.top;\n const range = Math.max(rect.height - vh * 0.2, 1);\n return Math.min(1, Math.max(0, scrolled / range));\n };\n\n line.style.transformOrigin = 'top center';\n line.style.willChange = 'transform';\n\n // Snap to the progress for the current scroll position, so content\n // already in the viewport at hydration is never re-hidden.\n let current = progressAt();\n line.style.transform = `scaleY(${current})`;\n\n let raf = 0;\n let last = 0;\n\n const step = (now: number) => {\n raf = 0;\n const dt = last ? Math.min((now - last) / 1000, 0.1) : 1 / 60;\n last = now;\n const target = progressAt();\n current += (target - current) * Math.min(1, dt * 3);\n if (Math.abs(target - current) < 0.001) current = target;\n line.style.transform = `scaleY(${current})`;\n if (current !== target) raf = requestAnimationFrame(step);\n };\n\n const onScroll = () => {\n if (!raf) {\n last = 0;\n raf = requestAnimationFrame(step);\n }\n };\n\n // Only do per-scroll work while the section is near the viewport.\n const io = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) {\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('resize', onScroll);\n onScroll();\n } else {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onScroll);\n }\n });\n io.observe(section);\n\n return () => {\n io.disconnect();\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onScroll);\n cancelAnimationFrame(raf);\n line.style.transformOrigin = '';\n line.style.willChange = '';\n line.style.transform = '';\n };\n }, [data.phases.length]);\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Our Strategy\n </h2>\n <p\n className=\"text-lg mb-16 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n A phased approach to delivering measurable results.\n </p>\n </ScrollReveal>\n\n <div ref={sectionRef} className=\"relative\">\n {/* Vertical timeline line — uses the circle column width to find center */}\n <div\n ref={timelineRef}\n className=\"absolute top-0 bottom-0 hidden md:block pointer-events-none w-12 md:w-16\"\n style={{ left: 0 }}\n >\n <div\n className=\"absolute top-0 bottom-0\"\n style={{\n left: '50%',\n transform: 'translateX(-50%)',\n width: '2px',\n background: 'var(--sk-primary, #6366f1)',\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"flex flex-col gap-12\">\n {data.phases.map((phase, index) => (\n <ScrollReveal key={index} y={40} delay={index * 0.15}>\n <div className=\"flex gap-6 md:gap-8\">\n {/* Number circle — fixed-width column so line can center on it */}\n <div className=\"flex flex-col items-center shrink-0 w-12 md:w-16\">\n <div\n className=\"flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full text-lg md:text-xl font-bold z-10\"\n style={{\n background: 'var(--sk-bg, #0a0a0a)',\n border: '3px solid var(--sk-primary, #6366f1)',\n color: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 0 20px color-mix(in srgb, var(--sk-primary, #6366f1) 30%, transparent)',\n }}\n >\n {phase.number}\n </div>\n </div>\n\n {/* Phase content */}\n <GlassCard padding=\"lg\" hover={false} className=\"flex-1\">\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <h3\n className=\"text-xl font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {phase.title}\n </h3>\n {phase.timeline && (\n <span\n className=\"px-3 py-0.5 rounded-full text-xs font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 12%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n }}\n >\n {phase.timeline}\n </span>\n )}\n </div>\n\n <p\n className=\"text-base leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {phase.description}\n </p>\n\n {/* Deliverables */}\n {phase.deliverables && phase.deliverables.length > 0 && (\n <ul className=\"flex flex-col gap-2 mt-2\">\n {phase.deliverables.map((deliverable, di) => (\n <li key={di} className=\"flex items-start gap-2\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n className=\"shrink-0 mt-0.5\"\n style={{ color: '#10b981' }}\n >\n <path\n d=\"M15 4.5L6.75 12.75 3 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span\n className=\"text-sm\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {deliverable}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </GlassCard>\n </div>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,162 @@
1
+ 'use client';
2
+ "use strict";
3
+ "use client";
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+
32
+ // src/portfolio/components/sections/TeamSection.tsx
33
+ var TeamSection_exports = {};
34
+ __export(TeamSection_exports, {
35
+ default: () => TeamSection
36
+ });
37
+ module.exports = __toCommonJS(TeamSection_exports);
38
+ var import_image = __toESM(require("next/image"), 1);
39
+
40
+ // src/shared/images.ts
41
+ var SANITY_ASSET_REF = /^image-[A-Za-z0-9]+-\d+x\d+-[a-z0-9]+$/;
42
+ var FILENAME_DIMS = /-(\d{2,5})x(\d{2,5})\.[a-z0-9]+(?:\?.*)?$/i;
43
+ var warnedAboutRefs = false;
44
+ function resolvePortfolioImage(input) {
45
+ const raw = typeof input === "string" ? input : input?.asset?._ref ?? "";
46
+ const value = (raw || "").trim();
47
+ if (!value) return null;
48
+ if (SANITY_ASSET_REF.test(value)) {
49
+ if (!warnedAboutRefs && typeof console !== "undefined") {
50
+ warnedAboutRefs = true;
51
+ console.warn(
52
+ "[@sonordev/agency-site-kit] Received a raw Sanity asset ref instead of an image URL \u2014 skipping render. The Sonor API should resolve image refs to cdn.sanity.io URLs before returning portfolio sections."
53
+ );
54
+ }
55
+ return null;
56
+ }
57
+ if (!/^https?:\/\//i.test(value) && !value.startsWith("/")) return null;
58
+ const dims = value.match(FILENAME_DIMS);
59
+ if (dims) {
60
+ const width = parseInt(dims[1], 10);
61
+ const height = parseInt(dims[2], 10);
62
+ if (width > 0 && height > 0) return { url: value, width, height };
63
+ }
64
+ return { url: value };
65
+ }
66
+
67
+ // src/portfolio/components/sections/TeamSection.tsx
68
+ var import_ScrollReveal = __toESM(require("@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal"), 1);
69
+ var import_GlassCard = __toESM(require("@sonordev/agency-site-kit/portfolio/primitives/GlassCard"), 1);
70
+ var import_jsx_runtime = require("react/jsx-runtime");
71
+ var TEAM_CARD_CSS = `
72
+ .sk-team-card .team-avatar{transition:transform .3s cubic-bezier(.25,.46,.45,.94)}
73
+ .sk-team-card:hover .team-avatar{transform:scale(1.08)}
74
+ @media (prefers-reduced-motion:reduce){.sk-team-card .team-avatar{transition:none}.sk-team-card:hover .team-avatar{transform:none}}
75
+ `;
76
+ function TeamCard({ member }) {
77
+ const avatar = resolvePortfolioImage(member.avatar);
78
+ const initials = member.name.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase();
79
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "sk-team-card", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_GlassCard.default, { padding: "md", hover: true, className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
80
+ avatar ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
81
+ import_image.default,
82
+ {
83
+ src: avatar.url,
84
+ alt: member.name,
85
+ width: 80,
86
+ height: 80,
87
+ className: "team-avatar w-20 h-20 rounded-full object-cover",
88
+ style: {
89
+ border: "3px solid var(--sk-border, rgba(255,255,255,0.1))",
90
+ willChange: "transform"
91
+ }
92
+ }
93
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
94
+ "div",
95
+ {
96
+ className: "team-avatar flex items-center justify-center w-20 h-20 rounded-full text-xl font-bold",
97
+ style: {
98
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)",
99
+ color: "var(--sk-primary, #6366f1)",
100
+ border: "3px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)",
101
+ willChange: "transform"
102
+ },
103
+ children: initials
104
+ }
105
+ ),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
108
+ "h3",
109
+ {
110
+ className: "text-base font-semibold",
111
+ style: { color: "var(--sk-text-primary, #ffffff)" },
112
+ children: member.name
113
+ }
114
+ ),
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
116
+ "p",
117
+ {
118
+ className: "text-sm mt-1",
119
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
120
+ children: member.role
121
+ }
122
+ )
123
+ ] })
124
+ ] }) }) });
125
+ }
126
+ function TeamSection({ data }) {
127
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
128
+ "section",
129
+ {
130
+ className: "w-full py-20 md:py-28",
131
+ style: { background: "var(--sk-bg, #0a0a0a)" },
132
+ children: [
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { href: "sk-team-card", precedence: "default", children: TEAM_CARD_CSS }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "max-w-7xl mx-auto px-6", children: [
135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ScrollReveal.default, { y: 30, children: [
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
137
+ "h2",
138
+ {
139
+ className: "text-3xl md:text-4xl font-bold mb-4",
140
+ style: {
141
+ color: "var(--sk-text-primary, #ffffff)",
142
+ fontFamily: "var(--sk-font-heading, inherit)"
143
+ },
144
+ children: "The Team"
145
+ }
146
+ ),
147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
148
+ "p",
149
+ {
150
+ className: "text-lg mb-12 max-w-2xl",
151
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
152
+ children: "The people who brought this project to life."
153
+ }
154
+ )
155
+ ] }),
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ScrollReveal.default, { stagger: 0.1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6", children: data.members.map((member, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TeamCard, { member }, index)) }) })
157
+ ] })
158
+ ]
159
+ }
160
+ );
161
+ }
162
+ //# sourceMappingURL=TeamSection.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/TeamSection.tsx","../../../src/shared/images.ts"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport Image from 'next/image';\nimport type { PortfolioTeamData, PortfolioTeamMember } from '../../../types';\nimport { resolvePortfolioImage } from '../../../shared/images';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\n\ninterface TeamSectionProps {\n data: PortfolioTeamData;\n}\n\n// Avatar zoom on card hover — pure CSS, no mouse handlers. .3s with a\n// power2.out-style ease matches the old hover tween.\nconst TEAM_CARD_CSS = `\n.sk-team-card .team-avatar{transition:transform .3s cubic-bezier(.25,.46,.45,.94)}\n.sk-team-card:hover .team-avatar{transform:scale(1.08)}\n@media (prefers-reduced-motion:reduce){.sk-team-card .team-avatar{transition:none}.sk-team-card:hover .team-avatar{transform:none}}\n`;\n\nfunction TeamCard({ member }: { member: PortfolioTeamMember }) {\n const avatar = resolvePortfolioImage(member.avatar);\n const initials = member.name\n .split(' ')\n .map((w: string) => w[0])\n .join('')\n .slice(0, 2)\n .toUpperCase();\n\n return (\n <div className=\"sk-team-card\">\n <GlassCard padding=\"md\" hover className=\"text-center\">\n <div className=\"flex flex-col items-center gap-4\">\n {avatar ? (\n <Image\n src={avatar.url}\n alt={member.name}\n width={80}\n height={80}\n className=\"team-avatar w-20 h-20 rounded-full object-cover\"\n style={{\n border: '3px solid var(--sk-border, rgba(255,255,255,0.1))',\n willChange: 'transform',\n }}\n />\n ) : (\n <div\n className=\"team-avatar flex items-center justify-center w-20 h-20 rounded-full text-xl font-bold\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '3px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n willChange: 'transform',\n }}\n >\n {initials}\n </div>\n )}\n\n <div>\n <h3\n className=\"text-base font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {member.name}\n </h3>\n <p\n className=\"text-sm mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {member.role}\n </p>\n </div>\n </div>\n </GlassCard>\n </div>\n );\n}\n\nexport default function TeamSection({ data }: TeamSectionProps) {\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n {/* Hover CSS (React 19 hoists + dedupes via href/precedence) */}\n <style href=\"sk-team-card\" precedence=\"default\">\n {TEAM_CARD_CSS}\n </style>\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-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n The Team\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The people who brought this project to life.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6\">\n {data.members.map((member, index) => (\n <TeamCard key={index} member={member} />\n ))}\n </div>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n","/**\n * Portfolio image resolution — single source of truth for turning the mixed\n * image shapes the API sends (plain URL strings, Supabase Storage URLs,\n * Sanity image objects) into something safe to render.\n *\n * IMPORTANT: a raw Sanity asset _ref (`image-{id}-{W}x{H}-{fmt}`) is an asset\n * ID, NOT a URL. Rendering it as `src` issues a garbage relative request\n * against the agency site's origin. Resolving refs to cdn.sanity.io URLs is\n * the API's job (it owns the Sanity project config); this helper refuses refs\n * so a broken image can never render, and warns once so the gap is visible.\n *\n * When a URL carries `-{W}x{H}.{ext}` dimensions (Sanity CDN URLs always do),\n * they're parsed out so callers can give next/image exact intrinsic sizes.\n */\n\nexport interface ResolvedPortfolioImage {\n url: string;\n width?: number;\n height?: number;\n}\n\n/** Raw Sanity asset reference — an ID, not a URL. */\nconst SANITY_ASSET_REF = /^image-[A-Za-z0-9]+-\\d+x\\d+-[a-z0-9]+$/;\n\n/** `…-1200x800.png` (optionally with a query string) → intrinsic dimensions. */\nconst FILENAME_DIMS = /-(\\d{2,5})x(\\d{2,5})\\.[a-z0-9]+(?:\\?.*)?$/i;\n\ninterface SanityImageLike {\n asset?: { _ref?: string };\n}\n\nlet warnedAboutRefs = false;\n\n/**\n * Resolve a portfolio image input into a renderable URL (+ intrinsic\n * dimensions when they can be derived). Returns null for empty values and\n * for unresolved Sanity refs — callers skip rendering in that case.\n */\nexport function resolvePortfolioImage(\n input: string | SanityImageLike | null | undefined,\n): ResolvedPortfolioImage | null {\n const raw =\n typeof input === 'string' ? input : input?.asset?._ref ?? '';\n const value = (raw || '').trim();\n if (!value) return null;\n\n if (SANITY_ASSET_REF.test(value)) {\n if (!warnedAboutRefs && typeof console !== 'undefined') {\n warnedAboutRefs = true;\n console.warn(\n '[@sonordev/agency-site-kit] Received a raw Sanity asset ref instead of an ' +\n 'image URL — skipping render. The Sonor API should resolve image refs to ' +\n 'cdn.sanity.io URLs before returning portfolio sections.',\n );\n }\n return null;\n }\n\n // Only absolute http(s) URLs or site-rooted paths are renderable.\n if (!/^https?:\\/\\//i.test(value) && !value.startsWith('/')) return null;\n\n const dims = value.match(FILENAME_DIMS);\n if (dims) {\n const width = parseInt(dims[1], 10);\n const height = parseInt(dims[2], 10);\n if (width > 0 && height > 0) return { url: value, width, height };\n }\n\n return { url: value };\n}\n"],"mappings":"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","names":["GlassCard","Image","ScrollReveal"]}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { g as PortfolioTeamData } from '../../types-D0nb6KAx.cjs';
3
+
4
+ interface TeamSectionProps {
5
+ data: PortfolioTeamData;
6
+ }
7
+ declare function TeamSection({ data }: TeamSectionProps): React.JSX.Element;
8
+
9
+ export { TeamSection as default };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { g as PortfolioTeamData } from '../../types-D0nb6KAx.js';
3
+
4
+ interface TeamSectionProps {
5
+ data: PortfolioTeamData;
6
+ }
7
+ declare function TeamSection({ data }: TeamSectionProps): React.JSX.Element;
8
+
9
+ export { TeamSection as default };
@@ -0,0 +1,106 @@
1
+ 'use client';
2
+ "use client";
3
+ import {
4
+ resolvePortfolioImage
5
+ } from "../../chunk-QDXZ27R7.js";
6
+
7
+ // src/portfolio/components/sections/TeamSection.tsx
8
+ import Image from "next/image";
9
+ import ScrollReveal from "@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal";
10
+ import GlassCard from "@sonordev/agency-site-kit/portfolio/primitives/GlassCard";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ var TEAM_CARD_CSS = `
13
+ .sk-team-card .team-avatar{transition:transform .3s cubic-bezier(.25,.46,.45,.94)}
14
+ .sk-team-card:hover .team-avatar{transform:scale(1.08)}
15
+ @media (prefers-reduced-motion:reduce){.sk-team-card .team-avatar{transition:none}.sk-team-card:hover .team-avatar{transform:none}}
16
+ `;
17
+ function TeamCard({ member }) {
18
+ const avatar = resolvePortfolioImage(member.avatar);
19
+ const initials = member.name.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase();
20
+ return /* @__PURE__ */ jsx("div", { className: "sk-team-card", children: /* @__PURE__ */ jsx(GlassCard, { padding: "md", hover: true, className: "text-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
21
+ avatar ? /* @__PURE__ */ jsx(
22
+ Image,
23
+ {
24
+ src: avatar.url,
25
+ alt: member.name,
26
+ width: 80,
27
+ height: 80,
28
+ className: "team-avatar w-20 h-20 rounded-full object-cover",
29
+ style: {
30
+ border: "3px solid var(--sk-border, rgba(255,255,255,0.1))",
31
+ willChange: "transform"
32
+ }
33
+ }
34
+ ) : /* @__PURE__ */ jsx(
35
+ "div",
36
+ {
37
+ className: "team-avatar flex items-center justify-center w-20 h-20 rounded-full text-xl font-bold",
38
+ style: {
39
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)",
40
+ color: "var(--sk-primary, #6366f1)",
41
+ border: "3px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)",
42
+ willChange: "transform"
43
+ },
44
+ children: initials
45
+ }
46
+ ),
47
+ /* @__PURE__ */ jsxs("div", { children: [
48
+ /* @__PURE__ */ jsx(
49
+ "h3",
50
+ {
51
+ className: "text-base font-semibold",
52
+ style: { color: "var(--sk-text-primary, #ffffff)" },
53
+ children: member.name
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsx(
57
+ "p",
58
+ {
59
+ className: "text-sm mt-1",
60
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
61
+ children: member.role
62
+ }
63
+ )
64
+ ] })
65
+ ] }) }) });
66
+ }
67
+ function TeamSection({ data }) {
68
+ return /* @__PURE__ */ jsxs(
69
+ "section",
70
+ {
71
+ className: "w-full py-20 md:py-28",
72
+ style: { background: "var(--sk-bg, #0a0a0a)" },
73
+ children: [
74
+ /* @__PURE__ */ jsx("style", { href: "sk-team-card", precedence: "default", children: TEAM_CARD_CSS }),
75
+ /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto px-6", children: [
76
+ /* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
77
+ /* @__PURE__ */ jsx(
78
+ "h2",
79
+ {
80
+ className: "text-3xl md:text-4xl font-bold mb-4",
81
+ style: {
82
+ color: "var(--sk-text-primary, #ffffff)",
83
+ fontFamily: "var(--sk-font-heading, inherit)"
84
+ },
85
+ children: "The Team"
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsx(
89
+ "p",
90
+ {
91
+ className: "text-lg mb-12 max-w-2xl",
92
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
93
+ children: "The people who brought this project to life."
94
+ }
95
+ )
96
+ ] }),
97
+ /* @__PURE__ */ jsx(ScrollReveal, { stagger: 0.1, children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6", children: data.members.map((member, index) => /* @__PURE__ */ jsx(TeamCard, { member }, index)) }) })
98
+ ] })
99
+ ]
100
+ }
101
+ );
102
+ }
103
+ export {
104
+ TeamSection as default
105
+ };
106
+ //# sourceMappingURL=TeamSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/TeamSection.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport Image from 'next/image';\nimport type { PortfolioTeamData, PortfolioTeamMember } from '../../../types';\nimport { resolvePortfolioImage } from '../../../shared/images';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\n\ninterface TeamSectionProps {\n data: PortfolioTeamData;\n}\n\n// Avatar zoom on card hover — pure CSS, no mouse handlers. .3s with a\n// power2.out-style ease matches the old hover tween.\nconst TEAM_CARD_CSS = `\n.sk-team-card .team-avatar{transition:transform .3s cubic-bezier(.25,.46,.45,.94)}\n.sk-team-card:hover .team-avatar{transform:scale(1.08)}\n@media (prefers-reduced-motion:reduce){.sk-team-card .team-avatar{transition:none}.sk-team-card:hover .team-avatar{transform:none}}\n`;\n\nfunction TeamCard({ member }: { member: PortfolioTeamMember }) {\n const avatar = resolvePortfolioImage(member.avatar);\n const initials = member.name\n .split(' ')\n .map((w: string) => w[0])\n .join('')\n .slice(0, 2)\n .toUpperCase();\n\n return (\n <div className=\"sk-team-card\">\n <GlassCard padding=\"md\" hover className=\"text-center\">\n <div className=\"flex flex-col items-center gap-4\">\n {avatar ? (\n <Image\n src={avatar.url}\n alt={member.name}\n width={80}\n height={80}\n className=\"team-avatar w-20 h-20 rounded-full object-cover\"\n style={{\n border: '3px solid var(--sk-border, rgba(255,255,255,0.1))',\n willChange: 'transform',\n }}\n />\n ) : (\n <div\n className=\"team-avatar flex items-center justify-center w-20 h-20 rounded-full text-xl font-bold\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '3px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n willChange: 'transform',\n }}\n >\n {initials}\n </div>\n )}\n\n <div>\n <h3\n className=\"text-base font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {member.name}\n </h3>\n <p\n className=\"text-sm mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {member.role}\n </p>\n </div>\n </div>\n </GlassCard>\n </div>\n );\n}\n\nexport default function TeamSection({ data }: TeamSectionProps) {\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n {/* Hover CSS (React 19 hoists + dedupes via href/precedence) */}\n <style href=\"sk-team-card\" precedence=\"default\">\n {TEAM_CARD_CSS}\n </style>\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-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n The Team\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The people who brought this project to life.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6\">\n {data.members.map((member, index) => (\n <TeamCard key={index} member={member} />\n ))}\n </div>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;AAGA,OAAO,WAAW;AAGlB,OAAO,kBAAkB;AACzB,OAAO,eAAe;AA4BV,cAyBF,YAzBE;AApBZ,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAMtB,SAAS,SAAS,EAAE,OAAO,GAAoC;AAC7D,QAAM,SAAS,sBAAsB,OAAO,MAAM;AAClD,QAAM,WAAW,OAAO,KACrB,MAAM,GAAG,EACT,IAAI,CAAC,MAAc,EAAE,CAAC,CAAC,EACvB,KAAK,EAAE,EACP,MAAM,GAAG,CAAC,EACV,YAAY;AAEf,SACE,oBAAC,SAAI,WAAU,gBACb,8BAAC,aAAU,SAAQ,MAAK,OAAK,MAAC,WAAU,eACtC,+BAAC,SAAI,WAAU,oCACZ;AAAA,aACC;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,OAAO;AAAA,QACZ,KAAK,OAAO;AAAA,QACZ,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,WAAU;AAAA,QACV,OAAO;AAAA,UACL,QAAQ;AAAA,UACR,YAAY;AAAA,QACd;AAAA;AAAA,IACF,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,YAAY;AAAA,QACd;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IAGF,qBAAC,SACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,OAAO,kCAAkC;AAAA,UAEjD,iBAAO;AAAA;AAAA,MACV;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,OAAO,mCAAmC;AAAA,UAElD,iBAAO;AAAA;AAAA,MACV;AAAA,OACF;AAAA,KACF,GACF,GACF;AAEJ;AAEe,SAAR,YAA6B,EAAE,KAAK,GAAqB;AAC9D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,YAAY,wBAAwB;AAAA,MAG7C;AAAA,4BAAC,WAAM,MAAK,gBAAe,YAAW,WACnC,yBACH;AAAA,QACA,qBAAC,SAAI,WAAU,0BACb;AAAA,+BAAC,gBAAa,GAAG,IACf;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,YAAY;AAAA,gBACd;AAAA,gBACD;AAAA;AAAA,YAED;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,oCAAoC;AAAA,gBACrD;AAAA;AAAA,YAED;AAAA,aACF;AAAA,UAEA,oBAAC,gBAAa,SAAS,KACrB,8BAAC,SAAI,WAAU,wDACZ,eAAK,QAAQ,IAAI,CAAC,QAAQ,UACzB,oBAAC,YAAqB,UAAP,KAAuB,CACvC,GACH,GACF;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ var chunkNI4FVCLS_cjs = require('../../chunk-NI4FVCLS.cjs');
4
+ var ScrollReveal = require('@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal');
5
+ var GlassCard = require('@sonordev/agency-site-kit/portfolio/primitives/GlassCard');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var ScrollReveal__default = /*#__PURE__*/_interopDefault(ScrollReveal);
11
+ var GlassCard__default = /*#__PURE__*/_interopDefault(GlassCard);
12
+
13
+ function TechStackSection({ data }) {
14
+ return /* @__PURE__ */ jsxRuntime.jsx(
15
+ "section",
16
+ {
17
+ className: "w-full py-20 md:py-28",
18
+ style: { background: "var(--sk-bg, #0a0a0a)" },
19
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
20
+ /* @__PURE__ */ jsxRuntime.jsxs(ScrollReveal__default.default, { y: 30, children: [
21
+ /* @__PURE__ */ jsxRuntime.jsx(
22
+ "h2",
23
+ {
24
+ className: "text-3xl md:text-4xl font-bold mb-4",
25
+ style: {
26
+ color: "var(--sk-text-primary, #ffffff)",
27
+ fontFamily: "var(--sk-font-heading, inherit)"
28
+ },
29
+ children: "Tech Stack"
30
+ }
31
+ ),
32
+ /* @__PURE__ */ jsxRuntime.jsx(
33
+ "p",
34
+ {
35
+ className: "text-lg mb-12 max-w-2xl",
36
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
37
+ children: "The technologies and tools powering this project."
38
+ }
39
+ )
40
+ ] }),
41
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-4", children: data.technologies.map((tech, ti) => {
42
+ const icon = chunkNI4FVCLS_cjs.resolvePortfolioImage(tech.icon);
43
+ return /* @__PURE__ */ jsxRuntime.jsx(ScrollReveal__default.default, { y: 20, delay: ti * 0.05, children: /* @__PURE__ */ jsxRuntime.jsxs(GlassCard__default.default, { padding: "md", hover: true, className: "flex items-start gap-3 h-full", children: [
44
+ icon ? /* @__PURE__ */ jsxRuntime.jsx(
45
+ "img",
46
+ {
47
+ src: icon.url,
48
+ alt: tech.name,
49
+ width: 28,
50
+ height: 28,
51
+ loading: "lazy",
52
+ decoding: "async",
53
+ className: "w-7 h-7 object-contain shrink-0 mt-0.5"
54
+ }
55
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
56
+ "div",
57
+ {
58
+ className: "w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5",
59
+ style: {
60
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
61
+ color: "var(--sk-primary, #6366f1)"
62
+ },
63
+ children: tech.name.charAt(0)
64
+ }
65
+ ),
66
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
67
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-0.5", children: [
68
+ /* @__PURE__ */ jsxRuntime.jsx(
69
+ "span",
70
+ {
71
+ className: "text-sm font-semibold",
72
+ style: { color: "var(--sk-text-primary, #ffffff)" },
73
+ children: tech.name
74
+ }
75
+ ),
76
+ /* @__PURE__ */ jsxRuntime.jsx(
77
+ "span",
78
+ {
79
+ className: "text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded",
80
+ style: {
81
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)",
82
+ color: "var(--sk-primary, #6366f1)"
83
+ },
84
+ children: tech.category
85
+ }
86
+ )
87
+ ] }),
88
+ tech.description && /* @__PURE__ */ jsxRuntime.jsx(
89
+ "p",
90
+ {
91
+ className: "text-xs leading-relaxed",
92
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
93
+ children: tech.description
94
+ }
95
+ )
96
+ ] })
97
+ ] }) }, ti);
98
+ }) })
99
+ ] })
100
+ }
101
+ );
102
+ }
103
+
104
+ module.exports = TechStackSection;
105
+ //# sourceMappingURL=TechStackSection.cjs.map
106
+ //# sourceMappingURL=TechStackSection.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/TechStackSection.tsx"],"names":["jsx","jsxs","ScrollReveal","resolvePortfolioImage","GlassCard"],"mappings":"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","file":"TechStackSection.cjs","sourcesContent":["// Server component — renders on the server; the client primitives below cross the\n// RSC boundary via package subpaths (never import them relatively here).\nimport React from 'react';\nimport type { PortfolioTechStackData } from '../../../types';\nimport { resolvePortfolioImage } from '../../../shared/images';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\n\ninterface TechStackSectionProps {\n data: PortfolioTechStackData;\n}\n\nexport default function TechStackSection({ data }: TechStackSectionProps) {\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Tech Stack\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The technologies and tools powering this project.\n </p>\n </ScrollReveal>\n\n {/* All technologies in a 2-3 column grid — never single column */}\n <div className=\"grid grid-cols-2 lg:grid-cols-3 gap-4\">\n {data.technologies.map((tech, ti) => {\n const icon = resolvePortfolioImage(tech.icon);\n return (\n <ScrollReveal key={ti} y={20} delay={ti * 0.05}>\n <GlassCard padding=\"md\" hover className=\"flex items-start gap-3 h-full\">\n {icon ? (\n <img\n src={icon.url}\n alt={tech.name}\n width={28}\n height={28}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"w-7 h-7 object-contain shrink-0 mt-0.5\"\n />\n ) : (\n <div\n className=\"w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.name.charAt(0)}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span\n className=\"text-sm font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {tech.name}\n </span>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.category}\n </span>\n </div>\n {tech.description && (\n <p\n className=\"text-xs leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {tech.description}\n </p>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n );\n })}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { h as PortfolioTechStackData } from '../../types-0tVPy4pU.cjs';
3
+
4
+ interface TechStackSectionProps {
5
+ data: PortfolioTechStackData;
6
+ }
7
+ declare function TechStackSection({ data }: TechStackSectionProps): React.JSX.Element;
8
+
9
+ export { TechStackSection as default };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { h as PortfolioTechStackData } from '../../types-0tVPy4pU.js';
3
+
4
+ interface TechStackSectionProps {
5
+ data: PortfolioTechStackData;
6
+ }
7
+ declare function TechStackSection({ data }: TechStackSectionProps): React.JSX.Element;
8
+
9
+ export { TechStackSection as default };
@@ -0,0 +1,99 @@
1
+ import { resolvePortfolioImage } from '../../chunk-XJ434N7I.js';
2
+ import ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';
3
+ import GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ function TechStackSection({ data }) {
7
+ return /* @__PURE__ */ jsx(
8
+ "section",
9
+ {
10
+ className: "w-full py-20 md:py-28",
11
+ style: { background: "var(--sk-bg, #0a0a0a)" },
12
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
13
+ /* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
14
+ /* @__PURE__ */ jsx(
15
+ "h2",
16
+ {
17
+ className: "text-3xl md:text-4xl font-bold mb-4",
18
+ style: {
19
+ color: "var(--sk-text-primary, #ffffff)",
20
+ fontFamily: "var(--sk-font-heading, inherit)"
21
+ },
22
+ children: "Tech Stack"
23
+ }
24
+ ),
25
+ /* @__PURE__ */ jsx(
26
+ "p",
27
+ {
28
+ className: "text-lg mb-12 max-w-2xl",
29
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
30
+ children: "The technologies and tools powering this project."
31
+ }
32
+ )
33
+ ] }),
34
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-4", children: data.technologies.map((tech, ti) => {
35
+ const icon = resolvePortfolioImage(tech.icon);
36
+ return /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: ti * 0.05, children: /* @__PURE__ */ jsxs(GlassCard, { padding: "md", hover: true, className: "flex items-start gap-3 h-full", children: [
37
+ icon ? /* @__PURE__ */ jsx(
38
+ "img",
39
+ {
40
+ src: icon.url,
41
+ alt: tech.name,
42
+ width: 28,
43
+ height: 28,
44
+ loading: "lazy",
45
+ decoding: "async",
46
+ className: "w-7 h-7 object-contain shrink-0 mt-0.5"
47
+ }
48
+ ) : /* @__PURE__ */ jsx(
49
+ "div",
50
+ {
51
+ className: "w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5",
52
+ style: {
53
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
54
+ color: "var(--sk-primary, #6366f1)"
55
+ },
56
+ children: tech.name.charAt(0)
57
+ }
58
+ ),
59
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
60
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-0.5", children: [
61
+ /* @__PURE__ */ jsx(
62
+ "span",
63
+ {
64
+ className: "text-sm font-semibold",
65
+ style: { color: "var(--sk-text-primary, #ffffff)" },
66
+ children: tech.name
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsx(
70
+ "span",
71
+ {
72
+ className: "text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded",
73
+ style: {
74
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)",
75
+ color: "var(--sk-primary, #6366f1)"
76
+ },
77
+ children: tech.category
78
+ }
79
+ )
80
+ ] }),
81
+ tech.description && /* @__PURE__ */ jsx(
82
+ "p",
83
+ {
84
+ className: "text-xs leading-relaxed",
85
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
86
+ children: tech.description
87
+ }
88
+ )
89
+ ] })
90
+ ] }) }, ti);
91
+ }) })
92
+ ] })
93
+ }
94
+ );
95
+ }
96
+
97
+ export { TechStackSection as default };
98
+ //# sourceMappingURL=TechStackSection.js.map
99
+ //# sourceMappingURL=TechStackSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/sections/TechStackSection.tsx"],"names":[],"mappings":";;;;;AAYe,SAAR,gBAAA,CAAkC,EAAE,IAAA,EAAK,EAA0B;AAExE,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,uBAAA;AAAA,MACV,KAAA,EAAO,EAAE,UAAA,EAAY,uBAAA,EAAwB;AAAA,MAE7C,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,YAAA,EAAA,EAAa,GAAG,EAAA,EACf,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,qCAAA;AAAA,cACV,KAAA,EAAO;AAAA,gBACL,KAAA,EAAO,iCAAA;AAAA,gBACP,UAAA,EAAY;AAAA,eACd;AAAA,cACD,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,yBAAA;AAAA,cACV,KAAA,EAAO,EAAE,KAAA,EAAO,mCAAA,EAAoC;AAAA,cACrD,QAAA,EAAA;AAAA;AAAA;AAED,SAAA,EACF,CAAA;AAAA,wBAGA,GAAA,CAAC,SAAI,SAAA,EAAU,uCAAA,EACZ,eAAK,YAAA,CAAa,GAAA,CAAI,CAAC,IAAA,EAAM,EAAA,KAAO;AACnC,UAAA,MAAM,IAAA,GAAO,qBAAA,CAAsB,IAAA,CAAK,IAAI,CAAA;AAC5C,UAAA,uBACA,GAAA,CAAC,YAAA,EAAA,EAAsB,CAAA,EAAG,EAAA,EAAI,OAAO,EAAA,GAAK,IAAA,EACxC,QAAA,kBAAA,IAAA,CAAC,SAAA,EAAA,EAAU,OAAA,EAAQ,IAAA,EAAK,KAAA,EAAK,IAAA,EAAC,WAAU,+BAAA,EACrC,QAAA,EAAA;AAAA,YAAA,IAAA,mBACC,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,KAAK,IAAA,CAAK,GAAA;AAAA,gBACV,KAAK,IAAA,CAAK,IAAA;AAAA,gBACV,KAAA,EAAO,EAAA;AAAA,gBACP,MAAA,EAAQ,EAAA;AAAA,gBACR,OAAA,EAAQ,MAAA;AAAA,gBACR,QAAA,EAAS,OAAA;AAAA,gBACT,SAAA,EAAU;AAAA;AAAA,aACZ,mBAEA,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,uFAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,UAAA,EAAY,iEAAA;AAAA,kBACZ,KAAA,EAAO;AAAA,iBACT;AAAA,gBAEC,QAAA,EAAA,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAC;AAAA;AAAA,aACrB;AAAA,4BAEF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gCAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,uBAAA;AAAA,oBACV,KAAA,EAAO,EAAE,KAAA,EAAO,iCAAA,EAAkC;AAAA,oBAEjD,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,iBACR;AAAA,gCACA,GAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,wEAAA;AAAA,oBACV,KAAA,EAAO;AAAA,sBACL,UAAA,EAAY,iEAAA;AAAA,sBACZ,KAAA,EAAO;AAAA,qBACT;AAAA,oBAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR,eAAA,EACF,CAAA;AAAA,cACC,KAAK,WAAA,oBACJ,GAAA;AAAA,gBAAC,GAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,yBAAA;AAAA,kBACV,KAAA,EAAO,EAAE,KAAA,EAAO,kCAAA,EAAmC;AAAA,kBAElD,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR,aAAA,EAEJ;AAAA,WAAA,EACF,KAlDiB,EAmDnB,CAAA;AAAA,QAEF,CAAC,CAAA,EACH;AAAA,OAAA,EACF;AAAA;AAAA,GACF;AAEJ","file":"TechStackSection.js","sourcesContent":["// Server component — renders on the server; the client primitives below cross the\n// RSC boundary via package subpaths (never import them relatively here).\nimport React from 'react';\nimport type { PortfolioTechStackData } from '../../../types';\nimport { resolvePortfolioImage } from '../../../shared/images';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\n\ninterface TechStackSectionProps {\n data: PortfolioTechStackData;\n}\n\nexport default function TechStackSection({ data }: TechStackSectionProps) {\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Tech Stack\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The technologies and tools powering this project.\n </p>\n </ScrollReveal>\n\n {/* All technologies in a 2-3 column grid — never single column */}\n <div className=\"grid grid-cols-2 lg:grid-cols-3 gap-4\">\n {data.technologies.map((tech, ti) => {\n const icon = resolvePortfolioImage(tech.icon);\n return (\n <ScrollReveal key={ti} y={20} delay={ti * 0.05}>\n <GlassCard padding=\"md\" hover className=\"flex items-start gap-3 h-full\">\n {icon ? (\n <img\n src={icon.url}\n alt={tech.name}\n width={28}\n height={28}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"w-7 h-7 object-contain shrink-0 mt-0.5\"\n />\n ) : (\n <div\n className=\"w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.name.charAt(0)}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span\n className=\"text-sm font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {tech.name}\n </span>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.category}\n </span>\n </div>\n {tech.description && (\n <p\n className=\"text-xs leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {tech.description}\n </p>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n );\n })}\n </div>\n </div>\n </section>\n );\n}\n"]}