From 575b50cc5e497033485ac6576e801c6529f8e872 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 12:37:28 +0000 Subject: [PATCH] Add a real 404 page with explorer search + home button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces Next.js's default plain-text 404 with one that matches the site's hero treatment: leaf-anchored eyebrow, gradient serif headline ("Lost in the Atmosphere."), short explainer, the explorer's SearchBox inline (so a mistyped handle is one keystroke from resolving), and Home + Explore buttons. Lives at src/app/not-found.tsx so it covers every Next.js 404 — the notFound() helper, missing dynamic routes, mistyped paths. --- src/app/not-found.tsx | 142 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/app/not-found.tsx diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 0000000..0c08cf9 --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,142 @@ +'use client'; + +import Link from 'next/link'; +import { motion } from 'framer-motion'; +import { ArrowLeft, Leaf, Telescope } from 'lucide-react'; +import Header from '@/components/Header'; +import SearchBox from '@/components/explore/SearchBox'; + +/** + * Global 404 page. Next.js falls back to its plain-text default when this + * file is absent; this version mirrors the site's hero treatment so a + * mistyped URL doesn't read as a regression to a different product. + * + * Bias toward "give the visitor a way out": leaf-anchored eyebrow, big + * serif headline, two-line explainer, the explorer's SearchBox (so a + * fat-fingered handle is one re-keystroke away from working), and a Home + * button next to a /explore link. + */ +export default function NotFound() { + return ( +
+
+
+
+ + + {/* Eyebrow */} +
+ + 404 · Not found +
+ +

+ + Lost in the Atmosphere. + +

+ +

+ The path you tried didn’t resolve. Search for a handle, DID, or + AT URI to keep looking — or head home. +

+ + {/* Search */} +
+ +
+ + {/* Quick actions */} +
+ + Home + + + Explore + +
+
+
+ ); +} + +const primaryBtn: React.CSSProperties = { + display: 'inline-flex', + alignItems: 'center', + gap: '0.4rem', + padding: '0.55rem 1rem', + background: 'var(--accent-moss)', + color: 'var(--text-on-accent)', + border: '1px solid var(--accent-moss)', + fontFamily: 'var(--font-serif)', + fontSize: '0.875rem', + textDecoration: 'none', +}; + +const ghostBtn: React.CSSProperties = { + display: 'inline-flex', + alignItems: 'center', + gap: '0.4rem', + padding: '0.55rem 1rem', + background: 'var(--bg-tertiary)', + color: 'var(--text-primary)', + border: '1px solid var(--border-medium)', + fontFamily: 'var(--font-serif)', + fontSize: '0.875rem', + textDecoration: 'none', +}; -- 2.51.2