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

55
Dockerfile Normal file
View File

@@ -0,0 +1,55 @@
# 1. Base image
FROM node:20-alpine AS base
# 2. Dependencies
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json package-lock.json* ./
RUN npm ci --legacy-peer-deps
# 3. Builder
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Environment variables must be present at build time for Next.js
# Coolify will provide these, but we can set defaults
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
# 4. Runner
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
# set hostname to localhost
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]

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

41
docs/dolcemare.md Normal file
View File

@@ -0,0 +1,41 @@
36 metre uzunluğunda ve 6 kabinli Dolce Mare yat, iki büyük ana kabin de dahil olmak üzere 12 misafir için güverte üstü ve güverte altı alanlarda olağanüstü bir alan sunmaktadır. Ana kabinlerde king size yataklar, kanepe oturma grubu ve çalışma masası/makyaj masası bulunmaktadır. Bu kabinde ayrıca jakuzili küvet ve ayrı bir banyo da mevcuttur. İki üç kişilik kabinde bir tek kişilik ve bir çift kişilik yatak, çalışma masası/makyaj masası ve jakuzili küvetli özel banyo bulunmaktadır. Diğer iki misafir kabininde ise büyük yuvarlak çift kişilik yataklar ve çalışma masası/makyaj masası mevcuttur. Gardırop alanı oldukça geniştir ve şık özel banyolar, modern ve zarif duş, lavabo ve tuvalet armatürleriyle yerel mermerle döşenmiştir. Tüm kabinlerde uydu TV, DVD oynatıcı ve ev sinema sistemi lüksü bulunmaktadır. Yatın tamamında isteğe bağlı olarak klima/ısıtma ve temiz hava sağlanmaktadır.
Genişlik, konfor ve şıklık duygusu, serin akşamlarda konukların yemek yiyip ardından rahat koltuklarda dinlenebileceği salona da yansıyor. Plazma ekran TV, DVD oynatıcı, kablosuz internet bağlantısı ve arka güverteye aktarılabilecek mükemmel müzik sistemi ile eğlence konusunda hiçbir eksiklik yok. Elbette ılık Türk gecelerinde arka güverteden daha iyi bir yer yok. 12 kişiye kadar konuk, masa etrafında rahatça oturabilir ve yemekten sonra minderlere yaslanabilir.
Dolce Mare guleti, navigasyon, yelken ve manevra kolaylığı için en son teknolojiyle donatılmıştır. Demir atıldığında, aktif olmayı sevenler için bol miktarda su oyuncağı mevcuttur. Geniş minderli ön güverte, konukların güneşte veya gölgede dinlenmelerine veya güvertedeki jakuzide serinlemelerine olanak tanır. Akşam yemeğinden önce içecekler için pruvada oturma alanı da ek bir özelliktir.
Ekibimiz, kaptan, aşçı, hostes ve üç denizci olmak üzere altı kişiden oluşmaktadır ve misafirlerin güvenliği ve konforu için son derece eğitimli ve özverilidirler. Yemek pişirme, temizlik, servis ve günlük aktivitelerin düzenlenmesi dahil olmak üzere eksiksiz bir hizmet sunacaklardır. Son teknoloji ürünü soğutma sistemi ve pişirme olanaklarıyla tam donanımlı mutfakta mükemmel yemekler hazırlanacaktır. Ekip, misafirlerin hizmetlerine ihtiyaç duyduklarını içgüdüsel olarak bilir ve mahremiyet tercih edildiğinde sessizce geri çekilir. Kendilerine ait ayrı konaklama ve banyo olanaklarına sahiptirler.
Dolce Mare yatının Türk kıyılarında en çok rağbet gören yatlardan biri olacağı kesin.
GEMİDEKİ EKİPMANLAR
• Uydu navigasyon ve televizyon kanalları
• Salonda ve tüm kabinlerde LED TV
• Kablosuz internet bağlantılı bilgisayar
• Tüm kabinlerde 5+1 ev sinema sistemi
• Sonos müzik sistemi
• Çamaşır makinesi, bulaşık makinesi
• Tam yelken ekipmanı
• Radar, GPS, AIS-A SINIFI, VHF, Navtex, Shart, EPIRB, SSAS, derinlik ölçer ve balık bulucu
• Su yapıcı
• Tam yönetmeliklere uygun güvenlik ekipmanı
• Balıılık ekipmanı, şnorkelli yüzme ekipmanı
• Duman dedektörü
• 115 hp motorlu sürat teknesi
• Kano, rüzgar sörfü
• Su kayağı, Ringo, Wakeboard, Deniz Scooterı
• Jetski (isteğe bağlı)
• Güvertede, ana kamaralarda ve üç kişilik kamaralarda jakuzi bulunmaktadır.
Aşağıdaki fiyatlar Euro cinsinden, haftalık ve Cumartesi kalkışlıdır.
MAYIS HAZİRAN TEMMUZ AĞUSTOS EYLÜL EKİM
32500 € 42000 € 54000 € 54000 € 42.000 € 32.500 €
Fiyatlarımıza yakıt, yiyecek, içecek, KDV, özel liman ücretleri, transfer, bot yakıtı ve
su sporları dahil değildir. Jet ski günlük 250 Euro'dur.

52
docs/meira.md Normal file
View File

@@ -0,0 +1,52 @@
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 kabinde king size yatak, üç büyük VIP kabinde çift kişilik yatak ve iki büyük kabinde ikiz yatak bulunmaktadır; bu ikiz yataklar tek büyük bir çift kişilik yatak veya iki ayrı büyük tek kişilik yatak olarak kullanılabilir (biri tek kişilik (100cm*200cm), diğeri çift kişilik (130cm*200cm)). Tüm kabinlerde ev otomasyon sistemi mevcuttur; klima, perdeler, ışıklar ve eğlence sistemi kontrol edilebilir.
Ana güvertede yemek alanı ve kanepeler bulunan büyük bir salon, dört güneşlenme alanı, flybridge güvertesinde bir havuz ve bar, kanepeler ve yemek alanı bulunan çok büyük ve konforlu bir gökyüzü salonu bulunmaktadır.
Gemide ayrıca misafirlerin son derece rahatlatıcı bir zaman geçirmelerini sağlamak için bir masaj odası ve bir sauna da bulunmaktadır.
YAPI
Gövde: Çelik, Üst yapı: Çelik
DIŞ TASARIM: Evan K. Marshall
İÇ MEKAN TASARIMI: Evan K. Marshall
DENİZ MİMARİSİ : Fuat Turan
SINIFLANDIRMALAR VE GÖSTERİMLER
Gemi, RINA kurallarına uygun olarak ve “100-A-1-1-Y” sınıflandırma notasyonuyla inşa edilecektir.
GEMİDEKİ EKİPMANLAR
Salonda, Sky Lounge'da ve tüm kabinlerde LED TV'ler bulunmaktadır.
Wi-Fi bağlantısı, Sonos müzik sistemi
Tüm kabinlerde ev sinema sistemi mevcuttur.
Playstation, Bilgisayar oyunları
Tam yelken ekipmanı
Radar, GPS, Vhf, Navtex, Shart, Epirp
AIS sistemi, derinlik ölçer ve bulucu, su yapıcı
Tam yönetmelikli güvenlik ekipmanı
100 beygirin üzerinde motora sahip sürat teknesi
Rüzgar sörfü, Kano, Wakeboard
Kürek sörfü, Su kayağı, Ringo
Şnorkelli yüzme ve balıılık ekipmanları
Jetski
MAYIS HAZİRAN TEMMUZ AĞUSTOS EYLÜL EKİM
110.000 € 120.000 € 155.000 € 155.000 € 120.000 € 110.000 €
MYBA şartları kabul edilebilir ve APA sistemi uygulanmaktadır. Yakıt
, yiyecek, içecek, transfer ve diğer tüm masraflar APA tarafından karşılanacaktır.

