Files
sase.tr/apps/web/src/routes/index.tsx
Semih Yesilyurt 6f4d6eff5c fix(web): consistent SiteHeader across all public pages
Blog and contact (and about/pricing/legal) pages rendered a stripped-down
header (logo + auth buttons only) with no nav — the site nav "disappeared".
Extracted the landing header into a shared <SiteHeader> (logo, nav, theme
toggle, auth-aware actions, mobile menu) used on every public page for
consistent UX.

- new components/site-header.tsx (nav links work from any route via /#…)
- landing nav gains Blog + İletişim so all pages share the same 5-link nav
- about, contact, pricing, blog, blog/$slug, kvkk, privacy, terms → SiteHeader
- demo keeps its purpose-built demo header (sticky + theme + CTA)

typecheck + biome clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 19:45:21 +03:00

1877 lines
78 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { KEYS_17, dynamicKeys } from "@/lib/keys";
import { Button, Input, Separator } from "@sase/ui";
import { Link, createFileRoute, useNavigate } from "@tanstack/react-router";
import {
ArrowRight,
Car,
CheckCircle2,
ChevronRight,
Database,
FolderTree,
Gift,
Hash,
Loader2,
Menu,
MessageCircle,
Moon,
MousePointerClick,
Puzzle,
Search,
ShieldCheck,
ShoppingCart,
Sun,
Tag,
Wrench,
X,
Zap,
} from "lucide-react";
import { Suspense, lazy, useEffect, useRef, useState } from "react";
// Remotion — lazy loaded to keep initial bundle lean
const RemotionSchemaPlayer = lazy(() =>
Promise.all([import("@remotion/player"), import("@/remotion/SchemaDemo")]).then(
([{ Player }, { SchemaDemo }]) => ({
default: ({ isDark }: { isDark: boolean }) => (
<Player
component={SchemaDemo}
compositionWidth={400}
compositionHeight={300}
durationInFrames={240}
fps={30}
loop
autoPlay
style={{ width: "100%" }}
inputProps={{ isDark }}
acknowledgeRemotionLicense
/>
),
}),
),
);
const RemotionDashboardPlayer = lazy(() =>
Promise.all([import("@remotion/player"), import("@/remotion/DashboardDemo")]).then(
([{ Player }, { DashboardDemo }]) => ({
default: ({ isDark }: { isDark: boolean }) => (
<Player
component={DashboardDemo}
compositionWidth={960}
compositionHeight={540}
durationInFrames={450}
fps={30}
loop
autoPlay
style={{ width: "100%" }}
inputProps={{ isDark }}
acknowledgeRemotionLicense
/>
),
}),
),
);
const RemotionEcommercePlayer = lazy(() =>
Promise.all([import("@remotion/player"), import("@/remotion/EcommerceDemo")]).then(
([{ Player }, { EcommerceDemo }]) => ({
default: ({ isDark }: { isDark: boolean }) => (
<Player
component={EcommerceDemo}
compositionWidth={960}
compositionHeight={540}
durationInFrames={420}
fps={30}
loop
autoPlay
style={{ width: "100%" }}
inputProps={{ isDark }}
acknowledgeRemotionLicense
/>
),
}),
),
);
import { useAuth } from "@/hooks/use-auth";
import { usePageMeta } from "@/hooks/use-page-meta";
import { ApiError, api } from "@/lib/api-client";
import { capture } from "@/lib/posthog";
import { toast } from "@/lib/toast";
import { getUserSettings, setUserSetting } from "@/lib/user-settings";
import { useAuthStore } from "@/stores/auth.store";
// ─── DATA ────────────────────────────────────────────────────────────────────
const BRANDS = [
"BMW",
"Mercedes-Benz",
"Audi",
"VW",
"Fiat",
"Renault",
"Peugeot",
"Citroen",
"Toyota",
"Honda",
"Hyundai",
"Kia",
"Ford",
"Opel",
"Skoda",
"Seat",
"Volvo",
"Nissan",
"Mazda",
"Porsche",
"Land Rover",
"Jaguar",
"Mini",
"Dacia",
"Subaru",
"Suzuki",
"Mitsubishi",
];
const FEATURES = [
{
icon: Search,
title: "Şase Çözme",
description:
"Müşteri araç bilgisini tam bilmiyor mu? Şase numarasını girin — marka, model, motor, donanım saniyeler içinde karşınızda.",
bullets: [
"Marka, model ve yıl tespiti",
"Motor ve şanzıman detayları",
"Donanım paketi bilgileri",
],
mockupTitle: "Şase Çözme — Araç Bilgileri",
mockupContent: (
<div className="space-y-3 p-4">
<div className="flex items-center gap-2 rounded-lg bg-muted px-3 py-2 text-sm text-muted-foreground">
<Search className="size-4 text-muted-foreground" />
<span>WVWZZZ1JZ3W597935</span>
</div>
<div className="space-y-2">
{[
["Marka", "Volkswagen"],
["Model", "Golf"],
["Yıl", "2003"],
["Motor", "1.6 FSI"],
["Kasa", "Hatchback"],
].map(([k, v]) => (
<div key={k} className="flex justify-between rounded bg-muted/50 px-3 py-1.5 text-sm">
<span className="text-muted-foreground">{k}</span>
<span className="text-foreground">{v}</span>
</div>
))}
</div>
</div>
),
},
{
icon: MousePointerClick,
title: "İnteraktif Şema",
description:
"Parça kataloglarında kaybolmak yerine, tıklanabilir diyagramlarda parçayı görsel olarak bulun.",
bullets: ["Tıklanabilir parça diyagramları", "Zoom & pan navigasyon", "Alt kategori derinliği"],
mockupTitle: "İnteraktif Şema — Motor Bölgesi",
mockupContent: (isDark: boolean) => (
<Suspense
fallback={
<div className="flex h-[300px] items-center justify-center text-muted-foreground text-sm">
Yükleniyor
</div>
}
>
<RemotionSchemaPlayer isDark={isDark} />
</Suspense>
),
},
{
icon: Database,
title: "OEM Parça Numaraları",
description:
"Birden fazla katalogda çapraz sorgulama yaparak her zaman en güncel ve doğru OEM kodlarını sunar — yanlış parça, iade derdi tarih olur.",
bullets: [
"Çoklu katalog çapraz sorgulama",
"Her zaman güncel OEM kodları",
"Fiyat karşılaştırma",
],
mockupTitle: "OEM Katalog — Parça Listesi",
mockupContent: (
<div className="space-y-2 p-4">
{[
{ code: "1J0 820 803F", name: "Klima Kompresörü", qty: 1 },
{ code: "1J0 819 031A", name: "Kalorifer Motoru", qty: 1 },
{ code: "1J0 698 151G", name: "Ön Fren Balatası", qty: 4 },
].map((p) => (
<div
key={p.code}
className="flex items-center justify-between rounded-lg bg-muted/50 px-3 py-2 text-sm"
>
<div>
<span className="font-mono text-foreground">{p.code}</span>
<span className="ml-2 text-muted-foreground">{p.name}</span>
</div>
<span className="text-xs text-muted-foreground/70">×{p.qty}</span>
</div>
))}
</div>
),
},
];
const USE_CASES = [
{
icon: Search,
title: "Yedek Parça Arama",
description: "Şase numarası ile araç modelinize uygun orijinal parçaları anında bulun.",
},
{
icon: Tag,
title: "Orijinal Parça Numarası",
description: "OEM parça kodlarına erişerek doğru parçayı ilk seferde sipariş edin.",
},
{
icon: Car,
title: "Araç Tanımlama",
description: "Şase çözme ile aracın tüm teknik detaylarını ve donanım bilgilerini öğrenin.",
},
{
icon: ShieldCheck,
title: ıkma Parça Doğrulama",
description: "OEM kodlarıyla çıkma parçaların orijinalliğini ve uyumluluğunu kontrol edin.",
},
{
icon: Wrench,
title: "Servis & Bakım",
description: "Bakım planlarına uygun parça listeleriyle servis süreçlerini hızlandırın.",
},
];
const BENTO_ITEMS = [
{
icon: Search,
title: "Şase Girin",
description: "17 haneli şase numarasını girin, araç anında tanımlansın.",
stat: "<2sn",
wide: true,
},
{
icon: Car,
title: "27+ Marka",
description: "Avrupa, Asya ve Amerikan markaları tek çatı altında.",
stat: null,
wide: false,
},
{
icon: FolderTree,
title: "Kategorileri Seçin",
description: "Motor, şasi, elektrik... İstediğiniz parça kategorisine dalın.",
stat: null,
wide: false,
},
{
icon: MousePointerClick,
title: "Şema İnceleyin",
description: "İnteraktif teknik diyagramlarda parça konumlarını görsel olarak keşfedin.",
stat: null,
wide: true,
},
{
icon: Hash,
title: "OEM Kod Alın",
description: "Orijinal üretici parça numarasını kopyalayın, siparişe hazır olun.",
stat: null,
wide: true,
},
{
icon: ShoppingCart,
title: "Sipariş Verin",
description: "Doğru parça numarasıyla tedarikçilere hızlıca sipariş oluşturun.",
stat: null,
wide: false,
},
];
const STATS = [
{ value: "1.2sn", label: "Ortalama sorgu süresi" },
{ value: "27", label: "Desteklenen marka" },
{ value: "243K+", label: "OEM parça numarası" },
{ value: "%99.9", label: "Platform erişilebilirlik" },
];
const COMPARISON = [
{ label: "Parça arama süresi", manual: "~15 dakika", sase: "30 saniye" },
{ label: "Yanlış parça riski", manual: "Yüksek", sase: "Sıfıra yakın" },
{
label: "OEM kodu bulma",
manual: "Tek katalog, güncel olmayabilir",
sase: "Çoklu katalog çapraz sorgu",
},
{ label: "Fiyat karşılaştırma", manual: "İmkansız", sase: "Tek ekranda" },
{ label: "Aylık zaman tasarrufu", manual: "—", sase: "~40 saat" },
];
const TESTIMONIALS = [
{
name: "Ahmet Y.",
role: "Yedek Parça Mağazası Sahibi",
initials: "AY",
text: "Eskiden bir parça aramak için 3-4 katalog açıyordum. Sase.tr ile şase numarasını giriyorum, 30 saniyede doğru OEM kodunu buluyorum. İade oranımız %80 düştü.",
rating: 5,
},
{
name: "Mehmet K.",
role: "Oto Servis İşletmecisi",
initials: "MK",
text: "Sase.tr'ye geçtiğimizden beri yanlış parça siparişlerimiz neredeyse sıfıra indi. Aylık 40 saatin üzerinde zaman tasarrufu sağlıyoruz.",
rating: 5,
},
{
name: "Özge D.",
role: "E-Ticaret Yöneticisi",
initials: "ÖD",
text: "Online mağazamıza VIN entegrasyonu ekledik. Müşteriler şase numarasını giriyor, sadece uyumlu parçalar listeleniyor. İade oranımız %42 düştü.",
rating: 5,
},
{
name: "Burak T.",
role: "Filo Yöneticisi",
initials: "BT",
text: "200+ araçlık filomuz için parça yönetimi çok kolay hale geldi. Özellikle interaktif şema özelliği montaj sürecini çok hızlandırıyor.",
rating: 5,
},
];
// ─── HELPERS ─────────────────────────────────────────────────────────────────
function SectionBadge({ children }: { children: React.ReactNode }) {
return (
<span className="inline-flex items-center gap-2 rounded-full border border-border bg-muted px-4 py-1.5 text-xs font-medium text-muted-foreground">
{children}
</span>
);
}
function BrowserFrame({
title,
children,
}: {
title: string;
children: React.ReactNode;
}) {
return (
<div className="overflow-hidden rounded-xl border border-border bg-surface">
<div className="flex items-center gap-2 border-b border-border px-4 py-2.5">
<div className="flex gap-1.5">
<div className="size-3 rounded-full bg-muted-foreground/30" />
<div className="size-3 rounded-full bg-muted-foreground/30" />
<div className="size-3 rounded-full bg-muted-foreground/30" />
</div>
<div className="ml-2 flex-1 rounded-md bg-muted px-3 py-1 text-xs text-muted-foreground">
{title}
</div>
</div>
<div>{children}</div>
</div>
);
}
// ─── ROUTE ───────────────────────────────────────────────────────────────────
export const Route = createFileRoute("/")({
component: HomePage,
});
export function HomePage() {
usePageMeta({
title: "Şase Numarası Sorgulama & OEM Parça Kataloğu | Sase.tr",
description:
"Araç şase numarasını (VIN) girin, saniyeler içinde OEM parça kodlarına ulaşın. 27+ marka, 243.000+ parça. Yanlış sipariş yapmadan doğru parçayı bulun.",
canonical: "https://sase.tr",
});
useEffect(() => {
const schemas = [
{
"@context": "https://schema.org",
"@type": "Organization",
name: "Sase.tr",
url: "https://sase.tr",
email: "info@sase.tr",
description:
"Türkiye'nin VIN/şase numarası sorgulama ve OEM yedek parça kataloğu platformu.",
},
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: "Sase.tr",
applicationCategory: "BusinessApplication",
operatingSystem: "Web",
offers: {
"@type": "Offer",
price: "200",
priceCurrency: "TRY",
},
description: "Araç şase numarası ile OEM yedek parça sorgulama platformu.",
},
];
const scripts = schemas.map((schema) => {
const el = document.createElement("script");
el.type = "application/ld+json";
el.textContent = JSON.stringify(schema);
el.dataset.seoSchema = "true";
document.head.appendChild(el);
return el;
});
return () => {
for (const el of scripts) el.remove();
};
}, []);
const navigate = useNavigate();
const { isAuthenticated } = useAuth();
const [vin, setVin] = useState("");
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [isDark, setIsDark] = useState(() => {
const theme = getUserSettings().theme ?? "dark";
if (theme === "system") {
return window.matchMedia("(prefers-color-scheme: dark)").matches;
}
return theme === "dark";
});
const [vinPreview, setVinPreview] = useState<{
make: string;
model: string;
year: string;
engine: string;
} | null>(null);
const [vinLoading, setVinLoading] = useState(false);
const [vinError, setVinError] = useState(false);
const [decodeLoading, setDecodeLoading] = useState(false);
const toggleTheme = () => {
const next = isDark ? "light" : "dark";
document.documentElement.classList.toggle("dark", next === "dark");
setUserSetting("theme", next);
setIsDark(next === "dark");
};
// VIN preview via backend (pl24 + emex)
useEffect(() => {
if (vin.length !== 17) {
setVinPreview(null);
setVinError(false);
return;
}
const controller = new AbortController();
setVinLoading(true);
setVinError(false);
fetch(`/api/vehicles/preview/${vin}`, { signal: controller.signal })
.then((res) => {
if (!res.ok) throw new Error("Bulunamadı");
return res.json();
})
.then((data) => {
const r = data.data !== undefined ? data.data : data;
if (r?.brandName) {
setVinPreview({
make: r.brandName,
model: r.model || "—",
year: r.year ? String(r.year) : "—",
engine: r.engine || "—",
});
} else {
setVinError(true);
}
setVinLoading(false);
})
.catch((err) => {
if (err.name !== "AbortError") {
setVinError(true);
setVinLoading(false);
}
});
return () => controller.abort();
}, [vin]);
const handleVinSearch = async () => {
const trimmed = vin.trim();
if (!trimmed) return;
// Read latest auth state directly from store (avoids stale closure)
const { user, isLoading } = useAuthStore.getState();
// If session still loading, wait for it to resolve
if (isLoading) {
setDecodeLoading(true);
await new Promise<void>((resolve) => {
const unsub = useAuthStore.subscribe((state) => {
if (!state.isLoading) {
unsub();
resolve();
}
});
});
}
const loggedIn = !!useAuthStore.getState().user;
if (!loggedIn) {
setDecodeLoading(false);
navigate({ to: "/register", search: { vin: trimmed } });
return;
}
setDecodeLoading(true);
try {
const vehicle = await api.post<{ id: string }>("/vehicles/decode", { vin: trimmed });
capture("vin_decode_success", { vin: trimmed, source: "landing", vehicle_id: vehicle.id });
navigate({ to: "/dashboard/vehicles/$id", params: { id: vehicle.id } });
} catch (err) {
const message =
err instanceof ApiError ? err.message : "Bir hata oluştu. Lütfen tekrar deneyin.";
capture("vin_decode_error", { vin: trimmed, source: "landing", error: message });
if (err instanceof ApiError) {
if (err.status === 403) {
toast.error(message);
navigate({ to: "/dashboard/subscription" });
} else if (err.status === 400) {
toast.error(message);
} else {
toast.error(message);
}
} else {
toast.error(message);
}
} finally {
setDecodeLoading(false);
}
};
const fillExampleVin = () => {
setVin("WVWZZZ1JZ3W597935");
};
// ─── Social proof impression tracking ────────────────────────────────────
const heroBadgeRef = useRef<HTMLDivElement>(null);
const testimonialStripRef = useRef<HTMLDivElement>(null);
const testimonialsRef = useRef<HTMLElement>(null);
const heroBadgeFiredRef = useRef(false);
const testimonialStripFiredRef = useRef(false);
const testimonialsFiredRef = useRef(false);
useEffect(() => {
const el = heroBadgeRef.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !heroBadgeFiredRef.current) {
heroBadgeFiredRef.current = true;
capture("social_proof_impression", { page: "landing", section: "hero_badge" });
}
},
{ threshold: 0.5 },
);
observer.observe(el);
return () => observer.disconnect();
}, []);
useEffect(() => {
const el = testimonialStripRef.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !testimonialStripFiredRef.current) {
testimonialStripFiredRef.current = true;
capture("social_proof_impression", { page: "landing", section: "testimonial_strip" });
}
},
{ threshold: 0.5 },
);
observer.observe(el);
return () => observer.disconnect();
}, []);
useEffect(() => {
const el = testimonialsRef.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !testimonialsFiredRef.current) {
testimonialsFiredRef.current = true;
capture("social_proof_impression", { page: "landing", section: "testimonials" });
}
},
{ threshold: 0.5 },
);
observer.observe(el);
return () => observer.disconnect();
}, []);
function handleSocialProofEngaged(section: string) {
capture("social_proof_engaged", { page: "landing", section });
}
return (
<div className="min-h-screen bg-background text-foreground">
{/* ─── 1. STICKY HEADER ─────────────────────────────────────────── */}
<header className="sticky top-0 z-50 border-b border-border bg-background/80 backdrop-blur-md">
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6">
<Link to="/" className="text-xl font-bold tracking-wider">
SASE
</Link>
{/* Desktop nav */}
<nav className="hidden items-center gap-8 text-sm text-muted-foreground md:flex">
<a href="#features" className="transition hover:text-foreground">
Özellikler
</a>
<a href="#how-it-works" className="transition hover:text-foreground">
Nasıl Çalışır
</a>
<Link to="/pricing" className="transition hover:text-foreground">
Fiyatlar
</Link>
<Link to="/blog" className="transition hover:text-foreground">
Blog
</Link>
<Link to="/contact" className="transition hover:text-foreground">
İletişim
</Link>
</nav>
<div className="hidden items-center gap-3 md:flex">
<button
type="button"
onClick={toggleTheme}
className="inline-flex size-9 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
aria-label="Tema değiştir"
>
{isDark ? <Sun className="size-4" /> : <Moon className="size-4" />}
</button>
{isAuthenticated ? (
<Link to="/dashboard/search">
<Button className="rounded-full bg-foreground text-background hover:bg-foreground/90">
Panele Git
</Button>
</Link>
) : (
<>
<Link to="/login">
<Button
variant="outline"
data-faro-user-action-name="hero-login"
className="rounded-full border-border text-muted-foreground hover:bg-muted hover:text-foreground"
>
Giriş Yap
</Button>
</Link>
<Link to="/register">
<Button
data-faro-user-action-name="hero-register"
className="rounded-full bg-foreground text-background hover:bg-foreground/90"
>
30 Gün Ücretsiz Deneyin
</Button>
</Link>
</>
)}
</div>
{/* Mobile toggle */}
<div className="flex items-center gap-2 md:hidden">
<button
type="button"
onClick={toggleTheme}
className="inline-flex size-9 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
aria-label="Tema değiştir"
>
{isDark ? <Sun className="size-4" /> : <Moon className="size-4" />}
</button>
<button type="button" onClick={() => setMobileMenuOpen(!mobileMenuOpen)}>
{mobileMenuOpen ? <X className="size-6" /> : <Menu className="size-6" />}
</button>
</div>
</div>
{/* Mobile menu */}
{mobileMenuOpen && (
<div className="border-t border-border px-4 py-4 md:hidden">
<nav className="flex flex-col gap-3 text-sm text-muted-foreground">
<button
type="button"
className="text-left transition hover:text-foreground"
onClick={() => {
document.getElementById("features")?.scrollIntoView({ behavior: "smooth" });
setMobileMenuOpen(false);
}}
>
Özellikler
</button>
<button
type="button"
className="text-left transition hover:text-foreground"
onClick={() => {
document.getElementById("how-it-works")?.scrollIntoView({ behavior: "smooth" });
setMobileMenuOpen(false);
}}
>
Nasıl Çalışır
</button>
<Link
to="/pricing"
className="transition hover:text-foreground"
onClick={() => setMobileMenuOpen(false)}
>
Fiyatlar
</Link>
<Link
to="/blog"
className="transition hover:text-foreground"
onClick={() => setMobileMenuOpen(false)}
>
Blog
</Link>
<Link
to="/contact"
className="transition hover:text-foreground"
onClick={() => setMobileMenuOpen(false)}
>
İletişim
</Link>
<Separator className="bg-border" />
{isAuthenticated ? (
<Link to="/dashboard/search" onClick={() => setMobileMenuOpen(false)}>
<Button className="w-full rounded-full bg-foreground text-background">
Panele Git
</Button>
</Link>
) : (
<>
<Link to="/login" onClick={() => setMobileMenuOpen(false)}>
<Button
variant="outline"
className="w-full rounded-full border-border text-muted-foreground"
>
Giriş Yap
</Button>
</Link>
<Link to="/register" onClick={() => setMobileMenuOpen(false)}>
<Button className="w-full rounded-full bg-foreground text-background">
30 Gün Ücretsiz Deneyin
</Button>
</Link>
</>
)}
</nav>
</div>
)}
</header>
<main id="main-content">
{/* ─── 2. HERO SECTION ──────────────────────────────────────────── */}
<section className="relative overflow-hidden px-4 pb-16 pt-16 sm:px-6 sm:pt-24 lg:pt-28">
{/* Decorative glow */}
<div className="pointer-events-none absolute left-1/2 top-0 -translate-x-1/2">
<div className="h-[600px] w-[800px] rounded-full bg-foreground/[0.03] blur-3xl" />
</div>
<div className="relative mx-auto max-w-4xl text-center">
{/* Pill badge — loss framing */}
<div className="mb-4 inline-flex items-center gap-2 rounded-full border border-border bg-muted px-4 py-1.5 text-xs text-muted-foreground">
<span className="relative flex size-2">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-destructive/60 opacity-75" />
<span className="relative inline-flex size-2 rounded-full bg-destructive" />
</span>
Her yanlış parça siparişi ortalama 450 TL'ye mal olur
</div>
{/* Social proof badge */}
<div
ref={heroBadgeRef}
// biome-ignore lint/a11y/useSemanticElements: analytics-only interaction on content block
role="button"
tabIndex={0}
onClick={() => handleSocialProofEngaged("hero_badge")}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleSocialProofEngaged("hero_badge");
}
}}
className="mt-3 inline-flex cursor-pointer items-center gap-3 rounded-full border border-border bg-muted px-4 py-1.5 text-xs text-muted-foreground"
>
<div className="flex -space-x-2">
{["AY", "MK", "ÖD", "BT"].map((initials) => (
<div
key={initials}
className="flex size-6 items-center justify-center rounded-full border-2 border-background bg-muted text-[10px] font-medium"
>
{initials}
</div>
))}
</div>
<Separator orientation="vertical" className="h-4 bg-border" />
<span>⭐ 4.9/5</span>
<Separator orientation="vertical" className="h-4 bg-border" />
<span>500+ İşletme Güveniyor</span>
</div>
<h1 className="mt-6 font-[family-name:var(--font-display)] text-4xl font-bold leading-[1.1] tracking-tight sm:text-5xl lg:text-7xl">
Doğru Parçayı Anında Bulun
</h1>
<p className="mx-auto mt-6 max-w-2xl text-base text-muted-foreground sm:text-lg">
Birden fazla katalogda çapraz sorgulama ile her zaman en güncel OEM kodları. Şase
numarasını girin, doğru parçayı ilk seferde gönderin.
</p>
{/* VIN Input */}
<div className="mx-auto mt-8 flex max-w-xl flex-col gap-3 sm:flex-row">
<div className="relative flex-1">
<Search className="absolute left-4 top-1/2 size-5 -translate-y-1/2 text-muted-foreground" />
<Input
value={vin}
onChange={(e) => setVin(e.target.value.toUpperCase())}
placeholder="Örnek: WVWZZZ1JZ3W597935"
maxLength={17}
className="h-12 rounded-full border-border bg-muted pl-12 pr-4 font-mono text-sm text-foreground placeholder:text-muted-foreground/70 focus-visible:ring-ring sm:h-14 sm:text-base"
onKeyDown={(e) => e.key === "Enter" && handleVinSearch()}
/>
</div>
<Button
onClick={handleVinSearch}
disabled={decodeLoading}
data-faro-user-action-name="hero-vin-search"
className="h-12 rounded-full bg-foreground px-8 text-sm font-semibold text-background hover:bg-foreground/90 sm:h-14 sm:text-base"
>
{decodeLoading ? (
<>
<Loader2 className="mr-2 size-4 animate-spin" />
Çözülüyor...
</>
) : (
<>
Ara
<ArrowRight className="ml-2 size-4" />
</>
)}
</Button>
</div>
{/* VIN Progress Bar */}
<div className="mx-auto mt-3 flex max-w-xl gap-0.5 px-1">
{KEYS_17.map((k, i) => (
<div
key={k}
className={`h-1 flex-1 rounded-full transition-colors duration-200 ${
i < vin.length ? "bg-brand" : "bg-border"
}`}
/>
))}
</div>
{/* VIN Preview Card */}
{vinLoading && (
<div className="mx-auto mt-4 flex max-w-xl items-center justify-center gap-2 rounded-2xl border border-border bg-surface p-4">
<Loader2 className="size-5 animate-spin text-muted-foreground" />
<span className="text-sm text-muted-foreground">Araç bilgileri alınıyor...</span>
</div>
)}
{vinPreview && !vinLoading && (
<div className="animate-fade-in-up mx-auto mt-4 max-w-xl rounded-2xl border border-brand/30 bg-surface p-5 text-left">
<div className="flex flex-wrap items-center gap-3">
<Car className="size-5 text-brand" />
<span className="font-semibold text-foreground">
{vinPreview.make} {vinPreview.model}
</span>
<span className="text-sm text-muted-foreground">{vinPreview.year}</span>
{vinPreview.engine !== "—" && (
<span className="rounded-full bg-muted px-2.5 py-0.5 text-xs text-muted-foreground">
{vinPreview.engine}
</span>
)}
</div>
<div className="mt-3">
<Button
size="sm"
onClick={handleVinSearch}
disabled={decodeLoading}
variant="brand"
className="rounded-full"
>
{decodeLoading ? (
<>
<Loader2 className="mr-1.5 size-3.5 animate-spin" />
Çözülüyor...
</>
) : (
<>
{isAuthenticated ? "Parça kataloğunu aç" : "Tam parça kataloğuna eriş"}
<ArrowRight className="ml-1.5 size-3.5" />
</>
)}
</Button>
</div>
</div>
)}
{vinError && !vinLoading && (
<div className="mx-auto mt-4 max-w-xl rounded-2xl border border-border bg-surface p-4 text-center text-sm text-muted-foreground">
Şase bilgisi bulunamadı. Lütfen kontrol edip tekrar deneyin.
</div>
)}
{/* Example VIN invite */}
<p className="mt-4 text-sm text-muted-foreground">
Şase numaranız yok mu?{" "}
<button
type="button"
onClick={fillExampleVin}
data-faro-user-action-name="hero-free-trial"
className="text-foreground underline underline-offset-4 transition hover:text-foreground/80"
>
Örnek aramayı deneyin →
</button>
</p>
{/* Metric badges */}
<div className="mt-8 flex flex-wrap items-center justify-center gap-4 sm:gap-6">
{[
{ icon: Zap, label: "Ortalama 1.2sn Sonuç" },
{ icon: Car, label: "27 Marka Desteği" },
{ icon: Database, label: "243.000+ OEM Parça" },
].map(({ icon: Icon, label }) => (
<div
key={label}
className="flex items-center gap-2 rounded-full border border-border bg-muted/50 px-4 py-2 text-sm text-muted-foreground"
>
<Icon className="size-4 text-muted-foreground" />
{label}
</div>
))}
</div>
</div>
</section>
{/* ─── 3. MARKA CAROUSEL ────────────────────────────────────────── */}
<section className="border-y border-border py-12">
<div className="mx-auto max-w-7xl px-4 sm:px-6">
<p className="mb-8 text-center text-sm text-muted-foreground">
Desteklenen 27+ Otomobil Markası
</p>
</div>
<div className="carousel-track relative overflow-hidden">
{/* Gradient overlays */}
<div className="pointer-events-none absolute left-0 top-0 z-10 h-full w-24 bg-gradient-to-r from-background to-transparent" />
<div className="pointer-events-none absolute right-0 top-0 z-10 h-full w-24 bg-gradient-to-l from-background to-transparent" />
<div className="animate-scroll-left flex w-max gap-8 whitespace-nowrap">
{[...BRANDS.map((b) => `${b}::a`), ...BRANDS.map((b) => `${b}::b`)].map((id) => (
<span
key={id}
className="inline-block text-sm font-medium text-muted-foreground transition hover:text-foreground"
>
{id.split("::")[0]}
</span>
))}
</div>
</div>
</section>
{/* ─── 3.5. TESTIMONIAL STRIP ────────────────────────────────── */}
<section
ref={testimonialStripRef}
className="border-b border-border bg-background px-4 py-14 sm:px-6"
>
<div className="mx-auto max-w-7xl">
<div className="text-center">
<p className="text-sm text-muted-foreground">Kullanıcılarımız ne diyor?</p>
</div>
<div className="mt-8 grid grid-cols-1 gap-4 sm:grid-cols-3">
{[
{
text: "Sase.tr ile yanlış parça siparişlerimiz %80 azaldı. Artık gönül rahatlığıyla sipariş veriyoruz.",
name: "Ahmet Y.",
role: "Yedek Parça Mağazası",
},
{
text: "Ayda 40 saatten fazla zaman kazanıyoruz. Şase numarasını girip anında doğru koda ulaşmak inanılmaz.",
name: "Mehmet K.",
role: "Oto Servis İşletmecisi",
},
{
text: "Online mağazamıza entegre ettik, iade oranımız yarıya düştü. Müşteri memnuniyeti gözle görülür arttı.",
name: "Özge D.",
role: "E-Ticaret Yöneticisi",
},
].map((t) => (
<div
key={t.name}
// biome-ignore lint/a11y/useSemanticElements: analytics-only interaction on content block
role="button"
tabIndex={0}
onClick={() => handleSocialProofEngaged("testimonial_strip")}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleSocialProofEngaged("testimonial_strip");
}
}}
className="cursor-pointer rounded-2xl border border-border bg-surface px-6 py-5 transition-all duration-300 hover:-translate-y-0.5 hover:border-foreground/10"
>
<div className="flex gap-0.5">
{dynamicKeys(5).map((k) => (
<svg
role="img"
aria-label="icon"
key={k}
viewBox="0 0 20 20"
className="size-3 fill-foreground/60"
aria-hidden="true"
>
<path d="M9.05.927c.3-.921 1.603-.921 1.902 0l1.794 5.522a1 1 0 00.95.69h5.806c.969 0 1.371 1.24.588 1.81l-4.696 3.412a1 1 0 00-.363 1.118l1.793 5.522c.3.921-.755 1.688-1.539 1.118l-4.695-3.413a1 1 0 00-1.176 0l-4.695 3.413c-.784.57-1.838-.197-1.539-1.118l1.793-5.522a1 1 0 00-.363-1.118L2.31 8.95c-.783-.57-.38-1.81.588-1.81h5.807a1 1 0 00.95-.69L9.05.927z" />
</svg>
))}
</div>
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">
&ldquo;{t.text}&rdquo;
</p>
<p className="mt-3 text-xs text-muted-foreground/70">
{t.name} &mdash; {t.role}
</p>
</div>
))}
</div>
</div>
</section>
{/* ─── 4. ÇÖZÜMLER / ÖZELLİKLER ────────────────────────────────── */}
<section id="features" className="px-4 py-20 sm:px-6">
<div className="mx-auto max-w-7xl">
<div className="text-center">
<SectionBadge>Çözümlerimiz</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Şase Çözme & Parça Kataloğu
</h2>
<p className="mx-auto mt-4 max-w-2xl text-muted-foreground">
Araç tanımlamadan parça siparişine kadar tüm süreç tek platformda.
</p>
</div>
<div className="mt-12 space-y-8">
{FEATURES.map((feature, idx) => {
const reversed = idx === 1;
const Icon = feature.icon;
return (
<div
key={feature.title}
className="overflow-hidden rounded-2xl bg-surface p-6 sm:p-8 lg:p-12"
>
<div
className={`flex flex-col gap-8 lg:flex-row lg:items-center lg:gap-12 ${reversed ? "lg:flex-row-reverse" : ""}`}
>
{/* Text */}
<div className="flex-1 space-y-5">
<div className="inline-flex rounded-lg bg-muted p-2.5">
<Icon className="size-5 text-muted-foreground" />
</div>
<h3 className="font-[family-name:var(--font-display)] text-2xl font-bold sm:text-3xl">
{feature.title}
</h3>
<p className="text-muted-foreground">{feature.description}</p>
<ul className="space-y-2">
{feature.bullets.map((b) => (
<li
key={b}
className="flex items-center gap-2 text-sm text-muted-foreground"
>
<CheckCircle2 className="size-4 shrink-0 text-brand" />
{b}
</li>
))}
</ul>
<Link to="/register">
<Button
variant="outline"
className="mt-2 rounded-full border-border text-muted-foreground hover:bg-muted hover:text-foreground"
>
Hemen Deneyin
<ArrowRight className="ml-2 size-4" />
</Button>
</Link>
</div>
{/* Browser mockup */}
<div className="flex-1">
<BrowserFrame title={feature.mockupTitle}>
{typeof feature.mockupContent === "function"
? feature.mockupContent(isDark)
: feature.mockupContent}
</BrowserFrame>
</div>
</div>
</div>
);
})}
</div>
</div>
</section>
{/* ─── 5. KARŞILAŞTIRMA TABLOSU (YENİ) ─────────────────────────── */}
<section className="bg-surface-alt px-4 py-20 sm:px-6">
<div className="mx-auto max-w-4xl">
<div className="text-center">
<SectionBadge>Karşılaştırma</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Manuel Yöntem vs Sase.tr
</h2>
</div>
{/* Desktop: table */}
<div className="mt-12 hidden overflow-hidden rounded-2xl border border-border bg-surface sm:block">
<table className="w-full">
<thead>
<tr className="border-b border-border">
<th className="px-6 py-4 text-left text-sm font-medium text-muted-foreground" />
<th className="px-6 py-4 text-center text-sm font-medium text-muted-foreground">
Manuel
</th>
<th className="px-6 py-4 text-center text-sm font-semibold text-foreground">
Sase.tr
</th>
</tr>
</thead>
<tbody>
{COMPARISON.map((row, idx) => (
<tr
key={row.label}
className={idx < COMPARISON.length - 1 ? "border-b border-border" : ""}
>
<td className="px-6 py-4 text-sm font-medium text-foreground">{row.label}</td>
<td className="px-6 py-4 text-center text-sm text-muted-foreground">
{row.manual}
</td>
<td className="px-6 py-4 text-center text-sm font-medium text-brand">
{row.sase}
</td>
</tr>
))}
</tbody>
</table>
</div>
{/* Mobile: cards */}
<div className="mt-12 space-y-3 sm:hidden">
{COMPARISON.map((row) => (
<div key={row.label} className="rounded-xl border border-border bg-surface p-4">
<p className="text-sm font-medium text-foreground">{row.label}</p>
<div className="mt-3 grid grid-cols-2 gap-3">
<div className="rounded-lg bg-muted/50 p-2.5 text-center">
<p className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground/70">
Manuel
</p>
<p className="mt-1 text-sm text-muted-foreground">{row.manual}</p>
</div>
<div className="rounded-lg bg-brand/10 p-2.5 text-center">
<p className="text-[10px] font-medium uppercase tracking-wider text-brand/70">
Sase.tr
</p>
<p className="mt-1 text-sm font-medium text-brand">{row.sase}</p>
</div>
</div>
</div>
))}
</div>
</div>
</section>
{/* ─── 6. BENTO GRID — NASIL ÇALIŞIR ────────────────────────────── */}
<section id="how-it-works" className="px-4 py-20 sm:px-6">
<div className="mx-auto max-w-7xl">
<div className="text-center">
<SectionBadge>Nasıl Çalışır</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
3 Adımda Orijinal Parçaya Ulaşın
</h2>
</div>
<div className="mt-12 grid grid-cols-1 gap-4 sm:gap-6 md:grid-cols-3">
{BENTO_ITEMS.map((item) => {
const Icon = item.icon;
const wide = item.wide;
return (
<div
key={item.title}
className={`group relative overflow-hidden rounded-2xl border border-border bg-surface p-6 transition-all duration-300 hover:-translate-y-1 hover:border-foreground/20 hover:shadow-[var(--shadow-md)] sm:p-8 ${wide ? "md:col-span-2" : "md:col-span-1"}`}
>
<div className="mb-4 inline-flex rounded-lg bg-muted p-2.5 text-muted-foreground transition-colors duration-300 group-hover:bg-foreground group-hover:text-background">
<Icon className="size-5" />
</div>
<h3 className="text-lg font-semibold tracking-tight">{item.title}</h3>
<p className="mt-2 text-sm text-muted-foreground">{item.description}</p>
{item.stat && (
<p className="mt-4 font-[family-name:var(--font-display)] text-4xl font-bold tabular tracking-tight">
{item.stat}
</p>
)}
</div>
);
})}
</div>
</div>
</section>
{/* ─── 7. KULLANIM ALANLARI ─────────────────────────────────────── */}
<section className="bg-surface-alt px-4 py-20 sm:px-6">
<div className="mx-auto max-w-7xl">
<div className="text-center">
<SectionBadge>Kullanım Alanları</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Kimler İçin?
</h2>
</div>
<div className="mt-12 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
{USE_CASES.map((uc, idx) => {
const Icon = uc.icon;
return (
<div
key={uc.title}
className={`group relative rounded-2xl border border-border bg-surface p-6 transition-all duration-300 hover:-translate-y-1 hover:border-foreground/20 hover:shadow-[var(--shadow-md)] ${idx % 2 === 1 ? "lg:translate-y-6" : ""}`}
>
<div className="mb-4 inline-flex rounded-lg bg-muted p-2.5 text-muted-foreground transition-colors duration-300 group-hover:bg-foreground group-hover:text-background">
<Icon className="size-5" />
</div>
<h3 className="text-lg font-semibold tracking-tight">{uc.title}</h3>
<p className="mt-2 text-sm text-muted-foreground">{uc.description}</p>
</div>
);
})}
{/* CTA card */}
<div className="flex flex-col items-start justify-between rounded-2xl border border-dashed border-border bg-surface p-6">
<div>
<div className="mb-4 inline-flex rounded-lg bg-muted p-2.5">
<MessageCircle className="size-5 text-muted-foreground" />
</div>
<h3 className="text-lg font-semibold">Farklı bir ihtiyacınız mı var?</h3>
<p className="mt-2 text-sm text-muted-foreground">
Özel entegrasyon veya toplu sorgulama ihtiyacınız varsa bize ulaşın.
</p>
</div>
<Button
variant="outline"
className="mt-4 rounded-full border-border text-muted-foreground hover:bg-muted hover:text-foreground"
>
Bize Ulaşın
<ChevronRight className="ml-1 size-4" />
</Button>
</div>
</div>
</div>
</section>
{/* ─── 8. RAKAMLARLA SASE.TR ────────────────────────────────────── */}
<section className="relative overflow-hidden bg-foreground px-4 py-24 text-background sm:px-6">
{/* Ambient grid pattern — breaks digital flatness */}
<div className="pointer-events-none absolute inset-0 opacity-[0.04]">
<svg width="100%" height="100%" aria-hidden="true">
<defs>
<pattern id="stats-grid" width="48" height="48" patternUnits="userSpaceOnUse">
<path d="M 48 0 L 0 0 0 48" fill="none" stroke="currentColor" strokeWidth="1" />
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#stats-grid)" />
</svg>
</div>
{/* Brand accent glow */}
<div className="pointer-events-none absolute -left-32 top-1/2 h-[400px] w-[400px] -translate-y-1/2 rounded-full bg-brand/20 blur-[120px]" />
<div className="pointer-events-none absolute -right-32 top-0 h-[300px] w-[300px] rounded-full bg-brand/10 blur-[100px]" />
<div className="relative mx-auto max-w-7xl">
<div className="max-w-2xl">
<span className="inline-flex items-center gap-2 rounded-full border border-background/15 bg-background/5 px-4 py-1.5 text-xs font-medium text-background/70 backdrop-blur-sm">
<span className="size-1.5 rounded-full bg-brand" />
Platform
</span>
<h2 className="mt-5 font-[family-name:var(--font-display)] text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
Rakamlarla
<br />
<span className="text-background/50">Sase.tr</span>
</h2>
</div>
<div className="mt-14 grid grid-cols-2 gap-px overflow-hidden rounded-2xl border border-background/10 bg-background/10 lg:grid-cols-4">
{STATS.map((stat) => (
<div
key={stat.label}
className="group relative bg-foreground p-7 transition-colors duration-300 hover:bg-background/[0.04] sm:p-9"
>
<p className="font-[family-name:var(--font-display)] text-5xl font-bold tracking-tight tabular sm:text-6xl">
{stat.value}
</p>
<p className="mt-3 text-sm text-background/60">{stat.label}</p>
<div className="absolute bottom-0 left-0 h-px w-0 bg-brand transition-all duration-500 group-hover:w-full" />
</div>
))}
</div>
</div>
</section>
{/* ─── 9. DASHBOARD SHOWCASE ────────────────────────────────────── */}
<section className="relative overflow-hidden bg-surface-alt px-4 py-20 sm:px-6">
{/* Decorative circles */}
<div className="pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
<div className="size-[600px] rounded-full border border-border/50" />
<div className="absolute inset-8 rounded-full border border-border/30" />
<div className="absolute inset-16 rounded-full border border-border/20" />
</div>
<div className="relative mx-auto max-w-5xl text-center">
<h2 className="font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Tüm Veriler, Tek Platform
</h2>
<p className="mx-auto mt-4 max-w-xl text-muted-foreground">
Şase çözme, parça kataloğu ve interaktif şemalar tek bir arayüzde.
</p>
<div className="relative mt-12">
<BrowserFrame title="sase.tr/dashboard">
<Suspense
fallback={
<div className="flex h-[540px] items-center justify-center text-muted-foreground text-sm">
Yükleniyor…
</div>
}
>
<RemotionDashboardPlayer isDark={isDark} />
</Suspense>
</BrowserFrame>
{/* Floating labels */}
<div className="animate-float absolute -left-2 top-1/4 rounded-lg border border-border bg-surface px-3 py-1.5 text-xs font-medium shadow-lg sm:-left-4">
Şase Arama
</div>
<div
className="animate-float absolute -right-2 top-1/3 rounded-lg border border-border bg-surface px-3 py-1.5 text-xs font-medium shadow-lg sm:-right-4"
style={{ animationDelay: "1s" }}
>
İnteraktif Şema
</div>
<div
className="animate-float absolute -bottom-2 left-1/4 rounded-lg border border-border bg-surface px-3 py-1.5 text-xs font-medium shadow-lg"
style={{ animationDelay: "2s" }}
>
OEM Kodları
</div>
</div>
</div>
</section>
{/* ─── 9.5. E-TİCARET ENTEGRASYONU ────────────────────────────── */}
<section className="px-4 py-20 sm:px-6">
<div className="mx-auto max-w-7xl">
<div className="text-center">
<SectionBadge>E-Ticaret Entegrasyonu</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Kendi Sitenize Şase Çözme Gücü Katın
</h2>
<p className="mx-auto mt-4 max-w-2xl text-muted-foreground">
Müşterileriniz yanlış parça sipariş edip iade mi açıyor? Sase.tr entegrasyonu ile
VIN bazlı filtreleme ekleyin — iadeler düşsün, dönüşüm artsın.
</p>
</div>
<div className="mt-12 overflow-hidden rounded-2xl bg-surface p-6 sm:p-8 lg:p-12">
<div className="flex flex-col gap-8 lg:flex-row lg:items-center lg:gap-12">
{/* Left — Video */}
<div className="flex-1">
<BrowserFrame title="otoyedekparca.co — Sase.tr Entegrasyonu">
<Suspense
fallback={
<div className="flex h-[540px] items-center justify-center text-muted-foreground text-sm">
Yükleniyor…
</div>
}
>
<RemotionEcommercePlayer isDark={isDark} />
</Suspense>
</BrowserFrame>
</div>
{/* Right — Text + Bullets + CTA */}
<div className="flex-1 space-y-5">
<div className="inline-flex items-center gap-2 rounded-lg bg-muted px-3 py-1.5 text-sm text-muted-foreground">
<Puzzle className="size-4" />
Kolay Entegrasyon
</div>
<h3 className="font-[family-name:var(--font-display)] text-2xl font-bold sm:text-3xl">
Birkaç Satır Kod, Büyük Fark
</h3>
<p className="text-muted-foreground">
E-ticaret sitenize Sase.tr'nin VIN çözme motorunu entegre edin. Müşterileriniz
şase numarasını girsin sadece araçlarına uygun parçalar listelensin.
</p>
<ul className="space-y-2">
{[
"API & Widget — Birkaç satır kodla sitenize entegre edin",
"VIN Bazlı Filtreleme — Sadece uyumlu parçalar görünsün",
"İade Oranını Düşürün — Doğru parça, ilk seferde",
"White-Label — Widget sitenizin tasarımına uyum sağlar",
].map((b) => (
<li key={b} className="flex items-center gap-2 text-sm text-muted-foreground">
<CheckCircle2 className="size-4 shrink-0 text-brand" />
{b}
</li>
))}
</ul>
<Link to="/contact">
<Button
variant="outline"
className="mt-2 rounded-full border-border text-muted-foreground hover:bg-muted hover:text-foreground"
>
İletişime Geçin
<ArrowRight className="ml-2 size-4" />
</Button>
</Link>
</div>
</div>
</div>
{/* Stats grid */}
<div className="mt-8 grid grid-cols-1 gap-4 sm:grid-cols-3">
{[
{ value: "%42", label: "Daha Az İade" },
{ value: "%35", label: "Daha Yüksek Dönüşüm" },
{ value: "<30dk", label: "Entegrasyon Süresi" },
].map((stat) => (
<div
key={stat.label}
className="rounded-2xl border border-border bg-surface p-6 sm:p-8 text-center"
>
<p className="font-[family-name:var(--font-display)] text-3xl font-bold text-brand sm:text-4xl">
{stat.value}
</p>
<p className="mt-2 text-sm text-muted-foreground">{stat.label}</p>
</div>
))}
</div>
</div>
</section>
{/* ─── 9.6. TESTIMONIALS ────────────────────────────────────── */}
<section ref={testimonialsRef} className="bg-surface-alt px-4 py-20 sm:px-6">
<div className="mx-auto max-w-7xl">
<div className="text-center">
<SectionBadge>Müşteri Yorumları</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
İşletme Sahipleri Ne Diyor?
</h2>
</div>
<div className="mt-12 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{TESTIMONIALS.map((t) => (
<div
key={t.name}
// biome-ignore lint/a11y/useSemanticElements: analytics-only interaction on content block
role="button"
tabIndex={0}
onClick={() => handleSocialProofEngaged("testimonials")}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleSocialProofEngaged("testimonials");
}
}}
className="group cursor-pointer rounded-2xl border border-border bg-surface p-6 transition-all duration-300 hover:-translate-y-1 hover:border-foreground/20 hover:shadow-[var(--shadow-md)]"
>
<div className="flex gap-0.5">
{dynamicKeys(t.rating).map((k) => (
<svg
role="img"
aria-label="icon"
key={k}
viewBox="0 0 20 20"
className="size-3.5 fill-foreground/85"
aria-hidden="true"
>
<path d="M9.05.927c.3-.921 1.603-.921 1.902 0l1.794 5.522a1 1 0 00.95.69h5.806c.969 0 1.371 1.24.588 1.81l-4.696 3.412a1 1 0 00-.363 1.118l1.793 5.522c.3.921-.755 1.688-1.539 1.118l-4.695-3.413a1 1 0 00-1.176 0l-4.695 3.413c-.784.57-1.838-.197-1.539-1.118l1.793-5.522a1 1 0 00-.363-1.118L2.31 8.95c-.783-.57-.38-1.81.588-1.81h5.807a1 1 0 00.95-.69L9.05.927z" />
</svg>
))}
</div>
<p className="mt-4 text-sm leading-relaxed text-muted-foreground">
&ldquo;{t.text}&rdquo;
</p>
<div className="mt-4 flex items-center gap-3">
<div className="flex size-10 items-center justify-center rounded-full bg-muted text-sm font-medium">
{t.initials}
</div>
<div>
<p className="text-sm font-medium">{t.name}</p>
<p className="text-xs text-muted-foreground">{t.role}</p>
</div>
</div>
</div>
))}
</div>
</div>
</section>
{/* ─── 10. PRICING ─────────────────────────────────────────────── */}
<section className="px-4 py-24 sm:px-6">
<div className="mx-auto max-w-6xl">
<div className="max-w-2xl">
<SectionBadge>Fiyatlandırma</SectionBadge>
<h2 className="mt-4 font-[family-name:var(--font-display)] text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl">
Günde 7 TL'den
<br />
<span className="text-muted-foreground">başlayan fiyatlar.</span>
</h2>
<p className="mt-5 max-w-xl text-base text-muted-foreground">
Tek bir yanlış parça iadesinin maliyetinden daha az. Tüm planlarda 30 gün ücretsiz
deneme var, kart bilgisi gerekmez.
</p>
</div>
{/* Tier tiles — horizontal row, compact, breaks 4-tower symmetry */}
<div className="mt-14 grid grid-cols-1 gap-4 sm:grid-cols-3 sm:gap-5">
{[
{
name: "1 Marka",
description: "Tek marka için erişim",
price: "200",
yearly: "2.000",
features: [
"1 marka seçimi",
"Sınırsız VIN arama",
"Parça kataloğu",
"Şema görüntüleyici",
],
},
{
name: "2 Marka",
description: "İki farklı marka",
price: "350",
yearly: "3.500",
features: [
"2 marka seçimi",
"Sınırsız VIN arama",
"Parça kataloğu",
"Öncelikli destek",
],
},
{
name: "3 Marka",
description: "Üç marka kapsamlı",
price: "500",
yearly: "5.000",
features: [
"3 marka seçimi",
"Sınırsız VIN arama",
"Parça kataloğu",
"Öncelikli destek",
],
},
].map((plan, idx) => (
<div
key={plan.name}
className={`group relative flex flex-col rounded-2xl border border-border bg-surface p-7 transition-all duration-300 hover:-translate-y-1 hover:border-foreground/20 hover:shadow-[var(--shadow-md)] ${idx === 1 ? "sm:translate-y-3" : ""} ${idx === 2 ? "sm:translate-y-6" : ""}`}
>
<div className="flex items-baseline justify-between">
<h3 className="font-[family-name:var(--font-display)] text-lg font-semibold">
{plan.name}
</h3>
<span className="text-xs text-muted-foreground tabular">/ay</span>
</div>
<p className="mt-1 text-sm text-muted-foreground">{plan.description}</p>
<div className="mt-5 flex items-baseline gap-1">
<span className="font-[family-name:var(--font-display)] text-4xl font-bold tabular tracking-tight">
{plan.price}
</span>
<span className="text-base font-medium text-muted-foreground">TL</span>
</div>
<p className="mt-1 text-xs text-muted-foreground tabular">
yıllık {plan.yearly} TL
</p>
<ul className="mt-6 flex-1 space-y-2.5 text-sm">
{plan.features.map((f) => (
<li key={f} className="flex items-start gap-2 text-muted-foreground">
<CheckCircle2 className="mt-0.5 size-4 shrink-0 text-foreground/40" />
<span>{f}</span>
</li>
))}
</ul>
<Link to="/register" className="mt-7">
<Button variant="outline" className="w-full rounded-full">
30 gün ücretsiz dene
</Button>
</Link>
</div>
))}
</div>
{/* Hero plan — Full Paket, asymmetric horizontal card with brand emphasis */}
<div className="mt-8 sm:mt-10">
<div className="relative overflow-hidden rounded-2xl border border-foreground/10 bg-foreground text-background shadow-[var(--shadow-lg)]">
{/* Brand accent glow */}
<div className="pointer-events-none absolute -right-32 top-1/2 h-[400px] w-[400px] -translate-y-1/2 rounded-full bg-brand/30 blur-[120px]" />
<div className="pointer-events-none absolute -left-24 -top-24 h-[300px] w-[300px] rounded-full bg-brand/15 blur-[100px]" />
<div className="relative grid gap-8 p-8 sm:p-10 lg:grid-cols-[1.1fr_1fr] lg:gap-12 lg:p-14">
{/* Left: pitch + price */}
<div>
<div className="inline-flex items-center gap-2 rounded-full border border-background/15 bg-background/5 px-3 py-1 text-xs font-medium text-background/80 backdrop-blur-sm">
<span className="size-1.5 rounded-full bg-brand" />
En çok tercih edilen
</div>
<h3 className="mt-5 font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl">
Full Paket
</h3>
<p className="mt-2 max-w-md text-background/70">
Tüm markalara sınırsız erişim. Tek bir aboneliğe sığdırdık.
</p>
<div className="mt-7 flex items-baseline gap-2">
<span className="font-[family-name:var(--font-display)] text-6xl font-bold tabular tracking-tight">
999
</span>
<span className="text-lg font-medium text-background/60">TL/ay</span>
</div>
<p className="mt-1 text-sm text-background/50 tabular">
yıllık 9.990 TL — ayda 832 TL'ye denk gelir
</p>
<Link to="/register" className="mt-8 inline-block">
<Button variant="brand" size="lg" className="rounded-full">
30 gün ücretsiz dene
<ArrowRight className="ml-2 size-4" />
</Button>
</Link>
<p className="mt-3 text-xs text-background/50">
Kart bilgisi gerekmez. İstediğin zaman iptal et.
</p>
</div>
{/* Right: feature list, two columns */}
<div className="border-t border-background/10 pt-8 lg:border-l lg:border-t-0 lg:pl-12 lg:pt-0">
<p className="text-xs font-medium uppercase tracking-wider text-background/50">
Pakete dahil
</p>
<ul className="mt-5 grid grid-cols-1 gap-x-6 gap-y-3 sm:grid-cols-2">
{[
"Tüm 27+ markaya erişim",
"Sınırsız VIN arama",
"OEM parça kataloğu",
"İnteraktif şema görüntüleyici",
"Geçmiş sorgular & favoriler",
"Öncelikli e-posta desteği",
"API erişimi (talep üzerine)",
"Toplu sorgu özelliği",
].map((f) => (
<li key={f} className="flex items-start gap-2.5 text-sm text-background/85">
<CheckCircle2 className="mt-0.5 size-4 shrink-0 text-brand" />
<span>{f}</span>
</li>
))}
</ul>
</div>
</div>
</div>
</div>
<div className="mt-10 flex items-center justify-center">
<Link
to="/pricing"
className="inline-flex items-center gap-1.5 rounded-full border border-border px-4 py-2 text-sm text-muted-foreground transition-all duration-200 hover:-translate-y-0.5 hover:border-foreground/30 hover:text-foreground hover:shadow-sm"
>
Detaylı karşılaştırmayı gör
<ArrowRight className="size-3.5" />
</Link>
</div>
</div>
</section>
{/* ─── 11. REFERRAL BANNER (YENİ) ───────────────────────────────── */}
<section className="px-4 py-10 sm:px-6">
<div className="mx-auto max-w-4xl overflow-hidden rounded-2xl border border-border bg-surface p-8 sm:p-12">
<div className="flex flex-col items-center gap-6 text-center sm:flex-row sm:text-left">
<div className="flex size-14 shrink-0 items-center justify-center rounded-xl bg-muted">
<Gift className="size-6 text-muted-foreground" />
</div>
<div className="flex-1">
<h3 className="font-[family-name:var(--font-display)] text-xl font-bold sm:text-2xl">
Arkadaşını Davet Et
</h3>
<p className="mt-2 text-sm text-muted-foreground">
3 davet = +7 gün ücretsiz, 5 davet = +1 ay ücretsiz
</p>
</div>
<Link to="/register">
<Button className="shrink-0 rounded-full bg-foreground text-background hover:bg-foreground/90">
Davet Kodunuzu Alın
<ArrowRight className="ml-2 size-4" />
</Button>
</Link>
</div>
</div>
</section>
{/* ─── 12. SON CTA ──────────────────────────────────────────────── */}
<section className="relative overflow-hidden bg-surface-alt px-4 py-20 sm:px-6 sm:py-24">
{/* SVG grid pattern */}
<div className="pointer-events-none absolute inset-0 opacity-[0.03]">
<svg width="100%" height="100%" role="img" aria-label="grid pattern">
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="currentColor" strokeWidth="1" />
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</svg>
</div>
{/* Blur glow */}
<div className="pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
<div className="h-[400px] w-[600px] rounded-full bg-foreground/[0.02] blur-3xl" />
</div>
<div className="relative mx-auto max-w-3xl text-center">
<h2 className="font-[family-name:var(--font-display)] text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
Her Yanlış Parça Size 200-500 TL'ye Mal Oluyor
</h2>
<p className="mx-auto mt-6 max-w-xl text-muted-foreground">
İade kargosu, müşteri kaybı, zaman kaybı. Şase çözme ile ilk seferde doğru parçayı
bulun.
</p>
<Link to="/register">
<Button
variant="outline"
className="mt-8 rounded-full border-border px-8 py-3 text-base text-foreground hover:bg-foreground hover:text-background"
>
Ücretsiz Deneyin Kart Gerekmez
<ArrowRight className="ml-2 size-4" />
</Button>
</Link>
</div>
</section>
</main>
{/* ─── 13. FOOTER ───────────────────────────────────────────────── */}
<footer className="bg-background px-4 sm:px-6">
<div className="mx-auto max-w-7xl">
<div className="grid grid-cols-2 gap-8 py-16 sm:grid-cols-4">
{/* Brand */}
<div className="col-span-2 sm:col-span-1">
<span className="text-lg font-bold">Sase.tr</span>
<p className="mt-3 text-sm text-muted-foreground">
Şase çözme & orijinal yedek parça kataloğu platformu.
</p>
<p className="mt-2 text-sm text-muted-foreground/70">info@sase.tr</p>
</div>
{/* Product */}
<div>
<h4 className="text-sm font-semibold text-muted-foreground">Ürün</h4>
<ul className="mt-3 space-y-2 text-sm text-muted-foreground">
<li>
<a href="#features" className="transition hover:text-foreground">
Şase Çözme
</a>
</li>
<li>
<a href="#features" className="transition hover:text-foreground">
Parça Kataloğu
</a>
</li>
<li>
<a href="#features" className="transition hover:text-foreground">
İnteraktif Şema
</a>
</li>
<li>
<Link to="/pricing" className="transition hover:text-foreground">
Fiyatlar
</Link>
</li>
</ul>
</div>
{/* Company */}
<div>
<h4 className="text-sm font-semibold text-muted-foreground">Şirket</h4>
<ul className="mt-3 space-y-2 text-sm text-muted-foreground">
<li>
<Link to="/about" className="transition hover:text-foreground">
Hakkımızda
</Link>
</li>
<li>
<Link to="/blog" className="transition hover:text-foreground">
Blog
</Link>
</li>
<li>
<Link to="/contact" className="transition hover:text-foreground">
İletişim
</Link>
</li>
</ul>
</div>
{/* Legal */}
<div>
<h4 className="text-sm font-semibold text-muted-foreground">Yasal</h4>
<ul className="mt-3 space-y-2 text-sm text-muted-foreground">
<li>
<Link to="/privacy" className="transition hover:text-foreground">
Gizlilik Politikası
</Link>
</li>
<li>
<Link to="/terms" className="transition hover:text-foreground">
Kullanım Koşulları
</Link>
</li>
<li>
<Link to="/kvkk" className="transition hover:text-foreground">
KVKK
</Link>
</li>
</ul>
</div>
</div>
<Separator className="bg-border" />
<div className="flex flex-col items-center justify-between gap-4 py-6 sm:flex-row">
<div className="flex flex-col items-center gap-3 sm:flex-row">
<p className="text-sm text-muted-foreground/70">
&copy; {new Date().getFullYear()} Sase.tr. Tüm hakları saklıdır.
</p>
<div className="flex items-center gap-2 text-sm text-muted-foreground/70">
<span className="size-2 rounded-full bg-brand" />
Tüm servisler aktif
</div>
</div>
<div className="flex items-center gap-4 text-muted-foreground/70">
<a href="mailto:info@sase.tr" className="text-sm transition hover:text-foreground">
info@sase.tr
</a>
</div>
</div>
</div>
</footer>
</div>
);
}