Initial commit: Salmakis Yachting Portal with Cloudinary & i18n
This commit is contained in:
41
app/components/Destinations.tsx
Normal file
41
app/components/Destinations.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
export default function Destinations() {
|
||||
const regions = [
|
||||
{ name: 'BODRUM', image: 'https://images.unsplash.com/photo-1544650039-33827ca79f06?q=80&w=2070&auto=format&fit=crop' },
|
||||
{ name: 'GÖCEK', image: 'https://images.unsplash.com/photo-1524231757912-21f4fe3a7200?q=80&w=2071&auto=format&fit=crop' },
|
||||
{ name: 'GREEK ISLANDS', image: 'https://images.unsplash.com/photo-1533105079780-92b9be482077?q=80&w=2068&auto=format&fit=crop' }
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="py-24 bg-white px-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="text-center mb-16">
|
||||
<span className="text-gold luxury-text text-sm mb-4 block">The Journey</span>
|
||||
<h2 className="text-midnight text-5xl mb-6">Unforgettable Destinations</h2>
|
||||
<p className="text-gray-500 max-w-2xl mx-auto">
|
||||
Explore the most exclusive bays and historical harbors of the Aegean and Mediterranean.
|
||||
From the turquoise waters of Bodrum to the secluded islands of Greece.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 h-[600px]">
|
||||
<div className="md:col-span-8 relative overflow-hidden group">
|
||||
<img src={regions[0].image} className="w-full h-full object-cover smooth-transition group-hover:scale-105" alt={regions[0].name} />
|
||||
<div className="absolute inset-0 bg-black/40 flex items-center justify-center">
|
||||
<h3 className="text-white text-4xl tracking-widest font-serif">{regions[0].name}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:col-span-4 grid grid-rows-2 gap-4">
|
||||
{regions.slice(1).map((region) => (
|
||||
<div key={region.name} className="relative overflow-hidden group">
|
||||
<img src={region.image} className="w-full h-full object-cover smooth-transition group-hover:scale-105" alt={region.name} />
|
||||
<div className="absolute inset-0 bg-black/30 flex items-center justify-center">
|
||||
<h3 className="text-white text-2xl tracking-widest font-serif">{region.name}</h3>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
66
app/components/FleetPreview.tsx
Normal file
66
app/components/FleetPreview.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function FleetPreview() {
|
||||
const featuredYachts = [
|
||||
{
|
||||
name: 'M/S MEIRA',
|
||||
length: '55m',
|
||||
guests: '12',
|
||||
image: 'https://images.unsplash.com/photo-1569263979104-865ab7cd8d13?q=80&w=2074&auto=format&fit=crop',
|
||||
href: '/fleet/meira'
|
||||
},
|
||||
{
|
||||
name: 'M/Y PRINCESS MELDA',
|
||||
length: '45m',
|
||||
guests: '10',
|
||||
image: 'https://images.unsplash.com/photo-1621275471769-e6aa344546d5?q=80&w=2073&auto=format&fit=crop',
|
||||
href: '/fleet/princess-melda'
|
||||
},
|
||||
{
|
||||
name: 'QUEEN OF SALMAKIS',
|
||||
length: '40m',
|
||||
guests: '18',
|
||||
image: 'https://images.unsplash.com/photo-1605281317010-fe5ffe798156?q=80&w=2044&auto=format&fit=crop',
|
||||
href: '/fleet/queen-of-salmakis'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="py-24 bg-soft-grey px-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-between items-end mb-16">
|
||||
<div>
|
||||
<span className="text-gold luxury-text text-sm mb-4 block">Our Collection</span>
|
||||
<h2 className="text-midnight text-5xl">Featured Fleet</h2>
|
||||
</div>
|
||||
<Link href="/fleet" className="luxury-text text-sm border-b border-gold pb-1 hover:text-gold smooth-transition">
|
||||
View All Yachts
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{featuredYachts.map((yacht) => (
|
||||
<Link key={yacht.name} href={yacht.href} className="group overflow-hidden bg-white shadow-lg smooth-transition hover:-translate-y-2">
|
||||
<div className="aspect-[4/5] relative overflow-hidden">
|
||||
<img
|
||||
src={yacht.image}
|
||||
alt={yacht.name}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-black/20 group-hover:bg-black/40 transition-colors" />
|
||||
<div className="absolute bottom-8 left-8 text-white">
|
||||
<h3 className="text-2xl mb-2">{yacht.name}</h3>
|
||||
<div className="flex gap-4 text-xs luxury-text opacity-80">
|
||||
<span>{yacht.length}</span>
|
||||
<span>{yacht.guests} Guests</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
119
app/components/Footer.tsx
Normal file
119
app/components/Footer.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="w-full bg-[#111111] text-white pt-20 px-6 md:px-12 border-t border-white/5 flex flex-col items-center">
|
||||
<div className="w-full max-w-[1440px] flex flex-col items-center">
|
||||
|
||||
{/* Top Section: Brand & Heritage */}
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-headline tracking-[0.3em] text-gold mb-4 uppercase">SALMAKIS</h2>
|
||||
<p className="font-label text-xs tracking-[0.3em] text-white/60 mb-8 uppercase italic">A Heritage of Excellence Since 1980.</p>
|
||||
|
||||
<div className="flex flex-col gap-2 font-body text-sm text-white/80 tracking-wide">
|
||||
<p>+90 252 316 65 06</p>
|
||||
<p>08:00 - 20:00</p>
|
||||
<p className="text-white/40">salmakis@salmakis.com.tr</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Middle Section: 3-Column Entities */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-8 lg:gap-24 w-full max-w-5xl mx-auto mb-20 text-center justify-items-center">
|
||||
|
||||
{/* Salmakis Resort */}
|
||||
<div className="flex flex-col items-center">
|
||||
<h3 className="font-headline text-xl text-gold mb-6 tracking-wider">Salmakis Resort</h3>
|
||||
<div className="flex flex-col gap-3 font-body text-xs text-white/60 leading-relaxed uppercase tracking-wider">
|
||||
<p>Bardakci Koyu<br />BODRUM/MUĞLA/TURKEY</p>
|
||||
<div className="flex flex-col gap-1 mt-2">
|
||||
<p>+90 252 316 65 06</p>
|
||||
<p>+90 252 316 65 07</p>
|
||||
<p>+90 252 316 65 11</p>
|
||||
</div>
|
||||
<p className="text-white/30 mt-2 lowercase">salmakis@salmakis.com.tr</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Salmakis Villas */}
|
||||
<div className="flex flex-col items-center">
|
||||
<h3 className="font-headline text-xl text-gold mb-6 tracking-wider">Salmakis Villas</h3>
|
||||
<div className="flex flex-col gap-3 font-body text-xs text-white/60 leading-relaxed uppercase tracking-wider">
|
||||
<p>Bademlik Mevkii<br />Kume Evleri No 24<br />Bodrum/MUGLA/TURKEY</p>
|
||||
<div className="flex flex-col gap-1 mt-2">
|
||||
<p>+90 252 316 27 38</p>
|
||||
<p>+90 252 316 28 77</p>
|
||||
<p>+90 532 731 78 04</p>
|
||||
<p>+90 252 316 27 37</p>
|
||||
</div>
|
||||
<p className="text-white/30 mt-2 lowercase">info@salmakisvillas.com</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Salmakis Yachting */}
|
||||
<div className="flex flex-col items-center">
|
||||
<h3 className="font-headline text-xl text-gold mb-6 tracking-wider">Salmakis Yachting</h3>
|
||||
<div className="flex flex-col gap-3 font-body text-xs text-white/60 leading-relaxed uppercase tracking-wider">
|
||||
<p>Kumbahce Mah. Icmeler Cad.<br />No 28/1<br />BODRUM/MUGLA/TURKEY</p>
|
||||
<div className="flex flex-col gap-1 mt-2">
|
||||
<p>+90 252 316 27 38</p>
|
||||
<p>+90 252 316 28 77</p>
|
||||
<p>+90 252 316 27 37</p>
|
||||
</div>
|
||||
<p className="text-white/30 mt-2 lowercase">info@salmakisyachting.com</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Social Follow Bar */}
|
||||
<div className="w-full flex justify-end items-center gap-6 mb-6 px-4">
|
||||
<span className="font-label text-xs tracking-widest text-white uppercase font-medium">FOLLOW US</span>
|
||||
<div className="flex items-center gap-4 text-white">
|
||||
<a href="#" className="hover:text-gold transition-colors">
|
||||
{/* Instagram representation */}
|
||||
<span className="material-symbols-outlined !text-2xl">photo_camera</span>
|
||||
</a>
|
||||
<a href="#" className="hover:text-gold transition-colors font-bold text-xl px-1">
|
||||
f
|
||||
</a>
|
||||
<a href="#" className="hover:text-gold transition-colors">
|
||||
<span className="material-symbols-outlined !text-2xl">play_circle</span>
|
||||
</a>
|
||||
<a href="#" className="hover:text-gold transition-colors font-bold text-xl px-1">
|
||||
in
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="w-full h-px bg-white/10 mb-6"></div>
|
||||
|
||||
{/* Bottom Legal Bar */}
|
||||
<div className="w-full flex flex-col md:flex-row justify-between items-center gap-6 px-4 pb-12">
|
||||
<div className="flex flex-wrap items-center justify-center md:justify-start gap-6 font-label text-[10px] tracking-widest text-white/80 uppercase">
|
||||
<Link href="/legal" className="hover:text-gold transition-colors">LEGAL & PRIVACY</Link>
|
||||
<Link href="/cookies" className="hover:text-gold transition-colors">COOKIES</Link>
|
||||
<Link href="/sitemap" className="hover:text-gold transition-colors">SITEMAP</Link>
|
||||
<button className="hover:text-gold transition-colors uppercase tracking-widest text-[10px] cursor-pointer">COOKIES SETTINGS</button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center md:items-end gap-2">
|
||||
<p className="font-label text-[10px] tracking-widest text-white/80 uppercase">
|
||||
© SALMAKIS 2026 ALL RIGHTS RESERVED
|
||||
</p>
|
||||
<a
|
||||
href="https://ayris.tech"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center gap-2"
|
||||
>
|
||||
<span className="font-label text-[9px] tracking-widest text-white/30 uppercase">Created by</span>
|
||||
<span className="font-headline text-[10px] tracking-[0.2em] text-white/60 font-bold border-b border-white/20 pb-0.5 group-hover:text-gold group-hover:border-gold transition-all">AYRISTECH</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
38
app/components/Hero.tsx
Normal file
38
app/components/Hero.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
export default function Hero() {
|
||||
return (
|
||||
<section className="relative h-screen w-full overflow-hidden bg-midnight">
|
||||
{/* Background Overlay */}
|
||||
<div className="absolute inset-0 bg-black/40 z-10" />
|
||||
|
||||
{/* Hero Image */}
|
||||
<div className="absolute inset-0 bg-[url('/hero-yacht.png')] bg-cover bg-center scale-105 animate-[zoom_20s_infinite_alternate]">
|
||||
{/* Animated background for a premium feel */}
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 h-full flex flex-col items-center justify-center text-center px-4">
|
||||
<span className="text-gold luxury-text text-sm mb-6 fade-in-up tracking-[0.4em]">Exclusivity Redefined</span>
|
||||
<h1 className="text-white text-6xl md:text-8xl lg:text-9xl mb-8 fade-in-up font-serif" style={{ animationDelay: '0.2s' }}>
|
||||
The Pinnacle of <br />
|
||||
<span className="italic">Aegean Luxury</span>
|
||||
</h1>
|
||||
<div className="w-24 h-px bg-gold fade-in-up mb-8" style={{ animationDelay: '0.4s' }}></div>
|
||||
<p className="text-sand text-lg md:text-xl luxury-text fade-in-up" style={{ animationDelay: '0.6s' }}>
|
||||
Since 1980
|
||||
</p>
|
||||
|
||||
<div className="mt-16 fade-in-up flex flex-col md:row gap-6" style={{ animationDelay: '0.8s' }}>
|
||||
<button className="btn-gold">Explore the Fleet</button>
|
||||
<button className="btn-hollow !text-white !border-white hover:!bg-white hover:!text-midnight">Our Destinations</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scroll indicator */}
|
||||
<div className="absolute bottom-10 left-1/2 -translate-x-1/2 z-20 animate-bounce cursor-pointer opacity-50 hover:opacity-100 transition-opacity">
|
||||
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1} d="M19 14l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
218
app/components/Navbar.tsx
Normal file
218
app/components/Navbar.tsx
Normal file
@@ -0,0 +1,218 @@
|
||||
'use client';
|
||||
|
||||
import { Link, usePathname, useRouter } from '@/i18n/routing';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useLocale, useTranslations } from 'next-intl';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
export default function Navbar() {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
const locale = useLocale();
|
||||
const t = useTranslations('Navbar');
|
||||
|
||||
// Close menu on route change
|
||||
useEffect(() => {
|
||||
setIsOpen(false);
|
||||
}, [pathname]);
|
||||
|
||||
// Lock body scroll when menu is open
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
} else {
|
||||
document.body.style.overflow = 'unset';
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const changeLocale = (nextLocale: string) => {
|
||||
router.replace(pathname, { locale: nextLocale });
|
||||
};
|
||||
|
||||
const navLinks = [
|
||||
{ name: t('meira'), href: '/fleet/meira' },
|
||||
{ name: t('princess'), href: '/fleet/princess-melda' },
|
||||
{ name: t('queen'), href: '/fleet/queen-of-salmakis' },
|
||||
{ name: t('dolce'), href: '/fleet/dolce-mare' },
|
||||
{ name: t('sunworld'), href: '/fleet/sunworld-8' },
|
||||
];
|
||||
|
||||
const menuVariants = {
|
||||
closed: {
|
||||
opacity: 0,
|
||||
y: "-100%",
|
||||
transition: {
|
||||
duration: 0.8,
|
||||
ease: [0.76, 0, 0.24, 1]
|
||||
}
|
||||
},
|
||||
open: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
duration: 0.8,
|
||||
ease: [0.76, 0, 0.24, 1]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const linkVariants = {
|
||||
closed: { opacity: 0, y: 30 },
|
||||
open: (i: number) => ({
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 0.3 + (i * 0.1),
|
||||
duration: 0.6,
|
||||
ease: "easeOut"
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
return (
|
||||
<nav className="fixed top-0 w-full z-50 transition-all duration-300">
|
||||
{/* Background Layer (Transparent initially, solid on scroll could be added later) */}
|
||||
<div className="absolute inset-0 bg-white/90 backdrop-blur-md border-b border-outline-variant/10 shadow-sm" />
|
||||
|
||||
<div className="relative w-full flex items-center justify-between px-6 md:px-12 py-6">
|
||||
|
||||
{/* Left: Hamburger (Mobile) / Placeholder (Desktop) */}
|
||||
<div className="md:hidden">
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="relative z-[70] w-10 h-10 flex flex-col items-center justify-center gap-1.5 focus:outline-none"
|
||||
>
|
||||
<motion.span
|
||||
animate={isOpen ? { rotate: 45, y: 8, backgroundColor: "#ffffff" } : { rotate: 0, y: 0, backgroundColor: "#06152D" }}
|
||||
className="w-8 h-px block"
|
||||
/>
|
||||
<motion.span
|
||||
animate={isOpen ? { opacity: 0 } : { opacity: 1 }}
|
||||
className="w-8 h-px bg-primary block"
|
||||
/>
|
||||
<motion.span
|
||||
animate={isOpen ? { rotate: -45, y: -6, backgroundColor: "#ffffff" } : { rotate: 0, y: 0, backgroundColor: "#06152D" }}
|
||||
className="w-8 h-px block"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Center: Logo */}
|
||||
<div className="absolute left-1/2 -translate-x-1/2 flex flex-col items-center">
|
||||
<Link href="/" className="group flex flex-col items-center">
|
||||
<span className="font-headline text-3xl md:text-4xl tracking-[0.5em] text-primary group-hover:text-secondary transition-colors duration-700 uppercase mr-[-0.5em]">
|
||||
SALMAKIS
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Right: Actions / Desktop Nav Wrapper */}
|
||||
<div className="flex items-center space-x-8">
|
||||
{/* Desktop Lang Switcher */}
|
||||
<div className="hidden md:flex items-center font-label text-[10px] tracking-[0.2em] uppercase text-primary/40">
|
||||
<button onClick={() => changeLocale('en')} className={`${locale === 'en' ? 'text-secondary font-bold' : ''}`}>EN</button>
|
||||
<span className="mx-2 text-outline-variant">|</span>
|
||||
<button onClick={() => changeLocale('tr')} className={`${locale === 'tr' ? 'text-secondary font-bold' : ''}`}>TR</button>
|
||||
</div>
|
||||
|
||||
<Link href="/contact" className="hidden lg:block font-headline text-[10px] tracking-[0.3em] font-medium border border-primary/20 px-6 py-2.5 uppercase hover:bg-primary hover:text-white transition-all duration-500">
|
||||
{t('contact') || 'Contact'}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Desktop Navigation Row (Optional: Can stay below logo or be inline) */}
|
||||
<div className="hidden md:flex relative justify-center border-t border-outline-variant/5 py-4">
|
||||
<div className="flex items-center gap-x-12">
|
||||
{navLinks.map((link) => {
|
||||
const isActive = pathname === link.href;
|
||||
return (
|
||||
<Link
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
className={`font-headline text-[11px] tracking-[0.35em] font-medium uppercase transition-all duration-500 relative pb-1 group ${isActive ? 'text-primary' : 'text-primary/50 hover:text-primary'}`}
|
||||
>
|
||||
{link.name}
|
||||
<motion.span
|
||||
initial={false}
|
||||
animate={isActive ? { width: "100%" } : { width: "0%" }}
|
||||
className="absolute bottom-0 left-0 h-px bg-secondary"
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Overlay */}
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
variants={menuVariants}
|
||||
initial="closed"
|
||||
animate="open"
|
||||
exit="closed"
|
||||
className="fixed inset-0 z-[60] bg-primary flex flex-col overflow-hidden"
|
||||
>
|
||||
{/* Artistic Background Element */}
|
||||
<div className="absolute top-0 right-0 w-[150%] h-full bg-[#050B15] -rotate-12 translate-x-1/2 pointer-events-none opacity-50" />
|
||||
|
||||
<div className="relative h-full flex flex-col px-8 pt-48 pb-12 justify-between">
|
||||
{/* Links */}
|
||||
<div className="flex flex-col space-y-8">
|
||||
{navLinks.map((link, i) => (
|
||||
<motion.div
|
||||
key={link.name}
|
||||
custom={i}
|
||||
variants={linkVariants}
|
||||
>
|
||||
<Link
|
||||
href={link.href}
|
||||
className="font-headline text-3xl md:text-5xl tracking-[0.2em] text-white/90 hover:text-secondary uppercase transition-colors flex items-center gap-4 group"
|
||||
>
|
||||
<span className="text-secondary font-headline text-xs tracking-widest opacity-40 group-hover:opacity-100">0{i+1}</span>
|
||||
{link.name}
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Bottom Info */}
|
||||
<div className="grid grid-cols-2 gap-8 border-t border-white/10 pt-12">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { delay: 1 } }}
|
||||
className="space-y-4"
|
||||
>
|
||||
<span className="font-label text-[10px] tracking-[0.3em] text-secondary uppercase">Quick Link</span>
|
||||
<Link href="/contact" className="block text-white font-headline text-sm tracking-widest uppercase mb-4">Inquire Now</Link>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<button onClick={() => changeLocale('en')} className={`text-[10px] tracking-[0.2em] font-bold ${locale === 'en' ? 'text-secondary' : 'text-white/40'}`}>EN</button>
|
||||
<button onClick={() => changeLocale('tr')} className={`text-[10px] tracking-[0.2em] font-bold ${locale === 'tr' ? 'text-secondary' : 'text-white/40'}`}>TR</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { delay: 1.2 } }}
|
||||
className="text-right space-y-4"
|
||||
>
|
||||
<span className="font-label text-[10px] tracking-[0.3em] text-secondary uppercase">Salmakis Yachting</span>
|
||||
<div className="text-white/60 font-body text-xs leading-relaxed">
|
||||
Bodrum, Mugla<br />
|
||||
Turkish Riviera
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
31
app/components/ValueProp.tsx
Normal file
31
app/components/ValueProp.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
export default function ValueProp() {
|
||||
return (
|
||||
<section className="py-24 bg-white px-8">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<h2 className="text-midnight text-4xl md:text-5xl mb-8">
|
||||
A Legacy of Excellence <span className="text-gold italic">Since 1980</span>
|
||||
</h2>
|
||||
<div className="w-24 h-px bg-gold mx-auto mb-8"></div>
|
||||
<p className="text-gray-600 text-lg leading-relaxed mb-12">
|
||||
Salmakis Yachting has been the benchmark for luxury charters in the Aegean for over four decades.
|
||||
Our fleet represents the pinnacle of seafaring elegance, combining the charm of traditional
|
||||
craftsmanship with the comforts of a 5-star floating hotel.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 text-center uppercase tracking-widest text-xs">
|
||||
<div>
|
||||
<span className="block text-gold text-2xl mb-2 font-serif">40+</span>
|
||||
Years Experience
|
||||
</div>
|
||||
<div>
|
||||
<span className="block text-gold text-2xl mb-2 font-serif">5★</span>
|
||||
Bespoke Service
|
||||
</div>
|
||||
<div>
|
||||
<span className="block text-gold text-2xl mb-2 font-serif">100%</span>
|
||||
Aegean Expertise
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
93
app/components/YachtCard.tsx
Normal file
93
app/components/YachtCard.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
import { CldImage } from 'next-cloudinary';
|
||||
import Link from 'next/link';
|
||||
import { Yacht } from '../data/yachts';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
interface YachtCardProps {
|
||||
yacht: Yacht;
|
||||
}
|
||||
|
||||
export default function YachtCard({ yacht }: YachtCardProps) {
|
||||
const t = useTranslations('YachtCard');
|
||||
return (
|
||||
<div className="flex flex-col group cursor-pointer">
|
||||
{/* Image Container */}
|
||||
<div className="relative aspect-[16/10] overflow-hidden mb-6">
|
||||
<CldImage
|
||||
src={yacht.heroImage}
|
||||
alt={yacht.name}
|
||||
fill
|
||||
crop="fill"
|
||||
gravity="auto"
|
||||
className="object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
|
||||
{/* Award Badge */}
|
||||
{yacht.award && (
|
||||
<div className="absolute top-4 left-4 z-10 w-24 h-24 border border-white/40 p-2 flex flex-col items-center justify-center text-center backdrop-blur-sm bg-black/10">
|
||||
<span className="text-[8px] font-bold text-white leading-tight uppercase tracking-tighter">
|
||||
{yacht.award}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Top Right Heart Icon */}
|
||||
<div className="absolute top-4 right-4 z-10 text-white hover:text-secondary transition-colors">
|
||||
<span className="material-symbols-outlined !text-xl">favorite</span>
|
||||
</div>
|
||||
|
||||
{/* Bottom Right Icons */}
|
||||
<div className="absolute bottom-4 right-4 z-10 flex flex-col gap-2">
|
||||
<div className="w-8 h-8 rounded-full border border-white/60 flex items-center justify-center text-white backdrop-blur-md bg-black/20 hover:bg-secondary/40 transition-colors">
|
||||
<span className="material-symbols-outlined !text-base">photo_camera</span>
|
||||
</div>
|
||||
<div className="w-8 h-8 rounded-full border border-white/60 flex items-center justify-center text-white backdrop-blur-md bg-black/20 hover:bg-secondary/40 transition-colors">
|
||||
<span className="material-symbols-outlined !text-base">play_arrow</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Brand Text Overlay */}
|
||||
<div className="absolute bottom-4 left-4 z-10">
|
||||
<span className="font-headline text-lg tracking-[0.2em] text-white uppercase opacity-80">SALMAKIS</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Info Section */}
|
||||
<div className="flex flex-col items-center text-center px-4">
|
||||
<h3 className="font-headline text-2xl text-primary tracking-widest uppercase mb-1">
|
||||
{yacht.name}
|
||||
</h3>
|
||||
|
||||
<p className="font-label text-[10px] tracking-[0.15em] text-on-surface-variant uppercase mb-6">
|
||||
{yacht.builder} — {yacht.year} {yacht.refitYear && `(${yacht.refitYear})`}
|
||||
</p>
|
||||
|
||||
{/* Spec Grid */}
|
||||
<div className="grid grid-cols-4 w-full border-t border-outline-variant/30 py-6 mb-2">
|
||||
<div className="flex flex-col items-center border-r border-outline-variant/30">
|
||||
<span className="font-body text-xs text-primary font-medium">{yacht.length} <span className="text-[10px] text-on-surface-variant">{yacht.lengthFt}</span></span>
|
||||
<span className="font-label text-[9px] tracking-[0.1em] text-on-surface-variant uppercase mt-1">{t('length')}</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center border-r border-outline-variant/30">
|
||||
<span className="font-body text-xs text-primary font-medium">{yacht.guests}</span>
|
||||
<span className="font-label text-[9px] tracking-[0.1em] text-on-surface-variant uppercase mt-1">{t('guests')}</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center border-r border-outline-variant/30">
|
||||
<span className="font-body text-xs text-primary font-medium">{yacht.cabins}</span>
|
||||
<span className="font-label text-[9px] tracking-[0.1em] text-on-surface-variant uppercase mt-1">{t('cabins')}</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center">
|
||||
<span className="font-body text-xs text-primary font-medium">{yacht.crew}</span>
|
||||
<span className="font-label text-[9px] tracking-[0.1em] text-on-surface-variant uppercase mt-1">{t('crew')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full bg-surface-container-low py-3 text-center">
|
||||
<p className="font-label text-[10px] tracking-widest text-on-surface-variant uppercase gap-1 flex items-center justify-center">
|
||||
{t('from')} <span className="font-body text-sm font-bold text-primary px-1">{yacht.weeklyPrice}</span> {t('p_week')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user