{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "animated-empty-state",
  "type": "registry:ui",
  "title": "Animated empty state",
  "description": "Moves a valid empty state directly toward one clear first action and result.",
  "dependencies": [
    "motion"
  ],
  "categories": [
    "forms-input"
  ],
  "docs": "https://motion-lexicon.pages.dev/en/components/animated-empty-state/",
  "meta": {
    "engines": [
      "motion"
    ],
    "runtimeCost": "light",
    "signature": "Context, illustration, and action arrive as one sequence",
    "sceneFamily": "editorial-warm",
    "motionRole": "lively",
    "primaryState": "Empty working surface with clear action",
    "assetProvenance": "self-contained"
  },
  "files": [
    {
      "path": "src/registry/components/animated-empty-state.tsx",
      "type": "registry:ui",
      "target": "components/motion-lexicon/animated-empty-state.tsx",
      "content": "\"use client\";\n\nimport { useId, useState } from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\n\nexport type AnimatedEmptyStateProps = { title?: string; description?: string; actionLabel?: string; onAction?: () => void | Promise<void>; className?: string };\n\nexport function AnimatedEmptyState({ title = \"A clear space to begin\", description = \"Add the first item to turn this view into a useful working surface.\", actionLabel = \"Create item\", onAction, className = \"\" }: AnimatedEmptyStateProps) {\n  const reduced = useReducedMotion() === true; const titleId = useId(); const [state, setState] = useState<\"empty\" | \"pending\" | \"ready\">(\"empty\");\n  const act = async () => { try { setState(\"pending\"); await onAction?.(); setState(\"ready\"); } catch { setState(\"empty\"); } };\n  return <section aria-labelledby={titleId} className={`overflow-hidden rounded-[18px] bg-[#e6e0d5] p-5 text-[#2c2721] shadow-[0_16px_42px_-30px_rgba(69,51,33,.55)] sm:p-7 ${className}`}><div className=\"relative min-h-[250px]\"><div aria-hidden className=\"absolute right-0 top-0 size-40 rounded-full border-[18px] border-[#c5a57d]/50\" /><AnimatePresence mode=\"wait\" initial={false}>{state === \"ready\" ? <motion.div key=\"ready\" initial={reduced ? false : { opacity: 0, scale: .9 }} animate={{ opacity: 1, scale: 1 }} className=\"relative flex min-h-[250px] flex-col justify-center\"><span className=\"grid size-11 place-items-center rounded-full bg-[#2c2721] text-white\">✓</span><h3 id={titleId} className=\"mt-5 text-3xl font-medium tracking-[-.055em]\">Your first item is ready.</h3><p className=\"mt-2 max-w-sm text-[12px] leading-relaxed text-[#675a4d]\">The empty state resolves directly into the next useful piece of work.</p><button type=\"button\" onClick={() => setState(\"empty\")} className=\"mt-5 min-h-11 w-fit rounded-full border border-[#2c2721]/15 px-4 text-[11px] outline-none hover:bg-white/45 focus-visible:ring-2 focus-visible:ring-[#4568FF]\">Reset preview</button></motion.div> : <motion.div key=\"empty\" initial={reduced ? false : { opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} className=\"relative flex min-h-[250px] flex-col justify-center\"><span className=\"font-mono text-[10px] uppercase tracking-[.18em] text-[#8a715a]\">Ready when you are</span><h3 id={titleId} className=\"mt-3 max-w-[11ch] text-3xl font-medium leading-[.96] tracking-[-.055em]\">{title}</h3><p className=\"mt-3 max-w-sm text-[12px] leading-relaxed text-[#675a4d]\">{description}</p><button type=\"button\" onClick={() => void act()} disabled={state === \"pending\"} className=\"mt-5 min-h-11 w-fit rounded-full bg-[#2c2721] px-4 text-[12px] font-medium text-white outline-none hover:bg-[#484037] disabled:opacity-60 focus-visible:ring-2 focus-visible:ring-[#4568FF] focus-visible:ring-offset-2 focus-visible:ring-offset-[#e6e0d5]\">{state === \"pending\" ? \"Creating…\" : actionLabel}</button></motion.div>}</AnimatePresence></div></section>;\n}\n"
    }
  ]
}
