first commit
This commit is contained in:
@@ -0,0 +1,555 @@
|
||||
"use client";
|
||||
|
||||
import { motion, useScroll, useTransform, AnimatePresence } from "framer-motion";
|
||||
import { useRef, useState, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import type { Locale } from "@/i18n-config";
|
||||
|
||||
const expo: [number, number, number, number] = [0.16, 1, 0.3, 1];
|
||||
|
||||
const IconArrowLeft = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="19" y1="12" x2="5" y2="12" />
|
||||
<polyline points="12 19 5 12 12 5" />
|
||||
</svg>
|
||||
);
|
||||
const IconArrowRight = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" />
|
||||
</svg>
|
||||
);
|
||||
const IconCheck = () => (
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#0A0A0A" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
// Tag colors per category
|
||||
const accentFor = (tag: string): string => {
|
||||
if (/ai|yz|ml/i.test(tag)) return "#FFE600";
|
||||
if (/web3|blockchain|chain/i.test(tag)) return "#FF4500";
|
||||
if (/mobile|mobil/i.test(tag)) return "#0A0A0A";
|
||||
return "#00CC77";
|
||||
};
|
||||
|
||||
interface Props {
|
||||
lang: Locale;
|
||||
dict: any;
|
||||
project: any;
|
||||
prev: any | null;
|
||||
next: any | null;
|
||||
}
|
||||
|
||||
const screenshotsFor = (slug: string): string[] => {
|
||||
const mapping: Record<string, string[]> = {
|
||||
"financeai-dashboard": [
|
||||
"https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1460925895917-afdab827c52f?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1551836022-d5d88e9218df?auto=format&fit=crop&w=1200&q=80",
|
||||
],
|
||||
"chainsupply-network": [
|
||||
"https://images.unsplash.com/photo-1508873535684-277a3cbcc4e8?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1639762681485-074b7f938ba0?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1504384308090-c894fdcc538d?auto=format&fit=crop&w=1200&q=80",
|
||||
],
|
||||
"meditrack-mobile": [
|
||||
"https://images.unsplash.com/photo-1576091160399-112ba8d25d1d?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1584982751601-97dcc096659c?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1530026405186-ed1ea0ac7a63?auto=format&fit=crop&w=1200&q=80",
|
||||
],
|
||||
"novamart-platform": [
|
||||
"https://images.unsplash.com/photo-1460925895917-afdab827c52f?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?auto=format&fit=crop&w=1200&q=80",
|
||||
"https://images.unsplash.com/photo-1523474253046-8cd2748b5fd2?auto=format&fit=crop&w=1200&q=80",
|
||||
],
|
||||
};
|
||||
return mapping[slug] || [];
|
||||
};
|
||||
|
||||
export default function WorkDetailClient({ lang, dict, project, prev, next }: Props) {
|
||||
const heroRef = useRef<HTMLDivElement>(null);
|
||||
const { scrollYProgress } = useScroll({ target: heroRef, offset: ["start start", "end start"] });
|
||||
const heroY = useTransform(scrollYProgress, [0, 1], ["0%", "30%"]);
|
||||
|
||||
const [activeImage, setActiveImage] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") setActiveImage(null);
|
||||
};
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, []);
|
||||
|
||||
const accent = accentFor(project.tag);
|
||||
let screenshots = screenshotsFor(project.slug);
|
||||
if (project.gallery && project.gallery.length > 0) {
|
||||
screenshots = project.gallery;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-[#F4F0E8] text-[#0A0A0A] font-body min-h-screen">
|
||||
<Header lang={lang} dict={dict.nav} />
|
||||
|
||||
{/* ── HERO ── */}
|
||||
<section
|
||||
ref={heroRef}
|
||||
className="relative min-h-[70vh] flex flex-col justify-end overflow-hidden border-b border-[#C8C2B8]"
|
||||
>
|
||||
{/* Dot grid */}
|
||||
<motion.div
|
||||
className="absolute inset-0"
|
||||
style={{ y: heroY }}
|
||||
>
|
||||
{project.image ? (
|
||||
<>
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center"
|
||||
style={{ backgroundImage: `url(${project.image})` }}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-[#F4F0E8]/80" />
|
||||
</>
|
||||
) : (
|
||||
<div className="absolute inset-0 dot-grid opacity-50" />
|
||||
)}
|
||||
</motion.div>
|
||||
|
||||
{/* Accent left vertical bar */}
|
||||
<div className="absolute top-0 left-0 w-1 h-full" style={{ backgroundColor: accent }} />
|
||||
|
||||
{/* Big number watermark */}
|
||||
<motion.div
|
||||
className="absolute right-0 bottom-0 font-display font-black select-none pointer-events-none text-[#E8E3DC] leading-none"
|
||||
style={{ fontSize: "clamp(8rem, 25vw, 20rem)" }}
|
||||
initial={{ opacity: 0, x: 40 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 1, delay: 0.3 }}
|
||||
>
|
||||
{project.num}
|
||||
</motion.div>
|
||||
|
||||
<div className="relative z-10 max-w-7xl mx-auto px-6 w-full pb-16 pt-36">
|
||||
{/* Breadcrumb */}
|
||||
<motion.div
|
||||
className="flex items-center gap-3 mb-10"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ delay: 0.1 }}
|
||||
>
|
||||
<Link
|
||||
href={`/${lang}/work`}
|
||||
className="flex items-center gap-2 font-mono text-[10px] tracking-[0.25em] uppercase text-[#A0998E] hover:text-[#0A0A0A] transition-colors"
|
||||
>
|
||||
<IconArrowLeft /> {dict.nav.work}
|
||||
</Link>
|
||||
<span className="text-[#C8C2B8]">/</span>
|
||||
<span className="font-mono text-[10px] tracking-[0.25em] uppercase text-[#0A0A0A]">
|
||||
{project.num}
|
||||
</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Tag badge */}
|
||||
<motion.div
|
||||
className="mb-5"
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.2, duration: 0.5 }}
|
||||
>
|
||||
<span
|
||||
className="inline-block font-mono text-[10px] tracking-[0.25em] uppercase px-3 py-1.5 border border-[#C8C2B8]"
|
||||
style={{ borderLeftColor: accent, borderLeftWidth: 3 }}
|
||||
>
|
||||
{project.tag}
|
||||
</span>
|
||||
</motion.div>
|
||||
|
||||
{/* Title */}
|
||||
<div className="overflow-hidden mb-8">
|
||||
<motion.h1
|
||||
className="font-display font-black uppercase leading-[0.85] tracking-tight text-[#0A0A0A]"
|
||||
style={{ fontSize: "clamp(3rem, 8vw, 7rem)" }}
|
||||
initial={{ y: "110%" }}
|
||||
animate={{ y: 0 }}
|
||||
transition={{ duration: 0.85, ease: expo, delay: 0.25 }}
|
||||
>
|
||||
{project.title}
|
||||
</motion.h1>
|
||||
</div>
|
||||
|
||||
{/* Meta row */}
|
||||
<motion.div
|
||||
className="grid grid-cols-2 md:grid-cols-4 gap-px bg-[#C8C2B8] border-t border-[#C8C2B8]"
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.5, duration: 0.6 }}
|
||||
>
|
||||
{[
|
||||
{ label: lang === "tr" ? "Yıl" : "Year", value: project.year },
|
||||
{ label: lang === "tr" ? "Süre" : "Duration", value: project.duration },
|
||||
{ label: lang === "tr" ? "Sektör" : "Sector", value: project.tag },
|
||||
{ label: lang === "tr" ? "Müşteri" : "Client", value: project.client },
|
||||
].map((m, i) => (
|
||||
<div key={i} className="bg-[#F4F0E8] px-5 py-4">
|
||||
<div className="font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E] mb-1">{m.label}</div>
|
||||
<div className="font-display font-black text-[13px] uppercase text-[#0A0A0A] truncate">{m.value}</div>
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── CONTENT ── */}
|
||||
<main className="max-w-7xl mx-auto px-6 py-20">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-16">
|
||||
|
||||
{/* Left column: main content */}
|
||||
<div className="lg:col-span-8 space-y-20">
|
||||
|
||||
{/* Overview */}
|
||||
<motion.section
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.7 }}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-4 h-4 flex-shrink-0" style={{ backgroundColor: accent }} />
|
||||
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{lang === "tr" ? "Genel Bakış" : "Overview"}
|
||||
</span>
|
||||
<div className="flex-1 h-px bg-[#C8C2B8]" />
|
||||
</div>
|
||||
<p className="text-[#4A4440] text-lg leading-relaxed border-l-4 pl-6" style={{ borderColor: accent }}>
|
||||
{project.desc}
|
||||
</p>
|
||||
</motion.section>
|
||||
|
||||
{/* Challenge */}
|
||||
<motion.section
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.7 }}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-4 h-4 border-2 border-[#0A0A0A] flex-shrink-0" />
|
||||
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{lang === "tr" ? "Problem" : "The Challenge"}
|
||||
</span>
|
||||
<div className="flex-1 h-px bg-[#C8C2B8]" />
|
||||
</div>
|
||||
<h2 className="font-display font-black text-2xl uppercase text-[#0A0A0A] mb-4">
|
||||
{lang === "tr" ? "Ne Sorununu Çözdük?" : "What Problem Did We Solve?"}
|
||||
</h2>
|
||||
<p className="text-[#6A6460] leading-relaxed">
|
||||
{project.challenge}
|
||||
</p>
|
||||
</motion.section>
|
||||
|
||||
{/* Solution */}
|
||||
<motion.section
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.7 }}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-4 h-4 border-2 flex-shrink-0" style={{ borderColor: accent }} />
|
||||
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{lang === "tr" ? "Çözüm" : "Our Solution"}
|
||||
</span>
|
||||
<div className="flex-1 h-px bg-[#C8C2B8]" />
|
||||
</div>
|
||||
<h2 className="font-display font-black text-2xl uppercase text-[#0A0A0A] mb-4">
|
||||
{lang === "tr" ? "Nasıl İnşa Ettik?" : "How Did We Build It?"}
|
||||
</h2>
|
||||
<p className="text-[#6A6460] leading-relaxed">
|
||||
{project.solution}
|
||||
</p>
|
||||
</motion.section>
|
||||
|
||||
{/* Results */}
|
||||
<motion.section
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.7 }}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<div className="w-4 h-4 flex-shrink-0" style={{ backgroundColor: accent }} />
|
||||
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{lang === "tr" ? "Sonuçlar" : "Results"}
|
||||
</span>
|
||||
<div className="flex-1 h-px bg-[#C8C2B8]" />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-px bg-[#C8C2B8]">
|
||||
{project.results.map((r: string, idx: number) => (
|
||||
<motion.div
|
||||
key={idx}
|
||||
className="bg-[#F4F0E8] p-6 flex items-start gap-4 group"
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: idx * 0.1 }}
|
||||
whileHover={{ backgroundColor: "#EDE8E0" }}
|
||||
>
|
||||
<div
|
||||
className="w-6 h-6 flex-shrink-0 flex items-center justify-center mt-0.5"
|
||||
style={{ backgroundColor: accent }}
|
||||
>
|
||||
<IconCheck />
|
||||
</div>
|
||||
<p className="font-display font-bold text-[14px] uppercase text-[#0A0A0A] leading-snug">
|
||||
{r}
|
||||
</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.section>
|
||||
</div>
|
||||
|
||||
{/* Right column: sidebar */}
|
||||
<aside className="lg:col-span-4 space-y-0">
|
||||
<div className="sticky top-24">
|
||||
|
||||
{/* Perf spec */}
|
||||
<motion.div
|
||||
className="border border-[#C8C2B8] mb-px"
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.4 }}
|
||||
>
|
||||
<div className="border-b border-[#C8C2B8] px-6 py-3 flex items-center gap-2">
|
||||
<div className="w-2 h-2" style={{ backgroundColor: accent }} />
|
||||
<span className="font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{dict.work.specsLabel}
|
||||
</span>
|
||||
</div>
|
||||
<div className="px-6 py-5">
|
||||
<p className="font-display font-black text-sm uppercase text-[#0A0A0A] leading-snug">
|
||||
{project.spec}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Tech stack */}
|
||||
<motion.div
|
||||
className="border border-[#C8C2B8] mb-px"
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.5 }}
|
||||
>
|
||||
<div className="border-b border-[#C8C2B8] px-6 py-3">
|
||||
<span className="font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{lang === "tr" ? "Teknoloji Yığını" : "Tech Stack"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="px-6 py-5 flex flex-wrap gap-2">
|
||||
{project.tech.map((t: string) => (
|
||||
<span
|
||||
key={t}
|
||||
className="font-mono text-[10px] tracking-wider uppercase px-2.5 py-1.5 border border-[#C8C2B8] text-[#6A6460] hover:border-[#0A0A0A] hover:text-[#0A0A0A] transition-colors cursor-default"
|
||||
>
|
||||
{t}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Website */}
|
||||
{project.website && (
|
||||
<motion.div
|
||||
className="border border-[#C8C2B8] mb-px"
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.55 }}
|
||||
>
|
||||
<div className="border-b border-[#C8C2B8] px-6 py-3 flex items-center gap-2">
|
||||
<div className="w-2 h-2" style={{ backgroundColor: accent }} />
|
||||
<span className="font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{lang === "tr" ? "Canlı Proje" : "Live Project"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="px-6 py-5">
|
||||
<a
|
||||
href={project.website.startsWith('http') ? project.website : `https://${project.website}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-block font-mono text-[10px] tracking-wider uppercase px-4 py-2 border border-[#0A0A0A] hover:bg-[#0A0A0A] hover:text-[#FFE600] transition-colors cursor-pointer w-full text-center"
|
||||
>
|
||||
{lang === "tr" ? "Siteyi Ziyaret Et" : "Visit Website"}
|
||||
</a>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* CTA */}
|
||||
<motion.div
|
||||
className="border-2 border-[#0A0A0A] p-6"
|
||||
style={{ backgroundColor: accent }}
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.6 }}
|
||||
>
|
||||
<p className="font-display font-black text-sm uppercase text-[#0A0A0A] mb-4 leading-snug">
|
||||
{lang === "tr" ? "Benzer bir proje mi istiyorsunuz?" : "Want a similar project?"}
|
||||
</p>
|
||||
<Link
|
||||
href={`/${lang}/contact`}
|
||||
className="btn-brutal inline-flex items-center gap-2 px-5 py-3 font-display font-black text-[11px] tracking-widest uppercase cursor-pointer bg-[#0A0A0A] text-[#F4F0E8] border-[#0A0A0A]"
|
||||
>
|
||||
{dict.nav.quote} <IconArrowRight />
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* ── PROJECT SCREENSHOTS GALLERY ── */}
|
||||
{screenshots.length > 0 && (
|
||||
<section className="py-24 border-t border-[#C8C2B8] bg-[#EDE8E0]">
|
||||
<div className="max-w-7xl mx-auto px-6">
|
||||
<div className="flex items-center gap-3 mb-12">
|
||||
<div className="w-3 h-3" style={{ backgroundColor: accent }} />
|
||||
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{dict.work.galleryTitle || "EKRAN GÖRÜNTÜLERİ"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{screenshots.map((src, idx) => (
|
||||
<motion.div
|
||||
key={idx}
|
||||
className="group bg-[#F4F0E8] border border-[#C8C2B8] hover:border-[#0A0A0A] p-3 relative overflow-hidden transition-all duration-300 cursor-zoom-in"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: idx * 0.1, duration: 0.6 }}
|
||||
onClick={() => setActiveImage(src)}
|
||||
whileHover={{ y: -6, boxShadow: `4px 4px 0px 0px ${accent}` }}
|
||||
>
|
||||
<div className="aspect-[16/10] w-full overflow-hidden border border-[#C8C2B8] group-hover:border-[#0A0A0A] bg-[#EDE8E0] transition-colors relative">
|
||||
<img
|
||||
src={src}
|
||||
alt={`${project.title} screenshot ${idx + 1}`}
|
||||
className="w-full h-full object-cover grayscale group-hover:grayscale-0 contrast-[1.1] brightness-[0.98] group-hover:scale-105 transition-all duration-700"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-[#0A0A0A]/5 opacity-100 group-hover:opacity-0 transition-opacity duration-300" />
|
||||
</div>
|
||||
<div className="mt-3 flex justify-between items-center font-mono text-[9px] text-[#A0998E] group-hover:text-[#0A0A0A] transition-colors">
|
||||
<span>SCREEN // 0{idx + 1}</span>
|
||||
<span className="uppercase tracking-widest">[ ZOOM ]</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Lightbox Modal */}
|
||||
<AnimatePresence>
|
||||
{activeImage && (
|
||||
<motion.div
|
||||
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/85 backdrop-blur-md px-6 cursor-zoom-out"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={() => setActiveImage(null)}
|
||||
>
|
||||
<button
|
||||
onClick={() => setActiveImage(null)}
|
||||
className="absolute top-6 right-6 w-12 h-12 border border-white/20 hover:border-white/80 hover:bg-white/10 text-white flex items-center justify-center font-mono text-[10px] uppercase tracking-widest cursor-pointer transition-colors duration-200"
|
||||
>
|
||||
[ CLOSE ]
|
||||
</button>
|
||||
<motion.div
|
||||
className="max-w-5xl max-h-[85vh] border-2 border-white/10 bg-[#0A0A0A] p-2 relative"
|
||||
initial={{ scale: 0.9, y: 20 }}
|
||||
animate={{ scale: 1, y: 0 }}
|
||||
exit={{ scale: 0.9, y: 20 }}
|
||||
transition={{ duration: 0.4, ease: expo }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<img
|
||||
src={activeImage}
|
||||
alt="Enlarged project screenshot"
|
||||
className="max-w-full max-h-[80vh] object-contain block"
|
||||
/>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
{/* ── PREV / NEXT NAVIGATION ── */}
|
||||
<div className="border-t border-[#C8C2B8]">
|
||||
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-px bg-[#C8C2B8]">
|
||||
|
||||
{/* Prev */}
|
||||
<div>
|
||||
{prev ? (
|
||||
<Link
|
||||
href={`/${lang}/work/${prev.slug}`}
|
||||
className="group flex flex-col p-10 bg-[#F4F0E8] hover:bg-[#EDE8E0] transition-colors h-full"
|
||||
>
|
||||
<div className="flex items-center gap-2 font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E] group-hover:text-[#0A0A0A] transition-colors mb-4">
|
||||
<IconArrowLeft />
|
||||
{lang === "tr" ? "Önceki Proje" : "Previous Project"}
|
||||
</div>
|
||||
<div className="font-display font-black text-xl uppercase text-[#0A0A0A] mt-auto">
|
||||
{prev.title}
|
||||
</div>
|
||||
<div className="font-mono text-[10px] tracking-wider uppercase text-[#A0998E] mt-1">
|
||||
{prev.tag}
|
||||
</div>
|
||||
</Link>
|
||||
) : (
|
||||
<div className="p-10 bg-[#EDE8E0]" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Next */}
|
||||
<div>
|
||||
{next ? (
|
||||
<Link
|
||||
href={`/${lang}/work/${next.slug}`}
|
||||
className="group flex flex-col items-end p-10 bg-[#F4F0E8] hover:bg-[#EDE8E0] transition-colors h-full text-right"
|
||||
>
|
||||
<div className="flex items-center gap-2 font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E] group-hover:text-[#0A0A0A] transition-colors mb-4">
|
||||
{lang === "tr" ? "Sonraki Proje" : "Next Project"}
|
||||
<IconArrowRight />
|
||||
</div>
|
||||
<div className="font-display font-black text-xl uppercase text-[#0A0A0A] mt-auto">
|
||||
{next.title}
|
||||
</div>
|
||||
<div className="font-mono text-[10px] tracking-wider uppercase text-[#A0998E] mt-1">
|
||||
{next.tag}
|
||||
</div>
|
||||
</Link>
|
||||
) : (
|
||||
<Link
|
||||
href={`/${lang}/work`}
|
||||
className="group flex flex-col items-end p-10 bg-[#F4F0E8] hover:bg-[#EDE8E0] transition-colors h-full text-right"
|
||||
>
|
||||
<div className="flex items-center gap-2 font-mono text-[9px] tracking-[0.3em] uppercase text-[#A0998E] group-hover:text-[#0A0A0A] transition-colors mb-4">
|
||||
{lang === "tr" ? "Tüm Projeler" : "All Projects"}
|
||||
<IconArrowRight />
|
||||
</div>
|
||||
<div className="font-display font-black text-xl uppercase text-[#C8C2B8] mt-auto">
|
||||
{lang === "tr" ? "Portfolyo" : "Portfolio"}
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer lang={lang} dict={dict} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user