Files
demo-ayristech/components/templates/TaxiTemplate2/index.tsx
T
2026-06-06 00:43:39 +03:00

1162 lines
59 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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">
&ldquo;{locTestimonial}&rdquo;
</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>
</>
);
}