Initial commit: Salmakis Yachting Portal with Cloudinary & i18n

This commit is contained in:
2026-04-14 12:34:19 +03:00
parent e6784f8056
commit 8b1bdfd3c6
99 changed files with 4118 additions and 115 deletions

View File

@@ -0,0 +1,101 @@
import { useTranslations } from 'next-intl';
export default function ContactPage() {
const t = useTranslations('Contact');
return (
<div className="pt-40 pb-24 px-6 md:px-24 min-h-screen bg-surface">
<div className="max-w-7xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-12 gap-24">
{/* Editorial Column */}
<div className="md:col-span-12 lg:col-span-5">
<span className="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4 block">{t('reservation_concierge')}</span>
<h1 className="text-primary font-headline text-6xl md:text-8xl mb-8 leading-tight">
{t('title1')} <br />
<span className="text-secondary italic">{t('title2')}</span>
</h1>
<div className="h-px w-24 bg-secondary mb-12"></div>
<div className="space-y-16 mt-24">
<div>
<h3 className="font-label text-xs tracking-[0.2em] text-secondary mb-4 uppercase">{t('headquarters')}</h3>
<p className="font-body text-xl text-primary font-light leading-relaxed">
{t('hq_address1')} <br />
{t('hq_address2')}
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<div>
<h3 className="font-label text-xs tracking-[0.2em] text-secondary mb-4 uppercase">{t('direct_line')}</h3>
<p className="font-body text-xl text-primary font-light">+90 (252) 316 12 34</p>
</div>
<div>
<h3 className="font-label text-xs tracking-[0.2em] text-secondary mb-4 uppercase">{t('digital_mail')}</h3>
<p className="font-body text-xl text-primary font-light">atelier@salmakis.com</p>
</div>
</div>
<div className="pt-8">
<button className="flex items-center gap-4 bg-[#0a0a0a] text-white px-12 py-5 hover:bg-secondary transition-all">
<span className="font-headline text-xs tracking-[0.3em] uppercase">{t('whatsapp_btn')}</span>
</button>
</div>
</div>
</div>
{/* Minimalist Form Column */}
<div className="md:col-span-12 lg:col-span-7 bg-white p-12 md:p-20">
<h2 className="font-headline text-3xl mb-12 text-primary uppercase tracking-widest border-b border-outline-variant/10 pb-6">{t('form_title')}</h2>
<form className="space-y-12">
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<div className="flex flex-col group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('first_name_label')}</label>
<input type="text" className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light" placeholder={t('first_name_placeholder')} />
</div>
<div className="flex flex-col group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('last_name_label')}</label>
<input type="text" className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light" placeholder={t('last_name_placeholder')} />
</div>
</div>
<div className="flex flex-col group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('email_label')}</label>
<input type="email" className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light" placeholder={t('email_placeholder')} />
</div>
<div className="flex flex-col group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('yacht_label')}</label>
<select className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light appearance-none">
<option>M/S MEIRA</option>
<option>M/Y PRINCESS MELDA</option>
<option>QUEEN OF SALMAKIS</option>
<option>DOLCE MARE</option>
<option>SUNWORLD-8</option>
</select>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<div className="flex flex-col group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('charter_start')}</label>
<input type="date" className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light" />
</div>
<div className="flex flex-col group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('charter_end')}</label>
<input type="date" className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light" />
</div>
</div>
<div className="flex flex-col pt-4 group">
<label className="font-label text-[10px] tracking-[0.2em] text-secondary uppercase mb-2 group-focus-within:text-primary transition-colors">{t('requirements_label')}</label>
<textarea rows={4} className="border-b border-outline-variant py-3 focus:border-secondary transition-all outline-none bg-transparent font-body text-lg font-light resize-none" placeholder={t('requirements_placeholder')}></textarea>
</div>
<button className="w-full bg-secondary text-white py-6 font-headline tracking-[0.4em] uppercase hover:bg-primary transition-all">{t('submit_btn')}</button>
</form>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,481 @@
'use client';
import { yachts } from "../../../data/yachts";
import { notFound } from "next/navigation";
import { Link } from "@/i18n/routing";
import { motion } from "framer-motion";
import { use, useState, useCallback, useEffect } from "react";
import { AnimatePresence } from "framer-motion";
import { CldImage } from "next-cloudinary";
import { useTranslations, useLocale } from "next-intl";
interface PageProps {
params: Promise<{ slug: string }>;
}
export default function YachtPage({ params }: PageProps) {
const { slug } = use(params);
const yacht = yachts.find((y) => y.slug === slug);
const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);
const t = useTranslations('FleetDetail');
const locale = useLocale();
const openLightbox = (index: number) => setLightboxIndex(index);
const closeLightbox = () => setLightboxIndex(null);
const goNext = useCallback(() => {
if (lightboxIndex !== null && yacht) {
setLightboxIndex((lightboxIndex + 1) % yacht.gallery.length);
}
}, [lightboxIndex, yacht]);
const goPrev = useCallback(() => {
if (lightboxIndex !== null && yacht) {
setLightboxIndex((lightboxIndex - 1 + yacht.gallery.length) % yacht.gallery.length);
}
}, [lightboxIndex, yacht]);
useEffect(() => {
const handleKey = (e: KeyboardEvent) => {
if (lightboxIndex === null) return;
if (e.key === 'Escape') closeLightbox();
if (e.key === 'ArrowRight') goNext();
if (e.key === 'ArrowLeft') goPrev();
};
window.addEventListener('keydown', handleKey);
return () => window.removeEventListener('keydown', handleKey);
}, [lightboxIndex, goNext, goPrev]);
if (!yacht) {
notFound();
}
const fadeInUp = {
hidden: { opacity: 0, y: 40 },
visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } }
};
const staggerContainer = {
hidden: { opacity: 0 },
visible: { opacity: 1, transition: { staggerChildren: 0.15 } }
};
return (
<div className="bg-surface">
{/* Editorial Hero Section */}
<section className="relative h-[90vh] md:h-screen w-full overflow-hidden">
<motion.div
initial={{ scale: 1.1, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 1.5, ease: "easeOut" }}
className="absolute inset-0 z-0"
>
<CldImage
src={yacht.heroImage}
alt={yacht.name}
fill
crop="fill"
gravity="auto"
className="object-cover grayscale-[10%]"
priority
/>
</motion.div>
<div className="absolute inset-0 bg-gradient-to-t from-primary/90 via-primary/20 to-transparent z-10 flex flex-col items-center justify-center text-center px-6">
<motion.div
initial="hidden"
animate="visible"
variants={staggerContainer}
className="flex flex-col items-center"
>
<motion.span variants={fadeInUp} className="font-label text-[10px] md:text-xs tracking-[0.5em] text-secondary uppercase mb-6">
The Fleet Collection
</motion.span>
<motion.h1 variants={fadeInUp} className="text-white font-headline text-5xl md:text-8xl lg:text-9xl mb-4 uppercase tracking-tighter">
{yacht.name}
</motion.h1>
<motion.p variants={fadeInUp} className="text-secondary font-headline text-lg md:text-2xl italic tracking-wide">
{yacht.tagline}
</motion.p>
</motion.div>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 1, duration: 1 }}
className="absolute bottom-12 left-1/2 -translate-x-1/2 flex flex-col items-center"
>
<span className="text-white/40 text-[9px] md:text-[10px] tracking-[0.5em] uppercase mb-4">Explore Specifications</span>
<div className="w-px h-12 md:h-16 bg-gradient-to-b from-secondary to-transparent"></div>
</motion.div>
</div>
</section>
{/* Technical Atelier Bar */}
<div className="bg-primary py-12 md:py-16 text-white border-y border-white/5 relative z-20">
<div className="w-full flex justify-center">
<div className="w-full max-w-5xl mx-auto grid grid-cols-2 md:grid-cols-5 px-6 gap-y-12 md:gap-y-0 text-center">
<div className="flex flex-col items-center">
<span className="material-symbols-outlined text-secondary text-2xl md:text-3xl mb-4">straighten</span>
<span className="text-secondary font-label text-[9px] tracking-[0.4em] mb-2 uppercase">{t('length')}</span>
<span className="text-xl md:text-2xl font-headline tracking-widest">{yacht.length}</span>
</div>
<div className="flex flex-col items-center md:border-l md:border-white/10">
<span className="material-symbols-outlined text-secondary text-2xl md:text-3xl mb-4">groups</span>
<span className="text-secondary font-label text-[9px] tracking-[0.4em] mb-2 uppercase">{t('guests')}</span>
<span className="text-xl md:text-2xl font-headline tracking-widest">{yacht.guests}</span>
</div>
<div className="flex flex-col items-center md:border-l md:border-white/10">
<span className="material-symbols-outlined text-secondary text-2xl md:text-3xl mb-4">bed</span>
<span className="text-secondary font-label text-[9px] tracking-[0.4em] mb-2 uppercase">{t('cabins')}</span>
<span className="text-xl md:text-2xl font-headline tracking-widest">{yacht.cabins}</span>
</div>
<div className="flex flex-col items-center md:border-l md:border-white/10">
<span className="material-symbols-outlined text-secondary text-2xl md:text-3xl mb-4">support_agent</span>
<span className="text-secondary font-label text-[9px] tracking-[0.4em] mb-2 uppercase">{t('crew')}</span>
<span className="text-xl md:text-2xl font-headline tracking-widest">{yacht.crew}</span>
</div>
<div className="flex flex-col items-center md:border-l md:border-white/10 col-span-2 md:col-span-1">
<span className="material-symbols-outlined text-secondary text-2xl md:text-3xl mb-4">speed</span>
<span className="text-secondary font-label text-[9px] tracking-[0.4em] mb-2 uppercase">{t('speed')}</span>
<span className="text-xl md:text-2xl font-headline tracking-widest">{yacht.speed}</span>
</div>
</div>
</div>
</div>
{/* Editorial Content Section */}
<section className="pt-24 md:pt-24 pb-32 md:pb-48 px-6 md:px-12 overflow-hidden flex flex-col items-center justify-center w-full">
{/* Intro Block - Full Width Centered */}
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={staggerContainer}
className="max-w-4xl mx-auto text-center mb-32 md:mb-48"
>
<motion.span variants={fadeInUp} className="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-6 block">
{t('design_engineering')}
</motion.span>
<motion.h2 variants={fadeInUp} className="text-primary font-headline text-5xl md:text-8xl mb-8 leading-[1.05] tracking-tight">
{t('sanctuary_title1')} <br />
<span className="text-secondary italic">{t('sanctuary_title2')}</span>
</motion.h2>
<motion.div variants={fadeInUp} className="h-px w-16 bg-secondary mx-auto mb-12"></motion.div>
<motion.div variants={fadeInUp} className="flex justify-center gap-12 mb-12 font-label text-xs text-on-surface-variant uppercase tracking-widest">
<div className="text-center">
<span className="block text-[9px] text-outline mb-1">{t('builder')}</span>
<span className="font-medium text-primary">{yacht.builder}</span>
</div>
<div className="w-px h-8 bg-outline-variant/20"></div>
<div className="text-center">
<span className="block text-[9px] text-outline mb-1">{t('year_refit')}</span>
<span className="font-medium text-primary">{yacht.year} {yacht.refitYear && `(${yacht.refitYear})`}</span>
</div>
</motion.div>
<motion.p variants={fadeInUp} className="font-body text-on-surface-variant font-light text-lg md:text-xl leading-[2] max-w-2xl mx-auto mb-16">
{locale === 'tr' && yacht.description_tr ? yacht.description_tr : yacht.description}
</motion.p>
<motion.div variants={fadeInUp}>
<Link href="/contact" className="inline-block px-16 py-5 bg-secondary text-white font-headline tracking-[0.3em] uppercase text-xs hover:bg-primary transition-colors duration-500">
{t('inquire_btn')}
</Link>
</motion.div>
</motion.div>
{/* Specifications Grid - Modern Cards */}
<div className="max-w-[1440px] mx-auto space-y-32">
{/* 1. Construction & Design */}
{(yacht.construction || yacht.furniture) && (
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={staggerContainer}
className="flex flex-col items-center"
>
<motion.div variants={fadeInUp} className="flex flex-col items-center text-center mb-16">
<span className="font-headline text-7xl md:text-9xl text-outline-variant/8 font-bold leading-none mb-4">01</span>
<h3 className="font-headline text-xl md:text-2xl tracking-[0.3em] text-primary uppercase">{t('design_construction').replace(/0\d\s\/\s/, '')}</h3>
<div className="h-px w-12 bg-secondary mt-4"></div>
</motion.div>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 w-full">
{yacht.construction && Object.entries(yacht.construction).map(([key, value]) => (
<motion.div
key={key}
variants={fadeInUp}
className="bg-white p-8 border border-outline-variant/8 hover:border-secondary/30 hover:shadow-lg transition-all duration-500 group text-center"
>
<span className="font-label text-[9px] tracking-[0.3em] text-secondary uppercase block mb-3">
{key.replace(/([A-Z])/g, ' $1').trim()}
</span>
<span className="font-headline text-base md:text-lg text-primary tracking-tight block">
{value}
</span>
</motion.div>
))}
</div>
</motion.div>
)}
{/* 2. Equipment on Board */}
{yacht.equipment && yacht.equipment.length > 0 && (
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={staggerContainer}
className="flex flex-col items-center"
>
<motion.div variants={fadeInUp} className="flex flex-col items-center text-center mb-16">
<span className="font-headline text-7xl md:text-9xl text-outline-variant/8 font-bold leading-none mb-4">02</span>
<h3 className="font-headline text-xl md:text-2xl tracking-[0.3em] text-primary uppercase">{t('tech_equipment').replace(/0\d\s\/\s/, '')}</h3>
<div className="h-px w-12 bg-secondary mt-4"></div>
</motion.div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 w-full">
{yacht.equipment.map((item, idx) => (
<motion.div
key={idx}
variants={fadeInUp}
className="flex items-center gap-5 px-6 py-5 bg-white border border-outline-variant/8 hover:border-secondary/20 hover:shadow-md transition-all duration-500 group"
>
<div className="w-8 h-8 flex items-center justify-center bg-surface border border-outline-variant/10 group-hover:bg-secondary/10 group-hover:border-secondary/20 transition-all duration-500 shrink-0">
<span className="material-symbols-outlined text-secondary text-sm">check</span>
</div>
<span className="font-body text-sm text-primary/80 tracking-wide leading-snug">{item}</span>
</motion.div>
))}
</div>
</motion.div>
)}
{/* 3. Tenders & Toys */}
{yacht.watersports && yacht.watersports.length > 0 && (
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={staggerContainer}
className="flex flex-col items-center"
>
<motion.div variants={fadeInUp} className="flex flex-col items-center text-center mb-16">
<span className="font-headline text-7xl md:text-9xl text-outline-variant/8 font-bold leading-none mb-4">03</span>
<h3 className="font-headline text-xl md:text-2xl tracking-[0.3em] text-primary uppercase">{t('water_toys').replace(/0\d\s\/\s/, '')}</h3>
<div className="h-px w-12 bg-secondary mt-4"></div>
</motion.div>
<div className="flex flex-wrap justify-center gap-4">
{yacht.watersports.map((item, idx) => (
<motion.div
key={idx}
variants={fadeInUp}
className="px-8 py-5 bg-white border border-outline-variant/10 hover:border-secondary hover:shadow-lg transition-all duration-500 group cursor-default"
>
<div className="flex items-center gap-4">
<span className="material-symbols-outlined text-secondary/40 text-lg group-hover:text-secondary transition-colors duration-500">anchor</span>
<span className="font-headline text-xs tracking-[0.25em] text-primary uppercase group-hover:text-secondary transition-colors duration-500">{item}</span>
</div>
</motion.div>
))}
</div>
</motion.div>
)}
</div>
</section>
{/* Atelier Gallery Section */}
{yacht.gallery && yacht.gallery.length > 0 && (
<section className="py-24 md:py-32 bg-white">
<div className="flex flex-col items-center text-center mb-16">
<span className="font-label text-xs tracking-[0.4em] text-secondary uppercase block mb-4">{t('atelier_experience')}</span>
<h2 className="font-headline text-4xl md:text-5xl text-primary leading-tight uppercase tracking-widest">
{t('gallery')}
</h2>
</div>
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={staggerContainer}
className="w-full max-w-[1600px] mx-auto px-4 md:px-8 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-[400px]"
>
{yacht.gallery.map((imgUrl, index) => {
const isLarge = index === 0;
return (
<motion.div
key={index}
variants={fadeInUp}
onClick={() => openLightbox(index)}
className={`relative overflow-hidden group cursor-pointer ${isLarge ? 'md:col-span-2 lg:col-span-2 row-span-2' : 'col-span-1 row-span-1'}`}
>
<CldImage
src={imgUrl}
alt={`${yacht.name} Gallery ${index + 1}`}
fill
crop="fill"
gravity="auto"
className="object-cover transition-transform duration-1000 group-hover:scale-105"
/>
<div className="absolute inset-0 bg-black/10 group-hover:bg-transparent transition-colors duration-500 flex items-center justify-center">
<span className="material-symbols-outlined text-white text-3xl opacity-0 group-hover:opacity-80 transition-opacity duration-500">zoom_in</span>
</div>
</motion.div>
);
})}
</motion.div>
</section>
)}
{/* Charter Rates Section */}
{yacht.prices && yacht.prices.length > 0 && (
<section className="py-32 md:py-48 bg-[#0a0a0a] text-white overflow-hidden relative">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none select-none opacity-[0.02] w-full text-center">
<span className="font-headline text-[10rem] md:text-[20rem] font-bold leading-none tracking-tighter uppercase">RATES</span>
</div>
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={staggerContainer}
className="max-w-6xl mx-auto px-6 md:px-12 relative z-10"
>
<div className="flex flex-col items-center text-center mb-24 border-b border-white/10 pb-16">
<motion.span variants={fadeInUp} className="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-6 block">
Charter Investment
</motion.span>
<motion.h2 variants={fadeInUp} className="font-headline text-4xl md:text-6xl uppercase tracking-widest mb-6">
{t('rates')}
</motion.h2>
<motion.p variants={fadeInUp} className="font-label text-xs tracking-widest text-white/50 uppercase">
{t('rates_desc')}
</motion.p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-px bg-white/10 border border-white/10">
{yacht.prices.map((p) => (
<motion.div key={p.month} variants={fadeInUp} className="bg-[#0a0a0a] p-12 hover:bg-white/5 transition-colors duration-500 flex flex-col items-center justify-center text-center group">
<span className="block font-label text-[10px] tracking-[0.4em] text-secondary uppercase mb-4 transition-transform duration-500 group-hover:-translate-y-1">
{p.month}
</span>
<span className="text-3xl md:text-4xl font-headline tracking-tighter text-white">
{p.price}
</span>
</motion.div>
))}
</div>
<motion.div variants={fadeInUp} className="mt-16 text-center">
<p className="font-body text-xs text-white/40 leading-loose max-w-2xl mx-auto">
* {t('apa_note')} <br />
* {t('vat_note')}
</p>
</motion.div>
</motion.div>
</section>
)}
{/* Editorial Navigation */}
<section className="py-32 md:py-48 bg-surface text-center px-6 flex flex-col items-center justify-center">
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={staggerContainer}
className="flex flex-col items-center max-w-3xl"
>
<motion.span variants={fadeInUp} className="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-8 block">
{t('journey_title')}
</motion.span>
<motion.h2 variants={fadeInUp} className="text-primary font-headline text-4xl md:text-7xl mb-16 italic tracking-tight leading-[1.1]">
{t('ready_title')}
</motion.h2>
<motion.div variants={fadeInUp} className="flex flex-col md:flex-row items-center justify-center gap-6 w-full">
<Link href="/contact" className="px-12 py-5 bg-secondary text-white font-headline text-xs tracking-[0.3em] uppercase w-full md:w-auto hover:bg-primary transition-colors duration-500">
{t('start_inquiry_btn')}
</Link>
<Link href="/fleet" className="px-12 py-5 border border-primary/20 text-primary font-headline text-xs tracking-[0.3em] uppercase w-full md:w-auto hover:bg-primary hover:text-white transition-colors duration-500">
{t('explore_btn')}
</Link>
</motion.div>
</motion.div>
</section>
{/* Lightbox Overlay */}
<AnimatePresence>
{lightboxIndex !== null && yacht.gallery && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
className="fixed inset-0 z-[100] bg-black/95 flex items-center justify-center"
onClick={closeLightbox}
>
{/* Close Button */}
<button
onClick={closeLightbox}
className="absolute top-8 right-8 text-white/60 hover:text-white transition-colors z-[110]"
>
<span className="material-symbols-outlined text-4xl">close</span>
</button>
{/* Image Counter */}
<div className="absolute top-8 left-8 font-label text-xs tracking-[0.3em] text-white/50 uppercase z-[110]">
{lightboxIndex + 1} / {yacht.gallery.length}
</div>
{/* Previous Arrow */}
<button
onClick={(e) => { e.stopPropagation(); goPrev(); }}
className="absolute left-4 md:left-8 top-1/2 -translate-y-1/2 w-14 h-14 flex items-center justify-center text-white/40 hover:text-white transition-colors z-[110]"
>
<span className="material-symbols-outlined text-4xl">chevron_left</span>
</button>
{/* Next Arrow */}
<button
onClick={(e) => { e.stopPropagation(); goNext(); }}
className="absolute right-4 md:right-8 top-1/2 -translate-y-1/2 w-14 h-14 flex items-center justify-center text-white/40 hover:text-white transition-colors z-[110]"
>
<span className="material-symbols-outlined text-4xl">chevron_right</span>
</button>
{/* Main Image */}
<motion.div
key={lightboxIndex}
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.3 }}
className="relative w-[90vw] h-[80vh] max-w-[1400px]"
onClick={(e) => e.stopPropagation()}
>
<CldImage
src={yacht.gallery[lightboxIndex]}
alt={`${yacht.name} Gallery ${lightboxIndex + 1}`}
fill
crop="pad"
className="object-contain"
sizes="90vw"
priority
/>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</div>
);
}

