24 Commits

Author SHA1 Message Date
888e761193 Merge version_15_1779482639185 into main
Merge version_15_1779482639185 into main
2026-05-22 20:45:05 +00:00
kudinDmitriyUp
8ce65992ec Bob AI: Populate src/pages/PricingPage.tsx (snippet builder, 2 sections) 2026-05-22 20:45:01 +00:00
kudinDmitriyUp
0c512c30c7 Bob AI: Add pricing page 2026-05-22 20:44:27 +00:00
487f48c1b0 Merge version_14_1779482132410 into main
Merge version_14_1779482132410 into main
2026-05-22 20:36:23 +00:00
kudinDmitriyUp
cac3617b28 Made the secondary button glassmorphic 2026-05-22 20:36:01 +00:00
b4c885763d Merge version_13_1779481241350 into main
Merge version_13_1779481241350 into main
2026-05-22 20:21:54 +00:00
kudinDmitriyUp
4d32e212af Replaced NavbarDropdown with NavbarFloating to display nav items directly. 2026-05-22 20:21:14 +00:00
c229c65533 Merge version_12_1779480333969 into main
Merge version_12_1779480333969 into main
2026-05-22 20:06:29 +00:00
kudinDmitriyUp
ba281a1663 Fix: Removed duplicate import of AboutFeaturesSplit in HomePage.tsx 2026-05-22 20:05:50 +00:00
e2c79b67de Merge version_11_1779480214878 into main
Merge version_11_1779480214878 into main
2026-05-22 20:04:43 +00:00
kudinDmitriyUp
cc3a538e36 Replaced FeaturesDetailedSteps with AboutFeaturesSplit in services section to reduce scrolling. 2026-05-22 20:04:04 +00:00
431297cfe1 Merge version_10_1779479872529 into main
Merge version_10_1779479872529 into main
2026-05-22 19:59:00 +00:00
kudinDmitriyUp
2bbb019ebb Changed the second section to AboutFeaturesSplit with text on left and image on right. 2026-05-22 19:58:20 +00:00
5ea6e81ae5 Merge version_9_1779479701095 into main
Merge version_9_1779479701095 into main
2026-05-22 19:55:51 +00:00
kudinDmitriyUp
c06cdb8555 Added advanced slide-in text animation to the hero H1 2026-05-22 19:55:28 +00:00
8c95d79eef Merge version_8_1779479631750 into main
Merge version_8_1779479631750 into main
2026-05-22 19:54:15 +00:00
kudinDmitriyUp
972274995a Bob AI: change the gradient for the h1 text to black and green 2026-05-22 19:54:11 +00:00
cdb7b844e1 Merge version_7_1779479536973 into main
Merge version_7_1779479536973 into main
2026-05-22 19:52:42 +00:00
kudinDmitriyUp
ef639e86c2 Bob AI: make the text in gradient and make it thicker on the h1 2026-05-22 19:52:39 +00:00
54a64ccde4 Merge version_6_1779479377409 into main
Merge version_6_1779479377409 into main
2026-05-22 19:50:39 +00:00
kudinDmitriyUp
16184c4cf9 Increased progress bar visibility and smoothed image fade transition 2026-05-22 19:49:59 +00:00
ae41762f34 Merge version_5_1779479259934 into main
Merge version_5_1779479259934 into main
2026-05-22 19:48:57 +00:00
kudinDmitriyUp
b606dc4a03 fix: Correct framer-motion import to motion/react 2026-05-22 19:48:17 +00:00
d83f92ad72 Merge version_4_1779479157047 into main
Merge version_4_1779479157047 into main
2026-05-22 19:46:56 +00:00
7 changed files with 118 additions and 31 deletions

View File

@@ -2,11 +2,13 @@ import { Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import HomePage from './pages/HomePage';
import PricingPage from "@/pages/PricingPage";
export default function App() {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<HomePage />} />
<Route path="/pricing" element={<PricingPage />} />
</Route>
</Routes>
);

View File