68
docs/melda.md Normal file
View File

@@ -0,0 +1,68 @@
YAPI
Gövde: Çelik
Üst yapı: Alüminyum
Dış Tasarım:Guido de Groot
İç Tasarım: Guido de Groot
Boya: Tekno Marin
Bayrak: Türk/Ticari/Sınırsız
Navigasyon
Mobilya
Meşe ağacı ve füme meşe, mermerle birlikte.
deri ve sanat eseri dekorasyonu
Gemideki Ekipmanlar
Salonda ve tüm kabinlerde LED TV'ler mevcuttur.
Wi-Fi bağlantısı
Tüm kabinlerde ev sinema sistemi mevcuttur.
Profesyonel müzik sistemleri
Playstation, Bilgisayar oyunları
Argus Radar, GPS, VHF, Navtex, Sart,
EPIRB, AIS, Derinlik Ölçer, GMDSS
2*400 lt Su Arıtma Cihazı/Selmar
Tam yönetmelikli güvenlik ekipmanı
Gemide Su Sporları ve Oyuncaklar
140 HP motorlu 1 hızlı tekne
90 HP motorlu 1 hızlı tekne
Rüzgar sörfü, Kano, Wakeboard,
2 x Kürek tahtası,
Şnorkelli Dalış ve Balıılık Ekipmanları
Su kayağı
Ringo
Deniz Kaydırağı
1 x Seabob
1 x Jetski
MAYIS. HAZİRAN TEMMUZ AĞUSTOS EYLÜL EKİM
110.000 € 120.000 € 165.000 € 165.000 € 120.000 € 110.000 €

64
docs/prd.md Normal file
View File

@@ -0,0 +1,64 @@
Ürün Gereksinim Dokümanı (PRD): Salmakis Yachting V2
1. Proje Genel Bakış
Amaç: Mevcut karmaşık ve eski yapıyı, lüks yat kiralama sektörünün (Burgess, Fraser gibi) standartlarına taşıyan, görsel odaklı ve prestijli bir web sitesi oluşturmak.
Hedef Kitle: Yüksek gelirli yerli/yabancı turistler, acenteler ve VIP tatil planlayıcıları.
2. Sayfa Yapıları ve Fonksiyonlar
A. Global Navbar (Navigasyon Çubuğu)
Logo: Sol tarafta minimal, yüksek çözünürlüklü (SVG) Salmakis Yachting logosu.
Filo Menüsü (Yat İsimleri): Navbar'da "Fleet" (Filo) üzerine gelindiğinde veya direkt menüde şu isimler şık bir tipografiyle listelenir:
M/S MEIRA
M/Y PRINCESS MELDA
QUEEN OF SALMAKIS
DOLCE MARE
SUNWORLD-8
Sağ Taraf: Dil seçici (EN | TR), İletişim butonu (Hollow button stili).
B. Landing Page (Giriş Sayfası)
Hero Section: Ekranı %100 kaplayan (Full-bleed), sessiz, drone ile çekilmiş yat videoları. Üzerinde sadece: "The Pinnacle of Aegean Luxury" (Ege Lüksünün Zirvesi).
Value Proposition (Değer Önerisi): "Since 1980" vurgusuyla grubun güvenilirliği ve 5 yıldızlı yüzen otel konsepti kısa, vurucu bir metinle anlatılır.
Quick Fleet Preview: Üç ana yatın büyük, yan yana kartlar (cards) halinde ön izlemesi.
Destinations (Kısa Geçiş): Bodrum, Göcek, Yunan Adaları gibi rotalara dair estetik bir görsel blok.
C. Filo & Yat Detay Sayfası (Kombine Yapı)
Her yatın sayfası bir "Digital Sales Pitch" gibi çalışmalıdır.
Teknik Özet Barı: Sayfanın başında ikonlarla: Boy (55m) | Misafir (12) | Kabin (6) | Mürettebat (10) | Hız (14 Knots).
Görsel Deneyim: * Interior Gallery: Tam ekran, yüksek kaliteli iç mekan fotoğrafları.
Lifestyle Shots: Yemek masası, jakuzi keyfi gibi "duygu" uyandıran kareler.
Teknik Detay Tablosu (Modernize): Kat planı (Deck plan), su oyuncakları (Seabob, Jet Ski vb.) ve eğlence sistemleri (Sonos, Home Theater) şık ikonik kutucuklar içinde.
Fiyat Paneli: Aylık fiyat tablosu (Mayıs - Ekim) temiz bir grid yapısında, KDV ve APA detayları dipnot olarak.
D. İletişim Sayfası
Hızlı Form: "Hangi yatla ilgileniyorsunuz?", "Tarih aralığınız nedir?" gibi seçmeli alanları olan minimal bir form.
Direct Contact: WhatsApp butonu, Google Maps entegrasyonu (Bodrum Merkez Ofis) ve direkt arama butonları.
3. Tasarım İlkeleri (UI Guidelines)
Renk Paleti: Gece Mavisi (Midnight Blue), Kum Beji (Sand Beige) ve detaylarda Altın (Gold). Arka planlar temiz beyaz veya çok açık gri (Soft Grey).
Tipografi: Başlıklar için lüks hissettiren Serif fontlar (örn: Cormorant Garamond), gövde metinleri için modern Sans-serif (örn: Inter veya Montserrat).
Animasyonlar: Sayfa aşağı kaydırıldığında görsellerin yumuşakça belirmesi (Fade-in up), butonların üzerine gelince zarifçe parlaması.
4. Teknik Gereksinimler
Hız (Performance): Resimler WebP/AVIF, videolar CDN üzerinden servis edilmeli. LCP (Largest Contentful Paint) < 2.5s olmalı.
SEO: Her yat sayfası için özel meta tag'ler (örn: "M/S Meira Luxury Charter Bodrum").
Mobil Uyumluluk: Yat galerileri mobilde kaydırılabilir (swipe) ve tam ekran açılabilir olmalı

54
docs/queensalmakis.md Normal file
View File

@@ -0,0 +1,54 @@
40 metrelik yepyeni ahşap yelkenli yat Kraliçe Salmakis, lüks ve modern tasarımlı bir gulettir. 2 direğiyle yelken açmaya tam donanımlı olan Kraliçe Salmakis, şık ve güzel tasarlanmış 8 kabininde (2 ana kabin, 4 çift kişilik ve 2 üç kişilik kabin - bir çift kişilik + bir tek kişilik yatak) 18 konuğa kadar ağırlayabilmektedir. Hem Türkiye'de hem de Yunanistan'da kalabalık özel gruplara üstün bir konaklama imkanı sunmaktadır.
Kabin tasarımında yarı ahşap, yarı süet kombinasyonu kullanılmış olup, diğer alışılagelmiş gulet tasarımlarından farklı olarak tüm banyolar aynı boyut ve ölçülerde inşa edilmiştir.
Türk Loyd sınıflandırmasına sahip Kraliçe Salmakis, en yüksek kalitede olanaklara ve güvertede jakuzi de dahil olmak üzere dikkat çekici bir alana sahip modern tesisler sunmaktadır. Tüm güverte alanları ve yaşam alanları, konuklarımızın zevki ve konforuna odaklanılarak geniş ve ferah tutulmuştur.
Lüks gulet sınıfında yer alan Queen of Salmakis, yüksek kaliteli lüks hizmet sunmakta olup, Yunanistan ve Türkiye seferleri için 18 kişilik kapasitesiyle 12 kişiden fazla VIP grubunu ağırlayabilmektedir.
UZUNLUK: 39,10 M
GENİŞLİK: 8,50 M
İNŞA YILI: 2018
İNŞA EDİCİ: SALMAKIS YACHTING
MÜRETTEBAT SAYISI: 7 (Yedi)
KONAKLAMA:
8 KABİNDE 18 KONUK İÇİN UYGUNDUR (2 USTA KABİN, 4 ÇİFT KİŞİLİK KABİN,
ÇİFT VE TEK KİŞİLİK YATAKLI 2 ÜÇ KİŞİLİK KABİN)
LİMAN: BODRUM
GÖVDE YAPISI: LAMİNE
BAYRAK: TÜRKİYE
LOYD: TÜRKİYE
MOTOR SAYISI: 2
SINIF
MAYIS
HAZİRAN
TEMMUZ
AĞUSTOS
Eylül
EKİM
vip
38.500 €
56.500 €
74.000 €
74.000 €
56.500 €
38.500 €
Koşullar
*Koşullar
*APA sistemi uygulanmaktadır. Türk karasularındaki yakıt, yiyecek, içecek ve diğer tüm masraflar APA tarafından karşılanacaktır. İsteğe bağlı jet ski günlük 250 Euro'dur.

