{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "quota-banner",
  "title": "Quota Banner",
  "description": "A message-quota banner with a live reset countdown.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "components/spectrumui/blocks/ai-assistants/quota-banner.tsx",
      "content": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Zap } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\nexport type QuotaBannerVariant = 'Banner' | 'Compact';\n\nexport interface QuotaBannerProps {\n  used: number;\n  limit: number;\n  resetsInSeconds?: number;\n  upgradeLabel?: string;\n  onUpgrade?: () => void;\n  variant?: QuotaBannerVariant;\n  className?: string;\n}\n\nfunction useCountdown(seconds?: number) {\n  const [remaining, setRemaining] = useState(seconds ?? 0);\n  useEffect(() => {\n    setRemaining(seconds ?? 0);\n    if (!seconds) return;\n    const t = setInterval(() => setRemaining((value) => Math.max(0, value - 1)), 1000);\n    return () => clearInterval(t);\n  }, [seconds]);\n  const minutes = Math.floor(remaining / 60);\n  return `${minutes}:${String(remaining % 60).padStart(2, '0')}`;\n}\n\nexport function QuotaBanner({\n  used,\n  limit,\n  resetsInSeconds,\n  upgradeLabel = 'Upgrade',\n  onUpgrade,\n  variant = 'Banner',\n  className,\n}: QuotaBannerProps) {\n  const countdown = useCountdown(resetsInSeconds);\n  const ratio = Math.min(1, used / limit);\n  const exhausted = used >= limit;\n\n  if (variant === 'Compact') {\n    return (\n      <div\n        className={cn(\n          'flex w-fit items-center gap-2.5 rounded-full border border-black/[0.08] bg-white py-1.5 pl-3 pr-1.5 text-[12px] dark:border-white/[0.09] dark:bg-[#0B0B0D]',\n          className,\n        )}\n      >\n        <span className=\"font-mono tabular-nums text-neutral-600 dark:text-neutral-300\">\n          {used}/{limit}\n        </span>\n        <span aria-hidden className=\"h-1 w-12 overflow-hidden rounded-full bg-black/[0.07] dark:bg-white/[0.09]\">\n          <span\n            className={cn(\n              'block h-full rounded-full transition-[width] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)]',\n              exhausted ? 'bg-amber-500' : 'bg-neutral-900 dark:bg-neutral-100',\n            )}\n            style={{ width: `${ratio * 100}%` }}\n          />\n        </span>\n        {resetsInSeconds !== undefined && (\n          <span className=\"font-mono text-[10.5px] tabular-nums text-neutral-400 dark:text-neutral-600\">\n            {countdown}\n          </span>\n        )}\n      </div>\n    );\n  }\n\n  return (\n    <div\n      role=\"status\"\n      className={cn(\n        'flex w-full max-w-[480px] items-center gap-3 rounded-xl border py-2.5 pl-3 pr-2',\n        exhausted\n          ? 'border-amber-500/25 bg-amber-500/[0.06]'\n          : 'border-black/[0.08] bg-white dark:border-white/[0.09] dark:bg-[#0B0B0D]',\n        className,\n      )}\n    >\n      <span\n        className={cn(\n          'grid size-7 shrink-0 place-items-center rounded-full',\n          exhausted\n            ? 'bg-amber-500/15 text-amber-600 dark:text-amber-400'\n            : 'bg-black/[0.05] text-neutral-500 dark:bg-white/[0.07] dark:text-neutral-400',\n        )}\n      >\n        <Zap className=\"size-3.5\" />\n      </span>\n\n      <div className=\"min-w-0 flex-1\">\n        <p className=\"text-[12.5px] font-medium text-neutral-900 dark:text-neutral-100\">\n          {exhausted ? 'Message limit reached' : `${limit - used} messages left today`}\n        </p>\n        <p className=\"mt-0.5 flex items-center gap-2 font-mono text-[10.5px] tabular-nums text-neutral-400 dark:text-neutral-500\">\n          <span aria-hidden className=\"h-1 w-16 overflow-hidden rounded-full bg-black/[0.07] dark:bg-white/[0.09]\">\n            <span\n              className={cn(\n                'block h-full rounded-full transition-[width] duration-500 ease-[cubic-bezier(0.23,1,0.32,1)]',\n                exhausted ? 'bg-amber-500' : 'bg-neutral-900 dark:bg-neutral-100',\n              )}\n              style={{ width: `${ratio * 100}%` }}\n            />\n          </span>\n          {used}/{limit}\n          {resetsInSeconds !== undefined && <span>· resets in {countdown}</span>}\n        </p>\n      </div>\n\n      <button\n        type=\"button\"\n        onClick={onUpgrade}\n        className=\"shrink-0 rounded-lg bg-neutral-900 px-3 py-1.5 text-[12px] 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 dark:bg-neutral-100 dark:text-neutral-900\"\n      >\n        {upgradeLabel}\n      </button>\n    </div>\n  );\n}\n\nexport default QuotaBanner;\n",
      "type": "registry:block",
      "target": "components/spectrumui/blocks/ai-assistants/quota-banner.tsx"
    }
  ],
  "type": "registry:block"
}
