ManiCandles/src/pages/home.tsx

297 lines
10 KiB
TypeScript

import { motion, AnimatePresence } from "framer-motion";
import { useEffect, useState } from "react";
import { Link } from "wouter";
import { Flame, Heart, Leaf, Sparkles } from "lucide-react";
import Box from "@mui/material/Box";
import Container from "@mui/material/Container";
import lavenderImage from "@/assets/images/image-removebg-preview.png";
import roseImage from "@/assets/images/product-rose.png";
import eucalyptusImage from "@/assets/images/product-eucalyptus.png";
import oudImage from "@/assets/images/product-oud.png";
import "./home.css";
const logoPath = "/opengraph.jpg";
const fadeInUp = {
hidden: { opacity: 0, y: 40 },
visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } },
};
const stagger = {
visible: { transition: { staggerChildren: 0.2 } },
};
export default function Home() {
const moods = [
{
title: "Lavender Dreams",
subtitle: "Calm your mind. Light your sanctuary.",
glow: "#7B3DB8",
},
{
title: "Rose & Vanilla",
subtitle: "Romance captured in every flame.",
glow: "#D67896",
},
{
title: "Eucalyptus Mint",
subtitle: "Freshness inspired by nature.",
glow: "#7DDCB4",
},
{
title: "Oud & Amber",
subtitle: "Luxury crafted into fragrance.",
glow: "#FFB446",
},
];
const [activeMood, setActiveMood] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setActiveMood((prev) => (prev + 1) % moods.length);
}, 8000);
return () => clearInterval(interval);
}, []);
return (
<Box>
{/* ── Hero ── */}
<section className="arrival-hero">
<div className="arrival-bg" />
<div className="fog fog-1" />
<div className="fog fog-2" />
<div className="fog fog-3" />
<div className="embers">
{[...Array(18)].map((_, i) => (
<span
key={i}
style={{
left: `${5 + Math.random() * 90}%`,
animationDelay: `${Math.random() * 8}s`,
}}
/>
))}
</div>
<Container maxWidth="xl">
<div className="arrival-content">
<motion.div
className="arrival-copy"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1.5 }}
>
<motion.img
src={logoPath}
alt="Mani Candles"
className="arrival-logo"
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5, duration: 1 }}
/>
<AnimatePresence mode="wait">
<motion.div
key={activeMood}
initial={{
opacity: 0,
filter: "blur(12px)",
y: 20,
}}
animate={{
opacity: 1,
filter: "blur(0px)",
y: 0,
}}
exit={{
opacity: 0,
filter: "blur(12px)",
y: -20,
}}
transition={{
duration: 1.2,
}}
>
<h1>{moods[activeMood].title}</h1>
<h2>
Light a Moment.
Create a Memory.
</h2>
<p>{moods[activeMood].subtitle}</p>
</motion.div>
</AnimatePresence>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 2.8 }}
>
<Link
href="/products"
className="arrival-btn"
>
Explore Collection
</Link>
</motion.div>
</motion.div>
<motion.div
className="arrival-candle-wrap"
animate={{
y: [0, -18, 0]
}}
transition={{
duration: 7,
repeat: Infinity,
ease: "easeInOut"
}}
>
<motion.div
className="arrival-glow"
animate={{
backgroundColor: moods[activeMood].glow,
}}
transition={{
duration: 3,
ease: "easeInOut",
}}
/>
<motion.img
src={lavenderImage}
alt="Luxury Candle"
className="arrival-candle"
initial={{
opacity: 0,
scale: 0.9,
filter: "blur(15px)"
}}
animate={{
opacity: 1,
scale: 1,
filter: "blur(0px)"
}}
transition={{
duration: 2.5,
delay: 1
}}
/>
</motion.div>
</div>
</Container>
<div className="scroll-indicator">
Scroll
</div>
</section>
{/* ── Philosophy ── */}
<section className="home-philosophy">
<Container maxWidth="lg">
<motion.div initial="hidden" whileInView="visible" viewport={{ once: true, margin: "-100px" }} variants={stagger}>
<motion.h2 variants={fadeInUp}>The Mani Philosophy</motion.h2>
<div className="section-divider" />
</motion.div>
<div className="philosophy-grid">
{[
{ Icon: Leaf, title: "Natural", desc: "Crafted with pure soy wax and essential oils. Clean burns that respect your home and our earth." },
{ Icon: Sparkles, title: "Handmade", desc: "Poured by hand in small batches to ensure unparalleled quality and attention to detail." },
{ Icon: Heart, title: "Heartmade", desc: "Every candle is infused with love and intention, designed to bring warmth to your sacred spaces." },
].map(({ Icon, title, desc }, i) => (
<motion.div
key={title}
className="philosophy-card"
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={{ hidden: { opacity: 0, y: 30 }, visible: { opacity: 1, y: 0, transition: { delay: i * 0.2, duration: 0.6 } } }}
>
<div className="philosophy-icon-wrap"><Icon size={32} /></div>
<h3>{title}</h3>
<p>{desc}</p>
</motion.div>
))}
</div>
</Container>
</section>
{/* ── Featured Products ── */}
<section className="home-products">
<Container maxWidth="xl">
<motion.div initial="hidden" whileInView="visible" viewport={{ once: true }} variants={fadeInUp} className="home-products-header">
<div>
<h2>Curated Favorites</h2>
<div className="section-divider" style={{ margin: "0.5rem 0 0", width: 80 }} />
</div>
<Link href="/products" className="view-all-link">View All Candles</Link>
</motion.div>
<div className="product-grid">
{[
{ id: 1, name: "Lavender Dream", image: lavenderImage, price: "$28" },
{ id: 2, name: "Rose & Vanilla", image: roseImage, price: "$32" },
{ id: 3, name: "Eucalyptus Mint", image: eucalyptusImage, price: "$28" },
{ id: 4, name: "Oud & Amber", image: oudImage, price: "$36" },
].map((product, i) => (
<motion.div
key={product.id}
className="product-card"
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={{ hidden: { opacity: 0, y: 20 }, visible: { opacity: 1, y: 0, transition: { delay: i * 0.1, duration: 0.6 } } }}
>
<div className="product-img-wrap">
<img src={product.image} alt={product.name} />
<div className="product-overlay">
<button className="product-overlay-btn">Quick Add</button>
</div>
</div>
<h3 className="product-name">{product.name}</h3>
<p className="product-price">{product.price}</p>
</motion.div>
))}
</div>
</Container>
</section>
{/* ── Quote ── */}
<section className="home-quote">
<div className="home-quote-texture" />
<motion.div initial="hidden" whileInView="visible" viewport={{ once: true }} variants={fadeInUp}>
<Flame className="animate-flame" size={48} style={{ color: "var(--brand-gold)", margin: "0 auto 1.5rem", display: "block" }} />
<blockquote>
"A candle loses nothing by lighting another candle. It only makes the room warmer, brighter, and more beautiful."
</blockquote>
<div className="home-quote-divider" />
</motion.div>
</section>
{/* ── Newsletter ── */}
<section className="home-newsletter">
<motion.div initial="hidden" whileInView="visible" viewport={{ once: true }} variants={fadeInUp}>
<h2>Join Our Sanctuary</h2>
<p>Subscribe to receive gentle updates on new collections, exclusive access, and a little light in your inbox.</p>
<form className="newsletter-form" onSubmit={(e) => e.preventDefault()}>
<input type="email" className="newsletter-input" placeholder="Your email address" required />
<button type="submit" className="newsletter-btn">Subscribe</button>
</form>
</motion.div>
</section>
</Box>
);
}