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>
This commit is contained in:
Marco
2026-07-19 20:21:57 +00:00
parent 0664e11d3b
commit e4a5ec1775
2 changed files with 28 additions and 20 deletions
+28 -20
View File
@@ -96,10 +96,15 @@ export default function NotFound() {
<p className="text-body text-text-muted">Aber kein Problem wir bringen dich gerne zurück auf Kurs.</p>
<Link
href="/"
className="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"
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" fill="none" aria-hidden="true">
<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>
@@ -113,7 +118,7 @@ export default function NotFound() {
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 rounded-sm bg-[#EDE3D0] shadow-modal p-8 flex flex-col items-center text-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"
@@ -141,7 +146,7 @@ export default function NotFound() {
</Reveal>
</div>
{/* Help links + search */}
{/* 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
@@ -155,41 +160,44 @@ export default function NotFound() {
<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="flex flex-col items-center text-center gap-3 pt-10 md:pt-0 first:pt-0 px-4">
<div className="flex size-14 items-center justify-center rounded-full bg-bg-muted text-brand">
<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-brand hover:underline">
<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" fill="none" aria-hidden="true">
<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>
<Reveal className="w-full max-w-[28rem]">
<div className="flex items-center gap-3 bg-bg-white border border-border rounded-sm px-6 py-3">
<svg viewBox="0 0 20 20" className="size-4 shrink-0 text-text-muted" fill="none" aria-hidden="true">
<circle cx="9" cy="9" r="6.5" stroke="currentColor" strokeWidth="1.6" />
<path d="m18 18-4-4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
</svg>
<span className="text-body text-text-muted">Suche nach Impulsen, Tools, Themen </span>
</div>
</Reveal>
</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. */}
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="/newsletter-modal-photo.jpg"
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" />