{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "author": "DesignX ", "name": "not-found", "type": "registry:component", "title": "Not Found", "description": "Five animated 404 pages — glitch, magnetic, spotlight, stacked and terminal.", "dependencies": [ "motion@^14.0.0" ], "registryDependencies": [ "@dx/lib-ease", "@dx/text-reveal", "@dx/utils" ], "files": [ { "path": "components/motion/not-found/index.tsx", "type": "registry:component", "target": "components/motion/not-found/index.tsx", "content": "export { NotFoundGlitch } from \"./glitch\";\nexport { NotFoundMagnetic } from \"./magnetic\";\nexport { NotFoundSpotlight } from \"./spotlight\";\nexport { NotFoundStacked } from \"./stacked\";\nexport { NotFoundTerminal } from \"./terminal\";\nexport {\n NOT_FOUND_DEFAULTS,\n NotFoundActions,\n NotFoundStage,\n type NotFoundProps,\n} from \"./shared\";\n" }, { "path": "components/motion/not-found/glitch.tsx", "type": "registry:component", "target": "components/motion/not-found/glitch.tsx", "content": "import { useEffect, useState } from \"react\";\nimport { useReducedMotion } from \"motion/react\";\nimport {\n NOT_FOUND_DEFAULTS,\n NotFoundActions,\n NotFoundStage,\n type NotFoundProps,\n} from \"./shared\";\n\nconst GLYPHS = \"ABCDEFGHJKLMNPQRSTUVWXYZ0123456789#%&@$?/\\\\\";\nconst SCRAMBLE_MS = 700;\nconst TICK_MS = 45;\n\n/**\n * Renders the code, scrambling each character on mount before it settles.\n * SSR and the first paint show the real code, so the scramble is a pure\n * client-side enhancement and reduced-motion users see the code immediately.\n */\nfunction Scramble({ text }: { text: string }) {\n const reduce = useReducedMotion();\n const [display, setDisplay] = useState(text);\n\n useEffect(() => {\n if (reduce) {\n setDisplay(text);\n return;\n }\n const chars = text.split(\"\");\n const start = performance.now();\n let raf = 0;\n let last = 0;\n\n const loop = (now: number) => {\n if (now - last >= TICK_MS) {\n last = now;\n const progress = Math.min((now - start) / SCRAMBLE_MS, 1);\n const settled = Math.floor(progress * chars.length);\n setDisplay(\n chars\n .map((ch, i) =>\n i < settled || ch === \" \"\n ? ch\n : GLYPHS[Math.floor(Math.random() * GLYPHS.length)],\n )\n .join(\"\"),\n );\n }\n if (now - start < SCRAMBLE_MS) {\n raf = requestAnimationFrame(loop);\n } else {\n setDisplay(text);\n }\n };\n raf = requestAnimationFrame(loop);\n return () => cancelAnimationFrame(raf);\n }, [text, reduce]);\n\n return {display};\n}\n\nexport function NotFoundGlitch({\n className,\n code = NOT_FOUND_DEFAULTS.code,\n title = NOT_FOUND_DEFAULTS.title,\n description = NOT_FOUND_DEFAULTS.description,\n homeHref,\n homeLabel,\n browseHref,\n browseLabel,\n}: NotFoundProps) {\n return (\n \n
\n {/* Chromatic ghost layers, nudged apart on hover. */}\n \n \n \n \n \n \n

\n \n

\n
\n\n
\n

{title}

\n

{description}

\n
\n\n \n
\n );\n}\n" }, { "path": "components/motion/not-found/magnetic.tsx", "type": "registry:component", "target": "components/motion/not-found/magnetic.tsx", "content": "import { Magnetic } from \"@/components/motion/magnetic\";\nimport { cn } from \"@/lib/utils\";\nimport {\n NOT_FOUND_DEFAULTS,\n NotFoundActions,\n NotFoundStage,\n type NotFoundProps,\n} from \"./shared\";\n\nexport function NotFoundMagnetic({\n className,\n code = NOT_FOUND_DEFAULTS.code,\n title = NOT_FOUND_DEFAULTS.title,\n description = NOT_FOUND_DEFAULTS.description,\n homeHref,\n homeLabel,\n browseHref,\n browseLabel,\n}: NotFoundProps) {\n const chars = code.split(\"\");\n\n return (\n \n \n {chars.map((ch, i) => (\n 0 && \"-ml-2\")}\n >\n \n {ch}\n \n \n ))}\n \n\n
\n

{title}

\n

{description}

\n
\n\n \n
\n );\n}\n" }, { "path": "components/motion/not-found/spotlight.tsx", "type": "registry:component", "target": "components/motion/not-found/spotlight.tsx", "content": "import { useRef } from \"react\";\nimport {\n motion,\n useMotionTemplate,\n useMotionValue,\n useReducedMotion,\n} from \"motion/react\";\nimport { useHoverCapable } from \"@/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/lib/utils\";\nimport {\n NOT_FOUND_DEFAULTS,\n NotFoundActions,\n NotFoundStage,\n type NotFoundProps,\n} from \"./shared\";\n\nexport function NotFoundSpotlight({\n className,\n code = NOT_FOUND_DEFAULTS.code,\n title = NOT_FOUND_DEFAULTS.title,\n description = NOT_FOUND_DEFAULTS.description,\n homeHref,\n homeLabel,\n browseHref,\n browseLabel,\n}: NotFoundProps) {\n const ref = useRef(null);\n const reduce = useReducedMotion();\n const canHover = useHoverCapable();\n const enabled = !reduce && canHover;\n\n const mx = useMotionValue(50);\n const my = useMotionValue(50);\n const mask = useMotionTemplate`radial-gradient(220px circle at ${mx}% ${my}%, #000 25%, transparent 72%)`;\n\n const onMove = (e: React.MouseEvent) => {\n const el = ref.current;\n if (!el || !enabled) return;\n const rect = el.getBoundingClientRect();\n mx.set(((e.clientX - rect.left) / rect.width) * 100);\n my.set(((e.clientY - rect.top) / rect.height) * 100);\n };\n\n return (\n \n \n {/* Dim base layer. */}\n \n {code}\n \n {/* Bright layer, revealed only under the spotlight. */}\n \n {code}\n \n \n\n
\n

