ec016d55d4
Same fixed-height + -inset-1 treatment as page-bestellbestaetigung's own testimonial band, and the same class of top-edge boundary artifact turned up in 404-testimonial-photo.jpg too (invisible in a downscaled preview, visible once object-cover scales it up in the browser) — re-cropped 15px further down to clear it. Also shrunk both pages' testimonial band from h-[20rem]/24rem to h-[14rem]/16rem — the taller version left too much empty vertical space around the 3-line quote. feat(cart): show the -XX% sale badge on cart line-item photos too Same badge already used in the shop grid/spotlight/todo-cards pricing panel, now also on /cart's product thumbnails when that item has a compareAtPrice set.
206 lines
8.8 KiB
TypeScript
206 lines
8.8 KiB
TypeScript
import type { Metadata } from "next";
|
||
import Link from "next/link";
|
||
import { Reveal, RevealGroup, RevealItem } from "./components/Reveal";
|
||
import { Footer } from "./components/Footer";
|
||
import { TrustRow } from "./components/TrustRow";
|
||
|
||
export const metadata: Metadata = {
|
||
title: "Seite nicht gefunden",
|
||
description: "Diese Seite ist gerade nicht dort, wo sie sein sollte.",
|
||
robots: { index: false, follow: true },
|
||
};
|
||
|
||
const helpLinks = [
|
||
{
|
||
href: "/",
|
||
title: "Startseite",
|
||
desc: "Zurück zu den wichtigsten Inhalten und Angeboten.",
|
||
cta: "Zur Startseite",
|
||
icon: (
|
||
<svg viewBox="0 0 24 24" className="size-6" fill="none" aria-hidden="true">
|
||
<path
|
||
d="M4 11.5 12 4l8 7.5M6 9.5V20h5v-5.5h2V20h5V9.5"
|
||
stroke="currentColor"
|
||
strokeWidth="1.6"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
/>
|
||
</svg>
|
||
),
|
||
},
|
||
{
|
||
href: "/blog",
|
||
title: "Im Blog stöbern",
|
||
desc: "Lass dich von Impulsen, Methoden und Gedanken inspirieren.",
|
||
cta: "Zum Blog",
|
||
icon: (
|
||
<svg viewBox="0 0 24 24" className="size-6" fill="none" aria-hidden="true">
|
||
<path
|
||
d="M6 3.5h9.5L20 8v12.5a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-16a1 1 0 0 1 1-1Z"
|
||
stroke="currentColor"
|
||
strokeWidth="1.6"
|
||
strokeLinejoin="round"
|
||
/>
|
||
<path d="M8.5 9.5h7M8.5 13h7M8.5 16.5h4.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
|
||
</svg>
|
||
),
|
||
},
|
||
{
|
||
href: "/#werkzeuge",
|
||
title: "Werkzeuge entdecken",
|
||
desc: "Praktische Tools für mehr Fokus, Struktur und Klarheit.",
|
||
cta: "Zu den Werkzeugen",
|
||
icon: (
|
||
<svg viewBox="0 0 24 24" className="size-6" fill="none" aria-hidden="true">
|
||
<path
|
||
d="M4 9.5h16a1 1 0 0 1 1 1V19a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-8.5a1 1 0 0 1 1-1Z"
|
||
stroke="currentColor"
|
||
strokeWidth="1.6"
|
||
strokeLinejoin="round"
|
||
/>
|
||
<path
|
||
d="M8.5 9.5V7a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v2.5"
|
||
stroke="currentColor"
|
||
strokeWidth="1.6"
|
||
strokeLinejoin="round"
|
||
/>
|
||
</svg>
|
||
),
|
||
},
|
||
];
|
||
|
||
export default function NotFound() {
|
||
return (
|
||
<>
|
||
<main className="flex flex-col flex-1 bg-bg-base">
|
||
{/* Hero — eyebrow / Ups. / subheading / copy / CTA, sticky note beside it */}
|
||
<div className="flex flex-col lg:flex-row gap-12 lg:gap-16 items-center pt-16 pb-20 px-[var(--layout-padding-x)] w-full">
|
||
<Reveal className="flex flex-col gap-4 items-start w-full lg:flex-1 max-w-[32rem]">
|
||
<p className="font-semibold text-body-sm text-brand tracking-wide">404 – Seite nicht gefunden</p>
|
||
<p
|
||
className="font-semibold text-[3.5rem] leading-[1.05] text-text-primary"
|
||
style={{ fontFamily: "var(--font-lora)" }}
|
||
>
|
||
Ups.
|
||
</p>
|
||
<p
|
||
className="font-semibold text-h-feature text-text-primary"
|
||
style={{ fontFamily: "var(--font-lora)" }}
|
||
>
|
||
Diese Seite ist gerade nicht dort, wo sie sein sollte.
|
||
</p>
|
||
<div className="h-[0.125rem] w-8 bg-brand" />
|
||
<p className="text-body text-text-muted">
|
||
Vielleicht wurde sie verschoben, umbenannt oder es hat sich ein kleiner Tippfehler eingeschlichen.
|
||
</p>
|
||
<p className="text-body text-text-muted">Aber kein Problem – wir bringen dich gerne zurück auf Kurs.</p>
|
||
<Link
|
||
href="/"
|
||
className="group flex items-center gap-2 mt-2 px-7 py-4 rounded-sm bg-brand text-h4 font-bold text-text-primary hover:bg-brand-hover active:scale-[0.97] transition-all"
|
||
>
|
||
Zur Startseite
|
||
<svg
|
||
viewBox="0 0 20 20"
|
||
className="size-4 transition-transform duration-200 group-hover:translate-x-1"
|
||
fill="none"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" />
|
||
</svg>
|
||
</Link>
|
||
</Reveal>
|
||
|
||
{/* Sticky note — real asset exported straight from the built
|
||
Figma page (page-404, node 4693:382), not a hand-coded
|
||
approximation — matches project convention of using the
|
||
actual photographed/rendered note rather than recreating its
|
||
handwriting in CSS. */}
|
||
<Reveal delay={0.15} className="w-full lg:flex-1 flex items-center justify-center">
|
||
<img
|
||
alt="Sticky Note: 404. Nicht hier. Aber dein Ziel ist sicher nicht weit."
|
||
src="/404-sticky-note.png"
|
||
className="w-full max-w-[22rem] rotate-2 hover:rotate-0 transition-transform duration-300"
|
||
/>
|
||
</Reveal>
|
||
</div>
|
||
|
||
{/* Help links */}
|
||
<div className="flex flex-col gap-10 items-center pb-16 px-[var(--layout-padding-x)] w-full">
|
||
<Reveal className="flex flex-col items-center gap-2">
|
||
<p
|
||
className="font-semibold text-h-small text-text-primary"
|
||
style={{ fontFamily: "var(--font-lora)" }}
|
||
>
|
||
Vielleicht hilft dir das weiter:
|
||
</p>
|
||
<div className="h-[0.125rem] w-8 bg-brand" />
|
||
</Reveal>
|
||
|
||
<RevealGroup className="grid grid-cols-1 md:grid-cols-3 gap-10 md:gap-8 w-full max-w-[64rem] divide-y md:divide-y-0 md:divide-x divide-border">
|
||
{helpLinks.map((link) => (
|
||
<RevealItem
|
||
key={link.href}
|
||
className="group flex flex-col items-center text-center gap-3 pt-10 md:pt-0 first:pt-0 px-4 transition-transform duration-200 hover:-translate-y-1"
|
||
>
|
||
<div className="flex size-14 items-center justify-center rounded-full bg-bg-muted text-brand transition-transform duration-300 group-hover:scale-110">
|
||
{link.icon}
|
||
</div>
|
||
<p className="font-semibold text-body text-text-primary">{link.title}</p>
|
||
<p className="text-body-sm text-text-muted">{link.desc}</p>
|
||
<Link href={link.href} className="flex items-center gap-1.5 text-body-sm font-semibold text-text-primary hover:underline">
|
||
{link.cta}
|
||
<svg
|
||
viewBox="0 0 20 20"
|
||
className="size-3.5 transition-transform duration-200 group-hover:translate-x-1"
|
||
fill="none"
|
||
aria-hidden="true"
|
||
>
|
||
<path d="M4 10h12m0 0-5-5m5 5-5 5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||
</svg>
|
||
</Link>
|
||
</RevealItem>
|
||
))}
|
||
</RevealGroup>
|
||
</div>
|
||
|
||
{/* Testimonial band — photo bleeds to the viewport edge, gradient
|
||
fade into bg-base on its trailing edge instead of a hard cut,
|
||
same idea as page-bestellbestaetigung's photo+quote pattern
|
||
(see that page's own comment for the fixed-h-/-inset-1
|
||
reasoning — a min-height alone lets whichever column has more
|
||
content stretch the row past what the other side visually
|
||
fills, and a plain inset-0 image can show a hairline gap at
|
||
the container edge). 404-testimonial-photo.jpg is cropped
|
||
directly from the actual mockup pixels
|
||
(mockups/einfach-produktiv_mockup_404.png) rather than
|
||
reusing an unrelated existing asset — same real-photo
|
||
extraction convention the Figma rebuild used, just done on
|
||
the flat mockup image instead of in Figma. */}
|
||
<Reveal className="relative w-full flex items-stretch h-[14rem] md:h-[16rem] bg-bg-muted overflow-hidden">
|
||
<div className="relative w-full md:w-[45%] shrink-0">
|
||
<img
|
||
alt=""
|
||
src="/404-testimonial-photo.jpg"
|
||
className="absolute -inset-1 w-[calc(100%+0.5rem)] h-[calc(100%+0.5rem)] object-cover"
|
||
/>
|
||
<div className="hidden md:block absolute inset-y-0 right-0 w-40 bg-gradient-to-l from-bg-muted to-transparent" />
|
||
</div>
|
||
<div className="flex-1 flex flex-col justify-center gap-3 px-8 md:px-16 py-6">
|
||
<p
|
||
className="font-semibold text-h-section text-text-primary leading-[1.3] max-w-[28rem]"
|
||
style={{ fontFamily: "var(--font-lora)" }}
|
||
>
|
||
„Manchmal führt der falsche Weg zu neuen klaren Gedanken.“
|
||
</p>
|
||
<div className="h-[0.125rem] w-8 bg-brand" />
|
||
<p className="text-body text-text-muted">Björn</p>
|
||
</div>
|
||
</Reveal>
|
||
|
||
<TrustRow />
|
||
</main>
|
||
<Footer />
|
||
</>
|
||
);
|
||
}
|