faqpage added and logo change

This commit is contained in:
priyanshuvish
2025-10-16 13:55:31 +05:30
parent 529b05ea1e
commit c8b65c6cf0
6 changed files with 688 additions and 14 deletions

View File

@@ -247,6 +247,12 @@ export function AppRouter({
</motion.div>
} />
<Route path="/faq" element={
<motion.div key="faq" {...pageTransition}>
<FAQPage {...commonNavHandlers} />
</motion.div>
} />
</Routes>
</AnimatePresence>

View File

@@ -12,7 +12,7 @@ interface LayoutProps {
children: ReactNode;
activeCity?: string;
showCitySubmenu?: boolean;
onSignInClick: () => void;
onSignInClick?: () => void; // ✅ optional
onSignOutClick?: () => void;
user?: User | null;
}
@@ -30,25 +30,21 @@ export function Layout({
{/* Navbar */}
<Navbar
activeCity={activeCity}
onCityChange={(city) => {
// Handle city change if needed
}}
onSignInClick={onSignInClick}
onCityChange={() => {}}
onSignInClick={() => onSignInClick?.()} // ✅ safe optional call
onSignOutClick={onSignOutClick}
isUserSignedIn={!!user}
user={user}
/>
{/* City Submenu - Conditionally rendered */}
{/* City Submenu */}
{showCitySubmenu && <CitySubmenu onClose={() => {}} />}
{/* Main Content */}
<main className="flex-1">
{children}
</main>
<main className="flex-1">{children}</main>
{/* Footer */}
<Footer />
</div>
);
}
}

