@sonordev/agency-site-kit 0.3.0 → 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 (365) 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 -30
  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 -8
  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 -19
  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 -6
  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 -139
  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 -137
  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-2UNKXWQM.js +0 -630
  335. package/dist/chunk-2UNKXWQM.js.map +0 -1
  336. package/dist/chunk-2Y4O3LWM.js +0 -53
  337. package/dist/chunk-2Y4O3LWM.js.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-EE75WRCM.cjs.map +0 -1
  343. package/dist/chunk-FDFVLYAM.cjs +0 -637
  344. package/dist/chunk-FDFVLYAM.cjs.map +0 -1
  345. package/dist/chunk-IKBK7HYX.cjs +0 -79
  346. package/dist/chunk-IKBK7HYX.cjs.map +0 -1
  347. package/dist/chunk-KEOHORIH.cjs +0 -79
  348. package/dist/chunk-KEOHORIH.cjs.map +0 -1
  349. package/dist/chunk-OA5ZM4OA.cjs +0 -139
  350. package/dist/chunk-OA5ZM4OA.cjs.map +0 -1
  351. package/dist/chunk-TVFXN6W6.js.map +0 -1
  352. package/dist/chunk-XCKXHK44.js +0 -15
  353. package/dist/chunk-XCKXHK44.js.map +0 -1
  354. package/dist/chunk-XONXEFJY.cjs +0 -58
  355. package/dist/chunk-XONXEFJY.cjs.map +0 -1
  356. package/dist/chunk-XQNJED46.cjs +0 -19
  357. package/dist/chunk-XQNJED46.cjs.map +0 -1
  358. package/dist/chunk-YB4B3OMC.js +0 -74
  359. package/dist/chunk-YB4B3OMC.js.map +0 -1
  360. package/dist/portfolio/sections.cjs +0 -20
  361. package/dist/portfolio/sections.cjs.map +0 -1
  362. package/dist/portfolio/sections.d.cts +0 -42
  363. package/dist/portfolio/sections.d.ts +0 -42
  364. package/dist/portfolio/sections.js +0 -4
  365. package/dist/portfolio/sections.js.map +0 -1
@@ -1,41 +1,41 @@
1
1
  'use strict';
2
2
 
3
- var chunkFDFVLYAM_cjs = require('../chunk-FDFVLYAM.cjs');
4
- require('../chunk-XONXEFJY.cjs');
5
- var chunkXQNJED46_cjs = require('../chunk-XQNJED46.cjs');
6
- var chunkOA5ZM4OA_cjs = require('../chunk-OA5ZM4OA.cjs');
7
- require('../chunk-KEOHORIH.cjs');
8
- require('../chunk-IKBK7HYX.cjs');
3
+ var chunkL7E3UHQC_cjs = require('../chunk-L7E3UHQC.cjs');
4
+ var chunk4N7ENJ7L_cjs = require('../chunk-4N7ENJ7L.cjs');
5
+ require('../chunk-7ZHRMWJU.cjs');
6
+ require('../chunk-FCKDJ4MJ.cjs');
7
+ require('../chunk-HQGAX2LI.cjs');
8
+ require('../chunk-XOWSXZYW.cjs');
9
9
 
10
10
 
11
11
 
12
12
  Object.defineProperty(exports, "PORTFOLIO_SECTION_TYPES", {
13
13
  enumerable: true,
14
- get: function () { return chunkFDFVLYAM_cjs.PORTFOLIO_SECTION_TYPES; }
14
+ get: function () { return chunkL7E3UHQC_cjs.PORTFOLIO_SECTION_TYPES; }
15
15
  });
