c8fa2e8b52
Deploy to route.crispygoat.com / deploy (push) Successful in 4m33s
- Remove Google Fonts @import from 4 components (SiteHeader, LandingPageWrapper, TestimonialsAndCTA, FeaturesAndStats) — eliminate render-blocking external request and font flash - Replace all unloaded Cormorant Garamond / Playfair Display / DM Sans / Plus Jakarta Sans references with the existing next/font variables (Fraunces, Manrope, Fragment_Mono) — visual coherence with the design system - Update 9 pages (blog, brands, changelog, maintenance, protected-example, roadmap, security, waitlist, WaitlistForm) to use the loaded Fraunces - Fix dead --font-geist / --font-jetbrains-mono references in admin-design-system.css (now point to --font-manrope / --font-fragment-mono which are actually loaded) - Add atelier-pill, atelier-numerals, atelier-fineprint, atelier-canvas-soft utility classes; .atelier-input:focus-visible refined ring - Add .ha-field-textarea, .ha-scroll, .ha-skeleton to admin design system - Extend prefers-reduced-motion guard to atelier-enter/stagger/shimmer - Apply atelier-fineprint to login/not-found/error pages for consistency - No structural changes; build passes, 0 type errors
93 lines
3.6 KiB
TypeScript
93 lines
3.6 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useEffect } from "react";
|
|
|
|
/**
|
|
* Root error boundary — the safety net for any uncaught error in the
|
|
* app. Renders inside the root layout, so it inherits the same font
|
|
* variables and design tokens as everything else.
|
|
*/
|
|
export default function ErrorPage({
|
|
error,
|
|
reset,
|
|
}: {
|
|
error: Error & { digest?: string };
|
|
reset: () => void;
|
|
}) {
|
|
useEffect(() => {
|
|
// Surface to the console for development; the Sentry-ready logger
|
|
// in src/lib/sentry.ts can be wired in here when keys are configured.
|
|
// eslint-disable-next-line no-console
|
|
console.error("[app/error]", error);
|
|
}, [error]);
|
|
|
|
return (
|
|
<main className="atelier-canvas relative min-h-screen flex items-center justify-center px-6 py-16 overflow-hidden">
|
|
<div className="atelier-grain" aria-hidden="true" />
|
|
|
|
{/* Ambient orbs */}
|
|
<div className="pointer-events-none absolute inset-0 overflow-hidden" aria-hidden="true">
|
|
<div
|
|
className="absolute top-1/4 left-1/4 w-96 h-96 rounded-full opacity-30"
|
|
style={{ background: "radial-gradient(circle, rgba(185, 28, 28, 0.12) 0%, transparent 70%)", filter: "blur(48px)" }}
|
|
/>
|
|
<div
|
|
className="absolute bottom-1/4 right-1/4 w-96 h-96 rounded-full opacity-20"
|
|
style={{ background: "radial-gradient(circle, rgba(202, 138, 4, 0.16) 0%, transparent 70%)", filter: "blur(48px)" }}
|
|
/>
|
|
</div>
|
|
|
|
<div className="relative z-10 max-w-md w-full text-center atelier-enter">
|
|
<div className="atelier-section-num justify-center mb-4">No. 500</div>
|
|
|
|
<h1 className="atelier-title text-5xl sm:text-6xl">
|
|
Something <span className="atelier-italic text-[#786B53]">broke</span>
|
|
</h1>
|
|
<p className="mt-4 text-stone-600 text-sm leading-relaxed">
|
|
We hit an unexpected snag loading this page. Our harvest crew has been notified.
|
|
</p>
|
|
|
|
{error.message && (
|
|
<details className="mt-6 text-left">
|
|
<summary className="atelier-fineprint cursor-pointer hover:text-stone-900 transition-colors">
|
|
Error details
|
|
</summary>
|
|
<div className="mt-3 rounded-lg border border-stone-200 bg-white/70 backdrop-blur-sm p-3.5 text-xs font-mono text-stone-700 break-words">
|
|
{error.message}
|
|
{error.digest && (
|
|
<div className="mt-2 pt-2 border-t border-stone-200 text-stone-500">
|
|
digest: <span className="text-stone-700">{error.digest}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</details>
|
|
)}
|
|
|
|
<div className="atelier-rule my-8" />
|
|
|
|
<div className="flex flex-col sm:flex-row items-stretch sm:items-center justify-center gap-3">
|
|
<button
|
|
type="button"
|
|
onClick={reset}
|
|
className="atelier-cta"
|
|
aria-label="Retry loading this page"
|
|
>
|
|
<svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} aria-hidden="true">
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
</svg>
|
|
<span className="relative z-10">Try again</span>
|
|
<span className="atelier-cta-shimmer" aria-hidden="true" />
|
|
</button>
|
|
<Link
|
|
href="/"
|
|
className="atelier-discard text-center"
|
|
>
|
|
← Return home
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|