Retour au catalogue
404 Illustrated
Page 404 avec illustration SVG decorative et liens de navigation.
error-pagessimple Both Responsive a11y
playfullightuniversalcentered
Theme
"use client";
import { motion } from "framer-motion";
import { Home, ArrowRight } from "lucide-react";
interface NavLink { label: string; href: string; }
interface Error404IllustratedProps {
title?: string;
description?: string;
ctaLabel?: string;
ctaUrl?: string;
links?: NavLink[];
}
const ease: [number, number, number, number] = [0.16, 1, 0.3, 1];
export default function Error404Illustrated({
title = "Oups ! Page introuvable",
description = "",
ctaLabel = "Retour",
ctaUrl = "/",
links = [],
}: Error404IllustratedProps) {
return (
<section className="min-h-screen flex items-center justify-center px-6" style={{ background: "var(--color-background)" }}>
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.6, ease }} className="text-center max-w-lg">
{/* SVG illustration */}
<svg className="w-48 h-48 mx-auto mb-8" viewBox="0 0 200 200" fill="none">
<circle cx="100" cy="100" r="80" stroke="var(--color-border)" strokeWidth="2" strokeDasharray="8 4" />
<text x="100" y="110" textAnchor="middle" fontSize="48" fontWeight="bold" fill="var(--color-accent)" opacity="0.6">404</text>
<circle cx="70" cy="80" r="5" fill="var(--color-foreground-light)" />
<circle cx="130" cy="80" r="5" fill="var(--color-foreground-light)" />
<path d="M 75 120 Q 100 110 125 120" stroke="var(--color-foreground-light)" strokeWidth="3" fill="none" strokeLinecap="round" />
</svg>
<h1 className="text-2xl md:text-3xl font-bold mb-3" style={{ color: "var(--color-foreground)" }}>{title}</h1>
{description && <p className="text-base mb-8" style={{ color: "var(--color-foreground-muted)" }}>{description}</p>}
<a href={ctaUrl} className="inline-flex items-center gap-2 px-6 py-3 rounded-lg text-sm font-semibold transition-opacity hover:opacity-90 mb-8" style={{ background: "var(--color-accent)", color: "var(--color-background)" }}>
<Home size={15} /> {ctaLabel}
</a>
{links.length > 0 && (
<div className="flex items-center justify-center gap-6">
{links.map((link) => (
<a key={link.label} href={link.href} className="flex items-center gap-1 text-sm font-medium hover:opacity-70 transition-opacity" style={{ color: "var(--color-foreground-muted)" }}>
{link.label} <ArrowRight size={12} />
</a>
))}
</div>
)}
</motion.div>
</section>
);
}