30
docs/sunworld.md Normal file
View File

@@ -0,0 +1,30 @@
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 çift kişilik yatak + tek kişilik yatak bulunan kabinlerde 19 kişiye kadar konaklama imkanı sunmaktadır. Her kabinin kendine ait özel tuvaleti ve duş imkanı bulunmaktadır; ayrıca ayrı bir duş ünitesi de mevcuttur.
GEMİDEKİ EKİPMANLAR
Klima,
TV ve DVD oynatıcı, CD müzik sistemi, bilgisayar, internet,
derin dondurucu, buz makinesi, su arıtma cihazı.
Radar, GPS, EPIRB, SHART, SSAS, AIS-A SINIFI, Derinlik ölçer, Balık bulucu
Çamaşır makinesi, bulaşık makinesi
Elektrikli tuvalet
Tam güvenlik ekipmanı
Yangın söndürücü, yangın battaniyesi, ilk yardım çantası
Can salı, can yelekleri, güvenlik işaretleri
Rüzgar sörfü ve kano
Şnorkelli yüzme ve balıılık ekipmanı
Tam yelken ekipmanı
60 hp motorlu sürat teknesi
Duman dedektörü
Sunworld-8 güvertesi
Aşağıdaki fiyatlar Euro cinsinden, haftalık ve Cumartesi kalkışlıdır.
MAYIS. HAZİRAN TEMMUZ AĞUSTOS EYLÜL EKİM
12000 € 14.500 € 18.500 € 18.500 € 14.500 € 12000 €
*Fiyatlarımıza yiyecek, içecek, transfer, liman ücretleri, su sporları yakıtı ve
KDV dahil değildir.
*Tam pansiyon menü (kahvaltı, öğle yemeği ve akşam yemeği) kişi başı haftalık 400 €'dur.

17
i18n/request.ts Normal file
View File

@@ -0,0 +1,17 @@
import {getRequestConfig} from 'next-intl/server';
import {routing} from './routing';
export default getRequestConfig(async ({requestLocale}) => {
// This typically corresponds to the `[locale]` segment
let locale = await requestLocale;
// Ensure that a valid locale is used
if (!locale || !routing.locales.includes(locale as any)) {
locale = routing.defaultLocale;
}
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default
};
});

15
i18n/routing.ts Normal file
View File

@@ -0,0 +1,15 @@
import {defineRouting} from 'next-intl/routing';
import {createNavigation} from 'next-intl/navigation';
export const routing = defineRouting({
// A list of all locales that are supported
locales: ['en', 'tr'],
// Used when no locale matches
defaultLocale: 'en'
});
// Lightweight wrappers around Next.js' navigation APIs
// that will consider the routing configuration
export const {Link, redirect, usePathname, useRouter} =
createNavigation(routing);

89
messages/en.json Normal file
View File

@@ -0,0 +1,89 @@
{
"Navbar": {
"meira": "M/S MEIRA",
"princess": "M/Y PRINCESS MELDA",
"queen": "QUEEN OF SALMAKIS",
"dolce": "DOLCE MARE",
"sunworld": "SUNWORLD-8",
"contact": "CONTACT"
},
"Home": {
"established": "Established 1980",
"title_main": "The Finest Name in ",
"title_italic": "Aegean Yachting.",
"description": "Salmakis Yachting is the region's leading concierge for luxury yacht charters. Discerning travelers and family offices rely on our decades of maritime expertise to curate the most spectacular journeys across the Aegean and Mediterranean. Our dedicated team is entrusted with arranging bespoke experiences in the world's most breathtaking turquoise destinations.",
"featured_fleet": "Featured ",
"featured_fleet_italic": "Fleet."
},
"FleetDetail": {
"length": "Length",
"guests": "Guests",
"cabins": "Cabins",
"crew": "Crew",
"speed": "Speed",
"design_engineering": "Design & Engineering",
"builder": "Builder",
"year_refit": "Year / Refit",
"sanctuary_title1": "A Sanctuary",
"sanctuary_title2": "Upon the Sea.",
"inquire_btn": "INQUIRE FOR CHARTER",
"design_construction": "01 / Design & Construction",
"materials_finish": "Materials & Interior Finish",
"tech_equipment": "02 / Technical Equipment",
"water_toys": "03 / Tenders & Water Toys",
"atelier_experience": "The Atelier Experience",
"gallery": "Gallery",
"rates": "Rates",
"rates_desc": "Base weekly rates for the season. APA and VAT not included.",
"apa_note": "Advanced Provisioning Allowance (APA) is typically 30% of the charter fee.",
"vat_note": "Local Value Added Tax (VAT) applies depending on the cruising area.",
"journey_title": "The Journey Continues",
"ready_title": "Ready for your Atelier experience?",
"start_inquiry_btn": "START AN INQUIRY",
"explore_btn": "EXPLORE FULL FLEET"
},
"FleetList": {
"collection": "The Collection",
"title1": "The Salmakis",
"title2": "Selection.",
"description": "Explore our hand-picked collection of the finest vessels in the Mediterranean. Each yacht is maintained to the highest standards of the Nautical Atelier.",
"bg_text": "FLEET",
"masterpiece": "Masterpiece No. 0",
"length": "Length",
"guests": "Guests",
"guests_suffix": "Pers.",
"discover": "Discover"
},
"YachtCard": {
"length": "Length",
"guests": "Guests",
"cabins": "Cabins",
"crew": "Crew",
"from": "FROM",
"p_week": "P/WEEK"
},
"Contact": {
"reservation_concierge": "Reservation & Concierge",
"title1": "Begin Your",
"title2": "Voyage.",
"headquarters": "Headquarters",
"hq_address1": "Bodrum Shipyard District,",
"hq_address2": "Mugla, Turkey 48400",
"direct_line": "Direct Line",
"digital_mail": "Digital Mail",
"whatsapp_btn": "Connect via WhatsApp",
"form_title": "Commission a Charter",
"first_name_label": "First Name",
"first_name_placeholder": "Alexander",
"last_name_label": "Last Name",
"last_name_placeholder": "Hamilton",
"email_label": "Email Address",
"email_placeholder": "ah@lifestyle.com",
"yacht_label": "Yacht of Interest",
"charter_start": "Charter Start",
"charter_end": "Charter End",
"requirements_label": "Bespoke Requirements",
"requirements_placeholder": "Special dietary needs, preferred harbors...",
"submit_btn": "Submit Selection"
}
}

89
messages/tr.json Normal file
View File

