Files
einfach-produktiv/app/not-found.tsx
T
Marco e4a5ec1775 Fix 404 page: correct testimonial photo, micro-interactions, black CTAs
- Swap the testimonial band's placeholder photo for one cropped directly
  from the actual mockup pixels (mockups/einfach-produktiv_mockup_404.png)
  instead of reusing an unrelated existing site asset.
- Remove the search bar — no search backend exists to wire it to, so it
  was a dead decorative element.
- Add micro-interactions: main CTA arrow slides right on hover, sticky
  note un-rotates on hover, help-link cards lift + icon circle inverts to
  brand fill + arrow slides right on hover.
- Help-link CTAs ("Zur Startseite" etc.) now text-text-primary (black)
  instead of text-brand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 20:21:57 +00:00

223 lines
9.7 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 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 — drawn natively (rotated card + tape + Caveat
handwriting) rather than a cropped photo asset, since there's
no such image in /public and this reads just as well as a
coded illustration built from the same tokens (Lora for the
"404", Caveat for the handwritten line) the rest of the site
already uses for handwritten-style accents (see About.tsx's
signature quote). */}
<Reveal delay={0.15} className="w-full lg:flex-1 flex items-center justify-center">
<div className="relative w-full max-w-[22rem] aspect-square rotate-2 hover:rotate-0 rounded-sm bg-[#EDE3D0] shadow-modal p-8 flex flex-col items-center text-center transition-transform duration-300">
<div className="absolute -top-3 left-1/2 -translate-x-1/2 -rotate-3 w-16 h-6 bg-[#d8cdb8]/80" />
<p
className="font-bold text-text-primary text-[4.5rem] leading-none mt-6"
style={{ fontFamily: "var(--font-lora)" }}
>
404
</p>
<div className="h-[0.1875rem] w-24 bg-brand mt-3 mb-4" />
<p
className="text-text-primary text-[1.75rem] leading-[1.15]"
style={{ fontFamily: "var(--font-caveat)" }}
>
Nicht hier.
<br />
Aber dein Ziel ist
<br />
sicher nicht weit.
</p>
<svg viewBox="0 0 32 32" className="size-8 mt-4 text-text-primary" fill="none" aria-hidden="true">
<circle cx="11" cy="13" r="1.6" fill="currentColor" />
<circle cx="21" cy="13" r="1.6" fill="currentColor" />
<path d="M9 19c1.8 2.4 4.4 3.6 7 3.6s5.2-1.2 7-3.6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
</svg>
</div>
</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-colors duration-200 group-hover:bg-brand group-hover:text-text-primary">
{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.
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 min-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-0 w-full h-full 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-12">
<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 />
</>
);
}