1103 lines
65 KiB
TypeScript
1103 lines
65 KiB
TypeScript
"use client";
|
||
|
||
import { motion, AnimatePresence, useScroll, useTransform } from "framer-motion";
|
||
import { useState, useEffect, useRef } from "react";
|
||
import type { DemoData } from "@/data/demos";
|
||
import AnimatedCounter from "@/components/ui/AnimatedCounter";
|
||
|
||
const E_SMOOTH = [0.25, 0.46, 0.45, 0.94] as [number, number, number, number];
|
||
const E_DRAMATIC = [0.16, 1, 0.3, 1 ] as [number, number, number, number];
|
||
|
||
const fadeUp = {
|
||
hidden: { opacity: 0, y: 48 },
|
||
show: { opacity: 1, y: 0, transition: { duration: 0.8, ease: E_SMOOTH } },
|
||
};
|
||
const fadeIn = {
|
||
hidden: { opacity: 0 },
|
||
show: { opacity: 1, transition: { duration: 0.6, ease: E_SMOOTH } },
|
||
};
|
||
const fadeLeft = {
|
||
hidden: { opacity: 0, x: 40 },
|
||
show: { opacity: 1, x: 0, transition: { duration: 0.8, ease: E_SMOOTH } },
|
||
};
|
||
const stagger = {
|
||
hidden: {},
|
||
show: { transition: { staggerChildren: 0.11 } },
|
||
};
|
||
const staggerFast = {
|
||
hidden: {},
|
||
show: { transition: { staggerChildren: 0.065 } },
|
||
};
|
||
|
||
function ServiceIcon({ ikon, color }: { ikon: string; color: string }) {
|
||
const p = { className: "w-6 h-6 fill-none", viewBox: "0 0 24 24", strokeWidth: "1.7", stroke: color };
|
||
if (ikon === "surgery" || ikon.includes("Cerrahi"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M9.663 17h4.673M12 3v1m6.364 1.636-.707.707M21 12h-1M4 12H3m3.343-5.657-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /></svg>;
|
||
if (ikon === "orthopedics" || ikon.includes("Ortopedi"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" /></svg>;
|
||
if (ikon === "pediatrics" || ikon.includes("Çocuk"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>;
|
||
if (ikon === "gynecology" || ikon.includes("Kadın"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" /></svg>;
|
||
if (ikon === "neurology" || ikon.includes("Nöroloji"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23-.693L5 14.5m14.8.8l1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0112 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5" /></svg>;
|
||
if (ikon === "laboratory" || ikon.includes("Laboratuvar"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" /></svg>;
|
||
if (ikon === "radiology" || ikon.includes("Radyoloji"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" /><path strokeLinecap="round" strokeLinejoin="round" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" /></svg>;
|
||
if (ikon === "gastro" || ikon.includes("Gastro"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" /></svg>;
|
||
if (ikon === "dietitian" || ikon.includes("Beslenme"))
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" /></svg>;
|
||
return <svg {...p}><path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 0 1-1.043 3.296 3.745 3.745 0 0 1-3.296 1.043A3.745 3.745 0 0 1 12 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 0 1-3.296-1.043 3.745 3.745 0 0 1-1.043-3.296A3.745 3.745 0 0 1 3 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 0 1 1.043-3.296 3.746 3.746 0 0 1 3.296-1.043A3.746 3.746 0 0 1 12 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 0 1 3.296 1.043 3.746 3.746 0 0 1 1.043 3.296A3.745 3.745 0 0 1 21 12Z" /></svg>;
|
||
}
|
||
|
||
const MARQUEE_A = ["SGK Anlaşmalı", "7/24 Acil Servis", "Uluslararası Hasta", "Modern Ameliyathane", "MR & Tomografi", "Online Randevu", "Engelli Erişimi"];
|
||
const MARQUEE_B = ["Genel Cerrahi", "Ortopedi", "Nöroloji", "Radyoloji", "Çocuk Sağlığı", "Beslenme & Diyet", "GETAT Birimi"];
|
||
|
||
const POLYCLINICS_TR = [
|
||
{ name: "Ortopedi ve Travmatoloji", desc: "Menüsküs yırtığı, kırık tedavisi, eklem cerrahisi ve sportif yaralanmalar için uzman yaklaşım." },
|
||
{ name: "Çocuk Sağlığı ve Hastalıkları", desc: "Pediatri, büyüme-gelişme takibi, aşı programları ve çocuk enfeksiyon hastalıkları." },
|
||
{ name: "Kadın Hastalıkları ve Doğum", desc: "Jinekoloji, gebelik takibi ve kadın sağlığına özel poliklinik hizmetleri." },
|
||
{ name: "Genel Cerrahi", desc: "Elektif ve acil cerrahi operasyonlar, ameliyathane ve yatan hasta servisi." },
|
||
{ name: "Nöroloji", desc: "Baş ağrısı, migren, epilepsi ve nörolojik hastalıkların tam tanı-tedavi süreci." },
|
||
{ name: "Beslenme ve Diyet", desc: "Uzman diyetisyen eşliğinde kişiye özel beslenme programı ve sağlıklı yaşam takibi." },
|
||
{ name: "Acil Servis", desc: "7/24 kesintisiz acil tıbbi hizmet, tüm yaş gruplarına anında müdahale kapasitesi." },
|
||
{ name: "GETAT Birimi", desc: "Proloterapi, akupunktur, posturoloji ve geleneksel tamamlayıcı tıp uygulamaları." },
|
||
];
|
||
const POLYCLINICS_EN = [
|
||
{ name: "Orthopedics & Traumatology", desc: "Meniscus tears, fractures, joint surgery and sports injuries treated by specialists." },
|
||
{ name: "Pediatrics", desc: "Child health and development monitoring, vaccination programs and pediatric diseases." },
|
||
{ name: "Gynecology & Obstetrics", desc: "Gynecology, pregnancy monitoring and women's health polyclinic services." },
|
||
{ name: "General Surgery", desc: "Elective and emergency surgical operations, operating room and inpatient ward." },
|
||
{ name: "Neurology", desc: "Headache, migraine, epilepsy and neurological disease diagnosis and treatment." },
|
||
{ name: "Nutrition & Dietetics", desc: "Personalized nutrition programs under expert dietitian guidance and lifestyle coaching." },
|
||
{ name: "Emergency Service", desc: "24/7 emergency medical service with immediate response capacity for all age groups." },
|
||
{ name: "CAIM Unit", desc: "Prolotherapy, acupuncture, posturology and traditional complementary medicine applications." },
|
||
];
|
||
|
||
const TRANSLATIONS = {
|
||
tr: {
|
||
badge: "ÖZEL TIP MERKEZİ · BODRUM",
|
||
heroT1: "Bodrum'un", heroT2: "Sağlığa Adanmış", heroT3: "Öncü Merkezi",
|
||
heroDesc: "İleri cerrahi teknolojisi, 12 uzman hekim ve hasta odaklı yaklaşımla; SGK anlaşmalı, 7/24 acil, uluslararası hasta hizmetiyle güvende olun.",
|
||
ctaBook: "Online Randevu Al", ctaServices: "Hizmetlerimiz",
|
||
navServices: "Hizmetler", navDoctors: "Doktorlar", navPoly: "Poliklinikler", navContact: "İletişim", navBook: "Randevu Al",
|
||
floatDoctors: "Uzman Hekim", floatIntl: "Uluslararası Hasta Departmanı",
|
||
workTitle: "Çalışma Saatleri", wkdays: "Hafta İçi: 08:30–17:30", saturday: "Cumartesi: 08:30–13:00", sunday: "Pazar: Acil Servis",
|
||
statsSection: "Sayılarla Bodrum Cerrahi",
|
||
srvTitle: "Tıbbi Birimlerimiz", srvHeader: "UZMANLAŞMIŞ SAĞLIK HİZMETLERİ",
|
||
srvDesc: "Ameliyathane, tıbbi laboratuvar, radyoloji birimi ve branş uzmanlarımızla kapsamlı sağlık çözümleri sunuyoruz.",
|
||
drTitle: "Uzman Kadromuz", drHeader: "ALANINDA UZMAN HEKİMLER",
|
||
drDesc: "Deneyimli cerrahlar, uzman hekimler ve yardımcı sağlık personeliyle profesyonel tedavi.",
|
||
drYil: "Yıl", drHasta: "Hasta",
|
||
polyTitle: "Poliklinikler", polyHeader: "TIP MERKEZİMİZ BRANŞLARI",
|
||
rvwTitle: "Hasta Yorumları", rvwHeader: "HASTALARIMIZ NE DÜŞÜNÜYOR?",
|
||
bookTitle: "Online Randevu", bookHeader: "RANDEVUNUZU PLANLAYALIM",
|
||
bookDesc: "Formu doldurun, randevu koordinatörümüz sizi 15 dakika içinde arasın ve gününüzü kesinleştirsin.",
|
||
fName: "Ad Soyad", fPhone: "Telefon", fEmail: "E-Posta", fDept: "Bölüm", fDate: "Tercih Tarihi", fSubmit: "RANDEVU TALEP ET",
|
||
contactTitle: "İrtibat Bilgileri", callCenter: "Danışma Hattı", adresLabel: "Adres", mailLabel: "E-Posta",
|
||
emergency: "Acil: 112 · 7/24 Hizmet",
|
||
footerDesc: "SGK anlaşmalı, uluslararası hasta hizmetleri sunan Bodrum'un öncü özel tıp merkezi.",
|
||
privacy: "Gizlilik Sözleşmesi", terms: "Kullanım Şartları",
|
||
deptOptions: ["Genel Cerrahi", "Ortopedi ve Travmatoloji", "Çocuk Sağlığı", "Kadın Hastalıkları", "Nöroloji", "Radyoloji", "Laboratuvar", "Gastroenteroloji", "Beslenme ve Diyet"],
|
||
demoBanner: "Bu site demo amaçlıdır — demo.ayristech.com",
|
||
},
|
||
en: {
|
||
badge: "PRIVATE MEDICAL CENTER · BODRUM",
|
||
heroT1: "Bodrum's", heroT2: "Dedicated", heroT3: "Healthcare Leader",
|
||
heroDesc: "Advanced surgical technology, 12 specialist physicians, patient-first care — SGK approved, 24/7 emergency and international patient services.",
|
||
ctaBook: "Book Appointment", ctaServices: "Our Services",
|
||
navServices: "Services", navDoctors: "Doctors", navPoly: "Polyclinics", navContact: "Contact", navBook: "Book Now",
|
||
floatDoctors: "Expert Physicians", floatIntl: "International Patient Dept.",
|
||
workTitle: "Working Hours", wkdays: "Weekdays: 08:30 – 17:30", saturday: "Saturday: 08:30 – 13:00", sunday: "Sunday: Emergency Only",
|
||
statsSection: "Bodrum Cerrahi in Numbers",
|
||
srvTitle: "Our Departments", srvHeader: "SPECIALIZED HEALTHCARE SERVICES",
|
||
srvDesc: "Surgery, medical laboratory, radiology and specialist physicians offering comprehensive healthcare solutions.",
|
||
drTitle: "Our Specialists", drHeader: "EXPERT PHYSICIANS",
|
||
drDesc: "Experienced surgeons, specialist physicians and support staff delivering professional treatment.",
|
||
drYil: "Yrs", drHasta: "Patients",
|
||
polyTitle: "Polyclinics", polyHeader: "MEDICAL CENTER SPECIALTIES",
|
||
rvwTitle: "Patient Reviews", rvwHeader: "WHAT OUR PATIENTS SAY",
|
||
bookTitle: "Appointment", bookHeader: "SCHEDULE YOUR VISIT",
|
||
bookDesc: "Fill in the form and our appointment coordinator will call you within 15 minutes to confirm your slot.",
|
||
fName: "Full Name", fPhone: "Phone", fEmail: "Email", fDept: "Department", fDate: "Preferred Date", fSubmit: "REQUEST APPOINTMENT",
|
||
contactTitle: "Contact Details", callCenter: "Consultation Line", adresLabel: "Address", mailLabel: "Email",
|
||
emergency: "Emergency: 112 · 24/7 Service",
|
||
footerDesc: "Bodrum's leading private medical center with SGK approval, 24/7 emergency and international patient services.",
|
||
privacy: "Privacy Policy", terms: "Terms of Service",
|
||
deptOptions: ["General Surgery", "Orthopedics", "Pediatrics", "Gynecology", "Neurology", "Radiology", "Laboratory", "Gastroenterology", "Nutrition & Dietetics"],
|
||
demoBanner: "This website is a demo — demo.ayristech.com",
|
||
},
|
||
};
|
||
|
||
export default function BodrumCerrahiTemplate({ data }: { data: DemoData }) {
|
||
const { firma, istatistikler = [], hizmetler = [], doktorlar = [], yorumlar = [] } = data;
|
||
|
||
const [preloader, setPreloader] = useState(true);
|
||
const [lang, setLang] = useState<"tr" | "en">("tr");
|
||
const [showBooking, setShowBooking] = useState(false);
|
||
const [activeReview, setActiveReview] = useState(0);
|
||
const [openPoly, setOpenPoly] = useState<number | null>(0);
|
||
|
||
const t = TRANSLATIONS[lang];
|
||
const polyclinics = lang === "tr" ? POLYCLINICS_TR : POLYCLINICS_EN;
|
||
|
||
const heroRef = useRef<HTMLDivElement>(null);
|
||
const { scrollYProgress } = useScroll({ target: heroRef, offset: ["start start", "end start"] });
|
||
const heroImgY = useTransform(scrollYProgress, [0, 1], ["0%", "28%"]);
|
||
const heroTextY = useTransform(scrollYProgress, [0, 1], ["0%", "-18%"]);
|
||
|
||
useEffect(() => {
|
||
let lenis: any;
|
||
import("@studio-freight/lenis").then(({ default: Lenis }) => {
|
||
lenis = new Lenis({ duration: 1.2, easing: (x: number) => Math.min(1, 1.001 - Math.pow(2, -10 * x)) });
|
||
function raf(time: number) { lenis.raf(time); requestAnimationFrame(raf); }
|
||
requestAnimationFrame(raf);
|
||
});
|
||
return () => lenis?.destroy();
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
const t = setTimeout(() => setPreloader(false), 2400);
|
||
return () => clearTimeout(t);
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
if (yorumlar.length === 0) return;
|
||
const iv = setInterval(() => setActiveReview(p => (p + 1) % yorumlar.length), 4800);
|
||
return () => clearInterval(iv);
|
||
}, [yorumlar.length]);
|
||
|
||
const css = `
|
||
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,600;1,700&family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600;9..40,700&display=swap');
|
||
|
||
:root {
|
||
--deep: #071629;
|
||
--mid: #0F2240;
|
||
--accent: #1B6FA8;
|
||
--bright: #00B4D8;
|
||
--sand: #F4F8FC;
|
||
--white: #FFFFFF;
|
||
}
|
||
|
||
.font-cormorant { font-family: 'Cormorant Garamond', serif; }
|
||
.font-dm { font-family: 'DM Sans', sans-serif; }
|
||
|
||
.hero-title {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: clamp(52px, 7.5vw, 108px);
|
||
line-height: 0.92;
|
||
letter-spacing: -0.02em;
|
||
}
|
||
.section-title {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: clamp(38px, 5vw, 72px);
|
||
line-height: 0.95;
|
||
letter-spacing: -0.015em;
|
||
}
|
||
|
||
.card-glow:hover {
|
||
box-shadow: 0 0 0 1px rgba(27,111,168,0.25), 0 24px 48px rgba(27,111,168,0.12);
|
||
}
|
||
.dr-scroll::-webkit-scrollbar { display: none; }
|
||
.dr-scroll { -ms-overflow-style: none; scrollbar-width: none; }
|
||
`;
|
||
|
||
return (
|
||
<>
|
||
<style>{css}</style>
|
||
|
||
{/* ── GRAIN OVERLAY ── */}
|
||
<div
|
||
className="fixed inset-0 pointer-events-none select-none z-[90]"
|
||
style={{
|
||
opacity: 0.035,
|
||
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
|
||
}}
|
||
/>
|
||
|
||
{/* ── DEMO BANNER ── */}
|
||
<div className="fixed bottom-4 left-4 z-[80] flex items-center gap-2 bg-[#071629]/90 backdrop-blur-sm border border-white/10 px-4 py-2.5 rounded-xl pointer-events-none select-none shadow-xl">
|
||
<span className="w-1.5 h-1.5 rounded-full bg-[#00B4D8] animate-pulse shrink-0" />
|
||
<span className="font-dm text-[9px] text-white/80 tracking-[1.5px] uppercase">{t.demoBanner}</span>
|
||
</div>
|
||
|
||
{/* ── PRELOADER — Medical cross SVG draw + curtain lift ── */}
|
||
<AnimatePresence>
|
||
{preloader && (
|
||
<motion.div
|
||
className="fixed inset-0 z-[200] flex flex-col items-center justify-center gap-8"
|
||
style={{ background: "var(--deep)" }}
|
||
exit={{ y: "-100%", transition: { duration: 0.9, ease: E_DRAMATIC } }}
|
||
>
|
||
{/* SVG medical cross drawing */}
|
||
<div className="relative">
|
||
<svg width="80" height="80" viewBox="0 0 80 80">
|
||
<motion.line
|
||
x1="40" y1="8" x2="40" y2="72"
|
||
stroke="#00B4D8" strokeWidth="7" strokeLinecap="round"
|
||
initial={{ pathLength: 0 }} animate={{ pathLength: 1 }}
|
||
transition={{ duration: 0.55, ease: E_SMOOTH }}
|
||
/>
|
||
<motion.line
|
||
x1="8" y1="40" x2="72" y2="40"
|
||
stroke="#00B4D8" strokeWidth="7" strokeLinecap="round"
|
||
initial={{ pathLength: 0 }} animate={{ pathLength: 1 }}
|
||
transition={{ duration: 0.55, delay: 0.55, ease: E_SMOOTH }}
|
||
/>
|
||
</svg>
|
||
<motion.div
|
||
className="absolute inset-0 rounded-full"
|
||
style={{ background: "radial-gradient(circle, rgba(0,180,216,0.15), transparent 70%)" }}
|
||
initial={{ scale: 0.5, opacity: 0 }}
|
||
animate={{ scale: 2, opacity: 1 }}
|
||
transition={{ duration: 1.2, delay: 1.1, ease: E_SMOOTH }}
|
||
/>
|
||
</div>
|
||
|
||
{/* Loading bar */}
|
||
<div className="w-48 h-px bg-white/8 relative overflow-hidden">
|
||
<motion.div
|
||
className="absolute inset-y-0 left-0"
|
||
style={{ background: "linear-gradient(90deg, #1B6FA8, #00B4D8)" }}
|
||
initial={{ width: "0%" }}
|
||
animate={{ width: "100%" }}
|
||
transition={{ duration: 1.8, ease: E_SMOOTH }}
|
||
/>
|
||
</div>
|
||
|
||
<motion.p
|
||
className="font-cormorant text-white/40 text-sm tracking-[4px] uppercase"
|
||
initial={{ opacity: 0 }} animate={{ opacity: 1 }}
|
||
transition={{ delay: 0.4, duration: 0.5 }}
|
||
>
|
||
{firma.adi}
|
||
</motion.p>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
|
||
<div className="font-dm bg-white text-[#071629] selection:bg-[#00B4D8] selection:text-white overflow-x-hidden">
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
NAVBAR
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<motion.header
|
||
className="fixed top-0 left-0 right-0 z-[60]"
|
||
initial={{ y: -90, opacity: 0 }}
|
||
animate={{ y: 0, opacity: 1 }}
|
||
transition={{ duration: 0.9, delay: 0.2, ease: E_DRAMATIC }}
|
||
>
|
||
<div className="mx-4 mt-4">
|
||
<div className="max-w-7xl mx-auto h-18 flex items-center justify-between px-6 bg-[#071629]/95 backdrop-blur-xl border border-white/[0.06] rounded-2xl shadow-[0_12px_40px_rgba(0,0,0,0.3)]">
|
||
|
||
{/* Logo */}
|
||
<a href="#" className="flex items-center gap-3 group shrink-0">
|
||
<div className="w-8 h-8 rounded-lg flex items-center justify-center" style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}>
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||
<line x1="8" y1="2" x2="8" y2="14" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
|
||
<line x1="2" y1="8" x2="14" y2="8" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
|
||
</svg>
|
||
</div>
|
||
<span className="font-cormorant font-semibold text-white text-lg tracking-wide">{firma.adi}</span>
|
||
</a>
|
||
|
||
{/* Nav links */}
|
||
<nav className="hidden lg:flex items-center gap-7">
|
||
{[
|
||
{ label: t.navServices, href: "#hizmetler" },
|
||
{ label: t.navDoctors, href: "#doktorlar" },
|
||
{ label: t.navPoly, href: "#poliklinikler" },
|
||
{ label: t.navContact, href: "#randevu" },
|
||
].map(item => (
|
||
<a
|
||
key={item.label}
|
||
href={item.href}
|
||
className="text-[10px] font-dm font-semibold tracking-[2px] uppercase text-white/50 hover:text-white transition-colors duration-200 relative group py-1"
|
||
>
|
||
{item.label}
|
||
<span className="absolute bottom-0 left-0 w-0 h-px bg-[#00B4D8] group-hover:w-full transition-all duration-300" />
|
||
</a>
|
||
))}
|
||
</nav>
|
||
|
||
{/* Right actions */}
|
||
<div className="flex items-center gap-3 shrink-0">
|
||
<div className="hidden sm:flex items-center gap-0.5 bg-white/5 border border-white/8 rounded-xl p-1">
|
||
{(["tr", "en"] as const).map(l => (
|
||
<button
|
||
key={l}
|
||
onClick={() => setLang(l)}
|
||
className={`text-[9px] font-semibold px-2.5 py-1.5 rounded-lg transition-all cursor-pointer ${lang === l ? "bg-white/15 text-white" : "text-white/40 hover:text-white/70"}`}
|
||
>
|
||
{l.toUpperCase()}
|
||
</button>
|
||
))}
|
||
</div>
|
||
<motion.button
|
||
onClick={() => setShowBooking(true)}
|
||
className="text-[10px] font-bold tracking-[2px] uppercase text-white px-5 py-3 rounded-xl cursor-pointer hidden sm:block"
|
||
style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}
|
||
whileHover={{ scale: 1.03 }}
|
||
whileTap={{ scale: 0.97 }}
|
||
>
|
||
{t.navBook}
|
||
</motion.button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</motion.header>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
HERO
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section
|
||
ref={heroRef}
|
||
className="relative min-h-screen flex items-center overflow-hidden"
|
||
style={{ background: "linear-gradient(145deg, #071629 0%, #0F2240 60%, #0B1A30 100%)" }}
|
||
>
|
||
{/* Ambient orbs */}
|
||
<div className="absolute top-[10%] left-[5%] w-[500px] h-[500px] rounded-full pointer-events-none" style={{ background: "radial-gradient(circle, rgba(27,111,168,0.15), transparent 70%)" }} />
|
||
<div className="absolute bottom-[5%] right-[10%] w-[400px] h-[400px] rounded-full pointer-events-none" style={{ background: "radial-gradient(circle, rgba(0,180,216,0.1), transparent 70%)" }} />
|
||
|
||
<div className="relative z-10 max-w-7xl mx-auto w-full px-6 pt-32 pb-16">
|
||
<div className="grid lg:grid-cols-12 gap-12 items-center">
|
||
|
||
{/* Left: Headline */}
|
||
<motion.div
|
||
className="lg:col-span-7"
|
||
style={{ y: heroTextY }}
|
||
variants={stagger}
|
||
initial="hidden"
|
||
animate="show"
|
||
>
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="inline-flex items-center gap-2 mb-8 px-4 py-2 rounded-full border text-[9px] font-semibold tracking-[2.5px] uppercase"
|
||
style={{ borderColor: "rgba(0,180,216,0.3)", color: "#00B4D8", background: "rgba(0,180,216,0.08)" }}
|
||
>
|
||
<span className="w-1.5 h-1.5 rounded-full bg-[#00B4D8] animate-pulse" />
|
||
{t.badge}
|
||
</motion.div>
|
||
|
||
<motion.h1 variants={fadeUp} className="hero-title font-cormorant text-white mb-6">
|
||
{t.heroT1}
|
||
<br />
|
||
<em className="not-italic" style={{ color: "#00B4D8" }}>{t.heroT2}</em>
|
||
<br />
|
||
{t.heroT3}
|
||
</motion.h1>
|
||
|
||
<motion.p variants={fadeUp} className="text-white/50 text-sm leading-relaxed max-w-xl mb-10 font-dm">
|
||
{t.heroDesc}
|
||
</motion.p>
|
||
|
||
{/* Stats row */}
|
||
<motion.div variants={fadeUp} className="grid grid-cols-2 sm:grid-cols-4 gap-5 mb-10">
|
||
{istatistikler.map((s, i) => (
|
||
<div key={i} className="border-l-2 pl-4 py-1" style={{ borderColor: "#1B6FA8" }}>
|
||
<p className="font-cormorant font-bold text-white text-2xl leading-none mb-1">{s.deger}</p>
|
||
<p className="text-white/40 text-[10px] font-dm leading-snug">{s.etiket}</p>
|
||
</div>
|
||
))}
|
||
</motion.div>
|
||
|
||
{/* CTAs */}
|
||
<motion.div variants={fadeUp} className="flex flex-wrap gap-4 mb-10">
|
||
<motion.button
|
||
onClick={() => setShowBooking(true)}
|
||
className="flex items-center gap-2.5 px-8 py-4 rounded-xl text-white text-[10px] font-bold tracking-[2px] uppercase cursor-pointer shadow-lg"
|
||
style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)", boxShadow: "0 8px 24px rgba(27,111,168,0.35)" }}
|
||
whileHover={{ scale: 1.03, boxShadow: "0 12px 32px rgba(27,111,168,0.5)" }}
|
||
whileTap={{ scale: 0.97 }}
|
||
>
|
||
<svg className="w-4 h-4 fill-none stroke-white" viewBox="0 0 24 24" strokeWidth="2"><path strokeLinecap="round" strokeLinejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" /></svg>
|
||
{t.ctaBook}
|
||
</motion.button>
|
||
<a
|
||
href="#hizmetler"
|
||
className="flex items-center gap-2 px-8 py-4 rounded-xl text-white/70 hover:text-white text-[10px] font-bold tracking-[2px] uppercase border border-white/15 hover:border-white/30 transition-all"
|
||
>
|
||
{t.ctaServices}
|
||
</a>
|
||
</motion.div>
|
||
|
||
{/* Working hours pill */}
|
||
<motion.div
|
||
variants={fadeUp}
|
||
className="inline-flex items-start gap-4 px-5 py-4 rounded-2xl border border-white/8 bg-white/4 backdrop-blur-sm"
|
||
>
|
||
<svg className="w-4 h-4 mt-0.5 fill-none stroke-[#00B4D8] shrink-0" viewBox="0 0 24 24" strokeWidth="2"><path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||
<div>
|
||
<p className="text-[9px] font-semibold text-white/30 tracking-[2px] uppercase mb-2">{t.workTitle}</p>
|
||
<div className="space-y-1">
|
||
{[t.wkdays, t.saturday, t.sunday].map((line, i) => (
|
||
<p key={i} className="text-[11px] font-dm text-white/60">{line}</p>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</motion.div>
|
||
|
||
{/* Right: Photography + floating cards */}
|
||
<div className="lg:col-span-5 relative hidden lg:flex justify-center">
|
||
<motion.div
|
||
className="relative w-[380px]"
|
||
style={{ y: heroImgY }}
|
||
initial={{ opacity: 0, scale: 0.96 }}
|
||
animate={{ opacity: 1, scale: 1 }}
|
||
transition={{ duration: 1.0, delay: 0.3, ease: E_DRAMATIC }}
|
||
>
|
||
{/* Main image */}
|
||
<div className="relative rounded-3xl overflow-hidden" style={{ aspectRatio: "3/4" }}>
|
||
<img
|
||
src="https://images.unsplash.com/photo-1579684385127-1ef15d508118?w=800&q=85&fit=crop"
|
||
alt="Bodrum Cerrahi Tıp Merkezi"
|
||
className="w-full h-full object-cover"
|
||
/>
|
||
<div className="absolute inset-0" style={{ background: "linear-gradient(to top, rgba(7,22,41,0.7) 0%, transparent 50%)" }} />
|
||
</div>
|
||
|
||
{/* Floating card — doctors */}
|
||
<motion.div
|
||
className="absolute -left-12 top-[12%] bg-white rounded-2xl px-5 py-4 shadow-2xl flex items-center gap-3.5 select-none"
|
||
animate={{ y: [0, -8, 0] }}
|
||
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
|
||
>
|
||
<div className="w-10 h-10 rounded-xl flex items-center justify-center shrink-0" style={{ background: "rgba(27,111,168,0.1)" }}>
|
||
<svg className="w-5 h-5 fill-none stroke-[#1B6FA8]" viewBox="0 0 24 24" strokeWidth="2"><path strokeLinecap="round" strokeLinejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
|
||
</div>
|
||
<div>
|
||
<p className="text-[#071629] font-bold text-lg leading-none font-cormorant">{doktorlar.length}+</p>
|
||
<p className="text-[#071629]/50 text-[9px] font-dm mt-0.5 tracking-wider uppercase">{t.floatDoctors}</p>
|
||
</div>
|
||
</motion.div>
|
||
|
||
{/* Floating card — international */}
|
||
<motion.div
|
||
className="absolute -right-8 bottom-[18%] bg-[#071629] rounded-2xl px-5 py-4 shadow-2xl flex items-center gap-3.5 select-none border border-white/8"
|
||
animate={{ y: [0, 8, 0] }}
|
||
transition={{ duration: 4.5, repeat: Infinity, ease: "easeInOut", delay: 1 }}
|
||
>
|
||
<div className="w-10 h-10 rounded-xl flex items-center justify-center shrink-0" style={{ background: "rgba(0,180,216,0.15)" }}>
|
||
<svg className="w-5 h-5 fill-none stroke-[#00B4D8]" viewBox="0 0 24 24" strokeWidth="2"><path strokeLinecap="round" strokeLinejoin="round" d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253" /></svg>
|
||
</div>
|
||
<div>
|
||
<p className="text-white font-semibold text-[11px] leading-snug max-w-[110px]">{t.floatIntl}</p>
|
||
</div>
|
||
</motion.div>
|
||
|
||
{/* Emergency badge */}
|
||
<motion.div
|
||
className="absolute left-0 right-0 bottom-0 mx-4 mb-4 flex items-center gap-3 rounded-xl px-4 py-3 backdrop-blur-sm border border-white/10"
|
||
style={{ background: "rgba(7,22,41,0.8)" }}
|
||
initial={{ opacity: 0, y: 16 }}
|
||
animate={{ opacity: 1, y: 0 }}
|
||
transition={{ delay: 1.2, duration: 0.6 }}
|
||
>
|
||
<span className="w-2 h-2 rounded-full bg-red-400 animate-pulse shrink-0" />
|
||
<p className="text-white/70 text-[10px] font-dm tracking-wide">{t.emergency}</p>
|
||
</motion.div>
|
||
</motion.div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bottom fade */}
|
||
<div className="absolute bottom-0 left-0 right-0 h-24 pointer-events-none" style={{ background: "linear-gradient(to bottom, transparent, #F4F8FC)" }} />
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
MARQUEE BAND
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<div className="relative overflow-hidden py-5 border-y" style={{ background: "#0F2240", borderColor: "rgba(27,111,168,0.3)" }}>
|
||
{/* Row A — left */}
|
||
<div className="overflow-hidden mb-3">
|
||
<motion.div
|
||
className="flex gap-10 items-center whitespace-nowrap"
|
||
animate={{ x: ["0%", "-50%"] }}
|
||
transition={{ duration: 32, ease: "linear", repeat: Infinity }}
|
||
>
|
||
{[...MARQUEE_A, ...MARQUEE_A].map((item, i) => (
|
||
<span key={i} className="flex items-center gap-3 shrink-0">
|
||
<span className="text-[#00B4D8] font-cormorant italic text-lg font-light">{item}</span>
|
||
<span className="w-1 h-1 rounded-full bg-[#1B6FA8] shrink-0" />
|
||
</span>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
{/* Row B — right */}
|
||
<div className="overflow-hidden">
|
||
<motion.div
|
||
className="flex gap-10 items-center whitespace-nowrap"
|
||
animate={{ x: ["-50%", "0%"] }}
|
||
transition={{ duration: 26, ease: "linear", repeat: Infinity }}
|
||
>
|
||
{[...MARQUEE_B, ...MARQUEE_B].map((item, i) => (
|
||
<span key={i} className="flex items-center gap-3 shrink-0">
|
||
<span className="text-white/30 font-dm text-[11px] font-medium tracking-widest uppercase">{item}</span>
|
||
<span className="w-1 h-1 rounded-full bg-white/10 shrink-0" />
|
||
</span>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
STATS
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section className="py-20 px-6" style={{ background: "var(--sand)" }}>
|
||
<div className="max-w-7xl mx-auto">
|
||
<motion.div
|
||
className="text-center mb-14"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={stagger}
|
||
>
|
||
<motion.p variants={fadeUp} className="text-[10px] font-semibold tracking-[3px] uppercase mb-3" style={{ color: "#1B6FA8" }}>
|
||
{t.statsSection}
|
||
</motion.p>
|
||
</motion.div>
|
||
<motion.div
|
||
className="grid grid-cols-2 lg:grid-cols-4 gap-6"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={staggerFast}
|
||
>
|
||
{istatistikler.map((s, i) => {
|
||
const numericValue = parseInt(s.deger.replace(/\D/g, ""), 10);
|
||
const suffix = s.deger.replace(/[\d]/g, "").trim();
|
||
return (
|
||
<motion.div
|
||
key={i}
|
||
variants={fadeUp}
|
||
className="bg-white rounded-3xl p-8 text-center border border-[#1B6FA8]/8 shadow-sm hover:shadow-md transition-shadow"
|
||
>
|
||
<p className="font-cormorant font-bold text-[#071629] mb-2" style={{ fontSize: "clamp(36px, 5vw, 60px)", lineHeight: 1 }}>
|
||
{!isNaN(numericValue) ? (
|
||
<><AnimatedCounter target={numericValue} suffix={suffix} /></>
|
||
) : (
|
||
s.deger
|
||
)}
|
||
</p>
|
||
<p className="text-[#071629]/50 text-xs font-dm">{s.etiket}</p>
|
||
</motion.div>
|
||
);
|
||
})}
|
||
</motion.div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
HİZMETLER
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section id="hizmetler" className="py-28 px-6 bg-white">
|
||
<div className="max-w-7xl mx-auto">
|
||
<motion.div
|
||
className="flex flex-col lg:flex-row lg:items-end justify-between gap-8 mb-20"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={stagger}
|
||
>
|
||
<div>
|
||
<motion.p variants={fadeUp} className="text-[10px] font-semibold tracking-[3px] uppercase mb-4" style={{ color: "#1B6FA8" }}>
|
||
{t.srvTitle}
|
||
</motion.p>
|
||
<motion.h2 variants={fadeUp} className="section-title font-cormorant text-[#071629]">
|
||
{t.srvHeader.split(" ").slice(0, 2).join(" ")}
|
||
<br />
|
||
<em className="not-italic" style={{ color: "#1B6FA8" }}>{t.srvHeader.split(" ").slice(2).join(" ")}</em>
|
||
</motion.h2>
|
||
</div>
|
||
<motion.p variants={fadeUp} className="text-[#071629]/50 text-sm leading-relaxed max-w-md font-dm lg:text-right">
|
||
{t.srvDesc}
|
||
</motion.p>
|
||
</motion.div>
|
||
|
||
<motion.div
|
||
className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={staggerFast}
|
||
>
|
||
{hizmetler.map((h, i) => (
|
||
<motion.div
|
||
key={i}
|
||
variants={fadeUp}
|
||
className="group p-8 rounded-3xl border border-[#071629]/8 hover:border-transparent transition-all duration-300 cursor-default card-glow flex flex-col justify-between h-64"
|
||
whileHover={{ y: -6 }}
|
||
>
|
||
<div>
|
||
<div className="w-12 h-12 rounded-2xl flex items-center justify-center mb-6 border border-[#1B6FA8]/15 group-hover:border-[#1B6FA8]/40 transition-colors" style={{ background: "rgba(27,111,168,0.06)" }}>
|
||
<ServiceIcon ikon={h.ikon} color="#1B6FA8" />
|
||
</div>
|
||
<h3 className="font-cormorant font-semibold text-[#071629] text-xl mb-2 leading-snug">{h.baslik}</h3>
|
||
<p className="text-[#071629]/50 text-xs leading-relaxed font-dm">{h.aciklama}</p>
|
||
</div>
|
||
<button
|
||
onClick={() => setShowBooking(true)}
|
||
className="text-[#1B6FA8] font-semibold text-[9px] tracking-[2px] uppercase flex items-center gap-1.5 pt-4 border-t border-[#071629]/6 mt-4 cursor-pointer hover:text-[#00B4D8] transition-colors group/btn"
|
||
>
|
||
{lang === "tr" ? "Randevu Al" : "Book Now"}
|
||
<svg className="w-3 h-3 group-hover/btn:translate-x-0.5 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2.5"><path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" /></svg>
|
||
</button>
|
||
</motion.div>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
DOKTORLAR (dark section, horizontal scroll)
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section id="doktorlar" className="py-28 px-6 relative overflow-hidden" style={{ background: "var(--deep)" }}>
|
||
<div className="absolute top-0 left-[-10%] w-[600px] h-[600px] rounded-full pointer-events-none" style={{ background: "radial-gradient(circle, rgba(27,111,168,0.12), transparent 70%)" }} />
|
||
|
||
<div className="max-w-7xl mx-auto">
|
||
<div className="flex flex-col lg:flex-row lg:items-end justify-between gap-8 mb-16">
|
||
<motion.div
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={stagger}
|
||
>
|
||
<motion.p variants={fadeUp} className="text-[10px] font-semibold tracking-[3px] uppercase mb-4" style={{ color: "#00B4D8" }}>
|
||
{t.drTitle}
|
||
</motion.p>
|
||
<motion.h2 variants={fadeUp} className="section-title font-cormorant text-white">
|
||
{t.drHeader}
|
||
</motion.h2>
|
||
</motion.div>
|
||
<motion.p
|
||
className="text-white/40 text-sm font-dm leading-relaxed max-w-sm lg:text-right"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={fadeIn}
|
||
>
|
||
{t.drDesc}
|
||
</motion.p>
|
||
</div>
|
||
|
||
{/* Horizontal scroll cards */}
|
||
<div className="overflow-x-auto dr-scroll -mx-6 px-6">
|
||
<motion.div
|
||
className="flex gap-5 pb-4"
|
||
style={{ width: "max-content" }}
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={staggerFast}
|
||
>
|
||
{doktorlar.map((doc, i) => (
|
||
<motion.div
|
||
key={i}
|
||
variants={fadeLeft}
|
||
className="w-60 shrink-0 rounded-3xl overflow-hidden border border-white/6 flex flex-col"
|
||
style={{ background: "rgba(255,255,255,0.04)" }}
|
||
whileHover={{ y: -6, borderColor: "rgba(27,111,168,0.4)" }}
|
||
>
|
||
{/* Avatar area */}
|
||
<div className="h-52 flex items-center justify-center relative overflow-hidden" style={{ background: "linear-gradient(135deg, rgba(27,111,168,0.2), rgba(0,180,216,0.1))" }}>
|
||
<motion.span
|
||
className="text-6xl select-none"
|
||
whileHover={{ scale: 1.15 }}
|
||
transition={{ type: "spring", stiffness: 260 }}
|
||
>
|
||
{doc.emoji}
|
||
</motion.span>
|
||
{/* Rating badge */}
|
||
<div className="absolute top-3 right-3 flex items-center gap-1 bg-[#071629]/80 px-2.5 py-1.5 rounded-xl border border-[#00B4D8]/20">
|
||
<svg className="w-3 h-3 fill-[#00B4D8]" 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>
|
||
<span className="text-[#00B4D8] text-[9px] font-bold">{doc.puan}</span>
|
||
</div>
|
||
</div>
|
||
<div className="p-5 flex flex-col flex-1 justify-between">
|
||
<div>
|
||
<h3 className="font-cormorant font-semibold text-white text-base leading-snug mb-1">{doc.ad}</h3>
|
||
<p className="text-[#00B4D8] text-[10px] font-dm font-medium uppercase tracking-wide mb-4">{doc.uzmanlik}</p>
|
||
</div>
|
||
<div className="flex justify-between items-center text-[9px] text-white/30 font-semibold uppercase tracking-wider pt-3 border-t border-white/6">
|
||
<span>{doc.yil} {t.drYil}</span>
|
||
<span>{doc.hasta}+ {t.drHasta}</span>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
POLİKLİNİKLER (accordion)
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section id="poliklinikler" className="py-28 px-6" style={{ background: "var(--sand)" }}>
|
||
<div className="max-w-4xl mx-auto">
|
||
<motion.div
|
||
className="mb-16"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={stagger}
|
||
>
|
||
<motion.p variants={fadeUp} className="text-[10px] font-semibold tracking-[3px] uppercase mb-4" style={{ color: "#1B6FA8" }}>
|
||
{t.polyTitle}
|
||
</motion.p>
|
||
<motion.h2 variants={fadeUp} className="section-title font-cormorant text-[#071629]">
|
||
{t.polyHeader}
|
||
</motion.h2>
|
||
</motion.div>
|
||
|
||
<motion.div
|
||
className="space-y-2"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={staggerFast}
|
||
>
|
||
{polyclinics.map((poly, i) => (
|
||
<motion.div
|
||
key={i}
|
||
variants={fadeUp}
|
||
className="rounded-2xl border overflow-hidden transition-colors"
|
||
style={{ borderColor: openPoly === i ? "rgba(27,111,168,0.25)" : "rgba(7,22,41,0.08)" }}
|
||
>
|
||
<button
|
||
className="w-full flex items-center justify-between px-7 py-5 text-left cursor-pointer group"
|
||
style={{ background: openPoly === i ? "rgba(27,111,168,0.05)" : "white" }}
|
||
onClick={() => setOpenPoly(openPoly === i ? null : i)}
|
||
>
|
||
<div className="flex items-center gap-4">
|
||
<div
|
||
className="w-2 h-2 rounded-full shrink-0 transition-colors"
|
||
style={{ background: openPoly === i ? "#1B6FA8" : "rgba(7,22,41,0.2)" }}
|
||
/>
|
||
<span
|
||
className="font-cormorant font-semibold text-lg transition-colors"
|
||
style={{ color: openPoly === i ? "#071629" : "#071629" }}
|
||
>
|
||
{poly.name}
|
||
</span>
|
||
</div>
|
||
<motion.div
|
||
animate={{ rotate: openPoly === i ? 45 : 0 }}
|
||
transition={{ duration: 0.25, ease: E_SMOOTH }}
|
||
>
|
||
<svg className="w-5 h-5 shrink-0" fill="none" viewBox="0 0 24 24" stroke={openPoly === i ? "#1B6FA8" : "#071629"} strokeWidth="1.5">
|
||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||
</svg>
|
||
</motion.div>
|
||
</button>
|
||
<AnimatePresence>
|
||
{openPoly === i && (
|
||
<motion.div
|
||
initial={{ height: 0, opacity: 0 }}
|
||
animate={{ height: "auto", opacity: 1 }}
|
||
exit={{ height: 0, opacity: 0 }}
|
||
transition={{ duration: 0.35, ease: E_SMOOTH }}
|
||
className="overflow-hidden"
|
||
layout
|
||
>
|
||
<div className="px-7 pb-6 pt-2 flex items-start gap-4">
|
||
<p className="text-[#071629]/55 text-sm font-dm leading-relaxed">{poly.desc}</p>
|
||
<button
|
||
onClick={() => setShowBooking(true)}
|
||
className="shrink-0 text-[9px] font-bold tracking-[2px] uppercase px-4 py-2.5 rounded-xl text-white cursor-pointer transition-all"
|
||
style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}
|
||
>
|
||
{lang === "tr" ? "Randevu" : "Book"}
|
||
</button>
|
||
</div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
</motion.div>
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
YORUMLAR
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section className="py-28 px-6 bg-white">
|
||
<div className="max-w-4xl mx-auto">
|
||
<motion.div
|
||
className="text-center mb-16"
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={stagger}
|
||
>
|
||
<motion.p variants={fadeUp} className="text-[10px] font-semibold tracking-[3px] uppercase mb-4" style={{ color: "#1B6FA8" }}>
|
||
{t.rvwTitle}
|
||
</motion.p>
|
||
<motion.h2 variants={fadeUp} className="section-title font-cormorant text-[#071629]">
|
||
{t.rvwHeader}
|
||
</motion.h2>
|
||
</motion.div>
|
||
|
||
<div className="relative">
|
||
<AnimatePresence mode="wait">
|
||
<motion.div
|
||
key={activeReview}
|
||
className="rounded-3xl p-10 border text-center"
|
||
style={{ background: "var(--sand)", borderColor: "rgba(27,111,168,0.12)" }}
|
||
initial={{ opacity: 0, y: 20, scale: 0.98 }}
|
||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||
exit={{ opacity: 0, y: -20, scale: 0.98 }}
|
||
transition={{ duration: 0.5, ease: E_SMOOTH }}
|
||
>
|
||
{/* Stars */}
|
||
<div className="flex justify-center gap-1 mb-6">
|
||
{[...Array(yorumlar[activeReview]?.puan ?? 5)].map((_, i) => (
|
||
<svg key={i} className="w-4 h-4" style={{ fill: "#1B6FA8" }} 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>
|
||
|
||
{/* Quote mark */}
|
||
<p className="font-cormorant italic text-[#071629]/25 text-6xl leading-none mb-2 select-none">“</p>
|
||
|
||
<p className="font-cormorant text-[#071629] text-xl lg:text-2xl leading-relaxed italic mb-8 max-w-2xl mx-auto">
|
||
{yorumlar[activeReview]?.yorum}
|
||
</p>
|
||
|
||
<div className="flex items-center gap-3 justify-center">
|
||
<div
|
||
className="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold text-sm select-none"
|
||
style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}
|
||
>
|
||
{yorumlar[activeReview]?.yazar.charAt(0)}
|
||
</div>
|
||
<div className="text-left">
|
||
<p className="font-dm font-semibold text-[#071629] text-sm">{yorumlar[activeReview]?.yazar}</p>
|
||
<p className="text-[#071629]/40 text-[10px] font-dm">{yorumlar[activeReview]?.tarih}</p>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</AnimatePresence>
|
||
|
||
{/* Dots */}
|
||
<div className="flex justify-center gap-2.5 mt-8">
|
||
{yorumlar.map((_, i) => (
|
||
<motion.button
|
||
key={i}
|
||
onClick={() => setActiveReview(i)}
|
||
className="rounded-full cursor-pointer transition-all"
|
||
style={{
|
||
width: i === activeReview ? 24 : 8,
|
||
height: 8,
|
||
background: i === activeReview ? "#1B6FA8" : "rgba(7,22,41,0.15)",
|
||
}}
|
||
whileHover={{ scale: 1.2 }}
|
||
/>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
RANDEVU CTA (full-bleed image)
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<section id="randevu" className="relative min-h-screen flex items-center py-28 px-6 overflow-hidden">
|
||
{/* Background image */}
|
||
<div className="absolute inset-0">
|
||
<img
|
||
src="https://images.unsplash.com/photo-1551076805-e1869033e561?w=1920&q=80&fit=crop"
|
||
alt=""
|
||
className="w-full h-full object-cover"
|
||
/>
|
||
<div className="absolute inset-0" style={{ background: "linear-gradient(135deg, rgba(7,22,41,0.93) 0%, rgba(15,34,64,0.88) 100%)" }} />
|
||
</div>
|
||
|
||
<div className="relative z-10 max-w-7xl mx-auto w-full">
|
||
<div className="grid lg:grid-cols-2 gap-16 items-start">
|
||
|
||
{/* Left: Contact info */}
|
||
<motion.div
|
||
initial="hidden" whileInView="show" viewport={{ once: true }} variants={stagger}
|
||
>
|
||
<motion.p variants={fadeUp} className="text-[10px] font-semibold tracking-[3px] uppercase mb-6" style={{ color: "#00B4D8" }}>
|
||
{t.bookTitle}
|
||
</motion.p>
|
||
<motion.h2 variants={fadeUp} className="section-title font-cormorant text-white mb-6">
|
||
{t.bookHeader}
|
||
</motion.h2>
|
||
<motion.p variants={fadeUp} className="text-white/50 text-sm leading-relaxed mb-10 font-dm">
|
||
{t.bookDesc}
|
||
</motion.p>
|
||
|
||
<motion.div variants={fadeUp} className="space-y-4">
|
||
{[
|
||
{ icon: "📞", label: t.callCenter, value: firma.telefon },
|
||
{ icon: "📍", label: t.adresLabel, value: firma.adres },
|
||
{ icon: "✉️", label: t.mailLabel, value: firma.email },
|
||
].map(item => (
|
||
<div key={item.label} className="flex items-start gap-4 p-4 rounded-2xl border border-white/6 bg-white/4">
|
||
<span className="text-lg mt-0.5 select-none shrink-0">{item.icon}</span>
|
||
<div>
|
||
<p className="text-white/40 text-[9px] font-semibold uppercase tracking-wider mb-1">{item.label}</p>
|
||
<p className="text-white/80 text-xs font-dm leading-snug">{item.value}</p>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</motion.div>
|
||
|
||
{/* Certifications */}
|
||
<motion.div variants={fadeUp} className="mt-8 flex flex-wrap gap-3">
|
||
{["SGK Anlaşmalı", "Bodrum Belediyesi", "Muğla Tabip Odası"].map(cert => (
|
||
<span key={cert} className="text-[9px] font-semibold tracking-wider uppercase px-3 py-2 rounded-xl border border-white/10 text-white/40">
|
||
{cert}
|
||
</span>
|
||
))}
|
||
</motion.div>
|
||
</motion.div>
|
||
|
||
{/* Right: Appointment form */}
|
||
<motion.div
|
||
className="bg-white rounded-3xl p-8 shadow-2xl"
|
||
initial={{ opacity: 0, y: 40 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.8, delay: 0.2, ease: E_SMOOTH }}
|
||
>
|
||
<h3 className="font-cormorant font-semibold text-[#071629] text-2xl mb-6">{t.bookTitle}</h3>
|
||
<div className="grid grid-cols-2 gap-4">
|
||
{[
|
||
{ label: t.fName, placeholder: lang === "tr" ? "Ad Soyad" : "Full Name", type: "text", full: false },
|
||
{ label: t.fPhone, placeholder: "0252 xxx xx xx", type: "tel", full: false },
|
||
{ label: t.fEmail, placeholder: "info@mail.com", type: "email", full: false },
|
||
{ label: t.fDept, placeholder: "", type: "select", full: false },
|
||
{ label: t.fDate, placeholder: "", type: "date", full: false },
|
||
].map((field, i) => (
|
||
<div key={i} className={field.full ? "col-span-2" : "col-span-2 sm:col-span-1"}>
|
||
<label className="block text-[9px] font-bold text-[#071629]/50 mb-1.5 uppercase tracking-wider">{field.label}</label>
|
||
{field.type === "select" ? (
|
||
<select className="w-full px-4 py-3.5 rounded-xl border border-[#071629]/12 text-xs text-[#071629] bg-[#F4F8FC] focus:outline-none focus:ring-2 transition-all cursor-pointer font-dm" style={{ "--tw-ring-color": "#1B6FA8" } as React.CSSProperties}>
|
||
{t.deptOptions.map(opt => <option key={opt}>{opt}</option>)}
|
||
</select>
|
||
) : (
|
||
<input
|
||
type={field.type}
|
||
placeholder={field.placeholder}
|
||
className="w-full px-4 py-3.5 rounded-xl border border-[#071629]/12 text-xs text-[#071629] bg-[#F4F8FC] focus:outline-none focus:ring-2 transition-all placeholder-[#071629]/25 font-dm"
|
||
style={{ "--tw-ring-color": "#1B6FA8" } as React.CSSProperties}
|
||
/>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
<motion.button
|
||
onClick={() => setShowBooking(true)}
|
||
className="mt-5 w-full py-4 rounded-xl text-white font-bold text-[10px] tracking-[2.5px] uppercase cursor-pointer shadow-lg"
|
||
style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.98 }}
|
||
>
|
||
📅 {t.fSubmit}
|
||
</motion.button>
|
||
</motion.div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
FOOTER
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<footer className="px-6 pt-20 pb-8 border-t" style={{ background: "var(--deep)", borderColor: "rgba(255,255,255,0.06)" }}>
|
||
<div className="max-w-7xl mx-auto">
|
||
<div className="grid md:grid-cols-4 gap-12 pb-16 border-b" style={{ borderColor: "rgba(255,255,255,0.06)" }}>
|
||
{/* Brand */}
|
||
<div className="md:col-span-2">
|
||
<div className="flex items-center gap-3 mb-5">
|
||
<div className="w-8 h-8 rounded-lg flex items-center justify-center" style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}>
|
||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
|
||
<line x1="7" y1="1.5" x2="7" y2="12.5" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
|
||
<line x1="1.5" y1="7" x2="12.5" y2="7" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
|
||
</svg>
|
||
</div>
|
||
<span className="font-cormorant font-semibold text-white text-xl">{firma.adi}</span>
|
||
</div>
|
||
<p className="text-white/35 text-xs font-dm leading-relaxed max-w-xs mb-7">{t.footerDesc}</p>
|
||
<div className="space-y-2.5 text-xs font-dm text-white/40">
|
||
<p>📍 {firma.adres}</p>
|
||
<p>📞 {firma.telefon}</p>
|
||
<p>✉️ {firma.email}</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Services */}
|
||
<div>
|
||
<h4 className="font-cormorant font-semibold text-white text-base mb-5">{t.navServices}</h4>
|
||
{hizmetler.slice(0, 5).map((h, i) => (
|
||
<a key={i} href="#hizmetler" className="block text-white/35 text-xs font-dm mb-3 hover:text-white transition-colors">{h.baslik}</a>
|
||
))}
|
||
</div>
|
||
|
||
{/* Navigation */}
|
||
<div>
|
||
<h4 className="font-cormorant font-semibold text-white text-base mb-5">{lang === "tr" ? "Kurumsal" : "Corporate"}</h4>
|
||
{[t.navServices, t.navDoctors, t.navPoly, t.navContact].map(item => (
|
||
<a key={item} href="#" className="block text-white/35 text-xs font-dm mb-3 hover:text-white transition-colors">{item}</a>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex flex-col sm:flex-row justify-between items-center pt-8 gap-4 text-white/25 text-xs font-dm">
|
||
<p>© 2026 {firma.adi}. {lang === "tr" ? "Tüm hakları saklıdır." : "All rights reserved."}</p>
|
||
<div className="flex gap-4">
|
||
<a href="#" className="hover:text-white transition-colors">{t.privacy}</a>
|
||
<span>·</span>
|
||
<a href="#" className="hover:text-white transition-colors">{t.terms}</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
|
||
{/* ══════════════════════════════════════════════════════════════
|
||
BOOKING MODAL
|
||
══════════════════════════════════════════════════════════════ */}
|
||
<AnimatePresence>
|
||
{showBooking && (
|
||
<motion.div
|
||
className="fixed inset-0 z-[150] flex items-center justify-center p-6 bg-black/60 backdrop-blur-md"
|
||
initial={{ opacity: 0 }}
|
||
animate={{ opacity: 1 }}
|
||
exit={{ opacity: 0 }}
|
||
onClick={() => setShowBooking(false)}
|
||
>
|
||
<motion.div
|
||
className="bg-white rounded-3xl p-8 max-w-sm w-full relative shadow-2xl border border-[#1B6FA8]/15"
|
||
initial={{ scale: 0.92, y: 24 }}
|
||
animate={{ scale: 1, y: 0 }}
|
||
exit={{ scale: 0.92, y: 24 }}
|
||
transition={{ duration: 0.4, ease: E_DRAMATIC }}
|
||
onClick={e => e.stopPropagation()}
|
||
>
|
||
<button
|
||
className="absolute top-5 right-5 w-8 h-8 rounded-full bg-[#071629]/6 flex items-center justify-center text-[#071629]/50 hover:bg-[#071629]/12 transition-colors cursor-pointer text-sm font-bold"
|
||
onClick={() => setShowBooking(false)}
|
||
>
|
||
✕
|
||
</button>
|
||
|
||
<div className="w-12 h-12 rounded-2xl flex items-center justify-center mb-5" style={{ background: "rgba(27,111,168,0.1)" }}>
|
||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
||
<line x1="10" y1="2" x2="10" y2="18" stroke="#1B6FA8" strokeWidth="3" strokeLinecap="round"/>
|
||
<line x1="2" y1="10" x2="18" y2="10" stroke="#1B6FA8" strokeWidth="3" strokeLinecap="round"/>
|
||
</svg>
|
||
</div>
|
||
|
||
<h3 className="font-cormorant font-semibold text-[#071629] text-2xl mb-1">{t.bookTitle}</h3>
|
||
<p className="text-[#071629]/40 text-xs font-dm mb-6">{lang === "tr" ? "Koordinatörümüz sizi arayacak." : "Our coordinator will call you back."}</p>
|
||
|
||
<div className="space-y-4">
|
||
<div>
|
||
<label className="block text-[9px] font-bold text-[#071629]/45 mb-1.5 uppercase tracking-wider">{t.fName}</label>
|
||
<input type="text" className="w-full px-4 py-3.5 rounded-xl border border-[#071629]/12 text-xs font-dm bg-[#F4F8FC] focus:outline-none" placeholder={lang === "tr" ? "Ad Soyad" : "Full Name"} />
|
||
</div>
|
||
<div>
|
||
<label className="block text-[9px] font-bold text-[#071629]/45 mb-1.5 uppercase tracking-wider">{t.fPhone}</label>
|
||
<input type="tel" className="w-full px-4 py-3.5 rounded-xl border border-[#071629]/12 text-xs font-dm bg-[#F4F8FC] focus:outline-none" placeholder="0252 xxx xx xx" />
|
||
</div>
|
||
<motion.button
|
||
className="w-full py-4 rounded-xl text-white font-bold text-[10px] tracking-[2px] uppercase cursor-pointer"
|
||
style={{ background: "linear-gradient(135deg, #1B6FA8, #00B4D8)" }}
|
||
whileHover={{ scale: 1.02 }}
|
||
whileTap={{ scale: 0.97 }}
|
||
onClick={() => setShowBooking(false)}
|
||
>
|
||
{lang === "tr" ? "Gönder" : "Submit"}
|
||
</motion.button>
|
||
</div>
|
||
</motion.div>
|
||
</motion.div>
|
||
)}
|
||
</AnimatePresence>
|
||
</>
|
||
);
|
||
}
|