@@ -0,0 +1,89 @@
{
"Navbar": {
"meira": "M/S MEIRA",
"princess": "M/Y PRINCESS MELDA",
"queen": "QUEEN OF SALMAKIS",
"dolce": "DOLCE MARE",
"sunworld": "SUNWORLD-8",
"contact": "İLETİŞİM"
},
"Home": {
"established": "1980'den Günümüze",
"title_main": "Ege ve Akdeniz'in ",
"title_italic": "En İhtişamlı İsmi.",
"description": "Salmakis Yachting, lüks yat kiralama konusunda bölgenin lider conciergedir. Dünyanın her yerinden gezginler ve aile ofisleri, Ege ve Akdeniz'de en muhteşem yolculukları hazırlamak için onlarca yıllık denizcilik uzmanlığımıza güvenmektedir.",
"featured_fleet": "Öne Çıkan ",
"featured_fleet_italic": "Filomuz."
},
"FleetDetail": {
"length": "Uzunluk",
"guests": "Misafir",
"cabins": "Kabin",
"crew": "Mürettebat",
"speed": "Seyir Hızı",
"design_engineering": "Tasarım & Mühendislik",
"builder": "Tersane",
"year_refit": "Yapım / Yenilenme",
"sanctuary_title1": "Denizin Üzerindeki",
"sanctuary_title2": "Sığınağınız.",
"inquire_btn": "KİRALAMAK İÇİN İLETİŞİME GEÇİN",
"design_construction": "01 / Tasarım & İnşa",
"materials_finish": "Malzeme & İç Dekorasyon",
"tech_equipment": "02 / Teknik Ekipman",
"water_toys": "03 / Su Oyuncakları & Ekipman",
"atelier_experience": "Atelier Deneyimi",
"gallery": "Galeri",
"rates": "Haftalık Ücretler",
"rates_desc": "Sezona göre başlangıç haftalık ücretleridir. APA ve KDV dahil değildir.",
"apa_note": "Gelişmiş Tedarik Ödeneği (APA) genellikle kiralama bedelinin %30'udur.",
"vat_note": "Yerel Katma Değer Vergisi (KDV) seyir rotasına göre uygulanır.",
"journey_title": "Yolculuk Devam Ediyor",
"ready_title": "Atelier deneyiminize hazır mısınız?",
"start_inquiry_btn": "BİZE ULAŞIN",
"explore_btn": "TÜM FİLOYU İNCELEYİN"
},
"FleetList": {
"collection": "Koleksiyon",
"title1": "Salmakis",
"title2": "Seçkisi.",
"description": "Akdeniz'in en seçkin yatlarından oluşan özenle seçilmiş koleksiyonumuzu keşfedin. Her yat, Nautical Atelier'in en yüksek yapı standartlarına uygun olarak tasarlanmıştır.",
"bg_text": "FİLO",
"masterpiece": "Başyapıt No. 0",
"length": "Uzunluk",
"guests": "Misafir",
"guests_suffix": "Kişi",
"discover": "Keşfet"
},
"YachtCard": {
"length": "Uzunluk",
"guests": "Misafir",
"cabins": "Kabin",
"crew": "Mürettebat",
"from": "BAŞLAYAN FİYATLARLA",
"p_week": "HAFTALIK"
},
"Contact": {
"reservation_concierge": "Rezervasyon & Concierge",
"title1": "Yolculuğunuza",
"title2": "Başlayın.",
"headquarters": "Merkez Ofis",
"hq_address1": "Bodrum Tersane Bölgesi,",
"hq_address2": "Muğla, Türkiye 48400",
"direct_line": "Direkt Hat",
"digital_mail": "Dijital Posta",
"whatsapp_btn": "WhatsApp Üzerinden İletişim",
"form_title": "Kiralama Talebi Oluşturun",
"first_name_label": "Adınız",
"first_name_placeholder": "Alexander",
"last_name_label": "Soyadınız",
"last_name_placeholder": "Hamilton",
"email_label": "E-Posta Adresi",
"email_placeholder": "ah@lifestyle.com",
"yacht_label": "İlgilendiğiniz Yat",
"charter_start": "Başlangıç Tarihi",
"charter_end": "Bitiş Tarihi",
"requirements_label": "Özel İstekleriniz",
"requirements_placeholder": "Özel diyet ihtiyaçları, tercih edilen limanlar...",
"submit_btn": "Talebi Gönder"
}
}

9
middleware.ts Normal file
View File

@@ -0,0 +1,9 @@
import createMiddleware from 'next-intl/middleware';
import {routing} from './i18n/routing';
export default createMiddleware(routing);
export const config = {
// Match only internationalized pathnames
matcher: ['/', '/(tr|en)/:path*']
};

View File

@@ -1,7 +1,22 @@
import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin("./i18n/request.ts");
const nextConfig: NextConfig = {
/* config options here */
output: 'standalone',
images: {
remotePatterns: [
{
protocol: "https",
hostname: "images.unsplash.com",
},
{
protocol: "https",
hostname: "res.cloudinary.com",
},
],
},
};
export default nextConfig;
export default withNextIntl(nextConfig);

882
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,12 @@
"lint": "eslint"
},
"dependencies": {
"cloudinary": "^2.9.0",
"dotenv": "^17.4.2",
"framer-motion": "^12.38.0",
"next": "16.2.3",
"next-cloudinary": "^6.17.5",
"next-intl": "^4.9.1",
"react": "19.2.4",
"react-dom": "19.2.4"
},

BIN
public/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
public/hero-yacht.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

59
scratch/bulk_upload.js Normal file
View File

@@ -0,0 +1,59 @@
const cloudinary = require('cloudinary').v2;
require('dotenv').config({ path: '.env.local' });
const fs = require('fs');
const path = require('path');
cloudinary.config({
cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});
const BASE_DIR = path.join('public', 'images');
const CLOUDINARY_ROOT = 'salmakisyat';
async function uploadFolder(folderName) {
const folderPath = path.join(BASE_DIR, folderName);
if (!fs.existsSync(folderPath)) return [];
const files = fs.readdirSync(folderPath);
const results = [];
for (const file of files) {
const filePath = path.join(folderPath, file);
if (!fs.lstatSync(filePath).isFile()) continue;
console.log(`Uploading ${folderName}/${file}...`);
try {
const result = await cloudinary.uploader.upload(filePath, {
folder: `${CLOUDINARY_ROOT}/${folderName}`,
use_filename: true,
unique_filename: false,
overwrite: true
});
results.push({
localFile: file,
public_id: result.public_id
});
console.log(`Done: ${result.public_id}`);
} catch (e) {
console.error(`Failed to upload ${file}:`, e.message);
}
}
return results;
}
async function main() {
const folders = ['meira', 'melda', 'queenofsalmakis', 'dolcemare', 'sunworld'];
const allResults = {};
for (const folder of folders) {
console.log(`\n--- Processing folder: ${folder} ---`);
allResults[folder] = await uploadFolder(folder);
}
fs.writeFileSync('scratch/upload_report.json', JSON.stringify(allResults, null, 2));
console.log('\nAll uploads completed! Report saved to scratch/upload_report.json');
}
main();

View File

@@ -0,0 +1,38 @@
const cloudinary = require('cloudinary').v2;
require('dotenv').config({ path: '.env.local' });
cloudinary.config({
cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});
async function listResources() {
try {
console.log('Fetching assets from Cloudinary...');
let allResources = [];
let nextCursor = null;
do {
const result = await cloudinary.api.resources({
type: 'upload',
prefix: 'salmakisyat/',
max_results: 500,
next_cursor: nextCursor
});
allResources = allResources.concat(result.resources);
nextCursor = result.next_cursor;
} while (nextCursor);
const mapping = allResources.map(res => ({
public_id: res.public_id,
folder: res.folder
}));
console.log(JSON.stringify(mapping, null, 2));
} catch (error) {
console.error('Error fetching resources:', error);
}
}
listResources();

248
scratch/upload_report.json Normal file
View File

