344 lines
13 KiB
TypeScript
344 lines
13 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { DollarSign, Coffee, Palette, MapPin, Star, Clock, Ticket, Banknote } from 'lucide-react';
|
|
import { motion, useInView } from 'motion/react';
|
|
import { useRef } from 'react';
|
|
|
|
// Animation variants
|
|
const containerVariants = {
|
|
hidden: { opacity: 0 },
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.05,
|
|
duration: 0.2,
|
|
}
|
|
}
|
|
};
|
|
|
|
const itemVariants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
y: 15,
|
|
scale: 0.98
|
|
},
|
|
visible: {
|
|
opacity: 1,
|
|
y: 0,
|
|
scale: 1,
|
|
transition: {
|
|
duration: 0.3,
|
|
ease: [0.25, 0.1, 0.25, 1]
|
|
}
|
|
}
|
|
};
|
|
|
|
const cardVariants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
y: 15,
|
|
scale: 0.98
|
|
},
|
|
visible: {
|
|
opacity: 1,
|
|
y: 0,
|
|
scale: 1,
|
|
transition: {
|
|
duration: 0.25,
|
|
ease: [0.25, 0.1, 0.25, 1]
|
|
}
|
|
}
|
|
};
|
|
|
|
export function WhyChooseCityCards() {
|
|
const ref = useRef(null);
|
|
const isInView = useInView(ref, { once: true, amount: 0.3 });
|
|
|
|
// Melbourne-focused benefits with Save Big first
|
|
const benefits = [
|
|
{
|
|
icon: DollarSign,
|
|
title: "Save Big",
|
|
subtitle: "Up to 43% off attractions",
|
|
description: "Why pay $350+ buying tickets individually when Melbourne City Card gives you 40+ attractions for as little as $199?",
|
|
highlight: "43% OFF"
|
|
},
|
|
{
|
|
icon: Coffee,
|
|
title: "Coffee Culture",
|
|
subtitle: "Melbourne's best cafés",
|
|
description: "Skip the queue at Melbourne's iconic coffee spots and hidden laneway gems with exclusive café partner discounts.",
|
|
highlight: "Free Coffee Tour"
|
|
},
|
|
{
|
|
icon: Palette,
|
|
title: "Street Art Tours",
|
|
subtitle: "World-famous laneways",
|
|
description: "Access guided street art tours through Melbourne's famous laneways with local artists and cultural insights.",
|
|
highlight: "Expert Guides"
|
|
}
|
|
];
|
|
|
|
const melbourneStats = [
|
|
{
|
|
icon: MapPin,
|
|
value: "40+",
|
|
label: "Attractions",
|
|
description: "From Royal Botanic Gardens to Eureka Skydeck"
|
|
},
|
|
{
|
|
icon: Star,
|
|
value: "4.8",
|
|
label: "Rating",
|
|
description: "Top-rated by culture and food enthusiasts"
|
|
},
|
|
{
|
|
icon: Clock,
|
|
value: "3 Days",
|
|
label: "Valid",
|
|
description: "Perfect for a long weekend adventure"
|
|
}
|
|
];
|
|
|
|
return (
|
|
<section ref={ref} className="relative py-20 bg-gradient-to-br from-blue-50/30 via-white to-purple-50/20 overflow-hidden">
|
|
{/* Enhanced background elements */}
|
|
{/* Why Choose Melbourne City Card Section */}
|
|
<div className="container mx-auto px-4 relative z-10">
|
|
{/* Section Header */}
|
|
<motion.div
|
|
className="text-center mb-16"
|
|
initial={{ opacity: 0, y: 30 }}
|
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
|
|
transition={{ duration: 0.6, ease: "easeOut" }}
|
|
>
|
|
<motion.h2
|
|
className="font-merchant text-2xl md:text-3xl lg:text-4xl leading-tight mb-6"
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
|
transition={{ duration: 0.6, delay: 0.1 }}
|
|
>
|
|
<span className="font-light">Why Choose </span>
|
|
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
|
City Cards
|
|
</span>
|
|
<span className="font-light">?</span>
|
|
</motion.h2>
|
|
<motion.p
|
|
className="font-poppins text-xl leading-relaxed font-normal text-gray-600 max-w-3xl mx-auto"
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }}
|
|
transition={{ duration: 0.6, delay: 0.2 }}
|
|
>
|
|
Unlock exclusive access to Australia's top destinations with premium city experiences,
|
|
unbeatable savings, and seamless digital convenience that transforms how you explore.
|
|
</motion.p>
|
|
</motion.div>
|
|
|
|
{/* Benefits Grid */}
|
|
<motion.div
|
|
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"
|
|
variants={containerVariants}
|
|
initial="hidden"
|
|
animate={isInView ? "visible" : "hidden"}
|
|
>
|
|
{/* Benefit 1: Save Big */}
|
|
<motion.div
|
|
className="group relative bg-white/80 backdrop-blur-md border border-gray-200/50 shadow-lg rounded-3xl p-8 hover:bg-white hover:shadow-xl transition-all duration-300 cursor-pointer"
|
|
variants={cardVariants}
|
|
whileHover={{
|
|
y: -8,
|
|
scale: 1.02,
|
|
transition: { duration: 0.3 }
|
|
}}
|
|
>
|
|
{/* Save Badge */}
|
|
<motion.div
|
|
className="absolute -top-3 -right-3 z-10"
|
|
initial={{ opacity: 0, scale: 0, rotate: 0 }}
|
|
animate={isInView ? { opacity: 1, scale: 1, rotate: 12 } : { opacity: 0, scale: 0, rotate: 0 }}
|
|
transition={{
|
|
duration: 0.6,
|
|
delay: 0.8,
|
|
type: "spring",
|
|
stiffness: 200
|
|
}}
|
|
>
|
|
<div className="bg-gradient-to-r from-green-500 to-emerald-500 text-white px-4 py-2 rounded-2xl">
|
|
<div className="text-center">
|
|
<div className="text-xs font-medium">SAVE</div>
|
|
<div className="text-lg font-bold">43% OFF</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
className="w-16 h-16 bg-gradient-to-r from-primary to-secondary rounded-2xl flex items-center justify-center mb-6"
|
|
whileHover={{
|
|
scale: 1.1,
|
|
rotate: 5,
|
|
transition: { duration: 0.2 }
|
|
}}
|
|
>
|
|
<DollarSign className="w-8 h-8 text-white" />
|
|
</motion.div>
|
|
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3">Save Big</h3>
|
|
<p className="text-primary font-medium text-sm mb-4">Up to 43% off attractions</p>
|
|
<p className="text-gray-600 leading-relaxed">
|
|
Why pay $350+ buying tickets individually when City Cards give you 40+ attractions across multiple cities for as little as $199?
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Benefit 2: Skip the Lines */}
|
|
<motion.div
|
|
className="group relative bg-white/80 backdrop-blur-md border border-gray-200/50 shadow-lg rounded-3xl p-8 hover:bg-white hover:shadow-xl transition-all duration-300 cursor-pointer"
|
|
variants={cardVariants}
|
|
whileHover={{
|
|
y: -8,
|
|
scale: 1.02,
|
|
transition: { duration: 0.3 }
|
|
}}
|
|
>
|
|
<motion.div
|
|
className="w-16 h-16 bg-gradient-to-r from-primary to-secondary rounded-2xl flex items-center justify-center mb-6"
|
|
whileHover={{
|
|
scale: 1.1,
|
|
rotate: 5,
|
|
transition: { duration: 0.2 }
|
|
}}
|
|
>
|
|
<Clock className="w-8 h-8 text-white" />
|
|
</motion.div>
|
|
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3">Skip the Lines</h3>
|
|
<p className="text-primary font-medium text-sm mb-4">Fast-track entry</p>
|
|
<p className="text-gray-600 leading-relaxed">
|
|
Jump straight to the fun with priority access to Australia's most popular attractions and experiences across all cities.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Benefit 3: Local Experiences */}
|
|
<motion.div
|
|
className="group relative bg-white/80 backdrop-blur-md border border-gray-200/50 shadow-lg rounded-3xl p-8 hover:bg-white hover:shadow-xl transition-all duration-300 cursor-pointer"
|
|
variants={cardVariants}
|
|
whileHover={{
|
|
y: -8,
|
|
scale: 1.02,
|
|
transition: { duration: 0.3 }
|
|
}}
|
|
>
|
|
<motion.div
|
|
className="w-16 h-16 bg-gradient-to-r from-primary to-secondary rounded-2xl flex items-center justify-center mb-6"
|
|
whileHover={{
|
|
scale: 1.1,
|
|
rotate: 5,
|
|
transition: { duration: 0.2 }
|
|
}}
|
|
>
|
|
<MapPin className="w-8 h-8 text-white" />
|
|
</motion.div>
|
|
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3">Local Experiences</h3>
|
|
<p className="text-primary font-medium text-sm mb-4">Hidden gems included</p>
|
|
<p className="text-gray-600 leading-relaxed">
|
|
Discover each city's best-kept secrets with insider access to local favorites and cultural hotspots across Australia.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Benefit 4: Coffee Culture */}
|
|
<motion.div
|
|
className="group relative bg-white/80 backdrop-blur-md border border-gray-200/50 shadow-lg rounded-3xl p-8 hover:bg-white hover:shadow-xl transition-all duration-300 cursor-pointer"
|
|
variants={cardVariants}
|
|
whileHover={{
|
|
y: -8,
|
|
scale: 1.02,
|
|
transition: { duration: 0.3 }
|
|
}}
|
|
>
|
|
<motion.div
|
|
className="w-16 h-16 bg-gradient-to-r from-primary to-secondary rounded-2xl flex items-center justify-center mb-6"
|
|
whileHover={{
|
|
scale: 1.1,
|
|
rotate: 5,
|
|
transition: { duration: 0.2 }
|
|
}}
|
|
>
|
|
<Coffee className="w-8 h-8 text-white" />
|
|
</motion.div>
|
|
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3">Food & Dining</h3>
|
|
<p className="text-primary font-medium text-sm mb-4">Exclusive restaurant perks</p>
|
|
<p className="text-gray-600 leading-relaxed">
|
|
Enjoy exclusive discounts and skip-the-wait access at premium restaurants, cafés, and local culinary hotspots across every city.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Benefit 5: Street Art Tours */}
|
|
<motion.div
|
|
className="group relative bg-white/80 backdrop-blur-md border border-gray-200/50 shadow-lg rounded-3xl p-8 hover:bg-white hover:shadow-xl transition-all duration-300 cursor-pointer"
|
|
variants={cardVariants}
|
|
whileHover={{
|
|
y: -8,
|
|
scale: 1.02,
|
|
transition: { duration: 0.3 }
|
|
}}
|
|
>
|
|
<motion.div
|
|
className="w-16 h-16 bg-gradient-to-r from-primary to-secondary rounded-2xl flex items-center justify-center mb-6"
|
|
whileHover={{
|
|
scale: 1.1,
|
|
rotate: 5,
|
|
transition: { duration: 0.2 }
|
|
}}
|
|
>
|
|
<Palette className="w-8 h-8 text-white" />
|
|
</motion.div>
|
|
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3">Cultural Tours</h3>
|
|
<p className="text-primary font-medium text-sm mb-4">Expert-guided experiences</p>
|
|
<p className="text-gray-600 leading-relaxed">
|
|
Access exclusive guided tours showcasing each city's unique culture, art, and heritage with local experts and insider stories.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* Benefit 6: Digital Convenience */}
|
|
<motion.div
|
|
className="group relative bg-white/80 backdrop-blur-md border border-gray-200/50 shadow-lg rounded-3xl p-8 hover:bg-white hover:shadow-xl transition-all duration-300 cursor-pointer"
|
|
variants={cardVariants}
|
|
whileHover={{
|
|
y: -8,
|
|
scale: 1.02,
|
|
transition: { duration: 0.3 }
|
|
}}
|
|
>
|
|
<motion.div
|
|
className="w-16 h-16 bg-gradient-to-r from-primary to-secondary rounded-2xl flex items-center justify-center mb-6"
|
|
whileHover={{
|
|
scale: 1.1,
|
|
rotate: 5,
|
|
transition: { duration: 0.2 }
|
|
}}
|
|
>
|
|
<Ticket className="w-8 h-8 text-white" />
|
|
</motion.div>
|
|
|
|
<h3 className="text-xl font-bold text-gray-900 mb-3">Digital Convenience</h3>
|
|
<p className="text-primary font-medium text-sm mb-4">All in your phone</p>
|
|
<p className="text-gray-600 leading-relaxed">
|
|
Everything you need in one app - maps, tickets, recommendations, and real-time updates for seamless exploring.
|
|
</p>
|
|
</motion.div>
|
|
</motion.div>
|
|
</div>
|
|
|
|
<motion.div
|
|
className="container mx-auto px-4"
|
|
initial="hidden"
|
|
animate={isInView ? "visible" : "hidden"}
|
|
variants={containerVariants}
|
|
>
|
|
|
|
</motion.div>
|
|
</section>
|
|
);
|
|
} |