View File

@@ -0,0 +1,76 @@
import { yachts } from "../../data/yachts";
import { Link } from "@/i18n/routing";
import { useTranslations, useLocale } from "next-intl";
import { CldImage } from "next-cloudinary";
export default function FleetPage() {
const t = useTranslations('FleetList');
const locale = useLocale();
return (
<div className="pt-40 pb-24 px-6 md:px-24 min-h-screen bg-surface">
<div className="max-w-7xl mx-auto">
<div className="flex flex-col md:flex-row items-end gap-16 mb-24">
<div className="w-full md:w-1/2">
<span className="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4 block">{t('collection')}</span>
<h1 className="font-headline text-5xl md:text-7xl text-primary leading-tight mb-8">
{t('title1')} <br />
<span className="text-secondary italic">{t('title2')}</span>
</h1>
<div className="h-px w-24 bg-secondary mb-8"></div>
<p className="font-body text-on-surface-variant text-lg leading-relaxed font-light">
{t('description')}
</p>
</div>
<div className="w-full md:w-1/2 flex justify-end">
<div className="text-right">
<span className="font-label text-6xl md:text-8xl text-outline-variant/30 font-bold leading-none uppercase">{t('bg_text')}</span>
</div>
</div>
</div>
<div className="space-y-40">
{yachts.map((yacht, index) => (
<div key={yacht.slug} className={`grid grid-cols-1 md:grid-cols-12 gap-0 group ${index % 2 !== 0 ? 'md:flex-row-reverse' : ''}`}>
<div className={`md:col-span-7 relative h-[500px] md:h-[700px] overflow-hidden ${index % 2 !== 0 ? 'md:order-2' : ''}`}>
<CldImage
src={yacht.heroImage}
alt={yacht.name}
fill
crop="fill"
gravity="auto"
className="w-full h-full object-cover transition-all duration-1000 scale-100 group-hover:scale-105"
/>
<div className="absolute inset-0 bg-primary/20 group-hover:bg-transparent transition-colors duration-700" />
</div>
<div className={`md:col-span-5 flex flex-col justify-center py-12 md:py-0 ${index % 2 !== 0 ? 'md:order-1 md:pr-20 md:text-right md:items-end' : 'md:pl-20'}`}>
<span className="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4">{t('masterpiece')}{index + 1}</span>
<h3 className="font-headline text-4xl md:text-5xl text-primary mb-8 tracking-wide uppercase">{yacht.name}</h3>
<p className="text-on-surface-variant font-light leading-relaxed mb-12 max-w-sm">
{locale === 'tr' && yacht.description_tr ? yacht.description_tr : yacht.description}
</p>
<div className="grid grid-cols-3 border-t border-outline-variant/20 pt-8 w-full text-left">
<div className="flex flex-col gap-1">
<span className="material-symbols-outlined text-secondary text-xl">straighten</span>
<span className="font-label text-[10px] tracking-widest text-outline uppercase mt-2">{t('length')}</span>
<span className="font-body text-sm text-primary font-semibold">{yacht.length}</span>
</div>
<div className="flex flex-col gap-1">
<span className="material-symbols-outlined text-secondary text-xl">groups</span>
<span className="font-label text-[10px] tracking-widest text-outline uppercase mt-2">{t('guests')}</span>
<span className="font-body text-sm text-primary font-semibold">{yacht.guests} {t('guests_suffix')}</span>
</div>
<div className="flex flex-col gap-1">
<Link href={`/fleet/${yacht.slug}`} className="mt-auto">
<span className="font-label text-[10px] tracking-widest text-secondary border-b border-secondary pb-1 uppercase hover:opacity-70 smooth-transition">{t('discover')}</span>
</Link>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
);
}

55
app/[locale]/layout.tsx Normal file
View File

@@ -0,0 +1,55 @@
import type { Metadata } from "next";
import { Inter, Oswald } from "next/font/google";
import "../globals.css";
import Navbar from "../components/Navbar";
import Footer from "../components/Footer";
import {NextIntlClientProvider} from 'next-intl';
import {getMessages} from 'next-intl/server';
const inter = Inter({
variable: "--font-inter",
subsets: ["latin"],
});
const oswald = Oswald({
variable: "--font-oswald",
subsets: ["latin", "latin-ext"],
});
export const metadata: Metadata = {
title: "Salmakis Yachting | Luxury Yacht Charters in Bodrum & Aegean",
description: "Experience the pinnacle of Aegean luxury with Salmakis Yachting. Premium yacht charters since 1980.",
keywords: ["yacht charter", "bodrum", "luxury yacht", "meira", "salmakis yachting"],
};
export default async function RootLayout({
children,
params
}: {
children: React.ReactNode;
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const messages = await getMessages();
return (
<html
lang={locale}
className={`${inter.variable} ${oswald.variable} h-full antialiased`}
>
<head>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet" />
</head>
<body className="min-h-full flex flex-col bg-white text-on-surface">
<NextIntlClientProvider messages={messages}>
<Navbar />
<main className="flex-grow">
{children}
</main>
<Footer />
</NextIntlClientProvider>
</body>
</html>
);
}

141
app/[locale]/page.tsx Normal file
View File

@@ -0,0 +1,141 @@
'use client';
import { Link } from '@/i18n/routing';
import { yachts } from '../data/yachts';
import YachtCard from '../components/YachtCard';
import { motion } from 'framer-motion';
import { useTranslations } from 'next-intl';
export default function Home() {
const t = useTranslations('Home');
const fadeInUp = {
hidden: { opacity: 0, y: 40 },
visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } }
};
return (
<>
<header className="relative h-screen w-full overflow-hidden">
{/* YouTube Video Background */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1.5 }}
className="absolute inset-0 z-0 pointer-events-none overflow-hidden bg-black"
>
<iframe
className="absolute top-1/2 left-1/2 w-[115vw] h-[115vh] min-w-[177.77vh] min-h-[56.25vw] -translate-x-1/2 -translate-y-1/2"
src="https://www.youtube.com/embed/0k4s7X8EgYI?autoplay=1&mute=1&controls=0&loop=1&playlist=0k4s7X8EgYI&showinfo=0&rel=0&modestbranding=1&playsinline=1&enablejsapi=1&vq=hd1080"
allow="autoplay; encrypted-media"
frameBorder="0"
></iframe>
{/* Elegant Overlay */}
<div className="absolute inset-0 bg-gradient-to-b from-primary/60 via-primary/20 to-primary/80"></div>
<div className="absolute inset-0 bg-black/10 backdrop-blur-[1px]"></div>
</motion.div>
<div className="relative h-full flex flex-col items-center justify-center text-center px-6">
{/* Text overlays removed for cinematic look */}
</div>
</header>
{/* Fiziksel Boşluk Ayırıcı - Üst */}
<div className="h-24 md:h-32"></div>
<section className="py-24 px-6 bg-surface overflow-hidden relative flex flex-col items-center justify-center text-center">
{/* Decorative Background Element */}
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
whileInView={{ opacity: 0.03, scale: 1 }}
transition={{ duration: 1.5 }}
viewport={{ once: true }}
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none select-none w-full text-center"
>
<span className="font-headline text-[15rem] md:text-[24rem] font-bold leading-none tracking-tighter text-primary">1980</span>
</motion.div>
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={{
visible: { transition: { staggerChildren: 0.2 } }
}}
className="max-w-4xl mx-auto relative z-10 flex flex-col items-center"
>
<motion.div variants={fadeInUp} className="mb-8 flex flex-col items-center gap-4">
<span className="font-label text-xs tracking-[0.4em] text-secondary uppercase">{t('established')}</span>
<div className="h-px w-12 bg-secondary/40"></div>
</motion.div>
<motion.div variants={fadeInUp}>
<h2 className="font-headline text-4xl md:text-7xl text-primary leading-[1.1] mb-16 tracking-tight">
{t('title_main')} <br />
<span className="text-secondary italic">{t('title_italic')}</span>
</h2>
</motion.div>
<motion.div variants={fadeInUp}>
<p className="font-body text-on-surface-variant text-lg md:text-xl leading-[2] font-light max-w-3xl mx-auto text-justify [text-align-last:center]">
{t('description')}
</p>
</motion.div>
</motion.div>
</section>
{/* Fiziksel Boşluk Ayırıcı - Alt */}
<div className="h-24 md:h-32"></div>
{/* Fleet Section */}
<section className="pb-48 px-6 md:px-12 bg-white flex flex-col items-center">
<div className="w-full max-w-[1440px] mx-auto flex flex-col items-center">
{/* Section Header */}
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
variants={fadeInUp}
className="flex flex-col items-center text-center"
>
<span className="font-label text-xs tracking-[0.4em] text-secondary uppercase block mb-4">Our Selection</span>
<h2 className="font-headline text-4xl md:text-6xl text-primary leading-tight uppercase">
{t('featured_fleet')} <span className="italic">{t('featured_fleet_italic')}</span>
</h2>
</motion.div>
{/* Kesin Boşluk Ayırıcı */}
<div className="h-16 md:h-24"></div>
{/* Cards Grid (3 on top, 2 centered on bottom) */}
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={{
visible: { transition: { staggerChildren: 0.15 } }
}}
className="flex flex-wrap justify-center gap-x-12 gap-y-24 w-full"
>
{yachts.map((yacht) => (
<motion.div
key={yacht.slug}
variants={fadeInUp}
className="w-full md:w-[calc(50%-3rem)] lg:w-[calc(33.333%-3rem)]"
>
<YachtCard yacht={yacht} />
</motion.div>
))}
</motion.div>
</div>
</section>
{/* Ekstra Alt Boşluk */}
<div className="h-32 md:h-48"></div>
</>
);
}

View 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>
);
}

