{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "approval-card",
  "title": "Approval Card",
  "description": "A human-in-the-loop approval for an action an agent wants to take.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "components/spectrumui/blocks/ai-assistants/approval-card.tsx",
      "content": "'use client';\n\nimport { useState } from 'react';\nimport { Check, X } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\nconst KEYFRAMES = `\n@keyframes su-pop { 0% { opacity: 0; transform: scale(0.85) } 100% { opacity: 1; transform: none } }\n@keyframes su-msg-in { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }\n`;\n\nexport type ApprovalDecision = 'approved' | 'rejected';\n\nexport interface ApprovalCardProps {\n  title?: string;\n  description?: string;\n  meta?: string;\n  approveLabel?: string;\n  rejectLabel?: string;\n  decision?: ApprovalDecision | null;\n  onDecide?: (decision: ApprovalDecision) => void;\n  className?: string;\n}\n\nexport function ApprovalCard({\n  title = 'Send carrier notice?',\n  description = 'A formal SLA-breach notice to Meridian Lines for the Rotterdam–Felixstowe lane, citing 2.3 days over contracted transit.',\n  meta = 'drafted by agent · draft_carrier_notice',\n  approveLabel = 'Approve & send',\n  rejectLabel = 'Dismiss',\n  decision: decisionProp,\n  onDecide,\n  className,\n}: ApprovalCardProps) {\n  const [decisionState, setDecisionState] = useState<ApprovalDecision | null>(null);\n  const decision = decisionProp !== undefined ? decisionProp : decisionState;\n\n  function decide(next: ApprovalDecision) {\n    setDecisionState(next);\n    onDecide?.(next);\n  }\n\n  return (\n    <div\n      className={cn(\n        'w-full max-w-[420px] rounded-2xl border border-black/[0.08] bg-white p-4 shadow-xs dark:border-white/[0.09] dark:bg-[#0B0B0D]',\n        className,\n      )}\n    >\n      <style dangerouslySetInnerHTML={{ __html: KEYFRAMES }} />\n\n      {decision ? (\n        <div className=\"flex flex-col items-center py-4 text-center motion-safe:animate-[su-msg-in_240ms_cubic-bezier(0.23,1,0.32,1)_both]\">\n          <span\n            className={cn(\n              'grid size-8 place-items-center rounded-full motion-safe:animate-[su-pop_200ms_cubic-bezier(0.23,1,0.32,1)_both]',\n              decision === 'approved'\n                ? 'bg-emerald-500/15 text-emerald-600 dark:text-emerald-400'\n                : 'bg-neutral-500/10 text-neutral-500 dark:text-neutral-400',\n            )}\n          >\n            {decision === 'approved' ? (\n              <Check className=\"size-4\" strokeWidth={2.5} />\n            ) : (\n              <X className=\"size-4\" strokeWidth={2.5} />\n            )}\n          </span>\n          <p className=\"mt-2.5 text-[13.5px] font-medium text-neutral-900 dark:text-neutral-50\">\n            {decision === 'approved' ? 'Approved — notice queued' : 'Dismissed'}\n          </p>\n          <p className=\"mt-1 font-mono text-[10.5px] text-neutral-400 dark:text-neutral-600\">\n            {meta}\n          </p>\n        </div>\n      ) : (\n        <>\n          <h3 className=\"text-[14px] font-semibold tracking-[-0.1px] text-neutral-900 dark:text-neutral-50\">\n            {title}\n          </h3>\n          <p className=\"mt-1.5 text-[13px] leading-[1.6] text-neutral-500 dark:text-neutral-400\">\n            {description}\n          </p>\n          <p className=\"mt-2.5 font-mono text-[10.5px] text-neutral-400 dark:text-neutral-600\">\n            {meta}\n          </p>\n\n          <div className=\"mt-4 flex items-center justify-end gap-2\">\n            <button\n              type=\"button\"\n              onClick={() => decide('rejected')}\n              className=\"rounded-lg px-3 py-1.5 text-[12.5px] font-medium text-neutral-500 transition-[color,background-color,transform] duration-150 hover:bg-black/[0.04] hover:text-neutral-800 active:scale-[0.97] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-neutral-400 dark:text-neutral-400 dark:hover:bg-white/[0.06] dark:hover:text-neutral-200\"\n            >\n              {rejectLabel}\n            </button>\n            <button\n              type=\"button\"\n              onClick={() => decide('approved')}\n              className=\"rounded-lg bg-neutral-900 px-3 py-1.5 text-[12.5px] font-medium text-white transition-transform duration-[160ms] ease-[cubic-bezier(0.23,1,0.32,1)] active:scale-[0.97] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 dark:bg-neutral-100 dark:text-neutral-900\"\n            >\n              {approveLabel}\n            </button>\n          </div>\n        </>\n      )}\n    </div>\n  );\n}\n\nexport default ApprovalCard;\n",
      "type": "registry:block",
      "target": "components/spectrumui/blocks/ai-assistants/approval-card.tsx"
    }
  ],
  "type": "registry:block"
}
