642 lines
36 KiB
TypeScript
642 lines
36 KiB
TypeScript
import { ArrowRight, Smartphone, MapPin, Star, Clock, Users, Heart, Share2, Filter, Search } from 'lucide-react';
|
||
import { motion } from 'motion/react';
|
||
import imgFrame1597884939 from "figma:asset/5da1b0444c0d21bc7ee776c49e36e2a8ea4d3e12.png";
|
||
|
||
export function MobileAppSection() {
|
||
// Generate a realistic QR code pattern
|
||
const generateQRPattern = () => {
|
||
const size = 21; // Standard QR code size
|
||
const pattern = [];
|
||
|
||
for (let i = 0; i < size * size; i++) {
|
||
// Create corner detection patterns
|
||
const row = Math.floor(i / size);
|
||
const col = i % size;
|
||
|
||
// Corner squares (7x7)
|
||
const isCornerSquare =
|
||
(row < 7 && col < 7) || // Top-left
|
||
(row < 7 && col >= 14) || // Top-right
|
||
(row >= 14 && col < 7); // Bottom-left
|
||
|
||
// Finder patterns within corner squares
|
||
const isFinderPattern = isCornerSquare && (
|
||
(row === 0 || row === 6 || col === 0 || col === 6) ||
|
||
(row >= 2 && row <= 4 && col >= 2 && col <= 4)
|
||
);
|
||
|
||
// Timing patterns
|
||
const isTimingPattern = (row === 6 && col >= 8 && col <= 12) || (col === 6 && row >= 8 && row <= 12);
|
||
|
||
// Random data pattern for other areas
|
||
const isDataPattern = !isCornerSquare && !isTimingPattern && Math.random() > 0.45;
|
||
|
||
pattern.push(isFinderPattern || isTimingPattern || isDataPattern);
|
||
}
|
||
|
||
return pattern;
|
||
};
|
||
|
||
const qrPattern = generateQRPattern();
|
||
|
||
return (
|
||
<section className="bg-muted/30 relative overflow-hidden">
|
||
{/* Subtle Background Elements */}
|
||
<div className="absolute inset-0">
|
||
<div className="absolute top-1/3 left-1/6 w-64 h-64 bg-primary/3 rounded-full blur-3xl"></div>
|
||
<div className="absolute bottom-1/2 right-1/6 w-48 h-48 bg-secondary/3 rounded-full blur-3xl"></div>
|
||
</div>
|
||
|
||
<div className="container mx-auto px-4 pt-4 relative z-10">
|
||
{/* Figma Layout Implementation */}
|
||
<motion.div
|
||
className="flex flex-col gap-16 lg:gap-20"
|
||
initial={{ opacity: 0, y: 40 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.8, ease: "easeOut" }}
|
||
>
|
||
{/* Header Section - Following Figma Layout */}
|
||
<div className="flex flex-col lg:flex-row items-start justify-between gap-12 lg:gap-16">
|
||
{/* Left Side - Main Heading */}
|
||
<motion.div
|
||
className="flex-1 max-w-2xl"
|
||
initial={{ opacity: 0, x: -40 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.7, ease: "easeOut" }}
|
||
>
|
||
<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 inline-block pr-2">
|
||
city cards
|
||
</span>
|
||
<br />
|
||
<span className="font-normal">on your</span>{' '}
|
||
<span className="font-semibold">phone.</span>
|
||
</h1>
|
||
</motion.div>
|
||
|
||
{/* Right Side - Description and Buttons */}
|
||
<motion.div
|
||
className="flex flex-col gap-8 w-full lg:w-[400px] xl:w-[450px]"
|
||
initial={{ opacity: 0, x: 40 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.7, ease: "easeOut", delay: 0.1 }}
|
||
>
|
||
{/* Description Text */}
|
||
<p className="font-poppins text-lg text-muted-foreground leading-relaxed font-normal">
|
||
Download our mobile app and unlock instant access to premium city experiences across Australia.
|
||
</p>
|
||
|
||
{/* Download Buttons - Following Figma Layout */}
|
||
<div className="flex flex-col sm:flex-row gap-6">
|
||
{/* Android Download Button */}
|
||
<motion.button
|
||
className="interactive-button relative flex items-center gap-3 bg-foreground text-background px-6 py-4 rounded-xl font-medium text-base hover:bg-foreground/90 transition-all duration-300 shadow-lg hover:shadow-xl flex-1 overflow-hidden group"
|
||
whileHover={{ scale: 1.02, y: -2 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
transition={{ duration: 0.2 }}
|
||
>
|
||
{/* Continuous Shine Effect */}
|
||
<div className="absolute inset-0 -top-px opacity-100">
|
||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/25 to-transparent transform -skew-x-12 animate-shine"></div>
|
||
</div>
|
||
|
||
{/* Google Play Logo */}
|
||
<svg className="w-6 h-6 relative z-10" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M3,20.5V3.5C3,2.91 3.34,2.39 3.84,2.15L13.69,12L3.84,21.85C3.34,21.6 3,21.09 3,20.5M16.81,15.12L6.05,21.34L14.54,12.85L16.81,15.12M20.16,10.81C20.5,11.08 20.75,11.5 20.75,12C20.75,12.5 20.53,12.9 20.18,13.18L17.89,14.5L15.39,12L17.89,9.5L20.16,10.81M6.05,2.66L16.81,8.88L14.54,11.15L6.05,2.66Z"/>
|
||
</svg>
|
||
<div className="text-left relative z-10">
|
||
<div className="font-poppins text-xs opacity-80">Get it on</div>
|
||
<div className="font-poppins font-semibold">Google Play</div>
|
||
</div>
|
||
</motion.button>
|
||
|
||
{/* iOS Download Button */}
|
||
<motion.button
|
||
className="interactive-button relative flex items-center gap-3 bg-foreground text-background px-6 py-4 rounded-xl font-medium text-base hover:bg-foreground/90 transition-all duration-300 shadow-lg hover:shadow-xl flex-1 overflow-hidden group"
|
||
whileHover={{ scale: 1.02, y: -2 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
transition={{ duration: 0.2 }}
|
||
>
|
||
{/* Continuous Shine Effect */}
|
||
<div className="absolute inset-0 -top-px opacity-100">
|
||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/25 to-transparent transform -skew-x-12 animate-shine"></div>
|
||
</div>
|
||
|
||
{/* Apple Logo */}
|
||
<svg className="w-6 h-6 relative z-10" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/>
|
||
</svg>
|
||
<div className="text-left relative z-10">
|
||
<div className="font-poppins text-xs opacity-80">Download on the</div>
|
||
<div className="font-poppins font-semibold">App Store</div>
|
||
</div>
|
||
</motion.button>
|
||
</div>
|
||
</motion.div>
|
||
</div>
|
||
|
||
{/* Mobile Mockups Section - Ultra-Realistic and Larger */}
|
||
<motion.div
|
||
className="relative w-full h-[400px] lg:h-[500px] rounded-3xl overflow-hidden shadow-2xl"
|
||
initial={{ opacity: 0, y: 40 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.8, ease: "easeOut", delay: 0.2 }}
|
||
style={{
|
||
background: `url(${imgFrame1597884939}) center/cover`
|
||
}}
|
||
>
|
||
{/* Mobile Mockup 1 - Enhanced Main App Screen */}
|
||
<div className="absolute top-[-6rem] lg:top-[-7rem] right-[calc(50%-100px-8.25rem)] lg:right-[calc(50%-100px-10.25rem)]">
|
||
<motion.div
|
||
className="w-60 lg:w-64 xl:w-72 h-[420px] lg:h-[480px] xl:h-[540px] bg-white rounded-[2.5rem] shadow-2xl border-4 lg:border-8 border-gray-900 relative overflow-hidden"
|
||
initial={{ opacity: 0, y: -30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.6, delay: 0.4 }}
|
||
whileHover={{ scale: 1.02, rotateY: 2 }}
|
||
>
|
||
{/* iPhone Status Bar */}
|
||
<div className="flex justify-between items-center px-6 py-3 bg-white">
|
||
<div className="flex items-center gap-1">
|
||
<span className="text-sm font-semibold text-black">9:41</span>
|
||
</div>
|
||
<div className="flex items-center gap-1">
|
||
{/* Signal bars */}
|
||
<div className="flex gap-0.5">
|
||
{[1, 2, 3, 4].map((bar) => (
|
||
<div key={bar} className={`w-1 bg-black rounded-full ${bar === 1 ? 'h-1' : bar === 2 ? 'h-2' : bar === 3 ? 'h-3' : 'h-4'}`}></div>
|
||
))}
|
||
</div>
|
||
{/* WiFi */}
|
||
<svg className="w-4 h-4 ml-1" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/>
|
||
</svg>
|
||
{/* Battery */}
|
||
<div className="w-6 h-3 border border-black rounded-sm ml-1">
|
||
<div className="w-4 h-1.5 bg-green-500 rounded-sm m-0.5"></div>
|
||
</div>
|
||
<div className="w-0.5 h-2 bg-black rounded-r-sm"></div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* App Header */}
|
||
<div className="px-5 py-4 bg-gradient-to-r from-primary to-secondary">
|
||
<div className="flex items-center justify-between text-white mb-3">
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-8 h-8 bg-white/20 rounded-xl flex items-center justify-center">
|
||
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<h3 className="text-lg font-bold">CityCards</h3>
|
||
<div className="text-xs text-white/70">Premium Active</div>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center gap-3">
|
||
<div className="relative">
|
||
<Search className="w-5 h-5 text-white/80" />
|
||
<div className="absolute -top-1 -right-1 w-2 h-2 bg-orange-400 rounded-full"></div>
|
||
</div>
|
||
<div className="w-8 h-8 bg-white/20 rounded-full flex items-center justify-center">
|
||
<div className="w-4 h-4 bg-white rounded-full"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Location */}
|
||
<div className="flex items-center justify-between text-white/90">
|
||
<div className="flex items-center gap-2">
|
||
<MapPin className="w-4 h-4" />
|
||
<span className="text-sm font-medium">Sydney, NSW</span>
|
||
<div className="w-1 h-1 bg-white/60 rounded-full"></div>
|
||
<span className="text-xs">22°C ☀️</span>
|
||
</div>
|
||
<div className="flex items-center gap-2 text-xs bg-white/20 px-3 py-1.5 rounded-full">
|
||
<span className="w-2 h-2 bg-green-400 rounded-full animate-pulse"></span>
|
||
<span>3 active</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* App Content */}
|
||
<div className="flex-1 overflow-hidden">
|
||
{/* Today's Deal Banner */}
|
||
<div className="mx-5 my-4 bg-gradient-to-r from-purple-100 via-blue-100 to-indigo-100 rounded-xl p-4 border border-purple-200">
|
||
<div className="flex items-center justify-between mb-2">
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-xs font-bold text-purple-700 bg-purple-200 px-2 py-1 rounded-full">TODAY ONLY</span>
|
||
<div className="flex items-center gap-1 text-xs text-purple-600">
|
||
<Clock className="w-3 h-3" />
|
||
<span>8h left</span>
|
||
</div>
|
||
</div>
|
||
<Heart className="w-4 h-4 text-red-400" />
|
||
</div>
|
||
<h4 className="font-bold text-gray-900 text-sm mb-1">Sydney Explorer Pass</h4>
|
||
<p className="text-xs text-gray-700 mb-3">Visit 3+ attractions & get 40% off</p>
|
||
<div className="flex gap-2">
|
||
<button className="bg-purple-600 text-white px-3 py-1.5 rounded-lg text-xs font-semibold">
|
||
Activate
|
||
</button>
|
||
<button className="border border-purple-300 text-purple-700 px-3 py-1.5 rounded-lg text-xs font-medium">
|
||
Details
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Stats Bar */}
|
||
<div className="mx-5 mb-4">
|
||
<div className="bg-gray-50 rounded-xl p-3 border border-gray-100">
|
||
<div className="flex items-center justify-between text-sm">
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-5 h-5 bg-green-100 rounded-full flex items-center justify-center">
|
||
<span className="text-xs font-bold text-green-700">3</span>
|
||
</div>
|
||
<span className="text-gray-700 text-xs">Passes used today</span>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="font-bold text-green-600 text-sm">$127</div>
|
||
<div className="text-xs text-gray-500">saved</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Attraction Cards */}
|
||
<div className="mx-5 space-y-3">
|
||
{/* Opera House */}
|
||
<div className="bg-white border border-gray-200 rounded-xl p-3 shadow-sm relative">
|
||
<div className="absolute top-2 right-2 bg-yellow-100 text-yellow-600 text-xs font-bold px-2 py-1 rounded-full">
|
||
PREMIUM
|
||
</div>
|
||
<div className="flex gap-3 mb-2">
|
||
<div className="w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
|
||
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.94-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
|
||
</svg>
|
||
</div>
|
||
<div className="flex-1">
|
||
<div className="flex items-start justify-between">
|
||
<div>
|
||
<h4 className="font-bold text-gray-900 text-sm">Sydney Opera House</h4>
|
||
<div className="flex items-center gap-1 text-xs text-gray-600 mt-0.5">
|
||
<Star className="w-3 h-3 text-yellow-400 fill-current" />
|
||
<span className="font-medium">4.8</span>
|
||
<span className="text-gray-400">(2.4k)</span>
|
||
<span className="mx-1">•</span>
|
||
<MapPin className="w-3 h-3 text-blue-500" />
|
||
<span>2.3km</span>
|
||
</div>
|
||
</div>
|
||
<div className="flex gap-1">
|
||
<Heart className="w-3 h-3 text-gray-400" />
|
||
<Share2 className="w-3 h-3 text-gray-400" />
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center gap-1.5 mt-2 text-xs">
|
||
<div className="bg-orange-100 text-orange-700 px-2 py-0.5 rounded-full font-medium">
|
||
Architecture
|
||
</div>
|
||
<div className="bg-blue-100 text-blue-700 px-2 py-0.5 rounded-full font-medium">
|
||
Cultural
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-center justify-between pt-2 border-t border-gray-100">
|
||
<div className="flex items-center gap-2">
|
||
<div>
|
||
<div className="flex items-center gap-1">
|
||
<span className="text-base font-bold text-gray-900">$45</span>
|
||
<span className="text-xs text-gray-500 line-through">$75</span>
|
||
</div>
|
||
<div className="text-xs text-green-600 font-medium">Save $30</div>
|
||
</div>
|
||
<div className="text-xs bg-green-100 text-green-700 px-2 py-1 rounded-full border border-green-200">
|
||
40% OFF
|
||
</div>
|
||
</div>
|
||
<button className="bg-primary text-white px-3 py-1.5 rounded-lg font-semibold text-xs">
|
||
Use Pass
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Harbour Bridge */}
|
||
<div className="bg-white border border-gray-200 rounded-xl p-3 shadow-sm relative">
|
||
<div className="absolute top-2 right-2 bg-blue-100 text-blue-600 text-xs font-bold px-2 py-1 rounded-full">
|
||
POPULAR
|
||
</div>
|
||
<div className="flex gap-3 mb-2">
|
||
<div className="w-12 h-12 bg-gradient-to-br from-emerald-500 to-green-600 rounded-lg flex items-center justify-center">
|
||
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
||
</svg>
|
||
</div>
|
||
<div className="flex-1">
|
||
<div className="flex items-start justify-between">
|
||
<div>
|
||
<h4 className="font-bold text-gray-900 text-sm">Harbour Bridge Climb</h4>
|
||
<div className="flex items-center gap-1 text-xs text-gray-600 mt-0.5">
|
||
<Star className="w-3 h-3 text-yellow-400 fill-current" />
|
||
<span className="font-medium">4.9</span>
|
||
<span className="text-gray-400">(1.8k)</span>
|
||
<span className="mx-1">•</span>
|
||
<MapPin className="w-3 h-3 text-blue-500" />
|
||
<span>1.8km</span>
|
||
</div>
|
||
</div>
|
||
<div className="flex gap-1">
|
||
<Heart className="w-3 h-3 text-red-400 fill-current" />
|
||
<Share2 className="w-3 h-3 text-gray-400" />
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center gap-1.5 mt-2 text-xs">
|
||
<div className="bg-green-100 text-green-700 px-2 py-0.5 rounded-full font-medium">
|
||
Adventure
|
||
</div>
|
||
<div className="bg-red-100 text-red-700 px-2 py-0.5 rounded-full font-medium">
|
||
Iconic
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-center justify-between pt-2 border-t border-gray-100">
|
||
<div className="flex items-center gap-2">
|
||
<div>
|
||
<div className="flex items-center gap-1">
|
||
<span className="text-base font-bold text-gray-900">$159</span>
|
||
<span className="text-xs text-gray-500 line-through">$289</span>
|
||
</div>
|
||
<div className="text-xs text-green-600 font-medium">Save $130</div>
|
||
</div>
|
||
<div className="text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full border border-blue-200">
|
||
45% OFF
|
||
</div>
|
||
</div>
|
||
<button className="bg-primary text-white px-3 py-1.5 rounded-lg font-semibold text-xs">
|
||
Use Pass
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Botanic Gardens */}
|
||
<div className="bg-white border border-gray-200 rounded-xl p-3 shadow-sm relative">
|
||
<div className="absolute top-2 right-2 bg-emerald-100 text-emerald-600 text-xs font-bold px-2 py-1 rounded-full">
|
||
FREE
|
||
</div>
|
||
<div className="flex gap-3 mb-2">
|
||
<div className="w-12 h-12 bg-gradient-to-br from-green-400 to-emerald-500 rounded-lg flex items-center justify-center">
|
||
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M17,8C8,10 5.9,16.17 3.82,21.34L5.71,22L6.66,19.7C7.14,19.87 7.64,20 8,20C19,20 22,3 22,3C21,5 14,5.25 9,6.25C4,7.25 2,11.5 2,13.5C2,15.5 3.75,17.25 3.75,17.25C7,8 17,8 17,8Z"/>
|
||
</svg>
|
||
</div>
|
||
<div className="flex-1">
|
||
<div className="flex items-start justify-between">
|
||
<div>
|
||
<h4 className="font-bold text-gray-900 text-sm">Royal Botanic Gardens</h4>
|
||
<div className="flex items-center gap-1 text-xs text-gray-600 mt-0.5">
|
||
<Star className="w-3 h-3 text-yellow-400 fill-current" />
|
||
<span className="font-medium">4.7</span>
|
||
<span className="text-gray-400">(956)</span>
|
||
<span className="mx-1">•</span>
|
||
<MapPin className="w-3 h-3 text-blue-500" />
|
||
<span>1.2km</span>
|
||
</div>
|
||
</div>
|
||
<div className="flex gap-1">
|
||
<Heart className="w-3 h-3 text-gray-400" />
|
||
<Share2 className="w-3 h-3 text-gray-400" />
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center gap-1.5 mt-2 text-xs">
|
||
<div className="bg-green-100 text-green-700 px-2 py-0.5 rounded-full font-medium">
|
||
Nature
|
||
</div>
|
||
<div className="bg-purple-100 text-purple-700 px-2 py-0.5 rounded-full font-medium">
|
||
Family
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-center justify-between pt-2 border-t border-gray-100">
|
||
<div className="flex items-center gap-2">
|
||
<div>
|
||
<span className="text-base font-bold text-green-600">FREE</span>
|
||
<div className="text-xs text-green-600 font-medium">Included</div>
|
||
</div>
|
||
</div>
|
||
<button className="bg-green-600 text-white px-3 py-1.5 rounded-lg font-semibold text-xs">
|
||
Visit Now
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bottom Navigation */}
|
||
<div className="border-t border-gray-100 bg-white/95 backdrop-blur-sm">
|
||
<div className="flex items-center justify-around py-3">
|
||
{[
|
||
{
|
||
icon: (
|
||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
|
||
</svg>
|
||
),
|
||
label: "Home",
|
||
active: true,
|
||
badge: null
|
||
},
|
||
{
|
||
icon: (
|
||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>
|
||
</svg>
|
||
),
|
||
label: "Map",
|
||
active: false,
|
||
badge: "3"
|
||
},
|
||
{
|
||
icon: (
|
||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M22 10v6c0 1.11-.89 2-2 2H4c-1.11 0-2-.89-2-2v-8c0-1.11.89-2 2-2h14l2-2v6zm-9 4.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/>
|
||
</svg>
|
||
),
|
||
label: "Passes",
|
||
active: false,
|
||
badge: null
|
||
},
|
||
{
|
||
icon: (
|
||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/>
|
||
</svg>
|
||
),
|
||
label: "Activity",
|
||
active: false,
|
||
badge: null
|
||
},
|
||
{
|
||
icon: (
|
||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
|
||
</svg>
|
||
),
|
||
label: "Profile",
|
||
active: false,
|
||
badge: null
|
||
}
|
||
].map((item, index) => (
|
||
<div key={index} className={`flex flex-col items-center justify-center gap-1 py-1 relative ${item.active ? 'text-primary' : 'text-gray-500'}`}>
|
||
<div className="relative">
|
||
{item.icon}
|
||
{item.badge && (
|
||
<div className="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full min-w-[16px] h-4 flex items-center justify-center px-1">
|
||
{item.badge}
|
||
</div>
|
||
)}
|
||
</div>
|
||
<span className={`text-xs ${item.active ? 'font-semibold' : 'font-medium'}`}>
|
||
{item.label}
|
||
</span>
|
||
{item.active && (
|
||
<div className="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-4 h-0.5 bg-primary rounded-full"></div>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</div>
|
||
|
||
{/* Mobile Mockup 2 - Map View */}
|
||
<div className="absolute bottom-[-6rem] lg:bottom-[-7rem] left-[calc(50%-100px-8.25rem)] lg:left-[calc(50%-100px-10.25rem)]">
|
||
<motion.div
|
||
className="w-56 lg:w-60 xl:w-64 h-[380px] lg:h-[440px] xl:h-[480px] bg-white rounded-[2.5rem] shadow-2xl border-4 lg:border-8 border-gray-900 relative overflow-hidden"
|
||
initial={{ opacity: 0, y: 30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.6, delay: 0.6 }}
|
||
whileHover={{ scale: 1.02, rotateY: -2 }}
|
||
>
|
||
{/* Status Bar */}
|
||
<div className="flex justify-between items-center px-6 py-3 bg-white">
|
||
<div className="flex items-center gap-1">
|
||
<span className="text-sm font-semibold text-black">9:41</span>
|
||
</div>
|
||
<div className="flex items-center gap-1">
|
||
<div className="flex gap-0.5">
|
||
{[1, 2, 3, 4].map((bar) => (
|
||
<div key={bar} className={`w-1 bg-black rounded-full ${bar === 1 ? 'h-1' : bar === 2 ? 'h-2' : bar === 3 ? 'h-3' : 'h-4'}`}></div>
|
||
))}
|
||
</div>
|
||
<svg className="w-4 h-4 ml-1" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/>
|
||
</svg>
|
||
<div className="w-6 h-3 border border-black rounded-sm ml-1">
|
||
<div className="w-4 h-1.5 bg-green-500 rounded-sm m-0.5"></div>
|
||
</div>
|
||
<div className="w-0.5 h-2 bg-black rounded-r-sm"></div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Map Header */}
|
||
<div className="px-5 py-3 bg-white border-b border-gray-100">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-3">
|
||
<button className="w-8 h-8 bg-gray-100 rounded-lg flex items-center justify-center">
|
||
<svg className="w-4 h-4 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||
</svg>
|
||
</button>
|
||
<div>
|
||
<h3 className="font-bold text-gray-900">Explore Sydney</h3>
|
||
<div className="text-xs text-gray-500">3 nearby attractions</div>
|
||
</div>
|
||
</div>
|
||
<button className="w-8 h-8 bg-primary/10 rounded-lg flex items-center justify-center">
|
||
<Filter className="w-4 h-4 text-primary" />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Map Content */}
|
||
<div className="flex-1 bg-gradient-to-br from-green-100 to-blue-100 relative overflow-hidden">
|
||
{/* Simplified Map Pattern */}
|
||
<div className="absolute inset-0 opacity-20">
|
||
<div className="w-full h-full bg-gradient-to-br from-blue-200 via-green-200 to-yellow-200"></div>
|
||
{/* Street lines */}
|
||
<div className="absolute top-1/4 left-0 right-0 h-px bg-gray-400 opacity-30"></div>
|
||
<div className="absolute top-1/2 left-0 right-0 h-px bg-gray-400 opacity-40"></div>
|
||
<div className="absolute top-3/4 left-0 right-0 h-px bg-gray-400 opacity-30"></div>
|
||
<div className="absolute left-1/4 top-0 bottom-0 w-px bg-gray-400 opacity-30"></div>
|
||
<div className="absolute left-1/2 top-0 bottom-0 w-px bg-gray-400 opacity-40"></div>
|
||
<div className="absolute left-3/4 top-0 bottom-0 w-px bg-gray-400 opacity-30"></div>
|
||
</div>
|
||
|
||
{/* Location Pins */}
|
||
<div className="absolute top-8 left-8 w-3 h-3 bg-red-500 rounded-full animate-pulse"></div>
|
||
<div className="absolute top-16 right-12 w-3 h-3 bg-blue-500 rounded-full animate-pulse"></div>
|
||
<div className="absolute bottom-20 left-12 w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>
|
||
<div className="absolute bottom-12 right-8 w-3 h-3 bg-purple-500 rounded-full animate-pulse"></div>
|
||
|
||
{/* Current Location */}
|
||
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||
<div className="relative">
|
||
<div className="w-6 h-6 bg-blue-600 rounded-full border-4 border-white shadow-lg animate-pulse"></div>
|
||
<div className="absolute inset-0 w-6 h-6 bg-blue-600 rounded-full animate-ping opacity-20"></div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Route Line */}
|
||
<svg className="absolute inset-0 w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none">
|
||
<path
|
||
d="M20,30 Q40,20 60,40 T80,70"
|
||
stroke="#6366f1"
|
||
strokeWidth="2"
|
||
fill="none"
|
||
strokeDasharray="5,5"
|
||
className="animate-pulse"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
|
||
{/* Bottom Card */}
|
||
<div className="absolute bottom-4 left-4 right-4 bg-white rounded-xl p-3 shadow-lg border border-gray-100">
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
|
||
<svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.94-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
|
||
</svg>
|
||
</div>
|
||
<div className="flex-1">
|
||
<h4 className="font-bold text-gray-900 text-sm">Sydney Opera House</h4>
|
||
<div className="flex items-center gap-1 text-xs text-gray-600">
|
||
<MapPin className="w-3 h-3 text-blue-500" />
|
||
<span>2.3km away • 5 min walk</span>
|
||
</div>
|
||
</div>
|
||
<button className="bg-primary text-white px-3 py-1.5 rounded-lg font-semibold text-xs">
|
||
Go
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</div>
|
||
</motion.div>
|
||
</motion.div>
|
||
</div>
|
||
</section>
|
||
);
|
||
} |