BIN
src/assets/cityLogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -2,7 +2,7 @@ import image_bc70aef6686e5f4d059b5ef3380fd4f44bb9f4c6 from '../assets/bc70aef668
import { motion } from 'motion/react';
import { Apple, Play } from 'lucide-react';
import { ImageWithFallback } from './figma/ImageWithFallback';
import cityCardsLogo from 'figma:asset/66c6d4d2fa6c02d9f60e12fcde70c13d4a78d0b7.png';
import cityCardsLogo from '../assets/cityLogo.png';
export function FooterBrand() {
return (
@@ -15,7 +15,7 @@ export function FooterBrand() {
>
<div className="flex items-center">
<img
src={image_bc70aef6686e5f4d059b5ef3380fd4f44bb9f4c6}
src={cityCardsLogo}
alt="CityCards Logo"
className="h-12 w-auto"
/>

View File

@@ -6,7 +6,7 @@ import Frame1597884853 from '../imports/Frame1597884853';
import { Button } from './ui/button';
import { ImageWithFallback } from './figma/ImageWithFallback';
import { CTAButton } from './CTAButton';
import logoImage from '../assets/cit-logo.png';
import logoImage from '../assets/cityLogo.png';
interface NavbarProps {
activeCity: string;
@@ -200,7 +200,7 @@ export default function Navbar({
const navigationItems = [
{ label: 'How It Works', path: '/how-it-works' },
{ label: 'Your Card', path: '/passes' },
{ label: 'FAQ', path: '/comming-soon' }
{ label: 'FAQ', path: '/faq' }
];
// Dropdown component with proper ref forwarding and glassmorphism

672
src/pages/FAQPage.tsx Normal file
View File

@@ -0,0 +1,672 @@
import { useState, useMemo, useEffect, useRef, forwardRef } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { Search, ChevronUp, ChevronDown, Globe, ShoppingBag, Menu, X } from 'lucide-react';
import { ImageWithFallback } from '../components/figma/ImageWithFallback';
import { Button } from '../components/ui/button';
import { Badge } from '../components/ui/badge';
import { Input } from '../components/ui/input';
import { MobileAppSection } from '../components/MobileAppSection';
import { WhyChooseCityCards } from '../components/WhyChooseCityCards';
import { Card, CardContent } from '../components/ui/card';
import { Layout } from '../Layout';
const logoImage = 'https://images.unsplash.com/photo-1759365400065-ab88a7b8e82f?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtb2Rlcm4lMjB0cmF2ZWwlMjBsb2dvfGVufDF8fHx8MTc2MDYwMTc0MHww&ixlib=rb-4.1.0&q=80&w=1080';
interface FAQ {
id: number;
question: string;
answer: string;
category: string;
}
interface DropdownItem {
id: string;
label: string;
icon?: React.ReactNode;
action?: () => void;
badge?: string | number;
}
interface CartItem {
id: string;
name: string;
price: string;
image?: string;
quantity: number;
}
interface DropdownProps {
isOpen: boolean;
onToggle: () => void;
items: DropdownItem[];
trigger: React.ReactNode;
title?: string;
className?: string;
}
interface FAQPageProps {
onHomeClick?: () => void;
onPassesClick?: () => void;
onSignInClick?: () => void;
onBackClick: () => void;
onMelbourneClick: () => void;
onCheckoutClick: () => 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;
currentPage: string;
user?: { email: string; name: string } | null;
}
interface LayoutProps {
activeCity?: string;
onSignInClick?: () => void;
onSignOutClick?: () => void;
user?: { email: string; name: string } | null;
showCitySubmenu?: boolean;
children: React.ReactNode;
}
const faqs: FAQ[] = [
{
id: 1,
question: "What is CityCards?",
answer: "CityCards is a digital pass that gives you access to multiple attractions, experiences, and tours in major cities. With one card, you can explore museums, landmarks, tours, and activities while saving money and time.",
category: "General"
},
{
id: 2,
question: "How does CityCards work?",
answer: "Purchase a CityCard for your chosen city, receive it instantly on your mobile device, and show it at participating attractions to gain entry. It's that simple! No need to print tickets or stand in long queues.",
category: "General"
},
{
id: 3,
question: "Which cities are available?",
answer: "CityCards is currently available in Melbourne, Sydney, Brisbane, Perth, and Adelaide. We're constantly expanding to new cities across Australia and around the world.",
category: "General"
},
{
id: 4,
question: "How much can I save with CityCards?",
answer: "On average, customers save 40-50% compared to buying individual attraction tickets. The more attractions you visit, the more you save! Some passes offer savings of up to 60% on popular experiences.",
category: "Pricing"
},
{
id: 5,
question: "What's included in a CityCard?",
answer: "Each CityCard includes entry to 30-50+ top attractions, museums, tours, and experiences. You'll also get skip-the-line access at select venues, exclusive discounts, and a digital guidebook with insider tips.",
category: "Features"
},
{
id: 6,
question: "How long is the CityCard valid?",
answer: "CityCards are valid for 1, 2, 3, or 7 consecutive days from first use, depending on which pass you choose. The countdown starts when you visit your first attraction, giving you flexibility to plan your trip.",
category: "Usage"
},
{
id: 7,
question: "Can I share my CityCard with others?",
answer: "No, CityCards are non-transferable and can only be used by the person whose name is on the card. Each person in your group will need their own card.",
category: "Usage"
},
{
id: 8,
question: "Do I need to book attractions in advance?",
answer: "Most attractions don't require advance booking - just show up with your CityCard. However, some popular venues may require reservations during peak times. Check the app for specific requirements.",
category: "Booking"
},
{
id: 9,
question: "Is the CityCard available on mobile?",
answer: "Yes! Our mobile app is available for iOS and Android. You can store your card, plan your itinerary, check attraction hours, and get directions - all in one place.",
category: "Technology"
},
{
id: 10,
question: "What if an attraction is closed?",
answer: "If an attraction is temporarily closed, we'll notify you via the app and suggest alternatives. Your card validity will be extended to compensate for closures beyond our control.",
category: "Usage"
},
{
id: 11,
question: "Can I get a refund?",
answer: "Unused CityCards can be refunded within 90 days of purchase, as long as the card hasn't been activated. Once activated, the card is non-refundable but can be modified for a small fee.",
category: "Pricing"
},
{
id: 12,
question: "Are there discounts for children?",
answer: "Yes! We offer discounted rates for children (ages 3-15) and youth (ages 16-25). Children under 3 can often enter attractions for free when accompanied by an adult with a valid CityCard.",
category: "Pricing"
},
{
id: 13,
question: "How do I activate my CityCard?",
answer: "Your CityCard activates automatically when you visit your first attraction. Simply show your digital card at the entrance, and the venue will scan it to begin your pass validity period.",
category: "Getting Started"
},
{
id: 14,
question: "Can I pause my CityCard?",
answer: "CityCards run on consecutive days and cannot be paused. However, you can choose when to activate it by selecting your first attraction visit date.",
category: "Usage"
},
{
id: 15,
question: "What if I lose my phone?",
answer: "No worries! Your CityCard is linked to your email account. Simply log in on another device or contact our support team to recover your card information.",
category: "Technology"
},
{
id: 16,
question: "Is there customer support?",
answer: "Yes! Our customer support team is available 24/7 via phone, email, and live chat. We're here to help you make the most of your CityCards experience.",
category: "Support"
},
{
id: 17,
question: "Can I visit the same attraction twice?",
answer: "Each attraction can typically be visited once per card validity period. However, some experiences like hop-on-hop-off buses allow multiple uses throughout the day.",
category: "Usage"
},
{
id: 18,
question: "Do I need to print anything?",
answer: "No printing required! Your CityCard is completely digital. Just show it on your smartphone at each attraction. Make sure your phone is charged and have a backup battery pack just in case.",
category: "Technology"
},
{
id: 19,
question: "Are guided tours included?",
answer: "Yes! Many CityCards include access to guided walking tours, bus tours, and audio guides at museums. Check your specific card's attraction list for details.",
category: "Features"
},
{
id: 20,
question: "How do skip-the-line benefits work?",
answer: "At participating venues, you can use the priority entrance lane by showing your CityCard. Some attractions may have specific time slots for CityCard holders - check the app for details.",
category: "Features"
},
{
id: 21,
question: "Can I buy CityCards as a gift?",
answer: "Absolutely! CityCards make perfect gifts. You can purchase a gift card and send it directly to the recipient's email with a personalized message.",
category: "Booking"
},
{
id: 22,
question: "What payment methods do you accept?",
answer: "We accept all major credit cards (Visa, Mastercard, American Express), PayPal, Apple Pay, and Google Pay. All transactions are secure and encrypted.",
category: "Pricing"
},
{
id: 23,
question: "Is there a group discount?",
answer: "Yes! Groups of 10 or more can receive special discounted rates. Contact our group sales team for a custom quote and additional perks.",
category: "Pricing"
},
{
id: 24,
question: "How often are new attractions added?",
answer: "We regularly partner with new venues and update our attraction lists quarterly. CityCard holders get notified about new additions and can access them immediately.",
category: "Features"
}
];
const categories = ["General", "Pricing", "Features", "Usage", "Booking", "Technology", "Support", "Getting Started"];
export function FAQPage({ onHomeClick,
onPassesClick,
onSignInClick,
onSignOutClick,
currentPage = 'faq',}: FAQPageProps) {
const [searchQuery, setSearchQuery] = useState('');
const [selectedCategory, setSelectedCategory] = useState('All');
const [expandedFAQs, setExpandedFAQs] = useState<Set<number>>(new Set());
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
const [activeLanguageDropdown, setActiveLanguageDropdown] = useState(false);
const [activeCartDropdown, setActiveCartDropdown] = useState(false);
const languageRef = useRef<HTMLDivElement>(null);
const cartRef = useRef<HTMLDivElement>(null);
// Languages available
const languages: DropdownItem[] = [
{ id: 'en', label: 'English', icon: <span className="text-base">🇺🇸</span> },
{ id: 'es', label: 'Español', icon: <span className="text-base">🇪🇸</span> },
{ id: 'fr', label: 'Français', icon: <span className="text-base">🇫🇷</span> },
{ id: 'de', label: 'Deutsch', icon: <span className="text-base">🇩🇪</span> },
{ id: 'it', label: 'Italiano', icon: <span className="text-base">🇮🇹</span> },
];
// Mock cart items
const cartItems: CartItem[] = [
{ id: '1', name: 'Sydney 2-Day Pass', price: '$89', quantity: 1 },
{ id: '2', name: 'Melbourne Premium Pass', price: '$129', quantity: 1 },
];
const toggleFAQ = (id: number) => {
setExpandedFAQs(prev => {
const newSet = new Set(prev);
if (newSet.has(id)) {
newSet.delete(id);
} else {
newSet.add(id);
}
return newSet;
});
};
const filteredFAQs = useMemo(() => {
return faqs.filter(faq => {
const matchesSearch = faq.question.toLowerCase().includes(searchQuery.toLowerCase()) ||
faq.answer.toLowerCase().includes(searchQuery.toLowerCase());
const matchesCategory = selectedCategory === 'All' || faq.category === selectedCategory;
return matchesSearch && matchesCategory;
});
}, [searchQuery, selectedCategory]);
const faqPairs = useMemo(() => {
const pairs = [];
for (let i = 0; i < filteredFAQs.length; i += 2) {
pairs.push(filteredFAQs.slice(i, i + 2));
}
return pairs;
}, [filteredFAQs]);
// Detect scroll for navbar styling
useEffect(() => {
const handleScroll = () => {
const scrolled = window.scrollY > 20;
setIsScrolled(scrolled);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
// Close dropdowns when clicking outside
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (languageRef.current && !languageRef.current.contains(event.target as Node)) {
setActiveLanguageDropdown(false);
}
if (cartRef.current && !cartRef.current.contains(event.target as Node)) {
setActiveCartDropdown(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
// Close mobile menu on escape key
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
setIsMobileMenuOpen(false);
setActiveLanguageDropdown(false);
setActiveCartDropdown(false);
}
};
document.addEventListener('keydown', handleEscape);
return () => document.removeEventListener('keydown', handleEscape);
}, []);
// Calculate cart total
const cartTotal = cartItems.reduce((total, item) => {
const price = parseFloat(item.price.replace('$', ''));
return total + (price * item.quantity);
}, 0);
// Create click handlers for the navbar elements
const handleNavClick = (section: string) => {
switch (section) {
case 'about':
onHomeClick?.();
break;
case 'products':
onPassesClick?.();
break;
case 'faq':
// Already on FAQ page
break;
case 'card':
onHomeClick?.();
break;
default:
break;
}
};
// Check if navigation item is active
const isNavItemActive = (action: string) => {
return currentPage === action;
};
// Dropdown component with proper ref forwarding
const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(({
isOpen,
onToggle,
items,
trigger,
title,
className = ""
}, ref) => (
<div ref={ref} className={`relative ${className}`}>
<motion.button
onClick={onToggle}
className="relative"
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
>
{trigger}
</motion.button>
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, y: 10, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: 10, scale: 0.95 }}
transition={{ duration: 0.2, ease: [0.25, 0.1, 0.25, 1] }}
className="absolute top-full right-0 mt-2 bg-white rounded-2xl shadow-xl border border-gray-100 min-w-[220px] overflow-hidden z-50"
>
{title && (
<div className="px-5 py-4 border-b border-gray-100">
<h3 className="font-poppins font-semibold text-gray-900 text-base">{title}</h3>
</div>
)}
<div className="py-2">
{items.map((item, index) => (
<motion.button
key={item.id}
onClick={() => {
item.action?.();
onToggle();
}}
className="w-full flex items-center justify-between px-5 py-3 text-left hover:bg-gray-50 transition-colors duration-200"
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.05 }}
whileHover={{ x: 4 }}
>
<div className="flex items-center space-x-3">
{item.icon}
<span className="font-poppins text-gray-700 text-base font-normal">{item.label}</span>
</div>
{item.badge && (
<span className="bg-primary text-primary-foreground text-xs px-2 py-1 rounded-full font-poppins font-medium">
{item.badge}
</span>
)}
</motion.button>
))}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
));
Dropdown.displayName = 'Dropdown';
return (
<div className="min-h-screen bg-white">
<Layout
activeCity=""
onSignInClick={onSignInClick}
onSignOutClick={onSignOutClick}
// user={user}
showCitySubmenu={false}
>
{/* Main Content */}
<div className="container mx-auto px-4 pt-32 lg:pt-52 pb-12">
{/* Page Header */}
<motion.div
className="text-center mb-12"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
<motion.div
className="font-poppins tracking-wider text-primary mb-4"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.4, delay: 0.2 }}
>
GET STARTED NOW
</motion.div>
<h1 className="font-poppins text-4xl md:text-5xl lg:text-6xl leading-tight text-gray-900 mb-6">
<span className="font-light">Frequently Asked</span>{' '}
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
Questions
</span>
</h1>
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-600 max-w-3xl mx-auto">
Find answers to the most common questions about CityCards, bookings, and your city exploration experience
</p>
</motion.div>
{/* Search and Filter Section */}
<motion.div
className="mb-12 max-w-4xl mx-auto"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.3 }}
>
{/* Search Bar */}
<div className="relative mb-8">
<Search className="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400 w-5 h-5" />
<Input
type="text"
placeholder="Search for questions..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-12 pr-4 py-6 bg-white border-2 border-gray-200 rounded-2xl focus:border-primary focus:ring-4 focus:ring-primary/10 transition-all duration-200 font-poppins"
/>
</div>
{/* Category Tags */}
<div className="flex flex-wrap gap-3 justify-center">
<Badge
variant={selectedCategory === 'All' ? 'default' : 'secondary'}
className={`px-6 py-3 cursor-pointer transition-all duration-200 hover:scale-105 font-poppins ${selectedCategory === 'All'
? 'bg-primary text-white shadow-lg'
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
}`}
onClick={() => setSelectedCategory('All')}
>
All
</Badge>
{categories.map((category) => (
<Badge
key={category}
variant={selectedCategory === category ? 'default' : 'secondary'}
className={`px-6 py-3 cursor-pointer transition-all duration-200 hover:scale-105 font-poppins ${selectedCategory === category
? 'bg-primary text-white shadow-lg'
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
}`}
onClick={() => setSelectedCategory(category)}
>
{category}
</Badge>
))}
</div>
</motion.div>
{/* FAQ Content */}
<div className="w-full">
{faqPairs.length === 0 ? (
<motion.div
className="text-center py-12"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.4 }}
>
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-500">No questions found matching your search.</p>
</motion.div>
) : (
<div className="space-y-8">
{faqPairs.map((pair, pairIndex) => (
<motion.div
key={pairIndex}
className="grid grid-cols-1 lg:grid-cols-2 gap-8"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: pairIndex * 0.1 }}
>
{pair.map((faq) => {
const isExpanded = expandedFAQs.has(faq.id);
return (
<div
key={faq.id}
className="faq-card bg-white rounded-2xl shadow-sm hover:shadow-md transition-all duration-300 relative overflow-hidden"
>
<button
onClick={() => toggleFAQ(faq.id)}
className="w-full p-8 text-left hover:bg-gray-100/50 transition-colors duration-200 focus:outline-none focus:ring-4 focus:ring-primary/10"
>
<div className="flex items-start gap-4 mb-4">
<span className="w-10 h-10 bg-primary text-white rounded-full flex items-center justify-center flex-shrink-0 font-poppins font-semibold">
{faq.id}
</span>
<div className="flex-1">
<h3 className="font-poppins text-xl leading-tight font-medium text-gray-900 mb-2">
{faq.question}
</h3>
<div className="flex items-center justify-between">
<Badge variant="secondary" className="px-3 py-1 bg-gray-100 text-gray-600 font-poppins font-normal">
{faq.category}
</Badge>
<div className="flex-shrink-0">
{isExpanded ? (
<ChevronUp className="w-5 h-5 text-primary" />
) : (
<ChevronDown className="w-5 h-5 text-gray-400" />
)}
</div>
</div>
</div>
</div>
</button>
{/* Answer Content */}
<AnimatePresence>
{isExpanded && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: 'auto', opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3, ease: [0.25, 0.1, 0.25, 1] }}
className="overflow-hidden"
>
<div className="px-8 pb-8">
<div className="border-t border-gray-200 pt-6">
<p className="font-poppins text-base leading-relaxed font-normal text-gray-600">
{faq.answer}
</p>
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
);
})}
{/* If odd number of FAQs, add empty space for the last row */}
{pair.length === 1 && (
<div className="hidden lg:block" />
)}
</motion.div>
))}
</div>
)}
</div>
{/* Mobile App Section */}
<motion.div
className="mt-20"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.5 }}
>
<div className="bg-muted/30 relative overflow-hidden rounded-3xl">
<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>
<MobileAppSection />
</div>
</motion.div>
{/* Why Choose Us Section */}
<motion.div
className="mt-20"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.6 }}
>
<WhyChooseCityCards />
</motion.div>
{/* Contact Support Section */}
<motion.div
className="mt-20 text-center"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.7 }}
>
<Card className="max-w-2xl mx-auto bg-gradient-to-br from-primary/5 to-secondary/5 border-2 border-primary/20 rounded-3xl p-8">
<CardContent className="p-0">
<h3 className="font-poppins text-2xl leading-tight font-medium text-gray-900 mb-4">
Still have questions?
</h3>
<p className="font-poppins text-base leading-relaxed font-normal text-gray-600 mb-6">
Our support team is available 24/7 to help you with any questions or concerns about your CityCards experience.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="mailto:support@citycards.com"
className="px-8 py-3 bg-primary text-white rounded-full hover:bg-primary/90 transition-colors duration-200 font-poppins font-medium"
>
Email Support
</a>
<a
href="tel:+1-800-CITYCARD"
className="px-8 py-3 bg-white text-primary border-2 border-primary rounded-full hover:bg-primary/5 transition-colors duration-200 font-poppins font-medium"
>
Call Us
</a>
</div>
</CardContent>
</Card>
</motion.div>
</div>
</Layout >
</div>
);
}