View 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
View 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
View 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
View 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>
);
}

View 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>
);
}

View 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>
);
}

323
app/data/yachts.ts Normal file
View File

@@ -0,0 +1,323 @@
export interface Yacht {
slug: string;
name: string;
tagline: string;
tagline_tr?: string;
length: string;
lengthFt: string;
guests: string;
cabins: string;
crew: string;
speed: string;
year: string;
refitYear?: string;
builder: string;
description: string;
description_tr?: string;
heroImage: string;
gallery: string[];
weeklyPrice: string;
award?: string;
prices: { month: string; price: string }[];
// New Detailed Specs
construction?: {
hull?: string;
superstructure?: string;
exteriorDesign?: string;
interiorDesign?: string;
navalArchitecture?: string;
class?: string;
paint?: string;
flag?: string;
};
furniture?: string;
equipment?: string[];
watersports?: string[];
}
export const yachts: Yacht[] = [
{
slug: 'meira',
name: 'M/S MEIRA',
tagline: 'The Ultimate Sailing Masterpiece',
length: '55m',
lengthFt: '(180ft)',
guests: '12',
cabins: '6',
crew: '10',
speed: '14 Knots',
year: '2018',
refitYear: '2023',
builder: 'NETA MARINE',
description: 'The 55-meter MEIRA offers extraordinary space for 12 guests above and below deck. Home automation in all cabins. Main deck features a large saloon, four sunbathing areas, pool, and bar. Includes a massage room and sauna for ultimate relaxation.',
description_tr: '55 metre uzunluğunda ve altı kabinli MEIRA, 12 misafir için güverte üstü ve altında olağanüstü bir alan sunmaktadır. Ana güvertede büyük bir ana kabin, 3 VIP kabin ve 2 ikiz kabin mevcuttur. Tüm kabinlerde ev otomasyon sistemi, masaj odası ve sauna bulunmaktadır.',
heroImage: 'salmakisyat/meira/MEIRA-2000x1333',
gallery: [
'salmakisyat/meira/GUEST-CABIN-3-1-1024x680',
'salmakisyat/meira/MASTER-CABIN-4-1024x680',
'salmakisyat/meira/MS-MEIRA-53-1-1024x683',
'salmakisyat/meira/MS-MEIRA-58-1024x683',
'salmakisyat/meira/PSU3709-1024x683',
'salmakisyat/meira/VIP-CABIN-1-1024x680'
],
weeklyPrice: '€125,000',
award: 'WORLD SUPERYACHT AWARDS 2024 WINNER',
prices: [
{ month: 'May', price: '€110,000' },
{ month: 'June', price: '€120,000' },
{ month: 'July', price: '€155,000' },
{ month: 'August', price: '€155,000' },
{ month: 'September', price: '€120,000' },
{ month: 'October', price: '€110,000' }
],
construction: {
hull: 'Steel',
superstructure: 'Steel',
exteriorDesign: 'Evan K. Marshall',
interiorDesign: 'Evan K. Marshall',
navalArchitecture: 'Fuat Turan',
class: 'RINA 100-A-1-1-Y',
paint: 'Tekno Marin',
flag: 'Turkish / Commercial / Unrestricted Navigation'
},
furniture: 'Oak wood and Smoked Oak with marble, leather and art work decoration.',
equipment: [
'LED TVs in Saloon, Sky Lounge, and all cabins',
'Wi-Fi connection, Sonos music system',
'Home Theater System in all cabins',
'Playstation & Computer games',
'Full sail equipment',
'Radar, GPS, VHF, Navtex, Sart, Epirb',
'AIS system, Depth Sounder, Water Maker',
'Full regulation safety equipment'
],
watersports: [
'Speedboat with >100 HP Engine',
'Windsurf, Canoe, Wakeboard',
'Paddleboard',
'Waterski, Ringo',
'Snorkeling & Fishing Equipment',
'Jetski'
]
},
{
slug: 'princess-melda',
name: 'M/Y PRINCESS MELDA',
tagline: 'Modern Elegance on the Waves',
length: '45m',
lengthFt: '(148ft)',
guests: '10',
cabins: '5',
crew: '8',
speed: '18 Knots',
year: '2020',
refitYear: '2025',
builder: 'CUSTOM BUILD',
description: 'Princess Melda offers a sleek, modern aesthetic with expansive deck spaces and a light, airy interior. Perfect for families seeking a high-speed luxury experience.',
description_tr: 'Prenses Melda, geniş güverte alanları ve aydınlık, ferah iç mekanıyla şık, modern bir estetik sunar. Yüksek hızlı bir lüks deneyim arayan aileler için mükemmeldir.',
heroImage: 'salmakisyat/melda/yuzen-yat-2000x1125',
gallery: [
'salmakisyat/melda/masteryeni2-768x432',
'salmakisyat/melda/master3-768x432',
'salmakisyat/melda/master4-768x432',
'salmakisyat/melda/twin1-768x432',
'salmakisyat/melda/balkon4-768x432',
'salmakisyat/melda/mastertuvalet-768x432'
],
weeklyPrice: '€110,000',
prices: [
{ month: 'May', price: '€110,000' },
{ month: 'June', price: '€120,000' },
{ month: 'July', price: '€165,000' },
{ month: 'August', price: '€165,000' },
{ month: 'September', price: '€120,000' },
{ month: 'October', price: '€110,000' }
],
construction: {
hull: 'Steel',
superstructure: 'Aluminium',
exteriorDesign: 'Guido de Groot',
interiorDesign: 'Guido de Groot',
paint: 'Tekno Marin',
flag: 'Turkish / Commercial / Unrestricted Navigation'
},
furniture: 'Oak wood and Smoked Oak with marble, leather and art work decoration.',
equipment: [
'LED TVs in Saloon and all cabins',
'Wi-Fi connection',
'Home Theater System in all cabins',
'Professional music systems',
'Playstation & Computer games',
'Argus Radar, GPS, VHF, Navtex, Sart, Epirb, AIS, Depth Sounder, GMDSS',
'2 x 400 lt Watermaker / Selmar',
'Full regulation safety equipment'
],
watersports: [
'1 Speed Boat with 140 HP Engine',
'1 Speed Boat with 90 HP Engine',
'Windsurf, Canoe, Wakeboard',
'2 x Paddleboard',
'Snorkelling & Fishing Equipment',
'Waterski',
'Ringo',
'Sea Slider',
'1 x Seabob',
'1 x Jet Ski'
]
},
{
slug: 'queen-of-salmakis',
name: 'QUEEN OF SALMAKIS',
tagline: 'The Grand Dame of the Aegean',
length: '40m',
lengthFt: '(131ft)',
guests: '18',
cabins: '8',
crew: '7',
speed: '12 Knots',
year: '2018',
builder: 'SALMAKIS YACHTING',
description: 'A traditional Turkish gulet reimagined for modern luxury. Queen of Salmakis is ideal for large groups and celebrations, offering unmatched stability and space, complete with a deck jacuzzi.',
description_tr: '40 metrelik yepyeni ahşap yelkenli yat Kraliçe Salmakis, lüks ve modern tasarımlı bir gulettir. 8 lüks kabininde 18 konuğa kadar ağırlayabilmektedir. Hem Türkiye\'de hem de Yunanistan\'da büyük gruplara üstün bir konaklama imkanı sunmaktadır. Güvertede jakuzi bulunmaktadır.',
heroImage: 'salmakisyat/queenofsalmakis/QOS-yelkenli-beyaz-7-2000x1333',
gallery: [
'salmakisyat/queenofsalmakis/QOS-AFTDECK-1',
'salmakisyat/queenofsalmakis/QOS-FOREDECK-6',
'salmakisyat/queenofsalmakis/QOS-cabin-BOW-MASTER-7',
'salmakisyat/queenofsalmakis/kic-master-lumboz-1',
'salmakisyat/queenofsalmakis/QOS-guverte-FOREDECK-2-scaled'
],
weeklyPrice: '€38,500',
prices: [
{ month: 'May', price: '€38,500' },
{ month: 'June', price: '€56,500' },
{ month: 'July', price: '€74,000' },
{ month: 'August', price: '€74,000' },
{ month: 'September', price: '€56,500' },
{ month: 'October', price: '€38,500' }
],
construction: {
hull: 'Laminated Wood',
flag: 'Turkey',
class: 'Turkish Loyd'
},
equipment: [
'2 x Main Engines',
'Deck Jacuzzi',
'Full Sail Equipment (2 Masts)',
'Wi-Fi connection',
'Air conditioning',
'Entertainment systems in all cabins'
],
watersports: [
'Speedboat',
'Watersports toys',
'Jetski (optional)'
]
},
{
slug: 'dolce-mare',
name: 'DOLCE MARE',
tagline: 'The Sweet Life on the Riviera',
length: '36m',
lengthFt: '(118ft)',
guests: '12',
cabins: '6',
crew: '6',
speed: '14 Knots',
year: '2012',
refitYear: '2021',
builder: 'CUSTOM',
description: 'Experience \'La Dolce Vita\' on the Turkish Riviera. An intimate vessel perfect for multi-generational family escapes, combining classic elegance with modern amenities and a deck jacuzzi.',
description_tr: '36 metre uzunluğunda ve 6 kabinli Dolce Mare yat, iki büyük ana kabin de dahil olmak üzere 12 misafir için olağanüstü bir alan sunmaktadır. Ana kabinlerde king size yatak, kanepe, jakuzili küvet ve ayrı bir banyo bulunur. Diğer kabinler yerel mermer detaylara sahip şık banyolara sahiptir. Tüm kabinlerde uydu TV ve ev sinema sistemi mevcuttur.',
heroImage: 'salmakisyat/dolcemare/Dolce-Mare-90-2000x1328',
gallery: [
'salmakisyat/dolcemare/Dolce-Mare-33-1024x680',
'salmakisyat/dolcemare/Dolce-Mare-57-1024x680',
'salmakisyat/dolcemare/Dolce-Mare-63-1024x680',
'salmakisyat/dolcemare/Dolce-Mare-66-1024x680',
'salmakisyat/dolcemare/Dolce-Mare-80-1024x680',
'salmakisyat/dolcemare/Dolce-Mare-12-1024x680'
],
weeklyPrice: '€32,500',
prices: [
{ month: 'May', price: '€32,500' },
{ month: 'June', price: '€42,000' },
{ month: 'July', price: '€54,000' },
{ month: 'August', price: '€54,000' },
{ month: 'September', price: '€42,000' },
{ month: 'October', price: '€32,500' }
],
equipment: [
'Satellite navigation & TV channels',
'LED TVs in saloon and all cabins',
'PC with Wi-Fi connection',
'5+1 Home Theater in all cabins',
'Sonos music system',
'Washing machine, Dishwasher',
'Full sail equipment',
'Radar, GPS, AIS-CLASS A, VHF, Navtex, Sart, EPIRB',
'Water maker, Smoke detector',
'Jacuzzi on deck, master cabins, and triple cabins'
],
watersports: [
'115 HP Speedboat',
'Canoe, Windsurf',
'Waterski, Ringo, Wakeboard, Sea Scooter',
'Snorkeling & Fishing equipment',
'Jetski (optional)'
]
},
{
slug: 'sunworld-8',
name: 'SUNWORLD-8',
tagline: 'Classic Gulet Experience',
length: '30m',
lengthFt: '(98ft)',
guests: '19',
cabins: '8',
crew: '4',
speed: '10 Knots',
year: '2008',
refitYear: '2019',
builder: 'SUNWORLD SAILING',
description: 'A beautifully maintained classic Turkish gulet. Sunworld-8 offers an authentic blue cruise experience with spacious deck areas and a warm, wooden interior. Designed especially for the charter market.',
description_tr: 'Sunworld-8 yatı, 30 metre uzunluğunda, klimalı, geleneksel ahşap bir gulettir. Özellikle kiralama pazarı için tasarlanmıştır. Beş adet çift kişilik, üç adet üç kişilik (çift+tek yatak) kabinlerde 19 kişiye kadar konaklama imkanı sunar.',
heroImage: 'salmakisyat/sunworld/784ff3f3e0fa5982c77288ecf6612842',
gallery: [
'salmakisyat/sunworld/bodrum-sunworld-8-kiralik-gulet-5',
'salmakisyat/sunworld/Saloon',
'salmakisyat/sunworld/Double-Bed-Cabin',
'salmakisyat/sunworld/Triple-Bed-Cabin',
'salmakisyat/sunworld/Sunbeds-on-Deck',
'salmakisyat/sunworld/Sitting-Area'
],
weeklyPrice: '€12,000',
prices: [
{ month: 'May', price: '€12,000' },
{ month: 'June', price: '€14,500' },
{ month: 'July', price: '€18,500' },
{ month: 'August', price: '€18,500' },
{ month: 'September', price: '€14,500' },
{ month: 'October', price: '€12,000' }
],
equipment: [
'Air Conditioning',
'TV & DVD player, CD music system',
'PC, Internet',
'Deep freezer, Ice maker, Water maker',
'Washing machine, Dishwasher',
'Radar, GPS, EPIRB, SART, SSAS, AIS-CLASS A',
'Depth & Fish finder',
'Electric WC',
'Smoke detector & Fire safety equipment'
],
watersports: [
'60 HP Speedboat',
'Windsurf, Canoe',
'Snorkeling & Fishing equipment',
'Full sail equipment'
]
}
];

