Initial commit - Route Commerce platform
This commit is contained in:
@@ -0,0 +1,690 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import { ReactElement } from "react";
|
||||
|
||||
interface Feature {
|
||||
icon: ReactElement;
|
||||
title: string;
|
||||
description: string;
|
||||
bgColor: string;
|
||||
borderColor: string;
|
||||
hoverBg: string;
|
||||
}
|
||||
|
||||
interface Stat {
|
||||
prefix: string;
|
||||
number: number;
|
||||
suffix: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const features: Feature[] = [
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5z" />
|
||||
<path d="M2 17l10 5 10-5" />
|
||||
<path d="M2 12l10 5 10-5" />
|
||||
</svg>
|
||||
),
|
||||
title: "Product Catalogs",
|
||||
description:
|
||||
"Showcase your seasonal produce with rich media galleries, detailed specs, and real-time availability updates.",
|
||||
bgColor: "#f0f5f1",
|
||||
borderColor: "#6b8f71",
|
||||
hoverBg: "#e8f0e9",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" />
|
||||
</svg>
|
||||
),
|
||||
title: "Route Planning",
|
||||
description:
|
||||
"Optimize delivery routes across your farm network with intelligent mapping and scheduling tools.",
|
||||
bgColor: "#fdf6f0",
|
||||
borderColor: "#c97a3e",
|
||||
hoverBg: "#fbeeda",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M9 11l3 3L22 4" />
|
||||
<path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11" />
|
||||
</svg>
|
||||
),
|
||||
title: "Order Management",
|
||||
description:
|
||||
"Track orders from placement through delivery with automated status updates and seamless integrations.",
|
||||
bgColor: "#f5f0f8",
|
||||
borderColor: "#7a5c9e",
|
||||
hoverBg: "#ece6f5",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M3 3h18v18H3zM21 9H3M9 21V9" />
|
||||
</svg>
|
||||
),
|
||||
title: "Wholesale Portal",
|
||||
description:
|
||||
"Give buyers a dedicated space to browse pricing, request quotes, and place bulk orders on their schedule.",
|
||||
bgColor: "#f0f5f5",
|
||||
borderColor: "#5c8a8f",
|
||||
hoverBg: "#e5f0f2",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
|
||||
<polyline points="22,6 12,13 2,6" />
|
||||
</svg>
|
||||
),
|
||||
title: "Harvest Reach",
|
||||
description:
|
||||
"Send email and SMS campaigns that keep buyers informed about seasonal availability and new harvests.",
|
||||
bgColor: "#faf5f0",
|
||||
borderColor: "#c97a3e",
|
||||
hoverBg: "#f5ebe0",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="18" y1="20" x2="18" y2="10" />
|
||||
<line x1="12" y1="20" x2="12" y2="4" />
|
||||
<line x1="6" y1="20" x2="6" y2="14" />
|
||||
</svg>
|
||||
),
|
||||
title: "Smart Analytics",
|
||||
description:
|
||||
"Uncover sales trends, buyer behavior, and operational insights with real-time dashboards and reports.",
|
||||
bgColor: "#f5f8f0",
|
||||
borderColor: "#6b8f71",
|
||||
hoverBg: "#eaf3e5",
|
||||
},
|
||||
];
|
||||
|
||||
const stats: Stat[] = [
|
||||
{ prefix: "", number: 500, suffix: "+", label: "Produce Brands" },
|
||||
{ prefix: "", number: 50000, suffix: "+", label: "Orders Delivered" },
|
||||
{ prefix: "", number: 98, suffix: "%", label: "On-Time Delivery" },
|
||||
{ prefix: "$", number: 2, suffix: "M+", label: "Weekly Sales" },
|
||||
];
|
||||
|
||||
export default function FeaturesAndStats() {
|
||||
const [countersStarted, setCountersStarted] = useState(false);
|
||||
const [counters, setCounters] = useState(stats.map(() => 0));
|
||||
const statsRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0].isIntersecting && !countersStarted) {
|
||||
setCountersStarted(true);
|
||||
}
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
);
|
||||
|
||||
if (statsRef.current) {
|
||||
observer.observe(statsRef.current);
|
||||
}
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, [countersStarted]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!countersStarted) return;
|
||||
|
||||
const duration = 2000;
|
||||
const steps = 60;
|
||||
const interval = duration / steps;
|
||||
|
||||
let step = 0;
|
||||
const timer = setInterval(() => {
|
||||
step++;
|
||||
const progress = step / steps;
|
||||
|
||||
const easeOut = 1 - Math.pow(1 - progress, 3);
|
||||
|
||||
setCounters(
|
||||
stats.map((stat) => {
|
||||
if (stat.number >= 1000) {
|
||||
return Math.floor(stat.number * easeOut);
|
||||
} else if (stat.number >= 100) {
|
||||
return Math.floor(stat.number * easeOut);
|
||||
} else if (stat.number >= 10) {
|
||||
return Math.floor(stat.number * easeOut);
|
||||
} else {
|
||||
return Math.floor(stat.number * easeOut);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (step >= steps) {
|
||||
clearInterval(timer);
|
||||
setCounters(stats.map((stat) => stat.number));
|
||||
}
|
||||
}, interval);
|
||||
|
||||
return () => clearInterval(timer);
|
||||
}, [countersStarted]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', sans-serif",
|
||||
background: "#faf8f5",
|
||||
color: "#1a1a1a",
|
||||
minHeight: "100vh",
|
||||
}}
|
||||
>
|
||||
<style jsx>{`
|
||||
@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap");
|
||||
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.section-label {
|
||||
font-family: "Plus Jakarta Sans", sans-serif;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.15em;
|
||||
text-transform: uppercase;
|
||||
color: #c97a3e;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-family: "Cormorant Garamond", serif;
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 600;
|
||||
color: #1a4d2e;
|
||||
line-height: 1.15;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-family: "Plus Jakarta Sans", sans-serif;
|
||||
font-size: 1.125rem;
|
||||
color: #4a4a4a;
|
||||
line-height: 1.6;
|
||||
max-width: 540px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
border: 1px solid transparent;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: default;
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
animation: fadeInUp 0.6s ease forwards;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-6px);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 1.25rem;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-card:hover .feature-icon {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-family: "Cormorant Garamond", serif;
|
||||
font-size: 1.375rem;
|
||||
font-weight: 600;
|
||||
color: #1a4d2e;
|
||||
margin-bottom: 0.625rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.feature-description {
|
||||
font-size: 0.9375rem;
|
||||
color: #555;
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.stat-block {
|
||||
text-align: center;
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
animation: fadeInUp 0.5s ease forwards;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-family: "Cormorant Garamond", serif;
|
||||
font-size: clamp(2.5rem, 5vw, 4rem);
|
||||
font-weight: 700;
|
||||
color: #1a4d2e;
|
||||
line-height: 1;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.9375rem;
|
||||
color: #6b8f71;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.stats-divider {
|
||||
width: 1px;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
#c97a3e40,
|
||||
transparent
|
||||
);
|
||||
align-self: stretch;
|
||||
margin: 0.1rem 0;
|
||||
}
|
||||
|
||||
.section-divider {
|
||||
width: 48px;
|
||||
height: 2px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#c97a3e,
|
||||
#1a4d2e
|
||||
);
|
||||
border-radius: 1px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-24px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(24px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-left {
|
||||
animation: slideInLeft 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.animate-right {
|
||||
animation: slideInRight 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.animate-scale {
|
||||
animation: scaleIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.stagger-1 { animation-delay: 0.1s; }
|
||||
.stagger-2 { animation-delay: 0.2s; }
|
||||
.stagger-3 { animation-delay: 0.3s; }
|
||||
.stagger-4 { animation-delay: 0.4s; }
|
||||
.stagger-5 { animation-delay: 0.5s; }
|
||||
.stagger-6 { animation-delay: 0.6s; }
|
||||
|
||||
.stat-stagger-1 { animation-delay: 0.15s; }
|
||||
.stat-stagger-2 { animation-delay: 0.3s; }
|
||||
.stat-stagger-3 { animation-delay: 0.45s; }
|
||||
.stat-stagger-4 { animation-delay: 0.6s; }
|
||||
`}</style>
|
||||
|
||||
{/* ─── FEATURES SECTION ─── */}
|
||||
<section
|
||||
style={{
|
||||
maxWidth: "1200px",
|
||||
margin: "0 auto",
|
||||
padding: "6rem 1.5rem",
|
||||
}}
|
||||
>
|
||||
{/* Header */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
textAlign: "center",
|
||||
marginBottom: "4rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="animate-scale"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<span className="section-label" style={{ marginBottom: "0.75rem" }}>
|
||||
Platform Features
|
||||
</span>
|
||||
<div className="section-divider" style={{ marginBottom: "1.25rem" }} />
|
||||
<h2 className="section-title" style={{ marginBottom: "1rem" }}>
|
||||
Everything You Need
|
||||
</h2>
|
||||
<p
|
||||
className="section-subtitle"
|
||||
style={{
|
||||
maxWidth: "520px",
|
||||
marginBottom: "0",
|
||||
color: "#5a5a5a",
|
||||
fontSize: "1.0625rem",
|
||||
}}
|
||||
>
|
||||
From farm to table, manage your entire produce supply chain in one
|
||||
place.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Feature Cards Grid */}
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))",
|
||||
gap: "1.25rem",
|
||||
}}
|
||||
>
|
||||
{features.map((feature, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`feature-card stagger-${index + 1}`}
|
||||
style={{
|
||||
backgroundColor: feature.bgColor,
|
||||
borderColor: `rgba(${index % 2 === 0 ? "107,143,113" : "201,122,62"}, 0.15)`,
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.backgroundColor = feature.hoverBg;
|
||||
e.currentTarget.style.borderColor = feature.borderColor;
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.backgroundColor = feature.bgColor;
|
||||
e.currentTarget.style.borderColor = `rgba(${
|
||||
index % 2 === 0 ? "107,143,113" : "201,122,62"
|
||||
}, 0.15)`;
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="feature-icon"
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${feature.borderColor}18, ${feature.borderColor}10)`,
|
||||
color: feature.borderColor,
|
||||
border: `1px solid ${feature.borderColor}20`,
|
||||
}}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className="feature-title">{feature.title}</h3>
|
||||
<p className="feature-description">{feature.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── STATS SECTION ─── */}
|
||||
<section
|
||||
ref={statsRef}
|
||||
style={{
|
||||
background: "#1a4d2e",
|
||||
padding: "5rem 1.5rem",
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{/* Subtle background pattern */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
opacity: 0.04,
|
||||
backgroundImage:
|
||||
"radial-gradient(circle at 25% 25%, #faf8f5 1px, transparent 1px), radial-gradient(circle at 75% 75%, #faf8f5 1px, transparent 1px)",
|
||||
backgroundSize: "32px 32px",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Decorative top line */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: "3px",
|
||||
background:
|
||||
"linear-gradient(to right, #c97a3e, #faf8f5, #c97a3e)",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
style={{
|
||||
maxWidth: "1000px",
|
||||
margin: "0 auto",
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
{/* Header */}
|
||||
<div style={{ textAlign: "center", marginBottom: "3.5rem" }}>
|
||||
<span
|
||||
style={{
|
||||
display: "block",
|
||||
fontFamily: "'Plus Jakarta Sans', sans-serif",
|
||||
fontSize: "0.75rem",
|
||||
fontWeight: 600,
|
||||
letterSpacing: "0.15em",
|
||||
textTransform: "uppercase",
|
||||
color: "#c97a3e",
|
||||
marginBottom: "0.75rem",
|
||||
}}
|
||||
>
|
||||
Our Reach
|
||||
</span>
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
fontSize: "clamp(2rem, 4vw, 2.75rem)",
|
||||
fontWeight: 600,
|
||||
color: "#faf8f5",
|
||||
lineHeight: 1.2,
|
||||
margin: "0 0 0.75rem",
|
||||
}}
|
||||
>
|
||||
Growing Together
|
||||
</h2>
|
||||
<div
|
||||
style={{
|
||||
width: "48px",
|
||||
height: "2px",
|
||||
background: "linear-gradient(to right, transparent, #c97a3e, transparent)",
|
||||
borderRadius: "1px",
|
||||
margin: "0 auto",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(4, 1fr)",
|
||||
gap: "1rem",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{stats.map((stat, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`stat-block stat-stagger-${index + 1}`}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
fontSize: "clamp(2.25rem, 4.5vw, 3.75rem)",
|
||||
fontWeight: 700,
|
||||
color: "#faf8f5",
|
||||
lineHeight: 1,
|
||||
marginBottom: "0.5rem",
|
||||
display: "flex",
|
||||
alignItems: "baseline",
|
||||
justifyContent: "center",
|
||||
gap: "0.1em",
|
||||
}}
|
||||
>
|
||||
{stat.prefix && (
|
||||
<span
|
||||
style={{
|
||||
fontSize: "0.55em",
|
||||
fontWeight: 500,
|
||||
color: "#c97a3e",
|
||||
marginRight: "0.05em",
|
||||
}}
|
||||
>
|
||||
{stat.prefix}
|
||||
</span>
|
||||
)}
|
||||
<span>
|
||||
{counters[index].toLocaleString()}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "0.55em",
|
||||
fontWeight: 500,
|
||||
color: "#c97a3e",
|
||||
marginLeft: "0.05em",
|
||||
}}
|
||||
>
|
||||
{stat.suffix}
|
||||
</span>
|
||||
</div>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', sans-serif",
|
||||
fontSize: "0.875rem",
|
||||
fontWeight: 500,
|
||||
color: "#6b8f71",
|
||||
letterSpacing: "0.02em",
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
{stat.label}
|
||||
</p>
|
||||
|
||||
{/* Divider between stats */}
|
||||
{index < stats.length - 1 && (
|
||||
<div
|
||||
style={{
|
||||
display: "none",
|
||||
}}
|
||||
className="stats-divider"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,773 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function HeroSection() {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<style jsx>{`
|
||||
@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600;700&display=swap");
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-40px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInRight {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(40px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse-glow {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(201, 122, 62, 0.4);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 20px 5px rgba(201, 122, 62, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes draw-path {
|
||||
from {
|
||||
stroke-dashoffset: 1000;
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce-down {
|
||||
0%,
|
||||
20%,
|
||||
50%,
|
||||
80%,
|
||||
100% {
|
||||
transform: translateY(0) translateX(-50%);
|
||||
}
|
||||
40% {
|
||||
transform: translateY(-8px) translateX(-50%);
|
||||
}
|
||||
60% {
|
||||
transform: translateY(-4px) translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes badge-enter {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.8) translateY(10px);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05) translateY(-5px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp 0.8s ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animate-fade-in-left {
|
||||
animation: fadeInLeft 0.9s ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animate-fade-in-right {
|
||||
animation: fadeInRight 0.9s ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animate-float {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-delayed {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
animation-delay: -2s;
|
||||
}
|
||||
|
||||
.animate-pulse-glow {
|
||||
animation: pulse-glow 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-bounce-down {
|
||||
animation: bounce-down 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-badge {
|
||||
animation: badge-enter 0.6s ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.path-animate {
|
||||
stroke-dasharray: 1000;
|
||||
animation: draw-path 2.5s ease-out forwards;
|
||||
}
|
||||
|
||||
.delay-100 { animation-delay: 100ms; }
|
||||
.delay-200 { animation-delay: 200ms; }
|
||||
.delay-300 { animation-delay: 300ms; }
|
||||
.delay-400 { animation-delay: 400ms; }
|
||||
.delay-500 { animation-delay: 500ms; }
|
||||
.delay-600 { animation-delay: 600ms; }
|
||||
.delay-700 { animation-delay: 700ms; }
|
||||
.delay-800 { animation-delay: 800ms; }
|
||||
|
||||
.font-display {
|
||||
font-family: "Cormorant Garamond", Georgia, serif;
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#1a4d2e 0%,
|
||||
#6b8f71 25%,
|
||||
#c97a3e 50%,
|
||||
#1a4d2e 75%,
|
||||
#1a4d2e 100%
|
||||
);
|
||||
background-size: 200% auto;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
animation: gradient-shift 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes gradient-shift {
|
||||
0%,
|
||||
100% {
|
||||
background-position: 0% center;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% center;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #1a4d2e 0%, #2d6b42 100%);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-primary::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.2),
|
||||
transparent
|
||||
);
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.btn-primary:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 30px rgba(26, 77, 46, 0.3);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
border: 2px solid #1a4d2e;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #1a4d2e;
|
||||
color: #faf8f5;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.trust-card {
|
||||
backdrop-filter: blur(10px);
|
||||
background: rgba(250, 248, 245, 0.9);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.trust-card:hover {
|
||||
transform: translateY(-5px) scale(1.02);
|
||||
box-shadow: 0 15px 40px rgba(26, 77, 46, 0.15);
|
||||
}
|
||||
`}</style>
|
||||
|
||||
<section
|
||||
className="min-h-screen relative overflow-hidden flex items-center"
|
||||
style={{ backgroundColor: "#faf8f5" }}
|
||||
>
|
||||
{/* Background Pattern - Subtle Grid */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-[0.03]"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(#1a4d2e 1px, transparent 1px),
|
||||
linear-gradient(90deg, #1a4d2e 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: "60px 60px",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Decorative Elements */}
|
||||
<div
|
||||
className="absolute top-20 left-10 w-32 h-32 rounded-full opacity-10"
|
||||
style={{ backgroundColor: "#6b8f71" }}
|
||||
/>
|
||||
<div
|
||||
className="absolute bottom-40 right-20 w-48 h-48 rounded-full opacity-5"
|
||||
style={{ backgroundColor: "#c97a3e" }}
|
||||
/>
|
||||
|
||||
<div className="container mx-auto px-6 lg:px-12 py-20 relative z-10">
|
||||
<div className="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
||||
{/* Left Column - Content */}
|
||||
<div className="space-y-8">
|
||||
{/* Animated Badge */}
|
||||
<div
|
||||
className={`inline-flex items-center gap-3 px-5 py-2.5 rounded-full border animate-badge ${
|
||||
mounted ? "delay-100" : ""
|
||||
}`}
|
||||
style={{
|
||||
borderColor: "#c97a3e",
|
||||
backgroundColor: "rgba(201, 122, 62, 0.08)",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="w-2 h-2 rounded-full animate-pulse"
|
||||
style={{ backgroundColor: "#c97a3e" }}
|
||||
/>
|
||||
<span
|
||||
className="text-sm font-medium tracking-wide"
|
||||
style={{ color: "#c97a3e" }}
|
||||
>
|
||||
Farm-Fresh Delivery Platform
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Main Headline */}
|
||||
<div className={mounted ? "animate-fade-in-up delay-200" : ""}>
|
||||
<h1
|
||||
className="font-display text-5xl sm:text-6xl lg:text-7xl xl:text-8xl font-bold leading-[0.95] tracking-tight"
|
||||
style={{ color: "#1a1a1a" }}
|
||||
>
|
||||
<span className="text-gradient">Harvest</span>
|
||||
<br />
|
||||
<span
|
||||
className="text-gradient"
|
||||
style={{ animationDelay: "0.5s" }}
|
||||
>
|
||||
Fresh Routes
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Subtext */}
|
||||
<p
|
||||
className={`text-lg sm:text-xl max-w-xl leading-relaxed ${
|
||||
mounted ? "animate-fade-in-up" : ""
|
||||
}`}
|
||||
style={{
|
||||
color: "#6b8f71",
|
||||
animationDelay: mounted ? "400ms" : "0ms",
|
||||
}}
|
||||
>
|
||||
We connect produce farms with reliable trucking partners,
|
||||
ensuring your harvest reaches markets faster, fresher, and more
|
||||
efficiently than ever before.
|
||||
</p>
|
||||
|
||||
{/* CTAs */}
|
||||
<div
|
||||
className={`flex flex-wrap gap-4 pt-4 ${mounted ? "animate-fade-in-up" : ""}`}
|
||||
style={{ animationDelay: mounted ? "500ms" : "0ms" }}
|
||||
>
|
||||
<Link
|
||||
href="/login"
|
||||
className="btn-primary inline-flex items-center gap-2 px-8 py-4 rounded-xl font-semibold text-white text-lg shadow-lg"
|
||||
style={{
|
||||
background: "linear-gradient(135deg, rgba(26, 77, 46, 0.95) 0%, rgba(45, 107, 79, 0.95) 100%)",
|
||||
backdropFilter: "blur(10px)",
|
||||
border: "1px solid rgba(255, 255, 255, 0.2)",
|
||||
boxShadow: "0 8px 32px rgba(26, 77, 46, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1)",
|
||||
}}
|
||||
>
|
||||
Start Your Route
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M17 8l4 4m0 0l-4 4m4-4H3" />
|
||||
</svg>
|
||||
</Link>
|
||||
<Link
|
||||
href="/brands"
|
||||
className="btn-secondary inline-flex items-center gap-2 px-8 py-4 rounded-xl font-semibold text-lg"
|
||||
style={{
|
||||
color: "#1a4d2e",
|
||||
background: "rgba(250, 248, 245, 0.8)",
|
||||
backdropFilter: "blur(10px)",
|
||||
border: "1px solid rgba(26, 77, 46, 0.3)",
|
||||
boxShadow: "0 4px 16px rgba(0, 0, 0, 0.08)",
|
||||
}}
|
||||
>
|
||||
Browse Farms
|
||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Trust Indicators */}
|
||||
<div
|
||||
className={`flex flex-wrap gap-6 pt-6 ${
|
||||
mounted ? "animate-fade-in-up" : ""
|
||||
}`}
|
||||
style={{ animationDelay: mounted ? "600ms" : "0ms" }}
|
||||
>
|
||||
{[
|
||||
{ stat: "500+", label: "Farm Brands" },
|
||||
{ stat: "98%", label: "On-Time" },
|
||||
{ stat: "50K+", label: "Deliveries" },
|
||||
].map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="trust-card rounded-2xl p-4 border"
|
||||
style={{ borderColor: "rgba(107, 143, 113, 0.2)" }}
|
||||
>
|
||||
<div
|
||||
className="font-display text-2xl sm:text-3xl font-bold"
|
||||
style={{ color: "#1a4d2e" }}
|
||||
>
|
||||
{item.stat}
|
||||
</div>
|
||||
<div
|
||||
className="text-sm font-medium"
|
||||
style={{ color: "#6b8f71" }}
|
||||
>
|
||||
{item.label}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Column - Visual */}
|
||||
<div
|
||||
className={`relative lg:h-[600px] ${
|
||||
mounted ? "animate-fade-in-right" : ""
|
||||
}`}
|
||||
style={{ animationDelay: mounted ? "300ms" : "0ms" }}
|
||||
>
|
||||
{/* Main Visual Container */}
|
||||
<div className="relative h-full w-full">
|
||||
{/* SVG Map/Routes Visual */}
|
||||
<svg
|
||||
viewBox="0 0 500 500"
|
||||
className="w-full h-full"
|
||||
style={{ maxHeight: "600px" }}
|
||||
>
|
||||
{/* Background Map */}
|
||||
<rect
|
||||
x="50"
|
||||
y="50"
|
||||
width="400"
|
||||
height="400"
|
||||
rx="20"
|
||||
fill="rgba(107, 143, 113, 0.08)"
|
||||
stroke="rgba(107, 143, 113, 0.3)"
|
||||
strokeWidth="1"
|
||||
/>
|
||||
|
||||
{/* Grid Lines */}
|
||||
<g stroke="rgba(107, 143, 113, 0.15)" strokeWidth="0.5">
|
||||
<line x1="50" y1="150" x2="450" y2="150" />
|
||||
<line x1="50" y1="250" x2="450" y2="250" />
|
||||
<line x1="50" y1="350" x2="450" y2="350" />
|
||||
<line x1="150" y1="50" x2="150" y2="450" />
|
||||
<line x1="250" y1="50" x2="250" y2="450" />
|
||||
<line x1="350" y1="50" x2="350" y2="450" />
|
||||
</g>
|
||||
|
||||
{/* Route Path */}
|
||||
<path
|
||||
d="M 100 380 Q 150 350, 180 280 T 250 200 Q 290 150, 350 120 T 400 100"
|
||||
fill="none"
|
||||
stroke="#c97a3e"
|
||||
strokeWidth="4"
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="1000"
|
||||
className="path-animate"
|
||||
style={{ animationDelay: "800ms" }}
|
||||
/>
|
||||
|
||||
{/* Secondary Route */}
|
||||
<path
|
||||
d="M 100 380 Q 200 420, 300 380 T 420 300"
|
||||
fill="none"
|
||||
stroke="#6b8f71"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="round"
|
||||
strokeDasharray="800"
|
||||
className="path-animate"
|
||||
style={{ animationDelay: "1200ms" }}
|
||||
opacity="0.6"
|
||||
/>
|
||||
|
||||
{/* Farm Location */}
|
||||
<g className="animate-fade-in-right" style={{ animationDelay: "1000ms" }}>
|
||||
<circle
|
||||
cx="100"
|
||||
cy="380"
|
||||
r="25"
|
||||
fill="#1a4d2e"
|
||||
opacity="0.2"
|
||||
/>
|
||||
<circle
|
||||
cx="100"
|
||||
cy="380"
|
||||
r="18"
|
||||
fill="#1a4d2e"
|
||||
opacity="0.4"
|
||||
/>
|
||||
<circle cx="100" cy="380" r="10" fill="#1a4d2e" />
|
||||
{/* Farm Icon */}
|
||||
<path
|
||||
d="M 100 372 L 100 388 M 95 377 L 100 372 L 105 377"
|
||||
stroke="#faf8f5"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
<text
|
||||
x="100"
|
||||
y="420"
|
||||
textAnchor="middle"
|
||||
fill="#1a4d2e"
|
||||
fontSize="12"
|
||||
fontWeight="600"
|
||||
>
|
||||
Farm Origin
|
||||
</text>
|
||||
</g>
|
||||
|
||||
{/* Distribution Hub */}
|
||||
<g className="animate-fade-in-up" style={{ animationDelay: "1100ms" }}>
|
||||
<circle
|
||||
cx="250"
|
||||
cy="200"
|
||||
r="30"
|
||||
fill="#c97a3e"
|
||||
opacity="0.2"
|
||||
/>
|
||||
<circle
|
||||
cx="250"
|
||||
cy="200"
|
||||
r="22"
|
||||
fill="#c97a3e"
|
||||
opacity="0.4"
|
||||
/>
|
||||
<circle cx="250" cy="200" r="14" fill="#c97a3e" />
|
||||
{/* Hub Icon */}
|
||||
<rect
|
||||
x="243"
|
||||
y="195"
|
||||
width="14"
|
||||
height="10"
|
||||
fill="#faf8f5"
|
||||
rx="2"
|
||||
/>
|
||||
<text
|
||||
x="250"
|
||||
y="250"
|
||||
textAnchor="middle"
|
||||
fill="#c97a3e"
|
||||
fontSize="12"
|
||||
fontWeight="600"
|
||||
>
|
||||
Distribution Hub
|
||||
</text>
|
||||
</g>
|
||||
|
||||
{/* Stop Points */}
|
||||
{[
|
||||
{ x: 180, y: 280, label: "Stop 1" },
|
||||
{ x: 350, y: 120, label: "Stop 2" },
|
||||
{ x: 400, y: 100, label: "Market" },
|
||||
].map((stop, i) => (
|
||||
<g
|
||||
key={i}
|
||||
className="animate-fade-in-up"
|
||||
style={{ animationDelay: `${1300 + i * 200}ms` }}
|
||||
>
|
||||
<circle
|
||||
cx={stop.x}
|
||||
cy={stop.y}
|
||||
r="12"
|
||||
fill="#faf8f5"
|
||||
stroke="#6b8f71"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<circle
|
||||
cx={stop.x}
|
||||
cy={stop.y}
|
||||
r="6"
|
||||
fill="#6b8f71"
|
||||
/>
|
||||
<text
|
||||
x={stop.x}
|
||||
y={stop.y + 28}
|
||||
textAnchor="middle"
|
||||
fill="#6b8f71"
|
||||
fontSize="10"
|
||||
fontWeight="500"
|
||||
>
|
||||
{stop.label}
|
||||
</text>
|
||||
</g>
|
||||
))}
|
||||
|
||||
{/* Decorative Trees/Fields */}
|
||||
{([[80, 400], [420, 350], [70, 150], [430, 200], [150, 430], [380, 400]] as [number, number][]).map((coords, i) => (
|
||||
<circle
|
||||
key={i}
|
||||
cx={coords[0]}
|
||||
cy={coords[1]}
|
||||
r="8"
|
||||
fill="rgba(107, 143, 113, 0.4)"
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Compass Rose */}
|
||||
<g transform="translate(420, 420)">
|
||||
<circle
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="25"
|
||||
fill="rgba(26, 77, 46, 0.1)"
|
||||
stroke="#1a4d2e"
|
||||
strokeWidth="1"
|
||||
/>
|
||||
<path
|
||||
d="M 0 -18 L 4 0 L 0 4 L -4 0 Z"
|
||||
fill="#c97a3e"
|
||||
/>
|
||||
<path
|
||||
d="M 0 18 L 4 0 L 0 -4 L -4 0 Z"
|
||||
fill="#6b8f71"
|
||||
/>
|
||||
<text
|
||||
x="0"
|
||||
y="-22"
|
||||
textAnchor="middle"
|
||||
fill="#1a4d2e"
|
||||
fontSize="10"
|
||||
fontWeight="600"
|
||||
>
|
||||
N
|
||||
</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
{/* Floating Stat Cards */}
|
||||
<div
|
||||
className={`absolute top-8 -left-4 lg:left-8 animate-float ${
|
||||
mounted ? "" : "opacity-0"
|
||||
}`}
|
||||
style={{ animationDelay: mounted ? "800ms" : "0ms" }}
|
||||
>
|
||||
<div
|
||||
className="animate-pulse-glow rounded-2xl p-4 shadow-xl border"
|
||||
style={{
|
||||
backgroundColor: "#faf8f5",
|
||||
borderColor: "rgba(201, 122, 62, 0.3)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="text-2xl font-bold"
|
||||
style={{ color: "#c97a3e" }}
|
||||
>
|
||||
2.4T
|
||||
</div>
|
||||
<div className="text-sm" style={{ color: "#6b8f71" }}>
|
||||
Miles Saved
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`absolute bottom-16 -right-4 lg:right-12 animate-float-delayed ${
|
||||
mounted ? "" : "opacity-0"
|
||||
}`}
|
||||
style={{ animationDelay: mounted ? "1000ms" : "0ms" }}
|
||||
>
|
||||
<div
|
||||
className="rounded-2xl p-4 shadow-xl border"
|
||||
style={{
|
||||
backgroundColor: "#faf8f5",
|
||||
borderColor: "rgba(26, 77, 46, 0.3)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="text-2xl font-bold"
|
||||
style={{ color: "#1a4d2e" }}
|
||||
>
|
||||
12hrs
|
||||
</div>
|
||||
<div className="text-sm" style={{ color: "#6b8f71" }}>
|
||||
Avg Delivery
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`absolute top-1/2 -right-8 lg:-right-16 animate-float ${
|
||||
mounted ? "" : "opacity-0"
|
||||
}`}
|
||||
style={{ animationDelay: mounted ? "1200ms" : "0ms" }}
|
||||
>
|
||||
<div
|
||||
className="rounded-2xl p-3 shadow-lg border"
|
||||
style={{
|
||||
backgroundColor: "rgba(107, 143, 113, 0.15)",
|
||||
borderColor: "rgba(107, 143, 113, 0.4)",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className="w-3 h-3 rounded-full"
|
||||
style={{ backgroundColor: "#1a4d2e" }}
|
||||
/>
|
||||
<span
|
||||
className="text-sm font-semibold"
|
||||
style={{ color: "#1a4d2e" }}
|
||||
>
|
||||
Live Tracking
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scroll Indicator */}
|
||||
<div
|
||||
className={`absolute bottom-8 left-1/2 transform -translate-x-1/2 cursor-pointer ${
|
||||
mounted ? "animate-bounce-down" : "opacity-0"
|
||||
}`}
|
||||
style={{ animationDelay: mounted ? "1500ms" : "0ms" }}
|
||||
onClick={() =>
|
||||
window.scrollTo({
|
||||
top: window.innerHeight,
|
||||
behavior: "smooth",
|
||||
})
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="flex flex-col items-center gap-2 px-4 py-2 rounded-full"
|
||||
style={{
|
||||
backgroundColor: "rgba(26, 77, 46, 0.1)",
|
||||
border: "1px solid rgba(26, 77, 46, 0.2)",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="text-xs font-medium tracking-wider uppercase"
|
||||
style={{ color: "#1a4d2e" }}
|
||||
>
|
||||
Scroll
|
||||
</span>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#1a4d2e"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M12 5v14M5 12l7 7 7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Decorative Leaf Elements */}
|
||||
<svg
|
||||
className="absolute bottom-20 left-10 opacity-20"
|
||||
width="60"
|
||||
height="60"
|
||||
viewBox="0 0 60 60"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M30 5 C45 15, 50 35, 30 55 C10 35, 15 15, 30 5"
|
||||
fill="#6b8f71"
|
||||
/>
|
||||
<path d="M30 5 L30 55" stroke="#1a4d2e" strokeWidth="2" />
|
||||
</svg>
|
||||
|
||||
<svg
|
||||
className="absolute top-32 right-20 opacity-20"
|
||||
width="40"
|
||||
height="40"
|
||||
viewBox="0 0 40 40"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M20 3 C30 10, 33 23, 20 37 C7 23, 10 10, 20 3"
|
||||
fill="#c97a3e"
|
||||
/>
|
||||
<path d="M20 3 L20 37" stroke="#1a4d2e" strokeWidth="1.5" />
|
||||
</svg>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
|
||||
// ============================================
|
||||
// HEADER COMPONENT
|
||||
// ============================================
|
||||
interface HeaderProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Header({ className = "" }: HeaderProps) {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
const navLinks = [
|
||||
{ label: "Features", href: "#features" },
|
||||
{ label: "Stats", href: "#stats" },
|
||||
{ label: "Reviews", href: "#reviews" },
|
||||
];
|
||||
|
||||
return (
|
||||
<header
|
||||
className={`sticky top-0 z-50 backdrop-blur-md bg-[#faf8f5]/90 border-b border-[#6b8f71]/20 shadow-sm ${className}`}
|
||||
style={{ scrollBehavior: "smooth" }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16 md:h-20">
|
||||
{/* Logo */}
|
||||
<a
|
||||
href="#"
|
||||
className="flex items-center gap-3 group"
|
||||
style={{ textDecoration: "none" }}
|
||||
>
|
||||
<div
|
||||
className="w-10 h-10 rounded-full flex items-center justify-center transition-transform group-hover:scale-105"
|
||||
style={{ backgroundColor: "#1a4d2e" }}
|
||||
>
|
||||
<svg
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M13 2L4.5 13.5H11.5L10.5 22L19 10.5H12L13 2Z"
|
||||
fill="#faf8f5"
|
||||
stroke="#faf8f5"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
className="text-xl font-semibold tracking-tight"
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', Georgia, serif",
|
||||
color: "#1a1a1a",
|
||||
}}
|
||||
>
|
||||
Route Commerce
|
||||
</span>
|
||||
</a>
|
||||
|
||||
{/* Desktop Navigation */}
|
||||
<nav className="hidden md:flex items-center gap-8">
|
||||
{navLinks.map((link) => (
|
||||
<a
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
className="text-sm font-medium transition-colors hover:opacity-70"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
color: "#1a1a1a",
|
||||
}}
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* Desktop CTA */}
|
||||
<div className="hidden md:flex items-center gap-4">
|
||||
<a
|
||||
href="/login"
|
||||
className="text-sm font-medium transition-opacity hover:opacity-70"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
color: "#1a4d2e",
|
||||
}}
|
||||
>
|
||||
Sign In
|
||||
</a>
|
||||
<a
|
||||
href="/admin"
|
||||
className="px-5 py-2.5 rounded-full text-sm font-semibold transition-all hover:opacity-90 active:scale-95"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
background: "rgba(26, 77, 46, 0.9)",
|
||||
backdropFilter: "blur(10px)",
|
||||
WebkitBackdropFilter: "blur(10px)",
|
||||
border: "1px solid rgba(255, 255, 255, 0.2)",
|
||||
color: "#faf8f5",
|
||||
boxShadow: "0 4px 16px rgba(26, 77, 46, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.1)",
|
||||
}}
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
<button
|
||||
className="md:hidden p-2 rounded-lg transition-colors"
|
||||
style={{ backgroundColor: "transparent" }}
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
{mobileMenuOpen ? (
|
||||
<path
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
stroke="#1a1a1a"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
) : (
|
||||
<path
|
||||
d="M4 6h16M4 12h16M4 18h16"
|
||||
stroke="#1a1a1a"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{mobileMenuOpen && (
|
||||
<div
|
||||
className="md:hidden py-4 border-t"
|
||||
style={{
|
||||
borderColor: "#6b8f71/20",
|
||||
backgroundColor: "#faf8f5",
|
||||
}}
|
||||
>
|
||||
<nav className="flex flex-col gap-2">
|
||||
{navLinks.map((link) => (
|
||||
<a
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
className="px-4 py-3 text-base font-medium rounded-lg transition-colors hover:bg-[#6b8f71]/10"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
color: "#1a1a1a",
|
||||
}}
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
))}
|
||||
<div
|
||||
className="flex flex-col gap-2 mt-2 pt-4 px-4"
|
||||
style={{ borderTop: "1px solid #6b8f71/20" }}
|
||||
>
|
||||
<a
|
||||
href="/login"
|
||||
className="py-3 text-base font-medium"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
color: "#1a4d2e",
|
||||
}}
|
||||
>
|
||||
Sign In
|
||||
</a>
|
||||
<a
|
||||
href="/admin"
|
||||
className="py-3 rounded-full text-base font-semibold text-center"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
background: "rgba(26, 77, 46, 0.9)",
|
||||
backdropFilter: "blur(10px)",
|
||||
border: "1px solid rgba(255, 255, 255, 0.2)",
|
||||
color: "#faf8f5",
|
||||
boxShadow: "0 4px 16px rgba(26, 77, 46, 0.2)",
|
||||
}}
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// FOOTER COMPONENT
|
||||
// ============================================
|
||||
interface FooterProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Footer({ className = "" }: FooterProps) {
|
||||
const footerLinks = [
|
||||
{ label: "Privacy", href: "#" },
|
||||
{ label: "Terms", href: "#" },
|
||||
{ label: "Contact", href: "#" },
|
||||
];
|
||||
|
||||
return (
|
||||
<footer
|
||||
className={`w-full py-8 border-t bg-[#faf8f5] ${className}`}
|
||||
style={{ borderColor: "#6b8f71/20" }}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
{/* Logo + Copyright */}
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="w-8 h-8 rounded-full flex items-center justify-center"
|
||||
style={{ backgroundColor: "#1a4d2e" }}
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M13 2L4.5 13.5H11.5L10.5 22L19 10.5H12L13 2Z"
|
||||
fill="#faf8f5"
|
||||
stroke="#faf8f5"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
className="text-sm"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
color: "#1a1a1a",
|
||||
opacity: 0.7,
|
||||
}}
|
||||
>
|
||||
© 2025 Route Commerce. All rights reserved.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Links */}
|
||||
<nav className="flex items-center gap-6">
|
||||
{footerLinks.map((link) => (
|
||||
<a
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
className="text-sm font-medium transition-opacity hover:opacity-70"
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
color: "#6b8f71",
|
||||
}}
|
||||
>
|
||||
{link.label}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// WRAPPER COMPONENT
|
||||
// ============================================
|
||||
interface SectionProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
interface WrapperProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function LandingPageWrapper({ children, className = "" }: WrapperProps) {
|
||||
return (
|
||||
<>
|
||||
{/* Google Fonts Import */}
|
||||
<style jsx global>{`
|
||||
@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap");
|
||||
`}</style>
|
||||
|
||||
<div
|
||||
className={`min-h-screen flex flex-col ${className}`}
|
||||
style={{
|
||||
fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif",
|
||||
scrollBehavior: "smooth",
|
||||
}}
|
||||
>
|
||||
<Header />
|
||||
|
||||
{/* Main Content with Organic Background */}
|
||||
<main
|
||||
className="flex-1 relative overflow-hidden"
|
||||
style={{
|
||||
backgroundColor: "#faf8f5",
|
||||
}}
|
||||
>
|
||||
{/* Decorative organic shapes */}
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute inset-0 overflow-hidden"
|
||||
>
|
||||
{/* Top-right blob */}
|
||||
<div
|
||||
className="absolute -top-32 -right-32 w-96 h-96 rounded-full opacity-30"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(circle at 30% 30%, #c97a3e20 0%, transparent 70%)",
|
||||
filter: "blur(40px)",
|
||||
}}
|
||||
/>
|
||||
{/* Bottom-left blob */}
|
||||
<div
|
||||
className="absolute -bottom-48 -left-48 w-[600px] h-[600px] rounded-full opacity-20"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(circle at 70% 70%, #6b8f7130 0%, transparent 70%)",
|
||||
filter: "blur(60px)",
|
||||
}}
|
||||
/>
|
||||
{/* Center accent blob */}
|
||||
<div
|
||||
className="absolute top-1/3 left-1/4 w-72 h-72 rounded-full opacity-10"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(circle, #1a4d2e15 0%, transparent 70%)",
|
||||
filter: "blur(30px)",
|
||||
}}
|
||||
/>
|
||||
{/* Organic shape 1 - leaf-like */}
|
||||
<svg
|
||||
className="absolute top-20 right-20 w-40 h-40 opacity-10"
|
||||
viewBox="0 0 100 100"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M50 10 C70 30, 80 50, 70 80 C60 95, 40 95, 30 80 C20 50, 30 30, 50 10"
|
||||
fill="#1a4d2e"
|
||||
/>
|
||||
</svg>
|
||||
{/* Organic shape 2 - wavy line */}
|
||||
<svg
|
||||
className="absolute bottom-32 left-10 w-60 h-20 opacity-10"
|
||||
viewBox="0 0 200 40"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M0 20 Q25 0, 50 20 T100 20 T150 20 T200 20"
|
||||
stroke="#6b8f71"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
/>
|
||||
</svg>
|
||||
{/* Organic shape 3 - circle cluster */}
|
||||
<svg
|
||||
className="absolute top-1/2 right-1/4 w-32 h-32 opacity-5"
|
||||
viewBox="0 0 100 100"
|
||||
fill="none"
|
||||
>
|
||||
<circle cx="50" cy="50" r="45" fill="#c97a3e" />
|
||||
<circle cx="35" cy="35" r="25" fill="#1a4d2e" />
|
||||
<circle cx="65" cy="60" r="20" fill="#6b8f71" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Content area */}
|
||||
<div className="relative z-10">{children}</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// UTILITY: Section Wrapper
|
||||
// ============================================
|
||||
export function Section({
|
||||
children,
|
||||
className = "",
|
||||
id,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
id?: string;
|
||||
}) {
|
||||
return (
|
||||
<section id={id} className={`relative z-10 ${className}`}>
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// DEFAULT EXPORT: Complete Landing Page
|
||||
// ============================================
|
||||
export default function LandingPage({
|
||||
children,
|
||||
}: {
|
||||
children?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<LandingPageWrapper>{children}</LandingPageWrapper>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,672 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import Link from "next/link";
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
initials: "TC",
|
||||
name: "Tuxedo Corn Co.",
|
||||
location: "Olathe, Colorado",
|
||||
quote:
|
||||
"Route Commerce transformed how we manage our wholesale operations. Our pickup efficiency increased by 40% in the first month.",
|
||||
},
|
||||
{
|
||||
initials: "IR",
|
||||
name: "Indian River Citrus",
|
||||
location: "Indian River, Florida",
|
||||
quote:
|
||||
"The Harvest Reach feature alone has recovered thousands in abandoned cart revenue. Game changer for our business.",
|
||||
},
|
||||
];
|
||||
|
||||
const containerVariants = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
transition: {
|
||||
staggerChildren: 0.15,
|
||||
delayChildren: 0.1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const itemVariants = {
|
||||
hidden: { opacity: 0, y: 24 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
duration: 0.6,
|
||||
ease: "easeOut" as const,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const cardHoverVariants = {
|
||||
rest: { y: 0, boxShadow: "0 4px 24px rgba(26, 77, 46, 0.08)" },
|
||||
hover: {
|
||||
y: -4,
|
||||
boxShadow: "0 12px 40px rgba(26, 77, 46, 0.12)",
|
||||
transition: { duration: 0.3, ease: "easeOut" },
|
||||
},
|
||||
};
|
||||
|
||||
export default function TestimonialsAndCTA() {
|
||||
return (
|
||||
<>
|
||||
{/* ─── Testimonials Section ─────────────────────────────────────────────── */}
|
||||
<section
|
||||
style={{
|
||||
background: "linear-gradient(180deg, #faf8f5 0%, #f5f2ed 100%)",
|
||||
fontFamily: "'Plus Jakarta Sans', sans-serif",
|
||||
}}
|
||||
>
|
||||
{/* Decorative botanical accent */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "5%",
|
||||
top: "20%",
|
||||
width: "120px",
|
||||
height: "120px",
|
||||
opacity: 0.06,
|
||||
background: "radial-gradient(ellipse at center, #1a4d2e 0%, transparent 70%)",
|
||||
borderRadius: "50%",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
right: "8%",
|
||||
bottom: "15%",
|
||||
width: "80px",
|
||||
height: "80px",
|
||||
opacity: 0.05,
|
||||
background: "radial-gradient(ellipse at center, #c97a3e 0%, transparent 70%)",
|
||||
borderRadius: "50%",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<div className="relative mx-auto max-w-6xl px-6 py-24">
|
||||
{/* Section header */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: "-60px" }}
|
||||
transition={{ duration: 0.7, ease: [0.22, 0.61, 0.36, 1] }}
|
||||
className="mb-16 text-center"
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "8px",
|
||||
fontSize: "0.75rem",
|
||||
fontWeight: 600,
|
||||
letterSpacing: "0.1em",
|
||||
textTransform: "uppercase",
|
||||
color: "#6b8f71",
|
||||
marginBottom: "12px",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5z" />
|
||||
<path d="M2 17l10 5 10-5" />
|
||||
<path d="M2 12l10 5 10-5" />
|
||||
</svg>
|
||||
Testimonials
|
||||
</span>
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
fontSize: "clamp(2.5rem, 5vw, 3.5rem)",
|
||||
fontWeight: 600,
|
||||
lineHeight: 1.1,
|
||||
color: "#1a1a1a",
|
||||
letterSpacing: "-0.02em",
|
||||
}}
|
||||
>
|
||||
Trusted by Farms
|
||||
</h2>
|
||||
<p
|
||||
style={{
|
||||
marginTop: "16px",
|
||||
fontSize: "1.125rem",
|
||||
color: "#555555",
|
||||
maxWidth: "480px",
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
}}
|
||||
>
|
||||
Produce operations across the country rely on Route Commerce to power their farm-fresh distribution.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Testimonial cards */}
|
||||
<motion.div
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, margin: "-40px" }}
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))",
|
||||
gap: "24px",
|
||||
maxWidth: "800px",
|
||||
margin: "0 auto",
|
||||
}}
|
||||
>
|
||||
{testimonials.map((testimonial, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
variants={itemVariants}
|
||||
style={{
|
||||
background: "linear-gradient(145deg, #ffffff 0%, #fdfcfa 100%)",
|
||||
borderRadius: "20px",
|
||||
padding: "32px",
|
||||
border: "1px solid rgba(26, 77, 46, 0.08)",
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
whileHover="hover"
|
||||
initial="rest"
|
||||
animate="rest"
|
||||
>
|
||||
{/* Decorative quote mark */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-8px",
|
||||
right: "20px",
|
||||
fontSize: "80px",
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
color: "rgba(26, 77, 46, 0.06)",
|
||||
lineHeight: 1,
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
>
|
||||
“
|
||||
</div>
|
||||
|
||||
{/* Avatar with gradient */}
|
||||
<div
|
||||
style={{
|
||||
width: "56px",
|
||||
height: "56px",
|
||||
borderRadius: "50%",
|
||||
background: `linear-gradient(135deg, #1a4d2e 0%, #6b8f71 50%, #c97a3e 100%)`,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
marginBottom: "20px",
|
||||
boxShadow: "0 4px 12px rgba(26, 77, 46, 0.15)",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: "#ffffff",
|
||||
fontSize: "1rem",
|
||||
fontWeight: 700,
|
||||
letterSpacing: "0.05em",
|
||||
textShadow: "0 1px 2px rgba(0,0,0,0.1)",
|
||||
}}
|
||||
>
|
||||
{testimonial.initials}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Quote text */}
|
||||
<blockquote
|
||||
style={{
|
||||
fontSize: "1rem",
|
||||
lineHeight: 1.7,
|
||||
color: "#1a1a1a",
|
||||
margin: 0,
|
||||
marginBottom: "20px",
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
“{testimonial.quote}”
|
||||
</blockquote>
|
||||
|
||||
{/* Attribution */}
|
||||
<div style={{ borderTop: "1px solid rgba(0,0,0,0.06)", paddingTop: "16px" }}>
|
||||
<p
|
||||
style={{
|
||||
fontWeight: 700,
|
||||
fontSize: "0.9375rem",
|
||||
color: "#1a1a1a",
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
{testimonial.name}
|
||||
</p>
|
||||
<p
|
||||
style={{
|
||||
fontSize: "0.8125rem",
|
||||
color: "#6b8f71",
|
||||
margin: 0,
|
||||
marginTop: "4px",
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{testimonial.location}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* Trust indicators */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6, delay: 0.3 }}
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: "40px",
|
||||
marginTop: "48px",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
{[
|
||||
{ value: "200+", label: "Farms & Co-ops" },
|
||||
{ value: "40%", label: "Avg. Efficiency Gain" },
|
||||
{ value: "94%", label: "Customer Retention" },
|
||||
].map((stat, i) => (
|
||||
<div key={i} style={{ textAlign: "center" }}>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
fontSize: "2.5rem",
|
||||
fontWeight: 600,
|
||||
color: "#1a4d2e",
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
{stat.value}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "0.8125rem",
|
||||
color: "#6b8f71",
|
||||
marginTop: "6px",
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{stat.label}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── CTA Section ──────────────────────────────────────────────────────── */}
|
||||
<section
|
||||
style={{
|
||||
background: "linear-gradient(180deg, #f5f2ed 0%, #faf8f5 50%, #faf8f5 100%)",
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
fontFamily: "'Plus Jakarta Sans', sans-serif",
|
||||
}}
|
||||
>
|
||||
{/* Decorative gradient orbs */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "10%",
|
||||
left: "10%",
|
||||
width: "300px",
|
||||
height: "300px",
|
||||
background: "radial-gradient(circle, rgba(26, 77, 46, 0.08) 0%, transparent 70%)",
|
||||
borderRadius: "50%",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "0",
|
||||
right: "5%",
|
||||
width: "250px",
|
||||
height: "250px",
|
||||
background: "radial-gradient(circle, rgba(201, 122, 62, 0.06) 0%, transparent 70%)",
|
||||
borderRadius: "50%",
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
{/* Botanical line decoration */}
|
||||
<svg
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "20px",
|
||||
right: "15%",
|
||||
width: "60px",
|
||||
height: "100px",
|
||||
opacity: 0.15,
|
||||
}}
|
||||
viewBox="0 0 60 100"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M30 100 C30 60, 10 50, 30 20 C50 50, 30 60, 30 100"
|
||||
stroke="#1a4d2e"
|
||||
strokeWidth="2"
|
||||
fill="none"
|
||||
/>
|
||||
<path
|
||||
d="M30 70 C20 60, 15 55, 25 45"
|
||||
stroke="#1a4d2e"
|
||||
strokeWidth="1.5"
|
||||
fill="none"
|
||||
/>
|
||||
<path
|
||||
d="M30 70 C40 60, 45 55, 35 45"
|
||||
stroke="#1a4d2e"
|
||||
strokeWidth="1.5"
|
||||
fill="none"
|
||||
/>
|
||||
<circle cx="30" cy="15" r="3" fill="#6b8f71" />
|
||||
<circle cx="22" cy="42" r="2" fill="#c97a3e" />
|
||||
<circle cx="38" cy="42" r="2" fill="#c97a3e" />
|
||||
</svg>
|
||||
|
||||
<div className="relative mx-auto max-w-4xl px-6 py-28 text-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: "-80px" }}
|
||||
transition={{ duration: 0.8, ease: [0.22, 0.61, 0.36, 1] }}
|
||||
>
|
||||
{/* Section label */}
|
||||
<span
|
||||
style={{
|
||||
display: "inline-block",
|
||||
fontSize: "0.75rem",
|
||||
fontWeight: 600,
|
||||
letterSpacing: "0.1em",
|
||||
textTransform: "uppercase",
|
||||
color: "#c97a3e",
|
||||
marginBottom: "16px",
|
||||
padding: "6px 14px",
|
||||
background: "rgba(201, 122, 62, 0.1)",
|
||||
borderRadius: "20px",
|
||||
}}
|
||||
>
|
||||
Get Started Today
|
||||
</span>
|
||||
|
||||
{/* Headline */}
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
fontSize: "clamp(2.75rem, 6vw, 4rem)",
|
||||
fontWeight: 600,
|
||||
lineHeight: 1.1,
|
||||
color: "#1a1a1a",
|
||||
letterSpacing: "-0.02em",
|
||||
marginBottom: "20px",
|
||||
}}
|
||||
>
|
||||
Ready to Grow Your Routes?
|
||||
</h2>
|
||||
|
||||
{/* Subtitle */}
|
||||
<p
|
||||
style={{
|
||||
fontSize: "1.125rem",
|
||||
lineHeight: 1.7,
|
||||
color: "#555555",
|
||||
maxWidth: "560px",
|
||||
margin: "0 auto 36px",
|
||||
}}
|
||||
>
|
||||
Join hundreds of produce brands who trust Route Commerce to power their farm-fresh operations.
|
||||
</p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "16px",
|
||||
justifyContent: "center",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
{/* Primary button */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<Link
|
||||
href="/admin"
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "8px",
|
||||
padding: "16px 32px",
|
||||
background: "rgba(26, 77, 46, 0.9)",
|
||||
backdropFilter: "blur(12px)",
|
||||
WebkitBackdropFilter: "blur(12px)",
|
||||
border: "1px solid rgba(255, 255, 255, 0.25)",
|
||||
color: "#ffffff",
|
||||
fontSize: "1rem",
|
||||
fontWeight: 600,
|
||||
borderRadius: "12px",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
boxShadow: "0 8px 32px rgba(26, 77, 46, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.1)",
|
||||
transition: "all 0.3s ease",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.background = "rgba(45, 107, 79, 0.95)";
|
||||
e.currentTarget.style.boxShadow = "0 12px 40px rgba(26, 77, 46, 0.45), inset 0 1px 0 rgba(255,255,255, 0.2)";
|
||||
e.currentTarget.style.transform = "translateY(-2px)";
|
||||
e.currentTarget.style.borderColor = "rgba(255,255,255, 0.35)";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = "rgba(26, 77, 46, 0.9)";
|
||||
e.currentTarget.style.boxShadow = "0 8px 32px rgba(26, 77, 46, 0.35), inset 0 1px 0 rgba(255,255,255, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.1)";
|
||||
e.currentTarget.style.transform = "translateY(0)";
|
||||
e.currentTarget.style.borderColor = "rgba(255,255,255, 0.25)";
|
||||
}}
|
||||
>
|
||||
Start Free Trial
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M5 12h14" />
|
||||
<path d="m12 5 7 7-7 7" />
|
||||
</svg>
|
||||
</Link>
|
||||
</motion.div>
|
||||
|
||||
{/* Secondary button */}
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<Link
|
||||
href="/brands"
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "8px",
|
||||
padding: "16px 32px",
|
||||
background: "rgba(250, 248, 245, 0.8)",
|
||||
backdropFilter: "blur(12px)",
|
||||
WebkitBackdropFilter: "blur(12px)",
|
||||
border: "1px solid rgba(26, 77, 46, 0.2)",
|
||||
color: "#1a4d2e",
|
||||
fontSize: "1rem",
|
||||
fontWeight: 600,
|
||||
borderRadius: "12px",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
boxShadow: "0 4px 16px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.5)",
|
||||
transition: "all 0.3s ease",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.background = "rgba(255, 255, 255, 0.9)";
|
||||
e.currentTarget.style.borderColor = "rgba(26, 77, 46, 0.4)";
|
||||
e.currentTarget.style.boxShadow = "0 8px 24px rgba(26, 77, 46, 0.12), inset 0 1px 0 rgba(255,255,255, 0.6)";
|
||||
e.currentTarget.style.transform = "translateY(-2px)";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.background = "rgba(250, 248, 245, 0.8)";
|
||||
e.currentTarget.style.borderColor = "rgba(26, 77, 46, 0.2)";
|
||||
e.currentTarget.style.boxShadow = "0 4px 16px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.5)";
|
||||
e.currentTarget.style.transform = "translateY(0)";
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
<polyline points="9 22 9 12 15 12 15 22" />
|
||||
</svg>
|
||||
View Farms
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Disclaimer */}
|
||||
<p
|
||||
style={{
|
||||
marginTop: "24px",
|
||||
fontSize: "0.8125rem",
|
||||
color: "#888888",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
gap: "6px",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
style={{ opacity: 0.6 }}
|
||||
>
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
||||
</svg>
|
||||
No credit card required · 14-day free trial · Cancel anytime
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Bottom decorative element */}
|
||||
<div
|
||||
style={{
|
||||
marginTop: "60px",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: "8px",
|
||||
opacity: 0.3,
|
||||
}}
|
||||
>
|
||||
{[0, 1, 2, 3, 4].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
style={{
|
||||
width: i === 2 ? "24px" : "6px",
|
||||
height: "6px",
|
||||
borderRadius: "3px",
|
||||
background: i === 2 ? "#1a4d2e" : "#1a4d2e",
|
||||
opacity: i === 2 ? 1 : 0.4,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style jsx>{`
|
||||
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap');
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse-soft {
|
||||
0%, 100% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scroll-triggered animations */
|
||||
section {
|
||||
scroll-margin-top: 80px;
|
||||
}
|
||||
|
||||
/* Ensure smooth transitions */
|
||||
a, button {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
`}</style>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user