import { cn } from "~/utils/cn";
type Props = {
status: number;
title: string;
description: React.ReactNode;
/** A git-style output line shown above the status, e.g. `fatal: couldn't find remote ref`. */
command: string;
/** Extra technical context (e.g. the server's message). */
detail?: string | null;
actions: React.ReactNode;
tone?: "accent" | "danger";
};
/** A branch that leaves main and ends at a dashed, detached commit — the visual for every error page. */
function DetachedBranch({ tone }: { tone: "accent" | "danger" }) {
const stroke = tone === "danger" ? "stroke-danger-400" : "stroke-accent-500";
return (
<svg viewBox="0 0 240 200" aria-hidden="true" className="w-full max-w-xs">
<path d="M40 10V190" className="stroke-gray-800" strokeWidth="3" fill="none" strokeLinecap="round" />
<path
d="M40 70c0 40 120 20 120 70"
className={cn("animate-graph-draw", stroke)}
strokeWidth="3"
fill="none"
strokeLinecap="round"
/>
<path d="M160 140v20" className={stroke} strokeWidth="3" strokeDasharray="4 6" strokeLinecap="round" />
{[30, 70, 130, 170].map((y) => (
<circle key={y} cx="40" cy={y} r="7" className="fill-gray-950 stroke-gray-700" strokeWidth="3" />
))}
<circle cx="160" cy="176" r="12" className={cn("fill-gray-950", stroke)} strokeWidth="3" strokeDasharray="5 5" />
</svg>
);
}
export function ErrorScreen({ status, title, description, command, detail, actions, tone = "accent" }: Props) {
return (
<div>
<div className="mx-auto grid max-w-5xl items-center gap-12 px-6 py-20 md:grid-cols-[1fr_auto] md:py-28">