846 lines
40 KiB
TypeScript
846 lines
40 KiB
TypeScript
"use client";
|
||
|
||
import { motion, AnimatePresence } from "framer-motion";
|
||
import { 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",
|
||
navSuites: "Özel Süitler",
|
||
navExp: "Deneyimler",
|
||
navRev: "Yorumlar",
|
||
badge: "BUTİK LÜKS RESORT",
|
||
heroTail: "sizi bekliyor",
|
||
heroDesc: "Cal Vestam'da eşsiz bir huzura dalın. Fethiye'nin nefes kesici mavi sırtlarının üzerinde, size özel cam kenarlı sonsuzluk havuzları ve organik zeytin yaprağı masaj terapileri sunuyoruz.",
|
||
reserveNow: "Rezervasyon Yap",
|
||
planEscape: "TATİLİ PLANLA",
|
||
resortServices: "RESORT HİZMETLERİ",
|
||
checkAvailability: "UYGUNLUK DURUMU",
|
||
scheduleEscape: "RESORT TATİLİNİZİ PLANLAYIN",
|
||
scheduleDesc: "Benzersiz deniz manzaralı teras süitinizde yerinizi ayırtmak için tarihlerinizi belirleyin.",
|
||
checkin: "GİRİŞ TARİHİ",
|
||
checkout: "ÇIKIŞ TARİHİ",
|
||
adults: "YETİŞKİN",
|
||
kids: "ÇOCUK (12 YAŞ ALTI)",
|
||
guests: "Misafir",
|
||
kidsLabel: "Çocuk",
|
||
guarantee: "Rezervasyonlar, giriş esnasında taze toplanmış narenciye kokteyli ikramı ile en iyi fiyat garantisini kilitler.",
|
||
confirmDetails: "TARİHLERİ ONAYLA",
|
||
suitesTitle: "TERAS SÜİTLERİ",
|
||
suitesHeader: "SEÇKİN SÜİTLER",
|
||
suitesDesc: "Özel dokuma keten serimler, doğal zeytinyağlı sabunlar ve kesintisiz deniz panoraması ile mimari lüksü deneyimleyin.",
|
||
secureRes: "REZERVASYON YAP →",
|
||
diaries: "Misafir Defteri",
|
||
lovedGuests: "LOVED BY GUESTS",
|
||
lovedDesc: "Seçkin gezginlerin ve küresel mimari yazarlarının Cal Vestam deneyimlerini keşfedin.",
|
||
vipCoords: "VIP KOORDİNATLAR",
|
||
conciergeActive: "Resort Concierge Aktif",
|
||
checkInOutDetails: "Giriş: 15:00 · Çıkış: 11:00",
|
||
boutiqueLeisures: "BUTİK AYRICALIKLAR",
|
||
privacyRegs: "Gizlilik Sözleşmesi",
|
||
termsStay: "Konaklama Şartları",
|
||
dismiss: "KAPAT",
|
||
enquiryActive: "BAŞVURU ALINDI",
|
||
ambassadorActive: "Cal Vestam Concierge Aktif",
|
||
enquirySuccess: "Akdeniz resort rezervasyon koordinatlarınızı kaydettik. Özel misafir elçimiz giriş işlemlerinizi öncelikli olarak tamamlamak için sizinle iletişime geçecektir. Teşekkürler!",
|
||
|
||
// Suite details
|
||
suite1Title: "PANORAMİK VESTAM SÜİT",
|
||
suite1Desc: "Fethiye'nin mavi sırtlarına bakan özel havuzlu balkon ve premium pamuklu yatak tasarımı.",
|
||
suite2Title: "NARENCİYE BAHÇE SÜİTİ",
|
||
suite2Desc: "Çevreleyen zeytin ve limon bahçeleriyle entegre, gün ışığıyla dolu ferah konaklama deneyimi.",
|
||
suite3Title: "AKDENİZ VİLLASI",
|
||
suite3Desc: "Özel sonsuzluk havuzları, kişisel uşak hizmeti ve gün batımı terasları sunan tam villa kiralama.",
|
||
|
||
// Welcome orchards
|
||
welcomeTitle: "Karşılama İkramları",
|
||
welcomeDesc: "MİSAFİRLERİMİZ İÇİN TAZE NARENCİYE KOKTEYLLERİ",
|
||
},
|
||
en: {
|
||
navBook: "Book stay",
|
||
navSuites: "Exclusive suites",
|
||
navExp: "Experiences",
|
||
navRev: "Guest reviews",
|
||
badge: "BOUTIQUE LUXURY RESORT",
|
||
heroTail: "awaits your arrival",
|
||
heroDesc: "Submerge into sheer tranquility at Cal Vestam. Situated directly above Muğla's gorgeous blue ridges, we stage exclusive glass-edge infinity pools and wellness stone therapy.",
|
||
reserveNow: "Reserve Now",
|
||
planEscape: "PLAN ESCAPE",
|
||
resortServices: "RESORT SERVICES",
|
||
checkAvailability: "Check availability",
|
||
scheduleEscape: "SCHEDULE YOUR RESORT ESCAPE",
|
||
scheduleDesc: "Allocate your exclusive sea-view panoramic terrace suite directly inside our luxury booking engine.",
|
||
checkin: "CHECK-IN DATE",
|
||
checkout: "CHECK-OUT DATE",
|
||
adults: "ADULTS",
|
||
kids: "KIDS (UNDER 12)",
|
||
guests: "Guests",
|
||
kidsLabel: "Kids",
|
||
guarantee: "Reservations lock in our premium best-rate guarantee with local welcome orchard citrus cocktail packages upon check-in.",
|
||
confirmDetails: "CONFIRM DETAILS",
|
||
suitesTitle: "Terrace suites",
|
||
suitesHeader: "EXCLUSIVE SUITES",
|
||
suitesDesc: "Experience high-end architecture layered with bespoke linen, local natural olive oil soaps, and floor-to-ceiling sea panoramas.",
|
||
secureRes: "SECURE RESERVATION →",
|
||
diaries: "Guest Diaries",
|
||
lovedGuests: "LOVED BY GUESTS",
|
||
lovedDesc: "Hear what prominent travelers and global architecture writers experience inside Cal Vestam.",
|
||
vipCoords: "VIP COORDINATES",
|
||
conciergeActive: "Concierge 24 Hours Active",
|
||
checkInOutDetails: "Check In: 3:00 PM · Check Out: 11:00 AM",
|
||
boutiqueLeisures: "BOUTIQUE LEISURES",
|
||
privacyRegs: "Privacy Regulations",
|
||
termsStay: "Terms of Stay",
|
||
dismiss: "DISMISS",
|
||
enquiryActive: "ENQUIRY ACTIVE",
|
||
ambassadorActive: "Cal Vestam Concierge Active",
|
||
enquirySuccess: "We have registered your Mediterranean resort reservation coordinates. A personal guest ambassador has locked your priority check-in slot. Thank you!",
|
||
|
||
// Suite details
|
||
suite1Title: "PANORAMIC VESTAM SUITE",
|
||
suite1Desc: "Private pool balcony looking directly over Fethiye blue ridges with premium cotton layout.",
|
||
suite2Title: "CITRUS GARDEN SUITE",
|
||
suite2Desc: "Cozy light-filled suite integrated with surrounding organic welcome olive and lemon orchards.",
|
||
suite3Title: "MEDITERRANEAN VILLA",
|
||
suite3Desc: "Executive buyout layout offering private infinity pools, automated concierge, and sunset lounges.",
|
||
|
||
// Welcome orchards
|
||
welcomeTitle: "Welcome Orchards",
|
||
welcomeDesc: "CITRUS COCKTAILS FOR GUESTS",
|
||
}
|
||
};
|
||
|
||
export default function HotelTemplate1({ data }: { data: DemoData }) {
|
||
const { firma, istatistikler = [], hizmetler = [], yorumlar = [] } = data;
|
||
const [showModal, setShowModal] = useState(false);
|
||
const [adults, setAdults] = useState(2);
|
||
const [kids, setKids] = useState(0);
|
||
const [lang, setLang] = useState<"tr" | "en">("tr");
|
||
const [preloader, setPreloader] = useState(true);
|
||
|
||
const t = translations[lang];
|
||
|
||
// 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 Curtain Timer
|
||
useEffect(() => {
|
||
const timer = setTimeout(() => {
|
||
setPreloader(false);
|
||
}, 1500);
|
||
return () => clearTimeout(timer);
|
||
}, []);
|
||
|
||
// Localized statistics
|
||
const getLocalizedStat = (etiket: string) => {
|
||
if (etiket.includes("Suites")) return lang === "tr" ? "İmza Deniz Süiti" : "Signature Sea Suites";
|
||
if (etiket.includes("Pools")) return lang === "tr" ? "Panoramik Havuz" : "Panoramic Infinity Pools";
|
||
if (etiket.includes("Experience")) return lang === "tr" ? "Misafir Memnuniyeti" : "Guest Experience Index";
|
||
return lang === "tr" ? "Doğal Zeytinyağı Sabun & Spa" : "Natural Olive Oil Soap & Spa";
|
||
};
|
||
|
||
// Localized services
|
||
const getLocalizedService = (baslik: string, aciklama: string) => {
|
||
if (baslik.includes("POOL")) {
|
||
return {
|
||
title: lang === "tr" ? "SONSUZLUK VESTAM HAVUZU" : "INFINITY VESTAM POOL",
|
||
desc: lang === "tr" ? "Fethiye'nin mavi sırtlarına bakan cam kenarlı, ödüllü sonsuzluk havuzlarımızın keyfini çıkarın." : aciklama
|
||
};
|
||
}
|
||
if (baslik.includes("SPA")) {
|
||
return {
|
||
title: lang === "tr" ? "REHIAL SPA TERAPİSİ" : "REHIAL SPA THERAPY",
|
||
desc: lang === "tr" ? "Yerel uzmanlar tarafından tasarlanan organik zeytin yaprağı taş masajları ve mineral tuzlu hidroterapi ile yenilenin." : aciklama
|
||
};
|
||
}
|
||
return {
|
||
title: lang === "tr" ? "AÇIK HAVA TERAS YEMEĞİ" : "AL-FRESCO TERRACE DINING",
|
||
desc: lang === "tr" ? "Akdeniz zeytin ağaçlarının altında taze bahçe malzemeleri ve soğuk sıkım narenciye lezzetlerinin tadını çıkarın." : aciklama
|
||
};
|
||
};
|
||
|
||
const css = `
|
||
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Inter:wght@300;400;500;600;700;800;900&display=swap');
|
||
|
||
:root {
|
||
--color-resort-teal: #14B8A6;
|
||
--color-resort-sand: #FAF8F5;
|
||
--color-resort-charcoal: #0F172A;
|
||
--color-resort-gold: #D4AF37;
|
||
}
|
||
|
||
.font-serif-editorial {
|
||
font-family: 'Playfair Display', Georgia, serif;
|
||
}
|
||
|
||
.font-sans-resort {
|
||
font-family: 'Inter', sans-serif;
|
||
}
|
||
|
||
.bg-light-mesh {
|
||
background-image:
|
||
radial-gradient(circle at 0% 0%, rgba(20, 184, 166, 0.04) 0%, transparent 40%),
|
||
radial-gradient(circle at 100% 100%, rgba(212, 175, 55, 0.03) 0%, transparent 50%);
|
||
}
|
||
|
||
.shadow-premium {
|
||
box-shadow: 0 20px 40px -15px rgba(15, 23, 42, 0.05);
|
||
}
|
||
|
||
.hero-title-clamp {
|
||
font-size: clamp(38px, 6vw, 90px);
|
||
letter-spacing: -0.02em;
|
||
line-height: 0.95;
|
||
}
|
||
`;
|
||
|
||
return (
|
||
<>
|
||
<style>{css}</style>
|
||
|
||
{/* ── IMZA AN: CURTAIN REVEAL PRELOADER ── */}
|
||
<AnimatePresence>
|
||
{preloader && (
|
||
<motion.div
|
||
className="fixed inset-0 z-50 bg-[#0F172A] 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-[#14B8A6] block"
|
||
initial={{ opacity: 0, y: 10 }}
|
||
animate={{ opacity: 1, y: 0 }}
|
||
transition={{ duration: 0.5 }}
|
||
>
|
||
CAL VESTAM RESORT
|
||
</motion.span>
|
||
<div className="h-[1px] w-48 bg-white/10 mx-auto relative overflow-hidden">
|
||
<motion.div
|
||
className="absolute inset-y-0 left-0 bg-[#14B8A6]"
|
||
initial={{ width: "0%" }}
|
||
animate={{ width: "100%" }}
|
||
transition={{ duration: 1.2, ease: "easeInOut" }}
|
||
/>
|
||
</div>
|
||
<motion.h2
|
||
className="font-serif-editorial text-white text-lg italic font-light tracking-wider"
|
||
initial={{ opacity: 0 }}
|
||
animate={{ opacity: 1 }}
|
||
transition={{ delay: 0.4, duration: 0.5 }}
|
||
>
|
||
interactive prototype
|
||
</motion.h2>
|
||
</div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
|
||
{/* MEDITERRANEAN RESORT LIGHT THEME */}
|
||
<div className="bg-[#FAF8F5] text-[#0F172A] min-h-screen font-sans-resort selection:bg-[#14B8A6] selection:text-white overflow-hidden relative bg-light-mesh pb-20">
|
||
|
||
{/* Floating Ambient Orbs */}
|
||
<div className="absolute top-[10%] left-[-15%] w-[600px] h-[600px] bg-[#14B8A6]/3 blur-[120px] rounded-full pointer-events-none z-0" />
|
||
<div className="absolute bottom-[20%] right-[-15%] w-[600px] h-[600px] bg-[#D4AF37]/3 blur-[140px] rounded-full pointer-events-none z-0" />
|
||
|
||
{/* ── MANDATORY FLOATING DEMO BANNER ── */}
|
||
<div className="fixed bottom-4 left-4 z-40 bg-[#0F172A]/90 backdrop-blur-md border border-white/10 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-[#14B8A6] animate-pulse" />
|
||
<span className="text-[9px] font-black uppercase tracking-[1.5px] text-white/90">
|
||
{lang === "tr" ? "Bu web sitesi Ayris Tech tarafından hazırlanmış bir konsept çalışmasıdır." : "This website is a premium concept prototype designed by Ayris Tech."}
|
||
</span>
|
||
</div>
|
||
|
||
{/* ── PREMIUM FLOATING 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.85, ease: [0.16, 1, 0.3, 1] }}
|
||
>
|
||
<div className="mx-auto max-w-7xl h-20 flex items-center justify-between px-8 bg-white/80 backdrop-blur-xl border border-white/40 rounded-2xl shadow-[0_10px_30px_rgba(15,23,42,0.03)]">
|
||
{/* Logo */}
|
||
<a href="#" className="flex items-center gap-2.5 group">
|
||
<span className="text-xl font-bold tracking-[2px] text-[#0F172A] font-serif-editorial flex items-center gap-2.5 uppercase">
|
||
<svg className="w-5 h-5 text-[#14B8A6]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M12 22V12" />
|
||
<path d="M5 12h14" />
|
||
<path d="M21 3H3l9 9Z" />
|
||
<path d="M12 12H7.5" />
|
||
</svg>
|
||
{firma.adi}
|
||
</span>
|
||
</a>
|
||
|
||
{/* Links */}
|
||
<nav className="hidden lg:flex items-center gap-8">
|
||
{[
|
||
{ label: t.navBook, href: "#booking-widget" },
|
||
{ label: t.navSuites, href: "#suites-showcase" },
|
||
{ label: t.navExp, href: "#experiences" },
|
||
{ label: t.navRev, href: "#testimonials" }
|
||
].map(item => (
|
||
<a
|
||
key={item.label}
|
||
href={item.href}
|
||
className="text-[10px] font-black tracking-[2px] uppercase text-[#0F172A]/70 hover:text-[#14B8A6] transition-colors relative py-1 cursor-pointer group"
|
||
>
|
||
{item.label}
|
||
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-[#14B8A6] transition-all group-hover:w-full" />
|
||
</a>
|
||
))}
|
||
</nav>
|
||
|
||
{/* Language Selector + Booking Button */}
|
||
<div className="flex items-center gap-4">
|
||
{/* Language Switcher */}
|
||
<div className="flex items-center gap-1 bg-[#0F172A]/5 border border-[#0F172A]/10 rounded-xl p-1 shrink-0">
|
||
<button
|
||
onClick={() => setLang("tr")}
|
||
className={`text-[9px] font-black px-2 py-1.5 rounded-lg transition-all cursor-pointer ${
|
||
lang === "tr" ? "bg-white text-slate-900 shadow-sm" : "text-[#0F172A]/60 hover:text-[#0F172A]"
|
||
}`}
|
||
>
|
||
TR
|
||
</button>
|
||
<button
|
||
onClick={() => setLang("en")}
|
||
className={`text-[9px] font-black px-2 py-1.5 rounded-lg transition-all cursor-pointer ${
|
||
lang === "en" ? "bg-white text-slate-900 shadow-sm" : "text-[#0F172A]/60 hover:text-[#0F172A]"
|
||
}`}
|
||
>
|
||
EN
|
||
</button>
|
||
</div>
|
||
|
||
<motion.button
|
||
onClick={() => setShowModal(true)}
|
||
className="text-[10px] font-black tracking-[2.5px] uppercase text-white bg-[#14B8A6] hover:bg-[#0D9488] px-6 py-3.5 rounded-xl transition-all cursor-pointer shadow-[0_4px_12px_rgba(20,184,166,0.15)] hidden sm:block"
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
>
|
||
{t.reserveNow}
|
||
</motion.button>
|
||
</div>
|
||
</div>
|
||
</motion.header>
|
||
|
||
{/* ── HERO & SUITE QUICK LOOK ── */}
|
||
<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-16 items-center">
|
||
|
||
{/* Left Column: Typography Details */}
|
||
<motion.div
|
||
className="lg:col-span-6 z-20"
|
||
variants={stagger}
|
||
initial="hidden"
|
||
animate="show"
|
||
>
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="inline-flex items-center gap-2 text-[10px] font-black uppercase tracking-widest text-[#14B8A6] mb-6 bg-[#14B8A6]/5 border border-[#14B8A6]/15 px-4 py-2 rounded-full"
|
||
>
|
||
<span className="w-1.5 h-1.5 rounded-full bg-[#14B8A6] animate-pulse" />
|
||
{t.badge}
|
||
</motion.div>
|
||
|
||
<motion.h1
|
||
variants={fadeUp}
|
||
className="font-serif-editorial font-bold text-[#0F172A] leading-[1.1] tracking-tight mb-8 hero-title-clamp"
|
||
>
|
||
{firma.slogan}
|
||
<br />
|
||
<span className="italic font-light text-[#14B8A6] lowercase">{t.heroTail}</span>
|
||
</motion.h1>
|
||
|
||
<motion.p
|
||
variants={fadeUp}
|
||
className="text-[#0F172A]/60 text-xs lg:text-sm leading-relaxed max-w-md mb-12 font-medium"
|
||
>
|
||
{t.heroDesc}
|
||
</motion.p>
|
||
|
||
{/* Statistics Grid */}
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="grid grid-cols-2 md:grid-cols-4 gap-6 mb-12"
|
||
>
|
||
{istatistikler.map((stat, idx) => (
|
||
<div key={idx} className="border-l border-[#14B8A6]/30 pl-4 py-1">
|
||
<h4 className="font-serif-editorial font-bold text-[#0F172A] text-base uppercase tracking-wider mb-1">
|
||
{stat.deger}
|
||
</h4>
|
||
<p className="text-[#0F172A]/50 text-[10px] leading-snug font-bold">
|
||
{getLocalizedStat(stat.etiket)}
|
||
</p>
|
||
</div>
|
||
))}
|
||
</motion.div>
|
||
|
||
{/* CTA buttons */}
|
||
<motion.div variants={fadeUp} className="flex gap-4">
|
||
<a
|
||
href="#booking-widget"
|
||
className="inline-flex items-center gap-3 px-8 py-4 rounded-xl bg-[#14B8A6] hover:bg-[#0D9488] text-white font-black text-[10px] tracking-[2px] uppercase transition-all shadow-[0_5px_15px_rgba(20,184,166,0.2)] cursor-pointer"
|
||
>
|
||
{t.planEscape}
|
||
</a>
|
||
<a
|
||
href="#experiences"
|
||
className="inline-flex items-center gap-3 px-8 py-4 rounded-xl border border-[#0F172A]/10 bg-white/40 hover:bg-white/80 text-[#0F172A] font-black text-[10px] tracking-[2px] uppercase transition-all cursor-pointer"
|
||
>
|
||
{t.resortServices}
|
||
</a>
|
||
</motion.div>
|
||
</motion.div>
|
||
|
||
{/* Right Column: Layered Boutique Showcase */}
|
||
<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-[460px] lg:h-[530px] rounded-3xl overflow-hidden shadow-premium border border-white/60 group"
|
||
initial={{ opacity: 0, scale: 0.95 }}
|
||
animate={{ opacity: 1, scale: 1 }}
|
||
transition={{ duration: 0.8, ease: "easeOut" }}
|
||
>
|
||
{/* Outer delicate lines */}
|
||
<div className="absolute inset-4 rounded-[20px] border border-dashed border-[#14B8A6]/10 animate-[spin_100s_linear_infinite] pointer-events-none" />
|
||
|
||
{/* Main Mediterranean Dining / Pool Setup */}
|
||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||
<img
|
||
src="/sicilia_hero_table.png"
|
||
alt="Cal Vestam Panoramic Dining Terrace"
|
||
className="w-full h-full object-cover scale-102 group-hover:scale-105 transition-transform duration-[4000ms]"
|
||
/>
|
||
|
||
{/* Floating Citrus Welcome Badge Overlay */}
|
||
<div className="absolute bottom-6 left-6 right-6 bg-white/90 backdrop-blur-xl border border-white/50 rounded-2xl p-5 shadow-2xl flex items-center gap-4">
|
||
{/* Miniature citrus close-up */}
|
||
<div className="w-12 h-12 rounded-xl overflow-hidden shrink-0 border border-white">
|
||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||
<img src="/sicilia_lemon_heritage.png" alt="Citrus welcome orchard" className="w-full h-full object-cover" />
|
||
</div>
|
||
<div>
|
||
<span className="text-[#14B8A6] text-[8px] font-black tracking-widest uppercase block mb-1">{t.welcomeTitle}</span>
|
||
<h4 className="font-serif-editorial text-xs font-bold text-[#0F172A] uppercase">{t.welcomeDesc}</h4>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── INTERACTIVE BOOKING ENGINE ── */}
|
||
<section id="booking-widget" className="py-24 relative z-10 px-6 bg-white/40 border-t border-white/60">
|
||
<div className="max-w-6xl mx-auto">
|
||
|
||
<div className="bg-white rounded-3xl border border-white p-8 md:p-12 shadow-premium relative">
|
||
{/* Glowing Top Line */}
|
||
<div className="absolute top-0 left-12 right-12 h-0.5 bg-gradient-to-r from-transparent via-[#14B8A6] to-transparent" />
|
||
|
||
<div className="text-center max-w-xl mx-auto mb-12">
|
||
<span className="text-[#14B8A6] font-serif-editorial italic font-bold text-[11px] tracking-[2px] uppercase block mb-2">{t.checkAvailability}</span>
|
||
<h2 className="font-serif-editorial text-3xl font-bold uppercase text-[#0F172A] tracking-wide">
|
||
{t.scheduleEscape}
|
||
</h2>
|
||
<p className="text-[#0F172A]/50 text-xs mt-2 font-medium">
|
||
{t.scheduleDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Booking Fields Grid */}
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||
{[
|
||
{ label: t.checkin, type: "date" },
|
||
{ label: t.checkout, type: "date" },
|
||
].map((field, idx) => (
|
||
<div key={idx} className="flex flex-col">
|
||
<label className="text-[10px] font-black text-[#0F172A]/50 mb-1.5 uppercase tracking-widest">{field.label}</label>
|
||
<input
|
||
type={field.type}
|
||
className="px-4 py-3.5 rounded-xl border border-gray-200 bg-[#FAF8F5] text-xs text-[#0F172A] focus:outline-none focus:border-[#14B8A6] focus:ring-1 focus:ring-[#14B8A6] transition-all font-semibold cursor-pointer"
|
||
/>
|
||
</div>
|
||
))}
|
||
|
||
{/* Adults Count */}
|
||
<div className="flex flex-col">
|
||
<label className="text-[10px] font-black text-[#0F172A]/50 mb-1.5 uppercase tracking-widest">{t.adults}</label>
|
||
<div className="flex items-center justify-between px-4 py-2.5 rounded-xl border border-gray-200 bg-[#FAF8F5]">
|
||
<button
|
||
onClick={() => setAdults(Math.max(1, adults - 1))}
|
||
className="w-8 h-8 rounded-lg bg-white border border-gray-100 flex items-center justify-center font-bold text-xs text-[#0F172A] hover:bg-gray-50 cursor-pointer shadow-sm"
|
||
>
|
||
-
|
||
</button>
|
||
<span className="text-xs font-black text-[#0F172A]">{adults} {t.guests}</span>
|
||
<button
|
||
onClick={() => setAdults(adults + 1)}
|
||
className="w-8 h-8 rounded-lg bg-white border border-gray-100 flex items-center justify-center font-bold text-xs text-[#0F172A] hover:bg-gray-50 cursor-pointer shadow-sm"
|
||
>
|
||
+
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Kids Count */}
|
||
<div className="flex flex-col">
|
||
<label className="text-[10px] font-black text-[#0F172A]/50 mb-1.5 uppercase tracking-widest">{t.kids}</label>
|
||
<div className="flex items-center justify-between px-4 py-2.5 rounded-xl border border-gray-200 bg-[#FAF8F5]">
|
||
<button
|
||
onClick={() => setKids(Math.max(0, kids - 1))}
|
||
className="w-8 h-8 rounded-lg bg-white border border-gray-100 flex items-center justify-center font-bold text-xs text-[#0F172A] hover:bg-gray-50 cursor-pointer shadow-sm"
|
||
>
|
||
-
|
||
</button>
|
||
<span className="text-xs font-black text-[#0F172A]">{kids} {t.kidsLabel}</span>
|
||
<button
|
||
onClick={() => setKids(kids + 1)}
|
||
className="w-8 h-8 rounded-lg bg-white border border-gray-100 flex items-center justify-center font-bold text-xs text-[#0F172A] hover:bg-gray-50 cursor-pointer shadow-sm"
|
||
>
|
||
+
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Action row */}
|
||
<div className="mt-8 pt-4 flex flex-col md:flex-row justify-between items-center gap-4">
|
||
<p className="text-[#0F172A]/40 text-xs font-medium max-w-md text-center md:text-left">
|
||
{t.guarantee}
|
||
</p>
|
||
<motion.button
|
||
onClick={() => setShowModal(true)}
|
||
className="w-full md:w-auto px-10 py-4 rounded-xl bg-[#14B8A6] hover:bg-[#0D9488] text-white font-black text-[10px] tracking-[2px] uppercase transition-all cursor-pointer shadow-[0_5px_15px_rgba(20,184,166,0.15)] shrink-0"
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
>
|
||
{t.confirmDetails}
|
||
</motion.button>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── SUITES GALLERY ── */}
|
||
<section id="suites-showcase" className="py-32 relative z-10 px-6">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="flex flex-col md:flex-row md:items-end justify-between mb-16 gap-6">
|
||
<div>
|
||
<span className="text-[#14B8A6] font-serif-editorial italic font-bold text-sm tracking-[2px] uppercase block mb-3">{t.suitesTitle}</span>
|
||
<h2 className="font-serif-editorial text-4xl lg:text-5xl font-bold tracking-tight text-[#0F172A] uppercase">
|
||
{t.suitesHeader}
|
||
</h2>
|
||
</div>
|
||
<p className="text-[#0F172A]/50 text-xs max-w-sm font-semibold leading-relaxed">
|
||
{t.suitesDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Gallery Columns */}
|
||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||
{[
|
||
{ title: t.suite1Title, img: "/sicilia_hero_table.png", desc: t.suite1Desc },
|
||
{ title: t.suite2Title, img: "/sicilia_lemon_heritage.png", desc: t.suite2Desc },
|
||
{ title: t.suite3Title, img: "/sicilia_hero_table.png", desc: t.suite3Desc },
|
||
].map((suite, idx) => (
|
||
<motion.div
|
||
key={idx}
|
||
className="bg-white rounded-3xl border border-white overflow-hidden transition-all duration-300 hover:border-[#14B8A6]/30 flex flex-col justify-between group shadow-premium"
|
||
initial={{ opacity: 0, y: 30 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.5, delay: idx * 0.1 }}
|
||
whileHover={{ y: -6 }}
|
||
>
|
||
<div className="h-56 overflow-hidden relative border-b border-gray-100">
|
||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||
<img
|
||
src={suite.img}
|
||
alt={suite.title}
|
||
className="w-full h-full object-cover scale-102 group-hover:scale-105 transition-transform duration-1000"
|
||
/>
|
||
<div className="absolute inset-0 bg-black/5" />
|
||
</div>
|
||
|
||
<div className="p-8 space-y-4">
|
||
<h3 className="font-serif-editorial font-bold text-lg text-[#0F172A] tracking-wider uppercase leading-snug">
|
||
{suite.title}
|
||
</h3>
|
||
<p className="text-[#0F172A]/50 text-[11px] leading-relaxed font-semibold">
|
||
{suite.desc}
|
||
</p>
|
||
</div>
|
||
|
||
<div className="px-8 pb-8">
|
||
<button
|
||
onClick={() => setShowModal(true)}
|
||
className="text-[#14B8A6] font-black text-[10px] tracking-[2px] uppercase flex items-center gap-1.5 cursor-pointer hover:text-[#0D9488] transition-colors"
|
||
>
|
||
{t.secureRes}
|
||
</button>
|
||
</div>
|
||
</motion.div>
|
||
))}
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── RESORT EXPERIENCES ── */}
|
||
<section id="experiences" className="py-24 relative z-10 px-6 bg-white/40 border-t border-white/60">
|
||
<div className="max-w-7xl mx-auto">
|
||
<div className="grid lg:grid-cols-3 gap-8">
|
||
{hizmetler.map((hizmet, idx) => {
|
||
const locServ = getLocalizedService(hizmet.baslik, hizmet.aciklama);
|
||
return (
|
||
<div
|
||
key={idx}
|
||
className="bg-white p-8 rounded-3xl border border-white flex flex-col justify-between h-72 transition-all hover:shadow-premium group"
|
||
>
|
||
<div>
|
||
<div className="w-12 h-12 rounded-2xl bg-[#14B8A6]/5 border border-[#14B8A6]/10 flex items-center justify-center mb-6">
|
||
<svg className="w-5 h-5 text-[#14B8A6]" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
|
||
<circle cx="12" cy="12" r="10" />
|
||
<path d="m9 12 2 2 4-4" />
|
||
</svg>
|
||
</div>
|
||
<h3 className="font-serif-editorial font-bold text-lg text-[#0F172A] mb-2 uppercase">
|
||
{locServ.title}
|
||
</h3>
|
||
<p className="text-[#0F172A]/60 text-[11px] leading-relaxed font-semibold">
|
||
{locServ.desc}
|
||
</p>
|
||
</div>
|
||
|
||
<button
|
||
onClick={() => setShowModal(true)}
|
||
className="text-[#14B8A6] font-black text-[9px] tracking-[2.5px] uppercase flex items-center gap-1 cursor-pointer hover:text-[#0D9488] transition-colors"
|
||
>
|
||
{lang === "tr" ? "DAHA FAZLA KEŞFET →" : "DISCOVER MORE →"}
|
||
</button>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── TESTIMONIALS ── */}
|
||
<section id="testimonials" className="py-28 relative z-10 px-6 border-t border-white/60">
|
||
<div className="max-w-7xl mx-auto">
|
||
|
||
<div className="text-center max-w-xl mx-auto mb-20">
|
||
<span className="text-[#14B8A6] font-serif-editorial italic font-bold text-sm tracking-[2px] uppercase block mb-2">{t.diaries}</span>
|
||
<h2 className="font-serif-editorial font-bold text-3xl lg:text-4xl uppercase text-[#0F172A] tracking-wider">
|
||
{t.lovedGuests}
|
||
</h2>
|
||
<p className="text-[#0F172A]/40 text-xs mt-2 font-medium">
|
||
{t.lovedDesc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Testimonials 2-Column Grid */}
|
||
<div className="grid md:grid-cols-2 gap-8">
|
||
{yorumlar.map((y, yIdx) => (
|
||
<div
|
||
key={yIdx}
|
||
className="bg-white border border-white rounded-3xl p-8 flex flex-col justify-between transition-all duration-300 hover:border-[#14B8A6]/30 group shadow-premium"
|
||
>
|
||
{/* Rating Stars SVG */}
|
||
<div className="flex gap-1.5 mb-6">
|
||
{[...Array(5)].map((_, starIdx) => (
|
||
<svg key={starIdx} className="w-4 h-4 fill-[#14B8A6]" 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-[#0F172A]/70 text-xs leading-relaxed italic mb-8 font-medium font-serif-editorial">
|
||
“{y.yorum}”
|
||
</p>
|
||
|
||
<div className="flex items-center gap-3">
|
||
<div className="w-10 h-10 rounded-full border border-gray-100 flex items-center justify-center text-lg bg-[#FAF8F5] select-none font-bold">
|
||
{y.yazar.charAt(0)}
|
||
</div>
|
||
<div>
|
||
<h4 className="font-serif-editorial text-[#0F172A] text-xs font-bold uppercase tracking-wider">
|
||
{y.yazar}
|
||
</h4>
|
||
<span className="text-[9px] text-[#0F172A]/40 uppercase tracking-widest font-black">
|
||
{y.tarih}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── FOOTER ── */}
|
||
<footer className="bg-white border-t border-gray-100 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-gray-100">
|
||
|
||
{/* About Column */}
|
||
<div className="md:col-span-2">
|
||
<span className="font-serif-editorial text-2xl font-bold text-[#0F172A] tracking-wider uppercase mb-4 block">
|
||
Cal<span className="text-[#14B8A6]">Vestam</span>
|
||
</span>
|
||
<p className="text-[#0F172A]/50 text-xs leading-relaxed max-w-sm mb-8 font-medium">
|
||
{firma.slogan} — Exclusive boutique resort nestled inside Ölüdeniz heights. Handcrafted sea suites, infinity pools, and organic salt therapy.
|
||
</p>
|
||
<div className="text-[#0F172A]/60 text-xs font-medium space-y-3">
|
||
<p className="flex items-center gap-2">
|
||
<svg className="w-4 h-4 text-[#14B8A6] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" />
|
||
<circle cx="12" cy="10" r="3" />
|
||
</svg>
|
||
<span className="text-[#0F172A]/80">{firma.adres}</span>
|
||
</p>
|
||
<p className="flex items-center gap-2">
|
||
<svg className="w-4 h-4 text-[#14B8A6] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<rect width="20" height="16" x="2" y="4" rx="2" />
|
||
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
|
||
</svg>
|
||
<span className="text-[#0F172A]/80">{firma.email}</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Coordinates Column */}
|
||
<div>
|
||
<h4 className="font-serif-editorial text-[#14B8A6] text-xs font-bold uppercase tracking-wider mb-6">
|
||
{t.vipCoords}
|
||
</h4>
|
||
<div className="space-y-4 text-xs text-[#0F172A]/50 font-semibold">
|
||
<p>{t.conciergeActive} <br /> <span className="text-[#0F172A]/80">24 Hours Active</span></p>
|
||
<p>Check-In/Out <br /> <span className="text-[#0F172A]/80">{t.checkInOutDetails}</span></p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Leisure Services Column */}
|
||
<div>
|
||
<h4 className="font-serif-editorial text-[#14B8A6] text-xs font-bold uppercase tracking-wider mb-6">
|
||
{t.boutiqueLeisures}
|
||
</h4>
|
||
<div className="space-y-4">
|
||
{hizmetler.map((h, hIdx) => {
|
||
const locS = getLocalizedService(h.baslik, h.aciklama);
|
||
return (
|
||
<a
|
||
key={hIdx}
|
||
href="#suites-showcase"
|
||
className="block text-[#0F172A]/50 hover:text-[#14B8A6] text-xs transition-colors font-semibold"
|
||
>
|
||
{locS.title}
|
||
</a>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div className="flex flex-col md:flex-row justify-between items-center pt-8 gap-4 text-[#0F172A]/30 text-xs font-semibold">
|
||
<p>© 2026 {firma.adi}. All rights reserved.</p>
|
||
<div className="flex gap-4">
|
||
<a href="#" className="hover:text-[#0F172A] transition-colors">{t.privacyRegs}</a>
|
||
<span>·</span>
|
||
<a href="#" className="hover:text-[#0F172A] transition-colors">{t.termsStay}</a>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</footer>
|
||
|
||
{/* ── CONFIRM SUCCESS MODAL ── */}
|
||
<AnimatePresence>
|
||
{showModal && (
|
||
<motion.div
|
||
className="fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30 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-gray-100"
|
||
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-[#FAF8F5] border border-gray-100 flex items-center justify-center text-[#0F172A]/40 hover:text-[#14B8A6] hover:border-[#14B8A6]/20 transition-all cursor-pointer font-bold"
|
||
onClick={() => setShowModal(false)}
|
||
>
|
||
✕
|
||
</button>
|
||
|
||
{/* Success check indicator */}
|
||
<div className="w-16 h-16 rounded-2xl bg-[#14B8A6]/10 border border-[#14B8A6]/20 flex items-center justify-center mb-6">
|
||
<svg className="w-8 h-8 stroke-[#14B8A6] 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-serif-editorial font-bold text-[#0F172A] text-2xl mb-1 uppercase tracking-wider">
|
||
{t.enquiryActive}
|
||
</h3>
|
||
<p className="text-[#14B8A6] font-sans-resort text-[10px] mb-6 uppercase tracking-widest font-black">
|
||
{t.ambassadorActive}
|
||
</p>
|
||
|
||
<p className="text-[#0F172A]/60 text-xs leading-relaxed mb-8 font-semibold">
|
||
{t.enquirySuccess}
|
||
</p>
|
||
|
||
<motion.button
|
||
className="w-full py-4 rounded-xl bg-[#14B8A6] hover:bg-[#0D9488] text-white font-black text-[10px] tracking-[2px] uppercase cursor-pointer shadow-md shadow-[#14B8A6]/15"
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
onClick={() => setShowModal(false)}
|
||
>
|
||
{t.dismiss}
|
||
</motion.button>
|
||
</motion.div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
|
||
</div>
|
||
</>
|
||
);
|
||
}
|