main #4
BIN
src/assets/front.jpg
Normal file
BIN
src/assets/front.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
@@ -168,7 +168,7 @@ export function AboutUsPage({
|
||||
transition={{ duration: 3, repeat: Infinity }}
|
||||
>
|
||||
<span className="font-merchant font-light" style={{ fontStretch: 'normal', fontVariant: 'normal' }}>Meet the</span>{' '}
|
||||
<span className="bg-gradient-to-r from-primary via-secondary to-primary bg-[length:200%_100%] bg-clip-text text-transparent font-bold italic animate-shimmer">
|
||||
<span className="bg-gradient-to-r from-primary via-secondary to-primary bg-[length:200%_100%] bg-clip-text text-transparent font-bold italic animate-shimmer pr-1">
|
||||
Dream Team
|
||||
</span>{' '}
|
||||
✈️
|
||||
|
||||
@@ -301,7 +301,7 @@ export function AttractionsPage({
|
||||
<div className="text-center mb-12">
|
||||
<h1 className="font-merchant text-2xl md:text-3xl lg:text-4xl leading-tight text-gray-900 mb-4">
|
||||
<span className="font-light">Discover</span>{' '}
|
||||
<span className="font-bold italic text-gradient-primary">Melbourne's</span>{' '}
|
||||
<span className="font-bold italic text-gradient-primary pr-1">Melbourne's</span>{' '}
|
||||
<span className="font-normal">Best</span>{' '}
|
||||
<span className="font-semibold text-emphasis">Attractions</span>
|
||||
</h1>
|
||||
|
||||
@@ -211,7 +211,7 @@ export function CheckoutPage({
|
||||
>
|
||||
<h1 className="font-merchant text-3xl md:text-4xl lg:text-5xl mb-4">
|
||||
<span className="font-light">Secure</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">Checkout</span>
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-2">Checkout</span>
|
||||
</h1>
|
||||
<p className="font-poppins text-lg text-gray-600">
|
||||
Complete your purchase and start exploring Paris
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button } from './ui/button';
|
||||
import { ImageWithFallback } from './figma/ImageWithFallback';
|
||||
import { motion, useMotionValue, useSpring, useTransform, useInView } from 'motion/react';
|
||||
import { HandwrittenText, useHandwrittenText } from './HandwrittenText';
|
||||
import postcardImage from 'figma:asset/d3a880cf8b7f1bec6da9b3f2ce4a76e822e483cf.png';
|
||||
import front from '../assets/front.jpg'
|
||||
|
||||
interface EditableCardProps {
|
||||
isEditing: boolean;
|
||||
@@ -190,485 +190,485 @@ export function CustomPostcards() {
|
||||
};
|
||||
|
||||
// Ultra-realistic vintage postcard with responsive scaling and animations
|
||||
const PostcardFrame = () => {
|
||||
return (
|
||||
<motion.div
|
||||
className="relative shadow-2xl transform rotate-[0.5deg] w-full h-full"
|
||||
initial={{ opacity: 0, scale: 0.9, rotate: 0 }}
|
||||
animate={{ opacity: 1, scale: 1, rotate: 0.5 }}
|
||||
transition={{ duration: 0.8, ease: "easeOut" }}
|
||||
style={{
|
||||
background: `
|
||||
radial-gradient(circle at 20% 80%, rgba(210, 180, 140, 0.15) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 20%, rgba(160, 130, 100, 0.1) 0%, transparent 50%),
|
||||
radial-gradient(circle at 40% 40%, rgba(190, 160, 120, 0.08) 0%, transparent 50%),
|
||||
linear-gradient(135deg, #f8f4e6 0%, #f0e7d3 25%, #ede2d0 50%, #e8dcc8 75%, #e3d5c2 100%)
|
||||
`,
|
||||
borderRadius: '10px',
|
||||
boxShadow: `
|
||||
inset 0px 1px 30px rgba(139, 115, 85, 0.2),
|
||||
inset 0px -1px 20px rgba(160, 130, 100, 0.15),
|
||||
0px 12px 40px rgba(0, 0, 0, 0.15),
|
||||
0px 4px 12px rgba(0, 0, 0, 0.1)
|
||||
`,
|
||||
border: '1px solid rgba(139, 115, 85, 0.2)'
|
||||
}}
|
||||
>
|
||||
{/* Realistic paper texture with variations */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-40 rounded-[10px] pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23d4af9a' fill-opacity='0.08'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"),
|
||||
radial-gradient(circle at 25% 75%, rgba(180, 150, 120, 0.1) 0%, transparent 40%),
|
||||
radial-gradient(circle at 75% 25%, rgba(160, 130, 100, 0.08) 0%, transparent 35%)
|
||||
`
|
||||
}}
|
||||
/>
|
||||
// const PostcardFrame = () => {
|
||||
// return (
|
||||
// <motion.div
|
||||
// className="relative shadow-2xl transform rotate-[0.5deg] w-full h-full"
|
||||
// initial={{ opacity: 0, scale: 0.9, rotate: 0 }}
|
||||
// animate={{ opacity: 1, scale: 1, rotate: 0.5 }}
|
||||
// transition={{ duration: 0.8, ease: "easeOut" }}
|
||||
// style={{
|
||||
// background: `
|
||||
// radial-gradient(circle at 20% 80%, rgba(210, 180, 140, 0.15) 0%, transparent 50%),
|
||||
// radial-gradient(circle at 80% 20%, rgba(160, 130, 100, 0.1) 0%, transparent 50%),
|
||||
// radial-gradient(circle at 40% 40%, rgba(190, 160, 120, 0.08) 0%, transparent 50%),
|
||||
// linear-gradient(135deg, #f8f4e6 0%, #f0e7d3 25%, #ede2d0 50%, #e8dcc8 75%, #e3d5c2 100%)
|
||||
// `,
|
||||
// borderRadius: '10px',
|
||||
// boxShadow: `
|
||||
// inset 0px 1px 30px rgba(139, 115, 85, 0.2),
|
||||
// inset 0px -1px 20px rgba(160, 130, 100, 0.15),
|
||||
// 0px 12px 40px rgba(0, 0, 0, 0.15),
|
||||
// 0px 4px 12px rgba(0, 0, 0, 0.1)
|
||||
// `,
|
||||
// border: '1px solid rgba(139, 115, 85, 0.2)'
|
||||
// }}
|
||||
// >
|
||||
// {/* Realistic paper texture with variations */}
|
||||
// <div
|
||||
// className="absolute inset-0 opacity-40 rounded-[10px] pointer-events-none"
|
||||
// style={{
|
||||
// backgroundImage: `
|
||||
// url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23d4af9a' fill-opacity='0.08'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"),
|
||||
// radial-gradient(circle at 25% 75%, rgba(180, 150, 120, 0.1) 0%, transparent 40%),
|
||||
// radial-gradient(circle at 75% 25%, rgba(160, 130, 100, 0.08) 0%, transparent 35%)
|
||||
// `
|
||||
// }}
|
||||
// />
|
||||
|
||||
{/* Age spots and stains */}
|
||||
<div className="absolute inset-0 rounded-[10px] pointer-events-none opacity-30">
|
||||
<div
|
||||
className="absolute w-8 h-6 rounded-full"
|
||||
style={{
|
||||
background: 'radial-gradient(ellipse, rgba(160, 120, 80, 0.15) 0%, transparent 70%)',
|
||||
top: '15%',
|
||||
right: '20%',
|
||||
transform: 'rotate(-15deg)'
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="absolute w-6 h-8 rounded-full"
|
||||
style={{
|
||||
background: 'radial-gradient(ellipse, rgba(140, 110, 70, 0.12) 0%, transparent 60%)',
|
||||
bottom: '25%',
|
||||
left: '15%',
|
||||
transform: 'rotate(25deg)'
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="absolute w-4 h-4 rounded-full"
|
||||
style={{
|
||||
background: 'radial-gradient(circle, rgba(180, 140, 100, 0.2) 0%, transparent 50%)',
|
||||
top: '60%',
|
||||
right: '10%'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
// {/* Age spots and stains */}
|
||||
// <div className="absolute inset-0 rounded-[10px] pointer-events-none opacity-30">
|
||||
// <div
|
||||
// className="absolute w-8 h-6 rounded-full"
|
||||
// style={{
|
||||
// background: 'radial-gradient(ellipse, rgba(160, 120, 80, 0.15) 0%, transparent 70%)',
|
||||
// top: '15%',
|
||||
// right: '20%',
|
||||
// transform: 'rotate(-15deg)'
|
||||
// }}
|
||||
// />
|
||||
// <div
|
||||
// className="absolute w-6 h-8 rounded-full"
|
||||
// style={{
|
||||
// background: 'radial-gradient(ellipse, rgba(140, 110, 70, 0.12) 0%, transparent 60%)',
|
||||
// bottom: '25%',
|
||||
// left: '15%',
|
||||
// transform: 'rotate(25deg)'
|
||||
// }}
|
||||
// />
|
||||
// <div
|
||||
// className="absolute w-4 h-4 rounded-full"
|
||||
// style={{
|
||||
// background: 'radial-gradient(circle, rgba(180, 140, 100, 0.2) 0%, transparent 50%)',
|
||||
// top: '60%',
|
||||
// right: '10%'
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
|
||||
{/* Corner wear and creases */}
|
||||
<div
|
||||
className="absolute top-0 right-0 w-12 h-12 opacity-25"
|
||||
style={{
|
||||
background: 'radial-gradient(circle at top right, rgba(139, 115, 85, 0.3) 20%, rgba(160, 130, 100, 0.2) 40%, transparent 70%)',
|
||||
borderTopRightRadius: '10px'
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="absolute bottom-0 left-0 w-16 h-16 opacity-20"
|
||||
style={{
|
||||
background: 'radial-gradient(circle at bottom left, rgba(120, 95, 70, 0.25) 25%, rgba(140, 115, 85, 0.15) 50%, transparent 75%)',
|
||||
borderBottomLeftRadius: '10px'
|
||||
}}
|
||||
/>
|
||||
// {/* Corner wear and creases */}
|
||||
// <div
|
||||
// className="absolute top-0 right-0 w-12 h-12 opacity-25"
|
||||
// style={{
|
||||
// background: 'radial-gradient(circle at top right, rgba(139, 115, 85, 0.3) 20%, rgba(160, 130, 100, 0.2) 40%, transparent 70%)',
|
||||
// borderTopRightRadius: '10px'
|
||||
// }}
|
||||
// />
|
||||
// <div
|
||||
// className="absolute bottom-0 left-0 w-16 h-16 opacity-20"
|
||||
// style={{
|
||||
// background: 'radial-gradient(circle at bottom left, rgba(120, 95, 70, 0.25) 25%, rgba(140, 115, 85, 0.15) 50%, transparent 75%)',
|
||||
// borderBottomLeftRadius: '10px'
|
||||
// }}
|
||||
// />
|
||||
|
||||
{/* Subtle crease lines */}
|
||||
<div
|
||||
className="absolute w-full h-px bg-gradient-to-r from-transparent via-amber-800/10 to-transparent opacity-40"
|
||||
style={{
|
||||
top: '35%',
|
||||
transform: 'rotate(-0.5deg)'
|
||||
}}
|
||||
/>
|
||||
// {/* Subtle crease lines */}
|
||||
// <div
|
||||
// className="absolute w-full h-px bg-gradient-to-r from-transparent via-amber-800/10 to-transparent opacity-40"
|
||||
// style={{
|
||||
// top: '35%',
|
||||
// transform: 'rotate(-0.5deg)'
|
||||
// }}
|
||||
// />
|
||||
|
||||
{/* Animated Vintage Vector Logo - Top Right - Mobile Optimized */}
|
||||
<motion.div
|
||||
className="absolute opacity-60 pointer-events-none"
|
||||
style={{
|
||||
top: '4.3%',
|
||||
right: '3.5%',
|
||||
width: '7.5%',
|
||||
height: '11.5%',
|
||||
filter: 'sepia(30%) saturate(120%) hue-rotate(15deg) brightness(85%) contrast(110%)'
|
||||
}}
|
||||
animate={{
|
||||
rotate: [5, 7, 3, 5],
|
||||
scale: [1, 1.02, 0.98, 1]
|
||||
}}
|
||||
transition={{
|
||||
duration: 8,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut"
|
||||
}}
|
||||
>
|
||||
<ImageWithFallback
|
||||
src="https://images.unsplash.com/photo-1702825328124-dab63d85490e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHx2aW50YWdlJTIwbG9nbyUyMHZlY3RvciUyMHBvc3RhbCUyMHN0YW1wfGVufDF8fHx8MTc1ODk5MjExN3ww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral"
|
||||
alt="Vintage logo"
|
||||
className="w-full h-full object-contain"
|
||||
style={{
|
||||
mixBlendMode: 'multiply',
|
||||
opacity: 0.8
|
||||
}}
|
||||
/>
|
||||
{/* Subtle aging overlay for the vector */}
|
||||
<div
|
||||
className="absolute inset-0 rounded-full"
|
||||
style={{
|
||||
background: `
|
||||
radial-gradient(circle at 30% 30%, rgba(160, 130, 90, 0.2) 0%, transparent 60%),
|
||||
radial-gradient(circle at 70% 70%, rgba(140, 110, 70, 0.15) 0%, transparent 50%)
|
||||
`,
|
||||
mixBlendMode: 'multiply'
|
||||
}}
|
||||
/>
|
||||
</motion.div>
|
||||
// {/* Animated Vintage Vector Logo - Top Right - Mobile Optimized */}
|
||||
// <motion.div
|
||||
// className="absolute opacity-60 pointer-events-none"
|
||||
// style={{
|
||||
// top: '4.3%',
|
||||
// right: '3.5%',
|
||||
// width: '7.5%',
|
||||
// height: '11.5%',
|
||||
// filter: 'sepia(30%) saturate(120%) hue-rotate(15deg) brightness(85%) contrast(110%)'
|
||||
// }}
|
||||
// animate={{
|
||||
// rotate: [5, 7, 3, 5],
|
||||
// scale: [1, 1.02, 0.98, 1]
|
||||
// }}
|
||||
// transition={{
|
||||
// duration: 8,
|
||||
// repeat: Infinity,
|
||||
// ease: "easeInOut"
|
||||
// }}
|
||||
// >
|
||||
// <ImageWithFallback
|
||||
// src="https://images.unsplash.com/photo-1702825328124-dab63d85490e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHx2aW50YWdlJTIwbG9nbyUyMHZlY3RvciUyMHBvc3RhbCUyMHN0YW1wfGVufDF8fHx8MTc1ODk5MjExN3ww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral"
|
||||
// alt="Vintage logo"
|
||||
// className="w-full h-full object-contain"
|
||||
// style={{
|
||||
// mixBlendMode: 'multiply',
|
||||
// opacity: 0.8
|
||||
// }}
|
||||
// />
|
||||
// {/* Subtle aging overlay for the vector */}
|
||||
// <div
|
||||
// className="absolute inset-0 rounded-full"
|
||||
// style={{
|
||||
// background: `
|
||||
// radial-gradient(circle at 30% 30%, rgba(160, 130, 90, 0.2) 0%, transparent 60%),
|
||||
// radial-gradient(circle at 70% 70%, rgba(140, 110, 70, 0.15) 0%, transparent 50%)
|
||||
// `,
|
||||
// mixBlendMode: 'multiply'
|
||||
// }}
|
||||
// />
|
||||
// </motion.div>
|
||||
|
||||
{/* For Correspondence Text */}
|
||||
<div
|
||||
className="absolute pointer-events-none"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '33.3%',
|
||||
height: '72.3%',
|
||||
left: '4.9%',
|
||||
top: '7.4%',
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start',
|
||||
paddingTop: '8%'
|
||||
}}
|
||||
>
|
||||
<p
|
||||
className="font-poppins font-light"
|
||||
style={{
|
||||
fontSize: 'clamp(10px, 2.2vw, 16px)',
|
||||
color: 'rgba(101, 84, 63, 0.4)',
|
||||
letterSpacing: '0.5px',
|
||||
lineHeight: '1.4',
|
||||
textShadow: '0px 0.5px 1px rgba(0, 0, 0, 0.05)'
|
||||
}}
|
||||
>
|
||||
For correspondence
|
||||
</p>
|
||||
</div>
|
||||
// {/* For Correspondence Text */}
|
||||
// <div
|
||||
// className="absolute pointer-events-none"
|
||||
// style={{
|
||||
// position: 'absolute',
|
||||
// width: '33.3%',
|
||||
// height: '72.3%',
|
||||
// left: '4.9%',
|
||||
// top: '7.4%',
|
||||
// display: 'flex',
|
||||
// alignItems: 'flex-start',
|
||||
// justifyContent: 'flex-start',
|
||||
// paddingTop: '8%'
|
||||
// }}
|
||||
// >
|
||||
// <p
|
||||
// className="font-poppins font-light"
|
||||
// style={{
|
||||
// fontSize: 'clamp(10px, 2.2vw, 16px)',
|
||||
// color: 'rgba(101, 84, 63, 0.4)',
|
||||
// letterSpacing: '0.5px',
|
||||
// lineHeight: '1.4',
|
||||
// textShadow: '0px 0.5px 1px rgba(0, 0, 0, 0.05)'
|
||||
// }}
|
||||
// >
|
||||
// For correspondence
|
||||
// </p>
|
||||
// </div>
|
||||
|
||||
{/* Realistic vertical divider with ink bleeding - Responsive */}
|
||||
<div
|
||||
className="absolute"
|
||||
style={{
|
||||
top: '10.6%',
|
||||
bottom: '10.6%',
|
||||
left: '43.1%',
|
||||
width: '2px',
|
||||
background: `
|
||||
linear-gradient(to bottom,
|
||||
transparent 0%,
|
||||
rgba(101, 84, 63, 0.4) 10%,
|
||||
rgba(101, 84, 63, 0.6) 30%,
|
||||
rgba(101, 84, 63, 0.8) 50%,
|
||||
rgba(101, 84, 63, 0.6) 70%,
|
||||
rgba(101, 84, 63, 0.4) 90%,
|
||||
transparent 100%
|
||||
)
|
||||
`,
|
||||
filter: 'blur(0.3px)'
|
||||
}}
|
||||
/>
|
||||
// {/* Realistic vertical divider with ink bleeding - Responsive */}
|
||||
// <div
|
||||
// className="absolute"
|
||||
// style={{
|
||||
// top: '10.6%',
|
||||
// bottom: '10.6%',
|
||||
// left: '43.1%',
|
||||
// width: '2px',
|
||||
// background: `
|
||||
// linear-gradient(to bottom,
|
||||
// transparent 0%,
|
||||
// rgba(101, 84, 63, 0.4) 10%,
|
||||
// rgba(101, 84, 63, 0.6) 30%,
|
||||
// rgba(101, 84, 63, 0.8) 50%,
|
||||
// rgba(101, 84, 63, 0.6) 70%,
|
||||
// rgba(101, 84, 63, 0.4) 90%,
|
||||
// transparent 100%
|
||||
// )
|
||||
// `,
|
||||
// filter: 'blur(0.3px)'
|
||||
// }}
|
||||
// />
|
||||
|
||||
{/* Ink bleed effect around divider - Responsive */}
|
||||
<div
|
||||
className="absolute opacity-20"
|
||||
style={{
|
||||
top: '10.6%',
|
||||
bottom: '10.6%',
|
||||
left: '42.8%',
|
||||
width: '6px',
|
||||
background: `
|
||||
linear-gradient(to bottom,
|
||||
transparent 0%,
|
||||
rgba(101, 84, 63, 0.1) 20%,
|
||||
rgba(101, 84, 63, 0.15) 50%,
|
||||
rgba(101, 84, 63, 0.1) 80%,
|
||||
transparent 100%
|
||||
)
|
||||
`,
|
||||
filter: 'blur(1px)'
|
||||
}}
|
||||
/>
|
||||
// {/* Ink bleed effect around divider - Responsive */}
|
||||
// <div
|
||||
// className="absolute opacity-20"
|
||||
// style={{
|
||||
// top: '10.6%',
|
||||
// bottom: '10.6%',
|
||||
// left: '42.8%',
|
||||
// width: '6px',
|
||||
// background: `
|
||||
// linear-gradient(to bottom,
|
||||
// transparent 0%,
|
||||
// rgba(101, 84, 63, 0.1) 20%,
|
||||
// rgba(101, 84, 63, 0.15) 50%,
|
||||
// rgba(101, 84, 63, 0.1) 80%,
|
||||
// transparent 100%
|
||||
// )
|
||||
// `,
|
||||
// filter: 'blur(1px)'
|
||||
// }}
|
||||
// />
|
||||
|
||||
{/* Right side content area - Responsive */}
|
||||
<div
|
||||
className="absolute pointer-events-none"
|
||||
style={{
|
||||
top: '10.6%',
|
||||
left: '47.2%',
|
||||
width: '47.2%',
|
||||
height: '78.7%'
|
||||
}}
|
||||
>
|
||||
{/* Editable Address Label Card - Responsive */}
|
||||
<EditableCard
|
||||
isEditing={editingCard === 'label'}
|
||||
onEdit={() => setEditingCard(editingCard === 'label' ? null : 'label')}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '4.1%',
|
||||
left: '0%',
|
||||
pointerEvents: 'auto',
|
||||
transform: 'rotate(-0.3deg)'
|
||||
}}
|
||||
editIcon={<Type className="w-3 h-3 text-gray-600" />}
|
||||
>
|
||||
<div
|
||||
className="px-2 py-1 rounded text-xs md:text-sm"
|
||||
style={{
|
||||
fontWeight: '600',
|
||||
letterSpacing: '2px',
|
||||
textTransform: 'uppercase',
|
||||
color: 'rgba(101, 84, 63, 0.8)',
|
||||
textShadow: '0px 1px 2px rgba(0, 0, 0, 0.1)'
|
||||
}}
|
||||
>
|
||||
{postcardData.addressLabel}
|
||||
</div>
|
||||
</EditableCard>
|
||||
// {/* Right side content area - Responsive */}
|
||||
// <div
|
||||
// className="absolute pointer-events-none"
|
||||
// style={{
|
||||
// top: '10.6%',
|
||||
// left: '47.2%',
|
||||
// width: '47.2%',
|
||||
// height: '78.7%'
|
||||
// }}
|
||||
// >
|
||||
// {/* Editable Address Label Card - Responsive */}
|
||||
// <EditableCard
|
||||
// isEditing={editingCard === 'label'}
|
||||
// onEdit={() => setEditingCard(editingCard === 'label' ? null : 'label')}
|
||||
// style={{
|
||||
// position: 'absolute',
|
||||
// top: '4.1%',
|
||||
// left: '0%',
|
||||
// pointerEvents: 'auto',
|
||||
// transform: 'rotate(-0.3deg)'
|
||||
// }}
|
||||
// editIcon={<Type className="w-3 h-3 text-gray-600" />}
|
||||
// >
|
||||
// <div
|
||||
// className="px-2 py-1 rounded text-xs md:text-sm"
|
||||
// style={{
|
||||
// fontWeight: '600',
|
||||
// letterSpacing: '2px',
|
||||
// textTransform: 'uppercase',
|
||||
// color: 'rgba(101, 84, 63, 0.8)',
|
||||
// textShadow: '0px 1px 2px rgba(0, 0, 0, 0.1)'
|
||||
// }}
|
||||
// >
|
||||
// {postcardData.addressLabel}
|
||||
// </div>
|
||||
// </EditableCard>
|
||||
|
||||
{/* Realistic horizontal ruled lines with ink bleeding - Responsive */}
|
||||
<div
|
||||
className="absolute pointer-events-none"
|
||||
style={{
|
||||
top: '14.9%',
|
||||
left: '0%',
|
||||
width: '94.1%',
|
||||
height: '59.5%'
|
||||
}}
|
||||
>
|
||||
{[...Array(9)].map((_, i) => (
|
||||
<div key={i} className="relative" style={{ marginBottom: '6.5%' }}>
|
||||
{/* Main line */}
|
||||
<div
|
||||
style={{
|
||||
height: '1px',
|
||||
width: i % 2 === 0 ? '100%' : '92%',
|
||||
background: `linear-gradient(to right,
|
||||
rgba(101, 84, 63, 0.3) 0%,
|
||||
rgba(101, 84, 63, 0.5) 20%,
|
||||
rgba(101, 84, 63, 0.6) 50%,
|
||||
rgba(101, 84, 63, 0.4) 80%,
|
||||
rgba(101, 84, 63, 0.2) 95%,
|
||||
transparent 100%
|
||||
)`,
|
||||
transform: `rotate(${(Math.random() - 0.5) * 0.5}deg)`
|
||||
}}
|
||||
/>
|
||||
{/* Ink bleed effect */}
|
||||
<div
|
||||
className="absolute top-0 left-0 opacity-30"
|
||||
style={{
|
||||
height: '3px',
|
||||
width: i % 2 === 0 ? '98%' : '90%',
|
||||
background: `linear-gradient(to right,
|
||||
rgba(101, 84, 63, 0.1) 0%,
|
||||
rgba(101, 84, 63, 0.2) 30%,
|
||||
rgba(101, 84, 63, 0.15) 70%,
|
||||
transparent 100%
|
||||
)`,
|
||||
filter: 'blur(1px)',
|
||||
transform: 'translateY(-1px)'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
// {/* Realistic horizontal ruled lines with ink bleeding - Responsive */}
|
||||
// <div
|
||||
// className="absolute pointer-events-none"
|
||||
// style={{
|
||||
// top: '14.9%',
|
||||
// left: '0%',
|
||||
// width: '94.1%',
|
||||
// height: '59.5%'
|
||||
// }}
|
||||
// >
|
||||
// {[...Array(9)].map((_, i) => (
|
||||
// <div key={i} className="relative" style={{ marginBottom: '6.5%' }}>
|
||||
// {/* Main line */}
|
||||
// <div
|
||||
// style={{
|
||||
// height: '1px',
|
||||
// width: i % 2 === 0 ? '100%' : '92%',
|
||||
// background: `linear-gradient(to right,
|
||||
// rgba(101, 84, 63, 0.3) 0%,
|
||||
// rgba(101, 84, 63, 0.5) 20%,
|
||||
// rgba(101, 84, 63, 0.6) 50%,
|
||||
// rgba(101, 84, 63, 0.4) 80%,
|
||||
// rgba(101, 84, 63, 0.2) 95%,
|
||||
// transparent 100%
|
||||
// )`,
|
||||
// transform: `rotate(${(Math.random() - 0.5) * 0.5}deg)`
|
||||
// }}
|
||||
// />
|
||||
// {/* Ink bleed effect */}
|
||||
// <div
|
||||
// className="absolute top-0 left-0 opacity-30"
|
||||
// style={{
|
||||
// height: '3px',
|
||||
// width: i % 2 === 0 ? '98%' : '90%',
|
||||
// background: `linear-gradient(to right,
|
||||
// rgba(101, 84, 63, 0.1) 0%,
|
||||
// rgba(101, 84, 63, 0.2) 30%,
|
||||
// rgba(101, 84, 63, 0.15) 70%,
|
||||
// transparent 100%
|
||||
// )`,
|
||||
// filter: 'blur(1px)',
|
||||
// transform: 'translateY(-1px)'
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// ))}
|
||||
// </div>
|
||||
|
||||
{/* Editable Message Card with Handwritten Animation - Responsive */}
|
||||
<EditableCard
|
||||
isEditing={editingCard === 'message'}
|
||||
onEdit={() => setEditingCard(editingCard === 'message' ? null : 'message')}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '17.6%',
|
||||
left: '4.4%',
|
||||
width: '88.2%',
|
||||
pointerEvents: 'auto',
|
||||
transform: 'rotate(-0.7deg)'
|
||||
}}
|
||||
editIcon={<Edit3 className="w-3 h-3 text-gray-600" />}
|
||||
>
|
||||
<div className="px-2 py-2 rounded leading-relaxed">
|
||||
{editingCard === 'message' ? (
|
||||
// Show static text when editing
|
||||
<div
|
||||
style={{
|
||||
fontFamily: "'Dancing Script', 'Brush Script MT', cursive",
|
||||
fontSize: 'clamp(14px, 3.6vw, 26px)',
|
||||
lineHeight: '1.7',
|
||||
color: 'rgba(85, 70, 50, 0.9)',
|
||||
textShadow: `
|
||||
1px 1px 2px rgba(0, 0, 0, 0.08),
|
||||
0px 0px 3px rgba(101, 84, 63, 0.1)
|
||||
`,
|
||||
whiteSpace: 'pre-line',
|
||||
filter: 'contrast(110%) brightness(98%)'
|
||||
}}
|
||||
>
|
||||
{postcardData.message}
|
||||
</div>
|
||||
) : (
|
||||
// Show animated handwritten text when not editing
|
||||
<HandwrittenText
|
||||
text={postcardData.message}
|
||||
speed={6}
|
||||
startDelay={0}
|
||||
autoStart={false}
|
||||
onComplete={handwrittenControl.onComplete}
|
||||
style={{
|
||||
fontFamily: "'Dancing Script', 'Brush Script MT', cursive",
|
||||
fontSize: 'clamp(14px, 3.6vw, 26px)',
|
||||
lineHeight: '1.7',
|
||||
color: 'rgba(85, 70, 50, 0.9)',
|
||||
textShadow: `
|
||||
1px 1px 2px rgba(0, 0, 0, 0.08),
|
||||
0px 0px 3px rgba(101, 84, 63, 0.1)
|
||||
`,
|
||||
filter: 'contrast(110%) brightness(98%)'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</EditableCard>
|
||||
// {/* Editable Message Card with Handwritten Animation - Responsive */}
|
||||
// <EditableCard
|
||||
// isEditing={editingCard === 'message'}
|
||||
// onEdit={() => setEditingCard(editingCard === 'message' ? null : 'message')}
|
||||
// style={{
|
||||
// position: 'absolute',
|
||||
// top: '17.6%',
|
||||
// left: '4.4%',
|
||||
// width: '88.2%',
|
||||
// pointerEvents: 'auto',
|
||||
// transform: 'rotate(-0.7deg)'
|
||||
// }}
|
||||
// editIcon={<Edit3 className="w-3 h-3 text-gray-600" />}
|
||||
// >
|
||||
// <div className="px-2 py-2 rounded leading-relaxed">
|
||||
// {editingCard === 'message' ? (
|
||||
// // Show static text when editing
|
||||
// <div
|
||||
// style={{
|
||||
// fontFamily: "'Dancing Script', 'Brush Script MT', cursive",
|
||||
// fontSize: 'clamp(14px, 3.6vw, 26px)',
|
||||
// lineHeight: '1.7',
|
||||
// color: 'rgba(85, 70, 50, 0.9)',
|
||||
// textShadow: `
|
||||
// 1px 1px 2px rgba(0, 0, 0, 0.08),
|
||||
// 0px 0px 3px rgba(101, 84, 63, 0.1)
|
||||
// `,
|
||||
// whiteSpace: 'pre-line',
|
||||
// filter: 'contrast(110%) brightness(98%)'
|
||||
// }}
|
||||
// >
|
||||
// {postcardData.message}
|
||||
// </div>
|
||||
// ) : (
|
||||
// // Show animated handwritten text when not editing
|
||||
// <HandwrittenText
|
||||
// text={postcardData.message}
|
||||
// speed={6}
|
||||
// startDelay={0}
|
||||
// autoStart={false}
|
||||
// onComplete={handwrittenControl.onComplete}
|
||||
// style={{
|
||||
// fontFamily: "'Dancing Script', 'Brush Script MT', cursive",
|
||||
// fontSize: 'clamp(14px, 3.6vw, 26px)',
|
||||
// lineHeight: '1.7',
|
||||
// color: 'rgba(85, 70, 50, 0.9)',
|
||||
// textShadow: `
|
||||
// 1px 1px 2px rgba(0, 0, 0, 0.08),
|
||||
// 0px 0px 3px rgba(101, 84, 63, 0.1)
|
||||
// `,
|
||||
// filter: 'contrast(110%) brightness(98%)'
|
||||
// }}
|
||||
// />
|
||||
// )}
|
||||
// </div>
|
||||
// </EditableCard>
|
||||
|
||||
{/* Editable Date Card - Responsive */}
|
||||
<EditableCard
|
||||
isEditing={editingCard === 'date'}
|
||||
onEdit={() => setEditingCard(editingCard === 'date' ? null : 'date')}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: '16.2%',
|
||||
right: '7.4%',
|
||||
pointerEvents: 'auto',
|
||||
transform: 'rotate(-1.5deg)'
|
||||
}}
|
||||
editIcon={<Calendar className="w-3 h-3 text-gray-600" />}
|
||||
>
|
||||
<div
|
||||
className="px-2 py-1 rounded text-xs"
|
||||
style={{
|
||||
fontWeight: '500',
|
||||
letterSpacing: '1px',
|
||||
color: 'rgba(101, 84, 63, 0.7)',
|
||||
textShadow: '0px 1px 1px rgba(0, 0, 0, 0.05)',
|
||||
fontFamily: "'Poppins', sans-serif"
|
||||
}}
|
||||
>
|
||||
{postcardData.date}
|
||||
</div>
|
||||
</EditableCard>
|
||||
</div>
|
||||
// {/* Editable Date Card - Responsive */}
|
||||
// <EditableCard
|
||||
// isEditing={editingCard === 'date'}
|
||||
// onEdit={() => setEditingCard(editingCard === 'date' ? null : 'date')}
|
||||
// style={{
|
||||
// position: 'absolute',
|
||||
// bottom: '16.2%',
|
||||
// right: '7.4%',
|
||||
// pointerEvents: 'auto',
|
||||
// transform: 'rotate(-1.5deg)'
|
||||
// }}
|
||||
// editIcon={<Calendar className="w-3 h-3 text-gray-600" />}
|
||||
// >
|
||||
// <div
|
||||
// className="px-2 py-1 rounded text-xs"
|
||||
// style={{
|
||||
// fontWeight: '500',
|
||||
// letterSpacing: '1px',
|
||||
// color: 'rgba(101, 84, 63, 0.7)',
|
||||
// textShadow: '0px 1px 1px rgba(0, 0, 0, 0.05)',
|
||||
// fontFamily: "'Poppins', sans-serif"
|
||||
// }}
|
||||
// >
|
||||
// {postcardData.date}
|
||||
// </div>
|
||||
// </EditableCard>
|
||||
// </div>
|
||||
|
||||
{/* Ultra-realistic stamp - Responsive */}
|
||||
<EditableCard
|
||||
isEditing={editingCard === 'stamp'}
|
||||
onEdit={() => setEditingCard(editingCard === 'stamp' ? null : 'stamp')}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '12.5%',
|
||||
height: '19.1%',
|
||||
right: '3.5%',
|
||||
bottom: '5.3%',
|
||||
transform: 'rotate(-12deg)'
|
||||
}}
|
||||
editIcon={<Edit3 className="w-3 h-3 text-gray-600" />}
|
||||
>
|
||||
<div
|
||||
className="w-full h-full border-2 border-dashed rounded-full flex items-center justify-center relative"
|
||||
style={{
|
||||
borderColor: 'rgba(139, 115, 85, 0.8)',
|
||||
background: `
|
||||
radial-gradient(circle at 30% 30%, rgba(220, 190, 150, 0.95) 0%, rgba(200, 170, 130, 0.9) 40%, rgba(180, 150, 110, 0.85) 100%),
|
||||
linear-gradient(135deg, rgba(240, 220, 180, 0.3) 0%, transparent 50%)
|
||||
`,
|
||||
boxShadow: `
|
||||
inset 0px 2px 8px rgba(0, 0, 0, 0.25),
|
||||
inset 0px -1px 4px rgba(255, 255, 255, 0.2),
|
||||
0px 4px 12px rgba(0, 0, 0, 0.15)
|
||||
`
|
||||
}}
|
||||
>
|
||||
{/* Stamp aging and wear */}
|
||||
<div
|
||||
className="absolute inset-0 rounded-full pointer-events-none"
|
||||
style={{
|
||||
background: `
|
||||
radial-gradient(circle at 70% 20%, rgba(160, 130, 90, 0.3) 0%, transparent 40%),
|
||||
radial-gradient(circle at 20% 80%, rgba(140, 110, 70, 0.2) 0%, transparent 35%)
|
||||
`,
|
||||
mixBlendMode: 'multiply'
|
||||
}}
|
||||
/>
|
||||
// {/* Ultra-realistic stamp - Responsive */}
|
||||
// <EditableCard
|
||||
// isEditing={editingCard === 'stamp'}
|
||||
// onEdit={() => setEditingCard(editingCard === 'stamp' ? null : 'stamp')}
|
||||
// style={{
|
||||
// position: 'absolute',
|
||||
// width: '12.5%',
|
||||
// height: '19.1%',
|
||||
// right: '3.5%',
|
||||
// bottom: '5.3%',
|
||||
// transform: 'rotate(-12deg)'
|
||||
// }}
|
||||
// editIcon={<Edit3 className="w-3 h-3 text-gray-600" />}
|
||||
// >
|
||||
// <div
|
||||
// className="w-full h-full border-2 border-dashed rounded-full flex items-center justify-center relative"
|
||||
// style={{
|
||||
// borderColor: 'rgba(139, 115, 85, 0.8)',
|
||||
// background: `
|
||||
// radial-gradient(circle at 30% 30%, rgba(220, 190, 150, 0.95) 0%, rgba(200, 170, 130, 0.9) 40%, rgba(180, 150, 110, 0.85) 100%),
|
||||
// linear-gradient(135deg, rgba(240, 220, 180, 0.3) 0%, transparent 50%)
|
||||
// `,
|
||||
// boxShadow: `
|
||||
// inset 0px 2px 8px rgba(0, 0, 0, 0.25),
|
||||
// inset 0px -1px 4px rgba(255, 255, 255, 0.2),
|
||||
// 0px 4px 12px rgba(0, 0, 0, 0.15)
|
||||
// `
|
||||
// }}
|
||||
// >
|
||||
// {/* Stamp aging and wear */}
|
||||
// <div
|
||||
// className="absolute inset-0 rounded-full pointer-events-none"
|
||||
// style={{
|
||||
// background: `
|
||||
// radial-gradient(circle at 70% 20%, rgba(160, 130, 90, 0.3) 0%, transparent 40%),
|
||||
// radial-gradient(circle at 20% 80%, rgba(140, 110, 70, 0.2) 0%, transparent 35%)
|
||||
// `,
|
||||
// mixBlendMode: 'multiply'
|
||||
// }}
|
||||
// />
|
||||
|
||||
{/* Stamp inner details */}
|
||||
<div className="absolute inset-3 border border-amber-800/50 rounded-full" />
|
||||
<div className="absolute inset-5 border border-amber-800/30 rounded-full" />
|
||||
// {/* Stamp inner details */}
|
||||
// <div className="absolute inset-3 border border-amber-800/50 rounded-full" />
|
||||
// <div className="absolute inset-5 border border-amber-800/30 rounded-full" />
|
||||
|
||||
{/* Stamp text */}
|
||||
<div className="text-center leading-tight z-10" style={{ color: 'rgba(101, 84, 63, 0.9)' }}>
|
||||
<div style={{ fontSize: 'clamp(6px, 1.25vw, 9px)', fontWeight: '700', letterSpacing: '1px' }}>
|
||||
TRAVEL
|
||||
</div>
|
||||
<div style={{ fontSize: 'clamp(5px, 0.97vw, 7px)', fontWeight: '600', marginTop: '2px', letterSpacing: '0.5px' }}>
|
||||
MEMORIES
|
||||
</div>
|
||||
<div style={{ fontSize: 'clamp(5px, 0.97vw, 7px)', fontWeight: '500', marginTop: '1px' }}>
|
||||
2024
|
||||
</div>
|
||||
</div>
|
||||
// {/* Stamp text */}
|
||||
// <div className="text-center leading-tight z-10" style={{ color: 'rgba(101, 84, 63, 0.9)' }}>
|
||||
// <div style={{ fontSize: 'clamp(6px, 1.25vw, 9px)', fontWeight: '700', letterSpacing: '1px' }}>
|
||||
// TRAVEL
|
||||
// </div>
|
||||
// <div style={{ fontSize: 'clamp(5px, 0.97vw, 7px)', fontWeight: '600', marginTop: '2px', letterSpacing: '0.5px' }}>
|
||||
// MEMORIES
|
||||
// </div>
|
||||
// <div style={{ fontSize: 'clamp(5px, 0.97vw, 7px)', fontWeight: '500', marginTop: '1px' }}>
|
||||
// 2024
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
{/* Stamp perforations with realistic variations */}
|
||||
{[...Array(20)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute rounded-full"
|
||||
style={{
|
||||
width: '2px',
|
||||
height: '2px',
|
||||
backgroundColor: 'rgba(101, 84, 63, 0.4)',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: `translate(-50%, -50%) rotate(${i * 18}deg) translateY(-42px)`,
|
||||
opacity: Math.random() > 0.1 ? 1 : 0.3 // Random missing perforations
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
// {/* Stamp perforations with realistic variations */}
|
||||
// {[...Array(20)].map((_, i) => (
|
||||
// <div
|
||||
// key={i}
|
||||
// className="absolute rounded-full"
|
||||
// style={{
|
||||
// width: '2px',
|
||||
// height: '2px',
|
||||
// backgroundColor: 'rgba(101, 84, 63, 0.4)',
|
||||
// top: '50%',
|
||||
// left: '50%',
|
||||
// transform: `translate(-50%, -50%) rotate(${i * 18}deg) translateY(-42px)`,
|
||||
// opacity: Math.random() > 0.1 ? 1 : 0.3 // Random missing perforations
|
||||
// }}
|
||||
// />
|
||||
// ))}
|
||||
|
||||
{/* Stamp smudge mark */}
|
||||
<div
|
||||
className="absolute w-3 h-2 opacity-25"
|
||||
style={{
|
||||
background: 'radial-gradient(ellipse, rgba(101, 84, 63, 0.4) 0%, transparent 70%)',
|
||||
bottom: '15%',
|
||||
right: '20%',
|
||||
transform: 'rotate(20deg)',
|
||||
filter: 'blur(0.5px)'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</EditableCard>
|
||||
// {/* Stamp smudge mark */}
|
||||
// <div
|
||||
// className="absolute w-3 h-2 opacity-25"
|
||||
// style={{
|
||||
// background: 'radial-gradient(ellipse, rgba(101, 84, 63, 0.4) 0%, transparent 70%)',
|
||||
// bottom: '15%',
|
||||
// right: '20%',
|
||||
// transform: 'rotate(20deg)',
|
||||
// filter: 'blur(0.5px)'
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// </EditableCard>
|
||||
|
||||
{/* Additional realistic aging effects */}
|
||||
<div
|
||||
className="absolute w-3 h-1 opacity-15"
|
||||
style={{
|
||||
background: 'linear-gradient(45deg, rgba(120, 100, 70, 0.3), transparent)',
|
||||
top: '20%',
|
||||
left: '60%',
|
||||
transform: 'rotate(45deg)',
|
||||
filter: 'blur(0.5px)'
|
||||
}}
|
||||
/>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
// {/* Additional realistic aging effects */}
|
||||
// <div
|
||||
// className="absolute w-3 h-1 opacity-15"
|
||||
// style={{
|
||||
// background: 'linear-gradient(45deg, rgba(120, 100, 70, 0.3), transparent)',
|
||||
// top: '20%',
|
||||
// left: '60%',
|
||||
// transform: 'rotate(45deg)',
|
||||
// filter: 'blur(0.5px)'
|
||||
// }}
|
||||
// />
|
||||
// </motion.div>
|
||||
// );
|
||||
// };
|
||||
|
||||
return (
|
||||
<section ref={sectionRef} className="py-12 md:py-16 lg:py-20 bg-white relative overflow-hidden">
|
||||
@@ -700,7 +700,7 @@ export function CustomPostcards() {
|
||||
<h2 className="text-3xl md:text-4xl lg:text-5xl xl:text-6xl text-gray-900 mb-6">
|
||||
<span className="font-light">The Only Card That Sends Your</span>
|
||||
<span className="block">
|
||||
<span className="font-bold text-warm-coral italic">
|
||||
<span className="font-bold text-warm-coral italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-2">
|
||||
Holiday
|
||||
</span>{' '}
|
||||
<span className="font-normal">Home.</span>
|
||||
@@ -783,7 +783,8 @@ export function CustomPostcards() {
|
||||
WebkitBackfaceVisibility: "hidden"
|
||||
}}
|
||||
>
|
||||
<PostcardFrame />
|
||||
{/* <PostcardFrame /> */}
|
||||
<img src={front} alt="Postcard Image" />
|
||||
|
||||
{/* Subtle glow effect */}
|
||||
<motion.div
|
||||
|
||||
@@ -483,7 +483,7 @@ export function DiscoverPage({
|
||||
transition={{ duration: 0.6, delay: 0.1 }}
|
||||
>
|
||||
<span className="font-light text-gray-900">Unlock Your </span>
|
||||
<span className="font-bold text-transparent bg-clip-text bg-gradient-to-r from-primary to-orange-500 italic">Adventure</span>
|
||||
<span className="font-bold text-transparent bg-clip-text bg-gradient-to-r from-primary to-orange-500 italic pr-2">Adventure</span>
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
className="font-poppins text-xl leading-relaxed font-light text-gray-600 max-w-2xl mx-auto"
|
||||
|
||||
@@ -91,7 +91,7 @@ export function EnhancedTestimonials() {
|
||||
>
|
||||
<h2 className="text-4xl lg:text-5xl xl:text-6xl mb-6">
|
||||
<span className="font-light">What our</span>{' '}
|
||||
<span className="bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent font-bold italic">
|
||||
<span className="bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent font-bold italic pr-1">
|
||||
travelers
|
||||
</span>{' '}
|
||||
<span className="font-normal">say</span>
|
||||
|
||||
@@ -244,7 +244,7 @@ export function FAQPage({
|
||||
|
||||
<h1 className="font-merchant font-light text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-6">
|
||||
Frequently Asked{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-2">
|
||||
Questions
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { CreditCard, MapPin, Calendar, Zap, ChevronLeft, ChevronRight, Smartphon
|
||||
import { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import { ImageWithFallback } from './figma/ImageWithFallback';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
const steps = [
|
||||
{
|
||||
@@ -51,6 +52,8 @@ const steps = [
|
||||
export function HowItWorks() {
|
||||
const [activeStep, setActiveStep] = useState(0); // Start with first step active
|
||||
|
||||
const location = useLocation()
|
||||
|
||||
const nextStep = () => {
|
||||
setActiveStep((prev) => (prev + 1) % steps.length);
|
||||
};
|
||||
@@ -78,8 +81,10 @@ export function HowItWorks() {
|
||||
</div>
|
||||
<h2 className="text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-4">
|
||||
<span className="font-light">How Your</span>{' '}
|
||||
<span className="font-normal">Melbourne</span>{' '}
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">City Card</span>{' '}
|
||||
{!location.pathname.includes("landing") &&
|
||||
<span className="font-normal">Melbourne </span>
|
||||
}
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic pr-2">City Card</span>{' '}
|
||||
<span className="font-light">Works.</span>
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
|
||||
@@ -131,7 +131,7 @@ export function LandingMagicItinerary() {
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<span className="font-light">Plan Your</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-warm-coral via-orange-500 to-rose-500 bg-clip-text text-transparent drop-shadow-lg">
|
||||
<span className="font-bold italic bg-gradient-to-r from-warm-coral via-orange-500 to-rose-500 bg-clip-text pr-2 text-transparent drop-shadow-lg">
|
||||
Dream Journey
|
||||
</span>
|
||||
<br />
|
||||
|
||||
@@ -5,364 +5,422 @@ import { Button } from './ui/button';
|
||||
import { Card, CardContent } from './ui/card';
|
||||
import { Badge } from './ui/badge';
|
||||
import Navbar from './Navbar';
|
||||
// import SubNavbar from './SubNavbar';
|
||||
import { Footer } from './Footer';
|
||||
import { MobileAppSection } from './MobileAppSection';
|
||||
import { EnhancedTestimonials } from './EnhancedTestimonials';
|
||||
import { HowItWorks } from './HowItWorks';
|
||||
import { ImageWithFallback } from './figma/ImageWithFallback';
|
||||
import { PersonalizedTourHero } from './PersonalizedTourHero';
|
||||
import { Layout } from '../Layout';
|
||||
|
||||
interface User {
|
||||
email: string;
|
||||
name: string;
|
||||
email: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface MagicItineraryPageProps {
|
||||
onBackClick: () => void;
|
||||
onHomeClick: () => void;
|
||||
onMelbourneClick: () => void;
|
||||
onPassesClick: () => void;
|
||||
onCheckoutClick: () => void;
|
||||
onSignInClick: () => void;
|
||||
onSignOutClick?: () => void;
|
||||
onAttractionsClick: () => void;
|
||||
onBlogsClick: () => void;
|
||||
onHowItWorksClick: () => void;
|
||||
onFAQClick: () => void;
|
||||
onPrivacyPolicyClick: () => void;
|
||||
onAboutUsClick: () => void;
|
||||
onProfileClick: () => void;
|
||||
onCityCardsClick: () => void;
|
||||
onMagicItineraryClick: () => void;
|
||||
onPostCardsClick: () => void;
|
||||
onOffersClick: () => void;
|
||||
onContactUsClick?: () => void;
|
||||
onEsimsClick?: () => void;
|
||||
onHotelDiscountsClick?: () => void;
|
||||
onCreateItineraryClick: () => void;
|
||||
onViewItineraryClick: () => void;
|
||||
currentPage: string;
|
||||
user: User | null;
|
||||
onBackClick: () => void;
|
||||
onHomeClick: () => void;
|
||||
onMelbourneClick: () => void;
|
||||
onPassesClick: () => void;
|
||||
onCheckoutClick: () => void;
|
||||
onSignInClick: () => void;
|
||||
onSignOutClick?: () => void;
|
||||
onAttractionsClick: () => void;
|
||||
onBlogsClick: () => void;
|
||||
onHowItWorksClick: () => void;
|
||||
onFAQClick: () => void;
|
||||
onPrivacyPolicyClick: () => void;
|
||||
onAboutUsClick: () => void;
|
||||
onProfileClick: () => void;
|
||||
onCityCardsClick: () => void;
|
||||
onMagicItineraryClick: () => void;
|
||||
onPostCardsClick: () => void;
|
||||
onOffersClick: () => void;
|
||||
onSuperSavingsClick?: () => void;
|
||||
onContactUsClick?: () => void;
|
||||
onEsimsClick?: () => void;
|
||||
onHotelDiscountsClick?: () => void;
|
||||
onCreateItineraryClick: () => void;
|
||||
onViewItineraryClick: () => void;
|
||||
currentPage: string;
|
||||
user: User | null;
|
||||
}
|
||||
|
||||
export function MagicItineraryPage({
|
||||
onBackClick,
|
||||
onHomeClick,
|
||||
onMelbourneClick,
|
||||
onPassesClick,
|
||||
onCheckoutClick,
|
||||
onSignInClick,
|
||||
onSignOutClick,
|
||||
onAttractionsClick,
|
||||
onBlogsClick,
|
||||
onHowItWorksClick,
|
||||
onFAQClick,
|
||||
onPrivacyPolicyClick,
|
||||
onAboutUsClick,
|
||||
onProfileClick,
|
||||
onCityCardsClick,
|
||||
onMagicItineraryClick,
|
||||
onPostCardsClick,
|
||||
onOffersClick,
|
||||
onContactUsClick,
|
||||
onEsimsClick,
|
||||
onHotelDiscountsClick,
|
||||
onCreateItineraryClick,
|
||||
onViewItineraryClick,
|
||||
currentPage,
|
||||
user
|
||||
onBackClick,
|
||||
onHomeClick,
|
||||
onMelbourneClick,
|
||||
onPassesClick,
|
||||
onCheckoutClick,
|
||||
onSignInClick,
|
||||
onSignOutClick,
|
||||
onAttractionsClick,
|
||||
onBlogsClick,
|
||||
onHowItWorksClick,
|
||||
onFAQClick,
|
||||
onPrivacyPolicyClick,
|
||||
onAboutUsClick,
|
||||
onProfileClick,
|
||||
onCityCardsClick,
|
||||
onMagicItineraryClick,
|
||||
onPostCardsClick,
|
||||
onOffersClick,
|
||||
onSuperSavingsClick,
|
||||
onContactUsClick,
|
||||
onEsimsClick,
|
||||
onHotelDiscountsClick,
|
||||
onCreateItineraryClick,
|
||||
onViewItineraryClick,
|
||||
currentPage,
|
||||
user
|
||||
}: MagicItineraryPageProps) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Navbar */}
|
||||
<Layout
|
||||
activeCity="Melbourne"
|
||||
onSignInClick={onSignInClick}
|
||||
onSignOutClick={onSignOutClick}
|
||||
user={user}
|
||||
>
|
||||
return (
|
||||
|
||||
{/* Sub Navbar */}
|
||||
{/* <SubNavbar
|
||||
activeTab="magic-itinerary"
|
||||
onCityCardsClick={onCityCardsClick}
|
||||
onMagicItineraryClick={onMagicItineraryClick}
|
||||
onPostCardsClick={onPostCardsClick}
|
||||
onOffersClick={onOffersClick}
|
||||
onEsimsClick={onEsimsClick}
|
||||
onHotelDiscountsClick={onHotelDiscountsClick}
|
||||
/> */}
|
||||
<Layout activeCity="Landingpage" onSignInClick={onSignInClick} onSignOutClick={onSignOutClick} user={user}>
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="relative pt-52 pb-20 overflow-hidden">
|
||||
{/* Background gradient */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-secondary/5 to-background"></div>
|
||||
<div className="min-h-screen bg-background">
|
||||
|
||||
<div className="container mx-auto px-4 relative z-10">
|
||||
<motion.div
|
||||
className="max-w-4xl mx-auto text-center"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<h1 className="font-merchant text-4xl md:text-5xl lg:text-6xl leading-tight mb-6">
|
||||
<span className="font-light">Plan Your Perfect</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
Melbourne Adventure
|
||||
</span>
|
||||
</h1>
|
||||
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||
Let our AI create a personalized itinerary just for you. Answer a few questions about your preferences,
|
||||
and we'll craft the perfect Melbourne experience tailored to your interests.
|
||||
</p>
|
||||
<Button
|
||||
onClick={onCreateItineraryClick}
|
||||
className="bg-primary hover:bg-primary/90 text-white px-8 py-6 font-poppins font-semibold text-lg"
|
||||
>
|
||||
Create My Magic Itinerary
|
||||
</Button>
|
||||
</motion.div>
|
||||
</div>
|
||||
{/* Hero Section */}
|
||||
<PersonalizedTourHero
|
||||
onCreateItineraryClick={onCreateItineraryClick}
|
||||
/>
|
||||
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute top-20 left-10 w-20 h-20 bg-primary/10 rounded-full blur-xl"></div>
|
||||
<div className="absolute bottom-20 right-10 w-32 h-32 bg-secondary/10 rounded-full blur-xl"></div>
|
||||
</section>
|
||||
{/* How It Works Section */}
|
||||
<HowItWorks />
|
||||
|
||||
{/* How It Works Section */}
|
||||
<HowItWorks />
|
||||
{/* Features Section */}
|
||||
<section className="py-16 bg-gradient-to-br from-gray-50 to-gray-100">
|
||||
<div className="container mx-auto px-4">
|
||||
{/* Section Header */}
|
||||
<motion.div
|
||||
className="text-center mb-16 max-w-3xl mx-auto"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<h2 className="font-poppins text-3xl md:text-4xl lg:text-5xl leading-tight mb-4">
|
||||
<span className="font-light text-gray-800">Smart Features for</span>{' '}
|
||||
<span className="font-bold" style={{ color: '#F95F62' }}>Smart Travelers</span>
|
||||
</h2>
|
||||
<p className="font-poppins text-base md:text-lg font-normal text-gray-600 leading-relaxed">
|
||||
Experience intelligent trip planning powered by AI technology
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Features Section */}
|
||||
<section className="py-16 bg-gradient-to-br from-gray-50 to-gray-100">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
||||
{/* Left side - Features */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
>
|
||||
<h2 className="font-merchant text-3xl mb-6">
|
||||
<span className="text-gray-900">Smart Features for</span><br />
|
||||
<span className="bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent">Smart Travelers</span>
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-start">
|
||||
{/* Left side - Features */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="space-y-5"
|
||||
>
|
||||
{[
|
||||
{
|
||||
icon: <Sparkles className="w-5 h-5" style={{ color: '#F95F62' }} />,
|
||||
title: 'AI-Powered Recommendations',
|
||||
description: 'Our advanced AI analyzes your preferences to suggest the perfect experiences'
|
||||
},
|
||||
{
|
||||
icon: <Clock className="w-5 h-5" style={{ color: '#F95F62' }} />,
|
||||
title: 'Optimized Scheduling',
|
||||
description: 'Smart timing that considers opening hours, travel time, and crowd patterns'
|
||||
},
|
||||
{
|
||||
icon: <MapPin className="w-5 h-5" style={{ color: '#F95F62' }} />,
|
||||
title: 'Location-Based Planning',
|
||||
description: 'Efficiently planned routes that minimize travel time and maximize experiences'
|
||||
},
|
||||
{
|
||||
icon: <Camera className="w-5 h-5" style={{ color: '#F95F62' }} />,
|
||||
title: 'Instagram-Worthy Spots',
|
||||
description: 'Discover hidden gems and perfect photo opportunities along your journey'
|
||||
}
|
||||
].map((feature, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.1 }}
|
||||
className="group relative bg-white rounded-2xl p-6 shadow-sm hover:shadow-xl transition-all duration-300 border border-gray-100 hover:border-gray-200"
|
||||
>
|
||||
{/* Subtle accent line */}
|
||||
<div
|
||||
className="absolute top-0 left-0 w-1 h-full rounded-l-2xl transition-all duration-300 group-hover:w-1.5"
|
||||
style={{ backgroundColor: '#F95F62' }}
|
||||
/>
|
||||
|
||||
<div className="space-y-6">
|
||||
{[
|
||||
{
|
||||
icon: <Sparkles className="w-6 h-6 text-purple-600" />,
|
||||
title: 'AI-Powered Recommendations',
|
||||
description: 'Our advanced AI analyzes your preferences to suggest the perfect experiences'
|
||||
},
|
||||
{
|
||||
icon: <Clock className="w-6 h-6 text-pink-600" />,
|
||||
title: 'Optimized Scheduling',
|
||||
description: 'Smart timing that considers opening hours, travel time, and crowd patterns'
|
||||
},
|
||||
{
|
||||
icon: <MapPin className="w-6 h-6 text-purple-600" />,
|
||||
title: 'Location-Based Planning',
|
||||
description: 'Efficiently planned routes that minimize travel time and maximize experiences'
|
||||
},
|
||||
{
|
||||
icon: <Camera className="w-6 h-6 text-pink-600" />,
|
||||
title: 'Instagram-Worthy Spots',
|
||||
description: 'Discover hidden gems and perfect photo opportunities along your journey'
|
||||
}
|
||||
].map((feature, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.1 }}
|
||||
className="flex items-start space-x-4"
|
||||
>
|
||||
<div className="flex-shrink-0 w-12 h-12 bg-white rounded-lg flex items-center justify-center shadow-md">
|
||||
{feature.icon}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-merchant text-lg mb-2">{feature.title}</h3>
|
||||
<p className="text-gray-600 font-poppins">{feature.description}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
<div className="flex items-start gap-4 ml-2">
|
||||
<div
|
||||
className="flex-shrink-0 w-12 h-12 rounded-xl flex items-center justify-center shadow-sm transition-all duration-300 group-hover:scale-110 group-hover:shadow-md"
|
||||
style={{ backgroundColor: 'rgba(249, 95, 98, 0.1)' }}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-poppins text-lg md:text-xl font-semibold leading-snug text-gray-900 mb-2">
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className="font-poppins text-sm md:text-base font-normal leading-relaxed text-gray-600">
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* Right side - Visual */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.4 }}
|
||||
className="relative"
|
||||
>
|
||||
<div className="bg-gradient-to-br from-purple-500 to-pink-500 rounded-2xl p-8 text-white">
|
||||
<h3 className="font-merchant text-2xl mb-6">Sample Itinerary</h3>
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{ time: '9:00 AM', activity: 'Coffee at Degraves Street', duration: '30 min' },
|
||||
{ time: '10:00 AM', activity: 'Royal Botanic Gardens', duration: '2 hours' },
|
||||
{ time: '1:00 PM', activity: 'Lunch at Queen Victoria Market', duration: '1 hour' },
|
||||
{ time: '3:00 PM', activity: 'Street Art Tour in Hosier Lane', duration: '1.5 hours' },
|
||||
{ time: '6:00 PM', activity: 'Sunset at Eureka Skydeck', duration: '1 hour' }
|
||||
].map((item, index) => (
|
||||
<div key={index} className="flex items-center space-x-4 bg-white/10 rounded-lg p-3">
|
||||
<div className="text-sm font-bold bg-white/20 px-2 py-1 rounded">
|
||||
{item.time}
|
||||
{/* Right side - Sample Itinerary */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 30 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.4 }}
|
||||
className="relative"
|
||||
>
|
||||
<div className="bg-white rounded-3xl p-8 shadow-lg border border-gray-100 overflow-hidden">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div className="w-10 h-10 rounded-xl flex items-center justify-center" style={{ backgroundColor: 'rgba(249, 95, 98, 0.1)' }}>
|
||||
<Calendar className="w-5 h-5" style={{ color: '#F95F62' }} />
|
||||
</div>
|
||||
<h3 className="font-poppins text-xl md:text-2xl font-semibold leading-snug text-gray-900">
|
||||
Sample Day Itinerary
|
||||
</h3>
|
||||
</div>
|
||||
<p className="font-poppins text-sm font-normal text-gray-600 leading-relaxed">
|
||||
A perfectly planned Melbourne adventure
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Timeline */}
|
||||
<div className="relative space-y-4">
|
||||
{/* Vertical line */}
|
||||
<div className="absolute left-[15px] top-3 bottom-3 w-0.5 bg-gray-200" />
|
||||
|
||||
{[
|
||||
{ time: '9:00 AM', activity: 'Coffee at Degraves Street', duration: '30 min', emoji: '☕' },
|
||||
{ time: '10:00 AM', activity: 'Royal Botanic Gardens', duration: '2 hours', emoji: '🌿' },
|
||||
{ time: '1:00 PM', activity: 'Lunch at Queen Victoria Market', duration: '1 hour', emoji: '🍽️' },
|
||||
{ time: '3:00 PM', activity: 'Street Art Tour in Hosier Lane', duration: '1.5 hours', emoji: '🎨' },
|
||||
{ time: '6:00 PM', activity: 'Sunset at Eureka Skydeck', duration: '1 hour', emoji: '🌅' }
|
||||
].map((item, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, x: -10 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.4, delay: 0.5 + index * 0.1 }}
|
||||
className="relative flex items-start gap-4 pl-10"
|
||||
>
|
||||
{/* Timeline dot */}
|
||||
<div
|
||||
className="absolute left-0 w-8 h-8 rounded-full border-4 border-white flex items-center justify-center shadow-sm"
|
||||
style={{ backgroundColor: index === 0 ? '#F95F62' : '#ffffff', borderColor: '#F95F62' }}
|
||||
>
|
||||
{index === 0 && <div className="w-2 h-2 rounded-full bg-white" />}
|
||||
</div>
|
||||
|
||||
<div className="flex-1 bg-gray-50 rounded-xl p-4 hover:bg-gray-100 transition-colors duration-200">
|
||||
<div className="flex items-start justify-between gap-3 mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-lg">{item.emoji}</span>
|
||||
<span className="font-poppins text-sm font-semibold" style={{ color: '#F95F62' }}>
|
||||
{item.time}
|
||||
</span>
|
||||
</div>
|
||||
<span className="font-poppins text-xs font-medium text-gray-500 bg-white px-2 py-1 rounded-full">
|
||||
{item.duration}
|
||||
</span>
|
||||
</div>
|
||||
<p className="font-poppins text-sm md:text-base font-medium text-gray-900 leading-snug">
|
||||
{item.activity}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Decorative gradient blur */}
|
||||
<div
|
||||
className="absolute -bottom-20 -right-20 w-40 h-40 rounded-full blur-3xl opacity-20 pointer-events-none"
|
||||
style={{ backgroundColor: '#F95F62' }}
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium">{item.activity}</div>
|
||||
<div className="text-xs text-white/80">{item.duration}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Benefits Section */}
|
||||
<section className="py-16">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h2 className="font-merchant text-3xl mb-4">Why Use Magic Itinerary?</h2>
|
||||
<p className="text-gray-600 font-poppins max-w-2xl mx-auto">
|
||||
Save time, discover more, and create unforgettable memories with personalized planning
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{
|
||||
icon: <Clock className="w-6 h-6" style={{ color: '#F95F62' }} />,
|
||||
title: 'Save Planning Time',
|
||||
description: 'Skip hours of research. Get a complete itinerary in under 5 minutes.',
|
||||
stat: '90% faster than manual planning'
|
||||
},
|
||||
{
|
||||
icon: <Star className="w-6 h-6" style={{ color: '#F95F62' }} />,
|
||||
title: 'Discover Hidden Gems',
|
||||
description: 'Find unique experiences and local favorites you might have missed.',
|
||||
stat: '50+ curated hidden spots'
|
||||
},
|
||||
{
|
||||
icon: <Heart className="w-6 h-6" style={{ color: '#F95F62' }} />,
|
||||
title: 'Personalized Experience',
|
||||
description: 'Every itinerary is unique, tailored specifically to your preferences.',
|
||||
stat: '1000+ possible combinations'
|
||||
}
|
||||
].map((benefit, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.1 }}
|
||||
>
|
||||
<Card className="h-full text-center hover:shadow-lg transition-shadow duration-300 border-gray-100">
|
||||
<CardContent className="p-8">
|
||||
<div className="flex justify-center mb-6">
|
||||
<div
|
||||
className="w-12 h-12 rounded-full flex items-center justify-center"
|
||||
style={{ backgroundColor: 'rgba(249, 95, 98, 0.1)' }}
|
||||
>
|
||||
{benefit.icon}
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="font-poppins text-xl md:text-2xl font-semibold leading-snug text-gray-900 mb-3">
|
||||
{benefit.title}
|
||||
</h3>
|
||||
<p className="font-poppins text-base font-normal leading-relaxed text-gray-600 mb-4">
|
||||
{benefit.description}
|
||||
</p>
|
||||
<Badge
|
||||
className="border-none font-poppins text-sm font-medium"
|
||||
style={{ backgroundColor: 'rgba(249, 95, 98, 0.1)', color: '#F95F62' }}
|
||||
>
|
||||
{benefit.stat}
|
||||
</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What's Included Section */}
|
||||
<section className="py-20 bg-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-center mb-16 max-w-3xl mx-auto"
|
||||
>
|
||||
<h2 className="font-poppins text-3xl md:text-4xl lg:text-5xl leading-tight mb-4">
|
||||
<span className="font-light text-gray-800">Everything You Need,</span>{' '}
|
||||
<span className="font-bold" style={{ color: '#F95F62' }}>All Included</span>
|
||||
</h2>
|
||||
<p className="font-poppins text-base md:text-lg font-normal leading-relaxed text-gray-600">
|
||||
Your Magic Itinerary comes with comprehensive features for an amazing Melbourne experience
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{[
|
||||
{
|
||||
emoji: '⏰',
|
||||
title: 'Detailed Timeline',
|
||||
description: 'Hour-by-hour schedule with optimal timing'
|
||||
},
|
||||
{
|
||||
emoji: '🚇',
|
||||
title: 'Transportation Tips',
|
||||
description: 'Best routes and transport options between locations'
|
||||
},
|
||||
{
|
||||
emoji: '⭐',
|
||||
title: 'Local Recommendations',
|
||||
description: 'Insider tips on food, shopping, and experiences'
|
||||
},
|
||||
{
|
||||
emoji: '💰',
|
||||
title: 'Budget Planning',
|
||||
description: 'Estimated costs and money-saving suggestions'
|
||||
},
|
||||
{
|
||||
emoji: '☔',
|
||||
title: 'Weather Backup Plans',
|
||||
description: 'Alternative indoor activities for rainy days'
|
||||
},
|
||||
{
|
||||
emoji: '📸',
|
||||
title: 'Photo Opportunities',
|
||||
description: 'Best spots and times for Instagram-worthy shots'
|
||||
},
|
||||
{
|
||||
emoji: '🏛️',
|
||||
title: 'Cultural Insights',
|
||||
description: 'Local history and interesting facts about each location'
|
||||
},
|
||||
{
|
||||
emoji: '🔔',
|
||||
title: 'Real-time Updates',
|
||||
description: 'Live information on closures, events, and crowds'
|
||||
}
|
||||
].map((item, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.05 }}
|
||||
className="group"
|
||||
>
|
||||
<div className="h-full bg-white rounded-2xl p-6 border border-gray-100 hover:border-gray-200 transition-all duration-300 hover:shadow-lg">
|
||||
<div className="flex flex-col items-center text-center">
|
||||
<div className="text-5xl mb-4 transition-all duration-300 group-hover:scale-110">
|
||||
{item.emoji}
|
||||
</div>
|
||||
<h3 className="font-poppins text-lg font-semibold leading-snug text-gray-900 mb-2">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="font-poppins text-sm font-normal leading-relaxed text-gray-600">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
|
||||
|
||||
{/* Mobile App Section */}
|
||||
<MobileAppSection />
|
||||
|
||||
{/* Customer Reviews */}
|
||||
<EnhancedTestimonials />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Benefits Section */}
|
||||
<section className="py-16">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h2 className="font-merchant text-3xl mb-4">Why Use Magic Itinerary?</h2>
|
||||
<p className="text-gray-600 font-poppins max-w-2xl mx-auto">
|
||||
Save time, discover more, and create unforgettable memories with personalized planning
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{
|
||||
icon: <Clock className="w-12 h-12 text-purple-600" />,
|
||||
title: 'Save Planning Time',
|
||||
description: 'Skip hours of research. Get a complete itinerary in under 5 minutes.',
|
||||
stat: '90% faster than manual planning'
|
||||
},
|
||||
{
|
||||
icon: <Star className="w-12 h-12 text-pink-600" />,
|
||||
title: 'Discover Hidden Gems',
|
||||
description: 'Find unique experiences and local favorites you might have missed.',
|
||||
stat: '50+ curated hidden spots'
|
||||
},
|
||||
{
|
||||
icon: <Heart className="w-12 h-12 text-purple-600" />,
|
||||
title: 'Personalized Experience',
|
||||
description: 'Every itinerary is unique, tailored specifically to your preferences.',
|
||||
stat: '1000+ possible combinations'
|
||||
}
|
||||
].map((benefit, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.1 }}
|
||||
>
|
||||
<Card className="h-full text-center hover:shadow-lg transition-shadow duration-300">
|
||||
<CardContent className="p-8">
|
||||
<div className="mb-4">
|
||||
{benefit.icon}
|
||||
</div>
|
||||
<h3 className="font-merchant text-xl mb-3">{benefit.title}</h3>
|
||||
<p className="text-gray-600 font-poppins mb-4">{benefit.description}</p>
|
||||
<Badge className="bg-gradient-to-r from-purple-100 to-pink-100 text-purple-700 border-none">
|
||||
{benefit.stat}
|
||||
</Badge>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What's Included Section */}
|
||||
<section className="py-16 bg-gradient-to-br from-purple-50 to-pink-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h2 className="font-merchant text-3xl mb-4">What's Included</h2>
|
||||
<p className="text-gray-600 font-poppins max-w-2xl mx-auto">
|
||||
Your Magic Itinerary comes with everything you need for an amazing Melbourne experience
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{[
|
||||
{
|
||||
title: 'Detailed Timeline',
|
||||
description: 'Hour-by-hour schedule with optimal timing'
|
||||
},
|
||||
{
|
||||
title: 'Transportation Tips',
|
||||
description: 'Best routes and transport options between locations'
|
||||
},
|
||||
{
|
||||
title: 'Local Recommendations',
|
||||
description: 'Insider tips on food, shopping, and experiences'
|
||||
},
|
||||
{
|
||||
title: 'Budget Planning',
|
||||
description: 'Estimated costs and money-saving suggestions'
|
||||
},
|
||||
{
|
||||
title: 'Weather Backup Plans',
|
||||
description: 'Alternative indoor activities for rainy days'
|
||||
},
|
||||
{
|
||||
title: 'Photo Opportunities',
|
||||
description: 'Best spots and times for Instagram-worthy shots'
|
||||
},
|
||||
{
|
||||
title: 'Cultural Insights',
|
||||
description: 'Local history and interesting facts about each location'
|
||||
},
|
||||
{
|
||||
title: 'Real-time Updates',
|
||||
description: 'Live information on closures, events, and crowds'
|
||||
}
|
||||
].map((item, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.05 }}
|
||||
>
|
||||
<Card className="h-full hover:shadow-md transition-shadow duration-300">
|
||||
<CardContent className="p-6 text-center">
|
||||
<h3 className="font-merchant text-lg mb-2">{item.title}</h3>
|
||||
<p className="text-gray-600 font-poppins text-sm">{item.description}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
|
||||
|
||||
{/* Mobile App Section */}
|
||||
<MobileAppSection />
|
||||
|
||||
{/* Customer Reviews */}
|
||||
<EnhancedTestimonials />
|
||||
|
||||
|
||||
</Layout>
|
||||
</div>
|
||||
);
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -281,7 +281,7 @@ export function MelbourneAttractions() {
|
||||
</div>
|
||||
<h2 className="heading-dynamic text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-4">
|
||||
<span className="font-light">Discover</span>{' '}
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic pr-1">
|
||||
Melbourne's
|
||||
</span>{' '}
|
||||
<span className="font-normal">Best</span>{' '}
|
||||
|
||||
@@ -116,7 +116,7 @@ export function MelbourneBlogs() {
|
||||
|
||||
<h2 className="font-merchant text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-6">
|
||||
<span className="font-normal">Melbourne</span>{' '}
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic pr-2">
|
||||
Blogs
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
@@ -124,7 +124,7 @@ export function MelbourneCardComparison({ onCheckoutClick }: MelbourneCardCompar
|
||||
</div>
|
||||
|
||||
<h2 className="font-merchant text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-6">
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic pr-2">
|
||||
Buy
|
||||
</span>{' '}
|
||||
<span className="font-normal">Now</span>
|
||||
|
||||
@@ -101,7 +101,7 @@ export function MelbourneFAQ() {
|
||||
|
||||
<h2 className="font-merchant text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-6">
|
||||
<span className="font-normal">Frequently Asked</span>{' '}
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
||||
<span className="pr-2 font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
||||
Questions
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
@@ -395,7 +395,7 @@ export function MelbournePage({
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<span className="font-light">Plan Your</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary via-orange-500 to-rose-500 bg-clip-text text-transparent drop-shadow-lg">
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary via-orange-500 to-rose-500 bg-clip-text text-transparent drop-shadow-lg pr-2">
|
||||
Dream Journey
|
||||
</span>
|
||||
<br />
|
||||
|
||||
@@ -89,7 +89,7 @@ export function MelbourneTourOverview() {
|
||||
>
|
||||
<h2 className="heading-dynamic font-merchant text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-8">
|
||||
<span className="font-light">Melbourne</span>{' '}
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
||||
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic pr-2">
|
||||
Tour
|
||||
</span>{' '}
|
||||
<span className="font-normal">Overview</span>
|
||||
|
||||
@@ -68,7 +68,7 @@ export function MobileAppSection() {
|
||||
>
|
||||
<h1 className="font-merchant text-4xl lg:text-5xl xl:text-6xl leading-tight text-foreground">
|
||||
<span className="font-normal">Access all your</span>{' '}
|
||||
<span className="bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent font-bold italic">
|
||||
<span className="bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent font-bold italic inline-block pr-2">
|
||||
city cards
|
||||
</span>
|
||||
<br />
|
||||
|
||||
@@ -142,6 +142,13 @@ export default function Navbar({
|
||||
path: '/faq',
|
||||
isShared: false
|
||||
},
|
||||
{
|
||||
label: 'Your PostCard',
|
||||
path: '/postcards',
|
||||
isShared: true,
|
||||
landingLabel: 'Your PostCard',
|
||||
melbourneLabel: 'Your PostCard'
|
||||
}
|
||||
],
|
||||
melbourne: [
|
||||
// Position 1
|
||||
@@ -177,6 +184,13 @@ export default function Navbar({
|
||||
isShared: true,
|
||||
landingLabel: 'Your Card',
|
||||
melbourneLabel: 'Your Card'
|
||||
},
|
||||
{
|
||||
label: 'Your PostCard',
|
||||
path: '/postcards',
|
||||
isShared: true,
|
||||
landingLabel: 'Your PostCard',
|
||||
melbourneLabel: 'Your PostCard'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -189,7 +189,7 @@ export function PassesPage({
|
||||
<div className="text-center mb-16">
|
||||
<div className="mb-6">
|
||||
<h1 className="font-merchant font-light text-4xl md:text-5xl lg:text-6xl mb-4">
|
||||
Buy <span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">Passes</span>
|
||||
Buy <span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-1.5">Passes</span>
|
||||
</h1>
|
||||
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-600 max-w-3xl mx-auto">
|
||||
Skip the lines, save money, and explore more with our flexible city cards designed for modern travelers
|
||||
@@ -329,7 +329,7 @@ export function PassesPage({
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="font-merchant text-4xl md:text-5xl text-gray-900 mb-6">
|
||||
<span className="font-light">Good to</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">Know</span>
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-2">Know</span>
|
||||
</h2>
|
||||
<p className="font-poppins text-lg text-gray-600 font-light max-w-2xl mx-auto leading-relaxed">
|
||||
Simple tips to help you get the most out of your CityCard experience
|
||||
@@ -604,7 +604,7 @@ export function PassesPage({
|
||||
<div className="p-8 lg:p-16">
|
||||
<h2 className="heading-dynamic text-4xl text-gray-900 mb-6">
|
||||
<span className="font-light">Access all your</span>{' '}
|
||||
<span className="font-bold italic text-gradient-primary">city cards</span>{' '}
|
||||
<span className="font-bold italic text-gradient-primary pr-2">city cards</span>{' '}
|
||||
<span className="font-normal">on your</span>{' '}
|
||||
<span className="font-semibold text-emphasis">phone</span>
|
||||
</h2>
|
||||
@@ -663,7 +663,7 @@ export function PassesPage({
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="heading-dynamic text-4xl text-gray-900 mb-4">
|
||||
<span className="font-light">Why Choose</span>{' '}
|
||||
<span className="font-bold italic text-gradient-primary">CityCards</span><span className="font-normal">?</span>
|
||||
<span className="font-bold italic text-gradient-primary pr-2">CityCards</span><span className="font-normal">?</span>
|
||||
</h2>
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto font-light">
|
||||
We're committed to providing the best city exploration experience with unmatched value and service
|
||||
|
||||
@@ -121,7 +121,8 @@ export function PersonalizedTourHero({ onCreateItineraryClick }: PersonalizedTou
|
||||
{/* Main Heading */}
|
||||
<h1 className="font-poppins text-4xl sm:text-5xl md:text-6xl leading-tight mb-6">
|
||||
<span className="font-light">Create Your</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary via-orange-500 to-rose-500 bg-clip-text text-transparent">
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary via-orange-500 to-rose-500
|
||||
bg-clip-text text-transparent inline-block overflow-visible whitespace-nowrap pr-2">
|
||||
Magic Itinerary
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
@@ -13,6 +13,8 @@ import { CustomPostcards } from './CustomPostcards';
|
||||
import { HowItWorks } from './HowItWorks';
|
||||
import { ImageWithFallback } from './figma/ImageWithFallback';
|
||||
import { Layout } from '../Layout';
|
||||
import front from '../assets/front.jpg'
|
||||
|
||||
|
||||
interface User {
|
||||
email: string;
|
||||
@@ -73,165 +75,155 @@ export function PostCardsPage({
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Navbar */}
|
||||
<Layout
|
||||
activeCity="Landingpage"
|
||||
onSignInClick={onSignInClick}
|
||||
onSignOutClick={onSignOutClick}
|
||||
user={user}
|
||||
>
|
||||
<Layout
|
||||
activeCity="Landingpage"
|
||||
onSignInClick={onSignInClick}
|
||||
onSignOutClick={onSignOutClick}
|
||||
user={user}
|
||||
>
|
||||
|
||||
{/* Sub Navbar */}
|
||||
{/* <SubNavbar
|
||||
activeTab="postcards"
|
||||
onCityCardsClick={onCityCardsClick}
|
||||
onMagicItineraryClick={onMagicItineraryClick}
|
||||
onPostCardsClick={onPostCardsClick}
|
||||
onOffersClick={onOffersClick}
|
||||
onEsimsClick={onEsimsClick}
|
||||
onHotelDiscountsClick={onHotelDiscountsClick}
|
||||
/> */}
|
||||
{/* Hero Section */}
|
||||
<section className="relative pt-52 pb-20 overflow-hidden">
|
||||
{/* Background gradient */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-secondary/5 to-background"></div>
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="relative pt-52 pb-20 overflow-hidden">
|
||||
{/* Background gradient */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-secondary/5 to-background"></div>
|
||||
|
||||
<div className="container mx-auto px-4 relative z-10">
|
||||
<motion.div
|
||||
className="max-w-4xl mx-auto text-center"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<h1 className="font-merchant text-4xl md:text-5xl lg:text-6xl leading-tight mb-6">
|
||||
<span className="font-light">Create Beautiful</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
Custom Postcards
|
||||
</span>
|
||||
</h1>
|
||||
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||
Transform your travel memories into stunning, personalized postcards with authentic handwritten messages.
|
||||
Share your journey in a way that feels truly personal and meaningful.
|
||||
</p>
|
||||
<Button
|
||||
<div className="flex mx-auto items-center px-4 relative z-10">
|
||||
<motion.div
|
||||
className="max-w-2xl mx-auto text-left"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<h1 className="font-merchant text-4xl md:text-5xl lg:text-6xl leading-tight mb-6">
|
||||
<span className="font-light">Create Beautiful</span>{' '}
|
||||
<span className="font-bold inline-block italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-2">
|
||||
Custom Postcards
|
||||
</span>
|
||||
</h1>
|
||||
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||
Transform your travel memories into stunning, personalized postcards with authentic handwritten messages.
|
||||
Share your journey in a way that feels truly personal and meaningful.
|
||||
</p>
|
||||
{/* <Button
|
||||
onClick={onCheckoutClick}
|
||||
className="bg-primary hover:bg-primary/90 text-white px-8 py-6 font-poppins font-semibold text-lg"
|
||||
>
|
||||
Start Creating Postcards
|
||||
</Button>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute top-20 left-10 w-20 h-20 bg-primary/10 rounded-full blur-xl"></div>
|
||||
<div className="absolute bottom-20 right-10 w-32 h-32 bg-secondary/10 rounded-full blur-xl"></div>
|
||||
</section>
|
||||
|
||||
{/* Reuse CustomPostcards Component */}
|
||||
<CustomPostcards />
|
||||
|
||||
{/* How It Works Section */}
|
||||
<HowItWorks />
|
||||
|
||||
{/* Features Section */}
|
||||
|
||||
|
||||
{/* Gallery Section */}
|
||||
<section className="py-16 bg-gradient-to-br from-amber-50 to-orange-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h2 className="font-merchant text-3xl mb-4">Postcard Gallery</h2>
|
||||
<p className="text-gray-600 font-poppins max-w-2xl mx-auto">
|
||||
Get inspired by beautiful postcards created by our community of travelers
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{[
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Tropical Paradise',
|
||||
message: 'Greetings from paradise! The beaches here are absolutely breathtaking...',
|
||||
location: 'Maldives'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1499856871958-5b9627545d1a?w=400&h=600&fit=crop',
|
||||
title: 'City Adventures',
|
||||
message: 'Having the most amazing time exploring this incredible city...',
|
||||
location: 'Paris, France'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Mountain Views',
|
||||
message: 'The views from up here are simply unbelievable. Wish you were here...',
|
||||
location: 'Swiss Alps'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Cultural Journey',
|
||||
message: 'Immersing myself in the rich culture and history of this amazing place...',
|
||||
location: 'Kyoto, Japan'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Safari Adventure',
|
||||
message: 'Just saw the most incredible wildlife! This experience is unforgettable...',
|
||||
location: 'Kenya, Africa'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Island Escape',
|
||||
message: 'Living the island life and loving every moment of this peaceful retreat...',
|
||||
location: 'Santorini, Greece'
|
||||
}
|
||||
].map((postcard, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.1 }}
|
||||
>
|
||||
<Card className="hover:shadow-xl transition-all duration-300 transform hover:-translate-y-2">
|
||||
<CardContent className="p-0">
|
||||
<div className="relative">
|
||||
<ImageWithFallback
|
||||
src={postcard.image}
|
||||
alt={postcard.title}
|
||||
className="w-full h-48 object-cover rounded-t-lg"
|
||||
/>
|
||||
<Badge className="absolute top-3 left-3 bg-white/90 text-gray-700">
|
||||
{postcard.location}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="p-6">
|
||||
<h3 className="font-merchant text-lg mb-2">{postcard.title}</h3>
|
||||
<p className="text-gray-600 font-poppins text-sm italic">"{postcard.message}"</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
))}
|
||||
</Button> */}
|
||||
</motion.div>
|
||||
< img src={front} alt='Postcard image' />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Ready to Explore Melbourne Section */}
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute top-20 left-10 w-20 h-20 bg-primary/10 rounded-full blur-xl"></div>
|
||||
<div className="absolute bottom-20 right-10 w-32 h-32 bg-secondary/10 rounded-full blur-xl"></div>
|
||||
</section>
|
||||
|
||||
{/* How It Works Section */}
|
||||
<HowItWorks />
|
||||
|
||||
{/* Reuse CustomPostcards Component */}
|
||||
<CustomPostcards />
|
||||
|
||||
{/* Features Section */}
|
||||
|
||||
|
||||
{/* Gallery Section */}
|
||||
<section className="py-16 bg-gradient-to-br from-amber-50 to-orange-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
className="text-center mb-12"
|
||||
>
|
||||
<h2 className="text-4xl lg:text-5xl xl:text-6xl mb-6">
|
||||
<span className="font-light">Postcard</span>{' '}
|
||||
<span className="bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent font-bold italic pr-2">
|
||||
Gallery
|
||||
</span>{' '}
|
||||
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600 font-poppins max-w-2xl mx-auto">
|
||||
Get inspired by beautiful postcards created by our community of travelers
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Mobile App Section */}
|
||||
<MobileAppSection />
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{[
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Tropical Paradise',
|
||||
message: 'Greetings from paradise! The beaches here are absolutely breathtaking...',
|
||||
location: 'Maldives'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1499856871958-5b9627545d1a?w=400&h=600&fit=crop',
|
||||
title: 'City Adventures',
|
||||
message: 'Having the most amazing time exploring this incredible city...',
|
||||
location: 'Paris, France'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Mountain Views',
|
||||
message: 'The views from up here are simply unbelievable. Wish you were here...',
|
||||
location: 'Swiss Alps'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Cultural Journey',
|
||||
message: 'Immersing myself in the rich culture and history of this amazing place...',
|
||||
location: 'Kyoto, Japan'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Safari Adventure',
|
||||
message: 'Just saw the most incredible wildlife! This experience is unforgettable...',
|
||||
location: 'Kenya, Africa'
|
||||
},
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=600&fit=crop',
|
||||
title: 'Island Escape',
|
||||
message: 'Living the island life and loving every moment of this peaceful retreat...',
|
||||
location: 'Santorini, Greece'
|
||||
}
|
||||
].map((postcard, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.6, delay: 0.3 + index * 0.1 }}
|
||||
>
|
||||
{/* <Card className="hover:shadow-xl transition-all rounded-none duration-300 transform hover:-translate-y-2"> */}
|
||||
{/* <CardContent className="p-0"> */}
|
||||
<div className="relative">
|
||||
<ImageWithFallback
|
||||
src={postcard.image}
|
||||
alt={postcard.title}
|
||||
className="w-full h-78 object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-0">
|
||||
<Badge className="p-0 bg-inherit text-gray-700">
|
||||
{postcard.location}
|
||||
</Badge>
|
||||
<h3 className="font-merchant text-left font-bold text-lg mb-2">{postcard.title}</h3>
|
||||
<p className="font-poppins text-sm">"{postcard.message}"</p>
|
||||
</div>
|
||||
{/* </CardContent>
|
||||
</Card> */}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Customer Reviews */}
|
||||
<EnhancedTestimonials />
|
||||
{/* Customer Reviews */}
|
||||
<EnhancedTestimonials />
|
||||
|
||||
{/* Mobile App Section */}
|
||||
<MobileAppSection />
|
||||
|
||||
|
||||
</Layout>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -305,7 +305,7 @@ export function SuperSavingsPage({
|
||||
>
|
||||
<h1 className="font-poppins text-4xl md:text-5xl lg:text-6xl leading-tight mb-6">
|
||||
<span className="font-light">Unlock</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
<span className="pr-2 font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
Super Savings
|
||||
</span>
|
||||
</h1>
|
||||
@@ -355,7 +355,7 @@ export function SuperSavingsPage({
|
||||
>
|
||||
<h2 className="font-poppins text-3xl md:text-4xl lg:text-5xl leading-tight mb-4">
|
||||
<span className="font-light">Featured</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
<span className="pr-2 font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
Super Savings
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
@@ -151,7 +151,7 @@ export function TrustSection() {
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="font-merchant text-2xl md:text-3xl lg:text-4xl leading-tight mb-6 text-gray-900">
|
||||
<span className="font-light">What Our</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-1">
|
||||
Travelers
|
||||
</span>{' '}
|
||||
<span className="font-light">Say</span>
|
||||
|
||||
@@ -41,7 +41,7 @@ interface WhatsIncludedProps {
|
||||
user: User | null;
|
||||
}
|
||||
|
||||
export function WhatsIncluded({
|
||||
export function WhatsIncluded({
|
||||
onBackClick,
|
||||
onHomeClick,
|
||||
onMelbourneClick,
|
||||
|
||||
@@ -99,10 +99,13 @@ export function WhatsIncludedHero({ onCreateItineraryClick }: WhatsIncludedHeroP
|
||||
className="text-center max-w-4xl"
|
||||
>
|
||||
{/* Main Heading */}
|
||||
<h1 className="font-poppins text-4xl sm:text-5xl md:text-6xl leading-tight mb-6">
|
||||
<h1 className="font-poppins text-4xl sm:text-5xl md:text-6xl w-full leading-tight mb-6">
|
||||
<span className="font-light">One pass.</span>{' '}
|
||||
<span className="font-bold italic bg-gradient-to-r from-primary via-orange-500 to-rose-500 bg-clip-text text-transparent">
|
||||
Everything you need
|
||||
<span className="font-bold italic pr-2 bg-gradient-to-r from-primary via-orange-500 to-rose-500 bg-clip-text text-transparent">
|
||||
Everything you
|
||||
</span>{' '}
|
||||
<span className="font-bold italic pr-2 bg-gradient-to-r from-primary via-orange-500 to-rose-500 bg-clip-text text-transparent">
|
||||
need
|
||||
</span>{' '}
|
||||
<span className="font-light">to explore.</span>
|
||||
</h1>
|
||||
|
||||
@@ -3661,6 +3661,7 @@
|
||||
.bg-gradient-to-r {
|
||||
--tw-gradient-position: to right in oklab;
|
||||
background-image: linear-gradient(var(--tw-gradient-stops));
|
||||
/* padding-right: 8px; */
|
||||
}
|
||||
|
||||
.bg-gradient-to-t {
|
||||
|
||||
@@ -84,7 +84,7 @@ import * as path from 'path';
|
||||
outDir: 'build',
|
||||
},
|
||||
server: {
|
||||
port: 4008,
|
||||
port: 4009,
|
||||
open: true,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user