404 page
All checks were successful
Build / build (push) Successful in 10s

This commit is contained in:
Mike Karl 2026-06-29 20:46:52 +02:00
parent 54644e3195
commit 60e2aed9f9
3 changed files with 127 additions and 0 deletions

View file

@ -10,6 +10,7 @@ import ContactPage from "./pages/ContactPage";
import RaycasterPage from "./pages/project/RaycasterPage";
import RaytracerPage from "./pages/project/RaytracerPage";
import EmulatorPage from "./pages/project/EmulatorPage";
import NotFoundPage from "./pages/NotFoundPage";
export default function App() {
return (
@ -86,6 +87,14 @@ export default function App() {
</PageTransition>
)}
/>
<Route
path="*404"
component={() => (
<PageTransition>
<NotFoundPage />
</PageTransition>
)}
/>
</Route>
);
}

View file

@ -32,6 +32,20 @@ export const homeMetadata = {
"Mike Karl — Systementwickler & Creative Technologist aus Grafenau. Portfolio mit Projekten aus Systems Programming, Computer Graphics und Low-Level-Entwicklung.",
};
export const notFoundPage = {
metadata: {
title: "404 — Seite nicht gefunden",
description: "Die angeforderte Seite existiert nicht.",
},
label: "404 — Seite nicht gefunden",
title: "404",
subtitle: "Die angeforderte Route existiert nicht oder wurde verschoben.",
terminalPrompt: "$ navigate",
terminalError: "ENOENT — route not found",
homeCta: "Zur Startseite",
browseLabel: "Oder schau dich um:",
};
export const heroContent = {
subtitle: [
"Full-Stack Entwickler",

104
src/pages/NotFoundPage.tsx Normal file
View file

@ -0,0 +1,104 @@
import { A, useLocation } from "@solidjs/router";
import { For } from "solid-js";
import { ArrowRight, Home } from "lucide-solid";
import { usePageMeta } from "@/lib/meta";
import { navLinks, notFoundPage } from "@/data/site";
export default function NotFoundPage() {
const location = useLocation();
usePageMeta(
notFoundPage.metadata.title,
notFoundPage.metadata.description
);
return (
<main class="relative min-h-screen bg-deep-space overflow-hidden flex items-center">
<div
class="absolute inset-0 pointer-events-none"
style={{
background:
"radial-gradient(ellipse at 50% 30%, rgba(232,97,1,0.06) 0%, transparent 55%)",
}}
/>
<div
class="absolute inset-0 pointer-events-none"
style={{
background:
"linear-gradient(to bottom, transparent 60%, #0F0E0C 100%)",
}}
/>
<section class="relative z-10 w-full pt-32 pb-24 px-[5vw]">
<div class="max-w-[640px] mx-auto text-center space-y-8">
<p class="section-label">{notFoundPage.label}</p>
<h1
class="font-display font-bold text-text-primary leading-[0.85] tracking-tight"
style={{ "font-size": "clamp(5rem, 18vw, 9rem)" }}
>
{notFoundPage.title}
</h1>
<div class="flex items-center justify-center gap-4">
<div class="w-[60px] h-px bg-amber" />
<p class="font-mono text-text-secondary text-xs md:text-sm tracking-wider uppercase">
Not Found
</p>
<div class="w-[60px] h-px bg-amber" />
</div>
<p class="text-text-secondary text-lg leading-relaxed">
{notFoundPage.subtitle}
</p>
<div class="border border-warm-grey bg-charcoal p-5 md:p-6 text-left code-block">
<p class="text-text-secondary mb-3">
{notFoundPage.terminalPrompt}{" "}
<span class="text-text-primary">{location.pathname}</span>
</p>
<p>
<span class="keyword">Error</span>
{": "}
<span class="type">ENOENT</span>
<span class="text-text-secondary"> — </span>
<span class="string">{notFoundPage.terminalError}</span>
</p>
</div>
<div class="flex flex-col sm:flex-row items-center justify-center gap-4 pt-2">
<A
href="/"
class="inline-flex items-center gap-2 px-6 py-3 bg-amber text-deep-space font-display font-medium hover:bg-amber-hover transition-colors"
>
<Home size={18} />
{notFoundPage.homeCta}
</A>
</div>
<div class="pt-4 space-y-4">
<p class="font-mono text-text-secondary text-xs uppercase tracking-wider">
{notFoundPage.browseLabel}
</p>
<div class="flex flex-wrap items-center justify-center gap-3">
<For each={navLinks}>
{(link) => (
<A
href={link.href}
class="inline-flex items-center gap-1.5 text-sm text-text-secondary hover:text-amber transition-colors group"
>
<span class="text-link">{link.label}</span>
<ArrowRight
size={14}
class="opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all"
/>
</A>
)}
</For>
</div>
</div>
</div>
</section>
</main>
);
}