{title}

\n

{description}

\n
\n\n \n
\n );\n}\n" }, { "path": "components/motion/not-found/stacked.tsx", "type": "registry:component", "target": "components/motion/not-found/stacked.tsx", "content": "import { motion, useReducedMotion } from \"motion/react\";\nimport { SPRING_PANEL } from \"@/lib/ease\";\nimport { useHoverCapable } from \"@/lib/hooks/use-hover-capable\";\nimport {\n NOT_FOUND_DEFAULTS,\n NotFoundActions,\n NotFoundStage,\n type NotFoundProps,\n} from \"./shared\";\n\nconst CARD =\n \"absolute inset-0 rounded-3xl border border-border bg-card shadow-sm\";\n\nexport function NotFoundStacked({\n className,\n code = NOT_FOUND_DEFAULTS.code,\n title = NOT_FOUND_DEFAULTS.title,\n description = NOT_FOUND_DEFAULTS.description,\n homeHref,\n homeLabel,\n browseHref,\n browseLabel,\n}: NotFoundProps) {\n const reduce = useReducedMotion();\n const canHover = useHoverCapable();\n const interactive = !reduce && canHover;\n\n return (\n \n \n \n \n \n

\n {code}\n

\n \n out of the deck\n \n \n \n\n
\n

{title}

\n

{description}

\n
\n\n \n
\n );\n}\n" }, { "path": "components/motion/not-found/terminal.tsx", "type": "registry:component", "target": "components/motion/not-found/terminal.tsx", "content": "import { TextReveal } from \"@/components/motion/text-reveal\";\nimport {\n NOT_FOUND_DEFAULTS,\n NotFoundActions,\n NotFoundStage,\n type NotFoundProps,\n} from \"./shared\";\n\nconst TYPE_SPRING = { stiffness: 320, damping: 30, mass: 0.6 };\n\nexport function NotFoundTerminal({\n className,\n code = NOT_FOUND_DEFAULTS.code,\n title = NOT_FOUND_DEFAULTS.title,\n description = NOT_FOUND_DEFAULTS.description,\n homeHref,\n homeLabel,\n browseHref,\n browseLabel,\n}: NotFoundProps) {\n return (\n \n
\n
\n \n \n \n ~/dx\n
\n
\n \n \n

