344b1701dd
Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
65 lines
3.6 KiB
TypeScript
65 lines
3.6 KiB
TypeScript
import type { Metadata } from "next";
|
|
import Link from "next/link";
|
|
import { SiteFooter, SiteNav, Wordmark, kicker, h1, body } from "@/components/site";
|
|
|
|
/* The 404 anyone reaches from a stale link, a typo, or a QR code printed before a route moved.
|
|
Until now this was Next's default black-on-white "404: This page could not be found." — no
|
|
wordmark, no navigation, and no way back into the site. */
|
|
export const metadata: Metadata = {
|
|
title: "Page not found",
|
|
robots: { index: false, follow: true },
|
|
};
|
|
|
|
const LINKS: [string, string, string][] = [
|
|
["Features", "/features", "What ThreadCount does"],
|
|
["How it works", "/how-it-works", "The shape of a working week"],
|
|
["Open the demo", "/demo", "A stocked linen room you can poke at"],
|
|
["Support", "/support", "If something here is broken"],
|
|
];
|
|
|
|
export default function NotFound() {
|
|
return (
|
|
<div style={{ fontFamily: "var(--font-body)", color: "var(--color-text)", background: "var(--color-bg)", minHeight: "100vh", display: "flex", flexDirection: "column" }}>
|
|
<SiteNav />
|
|
<div style={{ flex: 1 }}>
|
|
<section style={{ borderBottom: "2px solid var(--color-text)" }}>
|
|
<div style={{ maxWidth: 1440, margin: "0 auto", width: "100%", padding: "clamp(56px,8vw,96px) clamp(20px,5vw,40px) clamp(48px,6vw,72px)" }}>
|
|
<div style={{ ...kicker }}>Error 404</div>
|
|
<h1 style={{ ...h1, margin: "18px 0 0" }}>That page isn’t here.</h1>
|
|
<p style={{ ...body, fontSize: 17, maxWidth: "52ch", margin: "22px 0 0" }}>
|
|
The address is wrong, or the page has moved since whatever you followed was written.
|
|
Nothing has gone missing from anyone’s linen room — this is just the website.
|
|
</p>
|
|
<div style={{ width: 60, height: 4, background: "var(--color-accent)", margin: "26px 0 0" }} />
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<div style={{ maxWidth: 1440, margin: "0 auto", width: "100%", padding: "clamp(40px,5vw,64px) clamp(20px,5vw,40px) clamp(56px,7vw,88px)" }}>
|
|
<div style={{ fontSize: 11.5, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 800, borderBottom: "2px solid var(--color-text)", paddingBottom: 9 }}>
|
|
Where you were probably going
|
|
</div>
|
|
{/* A column gap is load-bearing here: each row pushes its arrow to the right edge of
|
|
its own cell, so without one the left column's arrow lands against the right
|
|
column's label. */}
|
|
<div className="tcm-2col" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", columnGap: 56, rowGap: 0, marginTop: 0 }}>
|
|
{LINKS.map(([label, href, note]) => (
|
|
<Link key={href} href={href} style={{ textDecoration: "none", color: "var(--color-text)", borderBottom: "1px solid var(--color-divider)", padding: "20px 0", display: "flex", alignItems: "baseline", gap: 14 }}>
|
|
<span style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: 19, letterSpacing: "-0.01em" }}>{label}</span>
|
|
<span style={{ fontSize: 14, color: "var(--color-neutral-700)" }}>{note}</span>
|
|
<span aria-hidden style={{ marginLeft: "auto", color: "var(--color-accent)", fontWeight: 800 }}>→</span>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
<div style={{ marginTop: 34 }}>
|
|
<Link href="/" className="btn btn-primary">Back to the start</Link>
|
|
</div>
|
|
<div style={{ marginTop: 40, opacity: 0.4 }}><Wordmark size={15} /></div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
<SiteFooter />
|
|
</div>
|
|
);
|
|
}
|