1162 lines
59 KiB
TypeScript
1162 lines
59 KiB
TypeScript
"use client";
|
||
|
||
import { motion, AnimatePresence } from "framer-motion";
|
||
import { useRef, useState, useEffect } from "react";
|
||
import type { DemoData } from "@/data/demos";
|
||
|
||
const fadeUp = {
|
||
hidden: { opacity: 0, y: 35 },
|
||
show: { opacity: 1, y: 0, transition: { duration: 0.75, ease: [0.25, 0.46, 0.45, 0.94] as [number, number, number, number] } },
|
||
};
|
||
|
||
const stagger = {
|
||
hidden: {},
|
||
show: { transition: { staggerChildren: 0.1 } },
|
||
};
|
||
|
||
const translations = {
|
||
tr: {
|
||
navBook: "Rezervasyon",
|
||
navTariffs: "Havalimanı Ücretleri",
|
||
navBenefits: "Ayrıcalıklar",
|
||
navApp: "Mobil Uygulama",
|
||
navReviews: "Misafir Yorumları",
|
||
callCenter: "Çağrı Hattı",
|
||
bookNow: "Rezervasyon Yap",
|
||
badge: "NYC MINIMALIST & CHIC HAVAALANI TRANSFERLERİ",
|
||
heroTitlePart1: "ZARİF & GÜVENLİ",
|
||
heroTitlePart2: "PREMIUM TRANSFERLER",
|
||
heroDesc: "Yeni nesil sıfır emisyonlu lüks yolculuk keyfi. Beyaz elektrikli lüks sedan filomuz JFK, LaGuardia ve Newark lounge transferleriniz için özel olarak optimize edilmiştir. 60 saniyede güvenli planlama.",
|
||
instantBooking: "Havalimanı Özel Hattı",
|
||
getQuote: "Rezervasyon Yap",
|
||
viewTariffs: "Havaalanı Tarifeleri",
|
||
fastFormSubtitle: "Transfer Seyahat Formu",
|
||
fastFormTitle: "MİL HESAPLA & REZERVE ET",
|
||
fastFormDesc: "Havalimanı kapı ve seyahat koordinatlarınızı girerek tahmini tutarı anında hesaplayın.",
|
||
formName: "Ad Soyad",
|
||
formNamePlaceholder: "Adınız Soyadınız",
|
||
formPhone: "Telefon Numarası",
|
||
formPhonePlaceholder: "İletişim Numaranız",
|
||
formDate: "Tarih",
|
||
formTime: "Saat",
|
||
formPickup: "Alış Noktası",
|
||
formDropoff: "Varış Noktası",
|
||
chooseVehicle: "Araç Sınıfı Seçimi",
|
||
submitBooking: "GÜVENLİ REZERVASYON",
|
||
dispatchWarning: "Bu formu gönderdiğinizde, sürücümüz sizinle 3 dakika içinde iletişime geçecektir.",
|
||
tariffsSubtitle: "Havalimanı Ücretleri",
|
||
tariffsTitle: "HAVAALANI TARİFELERİ",
|
||
tariffsDesc: "Lounge ve terminal koordinatlarınızı taçlandıracak en uygun sabit fiyatları inceleyin.",
|
||
popular: "EN ÇOK TERCİH EDİLEN",
|
||
perMile: "/ MİL",
|
||
bookTariff: "BU TARİFEYİ SEÇ",
|
||
benefitsSubtitle: "Özel Değerler",
|
||
benefitsTitle: "LOUNGE AYRICALIKLARI",
|
||
benefitsDesc: "Havaalanı ve şehir içi koordinatlarınızı tamamen stressiz hale getirmek için tasarlandı.",
|
||
appSubtitle: "Zarif Mobil Mobilite",
|
||
appTitle: "CHIC MOBİL UYGULAMASI",
|
||
appDesc: "CabHub mobil uygulamasını telefonunuza indirin. Sürücü atamalarını izleyin, anlık GPS rotalarını takip edin ve üyelere özel avantajlardan yararlanın.",
|
||
getItOn: "HEMEN İNDİRİN",
|
||
googlePlay: "Google Play",
|
||
appStore: "App Store",
|
||
reviewsSubtitle: "Müşteri Deneyimleri",
|
||
reviewsTitle: "AYRICALIKLI DENEYİMLER",
|
||
reviewsDesc: "Sık seyahat eden kurumsal yöneticilerimizin lounge transfer sistemimiz hakkındaki yorumları.",
|
||
callStripText: "7 GÜN 24 SAAT ÇAĞRILARINIZI CEVAPLAMAYA HAZIRIZ!",
|
||
footerRights: "Tüm hakları saklıdır.",
|
||
footerPrivacy: "Gizlilik Politikası",
|
||
footerTerms: "Kullanım Şartları",
|
||
bookingRequested: "TRANSFER REZERVE EDİLDİ",
|
||
nycDispatchActive: "Premium Lounge Sürücü Atama Aktif",
|
||
successDesc: "Havalimanı transfer parametrelerinizi kaydettik. En yakın CabHub özel şoförü 3 dakika içinde sizinle iletişime geçecektir. Teşekkürler!",
|
||
dismiss: "KAPAT",
|
||
conceptBanner: "Bu web sitesi Ayris Tech tarafından hazırlanmış bir konsept çalışmasıdır.",
|
||
calcEstimated: "Tahmini Tutar:",
|
||
calcLoading: "Hesaplanıyor...",
|
||
min: "dk",
|
||
calculatingText: "Mesafe bazlı anlık ücretlendirme"
|
||
},
|
||
en: {
|
||
navBook: "Reserve",
|
||
navTariffs: "Airport Rates",
|
||
navBenefits: "Why Us",
|
||
navApp: "Mobile App",
|
||
navReviews: "Reviews",
|
||
callCenter: "Lounge Line",
|
||
bookNow: "Book Transfer",
|
||
badge: "NYC MINIMALIST & CHIC AIRPORT TRANSFERS",
|
||
heroTitlePart1: "CHIC & SECURE",
|
||
heroTitlePart2: "PREMIUM TRANSFERS",
|
||
heroDesc: "Indulge in modern zero-emission comfort. Our fleet of white luxury electric sedans is fully optimized for JFK, LaGuardia, and Newark lounge drop-offs. Secure scheduling in under 60 seconds.",
|
||
instantBooking: "Lounge Concierge Line",
|
||
getQuote: "Reserve Now",
|
||
viewTariffs: "Airport Tariffs",
|
||
fastFormSubtitle: "Transfer Form",
|
||
fastFormTitle: "RESERVE TRANSFER",
|
||
fastFormDesc: "Input airport gate and travel coordinates to allocate a verified premium driver.",
|
||
formName: "Name",
|
||
formNamePlaceholder: "Your full name",
|
||
formPhone: "Phone",
|
||
formPhonePlaceholder: "Contact Number",
|
||
formDate: "Date",
|
||
formTime: "Time",
|
||
formPickup: "Start Location",
|
||
formDropoff: "End Destination",
|
||
chooseVehicle: "Choose Vehicle",
|
||
submitBooking: "SECURE BOOKING",
|
||
dispatchWarning: "By submitting this form, you secure immediate dispatch. A professional verified driver will reach out on your contact number in under 3 minutes.",
|
||
tariffsSubtitle: "Airport Rates",
|
||
tariffsTitle: "AIRPORT TARIFFS",
|
||
tariffsDesc: "Flat rates designed to elevate your airport lounge coordinates.",
|
||
popular: "MOST PREFERRED",
|
||
perMile: "/ MILE",
|
||
bookTariff: "BOOK TARIFF",
|
||
benefitsSubtitle: "Premium Values",
|
||
benefitsTitle: "LOUNGE ADVANTAGES",
|
||
benefitsDesc: "Designed to make airport and city coordinates completely stress-free.",
|
||
appSubtitle: "Light Application",
|
||
appTitle: "CHIC MOBILITY APP",
|
||
appDesc: "Reserve transfers, allocate verified chauffeurs, monitor real-time GPS trajectories, and redeem up to 40% saving balances. Beautiful, seamless light-mode smartphone UI.",
|
||
getItOn: "GET IT ON",
|
||
googlePlay: "Google Play",
|
||
appStore: "App Store",
|
||
reviewsSubtitle: "Reviews",
|
||
reviewsTitle: "TRUSTED EXPERIENCE",
|
||
reviewsDesc: "Hear what frequent corporate executives think of our lounge transfer system.",
|
||
callStripText: "WE ARE READY TO TAKE YOUR CALL 24 HOURS, 7 DAYS!",
|
||
footerRights: "All rights reserved.",
|
||
footerPrivacy: "Privacy Policy",
|
||
footerTerms: "Terms of Service",
|
||
bookingRequested: "TRANSFER SECURED",
|
||
nycDispatchActive: "Premium Lounge Dispatcher Active",
|
||
successDesc: "We have registered your airport transfer parameters. A professional verified CabHub chauffeur will reach out on your contact number in under 3 minutes. Thank you!",
|
||
dismiss: "DISMISS",
|
||
conceptBanner: "This website is a premium concept prototype designed by Ayris Tech.",
|
||
calcEstimated: "Estimated Fare:",
|
||
calcLoading: "Calculating...",
|
||
min: "min",
|
||
calculatingText: "Real-time coordinate-based pricing"
|
||
}
|
||
};
|
||
|
||
const locationsList = [
|
||
"Manhattan Midtown",
|
||
"Brooklyn Heights",
|
||
"Queens Astoria",
|
||
"JFK Airport",
|
||
"LaGuardia Airport"
|
||
];
|
||
|
||
export default function TaxiTemplate2({ data }: { data: DemoData }) {
|
||
const { firma, istatistikler = [], hizmetler = [], yorumlar = [] } = data;
|
||
const [showBookingModal, setShowBookingModal] = useState(false);
|
||
const [activePlan, setActivePlan] = useState<number>(1); // Standard active by default
|
||
const [lang, setLang] = useState<"tr" | "en">("tr");
|
||
const [preloader, setPreloader] = useState(true);
|
||
|
||
// Calculator states
|
||
const [pickupLoc, setPickupLoc] = useState("Manhattan Midtown");
|
||
const [dropoffLoc, setDropoffLoc] = useState("JFK Airport");
|
||
|
||
const t = translations[lang];
|
||
|
||
const getIconSvg = (type: string) => {
|
||
switch (type) {
|
||
case "pickup":
|
||
return (
|
||
<svg className="w-8 h-8 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M8.25 21v-4.875c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125V21m0 0h4.5V3.545M12.75 7.5h.008v.008h-.008V7.5Zm0 2.25h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008v-.008Zm-4.5-9h.008v.008H8.25V7.5Zm0 2.25h.008v.008H8.25v-.008Zm0 2.25h.008v.008H8.25v-.008Zm0 2.25h.008v.008H8.25v-.008Zm-3.75 9H3.75V3.545m0 0A2.24 2.24 0 0 1 6 1.375c.66 0 1.272.285 1.706.777l.01.012M3.75 3.545V21h4.5M18.75 3.545V21h-4.5" />
|
||
</svg>
|
||
);
|
||
case "booking":
|
||
return (
|
||
<svg className="w-8 h-8 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 0 0 6 3.75v16.5a2.25 2.25 0 0 0 2.25 2.25h7.5A2.25 2.25 0 0 0 18 20.25V3.75a2.25 2.25 0 0 0-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" />
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 13.5l10.5-11.25L12 9h8.25L9.75 20.25 12 13.5H3.75Z" />
|
||
</svg>
|
||
);
|
||
case "bonus":
|
||
return (
|
||
<svg className="w-8 h-8 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M21 11.25v8.25a1.5 1.5 0 0 1-1.5 1.5H5.25a1.5 1.5 0 0 1-1.5-1.5v-8.25M12 4.875A2.625 2.625 0 1 0 9.375 7.5H12m0-2.625V7.5m-9 3.75h18M12 7.5v13.5" />
|
||
</svg>
|
||
);
|
||
case "gps":
|
||
return (
|
||
<svg className="w-8 h-8 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 6.75h15m-15 4.5h15m-15 4.5h15M3 6.75h.008v.008H3V6.75Zm0 4.5h.008v.008H3v-.008Zm0 4.5h.008v.008H3v-.008Z" />
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25s-7.5-4.108-7.5-11.25a7.5 7.5 0 1 1 15 0Z" />
|
||
</svg>
|
||
);
|
||
default:
|
||
return (
|
||
<svg className="w-8 h-8 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||
</svg>
|
||
);
|
||
}
|
||
};
|
||
|
||
// 1. Lenis Smooth Scroll Integration
|
||
useEffect(() => {
|
||
let lenis: any;
|
||
import("@studio-freight/lenis").then(({ default: Lenis }) => {
|
||
lenis = new Lenis({ duration: 1.2, easing: (t: number) => Math.min(1, 1.001 - Math.pow(2, -10 * t)) });
|
||
function raf(time: number) { lenis.raf(time); requestAnimationFrame(raf); }
|
||
requestAnimationFrame(raf);
|
||
});
|
||
return () => lenis?.destroy();
|
||
}, []);
|
||
|
||
// 2. Preloader timer
|
||
useEffect(() => {
|
||
const timer = setTimeout(() => {
|
||
setPreloader(false);
|
||
}, 1500);
|
||
return () => clearTimeout(timer);
|
||
}, []);
|
||
|
||
// Fare estimation logic
|
||
const calculatePrice = () => {
|
||
if (pickupLoc === dropoffLoc) return "$5.00";
|
||
|
||
// JFK flat rates
|
||
if ((pickupLoc === "Manhattan Midtown" && dropoffLoc === "JFK Airport") ||
|
||
(pickupLoc === "JFK Airport" && dropoffLoc === "Manhattan Midtown")) {
|
||
return activePlan === 0 ? "$55.00" : activePlan === 1 ? "$75.00" : "$110.00";
|
||
}
|
||
// LaGuardia flat rates
|
||
if ((pickupLoc === "Manhattan Midtown" && dropoffLoc === "LaGuardia Airport") ||
|
||
(pickupLoc === "LaGuardia Airport" && dropoffLoc === "Manhattan Midtown")) {
|
||
return activePlan === 0 ? "$35.00" : activePlan === 1 ? "$48.00" : "$75.00";
|
||
}
|
||
|
||
// Mileage estimations based on distance
|
||
let miles = 8;
|
||
if ((pickupLoc === "Manhattan Midtown" && dropoffLoc === "Brooklyn Heights") ||
|
||
(pickupLoc === "Brooklyn Heights" && dropoffLoc === "Manhattan Midtown")) miles = 6;
|
||
else if ((pickupLoc === "Manhattan Midtown" && dropoffLoc === "Queens Astoria") ||
|
||
(pickupLoc === "Queens Astoria" && dropoffLoc === "Manhattan Midtown")) miles = 7;
|
||
else if ((pickupLoc === "Brooklyn Heights" && dropoffLoc === "Queens Astoria") ||
|
||
(pickupLoc === "Queens Astoria" && dropoffLoc === "Brooklyn Heights")) miles = 10;
|
||
else if ((pickupLoc === "Brooklyn Heights" && dropoffLoc === "JFK Airport") ||
|
||
(pickupLoc === "JFK Airport" && dropoffLoc === "Brooklyn Heights")) miles = 16;
|
||
else if ((pickupLoc === "Brooklyn Heights" && dropoffLoc === "LaGuardia Airport") ||
|
||
(pickupLoc === "LaGuardia Airport" && dropoffLoc === "Brooklyn Heights")) miles = 14;
|
||
else if ((pickupLoc === "Queens Astoria" && dropoffLoc === "JFK Airport") ||
|
||
(pickupLoc === "JFK Airport" && dropoffLoc === "Queens Astoria")) miles = 12;
|
||
else if ((pickupLoc === "Queens Astoria" && dropoffLoc === "LaGuardia Airport") ||
|
||
(pickupLoc === "LaGuardia Airport" && dropoffLoc === "Queens Astoria")) miles = 6;
|
||
else if ((pickupLoc === "JFK Airport" && dropoffLoc === "LaGuardia Airport") ||
|
||
(pickupLoc === "LaGuardia Airport" && dropoffLoc === "JFK Airport")) miles = 12;
|
||
|
||
const basePrice = miles * 1.6 + 5.0;
|
||
const multiplier = activePlan === 0 ? 1.0 : activePlan === 1 ? 1.5 : 2.2;
|
||
return `$${(basePrice * multiplier).toFixed(2)}`;
|
||
};
|
||
|
||
// Dynamic Localization handlers
|
||
const getLocalizedStat = (deger: string) => {
|
||
if (deger.toLowerCase().includes("economy")) {
|
||
return {
|
||
title: lang === "tr" ? "Chic Şehir İçi" : "Economy Class",
|
||
desc: lang === "tr" ? "Şehir içi ulaşımlarda konforlu ve sıfır emisyonlu elektrikli araç deneyimi. Mil başı $1.50." : "Comfortable zero-emission trips to any destination within boroughs. $1.5/MI"
|
||
};
|
||
}
|
||
if (deger.toLowerCase().includes("standard")) {
|
||
return {
|
||
title: lang === "tr" ? "Premium Şehirler Arası" : "Standard Class",
|
||
desc: lang === "tr" ? "Eyalet genelinde ve 3 ana havalimanına premium lüks seyahatler. Mil başı $2.20." : "Premium transfers. Verified luxury sedans covering tri-state airport hubs. $2.20/MI"
|
||
};
|
||
}
|
||
return {
|
||
title: lang === "tr" ? "First Class Yönetici" : "Business Class",
|
||
desc: lang === "tr" ? "Öncelikli geçiş şeridi ve en üst segment lüks şoför hizmeti. Mil başı $3.50." : "First class executive. Top-tier luxury vehicles with priority lane dispatch. $3.50/MI"
|
||
};
|
||
};
|
||
|
||
const getLocalizedService = (baslik: string, aciklama: string) => {
|
||
if (baslik.toLowerCase().includes("pickup") || baslik.toLowerCase().includes("lounge")) {
|
||
return {
|
||
title: lang === "tr" ? "LOUNGE'DAN ALIM" : "LOUNGE PICKUP",
|
||
desc: lang === "tr" ? "Doğrudan havalimanı lounge kapısından veya otel girişinden bagaj asistanlığıyla karşılama." : "Direct lounge or doorstep coordination for all airport coordinates."
|
||
};
|
||
}
|
||
if (baslik.toLowerCase().includes("booking") || baslik.toLowerCase().includes("reservation")) {
|
||
return {
|
||
title: lang === "tr" ? "PRATİK REZERVASYON" : "TAP RESERVATION",
|
||
desc: lang === "tr" ? "Akıllı telefon entegrasyonu ile seyahatlerinizi 60 saniyenin altında rezerve edin." : "Ultra-fast smartphone booking client. Secure scheduling under 60 seconds."
|
||
};
|
||
}
|
||
if (baslik.toLowerCase().includes("bonus") || baslik.toLowerCase().includes("member")) {
|
||
return {
|
||
title: lang === "tr" ? "ÜYELİK AVANTAJLARI" : "MEMBER BENEFITS",
|
||
desc: lang === "tr" ? "Mil toplayın ve bir sonraki premium seyahatinizde %40 indirim kazanın." : "Collect mileage dynamically. Redeem up to 40% savings on specialty trips."
|
||
};
|
||
}
|
||
return {
|
||
title: lang === "tr" ? "HASSAS GPS TAKİBİ" : "TRACKING GPS",
|
||
desc: lang === "tr" ? "Gerçek zamanlı uydu üzerinden sürüş takibi ve uçuş saati rötar senkronizasyonu." : "Real-time satellite path tracking and automated flight delay syncing."
|
||
};
|
||
};
|
||
|
||
const getLocalizedTestimonial = (yazar: string) => {
|
||
if (yazar.toLowerCase().includes("alexander")) {
|
||
return lang === "tr"
|
||
? "JFK'den transferim tamamen kusursuzdu. Sürücü beni lounge kapısında karşıladı ve elektrikli araç tertemiz durumdaydı."
|
||
: "The airport transfer from JFK was absolutely seamless. The driver met me at the lounge gate and the electric vehicle was in pristine condition.";
|
||
}
|
||
return lang === "tr"
|
||
? "Kurumsal seyahatlerimde kesinlikle ilk tercihim CabHub Premium. Açık renkli sade uygulamasından rezervasyon çok basit ve rötar takibi mükemmel."
|
||
: "CabHub Premium is my absolute go-to for corporate travel. The light theme app booking is simple and the delay syncing works perfectly.";
|
||
};
|
||
|
||
const css = `
|
||
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;700;900&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Syne:wght@700;800&display=swap');
|
||
|
||
:root {
|
||
--color-premium-gold: #E5A900;
|
||
--color-nordic-white: #FFFFFF;
|
||
--color-nordic-ivory: #FCFAF7;
|
||
--color-nordic-ivory-dark: #F5F2EC;
|
||
--color-coal-text: #111317;
|
||
--color-coal-muted: rgba(17, 19, 23, 0.6);
|
||
}
|
||
|
||
.font-industrial {
|
||
font-family: 'Syne', 'Oswald', sans-serif;
|
||
}
|
||
|
||
.font-sans-premium {
|
||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||
}
|
||
|
||
.spinning-badge {
|
||
animation: spin 25s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
from { transform: rotate(0deg); }
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
|
||
.bg-mesh-grid-light {
|
||
background-image:
|
||
linear-gradient(rgba(229, 169, 0, 0.02) 1px, transparent 1px),
|
||
linear-gradient(90deg, rgba(229, 169, 0, 0.02) 1px, transparent 1px);
|
||
background-size: 45px 45px;
|
||
}
|
||
|
||
.gold-bar-glow {
|
||
box-shadow: 0 0 12px rgba(229, 169, 0, 0.25);
|
||
}
|
||
|
||
.pulse-glow-dark {
|
||
animation: pulseDark 2s infinite;
|
||
}
|
||
|
||
@keyframes pulseDark {
|
||
0% { box-shadow: 0 0 0 0 rgba(17, 19, 23, 0.2); }
|
||
70% { box-shadow: 0 0 0 15px rgba(17, 19, 23, 0); }
|
||
100% { box-shadow: 0 0 0 0 rgba(17, 19, 23, 0); }
|
||
}
|
||
|
||
.hero-title-clamp {
|
||
font-size: clamp(34px, 5.8vw, 84px);
|
||
letter-spacing: -0.01em;
|
||
line-height: 0.95;
|
||
}
|
||
`;
|
||
|
||
return (
|
||
<>
|
||
<style>{css}</style>
|
||
|
||
{/* ── IMZA AN: LIGHT TARIFF PRELOADER ── */}
|
||
<AnimatePresence>
|
||
{preloader && (
|
||
<motion.div
|
||
className="fixed inset-0 z-50 bg-[#FCFAF7] flex flex-col items-center justify-center p-6"
|
||
exit={{
|
||
clipPath: "polygon(0 0, 100% 0, 100% 0, 0 0)",
|
||
transition: { duration: 0.85, ease: [0.16, 1, 0.3, 1] }
|
||
}}
|
||
>
|
||
<div className="max-w-md text-center space-y-6">
|
||
<motion.span
|
||
className="text-[9px] font-black tracking-[4px] uppercase text-[#E5A900] block font-sans-premium"
|
||
initial={{ opacity: 0, y: 10 }}
|
||
animate={{ opacity: 1, y: 0 }}
|
||
transition={{ duration: 0.5 }}
|
||
>
|
||
CABHUB PREMIUM SERVICE
|
||
</motion.span>
|
||
<div className="h-[1px] w-48 bg-black/10 mx-auto relative overflow-hidden">
|
||
<motion.div
|
||
className="absolute inset-y-0 left-0 bg-[#E5A900] gold-bar-glow"
|
||
initial={{ width: "0%" }}
|
||
animate={{ width: "100%" }}
|
||
transition={{ duration: 1.2, ease: "easeInOut" }}
|
||
/>
|
||
</div>
|
||
<motion.h2
|
||
className="font-industrial text-black text-base font-black tracking-widest uppercase"
|
||
initial={{ opacity: 0 }}
|
||
animate={{ opacity: 1 }}
|
||
transition={{ delay: 0.4, duration: 0.5 }}
|
||
>
|
||
allocating...
|
||
</motion.h2>
|
||
</div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
|
||
{/* ── MANDATORY FLOATING DEMO BANNER ── */}
|
||
<div className="fixed bottom-4 left-4 z-40 bg-white/95 backdrop-blur-md border border-black/5 px-4 py-2.5 rounded-xl shadow-2xl flex items-center gap-2.5 max-w-sm pointer-events-none select-none">
|
||
<div className="w-1.5 h-1.5 rounded-full bg-[#E5A900] animate-pulse" />
|
||
<span className="text-[9px] font-black uppercase tracking-[1.5px] text-slate-800 font-sans-premium">
|
||
{t.conceptBanner}
|
||
</span>
|
||
</div>
|
||
|
||
{/* ── MAIN CONTENT CONTAINER (Chic Minimalist Light Theme) ── */}
|
||
<div className="bg-[#FCFAF7] text-[#111317] min-h-screen font-sans-premium selection:bg-[#E5A900] selection:text-white overflow-hidden relative">
|
||
|
||
{/* Soft Grid Overlay */}
|
||
<div className="absolute inset-0 bg-mesh-grid-light pointer-events-none z-0" />
|
||
|
||
{/* Floating Ambient Warm Gold Orbs */}
|
||
<div className="absolute top-[20%] left-[-15%] w-[600px] h-[600px] bg-[#E5A900]/3 blur-[130px] rounded-full pointer-events-none z-0" />
|
||
<div className="absolute bottom-[20%] right-[-15%] w-[600px] h-[600px] bg-[#E5A900]/3 blur-[140px] rounded-full pointer-events-none z-0" />
|
||
|
||
{/* ── PREMIUM LIGHT NAVBAR ── */}
|
||
<motion.header
|
||
className="fixed top-4 left-4 right-4 z-50 px-4"
|
||
initial={{ y: -80, opacity: 0 }}
|
||
animate={{ y: 0, opacity: 1 }}
|
||
transition={{ duration: 0.7, ease: "easeOut" }}
|
||
>
|
||
<div className="mx-auto max-w-7xl h-20 flex items-center justify-between px-8 bg-white/95 backdrop-blur-xl border border-black/5 rounded-2xl shadow-[0_10px_25px_rgba(17,19,23,0.06)]">
|
||
{/* Logo */}
|
||
<a href="#" className="flex items-center gap-2 group">
|
||
<div className="w-10 h-10 rounded-xl bg-[#E5A900] flex items-center justify-center shadow-[0_4px_10px_rgba(229,169,0,0.15)] transition-transform group-hover:scale-105">
|
||
<svg className="w-6 h-6 fill-white" viewBox="0 0 24 24">
|
||
<path d="M22 10.07V6c0-.55-.45-1-1-1h-2v-.07c0-.9-.72-1.63-1.61-1.68C17.15 3.12 17 3.32 17 3.5V5h-2V3.5c0-.18-.15-.38-.39-.25-.89.05-1.61.78-1.61 1.68V5H5c-.55 0-1 .45-1 1v4.07c-1.19.43-2 1.56-2 2.93v3c0 .55.45 1 1 1h1v1.5c0 .83.67 1.5 1.5 1.5h1c.83 0 1.5-.67 1.5-1.5V18h10v1.5c0 .83.67 1.5 1.5 1.5h1c.83 0 1.5-.67 1.5-1.5V18h1c.55 0 1-.45 1-1v-3c0-1.37-.81-2.5-2-2.93z" />
|
||
</svg>
|
||
</div>
|
||
<span className="text-xl font-black tracking-wider text-[#111317] font-industrial uppercase">
|
||
CAB<span className="text-[#E5A900]">HUB</span>
|
||
</span>
|
||
</a>
|
||
|
||
{/* Navigation Links */}
|
||
<nav className="hidden lg:flex items-center gap-8">
|
||
{[
|
||
{ label: t.navBook, href: "#booking-flow" },
|
||
{ label: t.navTariffs, href: "#tariffs" },
|
||
{ label: t.navBenefits, href: "#benefits" },
|
||
{ label: t.navApp, href: "#app-showcase" },
|
||
{ label: t.navReviews, href: "#testimonials" }
|
||
].map(item => (
|
||
<a
|
||
key={item.label}
|
||
href={item.href}
|
||
className="text-[11px] font-bold tracking-[1.5px] uppercase text-[#111317]/70 hover:text-[#E5A900] transition-colors relative py-1 cursor-pointer group"
|
||
>
|
||
{item.label}
|
||
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-[#E5A900] transition-all group-hover:w-full" />
|
||
</a>
|
||
))}
|
||
</nav>
|
||
|
||
{/* Direct Dial booking & Lang Selector */}
|
||
<div className="flex items-center gap-6">
|
||
{/* Language Switcher */}
|
||
<div className="flex items-center gap-1 bg-[#111317]/5 border border-[#111317]/10 rounded-xl p-1 shrink-0">
|
||
<button
|
||
onClick={() => setLang("tr")}
|
||
className={`text-[9px] font-black px-2.5 py-1.5 rounded-lg transition-all cursor-pointer font-sans-premium ${
|
||
lang === "tr" ? "bg-[#E5A900] text-white shadow-sm" : "text-[#111317]/60 hover:text-[#111317]"
|
||
}`}
|
||
>
|
||
TR
|
||
</button>
|
||
<button
|
||
onClick={() => setLang("en")}
|
||
className={`text-[9px] font-black px-2.5 py-1.5 rounded-lg transition-all cursor-pointer font-sans-premium ${
|
||
lang === "en" ? "bg-[#E5A900] text-white shadow-sm" : "text-[#111317]/60 hover:text-[#111317]"
|
||
}`}
|
||
>
|
||
EN
|
||
</button>
|
||
</div>
|
||
|
||
<motion.button
|
||
onClick={() => setShowBookingModal(true)}
|
||
className="text-[11px] font-black tracking-[2px] uppercase text-white bg-[#E5A900] hover:bg-black px-6 py-3.5 rounded-xl transition-all cursor-pointer shadow-[0_4px_12px_rgba(229,169,0,0.2)] hidden sm:block"
|
||
whileHover={{ scale: 1.03 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
>
|
||
{t.bookNow}
|
||
</motion.button>
|
||
</div>
|
||
</div>
|
||
</motion.header>
|
||
|
||
{/* ── HERO SECTION ── */}
|
||
<section className="relative min-h-screen pt-32 pb-20 flex items-center z-10 px-6">
|
||
<div className="max-w-7xl mx-auto w-full">
|
||
<div className="grid lg:grid-cols-12 gap-12 items-center">
|
||
|
||
{/* Left Column: Heading, Slogans, Direct Reservation */}
|
||
<motion.div
|
||
className="lg:col-span-7 z-20"
|
||
variants={stagger}
|
||
initial="hidden"
|
||
animate="show"
|
||
>
|
||
{/* Minimalist Accent Badge */}
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="inline-flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-[#E5A900] mb-6 bg-[#E5A900]/5 border border-[#E5A900]/15 px-4 py-2 rounded-full"
|
||
>
|
||
<span className="w-1.5 h-1.5 rounded-full bg-[#E5A900]" />
|
||
{t.badge}
|
||
</motion.div>
|
||
|
||
<motion.h1
|
||
variants={fadeUp}
|
||
className="font-industrial font-black text-[#111317] mb-6 uppercase hero-title-clamp"
|
||
>
|
||
{t.heroTitlePart1}
|
||
<br />
|
||
<span className="text-[#E5A900]">{t.heroTitlePart2}</span>
|
||
</motion.h1>
|
||
|
||
<motion.p
|
||
variants={fadeUp}
|
||
className="text-black/60 text-sm lg:text-base leading-relaxed max-w-xl mb-10 font-medium"
|
||
>
|
||
{t.heroDesc}
|
||
</motion.p>
|
||
|
||
{/* Direct Dial block */}
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="flex items-center gap-6 mb-12"
|
||
>
|
||
<div className="w-14 h-14 rounded-2xl bg-white border border-black/5 flex items-center justify-center shrink-0 shadow-sm">
|
||
<svg className="w-6 h-6 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-2.824-1.802-5.12-4.098-6.922-6.922l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H3.75A2.25 2.25 0 0 0 2.25 4.5v2.25Z" />
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<div className="text-[11px] uppercase tracking-widest text-black/40 font-bold">{t.instantBooking}</div>
|
||
<a href={`tel:${firma.telefon}`} className="text-3xl font-black text-[#111317] hover:text-[#E5A900] transition-colors font-industrial tracking-wide">
|
||
{firma.telefon}
|
||
</a>
|
||
</div>
|
||
</motion.div>
|
||
|
||
{/* Action Buttons */}
|
||
<motion.div variants={fadeUp} className="flex gap-4">
|
||
<a
|
||
href="#booking-flow"
|
||
className="px-8 py-4 rounded-xl bg-[#E5A900] hover:bg-black text-white font-black text-xs uppercase tracking-wider transition-all shadow-[0_4px_12px_rgba(229,169,0,0.25)] cursor-pointer"
|
||
>
|
||
{t.getQuote}
|
||
</a>
|
||
<a
|
||
href="#tariffs"
|
||
className="px-8 py-4 rounded-xl border border-black/10 bg-white/50 hover:bg-[#F5F2EC] text-black font-black text-xs uppercase tracking-wider transition-all cursor-pointer shadow-sm"
|
||
>
|
||
{t.viewTariffs}
|
||
</a>
|
||
</motion.div>
|
||
</motion.div>
|
||
|
||
{/* Right Column: Premium White e-tron Car & Rotating circular stamp */}
|
||
<div className="lg:col-span-5 relative flex justify-center lg:justify-end">
|
||
<motion.div
|
||
className="relative w-full max-w-md lg:max-w-lg h-[400px] lg:h-[480px] flex items-center justify-center"
|
||
initial={{ opacity: 0, scale: 0.95 }}
|
||
animate={{ opacity: 1, scale: 1 }}
|
||
transition={{ duration: 0.85, ease: "easeOut" }}
|
||
>
|
||
{/* Outer circle overlay */}
|
||
<div className="absolute inset-2 rounded-full border border-dashed border-[#E5A900]/20 animate-[spin_60s_linear_infinite]" />
|
||
|
||
{/* High fidelity White luxury cab */}
|
||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||
<img
|
||
src="/cab_hero_white.png"
|
||
alt="CabHub White e-tron GT Luxury Electric NYC Cab"
|
||
className="w-full h-full object-contain relative z-10 drop-shadow-[0_15px_35px_rgba(229,169,0,0.1)] rounded-[32px]"
|
||
/>
|
||
|
||
{/* Spinning stamp */}
|
||
<div className="absolute bottom-0 right-0 z-20 w-32 h-32 flex items-center justify-center">
|
||
<svg className="absolute w-full h-full spinning-badge" viewBox="0 0 100 100">
|
||
<path id="badgePathLight" d="M 50, 50 m -35, 0 a 35,35 0 1,1 70,0 a 35,35 0 1,1 -70,0" fill="none" />
|
||
<text className="font-industrial font-bold text-[8.5px] fill-[#E5A900] tracking-[1.8px]">
|
||
<textPath xlinkHref="#badgePathLight">
|
||
LOUNGE TRANSFER • AIRPORT EXPRESS • 24/7 •
|
||
</textPath>
|
||
</text>
|
||
</svg>
|
||
<div className="w-12 h-12 rounded-full bg-white border border-[#E5A900]/30 flex items-center justify-center z-10 shadow-md">
|
||
<svg className="w-5 h-5 fill-[#E5A900]" viewBox="0 0 24 24">
|
||
<path d="M22 10.07V6c0-.55-.45-1-1-1h-2v-.07c0-.9-.72-1.63-1.61-1.68C17.15 3.12 17 3.32 17 3.5V5h-2V3.5c0-.18-.15-.38-.39-.25-.89.05-1.61.78-1.61 1.68V5H5c-.55 0-1 .45-1 1v4.07c-1.19.43-2 1.56-2 2.93v3c0 .55.45 1 1 1h1v1.5c0 .83.67 1.5 1.5 1.5h1c.83 0 1.5-.67 1.5-1.5V18h10v1.5c0 .83.67 1.5 1.5 1.5h1c.83 0 1.5-.67 1.5-1.5V18h1c.55 0 1-.45 1-1v-3c0-1.37-.81-2.5-2-2.93z" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── BOOKING FLOW & CALCULATOR ── */}
|
||
<section id="booking-flow" className="py-24 relative z-10 px-6 border-t border-black/5 bg-[#F5F2EC]/40">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="bg-white rounded-3xl border border-black/5 p-8 md:p-12 shadow-xl relative">
|
||
{/* Gold line border indicator */}
|
||
<div className="absolute top-0 left-12 right-12 h-0.5 bg-gradient-to-r from-transparent via-[#E5A900] to-transparent gold-bar-glow" />
|
||
|
||
<div className="text-center max-w-xl mx-auto mb-12">
|
||
<span className="text-[#E5A900] font-bold text-xs uppercase tracking-widest block mb-2 font-industrial">{t.fastFormSubtitle}</span>
|
||
<h2 className="font-industrial text-3xl md:text-4xl font-black uppercase text-[#111317]">
|
||
{t.fastFormTitle}
|
||
</h2>
|
||
<p className="text-[#111317]/50 text-xs mt-2 font-medium">
|
||
{t.fastFormDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Form Input fields */}
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||
{[
|
||
{ label: t.formName, placeholder: t.formNamePlaceholder, type: "text" },
|
||
{ label: t.formPhone, placeholder: t.formPhonePlaceholder, type: "tel" },
|
||
{ label: t.formDate, placeholder: "", type: "date" },
|
||
{ label: t.formTime, placeholder: "", type: "time" },
|
||
].map((field, idx) => (
|
||
<div key={idx} className="flex flex-col">
|
||
<label className="text-[10px] font-bold text-black/50 mb-1.5 uppercase tracking-widest">{field.label}</label>
|
||
<input
|
||
type={field.type}
|
||
placeholder={field.placeholder}
|
||
className="px-4 py-3.5 rounded-xl border border-black/5 bg-[#FCFAF7] text-sm text-black placeholder-black/20 focus:outline-none focus:border-[#E5A900] focus:ring-1 focus:ring-[#E5A900] transition-all font-sans-clean font-medium"
|
||
/>
|
||
</div>
|
||
))}
|
||
|
||
{/* Pickup Location select */}
|
||
<div className="flex flex-col">
|
||
<label className="text-[10px] font-bold text-black/50 mb-1.5 uppercase tracking-widest">{t.formPickup}</label>
|
||
<select
|
||
value={pickupLoc}
|
||
onChange={(e) => setPickupLoc(e.target.value)}
|
||
className="px-4 py-3.5 rounded-xl border border-black/5 bg-[#FCFAF7] text-sm text-black focus:outline-none focus:border-[#E5A900] transition-all font-sans-clean font-medium cursor-pointer"
|
||
>
|
||
{locationsList.map(loc => <option key={loc} value={loc} className="bg-white text-black">{loc}</option>)}
|
||
</select>
|
||
</div>
|
||
|
||
{/* Dropoff Location select */}
|
||
<div className="flex flex-col">
|
||
<label className="text-[10px] font-bold text-black/50 mb-1.5 uppercase tracking-widest">{t.formDropoff}</label>
|
||
<select
|
||
value={dropoffLoc}
|
||
onChange={(e) => setDropoffLoc(e.target.value)}
|
||
className="px-4 py-3.5 rounded-xl border border-black/5 bg-[#FCFAF7] text-sm text-black focus:outline-none focus:border-[#E5A900] transition-all font-sans-clean font-medium cursor-pointer"
|
||
>
|
||
{locationsList.map(loc => <option key={loc} value={loc} className="bg-white text-black">{loc}</option>)}
|
||
</select>
|
||
</div>
|
||
|
||
{/* Choose Vehicle */}
|
||
<div className="flex flex-col md:col-span-2">
|
||
<label className="text-[10px] font-bold text-black/50 mb-1.5 uppercase tracking-widest">{t.chooseVehicle}</label>
|
||
<div className="grid grid-cols-3 gap-2 h-full">
|
||
{["Economy", "Standard", "Business"].map((option, oIdx) => (
|
||
<button
|
||
key={option}
|
||
onClick={() => setActivePlan(oIdx)}
|
||
className={`py-3.5 px-3 rounded-xl border text-xs font-bold transition-all cursor-pointer flex items-center justify-center gap-1.5 ${
|
||
activePlan === oIdx
|
||
? "bg-[#E5A900] text-white border-[#E5A900]"
|
||
: "bg-[#FCFAF7] text-black/60 border-black/5 hover:border-black/15"
|
||
}`}
|
||
>
|
||
<span className="w-1.5 h-1.5 rounded-full" style={{ backgroundColor: activePlan === oIdx ? "white" : "#E5A900" }} />
|
||
{option}
|
||
</button>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* ESTIMATED FARE BANNER */}
|
||
<div className="mt-8 p-6 bg-[#FCFAF7] border border-black/5 rounded-2xl flex flex-col sm:flex-row justify-between items-center gap-4">
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-10 h-10 rounded-xl bg-[#E5A900]/10 border border-[#E5A900]/20 flex items-center justify-center shrink-0">
|
||
<span className="text-[#E5A900] text-lg font-black font-industrial">$</span>
|
||
</div>
|
||
<div>
|
||
<span className="text-black/40 text-[9px] uppercase tracking-widest font-black block">{t.calculatingText}</span>
|
||
<span className="font-industrial text-black text-sm font-bold uppercase tracking-wider">{t.calcEstimated} <span className="text-[#E5A900] text-base">{calculatePrice()}</span></span>
|
||
</div>
|
||
</div>
|
||
<div className="text-[10px] font-bold text-black/40 leading-relaxed font-sans-clean text-center sm:text-right">
|
||
Flat-rate airport vouchers apply dynamically between JFK / LaGuardia and Manhattan.
|
||
</div>
|
||
</div>
|
||
|
||
{/* Submit panel */}
|
||
<div className="mt-8 pt-4 flex flex-col md:flex-row justify-between items-center gap-4">
|
||
<p className="text-black/40 text-xs font-medium max-w-md text-center md:text-left">
|
||
{t.dispatchWarning}
|
||
</p>
|
||
<motion.button
|
||
onClick={() => setShowBookingModal(true)}
|
||
className="w-full md:w-auto px-10 py-4.5 rounded-xl bg-[#E5A900] hover:bg-black text-white font-black text-xs uppercase tracking-widest transition-all cursor-pointer shadow-[0_4px_12px_rgba(229,169,0,0.25)] shrink-0"
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
>
|
||
{t.submitBooking}
|
||
</motion.button>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── OUR TARIFFS (Bento style Light Plans) ── */}
|
||
<section id="tariffs" className="py-32 relative z-10 px-6 bg-[#FCFAF7]">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="text-center max-w-xl mx-auto mb-20">
|
||
<span className="text-[#E5A900] font-bold text-xs uppercase tracking-widest block mb-2 font-industrial">{t.tariffsSubtitle}</span>
|
||
<h2 className="font-industrial text-3xl lg:text-4xl font-black uppercase text-[#111317]">
|
||
{t.tariffsTitle}
|
||
</h2>
|
||
<p className="text-black/40 text-xs mt-2 font-medium">
|
||
{t.tariffsDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Three Cards Grid */}
|
||
<div className="grid lg:grid-cols-3 gap-8">
|
||
{istatistikler.map((stat, sIdx) => {
|
||
const locStat = getLocalizedStat(stat.deger);
|
||
const isPopular = stat.deger === "Standard Class";
|
||
return (
|
||
<motion.div
|
||
key={sIdx}
|
||
className={`relative rounded-3xl p-8 flex flex-col justify-between transition-all duration-300 group ${
|
||
isPopular
|
||
? "bg-white border-2 border-[#E5A900] shadow-[0_12px_30px_rgba(229,169,0,0.06)]"
|
||
: "bg-white border border-black/5 hover:border-black/10"
|
||
}`}
|
||
initial={{ opacity: 0, y: 30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.5, delay: sIdx * 0.1 }}
|
||
whileHover={{ y: -6 }}
|
||
>
|
||
{isPopular && (
|
||
<div className="absolute -top-3.5 left-1/2 -translate-x-1/2 px-4 py-1 bg-[#E5A900] text-white text-[9px] font-black uppercase tracking-widest rounded-full z-10 shadow-sm">
|
||
{t.popular}
|
||
</div>
|
||
)}
|
||
|
||
<div>
|
||
{/* Car vector silhouette placeholder */}
|
||
<div className="h-28 flex items-center justify-center border-b border-black/5 mb-8 relative">
|
||
<svg className={`w-32 h-16 ${isPopular ? "fill-[#E5A900]" : "fill-black/20 group-hover:fill-[#E5A900]"} transition-colors`} viewBox="0 0 24 24">
|
||
<path d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.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.5zM5 11l1.5-4.5h11L19 11H5z" />
|
||
</svg>
|
||
</div>
|
||
|
||
<h3 className="font-industrial font-black text-2xl uppercase tracking-wider text-black mb-2">
|
||
{locStat.title}
|
||
</h3>
|
||
<p className="text-black/60 text-xs leading-relaxed mb-8 font-medium">
|
||
{locStat.desc}
|
||
</p>
|
||
</div>
|
||
|
||
<div>
|
||
{/* Price display */}
|
||
<div className="flex items-baseline gap-1.5 mb-8">
|
||
<span className="text-3xl font-black text-[#E5A900] font-industrial">
|
||
{sIdx === 0 ? "$1.50" : sIdx === 1 ? "$2.20" : "$3.50"}
|
||
</span>
|
||
<span className="text-black/40 text-xs uppercase tracking-widest font-bold">{t.perMile}</span>
|
||
</div>
|
||
|
||
<motion.button
|
||
onClick={() => {
|
||
setActivePlan(sIdx);
|
||
const el = document.getElementById("booking-flow");
|
||
el?.scrollIntoView({ behavior: "smooth" });
|
||
}}
|
||
className={`w-full py-4.5 rounded-xl font-black text-xs uppercase tracking-widest transition-all cursor-pointer ${
|
||
isPopular
|
||
? "bg-[#E5A900] hover:bg-black text-white shadow-md shadow-[#E5A900]/10"
|
||
: "bg-[#FCFAF7] hover:bg-black hover:text-white text-black/70 border border-black/5 hover:border-black/10"
|
||
}`}
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
>
|
||
{t.bookTariff}
|
||
</motion.button>
|
||
</div>
|
||
|
||
</motion.div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── CORE BENEFITS ── */}
|
||
<section id="benefits" className="py-28 relative z-10 px-6 bg-white border-t border-black/5">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="text-center max-w-xl mx-auto mb-20">
|
||
<span className="text-[#E5A900] font-bold text-xs uppercase tracking-widest block mb-2 font-industrial">{t.benefitsSubtitle}</span>
|
||
<h2 className="font-industrial text-3xl lg:text-4xl font-black uppercase text-black">
|
||
{t.benefitsTitle}
|
||
</h2>
|
||
<p className="text-black/40 text-xs mt-2 font-medium">
|
||
{t.benefitsDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Grid */}
|
||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||
{hizmetler.map((benefit, bIdx) => {
|
||
const locBenefit = getLocalizedService(benefit.baslik, benefit.aciklama);
|
||
return (
|
||
<motion.div
|
||
key={bIdx}
|
||
className="bg-[#FCFAF7] rounded-2xl p-8 border border-black/5 hover:border-[#E5A900]/30 transition-all duration-300 flex flex-col items-center text-center group cursor-default shadow-sm"
|
||
initial={{ opacity: 0, y: 20 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.5, delay: bIdx * 0.1 }}
|
||
whileHover={{ y: -4 }}
|
||
>
|
||
<div className="w-16 h-16 rounded-2xl bg-white border border-black/5 flex items-center justify-center mb-6 transition-transform group-hover:scale-105 group-hover:border-[#E5A900]/30 shadow-sm">
|
||
{getIconSvg(benefit.ikon)}
|
||
</div>
|
||
|
||
<h3 className="font-industrial font-black text-lg text-black mb-3 tracking-wider uppercase">
|
||
{locBenefit.title}
|
||
</h3>
|
||
<p className="text-black/50 text-[11px] leading-relaxed font-medium">
|
||
{locBenefit.desc}
|
||
</p>
|
||
</motion.div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── APP SHOWCASE ── */}
|
||
<section id="app-showcase" className="py-32 relative z-10 px-6 bg-[#FCFAF7] border-t border-black/5">
|
||
<div className="max-w-7xl mx-auto">
|
||
<div className="grid lg:grid-cols-12 gap-16 items-center">
|
||
|
||
{/* Left Column: text details and store buttons */}
|
||
<motion.div
|
||
className="lg:col-span-6 z-20"
|
||
initial="hidden"
|
||
whileInView="show"
|
||
viewport={{ once: true, amount: 0.2 }}
|
||
variants={stagger}
|
||
>
|
||
<motion.span
|
||
variants={fadeUp}
|
||
className="text-[#E5A900] font-bold text-xs uppercase tracking-widest block mb-2 font-industrial"
|
||
>
|
||
{t.appSubtitle}
|
||
</motion.span>
|
||
<motion.h2
|
||
variants={fadeUp}
|
||
className="font-industrial text-4xl lg:text-5xl font-black tracking-tight text-black uppercase mb-6"
|
||
>
|
||
{t.appTitle}
|
||
</motion.h2>
|
||
<motion.p
|
||
variants={fadeUp}
|
||
className="text-black/60 text-sm leading-relaxed mb-10 max-w-md font-medium"
|
||
>
|
||
{t.appDesc}
|
||
</motion.p>
|
||
|
||
{/* Badges buttons */}
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="flex items-center gap-4 flex-wrap"
|
||
>
|
||
{/* Google Play */}
|
||
<a href="#" className="flex items-center gap-3 px-6 py-3 rounded-xl bg-white hover:bg-[#F5F2EC] border border-black/5 transition-colors shadow-sm cursor-pointer group">
|
||
<svg className="w-6 h-6 fill-[#E5A900]" viewBox="0 0 24 24">
|
||
<path d="M5 2c-.37 0-.71.18-.91.49l10.96 10.96 3.1-3.1L5.6 3.12C5.41 3.04 5.21 2 5 2zm10.75 11.21L4.69 22.42c.19-.07.38-.17.51-.29l12.65-7.3a1.5 1.5 0 0 0 .15-.15l-2.25-1.47zM3.19 3.81C3.07 4.17 3 4.58 3 5v14c0 .42.07.83.19 1.19l9.31-9.31-9.31-9.07z" />
|
||
</svg>
|
||
<div className="text-left">
|
||
<div className="text-[8px] text-black/40 uppercase tracking-wider font-bold">{t.getItOn}</div>
|
||
<div className="text-xs font-black text-black font-industrial tracking-wide">{t.googlePlay}</div>
|
||
</div>
|
||
</a>
|
||
|
||
{/* App Store */}
|
||
<a href="#" className="flex items-center gap-3 px-6 py-3 rounded-xl bg-white hover:bg-[#F5F2EC] border border-black/5 transition-colors shadow-sm cursor-pointer group">
|
||
<svg className="w-6 h-6 fill-[#E5A900]" viewBox="0 0 24 24">
|
||
<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.83M15.97 4.17c.66-.81 1.11-1.93.99-3.06-1 .04-2.21.67-2.93 1.49-.62.69-1.16 1.84-1.01 2.96 1.12.09 2.27-.57 2.95-1.39z" />
|
||
</svg>
|
||
<div className="text-left">
|
||
<div className="text-[8px] text-black/40 uppercase tracking-wider font-bold">{t.getItOn}</div>
|
||
<div className="text-xs font-black text-black font-industrial tracking-wide">{t.appStore}</div>
|
||
</div>
|
||
</a>
|
||
</motion.div>
|
||
</motion.div>
|
||
|
||
{/* Right Column: Light theme smartphone mockup */}
|
||
<div className="lg:col-span-6 relative flex justify-center lg:justify-end">
|
||
<motion.div
|
||
className="relative w-full max-w-md lg:max-w-lg h-[450px] lg:h-[520px] rounded-[36px] overflow-hidden shadow-xl border border-black/5 group"
|
||
initial={{ opacity: 0, x: 40 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.7 }}
|
||
>
|
||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||
<img
|
||
src="/cab_app_light.png"
|
||
alt="CabHub Light-themed Booking interface tracking map"
|
||
className="w-full h-full object-cover scale-102 group-hover:scale-105 transition-transform duration-[4000ms]"
|
||
/>
|
||
</motion.div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── TESTIMONIALS ── */}
|
||
<section id="testimonials" className="py-28 relative z-10 px-6 bg-white border-t border-black/5">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="text-center max-w-xl mx-auto mb-20">
|
||
<span className="text-[#E5A900] font-bold text-xs uppercase tracking-widest block mb-2 font-industrial">{t.reviewsSubtitle}</span>
|
||
<h2 className="font-industrial text-3xl lg:text-4xl font-black uppercase text-black">
|
||
{t.reviewsTitle}
|
||
</h2>
|
||
<p className="text-black/40 text-xs mt-2 font-medium">
|
||
{t.reviewsDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Testimonials 2-Column Grid */}
|
||
<div className="grid md:grid-cols-2 gap-8">
|
||
{yorumlar.map((y, yIdx) => {
|
||
const locTestimonial = getLocalizedTestimonial(y.yazar);
|
||
return (
|
||
<motion.div
|
||
key={yIdx}
|
||
className="bg-[#FCFAF7] border border-black/5 rounded-3xl p-8 flex flex-col justify-between transition-all duration-300 hover:border-[#E5A900]/30 group"
|
||
initial={{ opacity: 0, y: 30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.5, delay: yIdx * 0.1 }}
|
||
whileHover={{ y: -4 }}
|
||
>
|
||
{/* Rating Stars SVG */}
|
||
<div className="flex gap-1 mb-6">
|
||
{[...Array(5)].map((_, starIdx) => (
|
||
<svg key={starIdx} className="w-4.5 h-4.5 fill-[#E5A900]" viewBox="0 0 24 24">
|
||
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" />
|
||
</svg>
|
||
))}
|
||
</div>
|
||
|
||
<p className="text-black/70 text-xs leading-relaxed italic mb-8 font-medium">
|
||
“{locTestimonial}”
|
||
</p>
|
||
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-10 h-10 rounded-full border border-black/5 flex items-center justify-center text-xs font-sans-premium font-black bg-white select-none shadow-sm text-[#E5A900]">
|
||
{y.yazar.charAt(0)}
|
||
</div>
|
||
<div>
|
||
<h4 className="font-industrial text-black text-xs font-black uppercase tracking-wider">
|
||
{y.yazar}
|
||
</h4>
|
||
<span className="text-[9px] text-black/40 uppercase tracking-widest font-bold">
|
||
{y.tarih}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
</motion.div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── BOTTOM CALL RESERVATION DIRECT STRIP ── */}
|
||
<section className="relative z-10 bg-[#111317] text-white py-8 px-6 text-center pulse-glow-dark overflow-hidden">
|
||
<div className="max-w-7xl mx-auto relative z-10 flex flex-col md:flex-row justify-between items-center gap-4">
|
||
<h3 className="font-industrial font-black text-base md:text-xl uppercase tracking-wider text-white text-center md:text-left">
|
||
{t.callStripText}
|
||
</h3>
|
||
<a href={`tel:${firma.telefon}`} className="inline-flex items-center gap-3 px-8 py-3.5 bg-[#E5A900] hover:bg-white text-white hover:text-black rounded-xl font-industrial font-black tracking-widest uppercase transition-all shadow-[0_4px_12px_rgba(229,169,0,0.2)] text-sm cursor-pointer">
|
||
📞 {firma.telefon}
|
||
</a>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── FOOTER ── */}
|
||
<footer className="bg-[#FCFAF7] border-t border-black/5 pt-24 pb-8 px-6 relative z-10">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="grid md:grid-cols-4 gap-12 pb-16 border-b border-black/5">
|
||
|
||
{/* About Column */}
|
||
<div className="md:col-span-2">
|
||
<span className="font-industrial text-2xl font-black text-black tracking-wider uppercase mb-4 block">
|
||
CAB<span className="text-[#E5A900]">HUB</span>
|
||
</span>
|
||
<p className="text-black/50 text-xs leading-relaxed max-w-sm mb-8 font-medium">
|
||
{firma.slogan} — Exclusive, verified zero-emission lounge drop-offs and corporate city transfers in New York City.
|
||
</p>
|
||
<div className="text-black/60 text-xs font-medium space-y-2">
|
||
<p className="flex items-center gap-2">📍 <span className="text-black/80">{firma.adres}</span></p>
|
||
<p className="flex items-center gap-2">📧 <span className="text-black/80">{firma.email}</span></p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Download links */}
|
||
<div>
|
||
<h4 className="font-industrial text-[#E5A900] text-xs font-black uppercase tracking-wider mb-6">
|
||
DOWNLOAD APP
|
||
</h4>
|
||
<div className="space-y-4">
|
||
<a href="#" className="block text-black/50 hover:text-[#E5A900] text-xs transition-colors font-medium">
|
||
Google Play Store App
|
||
</a>
|
||
<a href="#" className="block text-black/50 hover:text-[#E5A900] text-xs transition-colors font-medium">
|
||
Apple iOS App Store
|
||
</a>
|
||
<a href="#" className="block text-black/50 hover:text-[#E5A900] text-xs transition-colors font-medium">
|
||
Direct Web Voucher Portal
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Navigation links */}
|
||
<div>
|
||
<h4 className="font-industrial text-[#E5A900] text-xs font-black uppercase tracking-wider mb-6">
|
||
USEFUL LINKS
|
||
</h4>
|
||
<div className="space-y-4">
|
||
{["Book a Cab", "Economy & Business Tariffs", "Our Core Benefits", "Happy Reviews", "Terms & Regulations"].map(item => (
|
||
<a
|
||
key={item}
|
||
href="#"
|
||
className="block text-black/50 hover:text-[#E5A900] text-xs transition-colors font-medium"
|
||
>
|
||
{item}
|
||
</a>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div className="flex flex-col md:flex-row justify-between items-center pt-8 gap-4 text-black/30 text-xs font-medium font-sans-premium">
|
||
<p>© 2026 {firma.adi}. {t.footerRights}</p>
|
||
<div className="flex gap-4">
|
||
<a href="#" className="hover:text-[#E5A900] transition-colors">{t.footerPrivacy}</a>
|
||
<span>·</span>
|
||
<a href="#" className="hover:text-[#E5A900] transition-colors">{t.footerTerms}</a>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</footer>
|
||
|
||
{/* ── FAST BOOKING SUCCESS MODAL ── */}
|
||
<AnimatePresence>
|
||
{showBookingModal && (
|
||
<motion.div
|
||
className="fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/50 backdrop-blur-sm"
|
||
initial={{ opacity: 0 }}
|
||
animate={{ opacity: 1 }}
|
||
exit={{ opacity: 0 }}
|
||
>
|
||
<motion.div
|
||
className="bg-white rounded-3xl p-8 max-w-md w-full relative shadow-2xl border border-black/5"
|
||
initial={{ scale: 0.95, y: 20 }}
|
||
animate={{ scale: 1, y: 0 }}
|
||
exit={{ scale: 0.95, y: 20 }}
|
||
>
|
||
{/* Close Button */}
|
||
<button
|
||
className="absolute top-6 right-6 w-8 h-8 rounded-full bg-[#FCFAF7] border border-black/5 flex items-center justify-center text-black/40 hover:text-[#E5A900] hover:border-[#E5A900]/20 transition-all cursor-pointer"
|
||
onClick={() => setShowBookingModal(false)}
|
||
>
|
||
✕
|
||
</button>
|
||
|
||
{/* Success check indicator */}
|
||
<div className="w-16 h-16 rounded-2xl bg-[#E5A900]/10 border border-[#E5A900]/20 flex items-center justify-center mb-6">
|
||
<svg className="w-8 h-8 stroke-[#E5A900] fill-none" viewBox="0 0 24 24" strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||
</svg>
|
||
</div>
|
||
|
||
<h3 className="font-industrial text-black text-2xl mb-1 uppercase tracking-wider">
|
||
{t.bookingRequested}
|
||
</h3>
|
||
<p className="text-[#E5A900] font-mono text-[10px] mb-6 uppercase tracking-widest font-bold">
|
||
{t.nycDispatchActive}
|
||
</p>
|
||
|
||
<p className="text-black/60 text-xs leading-relaxed mb-8 font-medium">
|
||
{t.successDesc}
|
||
</p>
|
||
|
||
<motion.button
|
||
className="w-full py-4.5 rounded-xl bg-[#E5A900] hover:bg-black text-white font-black text-xs uppercase tracking-widest cursor-pointer shadow-md shadow-[#E5A900]/15"
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
onClick={() => setShowBookingModal(false)}
|
||
>
|
||
{t.dismiss}
|
||
</motion.button>
|
||
</motion.div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
|
||
</div>
|
||
</>
|
||
);
|
||
}
|