View File

@@ -1,26 +1,155 @@
@import "tailwindcss";
:root {
--background: #ffffff;
--foreground: #171717;
/* Backgrounds & Foregrounds */
--background: #f9f9f9;
--foreground: #1a1c1c;
/* Retain for custom CSS */
--midnight-blue: #020B1A;
--sand-beige: #D4C3A3;
--gold: #C5A059;
--soft-grey: #F8F9FA;
--white: #FFFFFF;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-midnight: #020B1A;
--color-sand: #D4C3A3;
--color-gold: #C5A059;
--color-soft-grey: #F8F9FA;
/* Stitch Design System */
--color-primary: #000613;
--color-primary-container: #001f3f;
--color-secondary: #775a19;
--color-on-secondary-container: #785a1a;
--color-surface: #f9f9f9;
--color-on-surface: #1a1c1c;
--color-on-surface-variant: #43474e;
--color-outline-variant: #c4c6cf;
--color-outline: #74777f;
/* Map old font families from code.html to our current font variables */
--font-headline: var(--font-oswald), serif;
--font-body: var(--font-inter), sans-serif;
--font-label: var(--font-inter), sans-serif;
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
/* Tailwind's preflight handles box-sizing and resets.
We only add box-sizing for safety, NOT margin/padding reset. */
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
background-color: var(--background);
color: var(--foreground);
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
font-family: var(--font-inter), sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Fluid Typography — only for semantic headings, not Tailwind classes */
h1 {
font-family: var(--font-oswald), sans-serif;
font-weight: 200;
line-height: 1.1;
}
h2 {
font-family: var(--font-oswald), sans-serif;
font-weight: 300;
line-height: 1.2;
}
h3, h4, h5, h6 {
font-family: var(--font-oswald), sans-serif;
font-weight: 500;
}
.luxury-text {
letter-spacing: 0.1em;
text-transform: uppercase;
}
/* Animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes zoom {
from {
transform: scale(1);
}
to {
transform: scale(1.15);
}
}
.fade-in-up {
animation: fadeInUp 0.8s ease-out forwards;
}
/* Transitions */
.smooth-transition {
transition: all 0.3s ease;
}
/* Buttons */
.btn-hollow {
padding: 0.75rem 1.5rem;
border: 1px solid var(--midnight-blue);
background: transparent;
color: var(--midnight-blue);
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.875rem;
cursor: pointer;
transition: all 0.3s ease;
}
.btn-hollow:hover {
background: var(--midnight-blue);
color: var(--white);
}
.btn-gold {
padding: 1rem 2rem;
background: var(--gold);
color: var(--white);
border: none;
text-transform: uppercase;
letter-spacing: 2px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.btn-gold:hover {
background: #b49140;
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(197, 160, 89, 0.3);
}

View File

@@ -1,33 +0,0 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html
lang="en"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
>
<body className="min-h-full flex flex-col">{children}</body>
</html>
);
}

View File

@@ -1,65 +0,0 @@
import Image from "next/image";
export default function Home() {
return (
<div className="flex flex-col flex-1 items-center justify-center bg-zinc-50 font-sans dark:bg-black">
<main className="flex flex-1 w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={100}
height={20}
priority
/>
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
To get started, edit the page.tsx file.
</h1>
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
Looking for a starting point or more instructions? Head over to{" "}
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Templates
</a>{" "}
or the{" "}
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Learning
</a>{" "}
center.
</p>
</div>
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
<a
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={16}
height={16}
/>
Deploy Now
</a>
<a
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Documentation
</a>
</div>
</main>
</div>
);
}