16
- Object.defineProperty(exports, "PortfolioPage", {
16
+ Object.defineProperty(exports, "PortfolioIndex", {
17
17
  enumerable: true,
18
- get: function () { return chunkFDFVLYAM_cjs.PortfolioPage; }
18
+ get: function () { return chunkL7E3UHQC_cjs.PortfolioIndex; }
19
19
  });
20
- Object.defineProperty(exports, "getRegisteredSectionTypes", {
20
+ Object.defineProperty(exports, "PortfolioIndexSkeleton", {
21
21
  enumerable: true,
22
- get: function () { return chunkXQNJED46_cjs.getRegisteredSectionTypes; }
22
+ get: function () { return chunkL7E3UHQC_cjs.PortfolioIndexSkeleton; }
23
23
  });
24
- Object.defineProperty(exports, "getSectionRenderer", {
24
+ Object.defineProperty(exports, "PortfolioPage", {
25
25
  enumerable: true,
26
- get: function () { return chunkXQNJED46_cjs.getSectionRenderer; }
26
+ get: function () { return chunkL7E3UHQC_cjs.PortfolioPage; }
27
27
  });
28
- Object.defineProperty(exports, "registerSectionRenderer", {
28
+ Object.defineProperty(exports, "PortfolioPageSkeleton", {
29
29
  enumerable: true,
30
- get: function () { return chunkXQNJED46_cjs.registerSectionRenderer; }
30
+ get: function () { return chunkL7E3UHQC_cjs.PortfolioPageSkeleton; }
31
31
  });
32
- Object.defineProperty(exports, "PortfolioCard", {
32
+ Object.defineProperty(exports, "PortfolioSchema", {
33
33
  enumerable: true,
34
- get: function () { return chunkOA5ZM4OA_cjs.PortfolioCard; }
34
+ get: function () { return chunkL7E3UHQC_cjs.PortfolioSchema; }
35
35
  });
36
- Object.defineProperty(exports, "PortfolioGrid", {
36
+ Object.defineProperty(exports, "MetricsProvenance", {
37
37
  enumerable: true,
38
- get: function () { return chunkOA5ZM4OA_cjs.PortfolioGrid; }
38
+ get: function () { return chunk4N7ENJ7L_cjs.MetricsProvenance; }
39
39
  });
40
40
  //# sourceMappingURL=index.cjs.map
41
41
  //# sourceMappingURL=index.cjs.map
@@ -1,12 +1,138 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { P as PortfolioItemFull } from '../types-DL4t_Cfa.cjs';
3
- export { M as MetricSource, e as MetricsDelta, f as MetricsSnapshot, g as PORTFOLIO_SECTION_TYPES, i as PortfolioBeforeAfterData, j as PortfolioCTAData, l as PortfolioChallengesData, n as PortfolioConversionFunnelData, o as PortfolioDetailsData, p as PortfolioFeatureSpotlightData, r as PortfolioGalleryData, t as PortfolioHeroData, u as PortfolioItem, v as PortfolioKPI, a as PortfolioListResponse, x as PortfolioMetricsTimelineData, z as PortfolioResultsData, A as PortfolioSection, d as PortfolioSectionData, c as PortfolioSectionDataMap, b as PortfolioSectionType, C as PortfolioSeoData, E as PortfolioServicesData, F as PortfolioStrategyData, H as PortfolioTeamData, K as PortfolioTechStackData, L as PortfolioTestimonialData, N as PortfolioVideoData } from '../types-DL4t_Cfa.cjs';
4
- export { PortfolioCard, PortfolioCardProps, PortfolioFilterProps, PortfolioGrid, PortfolioGridProps, PortfolioPageClientProps, PortfolioSectionRendererProps } from './client.cjs';
5
- export { PortfolioSectionRenderer, PortfolioSectionRenderer as SectionRenderer, getRegisteredSectionTypes, getSectionRenderer, registerSectionRenderer } from './sections.cjs';
1
+ import React from 'react';
2
+ import { P as PortfolioItemFull, M as MetricsDelta } from '../types-0tVPy4pU.cjs';
3
+ export { j as MetricSource, k as MetricsSnapshot, l as PORTFOLIO_SECTION_TYPES, n as PortfolioBeforeAfterData, o as PortfolioCTAData, c as PortfolioChallengesData, r as PortfolioConversionFunnelData, d as PortfolioDetailsData, s as PortfolioFeatureSpotlightData, u as PortfolioGalleryData, e as PortfolioHeroData, w as PortfolioItem, x as PortfolioKPI, b as PortfolioListResponse, z as PortfolioMetricsTimelineData, f as PortfolioResultsData, a as PortfolioSection, C as PortfolioSectionData, D as PortfolioSectionDataMap, E as PortfolioSectionType, F as PortfolioSeoData, g as PortfolioServicesData, H as PortfolioStrategyData, J as PortfolioTeamData, h as PortfolioTechStackData, i as PortfolioTestimonialData, N as PortfolioVideoData } from '../types-0tVPy4pU.cjs';
4
+ export * from '@sonordev/agency-site-kit/portfolio/client';
5
+
6
+ /**
7
+ * PortfolioPage — Server component that renders a full portfolio case study.
8
+ *
9
+ * Maps each section in item.sections to the correct renderer component.
10
+ * All sections below the hero are loaded lazily via next/dynamic.
11
+ *
12
+ * NOTE: This file is intentionally NOT a client component — it is designed
13
+ * to be used as an RSC in a Next.js app directory page.
14
+ *
15
+ * Sections MUST be imported via `@sonordev/agency-site-kit/portfolio/sections/*`
16
+ * (self-referencing subpaths, external in tsup's server build), never via
17
+ * relative paths: a relative import would bundle the client sections into
18
+ * this server chunk, the 'use client' boundary would be lost, and the whole
19
+ * PortfolioItemFull would serialize into the RSC flight payload again.
20
+ *
21
+ * Whether a section is a server or client component is decided by the
22
+ * section file itself (its 'use client' directive; tsup routes it to the
23
+ * matching build). Server sections are imported statically — they ship zero
24
+ * client JS, so there is nothing to lazy-load. Client sections load through
25
+ * next/dynamic so each becomes its own browser chunk, fetched only when the
26
+ * case study actually renders that section type.
27
+ */
6
28
 
7
29
  interface PortfolioPageProps {
8
30
  item: PortfolioItemFull;
9
31
  }
10
- declare function PortfolioPage({ item }: PortfolioPageProps): react_jsx_runtime.JSX.Element;
32
+ declare function PortfolioPage({ item }: PortfolioPageProps): React.JSX.Element;
33
+
34
+ /**
35
+ * PortfolioSchema — JSON-LD structured data for a case study page.
36
+ *
37
+ * Server component: renders a single <script type="application/ld+json">
38
+ * describing the case study as a schema.org Article (there is no dedicated
39
+ * CaseStudy type; Article is what Google documents for editorial content).
40
+ * Ships zero client JS and adds rich-result eligibility + entity clarity for
41
+ * the agency's portfolio pages.
42
+ *
43
+ * Usage (in the case study page, next to <PortfolioPage />):
44
+ *
45
+ * ```tsx
46
+ * <PortfolioSchema
47
+ * item={item}
48
+ * url={`https://youragency.com/work/${item.slug}`}
49
+ * publisher={{ name: 'Your Agency', url: 'https://youragency.com' }}
50
+ * />
51
+ * ```
52
+ *
53
+ * Only reads fields from the already-sanitized PortfolioItemFull (see
54
+ * getPortfolioItem / sanitize.ts) — never section internals.
55
+ */
56
+
57
+ interface PortfolioSchemaProps {
58
+ item: PortfolioItemFull;
59
+ /** Canonical URL of this case study page. */
60
+ url: string;
61
+ /** The agency, emitted as author + publisher Organization. */
62
+ publisher?: {
63
+ name: string;
64
+ url?: string;
65
+ /** Absolute URL to a logo image. */
66
+ logo?: string;
67
+ };
68
+ }
69
+ declare function PortfolioSchema({ item, url, publisher }: PortfolioSchemaProps): React.JSX.Element;
70
+
71
+ /**
72
+ * PortfolioIndex — turnkey, server-rendered /work index.
73
+ *
74
+ * Fetches items + categories and renders: category nav (real links —
75
+ * crawlable, no client state), the portfolio grid, pagination, and an
76
+ * intentional empty state. Ships zero component JS.
77
+ *
78
+ * Category filtering is route-based for SEO:
79
+ * /work → all items
80
+ * /work/category/[category] → one category (slug via slugifyCategory)
81
+ * Pagination via ?page= on either route.
82
+ */
83
+
84
+ interface PortfolioIndexProps {
85
+ /** Route prefix for case studies + category links. Defaults to "/work". */
86
+ basePath?: string;
87
+ /** Active category SLUG (from the [category] route param). */
88
+ category?: string | null;
89
+ /** 1-based page number (from ?page=). */
90
+ page?: number;
91
+ /** Items per page. Defaults to 12. */
92
+ pageSize?: number;
93
+ /** Optional heading block rendered above the category nav. */
94
+ heading?: React.ReactNode;
95
+ /** Override the empty state. */
96
+ emptyState?: React.ReactNode;
97
+ /** Hide the category nav (e.g. single-category portfolios). */
98
+ showCategories?: boolean;
99
+ className?: string;
100
+ }
101
+ declare function PortfolioIndex({ basePath, category, page, pageSize, heading, emptyState, showCategories, className, }: PortfolioIndexProps): Promise<React.JSX.Element>;
102
+
103
+ /**
104
+ * MetricsProvenance — "these numbers are real" strip for case studies.
105
+ *
106
+ * Server component, zero JS. Renders the live metric deltas the platform
107
+ * computes from GSC/analytics baselines (MetricsDelta[]) plus the refresh
108
+ * timestamp — the trust signal a static agency portfolio can't fake.
109
+ *
110
+ * `direction` semantics come from the API: 'up' ALWAYS means "improved"
111
+ * (lower-is-better metrics like Avg Position/LCP are inverted server-side
112
+ * in metrics-baseline.service), so up renders positive/green.
113
+ */
114
+
115
+ interface MetricsProvenanceProps {
116
+ deltas: MetricsDelta[];
117
+ /** ISO timestamp of the last live-metrics refresh. */
118
+ refreshedAt?: string | null;
119
+ }
120
+ declare function MetricsProvenance({ deltas, refreshedAt }: MetricsProvenanceProps): React.JSX.Element | null;
121
+
122
+ /**
123
+ * Loading skeletons for portfolio routes — pure CSS pulse, server-safe,
124
+ * zero JS. Drop into `loading.tsx`:
125
+ *
126
+ * ```tsx
127
+ * export { PortfolioIndexSkeleton as default } from '@sonordev/agency-site-kit/portfolio';
128
+ * ```
129
+ */
130
+
131
+ /** Grid of pulsing card placeholders for the /work index. */
132
+ declare function PortfolioIndexSkeleton({ cards }: {
133
+ cards?: number;
134
+ }): React.JSX.Element;
135
+ /** Hero-shaped placeholder for /work/[slug] case study pages. */
136
+ declare function PortfolioPageSkeleton(): React.JSX.Element;
11
137
 
12
- export { PortfolioItemFull, PortfolioPage };
138
+ export { MetricsDelta, MetricsProvenance, PortfolioIndex, type PortfolioIndexProps, PortfolioIndexSkeleton, PortfolioItemFull, PortfolioPage, PortfolioPageSkeleton, PortfolioSchema };
@@ -1,12 +1,138 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { P as PortfolioItemFull } from '../types-DL4t_Cfa.js';
3
- export { M as MetricSource, e as MetricsDelta, f as MetricsSnapshot, g as PORTFOLIO_SECTION_TYPES, i as PortfolioBeforeAfterData, j as PortfolioCTAData, l as PortfolioChallengesData, n as PortfolioConversionFunnelData, o as PortfolioDetailsData, p as PortfolioFeatureSpotlightData, r as PortfolioGalleryData, t as PortfolioHeroData, u as PortfolioItem, v as PortfolioKPI, a as PortfolioListResponse, x as PortfolioMetricsTimelineData, z as PortfolioResultsData, A as PortfolioSection, d as PortfolioSectionData, c as PortfolioSectionDataMap, b as PortfolioSectionType, C as PortfolioSeoData, E as PortfolioServicesData, F as PortfolioStrategyData, H as PortfolioTeamData, K as PortfolioTechStackData, L as PortfolioTestimonialData, N as PortfolioVideoData } from '../types-DL4t_Cfa.js';
4
- export { PortfolioCard, PortfolioCardProps, PortfolioFilterProps, PortfolioGrid, PortfolioGridProps, PortfolioPageClientProps, PortfolioSectionRendererProps } from './client.js';
5
- export { PortfolioSectionRenderer, PortfolioSectionRenderer as SectionRenderer, getRegisteredSectionTypes, getSectionRenderer, registerSectionRenderer } from './sections.js';
1
+ import React from 'react';
2
+ import { P as PortfolioItemFull, M as MetricsDelta } from '../types-0tVPy4pU.js';
3
+ export { j as MetricSource, k as MetricsSnapshot, l as PORTFOLIO_SECTION_TYPES, n as PortfolioBeforeAfterData, o as PortfolioCTAData, c as PortfolioChallengesData, r as PortfolioConversionFunnelData, d as PortfolioDetailsData, s as PortfolioFeatureSpotlightData, u as PortfolioGalleryData, e as PortfolioHeroData, w as PortfolioItem, x as PortfolioKPI, b as PortfolioListResponse, z as PortfolioMetricsTimelineData, f as PortfolioResultsData, a as PortfolioSection, C as PortfolioSectionData, D as PortfolioSectionDataMap, E as PortfolioSectionType, F as PortfolioSeoData, g as PortfolioServicesData, H as PortfolioStrategyData, J as PortfolioTeamData, h as PortfolioTechStackData, i as PortfolioTestimonialData, N as PortfolioVideoData } from '../types-0tVPy4pU.js';
4
+ export * from '@sonordev/agency-site-kit/portfolio/client';
5
+
6
+ /**
7
+ * PortfolioPage — Server component that renders a full portfolio case study.
8
+ *
9
+ * Maps each section in item.sections to the correct renderer component.
10
+ * All sections below the hero are loaded lazily via next/dynamic.
11
+ *
12
+ * NOTE: This file is intentionally NOT a client component — it is designed
13
+ * to be used as an RSC in a Next.js app directory page.
14
+ *
15
+ * Sections MUST be imported via `@sonordev/agency-site-kit/portfolio/sections/*`
16
+ * (self-referencing subpaths, external in tsup's server build), never via
17
+ * relative paths: a relative import would bundle the client sections into
18
+ * this server chunk, the 'use client' boundary would be lost, and the whole
19
+ * PortfolioItemFull would serialize into the RSC flight payload again.
20
+ *
21
+ * Whether a section is a server or client component is decided by the
22
+ * section file itself (its 'use client' directive; tsup routes it to the
23
+ * matching build). Server sections are imported statically — they ship zero
24
+ * client JS, so there is nothing to lazy-load. Client sections load through
25
+ * next/dynamic so each becomes its own browser chunk, fetched only when the
26
+ * case study actually renders that section type.
27
+ */
6
28
 
7
29
  interface PortfolioPageProps {
8
30
  item: PortfolioItemFull;
9
31
  }
10
- declare function PortfolioPage({ item }: PortfolioPageProps): react_jsx_runtime.JSX.Element;
32
+ declare function PortfolioPage({ item }: PortfolioPageProps): React.JSX.Element;
33
+
34
+ /**
35
+ * PortfolioSchema — JSON-LD structured data for a case study page.
36
+ *
37
+ * Server component: renders a single <script type="application/ld+json">
38
+ * describing the case study as a schema.org Article (there is no dedicated
39
+ * CaseStudy type; Article is what Google documents for editorial content).
40
+ * Ships zero client JS and adds rich-result eligibility + entity clarity for
41
+ * the agency's portfolio pages.
42
+ *
43
+ * Usage (in the case study page, next to <PortfolioPage />):
44
+ *
45
+ * ```tsx
46
+ * <PortfolioSchema
47
+ * item={item}
48
+ * url={`https://youragency.com/work/${item.slug}`}
49
+ * publisher={{ name: 'Your Agency', url: 'https://youragency.com' }}
50
+ * />
51
+ * ```
52
+ *
53
+ * Only reads fields from the already-sanitized PortfolioItemFull (see
54
+ * getPortfolioItem / sanitize.ts) — never section internals.
55
+ */
56
+
57
+ interface PortfolioSchemaProps {
58
+ item: PortfolioItemFull;
59
+ /** Canonical URL of this case study page. */
60
+ url: string;
61
+ /** The agency, emitted as author + publisher Organization. */
62
+ publisher?: {
63
+ name: string;
64
+ url?: string;
65
+ /** Absolute URL to a logo image. */
66
+ logo?: string;
67
+ };
68
+ }
69
+ declare function PortfolioSchema({ item, url, publisher }: PortfolioSchemaProps): React.JSX.Element;
70
+
71
+ /**
72
+ * PortfolioIndex — turnkey, server-rendered /work index.
73
+ *
74
+ * Fetches items + categories and renders: category nav (real links —
75
+ * crawlable, no client state), the portfolio grid, pagination, and an
76
+ * intentional empty state. Ships zero component JS.
77
+ *
78
+ * Category filtering is route-based for SEO:
79
+ * /work → all items
80
+ * /work/category/[category] → one category (slug via slugifyCategory)
81
+ * Pagination via ?page= on either route.
82
+ */
83
+
84
+ interface PortfolioIndexProps {
85
+ /** Route prefix for case studies + category links. Defaults to "/work". */
86
+ basePath?: string;
87
+ /** Active category SLUG (from the [category] route param). */
88
+ category?: string | null;
89
+ /** 1-based page number (from ?page=). */
90
+ page?: number;
91
+ /** Items per page. Defaults to 12. */
92
+ pageSize?: number;
93
+ /** Optional heading block rendered above the category nav. */
94
+ heading?: React.ReactNode;
95
+ /** Override the empty state. */
96
+ emptyState?: React.ReactNode;
97
+ /** Hide the category nav (e.g. single-category portfolios). */
98
+ showCategories?: boolean;
99
+ className?: string;
100
+ }
101
+ declare function PortfolioIndex({ basePath, category, page, pageSize, heading, emptyState, showCategories, className, }: PortfolioIndexProps): Promise<React.JSX.Element>;
102
+
103
+ /**
104
+ * MetricsProvenance — "these numbers are real" strip for case studies.
105
+ *
106
+ * Server component, zero JS. Renders the live metric deltas the platform
107
+ * computes from GSC/analytics baselines (MetricsDelta[]) plus the refresh
108
+ * timestamp — the trust signal a static agency portfolio can't fake.
109
+ *
110
+ * `direction` semantics come from the API: 'up' ALWAYS means "improved"
111
+ * (lower-is-better metrics like Avg Position/LCP are inverted server-side
112
+ * in metrics-baseline.service), so up renders positive/green.
113
+ */
114
+
115
+ interface MetricsProvenanceProps {
116
+ deltas: MetricsDelta[];
117
+ /** ISO timestamp of the last live-metrics refresh. */
118
+ refreshedAt?: string | null;
119
+ }
120
+ declare function MetricsProvenance({ deltas, refreshedAt }: MetricsProvenanceProps): React.JSX.Element | null;
121
+
122
+ /**
123
+ * Loading skeletons for portfolio routes — pure CSS pulse, server-safe,
124
+ * zero JS. Drop into `loading.tsx`:
125
+ *
126
+ * ```tsx
127
+ * export { PortfolioIndexSkeleton as default } from '@sonordev/agency-site-kit/portfolio';
128
+ * ```
129
+ */
130
+
131
+ /** Grid of pulsing card placeholders for the /work index. */
132
+ declare function PortfolioIndexSkeleton({ cards }: {
133
+ cards?: number;
134
+ }): React.JSX.Element;
135
+ /** Hero-shaped placeholder for /work/[slug] case study pages. */
136
+ declare function PortfolioPageSkeleton(): React.JSX.Element;
11
137
 
12
- export { PortfolioItemFull, PortfolioPage };
138
+ export { MetricsDelta, MetricsProvenance, PortfolioIndex, type PortfolioIndexProps, PortfolioIndexSkeleton, PortfolioItemFull, PortfolioPage, PortfolioPageSkeleton, PortfolioSchema };
@@ -1,8 +1,8 @@
1
- export { PORTFOLIO_SECTION_TYPES, PortfolioPage } from '../chunk-2UNKXWQM.js';
2
- import '../chunk-2Y4O3LWM.js';
3
- export { getRegisteredSectionTypes, getSectionRenderer, registerSectionRenderer } from '../chunk-XCKXHK44.js';
4
- export { PortfolioCard, PortfolioGrid } from '../chunk-APG2QSMB.js';
5
- import '../chunk-YB4B3OMC.js';
6
- import '../chunk-7CFFAKDM.js';
1
+ export { PORTFOLIO_SECTION_TYPES, PortfolioIndex, PortfolioIndexSkeleton, PortfolioPage, PortfolioPageSkeleton, PortfolioSchema } from '../chunk-UNTOEWQL.js';
2
+ export { MetricsProvenance } from '../chunk-NIZJLONK.js';
3
+ import '../chunk-KXLROAO5.js';
4
+ import '../chunk-N7TVKUYQ.js';
5
+ import '../chunk-L4EOQVRJ.js';
6
+ import '../chunk-QL6KVIFR.js';
7
7
  //# sourceMappingURL=index.js.map
8
8
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,88 @@
1
+ 'use client';
2
+ "use strict";
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/portfolio/components/primitives/AnimatedCounter.tsx
23
+ var AnimatedCounter_exports = {};
24
+ __export(AnimatedCounter_exports, {
25
+ default: () => AnimatedCounter
26
+ });
27
+ module.exports = __toCommonJS(AnimatedCounter_exports);
28
+ var import_react = require("react");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ function AnimatedCounter({
31
+ value,
32
+ suffix = "",
33
+ prefix = "",
34
+ duration = 2,
35
+ decimals = 0,
36
+ className,
37
+ once = true
38
+ }) {
39
+ const ref = (0, import_react.useRef)(null);
40
+ const format = (v) => `${prefix}${decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString()}${suffix}`;
41
+ const [display, setDisplay] = (0, import_react.useState)(() => format(value));
42
+ (0, import_react.useEffect)(() => {
43
+ const el = ref.current;
44
+ if (!el) return;
45
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
46
+ setDisplay(format(value));
47
+ return;
48
+ }
49
+ const rect = el.getBoundingClientRect();
50
+ if (rect.top < window.innerHeight && rect.bottom > 0) return;
51
+ let raf = 0;
52
+ let played = false;
53
+ const easeOut = (t) => 1 - Math.pow(1 - t, 2);
54
+ const run = () => {
55
+ const start = performance.now();
56
+ const ms = duration * 1e3;
57
+ const tick = (now) => {
58
+ const p = Math.min(1, (now - start) / ms);
59
+ setDisplay(format(value * easeOut(p)));
60
+ if (p < 1) raf = requestAnimationFrame(tick);
61
+ };
62
+ setDisplay(format(0));
63
+ raf = requestAnimationFrame(tick);
64
+ };
65
+ const io = new IntersectionObserver(
66
+ ([entry]) => {
67
+ if (entry.isIntersecting) {
68
+ if (once && played) return;
69
+ played = true;
70
+ run();
71
+ if (once) io.disconnect();
72
+ } else if (!once && played) {
73
+ cancelAnimationFrame(raf);
74
+ setDisplay(format(0));
75
+ }
76
+ },
77
+ { rootMargin: "0px 0px -15% 0px" }
78
+ // ≈ gsap 'top 85%'
79
+ );
80
+ io.observe(el);
81
+ return () => {
82
+ io.disconnect();
83
+ cancelAnimationFrame(raf);
84
+ };
85
+ }, [value, suffix, prefix, duration, decimals, once]);
86
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ref, className, children: display });
87
+ }
88
+ //# sourceMappingURL=AnimatedCounter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/primitives/AnimatedCounter.tsx"],"sourcesContent":["'use client';\n\nimport React, { useRef, useEffect, useState } from 'react';\n\ninterface AnimatedCounterProps {\n value: number;\n suffix?: string;\n prefix?: string;\n duration?: number;\n decimals?: number;\n className?: string;\n once?: boolean;\n}\n\n/**\n * Count-up metric — IntersectionObserver + requestAnimationFrame, no gsap.\n *\n * SSR renders the REAL final value (SEO, screen readers, and no-JS users see\n * the true number — the old gsap version served \"0\" in the HTML). The\n * count-up runs only for counters still below the viewport at hydration;\n * above-the-fold values stay put per the house LCP rule.\n */\nexport default function AnimatedCounter({\n value,\n suffix = '',\n prefix = '',\n duration = 2,\n decimals = 0,\n className,\n once = true,\n}: AnimatedCounterProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const format = (v: number) =>\n `${prefix}${decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString()}${suffix}`;\n const [display, setDisplay] = useState(() => format(value));\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n setDisplay(format(value));\n return;\n }\n\n // Already visible at hydration → keep the final value, no re-zeroing.\n const rect = el.getBoundingClientRect();\n if (rect.top < window.innerHeight && rect.bottom > 0) return;\n\n let raf = 0;\n let played = false;\n const easeOut = (t: number) => 1 - Math.pow(1 - t, 2); // ≈ power2.out\n\n const run = () => {\n const start = performance.now();\n const ms = duration * 1000;\n const tick = (now: number) => {\n const p = Math.min(1, (now - start) / ms);\n setDisplay(format(value * easeOut(p)));\n if (p < 1) raf = requestAnimationFrame(tick);\n };\n setDisplay(format(0));\n raf = requestAnimationFrame(tick);\n };\n\n const io = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n if (once && played) return;\n played = true;\n run();\n if (once) io.disconnect();\n } else if (!once && played) {\n cancelAnimationFrame(raf);\n setDisplay(format(0));\n }\n },\n { rootMargin: '0px 0px -15% 0px' }, // ≈ gsap 'top 85%'\n );\n io.observe(el);\n\n return () => {\n io.disconnect();\n cancelAnimationFrame(raf);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value, suffix, prefix, duration, decimals, once]);\n\n return (\n <span ref={ref} className={className}>\n {display}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAmD;AAsF/C;AAlEW,SAAR,gBAAiC;AAAA,EACtC;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA,OAAO;AACT,GAAyB;AACvB,QAAM,UAAM,qBAAwB,IAAI;AACxC,QAAM,SAAS,CAAC,MACd,GAAG,MAAM,GAAG,WAAW,IAAI,EAAE,QAAQ,QAAQ,IAAI,KAAK,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,MAAM;AAC1F,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,MAAM,OAAO,KAAK,CAAC;AAE1D,8BAAU,MAAM;AACd,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,QAAI,OAAO,WAAW,kCAAkC,EAAE,SAAS;AACjE,iBAAW,OAAO,KAAK,CAAC;AACxB;AAAA,IACF;AAGA,UAAM,OAAO,GAAG,sBAAsB;AACtC,QAAI,KAAK,MAAM,OAAO,eAAe,KAAK,SAAS,EAAG;AAEtD,QAAI,MAAM;AACV,QAAI,SAAS;AACb,UAAM,UAAU,CAAC,MAAc,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAEpD,UAAM,MAAM,MAAM;AAChB,YAAM,QAAQ,YAAY,IAAI;AAC9B,YAAM,KAAK,WAAW;AACtB,YAAM,OAAO,CAAC,QAAgB;AAC5B,cAAM,IAAI,KAAK,IAAI,IAAI,MAAM,SAAS,EAAE;AACxC,mBAAW,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAAC;AACrC,YAAI,IAAI,EAAG,OAAM,sBAAsB,IAAI;AAAA,MAC7C;AACA,iBAAW,OAAO,CAAC,CAAC;AACpB,YAAM,sBAAsB,IAAI;AAAA,IAClC;AAEA,UAAM,KAAK,IAAI;AAAA,MACb,CAAC,CAAC,KAAK,MAAM;AACX,YAAI,MAAM,gBAAgB;AACxB,cAAI,QAAQ,OAAQ;AACpB,mBAAS;AACT,cAAI;AACJ,cAAI,KAAM,IAAG,WAAW;AAAA,QAC1B,WAAW,CAAC,QAAQ,QAAQ;AAC1B,+BAAqB,GAAG;AACxB,qBAAW,OAAO,CAAC,CAAC;AAAA,QACtB;AAAA,MACF;AAAA,MACA,EAAE,YAAY,mBAAmB;AAAA;AAAA,IACnC;AACA,OAAG,QAAQ,EAAE;AAEb,WAAO,MAAM;AACX,SAAG,WAAW;AACd,2BAAqB,GAAG;AAAA,IAC1B;AAAA,EAEF,GAAG,CAAC,OAAO,QAAQ,QAAQ,UAAU,UAAU,IAAI,CAAC;AAEpD,SACE,4CAAC,UAAK,KAAU,WACb,mBACH;AAEJ;","names":[]}
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+
3
+ interface AnimatedCounterProps {
4
+ value: number;
5
+ suffix?: string;
6
+ prefix?: string;
7
+ duration?: number;
8
+ decimals?: number;
9
+ className?: string;
10
+ once?: boolean;
11
+ }
12
+ /**
13
+ * Count-up metric — IntersectionObserver + requestAnimationFrame, no gsap.
14
+ *
15
+ * SSR renders the REAL final value (SEO, screen readers, and no-JS users see
16
+ * the true number — the old gsap version served "0" in the HTML). The
17
+ * count-up runs only for counters still below the viewport at hydration;
18
+ * above-the-fold values stay put per the house LCP rule.
19
+ */
20
+ declare function AnimatedCounter({ value, suffix, prefix, duration, decimals, className, once, }: AnimatedCounterProps): React.JSX.Element;
21
+
22
+ export { AnimatedCounter as default };
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+
3
+ interface AnimatedCounterProps {
4
+ value: number;
5
+ suffix?: string;
6
+ prefix?: string;
7
+ duration?: number;
8
+ decimals?: number;
9
+ className?: string;
10
+ once?: boolean;
11
+ }
12
+ /**
13
+ * Count-up metric — IntersectionObserver + requestAnimationFrame, no gsap.
14
+ *
15
+ * SSR renders the REAL final value (SEO, screen readers, and no-JS users see
16
+ * the true number — the old gsap version served "0" in the HTML). The
17
+ * count-up runs only for counters still below the viewport at hydration;
18
+ * above-the-fold values stay put per the house LCP rule.
19
+ */
20
+ declare function AnimatedCounter({ value, suffix, prefix, duration, decimals, className, once, }: AnimatedCounterProps): React.JSX.Element;
21
+
22
+ export { AnimatedCounter as default };
@@ -0,0 +1,68 @@
1
+ 'use client';
2
+ "use client";
3
+
4
+ // src/portfolio/components/primitives/AnimatedCounter.tsx
5
+ import { useRef, useEffect, useState } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function AnimatedCounter({
8
+ value,
9
+ suffix = "",
10
+ prefix = "",
11
+ duration = 2,
12
+ decimals = 0,
13
+ className,
14
+ once = true
15
+ }) {
16
+ const ref = useRef(null);
17
+ const format = (v) => `${prefix}${decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString()}${suffix}`;
18
+ const [display, setDisplay] = useState(() => format(value));
19
+ useEffect(() => {
20
+ const el = ref.current;
21
+ if (!el) return;
22
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
23
+ setDisplay(format(value));
24
+ return;
25
+ }
26
+ const rect = el.getBoundingClientRect();
27
+ if (rect.top < window.innerHeight && rect.bottom > 0) return;
28
+ let raf = 0;
29
+ let played = false;
30
+ const easeOut = (t) => 1 - Math.pow(1 - t, 2);
31
+ const run = () => {
32
+ const start = performance.now();
33
+ const ms = duration * 1e3;
34
+ const tick = (now) => {
35
+ const p = Math.min(1, (now - start) / ms);
36
+ setDisplay(format(value * easeOut(p)));
37
+ if (p < 1) raf = requestAnimationFrame(tick);
38
+ };
39
+ setDisplay(format(0));
40
+ raf = requestAnimationFrame(tick);
41
+ };
42
+ const io = new IntersectionObserver(
43
+ ([entry]) => {
44
+ if (entry.isIntersecting) {
45
+ if (once && played) return;
46
+ played = true;
47
+ run();
48
+ if (once) io.disconnect();
49
+ } else if (!once && played) {
50
+ cancelAnimationFrame(raf);
51
+ setDisplay(format(0));
52
+ }
53
+ },
54
+ { rootMargin: "0px 0px -15% 0px" }
55
+ // ≈ gsap 'top 85%'
56
+ );
57
+ io.observe(el);
58
+ return () => {
59
+ io.disconnect();
60
+ cancelAnimationFrame(raf);
61
+ };
62
+ }, [value, suffix, prefix, duration, decimals, once]);
63
+ return /* @__PURE__ */ jsx("span", { ref, className, children: display });
64
+ }
65
+ export {
66
+ AnimatedCounter as default
67
+ };
68
+ //# sourceMappingURL=AnimatedCounter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/portfolio/components/primitives/AnimatedCounter.tsx"],"sourcesContent":["'use client';\n\nimport React, { useRef, useEffect, useState } from 'react';\n\ninterface AnimatedCounterProps {\n value: number;\n suffix?: string;\n prefix?: string;\n duration?: number;\n decimals?: number;\n className?: string;\n once?: boolean;\n}\n\n/**\n * Count-up metric — IntersectionObserver + requestAnimationFrame, no gsap.\n *\n * SSR renders the REAL final value (SEO, screen readers, and no-JS users see\n * the true number — the old gsap version served \"0\" in the HTML). The\n * count-up runs only for counters still below the viewport at hydration;\n * above-the-fold values stay put per the house LCP rule.\n */\nexport default function AnimatedCounter({\n value,\n suffix = '',\n prefix = '',\n duration = 2,\n decimals = 0,\n className,\n once = true,\n}: AnimatedCounterProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const format = (v: number) =>\n `${prefix}${decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString()}${suffix}`;\n const [display, setDisplay] = useState(() => format(value));\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n setDisplay(format(value));\n return;\n }\n\n // Already visible at hydration → keep the final value, no re-zeroing.\n const rect = el.getBoundingClientRect();\n if (rect.top < window.innerHeight && rect.bottom > 0) return;\n\n let raf = 0;\n let played = false;\n const easeOut = (t: number) => 1 - Math.pow(1 - t, 2); // ≈ power2.out\n\n const run = () => {\n const start = performance.now();\n const ms = duration * 1000;\n const tick = (now: number) => {\n const p = Math.min(1, (now - start) / ms);\n setDisplay(format(value * easeOut(p)));\n if (p < 1) raf = requestAnimationFrame(tick);\n };\n setDisplay(format(0));\n raf = requestAnimationFrame(tick);\n };\n\n const io = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n if (once && played) return;\n played = true;\n run();\n if (once) io.disconnect();\n } else if (!once && played) {\n cancelAnimationFrame(raf);\n setDisplay(format(0));\n }\n },\n { rootMargin: '0px 0px -15% 0px' }, // ≈ gsap 'top 85%'\n );\n io.observe(el);\n\n return () => {\n io.disconnect();\n cancelAnimationFrame(raf);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value, suffix, prefix, duration, decimals, once]);\n\n return (\n <span ref={ref} className={className}>\n {display}\n </span>\n );\n}\n"],"mappings":";;;;AAEA,SAAgB,QAAQ,WAAW,gBAAgB;AAsF/C;AAlEW,SAAR,gBAAiC;AAAA,EACtC;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA,OAAO;AACT,GAAyB;AACvB,QAAM,MAAM,OAAwB,IAAI;AACxC,QAAM,SAAS,CAAC,MACd,GAAG,MAAM,GAAG,WAAW,IAAI,EAAE,QAAQ,QAAQ,IAAI,KAAK,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,MAAM;AAC1F,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,MAAM,OAAO,KAAK,CAAC;AAE1D,YAAU,MAAM;AACd,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,QAAI,OAAO,WAAW,kCAAkC,EAAE,SAAS;AACjE,iBAAW,OAAO,KAAK,CAAC;AACxB;AAAA,IACF;AAGA,UAAM,OAAO,GAAG,sBAAsB;AACtC,QAAI,KAAK,MAAM,OAAO,eAAe,KAAK,SAAS,EAAG;AAEtD,QAAI,MAAM;AACV,QAAI,SAAS;AACb,UAAM,UAAU,CAAC,MAAc,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAEpD,UAAM,MAAM,MAAM;AAChB,YAAM,QAAQ,YAAY,IAAI;AAC9B,YAAM,KAAK,WAAW;AACtB,YAAM,OAAO,CAAC,QAAgB;AAC5B,cAAM,IAAI,KAAK,IAAI,IAAI,MAAM,SAAS,EAAE;AACxC,mBAAW,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAAC;AACrC,YAAI,IAAI,EAAG,OAAM,sBAAsB,IAAI;AAAA,MAC7C;AACA,iBAAW,OAAO,CAAC,CAAC;AACpB,YAAM,sBAAsB,IAAI;AAAA,IAClC;AAEA,UAAM,KAAK,IAAI;AAAA,MACb,CAAC,CAAC,KAAK,MAAM;AACX,YAAI,MAAM,gBAAgB;AACxB,cAAI,QAAQ,OAAQ;AACpB,mBAAS;AACT,cAAI;AACJ,cAAI,KAAM,IAAG,WAAW;AAAA,QAC1B,WAAW,CAAC,QAAQ,QAAQ;AAC1B,+BAAqB,GAAG;AACxB,qBAAW,OAAO,CAAC,CAAC;AAAA,QACtB;AAAA,MACF;AAAA,MACA,EAAE,YAAY,mBAAmB;AAAA;AAAA,IACnC;AACA,OAAG,QAAQ,EAAE;AAEb,WAAO,MAAM;AACX,SAAG,WAAW;AACd,2BAAqB,GAAG;AAAA,IAC1B;AAAA,EAEF,GAAG,CAAC,OAAO,QAAQ,QAAQ,UAAU,UAAU,IAAI,CAAC;AAEpD,SACE,oBAAC,UAAK,KAAU,WACb,mBACH;AAEJ;","names":[]}