{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "invoice-creator-wizard",
  "title": "Invoice Creator Wizard",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/invoice-creator-wizard/InvoiceCreatorWizard.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Building2,\n  CheckCircle2,\n  CreditCard,\n  Eye,\n  FileText,\n  Percent,\n  Plus,\n  Receipt,\n  Save,\n  Send,\n  Trash2,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Separator } from '@/components/ui/separator'\nimport { Textarea } from '@/components/ui/textarea'\n\nexport interface InvoiceLineItem {\n  id: string\n  description: string\n  quantity: number\n  unitPrice: number\n}\n\nexport interface ClientPreset {\n  id: string\n  name: string\n  company: string\n  email: string\n  address: string\n}\n\nexport interface InvoiceCreatorWizardProps {\n  className?: string\n  initialInvoiceNumber?: string\n  initialIssuerName?: string\n  initialIssuerEmail?: string\n  initialIssuerAddress?: string\n  initialIssuerTaxId?: string\n  initialClientName?: string\n  initialClientCompany?: string\n  initialClientEmail?: string\n  initialClientAddress?: string\n  initialInvoiceDate?: string\n  initialDueDate?: string\n  initialPaymentTerms?: string\n  initialCurrency?: string\n  initialItems?: InvoiceLineItem[]\n  initialTaxRate?: number\n  initialDiscountType?: 'fixed' | 'percent'\n  initialDiscountValue?: number\n  initialNotes?: string\n  onSaveDraft?: (payload: Record<string, any>) => void\n  onSendInvoice?: (payload: Record<string, any>) => void\n  onPreviewPdf?: () => void\n}\n\nconst CLIENT_PRESETS: ClientPreset[] = [\n  {\n    id: 'c1',\n    name: 'Sarah Jenkins',\n    company: 'Apex Digital Inc.',\n    email: 'sarah.jenkins@apexdigital.com',\n    address: '742 Evergreen Terrace, Springfield, OR 97477',\n  },\n  {\n    id: 'c2',\n    name: 'Marcus Vance',\n    company: 'Northwind Global Corp.',\n    email: 'marcus.vance@northwind.io',\n    address: '452 Broadway, 8th Floor, New York, NY 10013',\n  },\n  {\n    id: 'c3',\n    name: 'Elena Rostova',\n    company: 'Hyperion Robotics',\n    email: 'elena@hyperion-robotics.ai',\n    address: '10 Tech Parkway, Suite 300, Boston, MA 02115',\n  },\n]\n\nconst DEFAULT_LINE_ITEMS: InvoiceLineItem[] = [\n  {\n    id: 'item-1',\n    description: 'Design System Architecture & Component Registry',\n    quantity: 1,\n    unitPrice: 3200,\n  },\n  {\n    id: 'item-2',\n    description: 'Frontend Implementation (Vue 3 + React Mirror)',\n    quantity: 35,\n    unitPrice: 120,\n  },\n  {\n    id: 'item-3',\n    description: 'Accessibility & WCAG AA Compliance Audit',\n    quantity: 1,\n    unitPrice: 850,\n  },\n]\n\nconst PAYMENT_TERMS_MAP: Record<string, string> = {\n  receipt: 'Due on Receipt',\n  net15: 'Net 15 (Due in 15 days)',\n  net30: 'Net 30 (Due in 30 days)',\n  net60: 'Net 60 (Due in 60 days)',\n}\n\nexport function InvoiceCreatorWizard({\n  className,\n  initialInvoiceNumber = 'INV-2026-0042',\n  initialIssuerName = 'Acme Design & Engineering Studio',\n  initialIssuerEmail = 'billing@acmestudio.io',\n  initialIssuerAddress = '100 Montgomery St, Suite 1400, San Francisco, CA 94104',\n  initialIssuerTaxId = 'US-EIN-94-2819034',\n  initialClientName = 'Sarah Jenkins',\n  initialClientCompany = 'Apex Digital Inc.',\n  initialClientEmail = 'sarah.jenkins@apexdigital.com',\n  initialClientAddress = '742 Evergreen Terrace, Springfield, OR 97477',\n  initialInvoiceDate = '2026-08-21',\n  initialDueDate = '2026-09-20',\n  initialPaymentTerms = 'net30',\n  initialCurrency = 'USD',\n  initialItems,\n  initialTaxRate = 8.5,\n  initialDiscountType = 'fixed',\n  initialDiscountValue = 150,\n  initialNotes = 'Thank you for your partnership! Please remit payment via wire transfer or online payment link within 30 days. Contact billing@acmestudio.io for any questions.',\n  onSaveDraft,\n  onSendInvoice,\n  onPreviewPdf,\n}: InvoiceCreatorWizardProps) {\n  // Form State\n  const [invoiceNumber] = React.useState(initialInvoiceNumber)\n  const [issuerName, setIssuerName] = React.useState(initialIssuerName)\n  const [issuerEmail, setIssuerEmail] = React.useState(initialIssuerEmail)\n  const [issuerAddress, setIssuerAddress] = React.useState(initialIssuerAddress)\n  const [issuerTaxId, setIssuerTaxId] = React.useState(initialIssuerTaxId)\n\n  const [selectedPreset, setSelectedPreset] = React.useState('c1')\n  const [clientName, setClientName] = React.useState(initialClientName)\n  const [clientCompany, setClientCompany] = React.useState(initialClientCompany)\n  const [clientEmail, setClientEmail] = React.useState(initialClientEmail)\n  const [clientAddress, setClientAddress] = React.useState(initialClientAddress)\n\n  const [invoiceDate, setInvoiceDate] = React.useState(initialInvoiceDate)\n  const [dueDate, setDueDate] = React.useState(initialDueDate)\n  const [paymentTerms, setPaymentTerms] = React.useState(initialPaymentTerms)\n  const [currency, setCurrency] = React.useState(initialCurrency)\n\n  const [items, setItems] = React.useState<InvoiceLineItem[]>(\n    initialItems && initialItems.length > 0\n      ? initialItems.map((i) => ({ ...i }))\n      : DEFAULT_LINE_ITEMS.map((i) => ({ ...i })),\n  )\n\n  const [taxRate, setTaxRate] = React.useState(initialTaxRate)\n  const [discountType, setDiscountType] = React.useState<'fixed' | 'percent'>(initialDiscountType)\n  const [discountValue, setDiscountValue] = React.useState(initialDiscountValue)\n  const [notes, setNotes] = React.useState(initialNotes)\n\n  // Notification toast state\n  const [notification, setNotification] = React.useState<{ type: 'success' | 'info'; message: string } | null>(null)\n  const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)\n\n  const showNotification = React.useCallback((message: string, type: 'success' | 'info' = 'success') => {\n    if (timeoutRef.current) clearTimeout(timeoutRef.current)\n    setNotification({ message, type })\n    timeoutRef.current = setTimeout(() => {\n      setNotification(null)\n    }, 4000)\n  }, [])\n\n  const handlePresetChange = (presetId: string) => {\n    setSelectedPreset(presetId)\n    if (presetId === 'custom') return\n\n    const preset = CLIENT_PRESETS.find((c) => c.id === presetId)\n    if (preset) {\n      setClientName(preset.name)\n      setClientCompany(preset.company)\n      setClientEmail(preset.email)\n      setClientAddress(preset.address)\n    }\n  }\n\n  const addLineItem = () => {\n    const newId = `item-${Date.now()}`\n    setItems((prev) => [\n      ...prev,\n      {\n        id: newId,\n        description: '',\n        quantity: 1,\n        unitPrice: 0,\n      },\n    ])\n  }\n\n  const removeLineItem = (id: string) => {\n    if (items.length > 1) {\n      setItems((prev) => prev.filter((i) => i.id !== id))\n    }\n  }\n\n  const updateLineItem = (id: string, field: keyof InvoiceLineItem, value: any) => {\n    setItems((prev) => prev.map((item) => (item.id === id ? { ...item, [field]: value } : item)))\n  }\n\n  // Calculations\n  const subtotal = React.useMemo(() => {\n    return items.reduce((acc, item) => {\n      const qty = Number(item.quantity) || 0\n      const price = Number(item.unitPrice) || 0\n      return acc + qty * price\n    }, 0)\n  }, [items])\n\n  const discountAmount = React.useMemo(() => {\n    const val = Number(discountValue) || 0\n    if (discountType === 'percent') {\n      return subtotal * (val / 100)\n    }\n    return val\n  }, [discountValue, discountType, subtotal])\n\n  const effectiveDiscount = React.useMemo(() => {\n    return Math.min(subtotal, Math.max(0, discountAmount))\n  }, [subtotal, discountAmount])\n\n  const taxableAmount = React.useMemo(() => {\n    return Math.max(0, subtotal - effectiveDiscount)\n  }, [subtotal, effectiveDiscount])\n\n  const taxAmount = React.useMemo(() => {\n    const rate = Number(taxRate) || 0\n    return taxableAmount * (rate / 100)\n  }, [taxableAmount, taxRate])\n\n  const totalDue = React.useMemo(() => {\n    return taxableAmount + taxAmount\n  }, [taxableAmount, taxAmount])\n\n  const formatCurrency = React.useCallback(\n    (amount: number, curr: string = currency) => {\n      try {\n        return new Intl.NumberFormat('en-US', {\n          style: 'currency',\n          currency: curr,\n          minimumFractionDigits: 2,\n          maximumFractionDigits: 2,\n        }).format(amount)\n      } catch {\n        const symbols: Record<string, string> = { USD: '$', EUR: '€', GBP: '£', CAD: 'CA$', AUD: 'AU$' }\n        const s = symbols[curr] || '$'\n        return `${s}${amount.toFixed(2)}`\n      }\n    },\n    [currency],\n  )\n\n  const formatDate = React.useCallback((dateStr: string) => {\n    if (!dateStr) return '—'\n    try {\n      const [y, m, d] = dateStr.split('-').map(Number)\n      if (!y || !m || !d) return dateStr\n      const date = new Date(y, m - 1, d)\n      return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })\n    } catch {\n      return dateStr\n    }\n  }, [])\n\n  const getPayload = React.useCallback(() => {\n    return {\n      invoiceNumber,\n      issuer: {\n        name: issuerName,\n        email: issuerEmail,\n        address: issuerAddress,\n        taxId: issuerTaxId,\n      },\n      client: {\n        name: clientName,\n        company: clientCompany,\n        email: clientEmail,\n        address: clientAddress,\n      },\n      dates: {\n        issued: invoiceDate,\n        due: dueDate,\n        terms: paymentTerms,\n      },\n      currency,\n      items,\n      calculations: {\n        subtotal,\n        discount: effectiveDiscount,\n        tax: taxAmount,\n        total: totalDue,\n      },\n      notes,\n    }\n  }, [\n    invoiceNumber,\n    issuerName,\n    issuerEmail,\n    issuerAddress,\n    issuerTaxId,\n    clientName,\n    clientCompany,\n    clientEmail,\n    clientAddress,\n    invoiceDate,\n    dueDate,\n    paymentTerms,\n    currency,\n    items,\n    subtotal,\n    effectiveDiscount,\n    taxAmount,\n    totalDue,\n    notes,\n  ])\n\n  const handleSaveDraft = () => {\n    const payload = getPayload()\n    onSaveDraft?.(payload)\n    showNotification(`Draft invoice ${invoiceNumber} saved successfully.`, 'info')\n  }\n\n  const handleSendInvoice = () => {\n    const payload = getPayload()\n    onSendInvoice?.(payload)\n    showNotification(`Invoice ${invoiceNumber} sent to ${clientEmail || 'client'}.`, 'success')\n  }\n\n  const handlePreviewPdf = () => {\n    onPreviewPdf?.()\n    showNotification(`Generating printable PDF preview for ${invoiceNumber}...`, 'info')\n  }\n\n  return (\n    <div data-slot=\"invoice-creator-wizard\" className={cn('mx-auto w-full max-w-7xl space-y-6', className)}>\n      {/* Top Action Header */}\n      <div className=\"border-border flex flex-col gap-4 border-b pb-5 sm:flex-row sm:items-center sm:justify-between\">\n        <div className=\"space-y-1\">\n          <div className=\"flex items-center gap-3\">\n            <h1 className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">Create New Invoice</h1>\n            <Badge wrap variant=\"outline\" className=\"px-2 py-0.5 font-mono text-xs font-semibold\">\n              {invoiceNumber}\n            </Badge>\n            <Badge wrap variant=\"secondary\" className=\"text-xs\">\n              Draft\n            </Badge>\n          </div>\n          <p className=\"text-muted-foreground text-xs sm:text-sm\">\n            Build itemized invoices with live calculation, instant document preview, and client presets.\n          </p>\n        </div>\n\n        {/* Action Buttons */}\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <Button variant=\"outline\" size=\"sm\" className=\"gap-1.5 text-xs\" onClick={handlePreviewPdf}>\n            <FileText className=\"size-3.5\" aria-hidden=\"true\" />\n            Preview PDF\n          </Button>\n          <Button variant=\"outline\" size=\"sm\" className=\"gap-1.5 text-xs\" onClick={handleSaveDraft}>\n            <Save className=\"size-3.5\" aria-hidden=\"true\" />\n            Save Draft\n          </Button>\n          <Button size=\"sm\" className=\"gap-1.5 text-xs font-medium\" onClick={handleSendInvoice}>\n            <Send className=\"size-3.5\" aria-hidden=\"true\" />\n            Send Invoice\n          </Button>\n        </div>\n      </div>\n\n      {/* Notification Toast / Alert Banner */}\n      {notification && (\n        <div\n          className={cn(\n            'flex flex-wrap items-center justify-between rounded-lg border px-4 py-2.5 text-xs transition-colors sm:text-sm',\n            notification.type === 'success'\n              ? 'border-success/30 bg-success/10 text-success'\n              : 'border-primary/30 bg-primary/10 text-primary',\n          )}\n          role=\"status\"\n        >\n          <div className=\"flex flex-wrap items-center gap-2\">\n            <CheckCircle2 className=\"size-4 shrink-0\" aria-hidden=\"true\" />\n            <span>{notification.message}</span>\n          </div>\n          <button\n            type=\"button\"\n            className=\"min-h-6 text-xs font-semibold underline-offset-2 opacity-80 hover:underline hover:opacity-100\"\n            onClick={() => setNotification(null)}\n          >\n            Dismiss\n          </button>\n        </div>\n      )}\n\n      {/* 2-Column Invoice Builder Layout */}\n      <div className=\"grid grid-cols-1 items-start gap-8 lg:grid-cols-12\">\n        {/* Left Column: Form Builder */}\n        <div className=\"space-y-6 lg:col-span-7\">\n          {/* Section 1: Business & Client Details */}\n          <Card>\n            <CardHeader className=\"pb-4\">\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <Building2 className=\"text-primary size-4\" aria-hidden=\"true\" />\n                <CardTitle className=\"text-base font-semibold\">Business & Client Details</CardTitle>\n              </div>\n              <CardDescription className=\"text-xs\">\n                Configure your issuing entity information and bill-to client contact.\n              </CardDescription>\n            </CardHeader>\n            <CardContent className=\"space-y-5\">\n              {/* Issuer Details */}\n              <div className=\"space-y-3\">\n                <div className=\"flex flex-wrap items-center justify-between\">\n                  <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                    From (Issuer)\n                  </span>\n                  <span className=\"text-muted-foreground font-mono text-xs\">ID: {invoiceNumber}</span>\n                </div>\n                <div className=\"grid gap-3 sm:grid-cols-2\">\n                  <div className=\"space-y-1.5 sm:col-span-2\">\n                    <label htmlFor=\"issuer-name\" className=\"text-foreground text-xs font-medium\">\n                      Business / Organization Name\n                    </label>\n                    <Input\n                      id=\"issuer-name\"\n                      value={issuerName}\n                      onChange={(e) => setIssuerName(e.target.value)}\n                      placeholder=\"Business name\"\n                      size=\"small\"\n                    />\n                  </div>\n                  <div className=\"space-y-1.5\">\n                    <label htmlFor=\"issuer-email\" className=\"text-foreground text-xs font-medium\">\n                      Billing Email\n                    </label>\n                    <Input\n                      id=\"issuer-email\"\n                      type=\"email\"\n                      value={issuerEmail}\n                      onChange={(e) => setIssuerEmail(e.target.value)}\n                      placeholder=\"billing@company.com\"\n                      size=\"small\"\n                    />\n                  </div>\n                  <div className=\"space-y-1.5\">\n                    <label htmlFor=\"issuer-tax\" className=\"text-foreground text-xs font-medium\">\n                      Tax ID / VAT Registration\n                    </label>\n                    <Input\n                      id=\"issuer-tax\"\n                      value={issuerTaxId}\n                      onChange={(e) => setIssuerTaxId(e.target.value)}\n                      placeholder=\"Tax ID / EIN\"\n                      size=\"small\"\n                    />\n                  </div>\n                  <div className=\"space-y-1.5 sm:col-span-2\">\n                    <label htmlFor=\"issuer-address\" className=\"text-foreground text-xs font-medium\">\n                      Business Address\n                    </label>\n                    <Input\n                      id=\"issuer-address\"\n                      value={issuerAddress}\n                      onChange={(e) => setIssuerAddress(e.target.value)}\n                      placeholder=\"Street, City, State, ZIP\"\n                      size=\"small\"\n                    />\n                  </div>\n                </div>\n              </div>\n\n              <Separator />\n\n              {/* Client Details */}\n              <div className=\"space-y-3\">\n                <div className=\"flex flex-wrap items-center justify-between\">\n                  <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                    Bill To (Client)\n                  </span>\n                  <div className=\"flex flex-wrap items-center gap-2\">\n                    <span className=\"text-muted-foreground text-xs\">Quick Preset:</span>\n                    <div className=\"w-48\">\n                      <Select value={selectedPreset} onValueChange={handlePresetChange}>\n                        <SelectTrigger size=\"sm\" className=\"h-7 text-xs\">\n                          <SelectValue placeholder=\"Select client\" />\n                        </SelectTrigger>\n                        <SelectContent>\n                          {CLIENT_PRESETS.map((preset) => (\n                            <SelectItem key={preset.id} value={preset.id}>\n                              {preset.company}\n                            </SelectItem>\n                          ))}\n                          <SelectItem value=\"custom\">Custom Client</SelectItem>\n                        </SelectContent>\n                      </Select>\n                    </div>\n                  </div>\n                </div>\n\n                <div className=\"grid gap-3 sm:grid-cols-2\">\n                  <div className=\"space-y-1.5\">\n                    <label htmlFor=\"client-name\" className=\"text-foreground text-xs font-medium\">\n                      Contact Name\n                    </label>\n                    <Input\n                      id=\"client-name\"\n                      value={clientName}\n                      onChange={(e) => setClientName(e.target.value)}\n                      placeholder=\"Client contact name\"\n                      size=\"small\"\n                    />\n                  </div>\n                  <div className=\"space-y-1.5\">\n                    <label htmlFor=\"client-company\" className=\"text-foreground text-xs font-medium\">\n                      Company Name\n                    </label>\n                    <Input\n                      id=\"client-company\"\n                      value={clientCompany}\n                      onChange={(e) => setClientCompany(e.target.value)}\n                      placeholder=\"Client company name\"\n                      size=\"small\"\n                    />\n                  </div>\n                  <div className=\"space-y-1.5\">\n                    <label htmlFor=\"client-email\" className=\"text-foreground text-xs font-medium\">\n                      Client Email\n                    </label>\n                    <Input\n                      id=\"client-email\"\n                      type=\"email\"\n                      value={clientEmail}\n                      onChange={(e) => setClientEmail(e.target.value)}\n                      placeholder=\"client@company.com\"\n                      size=\"small\"\n                    />\n                  </div>\n                  <div className=\"space-y-1.5\">\n                    <label htmlFor=\"client-address\" className=\"text-foreground text-xs font-medium\">\n                      Client Address\n                    </label>\n                    <Input\n                      id=\"client-address\"\n                      value={clientAddress}\n                      onChange={(e) => setClientAddress(e.target.value)}\n                      placeholder=\"Street, City, Postal Code\"\n                      size=\"small\"\n                    />\n                  </div>\n                </div>\n              </div>\n\n              <Separator />\n\n              {/* Invoice Timing & Currency */}\n              <div className=\"grid gap-3 sm:grid-cols-4\">\n                <div className=\"space-y-1.5\">\n                  <label htmlFor=\"invoice-date\" className=\"text-foreground text-xs font-medium\">\n                    Invoice Date\n                  </label>\n                  <Input\n                    id=\"invoice-date\"\n                    type=\"date\"\n                    value={invoiceDate}\n                    onChange={(e) => setInvoiceDate(e.target.value)}\n                    size=\"small\"\n                  />\n                </div>\n                <div className=\"space-y-1.5\">\n                  <label htmlFor=\"due-date\" className=\"text-foreground text-xs font-medium\">\n                    Due Date\n                  </label>\n                  <Input\n                    id=\"due-date\"\n                    type=\"date\"\n                    value={dueDate}\n                    onChange={(e) => setDueDate(e.target.value)}\n                    size=\"small\"\n                  />\n                </div>\n                <div className=\"space-y-1.5\">\n                  <label htmlFor=\"payment-terms\" className=\"text-foreground text-xs font-medium\">\n                    Payment Terms\n                  </label>\n                  <Select value={paymentTerms} onValueChange={setPaymentTerms}>\n                    <SelectTrigger id=\"payment-terms\" size=\"sm\" className=\"h-8 text-xs\">\n                      <SelectValue placeholder=\"Terms\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"receipt\">Due on Receipt</SelectItem>\n                      <SelectItem value=\"net15\">Net 15</SelectItem>\n                      <SelectItem value=\"net30\">Net 30</SelectItem>\n                      <SelectItem value=\"net60\">Net 60</SelectItem>\n                    </SelectContent>\n                  </Select>\n                </div>\n                <div className=\"space-y-1.5\">\n                  <label htmlFor=\"currency-select\" className=\"text-foreground text-xs font-medium\">\n                    Currency\n                  </label>\n                  <Select value={currency} onValueChange={setCurrency}>\n                    <SelectTrigger id=\"currency-select\" size=\"sm\" className=\"h-8 text-xs\">\n                      <SelectValue placeholder=\"Currency\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"USD\">USD ($)</SelectItem>\n                      <SelectItem value=\"EUR\">EUR (€)</SelectItem>\n                      <SelectItem value=\"GBP\">GBP (£)</SelectItem>\n                      <SelectItem value=\"CAD\">CAD ($)</SelectItem>\n                      <SelectItem value=\"AUD\">AUD ($)</SelectItem>\n                    </SelectContent>\n                  </Select>\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* Section 2: Interactive Line Items */}\n          <Card>\n            <CardHeader className=\"pb-3\">\n              <div className=\"flex flex-wrap items-center justify-between\">\n                <div className=\"flex flex-wrap items-center gap-2\">\n                  <Receipt className=\"text-primary size-4\" aria-hidden=\"true\" />\n                  <CardTitle className=\"text-base font-semibold\">Line Items</CardTitle>\n                </div>\n                <Badge wrap variant=\"secondary\" className=\"font-mono text-xs tabular-nums\">\n                  {items.length} {items.length === 1 ? 'item' : 'items'}\n                </Badge>\n              </div>\n              <CardDescription className=\"text-xs\">\n                Itemize deliverables, billable hours, software licenses, or custom services.\n              </CardDescription>\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              <div className=\"overflow-x-auto\">\n                <table className=\"w-full text-left text-xs\">\n                  <thead>\n                    <tr className=\"border-border text-muted-foreground border-b\">\n                      <th className=\"pb-2 font-medium\">Description</th>\n                      <th className=\"w-20 pb-2 text-right font-medium\">Qty</th>\n                      <th className=\"w-28 pb-2 text-right font-medium\">Unit Price</th>\n                      <th className=\"w-24 pb-2 text-right font-medium\">Line Total</th>\n                      <th className=\"w-10 pb-2 text-center font-medium\"></th>\n                    </tr>\n                  </thead>\n                  <tbody className=\"divide-border/60 divide-y\">\n                    {items.map((item) => (\n                      <tr key={item.id} className=\"group\">\n                        <td className=\"py-2.5 pr-2\">\n                          <Input\n                            value={item.description}\n                            onChange={(e) => updateLineItem(item.id, 'description', e.target.value)}\n                            placeholder=\"Service or product description...\"\n                            size=\"small\"\n                            className=\"w-full\"\n                          />\n                        </td>\n                        <td className=\"px-2 py-2.5\">\n                          <Input\n                            type=\"number\"\n                            min=\"1\"\n                            step=\"1\"\n                            value={item.quantity}\n                            onChange={(e) => updateLineItem(item.id, 'quantity', Number(e.target.value))}\n                            size=\"small\"\n                            className=\"w-20 text-right tabular-nums\"\n                          />\n                        </td>\n                        <td className=\"px-2 py-2.5\">\n                          <Input\n                            type=\"number\"\n                            min=\"0\"\n                            step=\"0.01\"\n                            value={item.unitPrice}\n                            onChange={(e) => updateLineItem(item.id, 'unitPrice', Number(e.target.value))}\n                            size=\"small\"\n                            className=\"w-28 text-right tabular-nums\"\n                          />\n                        </td>\n                        <td className=\"text-foreground py-2.5 pl-2 text-right font-medium whitespace-nowrap tabular-nums\">\n                          {formatCurrency((Number(item.quantity) || 0) * (Number(item.unitPrice) || 0))}\n                        </td>\n                        <td className=\"py-2.5 pl-1 text-center\">\n                          <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            className=\"text-muted-foreground hover:text-destructive size-7 disabled:opacity-30\"\n                            disabled={items.length <= 1}\n                            aria-label=\"Remove item\"\n                            onClick={() => removeLineItem(item.id)}\n                          >\n                            <Trash2 className=\"size-3.5\" aria-hidden=\"true\" />\n                          </Button>\n                        </td>\n                      </tr>\n                    ))}\n                  </tbody>\n                </table>\n              </div>\n\n              <div className=\"flex flex-wrap items-center justify-between pt-2\">\n                <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"gap-1 text-xs\" onClick={addLineItem}>\n                  <Plus className=\"size-3.5\" aria-hidden=\"true\" />\n                  Add Line Item\n                </Button>\n                <div className=\"text-muted-foreground text-xs\">\n                  Subtotal:{' '}\n                  <span className=\"text-foreground font-semibold tabular-nums\">{formatCurrency(subtotal)}</span>\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* Section 3: Adjustments & Payment Terms */}\n          <Card>\n            <CardHeader className=\"pb-3\">\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <Percent className=\"text-primary size-4\" aria-hidden=\"true\" />\n                <CardTitle className=\"text-base font-semibold\">Adjustments & Notes</CardTitle>\n              </div>\n              <CardDescription className=\"text-xs\">\n                Itemize tax rates, discount subtractions, and client payment instructions.\n              </CardDescription>\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              <div className=\"grid gap-4 sm:grid-cols-2\">\n                {/* Tax percentage */}\n                <div className=\"space-y-1.5\">\n                  <div className=\"flex flex-wrap items-center justify-between\">\n                    <label htmlFor=\"tax-rate\" className=\"text-foreground text-xs font-medium\">\n                      Tax Rate (%)\n                    </label>\n                    <span className=\"text-muted-foreground text-xs tabular-nums\">+{formatCurrency(taxAmount)}</span>\n                  </div>\n                  <Input\n                    id=\"tax-rate\"\n                    type=\"number\"\n                    min=\"0\"\n                    step=\"0.1\"\n                    value={taxRate}\n                    onChange={(e) => setTaxRate(Number(e.target.value))}\n                    placeholder=\"8.5\"\n                    size=\"small\"\n                  />\n                </div>\n\n                {/* Discount */}\n                <div className=\"space-y-1.5\">\n                  <div className=\"flex flex-wrap items-center justify-between\">\n                    <label htmlFor=\"discount-val\" className=\"text-foreground text-xs font-medium\">\n                      Discount\n                    </label>\n                    <div className=\"flex items-center gap-1\">\n                      <button\n                        type=\"button\"\n                        className={cn(\n                          'min-h-6 rounded px-1.5 py-0.5 text-xs font-medium transition-colors',\n                          discountType === 'fixed'\n                            ? 'bg-primary text-primary-foreground'\n                            : 'bg-muted text-muted-foreground hover:text-foreground',\n                        )}\n                        onClick={() => setDiscountType('fixed')}\n                      >\n                        Fixed ($)\n                      </button>\n                      <button\n                        type=\"button\"\n                        className={cn(\n                          'min-h-6 rounded px-1.5 py-0.5 text-xs font-medium transition-colors',\n                          discountType === 'percent'\n                            ? 'bg-primary text-primary-foreground'\n                            : 'bg-muted text-muted-foreground hover:text-foreground',\n                        )}\n                        onClick={() => setDiscountType('percent')}\n                      >\n                        Percent (%)\n                      </button>\n                    </div>\n                  </div>\n                  <div className=\"flex flex-wrap items-center gap-2\">\n                    <Input\n                      id=\"discount-val\"\n                      type=\"number\"\n                      min=\"0\"\n                      step=\"1\"\n                      value={discountValue}\n                      onChange={(e) => setDiscountValue(Number(e.target.value))}\n                      placeholder=\"0\"\n                      size=\"small\"\n                      className=\"w-full\"\n                    />\n                    <span className=\"text-success text-success text-xs font-medium whitespace-nowrap tabular-nums\">\n                      -{formatCurrency(effectiveDiscount)}\n                    </span>\n                  </div>\n                </div>\n              </div>\n\n              {/* Notes / Terms */}\n              <div className=\"space-y-1.5\">\n                <label htmlFor=\"invoice-notes\" className=\"text-foreground text-xs font-medium\">\n                  Notes & Terms for Client\n                </label>\n                <Textarea\n                  id=\"invoice-notes\"\n                  value={notes}\n                  onValueChange={setNotes}\n                  rows={3}\n                  placeholder=\"Payment instructions, bank wire info, or a personal thank you note...\"\n                  className=\"text-xs\"\n                />\n              </div>\n            </CardContent>\n          </Card>\n        </div>\n\n        {/* Right Column: Live Paper Document Preview */}\n        <div className=\"space-y-4 lg:sticky lg:top-6 lg:col-span-5\">\n          <div className=\"flex flex-wrap items-center justify-between px-1\">\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <span className=\"relative flex size-2\">\n                <span className=\"bg-success absolute inline-flex h-full w-full rounded-full opacity-75\"></span>\n                <span className=\"bg-success relative inline-flex size-2 rounded-full\"></span>\n              </span>\n              <span className=\"text-muted-foreground flex items-center gap-1 text-xs font-medium\">\n                <Eye className=\"size-3.5\" aria-hidden=\"true\" />\n                Live Document Preview\n              </span>\n            </div>\n            <span className=\"text-muted-foreground font-mono text-xs\">Printable A4</span>\n          </div>\n\n          {/* Paper Invoice Card */}\n          <div className=\"bg-card text-card-foreground border-border/80 relative space-y-6 overflow-hidden rounded-xl border p-6 shadow-md transition-colors sm:p-7\">\n            {/* Document Header */}\n            <div className=\"flex items-start justify-between gap-4\">\n              <div className=\"space-y-1\">\n                <div className=\"flex flex-wrap items-center gap-2\">\n                  <div className=\"bg-primary/10 text-primary border-primary/20 flex size-8 items-center justify-center rounded border text-xs font-bold\">\n                    AS\n                  </div>\n                  <div className=\"text-foreground text-sm leading-tight font-bold sm:text-base\">\n                    {issuerName || 'Business Name'}\n                  </div>\n                </div>\n                <p className=\"text-muted-foreground max-w-[200px] text-xs leading-relaxed\">\n                  {issuerAddress || 'Address not set'}\n                </p>\n                <p className=\"text-muted-foreground font-mono text-xs\">{issuerEmail || 'billing@domain.com'}</p>\n                {issuerTaxId && <p className=\"text-muted-foreground/80 font-mono text-xs\">Tax: {issuerTaxId}</p>}\n              </div>\n\n              <div className=\"shrink-0 space-y-1 text-right\">\n                <span className=\"text-muted-foreground text-xs font-bold tracking-wider uppercase\">Invoice</span>\n                <div className=\"text-foreground font-mono text-xs font-bold sm:text-sm\">{invoiceNumber}</div>\n                <Badge\n                  wrap\n                  variant=\"outline\"\n                  className=\"border-success/30 bg-success/10 text-success text-xs font-medium\"\n                >\n                  Ready to Send\n                </Badge>\n              </div>\n            </div>\n\n            <Separator className=\"opacity-60\" />\n\n            {/* Invoice Details: Bill To & Dates */}\n            <div className=\"grid grid-cols-2 gap-4 text-xs\">\n              <div className=\"space-y-1\">\n                <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Billed To</span>\n                <p className=\"text-foreground font-semibold\">{clientName || 'Client Name'}</p>\n                {clientCompany && <p className=\"text-muted-foreground font-medium\">{clientCompany}</p>}\n                <p className=\"text-muted-foreground leading-relaxed\">{clientAddress || 'No address provided'}</p>\n                <p className=\"text-muted-foreground font-mono\">{clientEmail || 'client@email.com'}</p>\n              </div>\n\n              <div className=\"space-y-1 text-right\">\n                <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                  Invoice Details\n                </span>\n                <div className=\"space-y-0.5\">\n                  <div className=\"text-muted-foreground flex justify-between gap-2 sm:justify-end\">\n                    <span>Issued:</span>\n                    <span className=\"text-foreground font-medium tabular-nums\">{formatDate(invoiceDate)}</span>\n                  </div>\n                  <div className=\"text-muted-foreground flex justify-between gap-2 sm:justify-end\">\n                    <span>Due:</span>\n                    <span className=\"text-foreground font-medium tabular-nums\">{formatDate(dueDate)}</span>\n                  </div>\n                  <div className=\"text-muted-foreground flex justify-between gap-2 sm:justify-end\">\n                    <span>Terms:</span>\n                    <span className=\"text-foreground font-medium\">\n                      {PAYMENT_TERMS_MAP[paymentTerms] || paymentTerms}\n                    </span>\n                  </div>\n                </div>\n              </div>\n            </div>\n\n            <Separator className=\"opacity-60\" />\n\n            {/* Line Items Table */}\n            <div className=\"space-y-2\">\n              <div className=\"overflow-x-auto\">\n                <table className=\"w-full text-xs\">\n                  <thead>\n                    <tr className=\"border-border/80 text-muted-foreground border-b font-medium\">\n                      <th className=\"pb-2 text-left\">Item & Description</th>\n                      <th className=\"w-12 pb-2 text-center\">Qty</th>\n                      <th className=\"w-16 pb-2 text-right\">Rate</th>\n                      <th className=\"w-20 pb-2 text-right\">Amount</th>\n                    </tr>\n                  </thead>\n                  <tbody className=\"divide-border/40 divide-y\">\n                    {items.map((item) => (\n                      <tr key={item.id} className=\"text-foreground\">\n                        <td className=\"py-2 pr-2\">\n                          <p className=\"leading-snug font-medium\">{item.description || 'Custom Deliverable'}</p>\n                        </td>\n                        <td className=\"text-muted-foreground px-1 py-2 text-center tabular-nums\">{item.quantity}</td>\n                        <td className=\"text-muted-foreground px-1 py-2 text-right tabular-nums\">\n                          {formatCurrency(Number(item.unitPrice) || 0)}\n                        </td>\n                        <td className=\"py-2 pl-2 text-right font-medium tabular-nums\">\n                          {formatCurrency((Number(item.quantity) || 0) * (Number(item.unitPrice) || 0))}\n                        </td>\n                      </tr>\n                    ))}\n                  </tbody>\n                </table>\n              </div>\n            </div>\n\n            <Separator className=\"opacity-60\" />\n\n            {/* Calculations Summary */}\n            <div className=\"space-y-2 text-xs\">\n              <div className=\"text-muted-foreground flex justify-between\">\n                <span>Subtotal</span>\n                <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(subtotal)}</span>\n              </div>\n\n              {effectiveDiscount > 0 && (\n                <div className=\"text-success flex justify-between font-medium\">\n                  <span>Discount {discountType === 'percent' ? `(${discountValue}%)` : ''}</span>\n                  <span className=\"tabular-nums\">-{formatCurrency(effectiveDiscount)}</span>\n                </div>\n              )}\n\n              {taxRate > 0 && (\n                <div className=\"text-muted-foreground flex justify-between\">\n                  <span>Tax ({taxRate}%)</span>\n                  <span className=\"text-foreground font-medium tabular-nums\">+{formatCurrency(taxAmount)}</span>\n                </div>\n              )}\n\n              <Separator className=\"my-1.5 opacity-80\" />\n\n              <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 pt-1\">\n                <span className=\"text-foreground text-sm font-bold\">Total Due</span>\n                <span className=\"text-foreground text-lg font-bold tabular-nums sm:text-xl\">\n                  {formatCurrency(totalDue)}\n                </span>\n              </div>\n            </div>\n\n            {/* Notes / Payment Info Callout */}\n            <div className=\"bg-muted/50 border-border/70 space-y-2 rounded-lg border p-3.5 text-xs\">\n              <div className=\"text-foreground flex items-center gap-1.5 font-medium\">\n                <CreditCard className=\"text-primary size-3.5\" aria-hidden=\"true\" />\n                <span>Payment Instructions</span>\n              </div>\n              {notes && <p className=\"text-muted-foreground leading-relaxed\">{notes}</p>}\n              <div className=\"border-border/50 text-muted-foreground flex flex-wrap items-center justify-between gap-2 border-t pt-1.5 font-mono text-xs\">\n                <span>ACH / Wire: **** 9104</span>\n                <span>Routing: **** 4892</span>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/InvoiceCreatorWizard.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/select.json",
    "https://uipkge.dev/r/react/separator.json",
    "https://uipkge.dev/r/react/textarea.json"
  ],
  "description": "Square/Stripe-style interactive invoice builder with itemized tax, discount calculation, dynamic line items, client presets, and a real-time paper document preview.",
  "categories": [
    "finance",
    "app",
    "billing",
    "form"
  ]
}