\n \n \n

\n
\n
\n\n
\n

{title}

\n

{description}

\n
\n\n \n
\n );\n}\n" }, { "path": "components/motion/not-found/shared.tsx", "type": "registry:component", "target": "components/motion/not-found/shared.tsx", "content": "import { motion, useReducedMotion } from \"motion/react\";\nimport { SPRING_PRESS } from \"@/lib/ease\";\nimport { useHoverCapable } from \"@/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface NotFoundProps {\n className?: string;\n /** The big status code. */\n code?: string;\n title?: string;\n description?: string;\n homeHref?: string;\n homeLabel?: string;\n browseHref?: string;\n browseLabel?: string;\n}\n\nexport const NOT_FOUND_DEFAULTS = {\n code: \"404\",\n title: \"Page not found\",\n description:\n \"The page you are looking for moved, vanished, or never existed.\",\n homeHref: \"/\",\n homeLabel: \"Back home\",\n browseHref: \"/components/motion\",\n browseLabel: \"Browse components\",\n} as const;\n\ntype ActionsProps = Pick<\n NotFoundProps,\n \"homeHref\" | \"homeLabel\" | \"browseHref\" | \"browseLabel\" | \"className\"\n>;\n\n/** The shared dual CTA: a primary \"Back home\" and a secondary \"Browse\". */\nexport function NotFoundActions({\n homeHref = NOT_FOUND_DEFAULTS.homeHref,\n homeLabel = NOT_FOUND_DEFAULTS.homeLabel,\n browseHref = NOT_FOUND_DEFAULTS.browseHref,\n browseLabel = NOT_FOUND_DEFAULTS.browseLabel,\n className,\n}: ActionsProps) {\n const reduce = useReducedMotion();\n const canHover = useHoverCapable();\n const whileTap = reduce ? undefined : { scale: 0.96 };\n const whileHover = reduce || !canHover ? undefined : { scale: 1.02 };\n\n return (\n \n \n {homeLabel}\n \n \n {browseLabel}\n \n \n );\n}\n\n/** Centers a variant and gives it a consistent minimum stage height. */\nexport function NotFoundStage({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n \n {children}\n \n );\n}\n" }, { "path": "components/motion/magnetic.tsx", "type": "registry:component", "target": "components/motion/magnetic.tsx", "content": "import { motion, useMotionValue, useReducedMotion, useSpring } from \"motion/react\";\nimport { useRef, type ReactNode } from \"react\";\nimport { SPRING_MOUSE } from \"@/lib/ease\";\nimport { useHoverCapable } from \"@/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface MagneticProps {\n children: ReactNode;\n strength?: number;\n className?: string;\n}\n\nexport function Magnetic({ children, strength = 0.35, className }: MagneticProps) {\n const ref = useRef(null);\n const reduce = useReducedMotion();\n const canHover = useHoverCapable();\n // Decorative cursor-follow: skip on touch (phantom hover) and reduced motion.\n const enabled = !reduce && canHover;\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n const sx = useSpring(x, SPRING_MOUSE);\n const sy = useSpring(y, SPRING_MOUSE);\n\n const onMove = (e: React.MouseEvent) => {\n const el = ref.current;\n if (!el || !enabled) return;\n const rect = el.getBoundingClientRect();\n x.set((e.clientX - rect.left - rect.width / 2) * strength);\n y.set((e.clientY - rect.top - rect.height / 2) * strength);\n };\n\n const onLeave = () => {\n x.set(0);\n y.set(0);\n };\n\n return (\n \n {children}\n \n );\n}\n" } ], "categories": [ "motion-kit" ], "meta": { "group": "motion", "docs": "https://dxuireact.com/docs/components/not-found" } }