@@ -0,0 +1,248 @@
{
"meira": [
{
"localFile": "GUEST-CABIN-3-1-1024x680.jpg",
"public_id": "salmakisyat/meira/GUEST-CABIN-3-1-1024x680"
},
{
"localFile": "MASTER-CABIN-4-1024x680.jpg",
"public_id": "salmakisyat/meira/MASTER-CABIN-4-1024x680"
},
{
"localFile": "MEIRA-2000x1333.jpg",
"public_id": "salmakisyat/meira/MEIRA-2000x1333"
},
{
"localFile": "MS-MEIRA-53-1-1024x683.jpg",
"public_id": "salmakisyat/meira/MS-MEIRA-53-1-1024x683"
},
{
"localFile": "MS-MEIRA-58-1024x683.jpg",
"public_id": "salmakisyat/meira/MS-MEIRA-58-1024x683"
},
{
"localFile": "PSU3709-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU3709-1024x683"
},
{
"localFile": "PSU3739-1-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU3739-1-1024x683"
},
{
"localFile": "PSU3741-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU3741-1024x683"
},
{
"localFile": "PSU3748-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU3748-1024x683"
},
{
"localFile": "PSU3965-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU3965-1024x683"
},
{
"localFile": "PSU4215-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU4215-1024x683"
},
{
"localFile": "PSU4475-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU4475-1024x683"
},
{
"localFile": "PSU4519-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU4519-1024x683"
},
{
"localFile": "PSU4814-1024x683.jpg",
"public_id": "salmakisyat/meira/PSU4814-1024x683"
},
{
"localFile": "VIP-CABIN-1-1024x680.jpg",
"public_id": "salmakisyat/meira/VIP-CABIN-1-1024x680"
}
],
"melda": [
{
"localFile": "balkon4-768x432.jpg",
"public_id": "salmakisyat/melda/balkon4-768x432"
},
{
"localFile": "master3-768x432.jpg",
"public_id": "salmakisyat/melda/master3-768x432"
},
{
"localFile": "master4-768x432.jpg",
"public_id": "salmakisyat/melda/master4-768x432"
},
{
"localFile": "mastertuvalet-768x432.jpg",
"public_id": "salmakisyat/melda/mastertuvalet-768x432"
},
{
"localFile": "mastertuvalet.jpg2_-768x432.jpg",
"public_id": "salmakisyat/melda/mastertuvalet.jpg2_-768x432"
},
{
"localFile": "masteryeni2-768x432.jpg",
"public_id": "salmakisyat/melda/masteryeni2-768x432"
},
{
"localFile": "twin1-768x432.jpg",
"public_id": "salmakisyat/melda/twin1-768x432"
},
{
"localFile": "yuzen-yat-2000x1125.jpg",
"public_id": "salmakisyat/melda/yuzen-yat-2000x1125"
}
],
"queenofsalmakis": [
{
"localFile": "kic-master-lumboz-1.jpg",
"public_id": "salmakisyat/queenofsalmakis/kic-master-lumboz-1"
},
{
"localFile": "Onaylanmayan 417802.crdownload",
"public_id": "salmakisyat/queenofsalmakis/Onaylanmayan_417802"
},
{
"localFile": "QOS-AFTDECK-1 (1).jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-AFTDECK-1_1"
},
{
"localFile": "QOS-AFTDECK-1.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-AFTDECK-1"
},
{
"localFile": "QOS-AFTDECK-4 (1).jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-AFTDECK-4_1"
},
{
"localFile": "QOS-AFTDECK-4.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-AFTDECK-4"
},
{
"localFile": "QOS-cabin-BOW-MASTER-7.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-cabin-BOW-MASTER-7"
},
{
"localFile": "QOS-FOREDECK-6.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-FOREDECK-6"
},
{
"localFile": "QOS-guverte-FOREDECK-2-scaled.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-guverte-FOREDECK-2-scaled"
},
{
"localFile": "QOS-guverte-FOREDECK-4-scaled.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-guverte-FOREDECK-4-scaled"
},
{
"localFile": "QOS-yelkenli-beyaz-7-2000x1333.jpg",
"public_id": "salmakisyat/queenofsalmakis/QOS-yelkenli-beyaz-7-2000x1333"
}
],
"dolcemare": [
{
"localFile": "Dolce-Mare-12-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-12-1024x680"
},
{
"localFile": "Dolce-Mare-33-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-33-1024x680"
},
{
"localFile": "Dolce-Mare-41-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-41-1024x680"
},
{
"localFile": "Dolce-Mare-47-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-47-1024x680"
},
{
"localFile": "Dolce-Mare-57-1024x680 (1).jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-57-1024x680_1"
},
{
"localFile": "Dolce-Mare-57-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-57-1024x680"
},
{
"localFile": "Dolce-Mare-63-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-63-1024x680"
},
{
"localFile": "Dolce-Mare-66-1024x680 (1).jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-66-1024x680_1"
},
{
"localFile": "Dolce-Mare-66-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-66-1024x680"
},
{
"localFile": "Dolce-Mare-80-1024x680.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-80-1024x680"
},
{
"localFile": "Dolce-Mare-90-2000x1328.jpg",
"public_id": "salmakisyat/dolcemare/Dolce-Mare-90-2000x1328"
}
],
"sunworld": [
{
"localFile": "784ff3f3e0fa5982c77288ecf6612842 (1).jpg",
"public_id": "salmakisyat/sunworld/784ff3f3e0fa5982c77288ecf6612842_1"
},
{
"localFile": "784ff3f3e0fa5982c77288ecf6612842.jpg",
"public_id": "salmakisyat/sunworld/784ff3f3e0fa5982c77288ecf6612842"
},
{
"localFile": "Aft-Double-Bed-Cabin.jpg",
"public_id": "salmakisyat/sunworld/Aft-Double-Bed-Cabin"
},
{
"localFile": "bodrum-sunworld-8-kiralik-gulet-5 (1).jpg",
"public_id": "salmakisyat/sunworld/bodrum-sunworld-8-kiralik-gulet-5_1"
},
{
"localFile": "bodrum-sunworld-8-kiralik-gulet-5.jpg",
"public_id": "salmakisyat/sunworld/bodrum-sunworld-8-kiralik-gulet-5"
},
{
"localFile": "Double-Bed-Cabin-1.jpg",
"public_id": "salmakisyat/sunworld/Double-Bed-Cabin-1"
},
{
"localFile": "Double-Bed-Cabin.jpg",
"public_id": "salmakisyat/sunworld/Double-Bed-Cabin"
},
{
"localFile": "Sailing-Boat.jpg",
"public_id": "salmakisyat/sunworld/Sailing-Boat"
},
{
"localFile": "Saloon.jpg",
"public_id": "salmakisyat/sunworld/Saloon"
},
{
"localFile": "Sitting-Area.jpg",
"public_id": "salmakisyat/sunworld/Sitting-Area"
},
{
"localFile": "Sunbeds-on-Deck.jpg",
"public_id": "salmakisyat/sunworld/Sunbeds-on-Deck"
},
{
"localFile": "Toilet-1.jpg",
"public_id": "salmakisyat/sunworld/Toilet-1"
},
{
"localFile": "Triple-Bed-Cabin.jpg",
"public_id": "salmakisyat/sunworld/Triple-Bed-Cabin"
},
{
"localFile": "Twin-Bed-Cabin.jpg",
"public_id": "salmakisyat/sunworld/Twin-Bed-Cabin"
}
]
}

BIN
stitch.zip Normal file

Binary file not shown.

72
stitch/DESIGN.md Normal file
View File

