@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
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
"use client";
|
|
3
|
+
import {
|
|
4
|
+
resolvePortfolioImage
|
|
5
|
+
} from "../../chunk-QDXZ27R7.js";
|
|
5
6
|
|
|
7
|
+
// src/portfolio/components/sections/GallerySection.tsx
|
|
8
|
+
import React, { useState, useCallback, useEffect } from "react";
|
|
9
|
+
import Image from "next/image";
|
|
10
|
+
import ScrollReveal from "@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
12
|
var typeBadgeColors = {
|
|
7
13
|
screenshot: {
|
|
8
14
|
bg: "color-mix(in srgb, #6366f1 12%, transparent)",
|
|
@@ -27,6 +33,8 @@ var typeBadgeColors = {
|
|
|
27
33
|
};
|
|
28
34
|
function GallerySection({ data }) {
|
|
29
35
|
const [lightboxIndex, setLightboxIndex] = useState(null);
|
|
36
|
+
const dialogRef = React.useRef(null);
|
|
37
|
+
const restoreFocusRef = React.useRef(null);
|
|
30
38
|
const layout = data.layout || "grid";
|
|
31
39
|
const openLightbox = useCallback((index) => {
|
|
32
40
|
setLightboxIndex(index);
|
|
@@ -46,20 +54,40 @@ function GallerySection({ data }) {
|
|
|
46
54
|
}, [data.images.length]);
|
|
47
55
|
useEffect(() => {
|
|
48
56
|
if (lightboxIndex === null) return;
|
|
57
|
+
restoreFocusRef.current = document.activeElement;
|
|
58
|
+
const dialog = dialogRef.current;
|
|
59
|
+
const focusables = () => dialog ? Array.from(
|
|
60
|
+
dialog.querySelectorAll('button, [href], [tabindex]:not([tabindex="-1"])')
|
|
61
|
+
) : [];
|
|
62
|
+
focusables()[0]?.focus();
|
|
49
63
|
function handleKeyDown(e) {
|
|
50
64
|
if (e.key === "Escape") closeLightbox();
|
|
51
65
|
if (e.key === "ArrowRight") goNext();
|
|
52
66
|
if (e.key === "ArrowLeft") goPrev();
|
|
67
|
+
if (e.key === "Tab") {
|
|
68
|
+
const items = focusables();
|
|
69
|
+
if (items.length === 0) return;
|
|
70
|
+
const first = items[0];
|
|
71
|
+
const last = items[items.length - 1];
|
|
72
|
+
if (e.shiftKey && document.activeElement === first) {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
last.focus();
|
|
75
|
+
} else if (!e.shiftKey && document.activeElement === last) {
|
|
76
|
+
e.preventDefault();
|
|
77
|
+
first.focus();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
53
80
|
}
|
|
54
81
|
document.addEventListener("keydown", handleKeyDown);
|
|
55
82
|
document.body.style.overflow = "hidden";
|
|
56
83
|
return () => {
|
|
57
84
|
document.removeEventListener("keydown", handleKeyDown);
|
|
58
85
|
document.body.style.overflow = "";
|
|
86
|
+
restoreFocusRef.current?.focus?.();
|
|
59
87
|
};
|
|
60
|
-
}, [lightboxIndex, closeLightbox, goNext, goPrev]);
|
|
61
|
-
function
|
|
62
|
-
return image.image
|
|
88
|
+
}, [lightboxIndex !== null, closeLightbox, goNext, goPrev]);
|
|
89
|
+
function getImage(image) {
|
|
90
|
+
return resolvePortfolioImage(image.image);
|
|
63
91
|
}
|
|
64
92
|
return /* @__PURE__ */ jsxs(
|
|
65
93
|
"section",
|
|
@@ -84,8 +112,11 @@ function GallerySection({ data }) {
|
|
|
84
112
|
{
|
|
85
113
|
className: layout === "masonry" ? "columns-1 md:columns-2 lg:columns-3 gap-4 space-y-4" : "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
86
114
|
children: data.images.map((img, index) => {
|
|
87
|
-
const
|
|
115
|
+
const resolved = getImage(img);
|
|
116
|
+
if (!resolved) return null;
|
|
88
117
|
const colors = typeBadgeColors[img.type || "screenshot"] || typeBadgeColors.screenshot;
|
|
118
|
+
const alt = img.caption || `Gallery image ${index + 1}`;
|
|
119
|
+
const imgClass = "w-full h-auto object-cover transition-transform duration-500 group-hover:scale-105";
|
|
89
120
|
return /* @__PURE__ */ jsxs(
|
|
90
121
|
"div",
|
|
91
122
|
{
|
|
@@ -95,13 +126,24 @@ function GallerySection({ data }) {
|
|
|
95
126
|
},
|
|
96
127
|
onClick: () => openLightbox(index),
|
|
97
128
|
children: [
|
|
98
|
-
/* @__PURE__ */ jsx(
|
|
129
|
+
resolved.width && resolved.height ? /* @__PURE__ */ jsx(
|
|
130
|
+
Image,
|
|
131
|
+
{
|
|
132
|
+
src: resolved.url,
|
|
133
|
+
alt,
|
|
134
|
+
width: resolved.width,
|
|
135
|
+
height: resolved.height,
|
|
136
|
+
sizes: "(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw",
|
|
137
|
+
className: imgClass
|
|
138
|
+
}
|
|
139
|
+
) : /* @__PURE__ */ jsx(
|
|
99
140
|
"img",
|
|
100
141
|
{
|
|
101
|
-
src: url,
|
|
102
|
-
alt
|
|
103
|
-
className:
|
|
104
|
-
loading: "lazy"
|
|
142
|
+
src: resolved.url,
|
|
143
|
+
alt,
|
|
144
|
+
className: imgClass,
|
|
145
|
+
loading: "lazy",
|
|
146
|
+
decoding: "async"
|
|
105
147
|
}
|
|
106
148
|
),
|
|
107
149
|
/* @__PURE__ */ jsx(
|
|
@@ -138,6 +180,10 @@ function GallerySection({ data }) {
|
|
|
138
180
|
lightboxIndex !== null && /* @__PURE__ */ jsxs(
|
|
139
181
|
"div",
|
|
140
182
|
{
|
|
183
|
+
ref: dialogRef,
|
|
184
|
+
role: "dialog",
|
|
185
|
+
"aria-modal": "true",
|
|
186
|
+
"aria-label": data.images[lightboxIndex].caption || `Gallery image ${lightboxIndex + 1} of ${data.images.length}`,
|
|
141
187
|
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
142
188
|
style: { background: "rgba(0,0,0,0.9)" },
|
|
143
189
|
onClick: closeLightbox,
|
|
@@ -196,9 +242,10 @@ function GallerySection({ data }) {
|
|
|
196
242
|
/* @__PURE__ */ jsx(
|
|
197
243
|
"img",
|
|
198
244
|
{
|
|
199
|
-
src:
|
|
245
|
+
src: getImage(data.images[lightboxIndex])?.url,
|
|
200
246
|
alt: data.images[lightboxIndex].caption || "",
|
|
201
|
-
className: "max-w-full max-h-[80vh] object-contain rounded-lg"
|
|
247
|
+
className: "max-w-full max-h-[80vh] object-contain rounded-lg",
|
|
248
|
+
decoding: "async"
|
|
202
249
|
}
|
|
203
250
|
),
|
|
204
251
|
data.images[lightboxIndex].caption && /* @__PURE__ */ jsx("p", { className: "text-sm text-white/70 text-center", children: data.images[lightboxIndex].caption })
|
|
@@ -212,7 +259,7 @@ function GallerySection({ data }) {
|
|
|
212
259
|
}
|
|
213
260
|
);
|
|
214
261
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
//# sourceMappingURL=GallerySection
|
|
262
|
+
export {
|
|
263
|
+
GallerySection as default
|
|
264
|
+
};
|
|
265
|
+
//# sourceMappingURL=GallerySection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/GallerySection.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport Image from 'next/image';\nimport type { PortfolioGalleryData } from '../../../types';\nimport { resolvePortfolioImage } from '../../../shared/images';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\n\ninterface GallerySectionProps {\n data: PortfolioGalleryData;\n}\n\nconst typeBadgeColors: Record<string, { bg: string; text: string; border: string }> = {\n screenshot: {\n bg: 'color-mix(in srgb, #6366f1 12%, transparent)',\n text: '#6366f1',\n border: 'color-mix(in srgb, #6366f1 20%, transparent)',\n },\n before: {\n bg: 'color-mix(in srgb, #f59e0b 12%, transparent)',\n text: '#f59e0b',\n border: 'color-mix(in srgb, #f59e0b 20%, transparent)',\n },\n after: {\n bg: 'color-mix(in srgb, #10b981 12%, transparent)',\n text: '#10b981',\n border: 'color-mix(in srgb, #10b981 20%, transparent)',\n },\n design: {\n bg: 'color-mix(in srgb, #ec4899 12%, transparent)',\n text: '#ec4899',\n border: 'color-mix(in srgb, #ec4899 20%, transparent)',\n },\n};\n\nexport default function GallerySection({ data }: GallerySectionProps) {\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);\n const dialogRef = React.useRef<HTMLDivElement>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n const layout = data.layout || 'grid';\n\n const openLightbox = useCallback((index: number) => {\n setLightboxIndex(index);\n }, []);\n\n const closeLightbox = useCallback(() => {\n setLightboxIndex(null);\n }, []);\n\n const goNext = useCallback(() => {\n setLightboxIndex((prev) =>\n prev !== null ? (prev + 1) % data.images.length : null,\n );\n }, [data.images.length]);\n\n const goPrev = useCallback(() => {\n setLightboxIndex((prev) =>\n prev !== null ? (prev - 1 + data.images.length) % data.images.length : null,\n );\n }, [data.images.length]);\n\n // Keyboard navigation + dialog focus management\n useEffect(() => {\n if (lightboxIndex === null) return;\n\n // Move focus into the dialog; restore it to the trigger on close.\n restoreFocusRef.current = document.activeElement as HTMLElement | null;\n const dialog = dialogRef.current;\n const focusables = () =>\n dialog\n ? Array.from(\n dialog.querySelectorAll<HTMLElement>('button, [href], [tabindex]:not([tabindex=\"-1\"])'),\n )\n : [];\n focusables()[0]?.focus();\n\n function handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') closeLightbox();\n if (e.key === 'ArrowRight') goNext();\n if (e.key === 'ArrowLeft') goPrev();\n if (e.key === 'Tab') {\n // Trap Tab inside the dialog\n const items = focusables();\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n document.addEventListener('keydown', handleKeyDown);\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n document.body.style.overflow = '';\n restoreFocusRef.current?.focus?.();\n };\n }, [lightboxIndex !== null, closeLightbox, goNext, goPrev]); // eslint-disable-line react-hooks/exhaustive-deps\n\n function getImage(image: typeof data.images[0]) {\n // URL (+ intrinsic dims when derivable); raw Sanity refs resolve to null.\n return resolvePortfolioImage(image.image);\n }\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-7xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-12\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Gallery\n </h2>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.08}>\n <div\n className={\n layout === 'masonry'\n ? 'columns-1 md:columns-2 lg:columns-3 gap-4 space-y-4'\n : 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'\n }\n >\n {data.images.map((img, index) => {\n const resolved = getImage(img);\n if (!resolved) return null;\n const colors = typeBadgeColors[img.type || 'screenshot'] || typeBadgeColors.screenshot;\n const alt = img.caption || `Gallery image ${index + 1}`;\n const imgClass =\n 'w-full h-auto object-cover transition-transform duration-500 group-hover:scale-105';\n\n return (\n <div\n key={index}\n className={`relative group cursor-pointer overflow-hidden rounded-xl ${\n layout === 'masonry' ? 'break-inside-avoid' : ''\n }`}\n style={{\n border: '1px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n onClick={() => openLightbox(index)}\n >\n {resolved.width && resolved.height ? (\n <Image\n src={resolved.url}\n alt={alt}\n width={resolved.width}\n height={resolved.height}\n sizes=\"(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw\"\n className={imgClass}\n />\n ) : (\n <img\n src={resolved.url}\n alt={alt}\n className={imgClass}\n loading=\"lazy\"\n decoding=\"async\"\n />\n )}\n\n {/* Overlay on hover */}\n <div\n className=\"absolute inset-0 flex flex-col justify-end p-4 opacity-0 group-hover:opacity-100 transition-opacity duration-300\"\n style={{\n background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%)',\n }}\n >\n {img.caption && (\n <p className=\"text-sm text-white font-medium\">{img.caption}</p>\n )}\n </div>\n\n {/* Type badge */}\n {img.type && (\n <span\n className=\"absolute top-3 left-3 px-2.5 py-1 rounded-full text-[11px] uppercase tracking-wider font-medium\"\n style={{\n background: colors.bg,\n color: colors.text,\n border: `1px solid ${colors.border}`,\n backdropFilter: 'blur(8px)',\n }}\n >\n {img.type}\n </span>\n )}\n </div>\n );\n })}\n </div>\n </ScrollReveal>\n </div>\n\n {/* Lightbox modal */}\n {lightboxIndex !== null && (\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={data.images[lightboxIndex].caption || `Gallery image ${lightboxIndex + 1} of ${data.images.length}`}\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n style={{ background: 'rgba(0,0,0,0.9)' }}\n onClick={closeLightbox}\n >\n {/* Close button */}\n <button\n onClick={closeLightbox}\n className=\"absolute top-6 right-6 w-10 h-10 flex items-center justify-center rounded-full transition-colors z-10\"\n style={{\n background: 'rgba(255,255,255,0.1)',\n color: '#ffffff',\n }}\n aria-label=\"Close lightbox\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M15 5L5 15M5 5l10 10\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n\n {/* Prev button */}\n <button\n onClick={(e) => { e.stopPropagation(); goPrev(); }}\n className=\"absolute left-4 md:left-8 w-12 h-12 flex items-center justify-center rounded-full transition-colors z-10\"\n style={{\n background: 'rgba(255,255,255,0.1)',\n color: '#ffffff',\n }}\n aria-label=\"Previous image\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M12.5 15l-5-5 5-5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n {/* Next button */}\n <button\n onClick={(e) => { e.stopPropagation(); goNext(); }}\n className=\"absolute right-4 md:right-8 w-12 h-12 flex items-center justify-center rounded-full transition-colors z-10\"\n style={{\n background: 'rgba(255,255,255,0.1)',\n color: '#ffffff',\n }}\n aria-label=\"Next image\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M7.5 5l5 5-5 5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n {/* Image */}\n <div\n className=\"max-w-[90vw] max-h-[85vh] flex flex-col items-center gap-4\"\n onClick={(e) => e.stopPropagation()}\n >\n <img\n src={getImage(data.images[lightboxIndex])?.url}\n alt={data.images[lightboxIndex].caption || ''}\n className=\"max-w-full max-h-[80vh] object-contain rounded-lg\"\n decoding=\"async\"\n />\n {data.images[lightboxIndex].caption && (\n <p className=\"text-sm text-white/70 text-center\">\n {data.images[lightboxIndex].caption}\n </p>\n )}\n </div>\n </div>\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkZBPF7TLZ_cjs = require('../../chunk-ZBPF7TLZ.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');
|
|
7
|
+
var DeviceTrifolio = require('@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var ScrollReveal__default = /*#__PURE__*/_interopDefault(ScrollReveal);
|
|
13
|
+
var AnimatedCounter__default = /*#__PURE__*/_interopDefault(AnimatedCounter);
|
|
14
|
+
var GlassCard__default = /*#__PURE__*/_interopDefault(GlassCard);
|
|
15
|
+
var DeviceTrifolio__default = /*#__PURE__*/_interopDefault(DeviceTrifolio);
|
|
16
|
+
|
|
17
|
+
var HERO_PARALLAX_CSS = `
|
|
18
|
+
@supports (animation-timeline: view()) {
|
|
19
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
20
|
+
.sk-hero-bg {
|
|
21
|
+
animation: sk-hero-drift linear both;
|
|
22
|
+
animation-timeline: view(block);
|
|
23
|
+
animation-range: exit 0% exit 100%;
|
|
24
|
+
}
|
|
25
|
+
@keyframes sk-hero-drift {
|
|
26
|
+
from { transform: translateY(0); }
|
|
27
|
+
to { transform: translateY(30%); }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
function HeroSection({ data, screenshots, liveUrl }) {
|
|
33
|
+
const shots = screenshots || data.screenshots;
|
|
34
|
+
const url = liveUrl || data.liveUrl;
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
36
|
+
"section",
|
|
37
|
+
{
|
|
38
|
+
className: "relative overflow-hidden w-full",
|
|
39
|
+
style: {
|
|
40
|
+
minHeight: "90vh",
|
|
41
|
+
display: "flex",
|
|
42
|
+
flexDirection: "column",
|
|
43
|
+
justifyContent: "center",
|
|
44
|
+
background: "var(--sk-bg, #0a0a0a)"
|
|
45
|
+
},
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { href: "sk-hero-parallax", precedence: "default", children: HERO_PARALLAX_CSS }),
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: "sk-hero-bg absolute inset-0 pointer-events-none",
|
|
52
|
+
style: {
|
|
53
|
+
background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,
|
|
54
|
+
willChange: "transform"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start", children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-6", children: [
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
61
|
+
"span",
|
|
62
|
+
{
|
|
63
|
+
className: "inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium",
|
|
64
|
+
style: {
|
|
65
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
|
|
66
|
+
color: "var(--sk-primary, #6366f1)",
|
|
67
|
+
border: "1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)"
|
|
68
|
+
},
|
|
69
|
+
children: chunkZBPF7TLZ_cjs.formatCategoryLabel(data.category)
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
73
|
+
"h1",
|
|
74
|
+
{
|
|
75
|
+
className: "text-4xl md:text-5xl lg:text-6xl font-bold leading-tight",
|
|
76
|
+
style: {
|
|
77
|
+
color: "var(--sk-text-primary, #ffffff)",
|
|
78
|
+
fontFamily: "var(--sk-font-heading, inherit)",
|
|
79
|
+
overflowWrap: "break-word",
|
|
80
|
+
wordBreak: "break-word"
|
|
81
|
+
},
|
|
82
|
+
children: data.headline
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86
|
+
"p",
|
|
87
|
+
{
|
|
88
|
+
className: "text-xl md:text-2xl font-medium",
|
|
89
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
90
|
+
children: data.subheadline
|
|
91
|
+
}
|
|
92
|
+
),
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
94
|
+
"p",
|
|
95
|
+
{
|
|
96
|
+
className: "text-base md:text-lg leading-relaxed",
|
|
97
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
98
|
+
children: data.description
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
data.services.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: data.services.map((service) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
"span",
|
|
103
|
+
{
|
|
104
|
+
className: "px-3 py-1 rounded-full text-xs font-medium",
|
|
105
|
+
style: {
|
|
106
|
+
background: "var(--sk-surface, rgba(255,255,255,0.05))",
|
|
107
|
+
color: "var(--sk-text-secondary, #a1a1aa)",
|
|
108
|
+
border: "1px solid var(--sk-border, rgba(255,255,255,0.1))"
|
|
109
|
+
},
|
|
110
|
+
children: chunkZBPF7TLZ_cjs.formatServiceTag(service)
|
|
111
|
+
},
|
|
112
|
+
service
|
|
113
|
+
)) }),
|
|
114
|
+
url && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
115
|
+
"a",
|
|
116
|
+
{
|
|
117
|
+
href: url,
|
|
118
|
+
target: "_blank",
|
|
119
|
+
rel: "noopener noreferrer",
|
|
120
|
+
"data-portfolio-action": "live-site",
|
|
121
|
+
className: "inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90",
|
|
122
|
+
style: {
|
|
123
|
+
background: "var(--sk-primary, #6366f1)",
|
|
124
|
+
color: "#ffffff"
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
"View Live Site",
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 3h7v7M13 3L3 13", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-10 lg:pt-8", children: [
|
|
134
|
+
(url || shots?.desktop || shots?.tablet || shots?.mobile) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
135
|
+
DeviceTrifolio__default.default,
|
|
136
|
+
{
|
|
137
|
+
screenshots: {
|
|
138
|
+
desktop: shots?.desktop,
|
|
139
|
+
tablet: shots?.tablet,
|
|
140
|
+
mobile: shots?.mobile
|
|
141
|
+
},
|
|
142
|
+
url
|
|
143
|
+
}
|
|
144
|
+
) }),
|
|
145
|
+
data.kpis.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ScrollReveal__default.default, { y: 30, delay: 0.6, stagger: 0.1, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: data.kpis.map((kpi, i) => /* @__PURE__ */ jsxRuntime.jsxs(GlassCard__default.default, { padding: "sm", hover: false, className: "text-center", children: [
|
|
146
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
147
|
+
"div",
|
|
148
|
+
{
|
|
149
|
+
className: "text-2xl md:text-3xl font-bold",
|
|
150
|
+
style: { color: "var(--sk-primary, #6366f1)" },
|
|
151
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
152
|
+
AnimatedCounter__default.default,
|
|
153
|
+
{
|
|
154
|
+
value: kpi.value,
|
|
155
|
+
suffix: kpi.suffix,
|
|
156
|
+
prefix: kpi.prefix,
|
|
157
|
+
duration: 2.5
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
),
|
|
162
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
className: "text-xs mt-1 font-medium",
|
|
166
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
167
|
+
children: kpi.label
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
] }, i)) }) })
|
|
171
|
+
] })
|
|
172
|
+
] }) })
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = HeroSection;
|
|
179
|
+
//# sourceMappingURL=HeroSection.cjs.map
|
|
180
|
+
//# sourceMappingURL=HeroSection.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/HeroSection.tsx"],"names":["jsxs","jsx","formatCategoryLabel","DeviceTrifolio","ScrollReveal","GlassCard","AnimatedCounter"],"mappings":";;;;;;;;;;;;;;;;AAmBA,IAAM,iBAAA,GAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAsBX,SAAR,WAAA,CAA6B,EAAE,IAAA,EAAM,WAAA,EAAa,SAAQ,EAAqB;AACpF,EAAA,MAAM,KAAA,GAAQ,eAAe,IAAA,CAAK,WAAA;AAClC,EAAA,MAAM,GAAA,GAAM,WAAW,IAAA,CAAK,OAAA;AAE5B,EAAA,uBACEA,eAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,iCAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,SAAA,EAAW,MAAA;AAAA,QACX,OAAA,EAAS,MAAA;AAAA,QACT,aAAA,EAAe,QAAA;AAAA,QACf,cAAA,EAAgB,QAAA;AAAA,QAChB,UAAA,EAAY;AAAA,OACd;AAAA,MAGA,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,kBAAA,EAAmB,UAAA,EAAW,WACvC,QAAA,EAAA,iBAAA,EACH,CAAA;AAAA,wBACAA,cAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,iDAAA;AAAA,YACV,KAAA,EAAO;AAAA,cACL,UAAA,EAAY,CAAA,wHAAA,CAAA;AAAA,cACZ,UAAA,EAAY;AAAA;AACd;AAAA,SACF;AAAA,uCAEC,KAAA,EAAA,EAAI,SAAA,EAAU,8EACb,QAAA,kBAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,sEAAA,EAEb,QAAA,EAAA;AAAA,0BAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wCAAA,EAEb,QAAA,EAAA;AAAA,4BAAAC,cAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,kFAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,UAAA,EAAY,iEAAA;AAAA,kBACZ,KAAA,EAAO,4BAAA;AAAA,kBACP,MAAA,EAAQ;AAAA,iBACV;AAAA,gBAEC,QAAA,EAAAC,qCAAA,CAAoB,KAAK,QAAQ;AAAA;AAAA,aACpC;AAAA,4BAGAD,cAAA;AAAA,cAAC,IAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,0DAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,KAAA,EAAO,iCAAA;AAAA,kBACP,UAAA,EAAY,iCAAA;AAAA,kBACZ,YAAA,EAAc,YAAA;AAAA,kBACd,SAAA,EAAW;AAAA,iBACb;AAAA,gBAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,aACR;AAAA,4BAGAA,cAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,iCAAA;AAAA,gBACV,KAAA,EAAO,EAAE,KAAA,EAAO,mCAAA,EAAoC;AAAA,gBAEnD,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,aACR;AAAA,4BAGAA,cAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,sCAAA;AAAA,gBACV,KAAA,EAAO,EAAE,KAAA,EAAO,kCAAA,EAAmC;AAAA,gBAElD,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,aACR;AAAA,YAGC,IAAA,CAAK,QAAA,CAAS,MAAA,GAAS,CAAA,oBACtBA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EACZ,QAAA,EAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,qBAClBA,cAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBAEC,SAAA,EAAU,4CAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,UAAA,EAAY,2CAAA;AAAA,kBACZ,KAAA,EAAO,mCAAA;AAAA,kBACP,MAAA,EAAQ;AAAA,iBACV;AAAA,gBAEC,6CAAiB,OAAO;AAAA,eAAA;AAAA,cARpB;AAAA,aAUR,CAAA,EACH,CAAA;AAAA,YAID,GAAA,oBACCD,eAAA;AAAA,cAAC,GAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAM,GAAA;AAAA,gBACN,MAAA,EAAO,QAAA;AAAA,gBACP,GAAA,EAAI,qBAAA;AAAA,gBACJ,uBAAA,EAAsB,WAAA;AAAA,gBACtB,SAAA,EAAU,0HAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACL,UAAA,EAAY,4BAAA;AAAA,kBACZ,KAAA,EAAO;AAAA,iBACT;AAAA,gBACD,QAAA,EAAA;AAAA,kBAAA,gBAAA;AAAA,kCAECC,cAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,MAAK,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EAAO,KAAA,EAAM,4BAAA,EAChE,yCAAC,MAAA,EAAA,EAAK,CAAA,EAAE,oBAAA,EAAqB,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,KAAI,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,CAAA,EAClH;AAAA;AAAA;AAAA;AACF,WAAA,EAGJ,CAAA;AAAA,0BAGAD,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iDAAA,EAEX,QAAA,EAAA;AAAA,YAAA,CAAA,GAAA,IAAO,KAAA,EAAO,WAAW,KAAA,EAAO,MAAA,IAAU,OAAO,MAAA,qBACjDC,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EACb,QAAA,kBAAAA,cAAA;AAAA,cAACE,+BAAA;AAAA,cAAA;AAAA,gBACC,WAAA,EAAa;AAAA,kBACX,SAAS,KAAA,EAAO,OAAA;AAAA,kBAChB,QAAQ,KAAA,EAAO,MAAA;AAAA,kBACf,QAAQ,KAAA,EAAO;AAAA,iBACjB;AAAA,gBACA;AAAA;AAAA,aACF,EACF,CAAA;AAAA,YAID,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAA,oBAClBF,cAAA,CAACG,6BAAA,EAAA,EAAa,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,GAAA,EAAK,OAAA,EAAS,GAAA,EACxC,QAAA,kBAAAH,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAA,EACZ,QAAA,EAAA,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,qBACnBD,eAAA,CAACK,0BAAA,EAAA,EAAkB,OAAA,EAAQ,IAAA,EAAK,KAAA,EAAO,KAAA,EAAO,WAAU,aAAA,EACtD,QAAA,EAAA;AAAA,8BAAAJ,cAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,gCAAA;AAAA,kBACV,KAAA,EAAO,EAAE,KAAA,EAAO,4BAAA,EAA6B;AAAA,kBAE7C,QAAA,kBAAAA,cAAA;AAAA,oBAACK,gCAAA;AAAA,oBAAA;AAAA,sBACC,OAAO,GAAA,CAAI,KAAA;AAAA,sBACX,QAAQ,GAAA,CAAI,MAAA;AAAA,sBACZ,QAAQ,GAAA,CAAI,MAAA;AAAA,sBACZ,QAAA,EAAU;AAAA;AAAA;AACZ;AAAA,eACF;AAAA,8BACAL,cAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EAAU,0BAAA;AAAA,kBACV,KAAA,EAAO,EAAE,KAAA,EAAO,mCAAA,EAAoC;AAAA,kBAEnD,QAAA,EAAA,GAAA,CAAI;AAAA;AAAA;AACP,aAAA,EAAA,EAjBc,CAkBhB,CACD,CAAA,EACH,CAAA,EACF;AAAA,WAAA,EAEJ;AAAA,SAAA,EACF,CAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ","file":"HeroSection.cjs","sourcesContent":["// Server component — the entire hero renders on the server and ships zero\n// component JS. Client primitives (counter, reveal, trifolio) cross the RSC\n// boundary via package subpaths.\nimport React from 'react';\nimport type { PortfolioHeroData } from '../../../types';\nimport { formatCategoryLabel, formatServiceTag } from '../../format';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\nimport DeviceTrifolio from '@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio';\n\n// LCP rule (monorepo CLAUDE.md, Performance): above-the-fold content renders\n// fully static — no entrance animation, no post-hydration re-hide. The text\n// column below must never be wrapped in ScrollReveal/SplitHeadline: hiding\n// the H1 after hydration moves LCP to the tween's end and tanks the mobile\n// Lighthouse score. Reveal animations are for the below-fold KPI cards only.\n\n// Background parallax as a CSS scroll-driven animation — progressive\n// enhancement: browsers without animation-timeline get a static gradient.\nconst HERO_PARALLAX_CSS = `\n@supports (animation-timeline: view()) {\n @media (prefers-reduced-motion: no-preference) {\n .sk-hero-bg {\n animation: sk-hero-drift linear both;\n animation-timeline: view(block);\n animation-range: exit 0% exit 100%;\n }\n @keyframes sk-hero-drift {\n from { transform: translateY(0); }\n to { transform: translateY(30%); }\n }\n }\n}\n`;\n\ninterface HeroSectionProps {\n data: PortfolioHeroData;\n screenshots?: { desktop?: string; tablet?: string; mobile?: string };\n liveUrl?: string;\n}\n\nexport default function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps) {\n const shots = screenshots || data.screenshots;\n const url = liveUrl || data.liveUrl;\n\n return (\n <section\n className=\"relative overflow-hidden w-full\"\n style={{\n minHeight: '90vh',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n background: 'var(--sk-bg, #0a0a0a)',\n }}\n >\n {/* Parallax background layer (CSS scroll-driven) */}\n <style href=\"sk-hero-parallax\" precedence=\"default\">\n {HERO_PARALLAX_CSS}\n </style>\n <div\n className=\"sk-hero-bg absolute inset-0 pointer-events-none\"\n style={{\n background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,\n willChange: 'transform',\n }}\n />\n\n <div className=\"relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32\">\n <div className=\"grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start\">\n {/* Text column — min-w-0 so grid track can shrink below content intrinsic width (mobile) */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-6\">\n {/* Category badge */}\n <span\n className=\"inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n }}\n >\n {formatCategoryLabel(data.category)}\n </span>\n\n {/* Headline — static, this is usually the LCP element */}\n <h1\n className=\"text-4xl md:text-5xl lg:text-6xl font-bold leading-tight\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n overflowWrap: 'break-word',\n wordBreak: 'break-word',\n }}\n >\n {data.headline}\n </h1>\n\n {/* Subheadline */}\n <p\n className=\"text-xl md:text-2xl font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.subheadline}\n </p>\n\n {/* Description */}\n <p\n className=\"text-base md:text-lg leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {data.description}\n </p>\n\n {/* Services tags */}\n {data.services.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {data.services.map((service) => (\n <span\n key={service}\n className=\"px-3 py-1 rounded-full text-xs font-medium\"\n style={{\n background: 'var(--sk-surface, rgba(255,255,255,0.05))',\n color: 'var(--sk-text-secondary, #a1a1aa)',\n border: '1px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n >\n {formatServiceTag(service)}\n </span>\n ))}\n </div>\n )}\n\n {/* CTA button */}\n {url && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-portfolio-action=\"live-site\"\n className=\"inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90\"\n style={{\n background: 'var(--sk-primary, #6366f1)',\n color: '#ffffff',\n }}\n >\n View Live Site\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 3h7v7M13 3L3 13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </a>\n )}\n\n </div>\n\n {/* Right column — trifolio + KPIs */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-10 lg:pt-8\">\n {/* Device trifolio — realistic device frames */}\n {(url || shots?.desktop || shots?.tablet || shots?.mobile) && (\n <div className=\"min-w-0 max-w-full\">\n <DeviceTrifolio\n screenshots={{\n desktop: shots?.desktop,\n tablet: shots?.tablet,\n mobile: shots?.mobile,\n }}\n url={url}\n />\n </div>\n )}\n\n {/* KPI cards — below trifolio in right column */}\n {data.kpis.length > 0 && (\n <ScrollReveal y={30} delay={0.6} stagger={0.1}>\n <div className=\"grid grid-cols-2 gap-3\">\n {data.kpis.map((kpi, i) => (\n <GlassCard key={i} padding=\"sm\" hover={false} className=\"text-center\">\n <div\n className=\"text-2xl md:text-3xl font-bold\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <AnimatedCounter\n value={kpi.value}\n suffix={kpi.suffix}\n prefix={kpi.prefix}\n duration={2.5}\n />\n </div>\n <div\n className=\"text-xs mt-1 font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {kpi.label}\n </div>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n )}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { e as PortfolioHeroData } from '../../types-0tVPy4pU.cjs';
|
|
3
|
+
|
|
4
|
+
interface HeroSectionProps {
|
|
5
|
+
data: PortfolioHeroData;
|
|
6
|
+
screenshots?: {
|
|
7
|
+
desktop?: string;
|
|
8
|
+
tablet?: string;
|
|
9
|
+
mobile?: string;
|
|
10
|
+
};
|
|
11
|
+
liveUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
declare function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps): React.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { HeroSection as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { e as PortfolioHeroData } from '../../types-0tVPy4pU.js';
|
|
3
|
+
|
|
4
|
+
interface HeroSectionProps {
|
|
5
|
+
data: PortfolioHeroData;
|
|
6
|
+
screenshots?: {
|
|
7
|
+
desktop?: string;
|
|
8
|
+
tablet?: string;
|
|
9
|
+
mobile?: string;
|
|
10
|
+
};
|
|
11
|
+
liveUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
declare function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps): React.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { HeroSection as default };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { formatCategoryLabel, formatServiceTag } from '../../chunk-7D4H36UF.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';
|
|
5
|
+
import DeviceTrifolio from '@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var HERO_PARALLAX_CSS = `
|
|
9
|
+
@supports (animation-timeline: view()) {
|
|
10
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
11
|
+
.sk-hero-bg {
|
|
12
|
+
animation: sk-hero-drift linear both;
|
|
13
|
+
animation-timeline: view(block);
|
|
14
|
+
animation-range: exit 0% exit 100%;
|
|
15
|
+
}
|
|
16
|
+
@keyframes sk-hero-drift {
|
|
17
|
+
from { transform: translateY(0); }
|
|
18
|
+
to { transform: translateY(30%); }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
function HeroSection({ data, screenshots, liveUrl }) {
|
|
24
|
+
const shots = screenshots || data.screenshots;
|
|
25
|
+
const url = liveUrl || data.liveUrl;
|
|
26
|
+
return /* @__PURE__ */ jsxs(
|
|
27
|
+
"section",
|
|
28
|
+
{
|
|
29
|
+
className: "relative overflow-hidden w-full",
|
|
30
|
+
style: {
|
|
31
|
+
minHeight: "90vh",
|
|
32
|
+
display: "flex",
|
|
33
|
+
flexDirection: "column",
|
|
34
|
+
justifyContent: "center",
|
|
35
|
+
background: "var(--sk-bg, #0a0a0a)"
|
|
36
|
+
},
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ jsx("style", { href: "sk-hero-parallax", precedence: "default", children: HERO_PARALLAX_CSS }),
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
className: "sk-hero-bg absolute inset-0 pointer-events-none",
|
|
43
|
+
style: {
|
|
44
|
+
background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,
|
|
45
|
+
willChange: "transform"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
/* @__PURE__ */ jsx("div", { className: "relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start", children: [
|
|
50
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-6", children: [
|
|
51
|
+
/* @__PURE__ */ jsx(
|
|
52
|
+
"span",
|
|
53
|
+
{
|
|
54
|
+
className: "inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium",
|
|
55
|
+
style: {
|
|
56
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
|
|
57
|
+
color: "var(--sk-primary, #6366f1)",
|
|
58
|
+
border: "1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)"
|
|
59
|
+
},
|
|
60
|
+
children: formatCategoryLabel(data.category)
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
/* @__PURE__ */ jsx(
|
|
64
|
+
"h1",
|
|
65
|
+
{
|
|
66
|
+
className: "text-4xl md:text-5xl lg:text-6xl font-bold leading-tight",
|
|
67
|
+
style: {
|
|
68
|
+
color: "var(--sk-text-primary, #ffffff)",
|
|
69
|
+
fontFamily: "var(--sk-font-heading, inherit)",
|
|
70
|
+
overflowWrap: "break-word",
|
|
71
|
+
wordBreak: "break-word"
|
|
72
|
+
},
|
|
73
|
+
children: data.headline
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
"p",
|
|
78
|
+
{
|
|
79
|
+
className: "text-xl md:text-2xl font-medium",
|
|
80
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
81
|
+
children: data.subheadline
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsx(
|
|
85
|
+
"p",
|
|
86
|
+
{
|
|
87
|
+
className: "text-base md:text-lg leading-relaxed",
|
|
88
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
89
|
+
children: data.description
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
data.services.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: data.services.map((service) => /* @__PURE__ */ jsx(
|
|
93
|
+
"span",
|
|
94
|
+
{
|
|
95
|
+
className: "px-3 py-1 rounded-full text-xs font-medium",
|
|
96
|
+
style: {
|
|
97
|
+
background: "var(--sk-surface, rgba(255,255,255,0.05))",
|
|
98
|
+
color: "var(--sk-text-secondary, #a1a1aa)",
|
|
99
|
+
border: "1px solid var(--sk-border, rgba(255,255,255,0.1))"
|
|
100
|
+
},
|
|
101
|
+
children: formatServiceTag(service)
|
|
102
|
+
},
|
|
103
|
+
service
|
|
104
|
+
)) }),
|
|
105
|
+
url && /* @__PURE__ */ jsxs(
|
|
106
|
+
"a",
|
|
107
|
+
{
|
|
108
|
+
href: url,
|
|
109
|
+
target: "_blank",
|
|
110
|
+
rel: "noopener noreferrer",
|
|
111
|
+
"data-portfolio-action": "live-site",
|
|
112
|
+
className: "inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90",
|
|
113
|
+
style: {
|
|
114
|
+
background: "var(--sk-primary, #6366f1)",
|
|
115
|
+
color: "#ffffff"
|
|
116
|
+
},
|
|
117
|
+
children: [
|
|
118
|
+
"View Live Site",
|
|
119
|
+
/* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M6 3h7v7M13 3L3 13", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] }),
|
|
124
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 max-w-full flex-col gap-10 lg:pt-8", children: [
|
|
125
|
+
(url || shots?.desktop || shots?.tablet || shots?.mobile) && /* @__PURE__ */ jsx("div", { className: "min-w-0 max-w-full", children: /* @__PURE__ */ jsx(
|
|
126
|
+
DeviceTrifolio,
|
|
127
|
+
{
|
|
128
|
+
screenshots: {
|
|
129
|
+
desktop: shots?.desktop,
|
|
130
|
+
tablet: shots?.tablet,
|
|
131
|
+
mobile: shots?.mobile
|
|
132
|
+
},
|
|
133
|
+
url
|
|
134
|
+
}
|
|
135
|
+
) }),
|
|
136
|
+
data.kpis.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 30, delay: 0.6, stagger: 0.1, children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3", children: data.kpis.map((kpi, i) => /* @__PURE__ */ jsxs(GlassCard, { padding: "sm", hover: false, className: "text-center", children: [
|
|
137
|
+
/* @__PURE__ */ jsx(
|
|
138
|
+
"div",
|
|
139
|
+
{
|
|
140
|
+
className: "text-2xl md:text-3xl font-bold",
|
|
141
|
+
style: { color: "var(--sk-primary, #6366f1)" },
|
|
142
|
+
children: /* @__PURE__ */ jsx(
|
|
143
|
+
AnimatedCounter,
|
|
144
|
+
{
|
|
145
|
+
value: kpi.value,
|
|
146
|
+
suffix: kpi.suffix,
|
|
147
|
+
prefix: kpi.prefix,
|
|
148
|
+
duration: 2.5
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ jsx(
|
|
154
|
+
"div",
|
|
155
|
+
{
|
|
156
|
+
className: "text-xs mt-1 font-medium",
|
|
157
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
158
|
+
children: kpi.label
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
] }, i)) }) })
|
|
162
|
+
] })
|
|
163
|
+
] }) })
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { HeroSection as default };
|
|
170
|
+
//# sourceMappingURL=HeroSection.js.map
|
|
171
|
+
//# sourceMappingURL=HeroSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/portfolio/components/sections/HeroSection.tsx"],"names":[],"mappings":"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","file":"HeroSection.js","sourcesContent":["// Server component — the entire hero renders on the server and ships zero\n// component JS. Client primitives (counter, reveal, trifolio) cross the RSC\n// boundary via package subpaths.\nimport React from 'react';\nimport type { PortfolioHeroData } from '../../../types';\nimport { formatCategoryLabel, formatServiceTag } from '../../format';\nimport ScrollReveal from '@sonordev/agency-site-kit/portfolio/primitives/ScrollReveal';\nimport AnimatedCounter from '@sonordev/agency-site-kit/portfolio/primitives/AnimatedCounter';\nimport GlassCard from '@sonordev/agency-site-kit/portfolio/primitives/GlassCard';\nimport DeviceTrifolio from '@sonordev/agency-site-kit/portfolio/primitives/DeviceTrifolio';\n\n// LCP rule (monorepo CLAUDE.md, Performance): above-the-fold content renders\n// fully static — no entrance animation, no post-hydration re-hide. The text\n// column below must never be wrapped in ScrollReveal/SplitHeadline: hiding\n// the H1 after hydration moves LCP to the tween's end and tanks the mobile\n// Lighthouse score. Reveal animations are for the below-fold KPI cards only.\n\n// Background parallax as a CSS scroll-driven animation — progressive\n// enhancement: browsers without animation-timeline get a static gradient.\nconst HERO_PARALLAX_CSS = `\n@supports (animation-timeline: view()) {\n @media (prefers-reduced-motion: no-preference) {\n .sk-hero-bg {\n animation: sk-hero-drift linear both;\n animation-timeline: view(block);\n animation-range: exit 0% exit 100%;\n }\n @keyframes sk-hero-drift {\n from { transform: translateY(0); }\n to { transform: translateY(30%); }\n }\n }\n}\n`;\n\ninterface HeroSectionProps {\n data: PortfolioHeroData;\n screenshots?: { desktop?: string; tablet?: string; mobile?: string };\n liveUrl?: string;\n}\n\nexport default function HeroSection({ data, screenshots, liveUrl }: HeroSectionProps) {\n const shots = screenshots || data.screenshots;\n const url = liveUrl || data.liveUrl;\n\n return (\n <section\n className=\"relative overflow-hidden w-full\"\n style={{\n minHeight: '90vh',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n background: 'var(--sk-bg, #0a0a0a)',\n }}\n >\n {/* Parallax background layer (CSS scroll-driven) */}\n <style href=\"sk-hero-parallax\" precedence=\"default\">\n {HERO_PARALLAX_CSS}\n </style>\n <div\n className=\"sk-hero-bg absolute inset-0 pointer-events-none\"\n style={{\n background: `radial-gradient(ellipse at 50% 20%, color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent) 0%, transparent 70%)`,\n willChange: 'transform',\n }}\n />\n\n <div className=\"relative z-10 max-w-7xl mx-auto w-full min-w-0 px-4 sm:px-6 py-24 lg:py-32\">\n <div className=\"grid grid-cols-1 min-w-0 lg:grid-cols-2 gap-12 lg:gap-16 items-start\">\n {/* Text column — min-w-0 so grid track can shrink below content intrinsic width (mobile) */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-6\">\n {/* Category badge */}\n <span\n className=\"inline-flex items-center self-start px-4 py-1.5 rounded-full text-sm font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n }}\n >\n {formatCategoryLabel(data.category)}\n </span>\n\n {/* Headline — static, this is usually the LCP element */}\n <h1\n className=\"text-4xl md:text-5xl lg:text-6xl font-bold leading-tight\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n overflowWrap: 'break-word',\n wordBreak: 'break-word',\n }}\n >\n {data.headline}\n </h1>\n\n {/* Subheadline */}\n <p\n className=\"text-xl md:text-2xl font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.subheadline}\n </p>\n\n {/* Description */}\n <p\n className=\"text-base md:text-lg leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {data.description}\n </p>\n\n {/* Services tags */}\n {data.services.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {data.services.map((service) => (\n <span\n key={service}\n className=\"px-3 py-1 rounded-full text-xs font-medium\"\n style={{\n background: 'var(--sk-surface, rgba(255,255,255,0.05))',\n color: 'var(--sk-text-secondary, #a1a1aa)',\n border: '1px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n >\n {formatServiceTag(service)}\n </span>\n ))}\n </div>\n )}\n\n {/* CTA button */}\n {url && (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-portfolio-action=\"live-site\"\n className=\"inline-flex items-center gap-2 self-start px-6 py-3 rounded-xl text-sm font-semibold transition-opacity hover:opacity-90\"\n style={{\n background: 'var(--sk-primary, #6366f1)',\n color: '#ffffff',\n }}\n >\n View Live Site\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 3h7v7M13 3L3 13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </a>\n )}\n\n </div>\n\n {/* Right column — trifolio + KPIs */}\n <div className=\"flex min-w-0 max-w-full flex-col gap-10 lg:pt-8\">\n {/* Device trifolio — realistic device frames */}\n {(url || shots?.desktop || shots?.tablet || shots?.mobile) && (\n <div className=\"min-w-0 max-w-full\">\n <DeviceTrifolio\n screenshots={{\n desktop: shots?.desktop,\n tablet: shots?.tablet,\n mobile: shots?.mobile,\n }}\n url={url}\n />\n </div>\n )}\n\n {/* KPI cards — below trifolio in right column */}\n {data.kpis.length > 0 && (\n <ScrollReveal y={30} delay={0.6} stagger={0.1}>\n <div className=\"grid grid-cols-2 gap-3\">\n {data.kpis.map((kpi, i) => (\n <GlassCard key={i} padding=\"sm\" hover={false} className=\"text-center\">\n <div\n className=\"text-2xl md:text-3xl font-bold\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n <AnimatedCounter\n value={kpi.value}\n suffix={kpi.suffix}\n prefix={kpi.prefix}\n duration={2.5}\n />\n </div>\n <div\n className=\"text-xs mt-1 font-medium\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {kpi.label}\n </div>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n )}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|