Custom Frutiger Aero 404

app/not-found.tsx renders a standalone screen: the root layout's ice
scene is the backdrop, the glass card/rim/bubbles come from the shared
recipes (full Aero with that theme on, frosted glass in light/dark),
and the mascot is the scene's glossy ice orb at full strength with a
snowflake and a "404" chip. Two ways out - back to the library and
into the chat - both 44px targets, en + cs.

The regression suite pins the 404 status, both links and the Czech
copy; the pixel-contrast scan covers the screen in all three themes.
The service worker no longer caches non-OK navigations as the offline
shell (a typo'd URL used to write the error page into the shell
cache). Version 0.5.6, SW -> freezmo-v78.
This commit is contained in:
Martin Dvořák 2026-10-14 15:27:47 +00:00
commit 7e42b03f7e
9 changed files with 137 additions and 4 deletions

View file

@ -1045,6 +1045,24 @@ body:has(.overlay-open) :is(.app-header, .segmented, .tabbar, .cookie-notice) {
.ice-orb-3 { display: none; }
}
/* The 404 mascot: the scene's glossy ice orb, at full strength so it reads on
the card glass in every theme (the scene's own orbs run at 0.22–0.6). */
.not-found-orb {
border-radius: 50%;
background: radial-gradient(
circle at 32% 26%,
rgb(255 255 255 / 0.98) 0%,
rgb(219 242 255 / 0.92) 26%,
rgb(125 200 245 / 0.95) 58%,
rgb(38 121 208 / 1) 100%
);
box-shadow:
inset -10px -14px 24px -12px rgb(3 74 124 / 0.6),
inset 8px 12px 20px -10px rgb(255 255 255 / 0.95),
inset 0 0 0 1px rgb(255 255 255 / 0.5),
0 18px 36px -18px rgb(2 62 110 / 0.6);
}
@layer components {
/* Frosted ice glass ------------------------------------------------------
Two recipes now:

12
app/not-found.tsx Normal file
View file

@ -0,0 +1,12 @@
import type { Metadata } from "next";
import { NotFoundScreen } from "@/components/NotFoundScreen";
export const metadata: Metadata = {
title: "Page not found",
};
/** Custom 404 for unknown URLs (and notFound() calls). */
export default function NotFound() {
return <NotFoundScreen />;
}