@@ -0,0 +1,72 @@
# Design System Strategy: The Nautical Atelier
## 1. Overview & Creative North Star
The Creative North Star for this design system is **"The Nautical Atelier."**
Unlike standard booking platforms that feel like transactional utilities, this system is designed to mirror the experience of a high-end concierge service. We are moving away from the "standard grid" into a space of **Editorial Precision**. The design breaks the traditional template look through intentional asymmetry—where high-resolution imagery of yacht hulls and crystalline waters bleeds off-canvas—and vast, "expensive" whitespace that allows the content to breathe, suggesting exclusivity and calm.
Every element is treated as a piece of craftsmanship. We use high-contrast typography scales (the "Didot" effect) to create a sense of heritage, paired with ultra-modern layout techniques to signal technological superiority.
## 2. Colors & Tonal Depth
The palette is rooted in the "Golden Hour" on the Mediterranean: deep oceanic shadows and the warm, metallic glint of sunset on hardware.
* **Primary (Deep Navy - #000613 / #001F3F):** Used for deep immersion. This is not just a background; it is the "anchor" of the visual identity. Use `primary_container` for hero sections to establish authority.
* **Secondary (Champagne Gold - #775A19):** This is your "jewelry." It should be used sparingly for high-value CTAs, iconography accents, and active states to guide the eye toward conversion.
* **Neutral (Pearl White - #F9F9F9):** The canvas. It provides the "vast whitespace" required to make the Navy and Gold feel premium.
### The "No-Line" Rule
Standard 1px borders are strictly prohibited for sectioning. They create visual noise that feels "cheap." Instead, boundaries must be defined by:
* **Background Shifts:** Transitioning from `surface` to `surface_container_low`.
* **Tonal Transitions:** Using subtle gradients between `primary` and `primary_container` for large-scale immersive sections.
### Surface Hierarchy & Nesting
Treat the UI as physical layers of fine paper or polished deck wood.
* **Level 1 (Foundation):** `surface` (#F9F9F9) for the main page body.
* **Level 2 (The Deck):** `surface_container_low` (#F3F3F3) for secondary content areas or sidebar filters.
* **Level 3 (The Cabin):** `surface_container_highest` (#E2E2E2) for interactive elements like cards.
### Signature Textures
Use **Glassmorphism** for navigation bars and floating price cards. Utilize semi-transparent versions of `surface` with a 20px backdrop-blur. This allows the high-quality imagery of the yachts to bleed through, maintaining a sense of place.
## 3. Typography: The Editorial Voice
Typography is the primary driver of the "Luxury Watch" aesthetic.
* **Display & Headline (Noto Serif):** These are your "statements." Set with increased letter-spacing (0.02em) and thin weights to mimic the elegance of *Vogue* or *Rolex* advertisements. Use `display-lg` for yacht names and `headline-md` for section introductions.
* **Body (Manrope):** A clean, high-legibility sans-serif. It acts as the functional counterpart to the serif. Keep line heights generous (1.6x) to maintain the feeling of openness.
* **Labels (Inter):** Small, all-caps labels (using `label-md`) should be used for technical specs (e.g., "LENGTH: 45M") to provide a precision-engineered feel.
## 4. Elevation & Depth
This design system rejects heavy drop shadows in favor of **Tonal Layering**.
* **The Layering Principle:** Depth is achieved by stacking. A `surface_container_lowest` card sitting on a `surface_container` background provides a soft, natural lift that mimics architectural shadows.
* **Ambient Shadows:** When a yacht listing card must float, use a "Sea Mist" shadow: `on_surface` color at 4% opacity, with a 40px blur and 10px Y-offset. It should be barely perceptible, felt rather than seen.
* **The Ghost Border:** If a form field or button requires a border, use `outline_variant` at 20% opacity. Never use 100% opaque lines.
## 5. Components
### Buttons: The "Gold Standard"
* **Primary:** Solid `secondary` (Champagne Gold) with `on_secondary` text. Rectangular with 0px corner radius (The "Sharp Edge" Rule) to convey architectural precision.
* **Secondary:** `primary` (Navy) with a gold `outline_variant` (20% opacity).
* **Tertiary:** Text-only with a 1px gold underline that expands on hover.
### Cards & Lists: The "Whitespace" Rule
* **Dividers:** Strictly forbidden. Separate yacht listings or itinerary items using 64px or 80px of vertical whitespace (from the spacing scale).
* **Imagery:** All cards must feature high-aspect-ratio photography. Content (Price, Name) should be overlaid using a subtle `primary_container` gradient at the bottom 30% of the image.
### Input Fields: The "Minimalist Entry"
* Inputs should not be boxes. They are a single 1px `outline_variant` line at the bottom. The label should be in `label-sm` (Inter) floating above the line, reminiscent of a yachts technical blueprint.
### Signature Component: The "Heritage Modal"
* A full-screen overlay using `primary_container` (Navy). Use `display-md` (Serif) for titles and high-opacity Glassmorphism for the close button. This creates a focused, "private lounge" experience for the user.
## 6. Dos and Don'ts
### Do:
* **Embrace Asymmetry:** Place a yacht image on the left and offset the text block to the right with 120px of padding.
* **Use The "Sharp Edge":** Keep all `borderRadius` at **0px**. Rounded corners are for consumer tech; sharp edges are for luxury yachts and supercars.
* **Prioritize Image Quality:** If the photography is low-res, the entire design system fails. Treat images as the primary "UI" element.
### Dont:
* **Don't use "Blue":** Avoid standard digital blues. Only use the Deep Navy (`#001F3F`) provided.
* **Don't use Grids rigidly:** Do not feel forced to align everything to a 12-column grid. Let elements overlap—like a serif headline partially covering an image—to create depth.
* **Don't use pure Black:** Use `primary` or `tertiary` for dark tones. Pure black (#000000) lacks the "soul" and depth of this maritime palette.

293
stitch/code.html Normal file
View File

@@ -0,0 +1,293 @@
<!DOCTYPE html>
<html class="scroll-smooth" lang="en"><head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>SALMAKIS YACHTING | The Nautical Atelier</title>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif:wght@200;300;400&amp;family=Manrope:wght@300;400;600&amp;family=Inter:wght@400;500;700&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
"colors": {
"on-secondary-container": "#785a1a",
"tertiary": "#090500",
"on-tertiary-container": "#958467",
"error-container": "#ffdad6",
"inverse-surface": "#2f3131",
"on-surface-variant": "#43474e",
"on-error-container": "#93000a",
"on-background": "#1a1c1c",
"on-tertiary-fixed-variant": "#52452c",
"surface-container-highest": "#e2e2e2",
"background": "#f9f9f9",
"surface-variant": "#e2e2e2",
"on-primary-fixed-variant": "#2f486a",
"tertiary-fixed": "#f4e0be",
"primary-container": "#001f3f",
"surface": "#f9f9f9",
"primary-fixed": "#d4e3ff",
"on-tertiary": "#ffffff",
"on-primary-container": "#6f88ad",
"on-secondary-fixed-variant": "#5d4201",
"on-primary": "#ffffff",
"on-secondary-fixed": "#261900",
"on-primary-fixed": "#001c3a",
"secondary-fixed-dim": "#e9c176",
"inverse-primary": "#afc8f0",
"outline-variant": "#c4c6cf",
"surface-dim": "#dadada",
"secondary": "#775a19",
"primary": "#000613",
"inverse-on-surface": "#f1f1f1",
"secondary-container": "#fed488",
"on-tertiary-fixed": "#241a06",
"surface-container": "#eeeeee",
"on-error": "#ffffff",
"error": "#ba1a1a",
"surface-container-high": "#e8e8e8",
"on-secondary": "#ffffff",
"surface-bright": "#f9f9f9",
"primary-fixed-dim": "#afc8f0",
"surface-container-lowest": "#ffffff",
"outline": "#74777f",
"secondary-fixed": "#ffdea5",
"surface-container-low": "#f3f3f3",
"tertiary-fixed-dim": "#d7c4a4",
"on-surface": "#1a1c1c",
"tertiary-container": "#271d08",
"surface-tint": "#476083"
},
"borderRadius": {
"DEFAULT": "0px",
"lg": "0px",
"xl": "0px",
"full": "9999px"
},
"fontFamily": {
"headline": ["Noto Serif"],
"body": ["Manrope"],
"label": ["Inter"]
}
},
},
}
</script>
<style>
.material-symbols-outlined {
font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 24;
}
.glass-nav {
background: rgba(249, 249, 249, 0.8);
backdrop-filter: blur(20px);
}
</style>
</head>
<body class="bg-surface text-on-surface font-body antialiased">
<!-- TopNavBar -->
<nav class="fixed top-0 w-full z-50 flex flex-col items-center justify-between px-6 md:px-12 py-6 w-full bg-surface/80 backdrop-blur-md dark:bg-primary/80">
<div class="flex items-center justify-between w-full">
<span class="text-2xl font-headline tracking-[0.2em] text-primary dark:text-white text-center w-full block uppercase">SALMAKIS</span>
<div class="md:hidden">
<span class="material-symbols-outlined text-secondary" data-icon="menu">menu</span>
</div>
</div>
<div class="hidden md:flex items-center space-x-12 mt-6">
<a class="font-headline tracking-widest uppercase text-sm font-light text-secondary border-b border-secondary pb-1 hover:text-secondary transition-colors duration-500" href="#">M/S MEIRA</a>
<a class="font-headline tracking-widest uppercase text-sm font-light text-primary/60 dark:text-white/60 hover:text-secondary transition-colors duration-500" href="#">M/Y PRINCESS MELDA</a>
<a class="font-headline tracking-widest uppercase text-sm font-light text-primary/60 dark:text-white/60 hover:text-secondary transition-colors duration-500" href="#">QUEEN OF SALMAKIS</a>
<a class="font-headline tracking-widest uppercase text-sm font-light text-primary/60 dark:text-white/60 hover:text-secondary transition-colors duration-500" href="#">DOLCE MARE</a>
</div>
</nav>
<!-- Hero Section -->
<header class="relative h-screen w-full overflow-hidden">
<div class="absolute inset-0">
<img alt="Luxury Yacht Sunset Dining" class="w-full h-full object-cover" data-alt="Cinematic 8k photo of a luxury yacht deck at sunset, elegant dining table set with crystal glasses and white linen, warm golden hour lighting reflecting off polished wood" src="https://lh3.googleusercontent.com/aida-public/AB6AXuB3yj7ljBpQhuIme8qbqiS6c-Q8OyFePxrE3AyiuUNJJ3RWdRvmgwjkLLC8I96z20Mh8QIBR976--8G-2xS7HO3c2ldhgTse9M8zPzZoKdBtrVL8ran-rm_UpwUZu_DzgTUYlbEkVTEEFunqFT0l4eUa8MuenzpfkkyLy5vnmoFGtMi0GR3Apw6TcaDeQo5rGq4Xg5PvE1pXFHe808wSZuBI3_a440lstHFXp0MrGu5ct2TW152xhoJELteMoyxPTSARgeIeMflRtf7"/>
<div class="absolute inset-0 bg-gradient-to-t from-primary/80 via-transparent to-transparent"></div>
</div>
<div class="relative h-full flex flex-col items-center justify-center text-center px-6">
<h1 class="font-headline text-5xl md:text-8xl font-extralight tracking-tight text-secondary mb-6 italic">A Masterpiece on Water</h1>
<p class="font-body text-white/80 tracking-widest uppercase text-sm md:text-base max-w-2xl">EXPERIENCE THE ART OF NAUTICAL LIVING. HANDCRAFTED VOYAGES ACROSS THE MEDITERRANEAN.</p>
<button class="mt-12 px-12 py-4 bg-secondary text-white font-headline tracking-[0.3em] uppercase text-xs hover:bg-on-secondary-container transition-all duration-700">
DISCOVER THE ATELIER
</button>
</div>
<div class="absolute bottom-12 left-1/2 -translate-x-1/2 flex flex-col items-center">
<span class="text-white/40 text-[10px] tracking-[0.5em] uppercase mb-4">Scroll to Explore</span>
<div class="w-px h-16 bg-gradient-to-b from-secondary to-transparent"></div>
</div>
</header>
<!-- Fleet Intro -->
<section class="py-32 px-6 md:px-24 bg-surface">
<div class="max-w-7xl mx-auto flex flex-col md:flex-row items-end gap-16">
<div class="w-full md:w-1/2">
<h2 class="font-headline text-4xl md:text-6xl text-primary leading-tight mb-8">The curated <br/><span class="text-secondary italic">Salmakis Fleet.</span></h2>
<div class="h-px w-24 bg-secondary mb-8"></div>
<p class="font-body text-on-surface-variant text-lg leading-relaxed font-light">
Our fleet represents the pinnacle of naval engineering and interior design. Each vessel is a sanctuary of privacy, offering a bespoke environment tailored to the world's most discerning travelers.
</p>
</div>
<div class="w-full md:w-1/2 flex justify-end">
<div class="text-right">
<span class="font-label text-6xl md:text-8xl text-outline-variant/30 font-bold leading-none">01 / 04</span>
</div>
</div>
</div>
</section>
<!-- Fleet Grid (Bento/Asymmetric Style) -->
<main class="pb-40 bg-surface">
<div class="max-w-[1400px] mx-auto px-6 space-y-40">
<!-- M/S MEIRA -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-0 group">
<div class="md:col-span-7 relative h-[600px] md:h-[800px] overflow-hidden">
<img alt="M/S MEIRA" class="w-full h-full object-cover grayscale-[20%] group-hover:grayscale-0 transition-all duration-1000 scale-100 group-hover:scale-105" data-alt="Sleek white motor sailor yacht M/S MEIRA sailing on turquoise waters under bright mediterranean sun" src="https://lh3.googleusercontent.com/aida-public/AB6AXuB74-T3Ti13lKiCdJ-Df40m60TYnUBXLLtZmtpzxb2e_67n7qXyUipwpNq3U9bxGjWLButShvUqP1EzE3Qre1na7LornQYMlbA3zfuAuVMUEcQJZ9YY0LR8FLG4T1O1Pon1Y7p47Ca_AGaOXmtOj7_Mimef8rZfETTYhaskftaTFyGLj9D3_lsG_VJjGs83SqFDegtluDx_AwMKO47IA-vh4UxreVaZxNInOQuD-T_ZWOHLd1ua6mNPjQGJkfUg-LcFJbBCorG4gx7-"/>
<div class="absolute bottom-0 left-0 right-0 p-8 bg-gradient-to-t from-primary/60 to-transparent md:hidden">
<h3 class="font-headline text-3xl text-white tracking-widest uppercase">M/S MEIRA</h3>
</div>
</div>
<div class="md:col-span-5 flex flex-col justify-center md:pl-20 py-12 md:py-0">
<span class="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4">Flagship Selection</span>
<h3 class="font-headline text-4xl md:text-6xl text-primary mb-8 tracking-wide">M/S MEIRA</h3>
<p class="text-on-surface-variant font-light leading-relaxed mb-12 max-w-sm">
Defining grandeur with six palatial staterooms and an expansive sundeck featuring a jacuzzi and sky lounge.
</p>
<div class="grid grid-cols-3 border-t border-outline-variant/20 pt-8">
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="straighten">straighten</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Length</span>
<span class="font-body text-sm text-primary font-semibold">55 Meters</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="groups">groups</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Guests</span>
<span class="font-body text-sm text-primary font-semibold">12 Persons</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="payments">payments</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Price</span>
<span class="font-body text-sm text-primary font-semibold">From €125k</span>
</div>
</div>
</div>
</div>
<!-- M/Y PRINCESS MELDA -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-0 group">
<div class="md:col-span-5 md:order-1 flex flex-col justify-center md:pr-20 py-12 md:py-0 md:text-right md:items-end">
<span class="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4">Pure Modernism</span>
<h3 class="font-headline text-4xl md:text-6xl text-primary mb-8 tracking-wide">M/Y PRINCESS MELDA</h3>
<p class="text-on-surface-variant font-light leading-relaxed mb-12 max-w-sm">
A contemporary masterpiece of glass and steel, offering panoramic views and a minimalist, zen-inspired interior.
</p>
<div class="grid grid-cols-3 border-t border-outline-variant/20 pt-8 w-full">
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="straighten">straighten</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Length</span>
<span class="font-body text-sm text-primary font-semibold">42 Meters</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="groups">groups</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Guests</span>
<span class="font-body text-sm text-primary font-semibold">10 Persons</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="payments">payments</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Price</span>
<span class="font-body text-sm text-primary font-semibold">From €95k</span>
</div>
</div>
</div>
<div class="md:col-span-7 md:order-2 relative h-[600px] md:h-[800px] overflow-hidden">
<img alt="M/Y PRINCESS MELDA" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-1000" data-alt="Modern motor yacht M/Y PRINCESS MELDA with sharp architectural lines anchored in a secluded azure cove at noon" src="https://lh3.googleusercontent.com/aida-public/AB6AXuAyUY-gItMKc5HHY-oWXhcwzD6MzOA6vwa_g1ztOkbR1yg0iW1HnEKN1xaD1bTXAODGX_K0Eljvlm7jWgUbR6PGwerp8GP7LlTY4snQ2Y0YFjnmdwTdPUw54CiaK0OyKrqebp2acJurrOJAnnVtiyKB2H3T7M8jqCdVtv9vX2shhnGawTiQJ4uRVDtEqYjVzguAo2J5YtRwGdsr4-U4qgPE1V8W3DFbtsqN7ZRnThFFi7VDz5WQYgS4gn443v6SIZai7pTvPMsv9Kt7"/>
</div>
</div>
<!-- QUEEN OF SALMAKIS -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-0 group">
<div class="md:col-span-7 relative h-[600px] md:h-[800px] overflow-hidden">
<img alt="QUEEN OF SALMAKIS" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-1000" data-alt="Traditional high-end Gulet QUEEN OF SALMAKIS with dark wood finish and cream sails gliding through calm seas" src="https://lh3.googleusercontent.com/aida-public/AB6AXuDAARpNbHLKXDKgwZTf3xnI87mwxADftMiVXQl1RV1pi94nUI7r2_JS9_6FGK28LC18bB2-NxVmo8iLO1mfxXwBM0ZMX7Z57O9g0INcRGlJEN52Ubvr3zcnnzh5g71lTJSBY5aXpdwZg6fLm_hBVzwb4fPUsg5ZynfYqccD7-8uZ4DnZYrHHVPQS62xxv0j2kH0FBgz-MSSr_S6h9pYu8Yg5LEJ2_u80l72OMJAKMkpdvhTNAwCa8ykBWdRQqQrFkX7KitUgACX4fc1"/>
</div>
<div class="md:col-span-5 flex flex-col justify-center md:pl-20 py-12 md:py-0">
<span class="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4">Heritage Craft</span>
<h3 class="font-headline text-4xl md:text-6xl text-primary mb-8 tracking-wide">QUEEN OF SALMAKIS</h3>
<p class="text-on-surface-variant font-light leading-relaxed mb-12 max-w-sm">
A royal gulet that marries centuries-old boatbuilding traditions with the uncompromising luxury of a modern resort.
</p>
<div class="grid grid-cols-3 border-t border-outline-variant/20 pt-8">
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="straighten">straighten</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Length</span>
<span class="font-body text-sm text-primary font-semibold">40 Meters</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="groups">groups</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Guests</span>
<span class="font-body text-sm text-primary font-semibold">18 Persons</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="payments">payments</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Price</span>
<span class="font-body text-sm text-primary font-semibold">From €70k</span>
</div>
</div>
</div>
</div>
<!-- DOLCE MARE -->
<div class="grid grid-cols-1 md:grid-cols-12 gap-0 group">
<div class="md:col-span-5 md:order-1 flex flex-col justify-center md:pr-20 py-12 md:py-0 md:text-right md:items-end">
<span class="font-label text-xs tracking-[0.4em] text-secondary uppercase mb-4">The Sweet Life</span>
<h3 class="font-headline text-4xl md:text-6xl text-primary mb-8 tracking-wide">DOLCE MARE</h3>
<p class="text-on-surface-variant font-light leading-relaxed mb-12 max-w-sm">
Experience 'La Dolce Vita' on the Turkish Riviera. An intimate vessel perfect for multi-generational family escapes.
</p>
<div class="grid grid-cols-3 border-t border-outline-variant/20 pt-8 w-full">
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="straighten">straighten</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Length</span>
<span class="font-body text-sm text-primary font-semibold">36 Meters</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="groups">groups</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Guests</span>
<span class="font-body text-sm text-primary font-semibold">12 Persons</span>
</div>
<div class="flex flex-col gap-1">
<span class="material-symbols-outlined text-secondary text-xl" data-icon="payments">payments</span>
<span class="font-label text-[10px] tracking-widest text-outline uppercase mt-2">Price</span>
<span class="font-body text-sm text-primary font-semibold">From €55k</span>
</div>
</div>
</div>
<div class="md:col-span-7 md:order-2 relative h-[600px] md:h-[800px] overflow-hidden">
<img alt="DOLCE MARE Interior" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-1000" data-alt="Interior of yacht DOLCE MARE showing a sun-drenched master cabin with polished mahogany and luxury white bedding" src="https://lh3.googleusercontent.com/aida-public/AB6AXuDIZB8oQKd5601RKs28u9wpSyzRpeG9jqovUE-0N2-U0P6YPuyhJL7b1GZTdeFrA_Goj2VCvedWSo-5q3VxYLBLgOXmLczwcSTRG2uG3AB0TZt863cg_BRqvdoIVS97J-wsOTcQYoFBRwRn1JaqUXExndCYR-eaW7qfcfnjKRc3SdkUxSFrb5WrfWtGX5SSn-549vgTsQARcTuB3BDGEfonptXrcywAPYz8ppGJ7jJeMuEzPOAfudLPZOy4r5b6V4XaKrn_rT8CCz7s"/>
</div>
</div>
</div>
</main>
<!-- Call to Action -->
<section class="py-40 bg-primary text-center">
<div class="max-w-4xl mx-auto px-6">
<h2 class="font-headline text-4xl md:text-7xl text-white mb-12">Your private horizon awaits.</h2>
<p class="font-body text-secondary text-lg tracking-widest uppercase mb-16">Contact our concierge for a bespoke consultation.</p>
<div class="flex flex-col md:flex-row items-center justify-center gap-8">
<button class="w-full md:w-auto px-16 py-5 bg-secondary text-white font-headline text-sm tracking-[0.2em] uppercase">BOOK AN INQUIRY</button>
<button class="w-full md:w-auto px-16 py-5 border border-secondary text-secondary font-headline text-sm tracking-[0.2em] uppercase hover:bg-secondary hover:text-white transition-all duration-500">VIEW ALL DESTINATIONS</button>
</div>
</div>
</section>
<!-- Footer -->
<footer class="flex flex-col items-center justify-center text-center w-full py-24 px-12 bg-primary dark:bg-primary">
<div class="text-xl font-headline text-secondary mb-4 tracking-[0.2em]">SALMAKIS</div>
<div class="flex flex-wrap justify-center gap-8 mb-12">
<a class="font-headline tracking-widest text-xs font-light uppercase text-secondary/50 hover:text-secondary transition-all" href="#">PRIVACY</a>
<a class="font-headline tracking-widest text-xs font-light uppercase text-secondary/50 hover:text-secondary transition-all" href="#">TERMS</a>
<a class="font-headline tracking-widest text-xs font-light uppercase text-secondary/50 hover:text-secondary transition-all" href="#">CONTACT</a>
<a class="font-headline tracking-widest text-xs font-light uppercase text-secondary/50 hover:text-secondary transition-all" href="#">PRESS</a>
</div>
<div class="font-headline tracking-widest text-xs font-light uppercase text-secondary">
© 2024 SALMAKIS YACHTING. THE NAUTICAL ATELIER.
</div>
</footer>
</body></html>

BIN
stitch/screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB