|
|
|
|
@@ -1,30 +1,35 @@
|
|
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { useParams } from "next/navigation";
|
|
|
|
|
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
|
|
|
|
import NavbarStyleFullscreen from '@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen';
|
|
|
|
|
import FooterSimple from '@/components/sections/footer/FooterSimple';
|
|
|
|
|
import { useState, useMemo, useEffect } from 'react';
|
|
|
|
|
import Link from 'next/link';
|
|
|
|
|
import { useParams } from 'next/navigation';
|
|
|
|
|
import { useEffect, useState, useMemo } from 'react';
|
|
|
|
|
|
|
|
|
|
const products = [
|
|
|
|
|
const PRODUCTS = [
|
|
|
|
|
{
|
|
|
|
|
id: "perfume-1", name: "Midnight Blossom", price: "$185", variant: "100ml • Floral • 3 Scent Notes", imageSrc: "http://img.b2bpic.net/free-photo/closeup-shot-beautifully-shaped-glass-bottles-filled-with-perfume_181624-28370.jpg?_wi=2", imageAlt: "Midnight Blossom Fragrance", description: "A captivating floral fragrance that combines the essence of midnight jasmine with subtle notes of moonflower. This exquisite blend creates an aura of mystery and elegance, perfect for evening occasions."
|
|
|
|
|
id: "perfume-1", name: "Midnight Blossom", price: "$185", variant: "100ml • Floral • 3 Scent Notes", imageSrc: "http://img.b2bpic.net/free-photo/closeup-shot-beautifully-shaped-glass-bottles-filled-with-perfume_181624-28370.jpg?_wi=2", imageAlt: "Midnight Blossom Fragrance", description: "A delicate blend of jasmine, rose, and violet that captures the essence of an evening garden in full bloom. Perfect for those who appreciate floral elegance.", notes: ["Top: Bergamot, Lemon", "Heart: Jasmine, Rose, Violet", "Base: Sandalwood, Musk"],
|
|
|
|
|
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "perfume-2", name: "Crystal Noir", price: "$210", variant: "100ml • Oriental • Premium Edition", imageSrc: "http://img.b2bpic.net/free-photo/close-up-variety-cosmetic-products-desk-isolated_574295-5284.jpg?_wi=2", imageAlt: "Crystal Noir Fragrance", description: "A luxurious oriental fragrance with deep amber and exotic spices. The premium edition features notes of oud, vanilla, and sandalwood, creating an intoxicating and sophisticated scent."
|
|
|
|
|
id: "perfume-2", name: "Crystal Noir", price: "$210", variant: "100ml • Oriental • Premium Edition", imageSrc: "http://img.b2bpic.net/free-photo/close-up-variety-cosmetic-products-desk-isolated_574295-5284.jpg?_wi=2", imageAlt: "Crystal Noir Fragrance", description: "An intoxicating oriental fragrance featuring rich amber, exotic spices, and precious woods. A bold statement for those who dare to be different.", notes: ["Top: Black Pepper, Saffron", "Heart: Amber, Oud, Cinnamon", "Base: Cedarwood, Patchouli, Vanilla"],
|
|
|
|
|
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "perfume-3", name: "Amber Essence", price: "$165", variant: "75ml • Woody • Signature Collection", imageSrc: "http://img.b2bpic.net/free-photo/ecofriendly-beauty-product_23-2150669115.jpg?_wi=2", imageAlt: "Amber Essence Fragrance", description: "A warm and woody composition from our signature collection. Featuring cedarwood and amber with hints of vanilla, this fragrance is timeless, versatile, and perfect for everyday wear."
|
|
|
|
|
id: "perfume-3", name: "Amber Essence", price: "$165", variant: "75ml • Woody • Signature Collection", imageSrc: "http://img.b2bpic.net/free-photo/ecofriendly-beauty-product_23-2150669115.jpg?_wi=2", imageAlt: "Amber Essence Fragrance", description: "Warm and enveloping, this woody fragrance celebrates the depth of amber and exotic woods. A timeless signature for the sophisticated.", notes: ["Top: Ginger, Apple", "Heart: Amber, Cedarwood", "Base: Sandalwood, Vetiver, Tonka Bean"],
|
|
|
|
|
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "perfume-4", name: "Rose Garden", price: "$195", variant: "100ml • Fruity Floral • Limited Release", imageSrc: "http://img.b2bpic.net/free-photo/containers-liquid-soap-shampoo-with-dispenser-is-sold-supermarket_169016-50305.jpg?_wi=3", imageAlt: "Rose Garden Fragrance", description: "A beautiful fruity floral from our limited release collection. Fresh rose petals blend with juicy berry notes, creating a romantic and vibrant fragrance for spring and summer."
|
|
|
|
|
id: "perfume-4", name: "Rose Garden", price: "$195", variant: "100ml • Fruity Floral • Limited Release", imageSrc: "http://img.b2bpic.net/free-photo/containers-liquid-soap-shampoo-with-dispenser-is-sold-supermarket_169016-50305.jpg?_wi=3", imageAlt: "Rose Garden Fragrance", description: "A romantic fruity-floral composition centered around Damascus rose, complemented by juicy fruits. Celebrates the beauty of a perfect garden.", notes: ["Top: Peach, Blackcurrant", "Heart: Damascus Rose, Peonies", "Base: Musk, Amber"],
|
|
|
|
|
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "perfume-5", name: "Ocean Wave", price: "$175", variant: "100ml • Fresh Citrus • Summer Collection", imageSrc: "http://img.b2bpic.net/free-photo/containers-liquid-soap-shampoo-with-dispenser-is-sold-supermarket_169016-50305.jpg?_wi=4", imageAlt: "Ocean Wave Fragrance", description: "A refreshing citrus fragrance inspired by ocean breezes. With notes of lemon, bergamot, and sea salt, this summer collection favorite brings the essence of coastal freshness to your day."
|
|
|
|
|
id: "perfume-5", name: "Ocean Wave", price: "$175", variant: "100ml • Fresh Citrus • Summer Collection", imageSrc: "http://img.b2bpic.net/free-photo/containers-liquid-soap-shampoo-with-dispenser-is-sold-supermarket_169016-50305.jpg?_wi=4", imageAlt: "Ocean Wave Fragrance", description: "A refreshing citrus fragrance that evokes the freshness of sea spray and sun-kissed shores. Perfect for summer and everyday wear.", notes: ["Top: Lemon, Orange, Yuzu", "Heart: Sea Salt, Aquatic Accord", "Base: Driftwood, White Cedar"],
|
|
|
|
|
concentration: "Eau de Toilette (EDT) - 5-15% fragrance concentration"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: "perfume-6", name: "Vanilla Luxe", price: "$200", variant: "100ml • Gourmand • Exclusive Blend", imageSrc: "http://img.b2bpic.net/free-photo/elegant-vegan-alcohol-arrangement_23-2149337695.jpg?_wi=2", imageAlt: "Vanilla Luxe Fragrance", description: "An exclusive gourmand blend with creamy vanilla and caramel notes. Perfect for those who love indulgent fragrances with a touch of sweetness and sophistication."
|
|
|
|
|
id: "perfume-6", name: "Vanilla Luxe", price: "$200", variant: "100ml • Gourmand • Exclusive Blend", imageSrc: "http://img.b2bpic.net/free-photo/elegant-vegan-alcohol-arrangement_23-2149337695.jpg?_wi=2", imageAlt: "Vanilla Luxe Fragrance", description: "An indulgent gourmand fragrance with creamy vanilla, caramel, and exotic spices. A sensual and comforting second skin.", notes: ["Top: Cardamom, Cinnamon", "Heart: Madagascar Vanilla, Caramel", "Base: Sandalwood, Amber, Tonka Bean"],
|
|
|
|
|
concentration: "Eau de Parfum (EDP) - 15-20% fragrance concentration"
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
@@ -32,16 +37,11 @@ export default function ProductDetailPage() {
|
|
|
|
|
const params = useParams();
|
|
|
|
|
const productId = params?.id as string;
|
|
|
|
|
const [showAnimation, setShowAnimation] = useState(true);
|
|
|
|
|
const [infoRevealed, setInfoRevealed] = useState(false);
|
|
|
|
|
const [product, setProduct] = useState<typeof products[0] | null>(null);
|
|
|
|
|
const [animationPhase, setAnimationPhase] = useState<'rotate' | 'spray' | 'reveal'>('rotate');
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const foundProduct = products.find(p => p.id === productId);
|
|
|
|
|
if (foundProduct) {
|
|
|
|
|
setProduct(foundProduct);
|
|
|
|
|
}
|
|
|
|
|
}, [productId]);
|
|
|
|
|
const product = PRODUCTS.find(p => p.id === productId);
|
|
|
|
|
|
|
|
|
|
// Generate particle animations with stable values
|
|
|
|
|
const particleAnimations = useMemo(() => {
|
|
|
|
|
return Array.from({ length: 12 }).map((_, i) => ({
|
|
|
|
|
id: i,
|
|
|
|
|
@@ -53,23 +53,26 @@ export default function ProductDetailPage() {
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const rotationDuration = 2000;
|
|
|
|
|
const revealDelay = 1200;
|
|
|
|
|
const sprayDuration = 2000;
|
|
|
|
|
if (!showAnimation) return;
|
|
|
|
|
|
|
|
|
|
const rotateTimer = setTimeout(() => {
|
|
|
|
|
setAnimationPhase('spray');
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
const animationTimer = setTimeout(() => {
|
|
|
|
|
const sprayTimer = setTimeout(() => {
|
|
|
|
|
setAnimationPhase('reveal');
|
|
|
|
|
}, 2000);
|
|
|
|
|
|
|
|
|
|
const finishTimer = setTimeout(() => {
|
|
|
|
|
setShowAnimation(false);
|
|
|
|
|
}, sprayDuration + rotationDuration);
|
|
|
|
|
|
|
|
|
|
const infoTimer = setTimeout(() => {
|
|
|
|
|
setInfoRevealed(true);
|
|
|
|
|
}, revealDelay + rotationDuration);
|
|
|
|
|
}, 3500);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
clearTimeout(animationTimer);
|
|
|
|
|
clearTimeout(infoTimer);
|
|
|
|
|
clearTimeout(rotateTimer);
|
|
|
|
|
clearTimeout(sprayTimer);
|
|
|
|
|
clearTimeout(finishTimer);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
}, [showAnimation]);
|
|
|
|
|
|
|
|
|
|
if (!product) {
|
|
|
|
|
return (
|
|
|
|
|
@@ -99,22 +102,14 @@ export default function ProductDetailPage() {
|
|
|
|
|
bottomRightText="hello@essenceaura.com"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex items-center justify-center min-h-[60vh]">
|
|
|
|
|
<p className="text-xl">Product not found. <Link href="/" className="text-blue-600 underline">Return home</Link></p>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="footer" data-section="footer">
|
|
|
|
|
<FooterSimple
|
|
|
|
|
columns={[
|
|
|
|
|
{
|
|
|
|
|
title: "Navigate", items: [
|
|
|
|
|
{ label: "Home", href: "/" },
|
|
|
|
|
{ label: "Shop", href: "#products" }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]}
|
|
|
|
|
bottomLeftText="© 2025 Essence & Aura. All rights reserved."
|
|
|
|
|
bottomRightText="Crafted with luxury and passion"
|
|
|
|
|
/>
|
|
|
|
|
<div className="min-h-screen flex items-center justify-center">
|
|
|
|
|
<div className="text-center">
|
|
|
|
|
<h1 className="text-4xl font-bold mb-4">Product Not Found</h1>
|
|
|
|
|
<p className="text-lg mb-8">Sorry, we couldn't find the product you're looking for.</p>
|
|
|
|
|
<Link href="/" className="text-primary-cta underline">
|
|
|
|
|
Return to Home
|
|
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</ThemeProvider>
|
|
|
|
|
);
|
|
|
|
|
@@ -148,204 +143,168 @@ export default function ProductDetailPage() {
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="relative pt-32 pb-20 px-6 md:px-12 min-h-screen flex items-center justify-center">
|
|
|
|
|
{showAnimation && (
|
|
|
|
|
<div className="absolute inset-0 pointer-events-none z-50 flex items-center justify-center pt-32">
|
|
|
|
|
<div className="relative w-80 h-80 md:w-96 md:h-96">
|
|
|
|
|
{/* Product rotates leftward */}
|
|
|
|
|
<div
|
|
|
|
|
className="absolute inset-0 will-change-transform"
|
|
|
|
|
style={{
|
|
|
|
|
animation: `rotateLeftThenRight 3s ease-in-out forwards`,
|
|
|
|
|
transformOrigin: 'center',
|
|
|
|
|
transformStyle: 'preserve-3d',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
src={product.imageSrc}
|
|
|
|
|
alt={product.imageAlt}
|
|
|
|
|
className="w-full h-full object-cover rounded-lg"
|
|
|
|
|
/>
|
|
|
|
|
<div className="min-h-screen pt-32 pb-20 px-4">
|
|
|
|
|
<div className="max-w-6xl mx-auto">
|
|
|
|
|
<Link href="/" className="text-primary-cta underline mb-8 inline-block">
|
|
|
|
|
← Back to Shop
|
|
|
|
|
</Link>
|
|
|
|
|
|
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-start">
|
|
|
|
|
{/* Product Image Section with Animation */}
|
|
|
|
|
<div className="relative h-96 lg:h-auto lg:aspect-square">
|
|
|
|
|
{showAnimation && (
|
|
|
|
|
<div className="absolute inset-0 pointer-events-none flex items-center justify-center z-50">
|
|
|
|
|
<div className="relative w-80 h-80">
|
|
|
|
|
{/* Product rotates leftward */}
|
|
|
|
|
<div
|
|
|
|
|
className="absolute inset-0"
|
|
|
|
|
style={{
|
|
|
|
|
animation: animationPhase === 'rotate' ? 'rotateLeftAnimation 1s ease-in-out forwards' : 'none',
|
|
|
|
|
transformOrigin: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
src={product.imageSrc}
|
|
|
|
|
alt={product.imageAlt}
|
|
|
|
|
className="w-full h-full object-cover rounded-lg"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Spray particles animation */}
|
|
|
|
|
{animationPhase !== 'rotate' && (
|
|
|
|
|
<div className="absolute inset-0 overflow-hidden rounded-lg">
|
|
|
|
|
{particleAnimations.map((particle) => (
|
|
|
|
|
<div
|
|
|
|
|
key={particle.id}
|
|
|
|
|
className="absolute w-2 h-2 bg-gradient-to-b from-white to-transparent rounded-full"
|
|
|
|
|
style={{
|
|
|
|
|
left: `${particle.left}%`,
|
|
|
|
|
top: `-10px`,
|
|
|
|
|
animation: `fall ${particle.duration}s ease-out forwards`,
|
|
|
|
|
animationDelay: `${particle.delay}s`,
|
|
|
|
|
opacity: animationPhase === 'spray' ? 0.7 : 0,
|
|
|
|
|
transition: 'opacity 0.3s ease-out',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Product information reveal overlay */}
|
|
|
|
|
{animationPhase === 'reveal' && (
|
|
|
|
|
<div
|
|
|
|
|
className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent rounded-lg flex flex-col justify-end p-6 text-white"
|
|
|
|
|
style={{
|
|
|
|
|
animation: 'fadeIn 0.6s ease-in forwards',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div className="animate-fadeInUp">
|
|
|
|
|
<h3 className="text-3xl font-bold mb-2">{product.name}</h3>
|
|
|
|
|
<p className="text-sm mb-2 opacity-90">{product.variant}</p>
|
|
|
|
|
<p className="text-2xl font-semibold">{product.price}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<style>{`
|
|
|
|
|
@keyframes rotateLeftAnimation {
|
|
|
|
|
from {
|
|
|
|
|
transform: perspective(1000px) rotateY(0deg);
|
|
|
|
|
}
|
|
|
|
|
to {
|
|
|
|
|
transform: perspective(1000px) rotateY(-30deg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@keyframes fall {
|
|
|
|
|
to {
|
|
|
|
|
transform: translateY(120px) translateX(var(--xOffset, 0px));
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@keyframes fadeIn {
|
|
|
|
|
from { opacity: 0; }
|
|
|
|
|
to { opacity: 1; }
|
|
|
|
|
}
|
|
|
|
|
@keyframes fadeInUp {
|
|
|
|
|
from {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transform: translateY(20px);
|
|
|
|
|
}
|
|
|
|
|
to {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.animate-fadeInUp {
|
|
|
|
|
animation: fadeInUp 0.8s ease-out forwards;
|
|
|
|
|
}
|
|
|
|
|
`}</style>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{!showAnimation && (
|
|
|
|
|
<div className="w-full h-full rounded-lg overflow-hidden shadow-lg">
|
|
|
|
|
<img
|
|
|
|
|
src={product.imageSrc}
|
|
|
|
|
alt={product.imageAlt}
|
|
|
|
|
className="w-full h-full object-cover"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Product Information Section */}
|
|
|
|
|
<div className={`transition-opacity duration-500 ${showAnimation && animationPhase !== 'reveal' ? 'opacity-0' : 'opacity-100'}`}>
|
|
|
|
|
<h1 className="text-5xl font-bold mb-2">{product.name}</h1>
|
|
|
|
|
<p className="text-lg text-foreground/70 mb-6">{product.variant}</p>
|
|
|
|
|
<p className="text-4xl font-bold text-primary-cta mb-8">{product.price}</p>
|
|
|
|
|
|
|
|
|
|
<div className="mb-8">
|
|
|
|
|
<p className="text-lg leading-relaxed mb-6">{product.description}</p>
|
|
|
|
|
<p className="text-sm text-foreground/60 italic">{product.concentration}</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Spray particles animation */}
|
|
|
|
|
<div className="absolute inset-0 overflow-hidden rounded-lg">
|
|
|
|
|
{particleAnimations.map((particle) => (
|
|
|
|
|
<div
|
|
|
|
|
key={particle.id}
|
|
|
|
|
className="absolute w-2 h-2 bg-gradient-to-b from-white to-transparent rounded-full pointer-events-none"
|
|
|
|
|
style={{
|
|
|
|
|
left: `${particle.left}%`,
|
|
|
|
|
top: `-10px`,
|
|
|
|
|
animation: `fall ${particle.duration}s ease-out forwards`,
|
|
|
|
|
animationDelay: `${0.8 + particle.delay}s`,
|
|
|
|
|
opacity: 0.7,
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
<div className="mb-8">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-4">Fragrance Notes</h3>
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
{product.notes.map((note, idx) => (
|
|
|
|
|
<div key={idx} className="flex items-start gap-3">
|
|
|
|
|
<div className="w-2 h-2 rounded-full bg-primary-cta mt-2 flex-shrink-0" />
|
|
|
|
|
<p className="text-foreground/80">{note}</p>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setShowAnimation(true)}
|
|
|
|
|
className="w-full bg-primary-cta text-primary-cta-text font-semibold py-3 px-6 rounded-lg hover:opacity-90 transition-opacity mb-4"
|
|
|
|
|
>
|
|
|
|
|
Add to Cart
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => window.open('/', '_self')}
|
|
|
|
|
className="w-full bg-secondary-cta text-secondary-cta-text font-semibold py-3 px-6 rounded-lg hover:opacity-90 transition-opacity border border-foreground/20"
|
|
|
|
|
>
|
|
|
|
|
Continue Shopping
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<div className="mt-8 pt-8 border-t border-foreground/10">
|
|
|
|
|
<h3 className="text-sm font-semibold mb-4">Why Choose This Fragrance?</h3>
|
|
|
|
|
<ul className="space-y-2 text-sm text-foreground/70">
|
|
|
|
|
<li>✓ Sourced from master perfumers worldwide</li>
|
|
|
|
|
<li>✓ 100% authentic luxury fragrance</li>
|
|
|
|
|
<li>✓ Premium quality guaranteed</li>
|
|
|
|
|
<li>✓ 30-day satisfaction guarantee</li>
|
|
|
|
|
<li>✓ Complimentary gift wrapping available</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Product details section */}
|
|
|
|
|
<div className="relative w-full max-w-2xl">
|
|
|
|
|
{infoRevealed && (
|
|
|
|
|
<div
|
|
|
|
|
className="space-y-6 animate-fadeInUp"
|
|
|
|
|
style={{
|
|
|
|
|
animation: 'fadeInUp 0.8s ease-out forwards',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<h1 className="text-5xl md:text-6xl font-bold text-foreground">
|
|
|
|
|
{product.name}
|
|
|
|
|
</h1>
|
|
|
|
|
<p className="text-xl text-foreground/80">
|
|
|
|
|
{product.variant}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-lg text-foreground/70 leading-relaxed">
|
|
|
|
|
{product.description}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<p className="text-3xl font-bold text-primary-cta">
|
|
|
|
|
{product.price}
|
|
|
|
|
</p>
|
|
|
|
|
<div className="flex flex-col sm:flex-row gap-4">
|
|
|
|
|
<button className="px-8 py-3 bg-primary-cta text-primary-cta-text rounded-full font-semibold hover:opacity-90 transition">
|
|
|
|
|
Add to Cart
|
|
|
|
|
</button>
|
|
|
|
|
<Link
|
|
|
|
|
href="/"
|
|
|
|
|
className="px-8 py-3 bg-secondary-cta text-secondary-cta-text rounded-full font-semibold hover:opacity-90 transition text-center"
|
|
|
|
|
>
|
|
|
|
|
Continue Shopping
|
|
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{!infoRevealed && !showAnimation && (
|
|
|
|
|
<div
|
|
|
|
|
className="space-y-6 animate-fadeInUp"
|
|
|
|
|
style={{
|
|
|
|
|
animation: 'fadeInUp 0.8s ease-out forwards',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<h1 className="text-5xl md:text-6xl font-bold text-foreground">
|
|
|
|
|
{product.name}
|
|
|
|
|
</h1>
|
|
|
|
|
<p className="text-xl text-foreground/80">
|
|
|
|
|
{product.variant}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-lg text-foreground/70 leading-relaxed">
|
|
|
|
|
{product.description}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<p className="text-3xl font-bold text-primary-cta">
|
|
|
|
|
{product.price}
|
|
|
|
|
</p>
|
|
|
|
|
<div className="flex flex-col sm:flex-row gap-4">
|
|
|
|
|
<button className="px-8 py-3 bg-primary-cta text-primary-cta-text rounded-full font-semibold hover:opacity-90 transition">
|
|
|
|
|
Add to Cart
|
|
|
|
|
</button>
|
|
|
|
|
<Link
|
|
|
|
|
href="/"
|
|
|
|
|
className="px-8 py-3 bg-secondary-cta text-secondary-cta-text rounded-full font-semibold hover:opacity-90 transition text-center"
|
|
|
|
|
>
|
|
|
|
|
Continue Shopping
|
|
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div id="footer" data-section="footer">
|
|
|
|
|
<FooterSimple
|
|
|
|
|
columns={[
|
|
|
|
|
{
|
|
|
|
|
title: "Navigate", items: [
|
|
|
|
|
{ label: "Home", href: "/" },
|
|
|
|
|
{ label: "Shop", href: "/#products" },
|
|
|
|
|
{ label: "About", href: "/#about" },
|
|
|
|
|
{ label: "Reviews", href: "/#testimonials" }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Support", items: [
|
|
|
|
|
{ label: "FAQ", href: "/#faq" },
|
|
|
|
|
{ label: "Contact Us", href: "/#contact" },
|
|
|
|
|
{ label: "Shipping Info", href: "#" },
|
|
|
|
|
{ label: "Returns", href: "#" }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Company", items: [
|
|
|
|
|
{ label: "About Us", href: "/#about" },
|
|
|
|
|
{ label: "Our Story", href: "/#about" },
|
|
|
|
|
{ label: "Careers", href: "#" },
|
|
|
|
|
{ label: "Blog", href: "#" }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "Legal", items: [
|
|
|
|
|
{ label: "Privacy Policy", href: "#" },
|
|
|
|
|
{ label: "Terms of Service", href: "#" },
|
|
|
|
|
{ label: "Cookie Policy", href: "#" }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]}
|
|
|
|
|
bottomLeftText="© 2025 Essence & Aura. All rights reserved."
|
|
|
|
|
bottomRightText="Crafted with luxury and passion"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<style>{`
|
|
|
|
|
@keyframes rotateLeftThenRight {
|
|
|
|
|
0% {
|
|
|
|
|
transform: perspective(1000px) rotateY(0deg);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
40% {
|
|
|
|
|
transform: perspective(1000px) rotateY(-90deg);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
100% {
|
|
|
|
|
transform: perspective(1000px) rotateY(90deg);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes fall {
|
|
|
|
|
to {
|
|
|
|
|
transform: translateY(100px) translateX(0px);
|
|
|
|
|
opacity: 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes fadeInUp {
|
|
|
|
|
from {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transform: translateY(20px);
|
|
|
|
|
}
|
|
|
|
|
to {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transform: translateY(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.animate-fadeInUp {
|
|
|
|
|
animation: fadeInUp 0.8s ease-out forwards;
|
|
|
|
|
}
|
|
|
|
|
`}</style>
|
|
|
|
|
</ThemeProvider>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|