@@ -1,5 +1,5 @@
import FooterMinimal from '@/components/sections/footer/FooterMinimal';
import NavbarDropdown from '@/components/ui/NavbarDropdown';
import NavbarFloating from '@/components/ui/NavbarFloating';
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
import SiteBackgroundSlot from "@/components/ui/SiteBackgroundSlot";
import { Facebook, Instagram, Twitter } from "lucide-react";
@@ -35,14 +35,16 @@ export default function Layout() {
{
"name": "Metrics",
"href": "#metrics"
}
},
{ name: "Pricing", href: "/pricing" },
];
return (
<StyleProvider buttonVariant="magnetic" siteBackground="noiseGradient" heroBackground="radialGradient">
<SiteBackgroundSlot />
<SectionErrorBoundary name="navbar">
<NavbarDropdown
<NavbarFloating
logo="GreenScape Pros"
ctaButton={{
text: "Get a Quote",

View File

@@ -3,7 +3,8 @@ import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import AvatarGroup from "@/components/ui/AvatarGroup";
import { useState, useEffect } from "react";
import { useState, useEffect, useRef } from "react";
import { motion } from "motion/react";
type HeroOverlayProps = {
tag: string;
@@ -27,15 +28,36 @@ const HeroOverlay = ({
avatarsLabel,
}: HeroOverlayProps) => {
const [currentImageIndex, setCurrentImageIndex] = useState(0);
const [progress, setProgress] = useState(0);
const intervalRef = useRef<NodeJS.Timeout | null>(null);
const imageDuration = 5000; // 5 seconds
const startProgress = () => {
setProgress(0);
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
intervalRef.current = setInterval(() => {
setProgress((prevProgress) => {
if (prevProgress >= 100) {
setCurrentImageIndex((prevIndex) => (prevIndex + 1) % imageSrcs.length);
return 0;
}
return prevProgress + (100 / (imageDuration / 100)); // Increment based on duration
});
}, 100); // Update every 100ms
};
useEffect(() => {
if (imageSrcs && imageSrcs.length > 1) {
const interval = setInterval(() => {
setCurrentImageIndex((prevIndex) => (prevIndex + 1) % imageSrcs.length);
}, 5000); // Change image every 5 seconds
return () => clearInterval(interval);
startProgress();
}
}, [imageSrcs]);
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
}, [imageSrcs, currentImageIndex]);
const currentImageSrc = imageSrcs ? imageSrcs[currentImageIndex] : undefined;
@@ -48,7 +70,7 @@ const HeroOverlay = ({
{currentImageSrc && (
<ImageOrVideo
imageSrc={currentImageSrc}
className="absolute inset-0 w-full h-full object-cover rounded-none transition-opacity duration-1000 ease-in-out"
className="absolute inset-0 w-full h-full object-cover rounded-none transition-opacity duration-2000 ease-in-out"
/>
)}
{videoSrc && (
@@ -63,6 +85,15 @@ const HeroOverlay = ({
aria-hidden="true"
/>
<div className="absolute bottom-0 left-0 w-full h-2 bg-white/50 z-20">
<motion.div
className="h-full bg-white"
initial={{ width: 0 }}
animate={{ width: `${progress}%` }}
transition={{ duration: 0.1, ease: "linear" }}
/>
</div>
<div className="relative z-10 w-content-width mx-auto pb-10 md:pb-25">
<div className="flex flex-col gap-3 w-full md:w-6/10 lg:w-1/2 xl:w-45/100 2xl:w-4/10">
<div className="w-fit px-3 py-1 mb-1 text-sm card rounded">
@@ -71,10 +102,10 @@ const HeroOverlay = ({
<TextAnimation
text={title}
variant="fade"
variant="slide-in"
gradientText={true}
tag="h1"
className="text-7xl 2xl:text-8xl font-medium text-primary-cta-text text-balance"
className="text-7xl 2xl:text-8xl font-bold text-primary-cta-text text-balance bg-gradient-to-r from-black to-green-500 text-transparent bg-clip-text"
/>
<TextAnimation

View File

@@ -30,7 +30,7 @@ const DefaultButton = ({ text, variant = "primary", href = "#", onClick, animate
<a
href={href}
onClick={handleClick}
className={cls("flex items-center justify-center h-9 px-6 text-sm rounded cursor-pointer", variant === "primary" ? "primary-button text-primary-cta-text" : "secondary-button text-secondary-cta-text", className)}
className={cls("flex items-center justify-center h-9 px-6 text-sm rounded cursor-pointer", variant === "primary" ? "primary-button text-primary-cta-text" : "bg-background/60 backdrop-blur-md border border-border text-secondary-cta-text", className)}
>
{text}
</a>

View File

@@ -1,7 +1,6 @@
import AboutMediaOverlay from '@/components/sections/about/AboutMediaOverlay';
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
import FeaturesDetailedSteps from '@/components/sections/features/FeaturesDetailedSteps';
import AboutFeaturesSplit from '@/components/sections/about/AboutFeaturesSplit';
import HeroOverlay from '@/components/sections/hero/HeroOverlay';
import MetricsGradientCards from '@/components/sections/metrics/MetricsGradientCards';
import ProductMediaCards from '@/components/sections/product/ProductMediaCards';
@@ -56,11 +55,28 @@ export default function HomePage() {
<div id="about" data-section="about">
<SectionErrorBoundary name="about">
<AboutMediaOverlay
<AboutFeaturesSplit
tag="Who We Are"
title="Passion for Green, Precision in Design"
description="At GreenScape Pros, we believe in creating more than just landscapes; we build experiences. With years of expertise and a commitment to quality, our team brings your outdoor dreams to life. From lush gardens to functional patios, we handle every project with meticulous care and innovative solutions. Partner with us for a greener tomorrow."
imageSrc="http://img.b2bpic.net/free-photo/team-multi-ethnic-architects-designing-blueprint-plan_482257-12295.jpg"
items={[
{
icon: "Sparkles",
title: "Innovative Solutions",
description: "We bring fresh ideas and creative designs to every project, ensuring your landscape stands out."
},
{
icon: "Leaf",
title: "Sustainable Practices",
description: "Committed to eco-friendly methods, we create beautiful spaces that are kind to the planet."
},
{
icon: "Heart",
title: "Client-Centric Approach",
description: "Your satisfaction is our priority. We work closely with you to achieve your dream outdoor space."
}
]}
primaryButton={{
text: "Learn More",
href: "#services",
@@ -71,32 +87,27 @@ export default function HomePage() {
<div id="services" data-section="services">
<SectionErrorBoundary name="services">
<FeaturesDetailedSteps
<AboutFeaturesSplit
tag="Our Expertise"
title="Comprehensive Landscaping Services"
description="From initial consultation to ongoing maintenance, we offer a full spectrum of services to keep your property looking its best year-round."
steps={[
imageSrc="http://img.b2bpic.net/free-photo/businessman-using-digital-tools-draft-plan-office-spaces-relocate_482257-90846.jpg"
items={[
{
tag: "Step 1",
icon: "Sparkles",
title: "Consultation & Design",
subtitle: "Your Vision, Our Blueprint",
description: "We start with a thorough understanding of your needs and preferences, translating them into a custom design plan that perfectly suits your space and style.",
imageSrc: "http://img.b2bpic.net/free-photo/businessman-using-digital-tools-draft-plan-office-spaces-relocate_482257-90846.jpg",
description: "We start with a thorough understanding of your needs and preferences, translating them into a custom design plan that perfectly suits your space and style."
},
{
tag: "Step 2",
icon: "Leaf",
title: "Installation & Build",
subtitle: "Bringing Designs to Life",
description: "Our skilled team meticulously executes the approved design, using high-quality materials and proven techniques to ensure lasting beauty and functionality.",
imageSrc: "http://img.b2bpic.net/free-photo/full-shot-happy-friends-outside_23-2149410424.jpg",
description: "Our skilled team meticulously executes the approved design, using high-quality materials and proven techniques to ensure lasting beauty and functionality."
},
{
tag: "Step 3",
icon: "Heart",
title: "Maintenance & Care",
subtitle: "Sustaining the Beauty",
description: "Beyond installation, we provide tailored maintenance programs, from seasonal clean-ups to regular upkeep, ensuring your landscape thrives for years to come.",
imageSrc: "http://img.b2bpic.net/free-photo/caucasian-male-gardener-shaping-overgrown-boxwood-bush-by-hedge-trimmer-garden-front-view_7502-10139.jpg",
},
description: "Beyond installation, we provide tailored maintenance programs, from seasonal clean-ups to regular upkeep, ensuring your landscape thrives for years to come."
}
]}
/>
</SectionErrorBoundary>

40
src/pages/PricingPage.tsx Normal file
View File

@@ -0,0 +1,40 @@
import { Check } from "lucide-react";
import Button from "@/components/ui/Button";
import TextAnimation from "@/components/ui/TextAnimation";
import GridOrCarousel from "@/components/ui/GridOrCarousel";
import ScrollReveal from "@/components/ui/ScrollReveal";
import { Check, X } from "lucide-react";
export default function PricingPage() {
return (
<>
<div data-webild-section="PricingSimpleCards"><section aria-label="Pricing section" className="py-20"><div className="flex flex-col gap-8"><div className="flex flex-col items-center w-content-width mx-auto gap-2"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Our Pricing</p></div><TextAnimation text="Invest in Your Outdoor Sanctuary" variant="fade-blur" gradientText={true} tag="h2" className="text-6xl font-medium text-center text-balance" /><TextAnimation text="Our pricing reflects the dedication, expertise, and sustainable practices we bring to every project, ensuring your outdoor space thrives and enhances your lifestyle. Choose the plan that best fits your vision." variant="fade-blur" gradientText={false} tag="p" className="md:max-w-6/10 text-lg leading-tight text-center" /><div className="flex flex-wrap justify-center gap-3 mt-3"><Button text="Get a Custom Quote" href="/contact" variant="primary" /><Button text="Explore Our Portfolio" href="/portfolio" variant="secondary" animationDelay={0.1} /></div></div><ScrollReveal variant="fade"><GridOrCarousel><div key="Monthly Care" className="flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 h-full card rounded"><span className="px-5 py-2 w-fit text-sm card rounded">Monthly Care</span><div className="flex flex-col gap-1"><span className="text-5xl font-medium">$199/mo</span><span className="text-base">Regular maintenance to keep your garden vibrant and healthy year-round with essential care.</span></div><div className="w-full h-px bg-foreground/20" /><div className="flex flex-col gap-3"><div key="Seasonal Pruning & Trimming" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Seasonal Pruning & Trimming</span></div>
<div key="Basic Lawn & Turf Care" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Basic Lawn & Turf Care</span></div>
<div key="Irrigation System Checks" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Irrigation System Checks</span></div>
<div key="Pest & Disease Monitoring" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Pest & Disease Monitoring</span></div>
<div key="Fertilization & Soil Health" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Fertilization & Soil Health</span></div></div></div>
<div key="Custom Design" className="flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 h-full card rounded"><span className="px-5 py-2 w-fit text-sm card rounded">Custom Design</span><div className="flex flex-col gap-1"><span className="text-5xl font-medium">From $2,500</span><span className="text-base">Transformative design and installation for a personalized outdoor oasis tailored to your dreams.</span></div><div className="w-full h-px bg-foreground/20" /><div className="flex flex-col gap-3"><div key="Initial Site Consultation" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Initial Site Consultation</span></div>
<div key="3D Landscape Design Renderings" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">3D Landscape Design Renderings</span></div>
<div key="Material & Plant Selection Guidance" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Material & Plant Selection Guidance</span></div>
<div key="Project Management & Oversight" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Project Management & Oversight</span></div>
<div key="Sustainable Planting Plan" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Sustainable Planting Plan</span></div>
<div key="Hardscaping Integration" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Hardscaping Integration</span></div></div></div>
<div key="Estate Excellence" className="flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 h-full card rounded"><span className="px-5 py-2 w-fit text-sm card rounded">Estate Excellence</span><div className="flex flex-col gap-1"><span className="text-5xl font-medium">Custom Quote</span><span className="text-base">Comprehensive, bespoke solutions for large estates requiring meticulous care and advanced design.</span></div><div className="w-full h-px bg-foreground/20" /><div className="flex flex-col gap-3"><div key="Master Landscape Planning" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Master Landscape Planning</span></div>
<div key="Advanced Irrigation Systems" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Advanced Irrigation Systems</span></div>
<div key="Specialized Plant & Tree Care" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Specialized Plant & Tree Care</span></div>
<div key="Seasonal Rotations & Updates" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Seasonal Rotations & Updates</span></div>
<div key="Dedicated Project Manager" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Dedicated Project Manager</span></div>
<div key="Smart Landscape Technology" className="flex items-start gap-3"><div className="flex items-center justify-center shrink-0 size-6 primary-button rounded"><Check className="size-3 text-primary-cta-text" strokeWidth={2} /></div><span className="text-base">Smart Landscape Technology</span></div></div></div></GridOrCarousel></ScrollReveal></div></section></div>
<div data-webild-section="FeaturesComparison"><section aria-label="Features comparison section" className="py-20"><div className="flex flex-col gap-8"><div className="flex flex-col items-center w-content-width mx-auto gap-2"><div className="px-3 py-1 mb-1 text-sm card rounded w-fit"><p>Value Comparison</p></div><TextAnimation text="Compare Our Landscape Solutions" variant="slide-up" gradientText={true} tag="h2" className="text-6xl font-medium text-center text-balance" /><TextAnimation text="Our tailored plans offer comprehensive care and design expertise. See how GreenScape delivers exceptional value for your outdoor space, ensuring lasting beauty and functionality." variant="slide-up" gradientText={false} tag="p" className="md:max-w-6/10 text-lg leading-tight text-center" /><div className="flex flex-wrap justify-center gap-3 mt-3"><Button text="Explore Our Plans" href="/pricing#plans" variant="primary" /><Button text="Request a Custom Quote" href="/contact#quote" variant="secondary" animationDelay={0.1} /></div></div><ScrollReveal variant="fade" className="grid grid-cols-1 md:grid-cols-2 w-content-width md:w-6/10 mx-auto gap-5"><div className="flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 card rounded opacity-50"><div key="Limited design revision cycles" className="flex items-center gap-2 text-base"><X className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Limited design revision cycles</span></div>
<div key="Standard material selection" className="flex items-center gap-2 text-base"><X className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Standard material selection</span></div>
<div key="No ongoing maintenance plan" className="flex items-center gap-2 text-base"><X className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">No ongoing maintenance plan</span></div>
<div key="Basic plant warranty" className="flex items-center gap-2 text-base"><X className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Basic plant warranty</span></div>
<div key="Limited post-installation support" className="flex items-center gap-2 text-base"><X className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Limited post-installation support</span></div></div><div className="flex flex-col gap-3 xl:gap-4 2xl:gap-5 p-3 xl:p-4 2xl:p-5 card rounded"><div key="Unlimited design revisions" className="flex items-center gap-2 text-base"><Check className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Unlimited design revisions</span></div>
<div key="Premium & sustainable material sourcing" className="flex items-center gap-2 text-base"><Check className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Premium & sustainable material sourcing</span></div>
<div key="Comprehensive ongoing maintenance" className="flex items-center gap-2 text-base"><Check className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Comprehensive ongoing maintenance</span></div>
<div key="Extended plant and workmanship warranty" className="flex items-center gap-2 text-base"><Check className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Extended plant and workmanship warranty</span></div>
<div key="Dedicated project manager" className="flex items-center gap-2 text-base"><Check className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Dedicated project manager</span></div>
<div key="Priority scheduling and support" className="flex items-center gap-2 text-base"><Check className="shrink-0 h-[1em] w-auto" /><span className="text-base truncate">Priority scheduling and support</span></div></div></ScrollReveal></div></section></div>
</>
);
}

View File

@@ -6,4 +6,5 @@ export interface Route {
export const routes: Route[] = [
{ path: '/', label: 'Home', pageFile: 'HomePage' },
{ path: '/pricing', label: 'Pricing', pageFile: 'PricingPage' },
];