{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "error-404-page-section",
  "title": "404 Page Section",
  "description": "A centered \"page not found\" section: a big glitching error code, heading, description and one or two pill buttons. Follows the host site's theme by default (or a fixed dark / light palette with an optional theme toggle) and scales with its own width.",
  "dependencies": [
    "motion",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/new-york/error-404-page-section/error-404-page-section.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { MotionConfig, motion } from \"motion/react\";\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nfunction cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n\nexport type Error404Theme = \"auto\" | \"dark\" | \"light\";\n\nexport interface Error404PageSectionProps extends Omit<React.ComponentPropsWithoutRef<\"section\">, \"children\"> {\n  code?: string;\n  heading?: string;\n  description?: string;\n  buttonLabel?: string;\n  buttonHref?: string;\n  /** Optional second, outlined button (e.g. \"Browse components\"). */\n  secondaryLabel?: string;\n  secondaryHref?: string;\n  glitch?: boolean;\n  /** \"auto\" follows the host site's --background / --foreground tokens; \"dark\" / \"light\" use a fixed palette. */\n  theme?: Error404Theme;\n  /** Small dark/light switch in the corner. Only shown with a fixed palette (not with theme=\"auto\"). */\n  showThemeToggle?: boolean;\n  /** Desktop sizes in px. Everything scales down with the section's own width. */\n  codeSize?: number;\n  headingSize?: number;\n  descriptionSize?: number;\n}\n\ninterface Palette {\n  bg: string;\n  code: string;\n  title: string;\n  description: string;\n  buttonBg: string;\n  buttonText: string;\n  outline: string;\n  toggleBg: string;\n  toggleBorder: string;\n  focus: string;\n}\n\nconst PALETTES: Record<Error404Theme, Palette> = {\n  dark: {\n    bg: \"#0a0a0a\",\n    code: \"rgba(180,180,180,0.72)\",\n    title: \"#ffffff\",\n    description: \"rgba(255,255,255,0.55)\",\n    buttonBg: \"#ffffff\",\n    buttonText: \"#111111\",\n    outline: \"rgba(255,255,255,0.22)\",\n    toggleBg: \"rgba(255,255,255,0.08)\",\n    toggleBorder: \"rgba(255,255,255,0.12)\",\n    focus: \"rgba(255,255,255,0.35)\",\n  },\n  light: {\n    bg: \"#ffffff\",\n    code: \"rgba(40,40,40,0.55)\",\n    title: \"#111111\",\n    description: \"rgba(0,0,0,0.6)\",\n    buttonBg: \"#111111\",\n    buttonText: \"#ffffff\",\n    outline: \"rgba(0,0,0,0.2)\",\n    toggleBg: \"rgba(0,0,0,0.04)\",\n    toggleBorder: \"rgba(0,0,0,0.08)\",\n    focus: \"rgba(0,0,0,0.28)\",\n  },\n  // Reads the host site's shadcn-style tokens, so it follows the site theme by itself.\n  auto: {\n    bg: \"var(--background, #0a0a0a)\",\n    code: \"color-mix(in srgb, var(--foreground, #ffffff) 55%, transparent)\",\n    title: \"var(--foreground, #ffffff)\",\n    description: \"var(--muted-foreground, rgba(255,255,255,0.55))\",\n    buttonBg: \"var(--foreground, #ffffff)\",\n    buttonText: \"var(--background, #0a0a0a)\",\n    outline: \"color-mix(in srgb, var(--foreground, #ffffff) 22%, transparent)\",\n    toggleBg: \"color-mix(in srgb, var(--foreground, #ffffff) 6%, transparent)\",\n    toggleBorder: \"var(--border, rgba(255,255,255,0.12))\",\n    focus: \"color-mix(in srgb, var(--foreground, #ffffff) 35%, transparent)\",\n  },\n};\n\nexport function Error404PageSection({\n  code = \"404\",\n  heading = \"Page not found\",\n  description = \"The page you're looking for doesn't exist or may have been moved.\",\n  buttonLabel = \"Back to Home\",\n  buttonHref = \"/\",\n  secondaryLabel,\n  secondaryHref = \"#\",\n  glitch = true,\n  theme = \"auto\",\n  showThemeToggle = false,\n  codeSize = 168,\n  headingSize = 36,\n  descriptionSize = 15,\n  className,\n  style,\n  ...props\n}: Error404PageSectionProps) {\n  // The toggle overrides the theme prop until the prop itself changes.\n  const [state, setState] = React.useState<{ base: Error404Theme; picked: \"dark\" | \"light\" | null }>({ base: theme, picked: null });\n  if (state.base !== theme) setState({ base: theme, picked: null });\n  const active: Error404Theme = state.picked ?? theme;\n  const palette = PALETTES[active];\n  const isDark = active === \"dark\";\n  const canToggle = showThemeToggle && active !== \"auto\";\n\n  const scope = React.useId().replace(/[^a-zA-Z0-9]/g, \"\");\n  const headingId = `e404-heading-${scope}`;\n\n  // Everything sizes against the section's own width (container query units), so it also works\n  // inside narrow previews and columns, not just on narrow viewports.\n  const codeFontSize = `min(${codeSize}px, 36cqw)`;\n  const headingFontSize = `clamp(24px, 7.5cqw, ${headingSize}px)`;\n  const descriptionFontSize = `clamp(14px, 4cqw, ${descriptionSize}px)`;\n  const padding = \"clamp(48px, 10cqw, 72px) clamp(20px, 5cqw, 40px)\";\n\n  return (\n    <MotionConfig reducedMotion=\"user\">\n      <section\n        role=\"region\"\n        aria-labelledby={headingId}\n        data-e404={scope}\n        className={cn(\"relative flex min-h-[520px] w-full items-center justify-center overflow-hidden\", className)}\n        style={{ containerType: \"inline-size\", background: palette.bg, transition: \"background-color 0.25s ease\", ...style }}\n        {...props}\n      >\n        {canToggle && (\n          <button\n            type=\"button\"\n            onClick={() => setState({ base: theme, picked: isDark ? \"light\" : \"dark\" })}\n            aria-label={isDark ? \"Switch to light mode\" : \"Switch to dark mode\"}\n            className=\"absolute top-4 left-4 z-50 flex size-10 cursor-pointer items-center justify-center rounded-xl p-0 outline-none focus-visible:outline-2 focus-visible:outline-offset-2\"\n            style={{ background: palette.toggleBg, border: `1px solid ${palette.toggleBorder}`, color: palette.title, outlineColor: palette.focus }}\n          >\n            {isDark ? (\n              <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n                <circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.8\" />\n                <path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" />\n              </svg>\n            ) : (\n              <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n                <path d=\"M21 14.5A8.5 8.5 0 0 1 9.5 3 7 7 0 1 0 21 14.5z\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n              </svg>\n            )}\n          </button>\n        )}\n\n        <div className=\"w-full\" style={{ padding }}>\n          <div className=\"mx-auto w-full max-w-[720px] text-center\">\n            <div className=\"relative inline-block\" style={{ marginBottom: \"clamp(16px, 4cqw, 24px)\" }}>\n              <motion.div\n                initial={{ opacity: 0, y: 10 }}\n                animate={{ opacity: 1, y: 0 }}\n                transition={{ duration: 0.45 }}\n                className=\"relative font-mono font-bold tabular-nums select-none\"\n                style={{ color: palette.code, fontSize: codeFontSize, lineHeight: 0.85, letterSpacing: \"-0.04em\" }}\n              >\n                <span className=\"relative z-[2]\">{code}</span>\n                {glitch && (\n                  <>\n                    <span aria-hidden=\"true\" className=\"e404-layer e404-a\" style={{ color: palette.code }}>\n                      {code}\n                    </span>\n                    <span aria-hidden=\"true\" className=\"e404-layer e404-b\" style={{ color: palette.code }}>\n                      {code}\n                    </span>\n                  </>\n                )}\n              </motion.div>\n            </div>\n\n            <h1 id={headingId} className=\"m-0 mb-3 font-semibold\" style={{ color: palette.title, fontSize: headingFontSize, lineHeight: 1.2, letterSpacing: \"-0.03em\" }}>\n              {heading}\n            </h1>\n\n            {description ? (\n              <p className=\"mx-auto mb-7 max-w-[520px]\" style={{ color: palette.description, fontSize: descriptionFontSize, lineHeight: 1.6 }}>\n                {description}\n              </p>\n            ) : null}\n\n            {(buttonLabel || secondaryLabel) && (\n              <div className=\"flex flex-wrap items-center justify-center gap-3\">\n                {buttonLabel ? (\n                  <a\n                    href={buttonHref || \"/\"}\n                    className=\"inline-flex items-center justify-center rounded-full px-[22px] py-3 text-sm leading-[1.2] font-medium no-underline transition-[opacity,transform] duration-200 hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 active:scale-[0.98]\"\n                    style={{ background: palette.buttonBg, color: palette.buttonText, outlineColor: palette.focus }}\n                  >\n                    {buttonLabel}\n                  </a>\n                ) : null}\n                {secondaryLabel ? (\n                  <a\n                    href={secondaryHref || \"#\"}\n                    className=\"inline-flex items-center justify-center rounded-full border px-[22px] py-3 text-sm leading-[1.2] font-medium no-underline transition-[opacity,transform] duration-200 hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2 active:scale-[0.98]\"\n                    style={{ borderColor: palette.outline, color: palette.title, outlineColor: palette.focus }}\n                  >\n                    {secondaryLabel}\n                  </a>\n                ) : null}\n              </div>\n            )}\n          </div>\n        </div>\n\n        <style>{`\n          [data-e404=\"${scope}\"] .e404-layer { position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: ${active === \"light\" || active === \"auto\" ? \"multiply\" : \"screen\"}; }\n          ${active === \"auto\" ? `.dark [data-e404=\"${scope}\"] .e404-layer { mix-blend-mode: screen; }` : \"\"}\n          [data-e404=\"${scope}\"] .e404-a { animation: e404-a-${scope} 2.4s infinite linear alternate-reverse; clip-path: inset(12% 0 58% 0); transform: translate(-3px, 0); opacity: 0.55; filter: blur(0.3px); }\n          [data-e404=\"${scope}\"] .e404-b { animation: e404-b-${scope} 1.8s infinite linear alternate-reverse; clip-path: inset(62% 0 8% 0); transform: translate(3px, 0); opacity: 0.45; filter: blur(0.4px); }\n          @keyframes e404-a-${scope} { 0% { transform: translate(-4px, -1px); clip-path: inset(8% 0 70% 0); } 20% { transform: translate(5px, 0); clip-path: inset(18% 0 46% 0); } 40% { transform: translate(-6px, 1px); clip-path: inset(2% 0 78% 0); } 60% { transform: translate(3px, -1px); clip-path: inset(28% 0 40% 0); } 80% { transform: translate(-2px, 0); clip-path: inset(12% 0 62% 0); } 100% { transform: translate(4px, 1px); clip-path: inset(22% 0 50% 0); } }\n          @keyframes e404-b-${scope} { 0% { transform: translate(4px, 1px); clip-path: inset(68% 0 6% 0); } 25% { transform: translate(-5px, 0); clip-path: inset(54% 0 18% 0); } 50% { transform: translate(6px, -1px); clip-path: inset(72% 0 4% 0); } 75% { transform: translate(-3px, 1px); clip-path: inset(60% 0 12% 0); } 100% { transform: translate(2px, 0); clip-path: inset(66% 0 8% 0); } }\n          @media (prefers-reduced-motion: reduce) { [data-e404=\"${scope}\"] .e404-layer { display: none; } }\n        `}</style>\n      </section>\n    </MotionConfig>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}