@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.
- package/README.md +302 -0
- package/bin/setup.mjs +79 -0
- package/dist/{chunk-RXBK2EOE.js → chunk-4IES23GV.js} +3 -3
- package/dist/{chunk-RXBK2EOE.js.map → chunk-4IES23GV.js.map} +1 -1
- package/dist/{chunk-WNR4KNG4.cjs → chunk-5MEZU3OG.cjs} +4 -4
- package/dist/{chunk-WNR4KNG4.cjs.map → chunk-5MEZU3OG.cjs.map} +1 -1
- package/dist/chunk-7D4H36UF.js +13 -0
- package/dist/chunk-7D4H36UF.js.map +1 -0
- package/dist/chunk-7ZHRMWJU.cjs +306 -0
- package/dist/chunk-7ZHRMWJU.cjs.map +1 -0
- package/dist/chunk-CVT7I5BQ.js +71 -0
- package/dist/chunk-CVT7I5BQ.js.map +1 -0
- package/dist/chunk-HQGAX2LI.cjs +8 -0
- package/dist/chunk-HQGAX2LI.cjs.map +1 -0
- package/dist/chunk-K2BGTDSN.js +45 -0
- package/dist/chunk-K2BGTDSN.js.map +1 -0
- package/dist/chunk-KXLROAO5.js +291 -0
- package/dist/chunk-KXLROAO5.js.map +1 -0
- package/dist/chunk-L4EOQVRJ.js +6 -0
- package/dist/chunk-L4EOQVRJ.js.map +1 -0
- package/dist/chunk-NI4FVCLS.cjs +32 -0
- package/dist/chunk-NI4FVCLS.cjs.map +1 -0
- package/dist/chunk-NLGUPJZA.js +507 -0
- package/dist/chunk-NLGUPJZA.js.map +1 -0
- package/dist/chunk-QDXZ27R7.js +33 -0
- package/dist/chunk-QDXZ27R7.js.map +1 -0
- package/dist/chunk-QGSW43TM.cjs +538 -0
- package/dist/chunk-QGSW43TM.cjs.map +1 -0
- package/dist/{chunk-TVFXN6W6.js → chunk-QL6KVIFR.js} +8 -4
- package/dist/chunk-QL6KVIFR.js.map +1 -0
- package/dist/chunk-RWQ675N6.js +165 -0
- package/dist/chunk-RWQ675N6.js.map +1 -0
- package/dist/chunk-UXUU7FVT.cjs +171 -0
- package/dist/chunk-UXUU7FVT.cjs.map +1 -0
- package/dist/chunk-XJ434N7I.js +30 -0
- package/dist/chunk-XJ434N7I.js.map +1 -0
- package/dist/{chunk-EE75WRCM.cjs → chunk-XOWSXZYW.cjs} +8 -4
- package/dist/chunk-XOWSXZYW.cjs.map +1 -0
- package/dist/chunk-ZBPF7TLZ.cjs +16 -0
- package/dist/chunk-ZBPF7TLZ.cjs.map +1 -0
- package/dist/chunk-ZINKVJQU.js +67 -0
- package/dist/chunk-ZINKVJQU.js.map +1 -0
- package/dist/index.cjs +53 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +8 -9
- package/dist/index.js.map +1 -1
- package/dist/layout/index.cjs +3 -3
- package/dist/layout/index.d.cts +1 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/index.js +2 -2
- package/dist/portfolio/client.cjs +376 -12
- package/dist/portfolio/client.cjs.map +1 -1
- package/dist/portfolio/client.d.cts +27 -85
- package/dist/portfolio/client.d.ts +27 -85
- package/dist/portfolio/client.js +182 -4
- package/dist/portfolio/client.js.map +1 -1
- package/dist/portfolio/components/PortfolioAnalytics.cjs +87 -0
- package/dist/portfolio/components/PortfolioAnalytics.cjs.map +1 -0
- package/dist/portfolio/components/PortfolioAnalytics.d.cts +5 -0
- package/dist/portfolio/components/PortfolioAnalytics.d.ts +5 -0
- package/dist/portfolio/components/PortfolioAnalytics.js +9 -0
- package/dist/portfolio/components/PortfolioAnalytics.js.map +1 -0
- package/dist/portfolio/components/PortfolioErrorFallback.cjs +65 -0
- package/dist/portfolio/components/PortfolioErrorFallback.cjs.map +1 -0
- package/dist/portfolio/components/PortfolioErrorFallback.d.cts +22 -0
- package/dist/portfolio/components/PortfolioErrorFallback.d.ts +22 -0
- package/dist/portfolio/components/PortfolioErrorFallback.js +9 -0
- package/dist/portfolio/components/PortfolioErrorFallback.js.map +1 -0
- package/dist/portfolio/components/PortfolioLeadCTA.cjs +91 -0
- package/dist/portfolio/components/PortfolioLeadCTA.cjs.map +1 -0
- package/dist/portfolio/components/PortfolioLeadCTA.d.cts +34 -0
- package/dist/portfolio/components/PortfolioLeadCTA.d.ts +34 -0
- package/dist/portfolio/components/PortfolioLeadCTA.js +9 -0
- package/dist/portfolio/components/PortfolioLeadCTA.js.map +1 -0
- package/dist/portfolio/index.cjs +43 -19
- package/dist/portfolio/index.d.cts +210 -7
- package/dist/portfolio/index.d.ts +210 -7
- package/dist/portfolio/index.js +7 -7
- package/dist/portfolio/primitives/AnimatedCounter.cjs +88 -0
- package/dist/portfolio/primitives/AnimatedCounter.cjs.map +1 -0
- package/dist/portfolio/primitives/AnimatedCounter.d.cts +22 -0
- package/dist/portfolio/primitives/AnimatedCounter.d.ts +22 -0
- package/dist/portfolio/primitives/AnimatedCounter.js +68 -0
- package/dist/portfolio/primitives/AnimatedCounter.js.map +1 -0
- package/dist/portfolio/primitives/AnnotatedImage.cjs +320 -0
- package/dist/portfolio/primitives/AnnotatedImage.cjs.map +1 -0
- package/dist/portfolio/primitives/AnnotatedImage.d.cts +18 -0
- package/dist/portfolio/primitives/AnnotatedImage.d.ts +18 -0
- package/dist/portfolio/primitives/AnnotatedImage.js +264 -0
- package/dist/portfolio/primitives/AnnotatedImage.js.map +1 -0
- package/dist/portfolio/primitives/BeforeAfterSlider.cjs +348 -0
- package/dist/portfolio/primitives/BeforeAfterSlider.cjs.map +1 -0
- package/dist/portfolio/primitives/BeforeAfterSlider.d.cts +13 -0
- package/dist/portfolio/primitives/BeforeAfterSlider.d.ts +13 -0
- package/dist/portfolio/primitives/BeforeAfterSlider.js +292 -0
- package/dist/portfolio/primitives/BeforeAfterSlider.js.map +1 -0
- package/dist/portfolio/primitives/DeviceTrifolio.cjs +298 -0
- package/dist/portfolio/primitives/DeviceTrifolio.cjs.map +1 -0
- package/dist/portfolio/primitives/DeviceTrifolio.d.cts +14 -0
- package/dist/portfolio/primitives/DeviceTrifolio.d.ts +14 -0
- package/dist/portfolio/primitives/DeviceTrifolio.js +242 -0
- package/dist/portfolio/primitives/DeviceTrifolio.js.map +1 -0
- package/dist/portfolio/primitives/FrequencyBarSkeleton.cjs +88 -0
- package/dist/portfolio/primitives/FrequencyBarSkeleton.cjs.map +1 -0
- package/dist/portfolio/primitives/FrequencyBarSkeleton.d.cts +10 -0
- package/dist/portfolio/primitives/FrequencyBarSkeleton.d.ts +10 -0
- package/dist/portfolio/primitives/FrequencyBarSkeleton.js +68 -0
- package/dist/portfolio/primitives/FrequencyBarSkeleton.js.map +1 -0
- package/dist/portfolio/primitives/GlassCard.cjs +45 -0
- package/dist/portfolio/primitives/GlassCard.cjs.map +1 -0
- package/dist/portfolio/primitives/GlassCard.d.cts +11 -0
- package/dist/portfolio/primitives/GlassCard.d.ts +11 -0
- package/dist/portfolio/primitives/GlassCard.js +43 -0
- package/dist/portfolio/primitives/GlassCard.js.map +1 -0
- package/dist/portfolio/primitives/MetricBadge.cjs +74 -0
- package/dist/portfolio/primitives/MetricBadge.cjs.map +1 -0
- package/dist/portfolio/primitives/MetricBadge.d.cts +9 -0
- package/dist/portfolio/primitives/MetricBadge.d.ts +9 -0
- package/dist/portfolio/primitives/MetricBadge.js +54 -0
- package/dist/portfolio/primitives/MetricBadge.js.map +1 -0
- package/dist/portfolio/primitives/SVGChart.cjs +316 -0
- package/dist/portfolio/primitives/SVGChart.cjs.map +1 -0
- package/dist/portfolio/primitives/SVGChart.d.cts +18 -0
- package/dist/portfolio/primitives/SVGChart.d.ts +18 -0
- package/dist/portfolio/primitives/SVGChart.js +296 -0
- package/dist/portfolio/primitives/SVGChart.js.map +1 -0
- package/dist/portfolio/primitives/ScrollReveal.cjs +97 -0
- package/dist/portfolio/primitives/ScrollReveal.cjs.map +1 -0
- package/dist/portfolio/primitives/ScrollReveal.d.cts +27 -0
- package/dist/portfolio/primitives/ScrollReveal.d.ts +27 -0
- package/dist/portfolio/primitives/ScrollReveal.js +77 -0
- package/dist/portfolio/primitives/ScrollReveal.js.map +1 -0
- package/dist/portfolio/primitives/SplitHeadline.cjs +107 -0
- package/dist/portfolio/primitives/SplitHeadline.cjs.map +1 -0
- package/dist/portfolio/primitives/SplitHeadline.d.cts +24 -0
- package/dist/portfolio/primitives/SplitHeadline.d.ts +24 -0
- package/dist/portfolio/primitives/SplitHeadline.js +87 -0
- package/dist/portfolio/primitives/SplitHeadline.js.map +1 -0
- package/dist/portfolio/sections/BeforeAfterSection.cjs +271 -0
- package/dist/portfolio/sections/BeforeAfterSection.cjs.map +1 -0
- package/dist/portfolio/sections/BeforeAfterSection.d.cts +9 -0
- package/dist/portfolio/sections/BeforeAfterSection.d.ts +9 -0
- package/dist/{BeforeAfterSection-6BHFLY4Y.js → portfolio/sections/BeforeAfterSection.js} +66 -27
- package/dist/portfolio/sections/BeforeAfterSection.js.map +1 -0
- package/dist/portfolio/sections/CTASection.cjs +123 -0
- package/dist/portfolio/sections/CTASection.cjs.map +1 -0
- package/dist/portfolio/sections/CTASection.d.cts +9 -0
- package/dist/portfolio/sections/CTASection.d.ts +9 -0
- package/dist/portfolio/sections/CTASection.js +93 -0
- package/dist/portfolio/sections/CTASection.js.map +1 -0
- package/dist/{ChallengesSection-IZ3DHECS.cjs → portfolio/sections/ChallengesSection.cjs} +13 -7
- package/dist/portfolio/sections/ChallengesSection.cjs.map +1 -0
- package/dist/portfolio/sections/ChallengesSection.d.cts +9 -0
- package/dist/portfolio/sections/ChallengesSection.d.ts +9 -0
- package/dist/{ChallengesSection-GEQGVSJN.js → portfolio/sections/ChallengesSection.js} +6 -5
- package/dist/portfolio/sections/ChallengesSection.js.map +1 -0
- package/dist/portfolio/sections/ConversionFunnelSection.cjs +263 -0
- package/dist/portfolio/sections/ConversionFunnelSection.cjs.map +1 -0
- package/dist/portfolio/sections/ConversionFunnelSection.d.cts +9 -0
- package/dist/portfolio/sections/ConversionFunnelSection.d.ts +9 -0
- package/dist/{ConversionFunnelSection-D3GE4NKE.js → portfolio/sections/ConversionFunnelSection.js} +60 -56
- package/dist/portfolio/sections/ConversionFunnelSection.js.map +1 -0
- package/dist/{DesignSystemSection-KXIQXITF.cjs → portfolio/sections/DesignSystemSection.cjs} +13 -7
- package/dist/portfolio/sections/DesignSystemSection.cjs.map +1 -0
- package/dist/portfolio/sections/DesignSystemSection.d.cts +32 -0
- package/dist/portfolio/sections/DesignSystemSection.d.ts +32 -0
- package/dist/{DesignSystemSection-2R5BRBGO.js → portfolio/sections/DesignSystemSection.js} +5 -4
- package/dist/portfolio/sections/DesignSystemSection.js.map +1 -0
- package/dist/{DetailsSection-TTUZAPZZ.cjs → portfolio/sections/DetailsSection.cjs} +12 -6
- package/dist/portfolio/sections/DetailsSection.cjs.map +1 -0
- package/dist/portfolio/sections/DetailsSection.d.cts +9 -0
- package/dist/portfolio/sections/DetailsSection.d.ts +9 -0
- package/dist/{DetailsSection-A6PZQUQL.js → portfolio/sections/DetailsSection.js} +5 -4
- package/dist/portfolio/sections/DetailsSection.js.map +1 -0
- package/dist/portfolio/sections/FeatureSpotlightSection.cjs +267 -0
- package/dist/portfolio/sections/FeatureSpotlightSection.cjs.map +1 -0
- package/dist/portfolio/sections/FeatureSpotlightSection.d.cts +9 -0
- package/dist/portfolio/sections/FeatureSpotlightSection.d.ts +9 -0
- package/dist/{FeatureSpotlightSection-B7P3JGNL.js → portfolio/sections/FeatureSpotlightSection.js} +39 -33
- package/dist/portfolio/sections/FeatureSpotlightSection.js.map +1 -0
- package/dist/portfolio/sections/GallerySection.cjs +321 -0
- package/dist/portfolio/sections/GallerySection.cjs.map +1 -0
- package/dist/portfolio/sections/GallerySection.d.cts +9 -0
- package/dist/portfolio/sections/GallerySection.d.ts +9 -0
- package/dist/{GallerySection-VMKORC47.js → portfolio/sections/GallerySection.js} +65 -18
- package/dist/portfolio/sections/GallerySection.js.map +1 -0
- package/dist/portfolio/sections/HeroSection.cjs +180 -0
- package/dist/portfolio/sections/HeroSection.cjs.map +1 -0
- package/dist/portfolio/sections/HeroSection.d.cts +15 -0
- package/dist/portfolio/sections/HeroSection.d.ts +15 -0
- package/dist/portfolio/sections/HeroSection.js +171 -0
- package/dist/portfolio/sections/HeroSection.js.map +1 -0
- package/dist/{MetricsTimelineSection-4L6DUHJ5.cjs → portfolio/sections/MetricsTimelineSection.cjs} +102 -61
- package/dist/portfolio/sections/MetricsTimelineSection.cjs.map +1 -0
- package/dist/portfolio/sections/MetricsTimelineSection.d.cts +9 -0
- package/dist/portfolio/sections/MetricsTimelineSection.d.ts +9 -0
- package/dist/{MetricsTimelineSection-6BT5GNFV.js → portfolio/sections/MetricsTimelineSection.js} +45 -29
- package/dist/portfolio/sections/MetricsTimelineSection.js.map +1 -0
- package/dist/portfolio/sections/PerformanceSection.cjs +336 -0
- package/dist/portfolio/sections/PerformanceSection.cjs.map +1 -0
- package/dist/portfolio/sections/PerformanceSection.d.cts +22 -0
- package/dist/portfolio/sections/PerformanceSection.d.ts +22 -0
- package/dist/{PerformanceSection-MGCEIXDX.js → portfolio/sections/PerformanceSection.js} +59 -104
- package/dist/portfolio/sections/PerformanceSection.js.map +1 -0
- package/dist/{ResultsSection-XLGMMQKY.cjs → portfolio/sections/ResultsSection.cjs} +23 -10
- package/dist/portfolio/sections/ResultsSection.cjs.map +1 -0
- package/dist/portfolio/sections/ResultsSection.d.cts +13 -0
- package/dist/portfolio/sections/ResultsSection.d.ts +13 -0
- package/dist/{ResultsSection-DFUJ5U6M.js → portfolio/sections/ResultsSection.js} +14 -7
- package/dist/portfolio/sections/ResultsSection.js.map +1 -0
- package/dist/portfolio/sections/ServicesSection.cjs +129 -0
- package/dist/portfolio/sections/ServicesSection.cjs.map +1 -0
- package/dist/portfolio/sections/ServicesSection.d.cts +9 -0
- package/dist/portfolio/sections/ServicesSection.d.ts +9 -0
- package/dist/portfolio/sections/ServicesSection.js +122 -0
- package/dist/portfolio/sections/ServicesSection.js.map +1 -0
- package/dist/{SiteArchitectureSection-J7BPBERH.cjs → portfolio/sections/SiteArchitectureSection.cjs} +117 -93
- package/dist/portfolio/sections/SiteArchitectureSection.cjs.map +1 -0
- package/dist/portfolio/sections/SiteArchitectureSection.d.cts +21 -0
- package/dist/portfolio/sections/SiteArchitectureSection.d.ts +21 -0
- package/dist/{SiteArchitectureSection-TE22OAWV.js → portfolio/sections/SiteArchitectureSection.js} +47 -48
- package/dist/portfolio/sections/SiteArchitectureSection.js.map +1 -0
- package/dist/{SpeedComparisonSection-EZKFQVGW.cjs → portfolio/sections/SpeedComparisonSection.cjs} +13 -7
- package/dist/portfolio/sections/SpeedComparisonSection.cjs.map +1 -0
- package/dist/portfolio/sections/SpeedComparisonSection.d.cts +20 -0
- package/dist/portfolio/sections/SpeedComparisonSection.d.ts +20 -0
- package/dist/{SpeedComparisonSection-Y3K7OFZQ.js → portfolio/sections/SpeedComparisonSection.js} +6 -5
- package/dist/portfolio/sections/SpeedComparisonSection.js.map +1 -0
- package/dist/portfolio/sections/StrategySection.cjs +233 -0
- package/dist/portfolio/sections/StrategySection.cjs.map +1 -0
- package/dist/portfolio/sections/StrategySection.d.cts +9 -0
- package/dist/portfolio/sections/StrategySection.d.ts +9 -0
- package/dist/{StrategySection-DI5RSCJU.js → portfolio/sections/StrategySection.js} +60 -26
- package/dist/portfolio/sections/StrategySection.js.map +1 -0
- package/dist/portfolio/sections/TeamSection.cjs +162 -0
- package/dist/portfolio/sections/TeamSection.cjs.map +1 -0
- package/dist/portfolio/sections/TeamSection.d.cts +9 -0
- package/dist/portfolio/sections/TeamSection.d.ts +9 -0
- package/dist/portfolio/sections/TeamSection.js +106 -0
- package/dist/portfolio/sections/TeamSection.js.map +1 -0
- package/dist/portfolio/sections/TechStackSection.cjs +106 -0
- package/dist/portfolio/sections/TechStackSection.cjs.map +1 -0
- package/dist/portfolio/sections/TechStackSection.d.cts +9 -0
- package/dist/portfolio/sections/TechStackSection.d.ts +9 -0
- package/dist/portfolio/sections/TechStackSection.js +99 -0
- package/dist/portfolio/sections/TechStackSection.js.map +1 -0
- package/dist/{TestimonialSection-XPTFUQIN.cjs → portfolio/sections/TestimonialSection.cjs} +47 -28
- package/dist/portfolio/sections/TestimonialSection.cjs.map +1 -0
- package/dist/portfolio/sections/TestimonialSection.d.cts +9 -0
- package/dist/portfolio/sections/TestimonialSection.d.ts +9 -0
- package/dist/{TestimonialSection-6RGSMXQB.js → portfolio/sections/TestimonialSection.js} +40 -27
- package/dist/portfolio/sections/TestimonialSection.js.map +1 -0
- package/dist/portfolio/sections/VideoSection.cjs +181 -0
- package/dist/portfolio/sections/VideoSection.cjs.map +1 -0
- package/dist/portfolio/sections/VideoSection.d.cts +9 -0
- package/dist/portfolio/sections/VideoSection.d.ts +9 -0
- package/dist/{VideoSection-4A2HC6K6.js → portfolio/sections/VideoSection.js} +21 -13
- package/dist/portfolio/sections/VideoSection.js.map +1 -0
- package/dist/portfolio/server.cjs +56 -144
- package/dist/portfolio/server.cjs.map +1 -1
- package/dist/portfolio/server.d.cts +157 -7
- package/dist/portfolio/server.d.ts +157 -7
- package/dist/portfolio/server.js +3 -142
- package/dist/portfolio/server.js.map +1 -1
- package/dist/preview.cjs +56 -0
- package/dist/preview.cjs.map +1 -0
- package/dist/preview.d.cts +31 -0
- package/dist/preview.d.ts +31 -0
- package/dist/preview.js +54 -0
- package/dist/preview.js.map +1 -0
- package/dist/{types-DL4t_Cfa.d.ts → types-0tVPy4pU.d.cts} +7 -1
- package/dist/{types-DL4t_Cfa.d.cts → types-0tVPy4pU.d.ts} +7 -1
- package/dist/types-D0nb6KAx.d.cts +299 -0
- package/dist/types-D0nb6KAx.d.ts +299 -0
- package/package.json +38 -14
- package/templates/api-portfolio-preview.ts +6 -0
- package/templates/api-revalidate.ts +5 -0
- package/templates/work-category-page.tsx +40 -0
- package/templates/work-error.tsx +3 -0
- package/templates/work-loading.tsx +1 -0
- package/templates/work-page.tsx +37 -0
- package/templates/work-slug-loading.tsx +1 -0
- package/templates/work-slug-page.tsx +41 -0
- package/dist/BeforeAfterSection-6BHFLY4Y.js.map +0 -1
- package/dist/BeforeAfterSection-JTORBR3A.cjs +0 -181
- package/dist/BeforeAfterSection-JTORBR3A.cjs.map +0 -1
- package/dist/CTASection-4JKLXEUF.cjs +0 -111
- package/dist/CTASection-4JKLXEUF.cjs.map +0 -1
- package/dist/CTASection-BJA72XIL.js +0 -106
- package/dist/CTASection-BJA72XIL.js.map +0 -1
- package/dist/ChallengesSection-GEQGVSJN.js.map +0 -1
- package/dist/ChallengesSection-IZ3DHECS.cjs.map +0 -1
- package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs +0 -209
- package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs.map +0 -1
- package/dist/ConversionFunnelSection-D3GE4NKE.js.map +0 -1
- package/dist/DesignSystemSection-2R5BRBGO.js.map +0 -1
- package/dist/DesignSystemSection-KXIQXITF.cjs.map +0 -1
- package/dist/DetailsSection-A6PZQUQL.js.map +0 -1
- package/dist/DetailsSection-TTUZAPZZ.cjs.map +0 -1
- package/dist/FeatureSpotlightSection-B7P3JGNL.js.map +0 -1
- package/dist/FeatureSpotlightSection-WRHXS7TU.cjs +0 -210
- package/dist/FeatureSpotlightSection-WRHXS7TU.cjs.map +0 -1
- package/dist/GallerySection-VMKORC47.js.map +0 -1
- package/dist/GallerySection-WJ4PQDBI.cjs +0 -219
- package/dist/GallerySection-WJ4PQDBI.cjs.map +0 -1
- package/dist/MetricsTimelineSection-4L6DUHJ5.cjs.map +0 -1
- package/dist/MetricsTimelineSection-6BT5GNFV.js.map +0 -1
- package/dist/PerformanceSection-24TVVFZA.cjs +0 -356
- package/dist/PerformanceSection-24TVVFZA.cjs.map +0 -1
- package/dist/PerformanceSection-MGCEIXDX.js.map +0 -1
- package/dist/ResultsSection-DFUJ5U6M.js.map +0 -1
- package/dist/ResultsSection-XLGMMQKY.cjs.map +0 -1
- package/dist/ServicesSection-D5V3Q4GR.js +0 -118
- package/dist/ServicesSection-D5V3Q4GR.js.map +0 -1
- package/dist/ServicesSection-WJMGK2MF.cjs +0 -120
- package/dist/ServicesSection-WJMGK2MF.cjs.map +0 -1
- package/dist/SiteArchitectureSection-J7BPBERH.cjs.map +0 -1
- package/dist/SiteArchitectureSection-TE22OAWV.js.map +0 -1
- package/dist/SpeedComparisonSection-EZKFQVGW.cjs.map +0 -1
- package/dist/SpeedComparisonSection-Y3K7OFZQ.js.map +0 -1
- package/dist/StrategySection-CJ7Y6OFQ.cjs +0 -174
- package/dist/StrategySection-CJ7Y6OFQ.cjs.map +0 -1
- package/dist/StrategySection-DI5RSCJU.js.map +0 -1
- package/dist/TeamSection-DZVSNZE6.cjs +0 -112
- package/dist/TeamSection-DZVSNZE6.cjs.map +0 -1
- package/dist/TeamSection-HGKFW6PQ.js +0 -107
- package/dist/TeamSection-HGKFW6PQ.js.map +0 -1
- package/dist/TechStackSection-2AQ7RGY3.js +0 -93
- package/dist/TechStackSection-2AQ7RGY3.js.map +0 -1
- package/dist/TechStackSection-VTNNZR5V.cjs +0 -95
- package/dist/TechStackSection-VTNNZR5V.cjs.map +0 -1
- package/dist/TestimonialSection-6RGSMXQB.js.map +0 -1
- package/dist/TestimonialSection-XPTFUQIN.cjs.map +0 -1
- package/dist/VideoSection-4A2HC6K6.js.map +0 -1
- package/dist/VideoSection-G3DFS7UH.cjs +0 -118
- package/dist/VideoSection-G3DFS7UH.cjs.map +0 -1
- package/dist/chunk-2Y4O3LWM.js +0 -53
- package/dist/chunk-2Y4O3LWM.js.map +0 -1
- package/dist/chunk-633UMQQH.cjs +0 -31
- package/dist/chunk-633UMQQH.cjs.map +0 -1
- package/dist/chunk-7CFFAKDM.js +0 -74
- package/dist/chunk-7CFFAKDM.js.map +0 -1
- package/dist/chunk-APG2QSMB.js +0 -131
- package/dist/chunk-APG2QSMB.js.map +0 -1
- package/dist/chunk-AVCH4LMG.cjs +0 -620
- package/dist/chunk-AVCH4LMG.cjs.map +0 -1
- package/dist/chunk-AYBUHRFS.js +0 -613
- package/dist/chunk-AYBUHRFS.js.map +0 -1
- package/dist/chunk-EE75WRCM.cjs.map +0 -1
- package/dist/chunk-IKBK7HYX.cjs +0 -79
- package/dist/chunk-IKBK7HYX.cjs.map +0 -1
- package/dist/chunk-KEOHORIH.cjs +0 -79
- package/dist/chunk-KEOHORIH.cjs.map +0 -1
- package/dist/chunk-OA5ZM4OA.cjs +0 -139
- package/dist/chunk-OA5ZM4OA.cjs.map +0 -1
- package/dist/chunk-TVFXN6W6.js.map +0 -1
- package/dist/chunk-VVTK4OL6.js +0 -28
- package/dist/chunk-VVTK4OL6.js.map +0 -1
- package/dist/chunk-XCKXHK44.js +0 -15
- package/dist/chunk-XCKXHK44.js.map +0 -1
- package/dist/chunk-XONXEFJY.cjs +0 -58
- package/dist/chunk-XONXEFJY.cjs.map +0 -1
- package/dist/chunk-XQNJED46.cjs +0 -19
- package/dist/chunk-XQNJED46.cjs.map +0 -1
- package/dist/chunk-YB4B3OMC.js +0 -74
- package/dist/chunk-YB4B3OMC.js.map +0 -1
- package/dist/portfolio/sections.cjs +0 -20
- package/dist/portfolio/sections.cjs.map +0 -1
- package/dist/portfolio/sections.d.cts +0 -42
- package/dist/portfolio/sections.d.ts +0 -42
- package/dist/portfolio/sections.js +0 -4
- package/dist/portfolio/sections.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/PerformanceSection.tsx"],"sourcesContent":["'use client';\n\nimport React, { useRef, useEffect, useState } from 'react';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\n\ninterface LighthouseScores {\n performance?: number;\n seo?: number;\n accessibility?: number;\n bestPractices?: number;\n}\n\ninterface PerformanceSectionProps {\n data: {\n before?: LighthouseScores;\n after?: LighthouseScores;\n cwv?: {\n lcp?: number;\n cls?: number;\n inp?: number;\n };\n };\n}\n\nconst CATEGORIES = [\n { key: 'performance', label: 'Performance', color: '#10b981' },\n { key: 'seo', label: 'SEO', color: '#6366f1' },\n { key: 'accessibility', label: 'Accessibility', color: '#f59e0b' },\n { key: 'bestPractices', label: 'Best Practices', color: '#3b82f6' },\n] as const;\n\nfunction getScoreColor(score: number): string {\n if (score >= 90) return '#10b981'; // green\n if (score >= 50) return '#f59e0b'; // amber\n return '#ef4444'; // red\n}\n\nconst EASE = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'; // ≈ power2.out\nconst RADIUS = 44;\nconst CIRCUMFERENCE = 2 * Math.PI * RADIUS;\n\nfunction ScoreGauge({\n score,\n label,\n previousScore,\n delay = 0,\n}: {\n score: number;\n label: string;\n previousScore?: number;\n delay?: number;\n}) {\n const circleRef = useRef<SVGCircleElement>(null);\n // SSR renders the real final score + arc (crawlers and no-JS users see the\n // true number); the count-up only runs for gauges below the viewport.\n const [displayScore, setDisplayScore] = useState(score);\n\n useEffect(() => {\n const circle = circleRef.current;\n if (!circle) return;\n\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {\n setDisplayScore(score);\n return;\n }\n\n // Never re-hide a gauge already in the viewport at hydration.\n const rect = circle.getBoundingClientRect();\n if (rect.top < window.innerHeight && rect.bottom > 0) {\n setDisplayScore(score);\n return;\n }\n\n // Hidden state: arc fully retracted, score zeroed.\n const finalOffset = CIRCUMFERENCE - (score / 100) * CIRCUMFERENCE;\n circle.style.strokeDashoffset = String(CIRCUMFERENCE);\n setDisplayScore(0);\n\n let raf = 0;\n const easeOut = (t: number) => 1 - Math.pow(1 - t, 2); // ≈ power2.out\n\n const io = new IntersectionObserver(\n ([entry]) => {\n if (!entry.isIntersecting) return;\n io.disconnect();\n // Draw the arc in, and count the score up in sync with the draw.\n circle.style.transition = `stroke-dashoffset 1.5s ${EASE} ${delay}s`;\n circle.style.strokeDashoffset = String(finalOffset);\n const start = performance.now();\n const tick = (now: number) => {\n const p = Math.min(1, Math.max(0, (now - start - delay * 1000) / 1500));\n setDisplayScore(Math.round(easeOut(p) * score));\n if (p < 1) raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n },\n { rootMargin: '0px 0px -15% 0px' }, // ≈ the old 'top 85%' trigger\n );\n io.observe(circle);\n\n return () => {\n io.disconnect();\n cancelAnimationFrame(raf);\n circle.style.transition = '';\n circle.style.strokeDashoffset = '';\n };\n }, [score, delay]);\n\n const color = getScoreColor(score);\n const improvement = previousScore ? score - previousScore : undefined;\n\n return (\n <div className=\"flex flex-col items-center gap-3\">\n <div className=\"relative w-28 h-28\">\n <svg className=\"w-full h-full -rotate-90\" viewBox=\"0 0 100 100\">\n {/* Background circle */}\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"44\"\n fill=\"none\"\n stroke=\"var(--sk-surface, rgba(255,255,255,0.05))\"\n strokeWidth=\"6\"\n />\n {/* Score arc — rendered at its final sweep; the effect retracts and\n redraws it only when the gauge scrolls in */}\n <circle\n ref={circleRef}\n cx=\"50\"\n cy=\"50\"\n r={RADIUS}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"6\"\n strokeLinecap=\"round\"\n strokeDasharray={CIRCUMFERENCE}\n strokeDashoffset={CIRCUMFERENCE - (score / 100) * CIRCUMFERENCE}\n />\n </svg>\n {/* Score text */}\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <span\n className=\"text-2xl font-bold\"\n style={{ color }}\n >\n {displayScore}\n </span>\n </div>\n </div>\n <span\n className=\"text-sm font-medium text-center\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {label}\n </span>\n {improvement !== undefined && improvement > 0 && (\n <span\n className=\"text-xs font-semibold px-2 py-0.5 rounded-full\"\n style={{\n background: 'color-mix(in srgb, #10b981 15%, transparent)',\n color: '#10b981',\n }}\n >\n +{improvement} pts\n </span>\n )}\n </div>\n );\n}\n\nexport default function PerformanceSection({ data }: PerformanceSectionProps) {\n const hasBeforeAfter = data.before && data.after;\n const scores = data.after || data.before;\n if (!scores && !data.cwv) return null;\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 Performance\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {hasBeforeAfter\n ? 'Real Lighthouse scores, before and after our rebuild.'\n : 'Real performance metrics measured by Google Lighthouse.'}\n </p>\n </ScrollReveal>\n\n {/* Score gauges */}\n {scores && (\n <ScrollReveal y={30}>\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-8 mb-8\">\n {CATEGORIES.map((cat, i) => {\n const currentScore = (scores as any)[cat.key];\n const previousScore = hasBeforeAfter ? (data.before as any)?.[cat.key] : undefined;\n if (currentScore === undefined) return null;\n return (\n <ScoreGauge\n key={cat.key}\n score={currentScore}\n label={cat.label}\n previousScore={previousScore}\n delay={i * 0.15}\n />\n );\n })}\n </div>\n </ScrollReveal>\n )}\n\n {/* Before/After comparison cards */}\n {hasBeforeAfter && (\n <ScrollReveal y={30} delay={0.3}>\n <div className=\"grid md:grid-cols-2 gap-4\">\n <GlassCard padding=\"lg\" hover={false}>\n <h3\n className=\"text-sm font-semibold uppercase tracking-wider mb-4\"\n style={{ color: '#ef4444' }}\n >\n Before (Original Site)\n </h3>\n <div className=\"grid grid-cols-2 gap-3\">\n {CATEGORIES.map((cat) => {\n const val = (data.before as any)?.[cat.key];\n if (val === undefined) return null;\n return (\n <div key={cat.key} className=\"text-center\">\n <span className=\"text-2xl font-bold\" style={{ color: getScoreColor(val) }}>\n {val}\n </span>\n <span\n className=\"block text-[11px] mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {cat.label}\n </span>\n </div>\n );\n })}\n </div>\n </GlassCard>\n <GlassCard padding=\"lg\" hover={false}>\n <h3\n className=\"text-sm font-semibold uppercase tracking-wider mb-4\"\n style={{ color: '#10b981' }}\n >\n After (Next.js Rebuild)\n </h3>\n <div className=\"grid grid-cols-2 gap-3\">\n {CATEGORIES.map((cat) => {\n const val = (data.after as any)?.[cat.key];\n if (val === undefined) return null;\n return (\n <div key={cat.key} className=\"text-center\">\n <span className=\"text-2xl font-bold\" style={{ color: getScoreColor(val) }}>\n {val}\n </span>\n <span\n className=\"block text-[11px] mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {cat.label}\n </span>\n </div>\n );\n })}\n </div>\n </GlassCard>\n </div>\n </ScrollReveal>\n )}\n\n {/* Core Web Vitals */}\n {data.cwv && (data.cwv.lcp != null || data.cwv.cls != null || data.cwv.inp != null) && (\n <ScrollReveal y={30} delay={0.4}>\n <div className=\"grid grid-cols-3 gap-4 mt-8\">\n {data.cwv.lcp != null && (\n <GlassCard padding=\"md\" hover={false} className=\"text-center\">\n <span\n className=\"text-2xl font-bold\"\n style={{ color: data.cwv.lcp < 2500 ? '#10b981' : data.cwv.lcp < 4000 ? '#f59e0b' : '#ef4444' }}\n >\n {(data.cwv.lcp / 1000).toFixed(1)}s\n </span>\n <span\n className=\"block text-xs mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n LCP\n </span>\n </GlassCard>\n )}\n {data.cwv.cls != null && (\n <GlassCard padding=\"md\" hover={false} className=\"text-center\">\n <span\n className=\"text-2xl font-bold\"\n style={{ color: data.cwv.cls < 0.1 ? '#10b981' : data.cwv.cls < 0.25 ? '#f59e0b' : '#ef4444' }}\n >\n {data.cwv.cls.toFixed(3)}\n </span>\n <span\n className=\"block text-xs mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n CLS\n </span>\n </GlassCard>\n )}\n {data.cwv.inp != null && (\n <GlassCard padding=\"md\" hover={false} className=\"text-center\">\n <span\n className=\"text-2xl font-bold\"\n style={{ color: data.cwv.inp < 200 ? '#10b981' : data.cwv.inp < 500 ? '#f59e0b' : '#ef4444' }}\n >\n {data.cwv.inp}ms\n </span>\n <span\n className=\"block text-xs mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n INP\n </span>\n </GlassCard>\n )}\n </div>\n </ScrollReveal>\n )}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkUXUU7FVT_cjs = require('../../chunk-UXUU7FVT.cjs');
|
|
4
|
+
var ScrollReveal = require('@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal');
|
|
5
|
+
var AnimatedCounter = require('@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter');
|
|
6
|
+
var GlassCard = require('@sonordev/agency-site-kit/portfolio/primitives/GlassCard');
|
|
6
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
|
|
8
|
-
function
|
|
9
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var ScrollReveal__default = /*#__PURE__*/_interopDefault(ScrollReveal);
|
|
12
|
+
var AnimatedCounter__default = /*#__PURE__*/_interopDefault(AnimatedCounter);
|
|
13
|
+
var GlassCard__default = /*#__PURE__*/_interopDefault(GlassCard);
|
|
14
|
+
|
|
15
|
+
function ResultsSection({
|
|
16
|
+
data,
|
|
17
|
+
metricsDelta,
|
|
18
|
+
metricsRefreshedAt
|
|
19
|
+
}) {
|
|
20
|
+
if (!data.items.length && !chunkUXUU7FVT_cjs.gateMetricsDeltas(metricsDelta).length) return null;
|
|
9
21
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10
22
|
"section",
|
|
11
23
|
{
|
|
12
24
|
className: "w-full py-20 md:py-28",
|
|
13
25
|
style: { background: "var(--sk-bg, #0a0a0a)" },
|
|
14
26
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-6", children: [
|
|
15
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
27
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ScrollReveal__default.default, { y: 30, children: [
|
|
16
28
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17
29
|
"h2",
|
|
18
30
|
{
|
|
@@ -33,14 +45,14 @@ function ResultsSection({ data }) {
|
|
|
33
45
|
}
|
|
34
46
|
)
|
|
35
47
|
] }),
|
|
36
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollReveal__default.default, { stagger: 0.1, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: data.items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(GlassCard__default.default, { padding: "lg", hover: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
37
49
|
item.metric && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38
50
|
"div",
|
|
39
51
|
{
|
|
40
52
|
className: "text-3xl md:text-4xl font-bold",
|
|
41
53
|
style: { color: "var(--sk-primary, #6366f1)" },
|
|
42
54
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
43
|
-
|
|
55
|
+
AnimatedCounter__default.default,
|
|
44
56
|
{
|
|
45
57
|
value: item.metric.value,
|
|
46
58
|
suffix: item.metric.suffix,
|
|
@@ -84,12 +96,13 @@ function ResultsSection({ data }) {
|
|
|
84
96
|
]
|
|
85
97
|
}
|
|
86
98
|
)
|
|
87
|
-
] }) }, index)) }) })
|
|
99
|
+
] }) }, index)) }) }),
|
|
100
|
+
metricsDelta && metricsDelta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ScrollReveal__default.default, { y: 30, delay: 0.1, children: /* @__PURE__ */ jsxRuntime.jsx(chunkUXUU7FVT_cjs.MetricsProvenance, { deltas: metricsDelta, refreshedAt: metricsRefreshedAt }) })
|
|
88
101
|
] })
|
|
89
102
|
}
|
|
90
103
|
);
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
module.exports = ResultsSection;
|
|
94
|
-
//# sourceMappingURL=ResultsSection
|
|
95
|
-
//# sourceMappingURL=ResultsSection
|
|
107
|
+
//# sourceMappingURL=ResultsSection.cjs.map
|
|
108
|
+
//# sourceMappingURL=ResultsSection.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/ResultsSection.tsx"],"names":["gateMetricsDeltas","jsx","jsxs","ScrollReveal","GlassCard","AnimatedCounter","MetricsProvenance"],"mappings":";;;;;;;;;;;;;;AAkBe,SAAR,cAAA,CAAgC;AAAA,EACrC,IAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA,EAAwB;AAEtB,EAAA,IAAI,CAAC,KAAK,KAAA,CAAM,MAAA,IAAU,CAACA,mCAAA,CAAkB,YAAY,CAAA,CAAE,MAAA,EAAQ,OAAO,IAAA;AAE1E,EAAA,uBACEC,cAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,uBAAA;AAAA,MACV,KAAA,EAAO,EAAE,UAAA,EAAY,uBAAA,EAAwB;AAAA,MAE7C,QAAA,kBAAAC,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,eAAA,CAACC,6BAAA,EAAA,EAAa,GAAG,EAAA,EACf,QAAA,EAAA;AAAA,0BAAAF,cAAA;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,0BACAA,cAAA;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,wBAEAA,cAAA,CAACE,iCAAa,OAAA,EAAS,GAAA,EACrB,yCAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sDAAA,EACZ,QAAA,EAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,qBACrBF,cAAA,CAACG,0BAAA,EAAA,EAAsB,OAAA,EAAQ,IAAA,EAAK,OAAK,IAAA,EACvC,QAAA,kBAAAF,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAEZ,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,MAAA,oBACJD,cAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,gCAAA;AAAA,cACV,KAAA,EAAO,EAAE,KAAA,EAAO,4BAAA,EAA6B;AAAA,cAE7C,QAAA,kBAAAA,cAAA;AAAA,gBAACI,gCAAA;AAAA,gBAAA;AAAA,kBACC,KAAA,EAAO,KAAK,MAAA,CAAO,KAAA;AAAA,kBACnB,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA;AAAA,kBACpB,MAAA,EAAQ,KAAK,MAAA,CAAO,MAAA;AAAA,kBACpB,QAAA,EAAU;AAAA;AAAA;AACZ;AAAA,WACF;AAAA,0BAGFJ,cAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,uBAAA;AAAA,cACV,KAAA,EAAO,EAAE,KAAA,EAAO,iCAAA,EAAkC;AAAA,cAEjD,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,WACR;AAAA,0BAEAA,cAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,yBAAA;AAAA,cACV,KAAA,EAAO,EAAE,KAAA,EAAO,kCAAA,EAAmC;AAAA,cAElD,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,WACR;AAAA,0BAGAC,eAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,0HAAA;AAAA,cACV,KAAA,EAAO;AAAA,gBACL,UAAA,EACE,IAAA,CAAK,MAAA,KAAW,UAAA,GACZ,8CAAA,GACA,8CAAA;AAAA,gBACN,KAAA,EAAO,IAAA,CAAK,MAAA,KAAW,UAAA,GAAa,SAAA,GAAY,SAAA;AAAA,gBAChD,QAAQ,CAAA,UAAA,EACN,IAAA,CAAK,MAAA,KAAW,UAAA,GACZ,iDACA,8CACN,CAAA;AAAA,eACF;AAAA,cAEC,QAAA,EAAA;AAAA,gBAAA,IAAA,CAAK,MAAA,KAAW,UAAA,mBACfD,cAAA,CAAC,KAAA,EAAA,EAAI,OAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EACnD,QAAA,kBAAAA,cAAA,CAAC,MAAA,EAAA,EAAK,GAAE,mBAAA,EAAoB,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,OAAM,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,GACnH,CAAA,mBAEAC,eAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,MAAK,MAAA,EAAO,IAAA,EAAK,OAAA,EAAQ,WAAA,EAAY,MAAK,MAAA,EACnD,QAAA,EAAA;AAAA,kCAAAD,cAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,GAAE,GAAA,EAAI,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,KAAA,EAAM,CAAA;AAAA,kCACpEA,cAAA,CAAC,UAAK,CAAA,EAAE,gBAAA,EAAiB,QAAO,cAAA,EAAe,WAAA,EAAY,KAAA,EAAM,aAAA,EAAc,OAAA,EAAQ;AAAA,iBAAA,EACzF,CAAA;AAAA,gBAED,IAAA,CAAK;AAAA;AAAA;AAAA;AACR,SAAA,EACF,CAAA,EAAA,EA3Dc,KA4DhB,CACD,CAAA,EACH,CAAA,EACF,CAAA;AAAA,QAGC,gBAAgB,YAAA,CAAa,MAAA,GAAS,CAAA,oBACrCA,cAAA,CAACE,iCAAa,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,GAAA,EAC1B,yCAACG,mCAAA,EAAA,EAAkB,MAAA,EAAQ,YAAA,EAAc,WAAA,EAAa,oBAAoB,CAAA,EAC5E;AAAA,OAAA,EAEJ;AAAA;AAAA,GACF;AAEJ","file":"ResultsSection.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 { MetricsDelta, PortfolioResultsData } from '../../../types';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\nimport MetricsProvenance from '../MetricsProvenance';\nimport { gateMetricsDeltas } from '../../curate-proof';\n\ninterface ResultsSectionProps {\n data: PortfolioResultsData;\n /** Live metric deltas computed by the platform (item.metricsDelta). */\n metricsDelta?: MetricsDelta[];\n /** ISO timestamp of the last live-metrics refresh. */\n metricsRefreshedAt?: string | null;\n}\n\nexport default function ResultsSection({\n data,\n metricsDelta,\n metricsRefreshedAt,\n}: ResultsSectionProps) {\n // Nothing survives display curation → no section, not an empty header.\n if (!data.items.length && !gateMetricsDeltas(metricsDelta).length) return null;\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-7xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Results\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n Measurable outcomes that speak for themselves.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {data.items.map((item, index) => (\n <GlassCard key={index} padding=\"lg\" hover>\n <div className=\"flex flex-col gap-3\">\n {/* Metric counter */}\n {item.metric && (\n <div\n className=\"text-3xl md:text-4xl font-bold\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <AnimatedCounter\n value={item.metric.value}\n suffix={item.metric.suffix}\n prefix={item.metric.prefix}\n duration={2.5}\n />\n </div>\n )}\n\n <h3\n className=\"text-lg font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {item.title}\n </h3>\n\n <p\n className=\"text-sm leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {item.description}\n </p>\n\n {/* Source badge */}\n <span\n className=\"inline-flex self-start items-center gap-1 px-2.5 py-1 rounded-full text-[11px] uppercase tracking-wider font-medium mt-1\"\n style={{\n background:\n item.source === 'measured'\n ? 'color-mix(in srgb, #10b981 12%, transparent)'\n : 'color-mix(in srgb, #f59e0b 12%, transparent)',\n color: item.source === 'measured' ? '#10b981' : '#f59e0b',\n border: `1px solid ${\n item.source === 'measured'\n ? 'color-mix(in srgb, #10b981 20%, transparent)'\n : 'color-mix(in srgb, #f59e0b 20%, transparent)'\n }`,\n }}\n >\n {item.source === 'measured' ? (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M10 3L4.5 8.5 2 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ) : (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <circle cx=\"6\" cy=\"6\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6 4v2.5l1.5 1\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )}\n {item.source}\n </span>\n </div>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n\n {/* Live verified metrics — the numbers a static portfolio can't fake */}\n {metricsDelta && metricsDelta.length > 0 && (\n <ScrollReveal y={30} delay={0.1}>\n <MetricsProvenance deltas={metricsDelta} refreshedAt={metricsRefreshedAt} />\n </ScrollReveal>\n )}\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { f as PortfolioResultsData, M as MetricsDelta } from '../../types-0tVPy4pU.cjs';
|
|
3
|
+
|
|
4
|
+
interface ResultsSectionProps {
|
|
5
|
+
data: PortfolioResultsData;
|
|
6
|
+
/** Live metric deltas computed by the platform (item.metricsDelta). */
|
|
7
|
+
metricsDelta?: MetricsDelta[];
|
|
8
|
+
/** ISO timestamp of the last live-metrics refresh. */
|
|
9
|
+
metricsRefreshedAt?: string | null;
|
|
10
|
+
}
|
|
11
|
+
declare function ResultsSection({ data, metricsDelta, metricsRefreshedAt, }: ResultsSectionProps): React.JSX.Element | null;
|
|
12
|
+
|
|
13
|
+
export { ResultsSection as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { f as PortfolioResultsData, M as MetricsDelta } from '../../types-0tVPy4pU.js';
|
|
3
|
+
|
|
4
|
+
interface ResultsSectionProps {
|
|
5
|
+
data: PortfolioResultsData;
|
|
6
|
+
/** Live metric deltas computed by the platform (item.metricsDelta). */
|
|
7
|
+
metricsDelta?: MetricsDelta[];
|
|
8
|
+
/** ISO timestamp of the last live-metrics refresh. */
|
|
9
|
+
metricsRefreshedAt?: string | null;
|
|
10
|
+
}
|
|
11
|
+
declare function ResultsSection({ data, metricsDelta, metricsRefreshedAt, }: ResultsSectionProps): React.JSX.Element | null;
|
|
12
|
+
|
|
13
|
+
export { ResultsSection as default };
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { gateMetricsDeltas, MetricsProvenance } from '../../chunk-RWQ675N6.js';
|
|
2
|
+
import ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';
|
|
3
|
+
import AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';
|
|
4
|
+
import GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';
|
|
4
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
|
-
function ResultsSection({
|
|
7
|
+
function ResultsSection({
|
|
8
|
+
data,
|
|
9
|
+
metricsDelta,
|
|
10
|
+
metricsRefreshedAt
|
|
11
|
+
}) {
|
|
12
|
+
if (!data.items.length && !gateMetricsDeltas(metricsDelta).length) return null;
|
|
7
13
|
return /* @__PURE__ */ jsx(
|
|
8
14
|
"section",
|
|
9
15
|
{
|
|
@@ -82,12 +88,13 @@ function ResultsSection({ data }) {
|
|
|
82
88
|
]
|
|
83
89
|
}
|
|
84
90
|
)
|
|
85
|
-
] }) }, index)) }) })
|
|
91
|
+
] }) }, index)) }) }),
|
|
92
|
+
metricsDelta && metricsDelta.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 30, delay: 0.1, children: /* @__PURE__ */ jsx(MetricsProvenance, { deltas: metricsDelta, refreshedAt: metricsRefreshedAt }) })
|
|
86
93
|
] })
|
|
87
94
|
}
|
|
88
95
|
);
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
export { ResultsSection as default };
|
|
92
|
-
//# sourceMappingURL=ResultsSection
|
|
93
|
-
//# sourceMappingURL=ResultsSection
|
|
99
|
+
//# sourceMappingURL=ResultsSection.js.map
|
|
100
|
+
//# sourceMappingURL=ResultsSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/ResultsSection.tsx"],"names":[],"mappings":"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","file":"ResultsSection.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 { MetricsDelta, PortfolioResultsData } from '../../../types';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\nimport MetricsProvenance from '../MetricsProvenance';\nimport { gateMetricsDeltas } from '../../curate-proof';\n\ninterface ResultsSectionProps {\n data: PortfolioResultsData;\n /** Live metric deltas computed by the platform (item.metricsDelta). */\n metricsDelta?: MetricsDelta[];\n /** ISO timestamp of the last live-metrics refresh. */\n metricsRefreshedAt?: string | null;\n}\n\nexport default function ResultsSection({\n data,\n metricsDelta,\n metricsRefreshedAt,\n}: ResultsSectionProps) {\n // Nothing survives display curation → no section, not an empty header.\n if (!data.items.length && !gateMetricsDeltas(metricsDelta).length) return null;\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-7xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Results\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n Measurable outcomes that speak for themselves.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {data.items.map((item, index) => (\n <GlassCard key={index} padding=\"lg\" hover>\n <div className=\"flex flex-col gap-3\">\n {/* Metric counter */}\n {item.metric && (\n <div\n className=\"text-3xl md:text-4xl font-bold\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <AnimatedCounter\n value={item.metric.value}\n suffix={item.metric.suffix}\n prefix={item.metric.prefix}\n duration={2.5}\n />\n </div>\n )}\n\n <h3\n className=\"text-lg font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {item.title}\n </h3>\n\n <p\n className=\"text-sm leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {item.description}\n </p>\n\n {/* Source badge */}\n <span\n className=\"inline-flex self-start items-center gap-1 px-2.5 py-1 rounded-full text-[11px] uppercase tracking-wider font-medium mt-1\"\n style={{\n background:\n item.source === 'measured'\n ? 'color-mix(in srgb, #10b981 12%, transparent)'\n : 'color-mix(in srgb, #f59e0b 12%, transparent)',\n color: item.source === 'measured' ? '#10b981' : '#f59e0b',\n border: `1px solid ${\n item.source === 'measured'\n ? 'color-mix(in srgb, #10b981 20%, transparent)'\n : 'color-mix(in srgb, #f59e0b 20%, transparent)'\n }`,\n }}\n >\n {item.source === 'measured' ? (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M10 3L4.5 8.5 2 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ) : (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <circle cx=\"6\" cy=\"6\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M6 4v2.5l1.5 1\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )}\n {item.source}\n </span>\n </div>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n\n {/* Live verified metrics — the numbers a static portfolio can't fake */}\n {metricsDelta && metricsDelta.length > 0 && (\n <ScrollReveal y={30} delay={0.1}>\n <MetricsProvenance deltas={metricsDelta} refreshedAt={metricsRefreshedAt} />\n </ScrollReveal>\n )}\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,129 @@
|
|
|
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 ServicesSection({ 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-7xl 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: "Services Provided"
|
|
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: "A breakdown of the services delivered for this project."
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
] }),
|
|
41
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollReveal__default.default, { stagger: 0.1, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: data.items.map((service, index) => {
|
|
42
|
+
const icon = chunkNI4FVCLS_cjs.resolvePortfolioImage(service.icon);
|
|
43
|
+
return /* @__PURE__ */ jsxRuntime.jsx(GlassCard__default.default, { padding: "lg", hover: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
44
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
className: "flex items-center justify-center w-12 h-12 rounded-xl",
|
|
48
|
+
style: {
|
|
49
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)"
|
|
50
|
+
},
|
|
51
|
+
children: icon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: icon.url, alt: "", width: 24, height: 24, loading: "lazy", decoding: "async", className: "w-6 h-6 object-contain" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
52
|
+
"svg",
|
|
53
|
+
{
|
|
54
|
+
width: "24",
|
|
55
|
+
height: "24",
|
|
56
|
+
viewBox: "0 0 24 24",
|
|
57
|
+
fill: "none",
|
|
58
|
+
style: { color: "var(--sk-primary, #6366f1)" },
|
|
59
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
60
|
+
"path",
|
|
61
|
+
{
|
|
62
|
+
d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5",
|
|
63
|
+
stroke: "currentColor",
|
|
64
|
+
strokeWidth: "2",
|
|
65
|
+
strokeLinecap: "round",
|
|
66
|
+
strokeLinejoin: "round"
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74
|
+
"h3",
|
|
75
|
+
{
|
|
76
|
+
className: "text-lg font-semibold",
|
|
77
|
+
style: { color: "var(--sk-text-primary, #ffffff)" },
|
|
78
|
+
children: service.title
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
82
|
+
"p",
|
|
83
|
+
{
|
|
84
|
+
className: "text-sm leading-relaxed",
|
|
85
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
86
|
+
children: service.description
|
|
87
|
+
}
|
|
88
|
+
),
|
|
89
|
+
service.features.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-2 mt-1", children: service.features.map((feature, fi) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-2", children: [
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91
|
+
"svg",
|
|
92
|
+
{
|
|
93
|
+
width: "16",
|
|
94
|
+
height: "16",
|
|
95
|
+
viewBox: "0 0 16 16",
|
|
96
|
+
fill: "none",
|
|
97
|
+
className: "shrink-0 mt-0.5",
|
|
98
|
+
style: { color: "#10b981" },
|
|
99
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
100
|
+
"path",
|
|
101
|
+
{
|
|
102
|
+
d: "M13.333 4L6 11.333 2.667 8",
|
|
103
|
+
stroke: "currentColor",
|
|
104
|
+
strokeWidth: "1.5",
|
|
105
|
+
strokeLinecap: "round",
|
|
106
|
+
strokeLinejoin: "round"
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112
|
+
"span",
|
|
113
|
+
{
|
|
114
|
+
className: "text-sm",
|
|
115
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
116
|
+
children: feature
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
] }, fi)) })
|
|
120
|
+
] }) }, index);
|
|
121
|
+
}) }) })
|
|
122
|
+
] })
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = ServicesSection;
|
|
128
|
+
//# sourceMappingURL=ServicesSection.cjs.map
|
|
129
|
+
//# sourceMappingURL=ServicesSection.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/ServicesSection.tsx"],"names":["jsx","jsxs","ScrollReveal","resolvePortfolioImage","GlassCard"],"mappings":"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","file":"ServicesSection.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 { PortfolioServicesData } 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 ServicesSectionProps {\n data: PortfolioServicesData;\n}\n\nexport default function ServicesSection({ data }: ServicesSectionProps) {\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-7xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Services Provided\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n A breakdown of the services delivered for this project.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {data.items.map((service, index) => {\n const icon = resolvePortfolioImage(service.icon);\n return (\n <GlassCard key={index} padding=\"lg\" hover>\n <div className=\"flex flex-col gap-4\">\n {/* Icon */}\n <div\n className=\"flex items-center justify-center w-12 h-12 rounded-xl\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n }}\n >\n {icon ? (\n <img src={icon.url} alt=\"\" width={24} height={24} loading=\"lazy\" decoding=\"async\" className=\"w-6 h-6 object-contain\" />\n ) : (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <path\n d=\"M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </div>\n\n <h3\n className=\"text-lg font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {service.title}\n </h3>\n\n <p\n className=\"text-sm leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {service.description}\n </p>\n\n {/* Feature list */}\n {service.features.length > 0 && (\n <ul className=\"flex flex-col gap-2 mt-1\">\n {service.features.map((feature, fi) => (\n <li key={fi} className=\"flex items-start gap-2\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n className=\"shrink-0 mt-0.5\"\n style={{ color: '#10b981' }}\n >\n <path\n d=\"M13.333 4L6 11.333 2.667 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\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 {feature}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </GlassCard>\n );\n })}\n </div>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { g as PortfolioServicesData } from '../../types-0tVPy4pU.cjs';
|
|
3
|
+
|
|
4
|
+
interface ServicesSectionProps {
|
|
5
|
+
data: PortfolioServicesData;
|
|
6
|
+
}
|
|
7
|
+
declare function ServicesSection({ data }: ServicesSectionProps): React.JSX.Element;
|
|
8
|
+
|
|
9
|
+
export { ServicesSection as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { g as PortfolioServicesData } from '../../types-0tVPy4pU.js';
|
|
3
|
+
|
|
4
|
+
interface ServicesSectionProps {
|
|
5
|
+
data: PortfolioServicesData;
|
|
6
|
+
}
|
|
7
|
+
declare function ServicesSection({ data }: ServicesSectionProps): React.JSX.Element;
|
|
8
|
+
|
|
9
|
+
export { ServicesSection as default };
|
|
@@ -0,0 +1,122 @@
|
|
|
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 ServicesSection({ 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-7xl 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: "Services Provided"
|
|
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: "A breakdown of the services delivered for this project."
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] }),
|
|
34
|
+
/* @__PURE__ */ jsx(ScrollReveal, { stagger: 0.1, children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: data.items.map((service, index) => {
|
|
35
|
+
const icon = resolvePortfolioImage(service.icon);
|
|
36
|
+
return /* @__PURE__ */ jsx(GlassCard, { padding: "lg", hover: true, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
className: "flex items-center justify-center w-12 h-12 rounded-xl",
|
|
41
|
+
style: {
|
|
42
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)"
|
|
43
|
+
},
|
|
44
|
+
children: icon ? /* @__PURE__ */ jsx("img", { src: icon.url, alt: "", width: 24, height: 24, loading: "lazy", decoding: "async", className: "w-6 h-6 object-contain" }) : /* @__PURE__ */ jsx(
|
|
45
|
+
"svg",
|
|
46
|
+
{
|
|
47
|
+
width: "24",
|
|
48
|
+
height: "24",
|
|
49
|
+
viewBox: "0 0 24 24",
|
|
50
|
+
fill: "none",
|
|
51
|
+
style: { color: "var(--sk-primary, #6366f1)" },
|
|
52
|
+
children: /* @__PURE__ */ jsx(
|
|
53
|
+
"path",
|
|
54
|
+
{
|
|
55
|
+
d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5",
|
|
56
|
+
stroke: "currentColor",
|
|
57
|
+
strokeWidth: "2",
|
|
58
|
+
strokeLinecap: "round",
|
|
59
|
+
strokeLinejoin: "round"
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
"h3",
|
|
68
|
+
{
|
|
69
|
+
className: "text-lg font-semibold",
|
|
70
|
+
style: { color: "var(--sk-text-primary, #ffffff)" },
|
|
71
|
+
children: service.title
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
"p",
|
|
76
|
+
{
|
|
77
|
+
className: "text-sm leading-relaxed",
|
|
78
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
79
|
+
children: service.description
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
service.features.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2 mt-1", children: service.features.map((feature, fi) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"svg",
|
|
85
|
+
{
|
|
86
|
+
width: "16",
|
|
87
|
+
height: "16",
|
|
88
|
+
viewBox: "0 0 16 16",
|
|
89
|
+
fill: "none",
|
|
90
|
+
className: "shrink-0 mt-0.5",
|
|
91
|
+
style: { color: "#10b981" },
|
|
92
|
+
children: /* @__PURE__ */ jsx(
|
|
93
|
+
"path",
|
|
94
|
+
{
|
|
95
|
+
d: "M13.333 4L6 11.333 2.667 8",
|
|
96
|
+
stroke: "currentColor",
|
|
97
|
+
strokeWidth: "1.5",
|
|
98
|
+
strokeLinecap: "round",
|
|
99
|
+
strokeLinejoin: "round"
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
"span",
|
|
106
|
+
{
|
|
107
|
+
className: "text-sm",
|
|
108
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
109
|
+
children: feature
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
] }, fi)) })
|
|
113
|
+
] }) }, index);
|
|
114
|
+
}) }) })
|
|
115
|
+
] })
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export { ServicesSection as default };
|
|
121
|
+
//# sourceMappingURL=ServicesSection.js.map
|
|
122
|
+
//# sourceMappingURL=ServicesSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/ServicesSection.tsx"],"names":[],"mappings":"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","file":"ServicesSection.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 { PortfolioServicesData } 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 ServicesSectionProps {\n data: PortfolioServicesData;\n}\n\nexport default function ServicesSection({ data }: ServicesSectionProps) {\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-7xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Services Provided\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n A breakdown of the services delivered for this project.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {data.items.map((service, index) => {\n const icon = resolvePortfolioImage(service.icon);\n return (\n <GlassCard key={index} padding=\"lg\" hover>\n <div className=\"flex flex-col gap-4\">\n {/* Icon */}\n <div\n className=\"flex items-center justify-center w-12 h-12 rounded-xl\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n }}\n >\n {icon ? (\n <img src={icon.url} alt=\"\" width={24} height={24} loading=\"lazy\" decoding=\"async\" className=\"w-6 h-6 object-contain\" />\n ) : (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <path\n d=\"M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </div>\n\n <h3\n className=\"text-lg font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {service.title}\n </h3>\n\n <p\n className=\"text-sm leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {service.description}\n </p>\n\n {/* Feature list */}\n {service.features.length > 0 && (\n <ul className=\"flex flex-col gap-2 mt-1\">\n {service.features.map((feature, fi) => (\n <li key={fi} className=\"flex items-start gap-2\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n className=\"shrink-0 mt-0.5\"\n style={{ color: '#10b981' }}\n >\n <path\n d=\"M13.333 4L6 11.333 2.667 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\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 {feature}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </GlassCard>\n );\n })}\n </div>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
|