{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "currency-converter-widget",
  "title": "Currency Converter Widget",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/currency-converter-widget/CurrencyConverterWidget.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  ArrowDownRight,\n  ArrowRight,\n  ArrowUpDown,\n  ArrowUpRight,\n  Building2,\n  Lock,\n  Minus,\n  RefreshCw,\n  ShieldCheck,\n  Coins,\n  Zap,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'\nimport { Separator } from '@/components/ui/separator'\n\nexport interface CurrencyOption {\n  code: string\n  name: string\n  symbol: string\n  flag: string\n  rateToBase: number // USD base = 1.0\n  deliverySpeed: string\n  deliveryNetwork: string\n}\n\nexport interface PopularPair {\n  id: string\n  from: string\n  to: string\n  change24h: number\n  trend: 'up' | 'down'\n}\n\nexport interface TransferPayload {\n  sendAmount: number\n  fromCurrency: string\n  toCurrency: string\n  recipientGets: number\n  fee: number\n  rate: number\n}\n\nexport interface CurrencyConverterWidgetProps {\n  initialSendAmount?: number\n  initialFromCurrency?: string\n  initialToCurrency?: string\n  className?: string\n  onTransfer?: (payload: TransferPayload) => void\n}\n\nconst CURRENCIES: CurrencyOption[] = [\n  {\n    code: 'USD',\n    name: 'US Dollar',\n    symbol: '$',\n    flag: '🇺🇸',\n    rateToBase: 1.0,\n    deliverySpeed: 'in minutes',\n    deliveryNetwork: 'FedNow / RTP',\n  },\n  {\n    code: 'EUR',\n    name: 'Euro',\n    symbol: '€',\n    flag: '🇪🇺',\n    rateToBase: 0.9245,\n    deliverySpeed: 'in minutes',\n    deliveryNetwork: 'SEPA Instant',\n  },\n  {\n    code: 'GBP',\n    name: 'British Pound',\n    symbol: '£',\n    flag: '🇬🇧',\n    rateToBase: 0.7892,\n    deliverySpeed: 'in seconds',\n    deliveryNetwork: 'Faster Payments',\n  },\n  {\n    code: 'JPY',\n    name: 'Japanese Yen',\n    symbol: '¥',\n    flag: '🇯🇵',\n    rateToBase: 154.6,\n    deliverySpeed: 'within 4 hours',\n    deliveryNetwork: 'Zengin System',\n  },\n  {\n    code: 'CAD',\n    name: 'Canadian Dollar',\n    symbol: 'CA$',\n    flag: '🇨🇦',\n    rateToBase: 1.378,\n    deliverySpeed: 'in minutes',\n    deliveryNetwork: 'Interac Direct',\n  },\n  {\n    code: 'AUD',\n    name: 'Australian Dollar',\n    symbol: 'A$',\n    flag: '🇦🇺',\n    rateToBase: 1.523,\n    deliverySpeed: 'in minutes',\n    deliveryNetwork: 'NPP / PayID',\n  },\n  {\n    code: 'SGD',\n    name: 'Singapore Dollar',\n    symbol: 'S$',\n    flag: '🇸🇬',\n    rateToBase: 1.348,\n    deliverySpeed: 'instant',\n    deliveryNetwork: 'FAST Network',\n  },\n  {\n    code: 'CHF',\n    name: 'Swiss Franc',\n    symbol: 'CHF',\n    flag: '🇨🇭',\n    rateToBase: 0.898,\n    deliverySpeed: 'in minutes',\n    deliveryNetwork: 'SIC Instant',\n  },\n]\n\nconst POPULAR_PAIRS: PopularPair[] = [\n  { id: 'eur-usd', from: 'EUR', to: 'USD', change24h: 0.18, trend: 'up' },\n  { id: 'gbp-usd', from: 'GBP', to: 'USD', change24h: 0.24, trend: 'up' },\n  { id: 'usd-jpy', from: 'USD', to: 'JPY', change24h: -0.32, trend: 'down' },\n  { id: 'usd-cad', from: 'USD', to: 'CAD', change24h: 0.09, trend: 'up' },\n  { id: 'usd-eur', from: 'USD', to: 'EUR', change24h: -0.18, trend: 'down' },\n  { id: 'gbp-eur', from: 'GBP', to: 'EUR', change24h: 0.05, trend: 'up' },\n]\n\nfunction formatAmount(val: number, currencyCode: string): string {\n  const isZeroDecimal = currencyCode === 'JPY'\n  return new Intl.NumberFormat('en-US', {\n    minimumFractionDigits: isZeroDecimal ? 0 : 2,\n    maximumFractionDigits: isZeroDecimal ? 0 : 2,\n  }).format(val)\n}\n\nfunction getPairRate(fromCode: string, toCode: string): string {\n  const f = CURRENCIES.find((c) => c.code === fromCode)?.rateToBase || 1\n  const t = CURRENCIES.find((c) => c.code === toCode)?.rateToBase || 1\n  const rate = t / f\n  return rate >= 100 ? rate.toFixed(2) : rate.toFixed(4)\n}\n\nexport function CurrencyConverterWidget({\n  initialSendAmount = 1000,\n  initialFromCurrency = 'USD',\n  initialToCurrency = 'EUR',\n  className,\n  onTransfer,\n}: CurrencyConverterWidgetProps) {\n  const [sendAmount, setSendAmount] = React.useState<number>(initialSendAmount)\n  const [fromCurrency, setFromCurrency] = React.useState<string>(initialFromCurrency)\n  const [toCurrency, setToCurrency] = React.useState<string>(initialToCurrency)\n  const [paymentMethod, setPaymentMethod] = React.useState<'bank' | 'card'>('bank')\n  const [isRefreshing, setIsRefreshing] = React.useState<boolean>(false)\n  const [refreshSuccess, setRefreshSuccess] = React.useState<boolean>(false)\n\n  const fromCurrencyObj = React.useMemo(\n    () => CURRENCIES.find((c) => c.code === fromCurrency) || CURRENCIES[0],\n    [fromCurrency],\n  )\n  const toCurrencyObj = React.useMemo(\n    () => CURRENCIES.find((c) => c.code === toCurrency) || CURRENCIES[1],\n    [toCurrency],\n  )\n\n  // Dynamic mid-market rate calculation\n  const exchangeRate = React.useMemo(() => {\n    if (!fromCurrencyObj || !toCurrencyObj) return 1\n    return toCurrencyObj.rateToBase / fromCurrencyObj.rateToBase\n  }, [fromCurrencyObj, toCurrencyObj])\n\n  const formattedExchangeRate = React.useMemo(() => {\n    if (exchangeRate >= 100) return exchangeRate.toFixed(2)\n    if (exchangeRate >= 1) return exchangeRate.toFixed(4)\n    return exchangeRate.toFixed(5)\n  }, [exchangeRate])\n\n  // Fee calculation logic\n  const fixedBaseFee = React.useMemo(() => {\n    const base = 1.2 * fromCurrencyObj.rateToBase\n    return paymentMethod === 'card' ? base * 1.6 : base\n  }, [fromCurrencyObj, paymentMethod])\n\n  const variableRate = paymentMethod === 'card' ? 0.0065 : 0.0035\n  const variableFee = (sendAmount || 0) * variableRate\n  const totalFee = fixedBaseFee + variableFee\n  const amountToConvert = Math.max(0, (sendAmount || 0) - totalFee)\n  const recipientGets = amountToConvert * exchangeRate\n\n  // Bank comparison calculation\n  const bankWireFee = 20 * fromCurrencyObj.rateToBase\n  const bankMarkupSpread = 0.032 // 3.2% average hidden bank margin\n  const bankTotalCost = bankWireFee + (sendAmount || 0) * bankMarkupSpread\n  const estimatedSavings = Math.max(0, bankTotalCost - totalFee)\n\n  const handleSwap = React.useCallback(() => {\n    setFromCurrency(toCurrency)\n    setToCurrency(fromCurrency)\n  }, [fromCurrency, toCurrency])\n\n  const handleSelectPair = React.useCallback((pair: PopularPair) => {\n    setFromCurrency(pair.from)\n    setToCurrency(pair.to)\n  }, [])\n\n  const handleRefresh = React.useCallback(() => {\n    if (isRefreshing) return\n    setIsRefreshing(true)\n    setTimeout(() => {\n      setIsRefreshing(false)\n      setRefreshSuccess(true)\n      setTimeout(() => {\n        setRefreshSuccess(false)\n      }, 2000)\n    }, 450)\n  }, [isRefreshing])\n\n  const handleTransfer = React.useCallback(() => {\n    onTransfer?.({\n      sendAmount: Number(sendAmount) || 0,\n      fromCurrency,\n      toCurrency,\n      recipientGets,\n      fee: totalFee,\n      rate: exchangeRate,\n    })\n  }, [sendAmount, fromCurrency, toCurrency, recipientGets, totalFee, exchangeRate, onTransfer])\n\n  return (\n    <div className={cn('mx-auto w-full max-w-2xl space-y-6', className)} data-slot=\"currency-converter-widget\">\n      {/* Header Section */}\n      <div className=\"space-y-2\">\n        <div className=\"flex flex-wrap items-center justify-between gap-2\">\n          <h2 className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">\n            Currency Converter & International Transfer\n          </h2>\n          <Badge variant=\"outline\" className=\"gap-1.5 py-1 text-xs font-normal\">\n            <span className=\"bg-success size-2 animate-pulse rounded-full\" />\n            Live Market Rates\n          </Badge>\n        </div>\n        <p className=\"text-muted-foreground text-sm\">\n          Real-time mid-market exchange rates with transparent fees. No hidden markups.\n        </p>\n\n        {/* Refresh & Current Mid-market rate banner */}\n        <div className=\"border-border bg-muted/40 text-muted-foreground flex flex-wrap items-center justify-between gap-2 rounded-lg border px-3.5 py-2 text-xs\">\n          <div className=\"flex items-center gap-2\">\n            <span className=\"text-foreground font-medium\">\n              Mid-market rate: 1 {fromCurrencyObj.code} = {formattedExchangeRate} {toCurrencyObj.code}\n            </span>\n            <span>Updated 1m ago</span>\n          </div>\n          <button\n            type=\"button\"\n            aria-label=\"Refresh exchange rates\"\n            className=\"text-foreground hover:text-primary focus-visible:ring-ring inline-flex min-h-6 items-center gap-1 rounded px-1.5 py-0.5 font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n            onClick={handleRefresh}\n          >\n            <RefreshCw\n              className={cn(\n                'size-3.5 transition-transform duration-500',\n                isRefreshing ? 'text-primary animate-spin' : '',\n              )}\n            />\n            <span>{refreshSuccess ? 'Refreshed!' : 'Refresh'}</span>\n          </button>\n        </div>\n      </div>\n\n      {/* Main Converter Card */}\n      <Card className=\"border-border shadow-xs\">\n        <CardContent className=\"space-y-4 p-5 sm:p-6\">\n          {/* Payment method tab pill */}\n          <div className=\"flex items-center justify-between gap-2\">\n            <div className=\"border-border bg-muted/50 inline-flex rounded-lg border p-1 text-xs\">\n              <button\n                type=\"button\"\n                className={cn(\n                  'min-h-6 rounded-md px-3 py-1 font-medium transition-colors',\n                  paymentMethod === 'bank'\n                    ? 'bg-card text-foreground shadow-xs'\n                    : 'text-muted-foreground hover:text-foreground',\n                )}\n                onClick={() => setPaymentMethod('bank')}\n              >\n                Bank Transfer (Lowest Fee)\n              </button>\n              <button\n                type=\"button\"\n                className={cn(\n                  'min-h-6 rounded-md px-3 py-1 font-medium transition-colors',\n                  paymentMethod === 'card'\n                    ? 'bg-card text-foreground shadow-xs'\n                    : 'text-muted-foreground hover:text-foreground',\n                )}\n                onClick={() => setPaymentMethod('card')}\n              >\n                Debit / Credit Card\n              </button>\n            </div>\n\n            <span className=\"text-muted-foreground hidden text-xs sm:inline-flex\">Guaranteed rate for 24h</span>\n          </div>\n\n          {/* \"You send\" Input Container */}\n          <div className=\"border-input bg-card focus-within:border-ring focus-within:ring-ring/20 rounded-xl border p-3.5 shadow-2xs transition-colors focus-within:ring-2\">\n            <div className=\"text-muted-foreground mb-1.5 flex items-center justify-between text-xs\">\n              <label htmlFor=\"send-amount-react-input\" className=\"text-foreground font-medium\">\n                You send\n              </label>\n              <span>Max limit: $100,000 / transfer</span>\n            </div>\n\n            <div className=\"flex flex-wrap items-center gap-3\">\n              <div className=\"flex flex-1 items-baseline gap-1\">\n                <span className=\"text-muted-foreground text-xl font-semibold select-none sm:text-2xl\">\n                  {fromCurrencyObj.symbol}\n                </span>\n                <input\n                  id=\"send-amount-react-input\"\n                  value={Number.isNaN(sendAmount) ? '' : sendAmount}\n                  onChange={(e) => setSendAmount(Number.parseFloat(e.target.value) || 0)}\n                  type=\"number\"\n                  min=\"1\"\n                  step=\"any\"\n                  placeholder=\"1,000.00\"\n                  className=\"text-foreground placeholder:text-muted-foreground/40 w-full bg-transparent text-2xl font-bold tracking-tight tabular-nums outline-none sm:text-3xl\"\n                />\n              </div>\n\n              {/* From Currency Selector */}\n              <div className=\"w-36 shrink-0\">\n                <Select value={fromCurrency} onValueChange={(val) => setFromCurrency(val)}>\n                  <SelectTrigger className=\"bg-muted/40 h-11 w-full text-xs font-medium sm:text-sm\">\n                    <div className=\"flex items-center gap-2 text-left\">\n                      <span className=\"text-base leading-none\">{fromCurrencyObj.flag}</span>\n                      <span className=\"font-semibold\">{fromCurrencyObj.code}</span>\n                    </div>\n                  </SelectTrigger>\n                  <SelectContent className=\"max-h-64\">\n                    {CURRENCIES.map((curr) => (\n                      <SelectItem key={curr.code} value={curr.code}>\n                        <div className=\"flex items-center gap-2\">\n                          <span className=\"text-base\">{curr.flag}</span>\n                          <span className=\"font-semibold\">{curr.code}</span>\n                          <span className=\"text-muted-foreground truncate text-xs\">({curr.name})</span>\n                        </div>\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n\n          {/* Transfer Breakdown Rail (Vertical Connector) */}\n          <div className=\"before:bg-border relative my-1 space-y-3.5 py-2 pl-6 before:absolute before:top-2 before:bottom-2 before:left-2.5 before:w-px\">\n            {/* Step 1: Fee */}\n            <div className=\"relative flex items-center justify-between text-xs\">\n              <div className=\"border-border bg-card text-muted-foreground absolute -left-[19px] flex size-3.5 items-center justify-center rounded-full border\">\n                <Minus className=\"size-2.5\" />\n              </div>\n              <div className=\"flex items-center gap-1.5\">\n                <span className=\"text-foreground font-semibold tabular-nums\">\n                  -{fromCurrencyObj.symbol}\n                  {formatAmount(totalFee, fromCurrencyObj.code)} {fromCurrencyObj.code}\n                </span>\n                <span className=\"text-muted-foreground\">Transfer fee</span>\n                <Badge variant=\"secondary\" className=\"text-muted-foreground h-4.5 px-1.5 text-xs font-normal\">\n                  {paymentMethod === 'card' ? '0.65% + $1.20' : '0.35% + $1.20'}\n                </Badge>\n              </div>\n              <span className=\"text-muted-foreground hidden sm:inline\">Transparent fixed rate</span>\n            </div>\n\n            {/* Step 2: Amount to convert */}\n            <div className=\"relative flex items-center justify-between text-xs\">\n              <div className=\"border-border bg-card text-muted-foreground absolute -left-[19px] flex size-3.5 items-center justify-center rounded-full border\">\n                <span className=\"text-xs leading-none font-bold\">=</span>\n              </div>\n              <div className=\"flex items-center gap-1.5\">\n                <span className=\"text-foreground font-semibold tabular-nums\">\n                  {fromCurrencyObj.symbol}\n                  {formatAmount(amountToConvert, fromCurrencyObj.code)} {fromCurrencyObj.code}\n                </span>\n                <span className=\"text-muted-foreground\">Amount to convert</span>\n              </div>\n              <span className=\"text-muted-foreground hidden sm:inline\">Net transfer base</span>\n            </div>\n\n            {/* Step 3: Guaranteed Exchange Rate & Swap Button Line */}\n            <div className=\"relative flex flex-wrap items-center justify-between gap-2 text-xs\">\n              <div className=\"border-primary/50 bg-primary text-primary-foreground absolute -left-[19px] flex size-3.5 items-center justify-center rounded-full border\">\n                <Lock className=\"size-2\" />\n              </div>\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <span className=\"text-foreground font-semibold tabular-nums\">× {formattedExchangeRate}</span>\n                <span className=\"text-muted-foreground\">Guaranteed mid-market rate</span>\n                <Badge variant=\"outline\" className=\"border-success/30 bg-success/10 text-success gap-1 py-0.5 text-xs\">\n                  <Lock className=\"size-2.5\" />\n                  24h Guarantee\n                </Badge>\n              </div>\n\n              {/* Swap Currencies Button */}\n              <button\n                type=\"button\"\n                aria-label=\"Swap currencies\"\n                className=\"border-border bg-card text-foreground hover:bg-accent hover:border-primary/50 focus-visible:ring-ring inline-flex min-h-6 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium shadow-2xs transition-[background-color,border-color,box-shadow,scale] focus-visible:ring-2 focus-visible:outline-none active:scale-95\"\n                onClick={handleSwap}\n              >\n                <ArrowUpDown className=\"text-primary size-3\" />\n                <span>Swap</span>\n              </button>\n            </div>\n          </div>\n\n          {/* \"Recipient gets\" Input / Output Container */}\n          <div className=\"border-input bg-card focus-within:border-ring focus-within:ring-ring/20 rounded-xl border p-3.5 shadow-2xs transition-colors focus-within:ring-2\">\n            <div className=\"text-muted-foreground mb-1.5 flex items-center justify-between text-xs\">\n              <label className=\"text-foreground font-medium\">Recipient gets</label>\n              <span className=\"text-success flex items-center gap-1 font-medium\">\n                <Zap className=\"size-3\" />\n                {toCurrencyObj.deliverySpeed}\n              </span>\n            </div>\n\n            <div className=\"flex flex-wrap items-center gap-3\">\n              <div className=\"flex min-w-0 flex-1 items-baseline gap-1\">\n                <span className=\"text-muted-foreground text-xl font-semibold select-none sm:text-2xl\">\n                  {toCurrencyObj.symbol}\n                </span>\n                <div className=\"text-foreground w-full truncate text-2xl font-bold tracking-tight tabular-nums select-all sm:text-3xl\">\n                  {formatAmount(recipientGets, toCurrencyObj.code)}\n                </div>\n              </div>\n\n              {/* To Currency Selector */}\n              <div className=\"w-36 shrink-0\">\n                <Select value={toCurrency} onValueChange={(val) => setToCurrency(val)}>\n                  <SelectTrigger className=\"bg-muted/40 h-11 w-full text-xs font-medium sm:text-sm\">\n                    <div className=\"flex items-center gap-2 text-left\">\n                      <span className=\"text-base leading-none\">{toCurrencyObj.flag}</span>\n                      <span className=\"font-semibold\">{toCurrencyObj.code}</span>\n                    </div>\n                  </SelectTrigger>\n                  <SelectContent className=\"max-h-64\">\n                    {CURRENCIES.map((curr) => (\n                      <SelectItem key={curr.code} value={curr.code}>\n                        <div className=\"flex items-center gap-2\">\n                          <span className=\"text-base\">{curr.flag}</span>\n                          <span className=\"font-semibold\">{curr.code}</span>\n                          <span className=\"text-muted-foreground truncate text-xs\">({curr.name})</span>\n                        </div>\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n\n          {/* Delivery Speed & Savings Breakdown Banner */}\n          <div className=\"border-border bg-muted/30 space-y-3 rounded-lg border p-4\">\n            <div className=\"flex flex-wrap items-center justify-between gap-2\">\n              <div className=\"flex items-center gap-2 text-xs\">\n                <span className=\"bg-primary/10 text-primary flex size-6 items-center justify-center rounded-full\">\n                  <Zap className=\"size-3.5\" />\n                </span>\n                <div>\n                  <p className=\"text-foreground font-semibold\">Estimated delivery: {toCurrencyObj.deliverySpeed}</p>\n                  <p className=\"text-muted-foreground\">Via {toCurrencyObj.deliveryNetwork}</p>\n                </div>\n              </div>\n\n              <Badge variant=\"outline\" className=\"border-warning/30 bg-warning/10 text-warning gap-1 py-1 text-xs\">\n                <Coins className=\"size-3\" />\n                Save ~{fromCurrencyObj.symbol}\n                {formatAmount(estimatedSavings, fromCurrencyObj.code)} {fromCurrencyObj.code}\n              </Badge>\n            </div>\n\n            <Separator />\n\n            {/* Comparison vs Standard High-Street Bank */}\n            <div className=\"grid grid-cols-1 gap-3 text-xs sm:grid-cols-2\">\n              <div className=\"bg-card/60 border-border flex items-start gap-2 rounded-md border p-2.5\">\n                <ShieldCheck className=\"text-success mt-0.5 size-4 shrink-0\" />\n                <div>\n                  <p className=\"text-foreground font-medium\">UIPKGE Transfer</p>\n                  <p className=\"text-muted-foreground text-xs\">\n                    Fee: {fromCurrencyObj.symbol}\n                    {formatAmount(totalFee, fromCurrencyObj.code)} · 0% exchange spread\n                  </p>\n                </div>\n              </div>\n\n              <div className=\"bg-card/60 border-border flex items-start gap-2 rounded-md border p-2.5 opacity-75\">\n                <Building2 className=\"text-muted-foreground mt-0.5 size-4 shrink-0\" />\n                <div>\n                  <p className=\"text-foreground font-medium\">Standard Bank Wire</p>\n                  <p className=\"text-muted-foreground text-xs\">\n                    Fee: ~{fromCurrencyObj.symbol}\n                    {formatAmount(bankTotalCost, fromCurrencyObj.code)} · ~3.2% hidden spread\n                  </p>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          {/* Primary Action Button */}\n          <Button className=\"h-11 w-full gap-2 text-base font-semibold shadow-sm\" onClick={handleTransfer}>\n            <span>\n              Get Started / Send {fromCurrencyObj.symbol}\n              {formatAmount(sendAmount || 0, fromCurrencyObj.code)}\n            </span>\n            <ArrowRight className=\"size-4\" />\n          </Button>\n\n          <p className=\"text-muted-foreground flex items-center justify-center gap-1.5 text-center text-xs\">\n            <Lock className=\"text-muted-foreground size-3\" />\n            <span>Rates locked for 24 hours. Licensed & regulated financial institution.</span>\n          </p>\n        </CardContent>\n      </Card>\n\n      {/* Popular Currency Pairs Quick Rate Ticker */}\n      <div className=\"space-y-3\">\n        <div className=\"flex items-center justify-between\">\n          <h3 className=\"text-foreground text-sm font-semibold\">Popular Currency Pairs</h3>\n          <span className=\"text-muted-foreground text-xs\">Click pair to load</span>\n        </div>\n\n        <div className=\"grid grid-cols-2 gap-2.5 sm:grid-cols-3\">\n          {POPULAR_PAIRS.map((pair) => {\n            const isSelected = fromCurrency === pair.from && toCurrency === pair.to\n            return (\n              <button\n                key={pair.id}\n                type=\"button\"\n                className={cn(\n                  'hover:bg-accent focus-visible:ring-ring flex flex-col items-start gap-1 rounded-lg border p-3 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none',\n                  isSelected ? 'border-primary bg-primary/5 ring-primary/20 ring-1' : 'border-border bg-card',\n                )}\n                onClick={() => handleSelectPair(pair)}\n              >\n                <div className=\"flex w-full items-center justify-between text-xs\">\n                  <span className=\"text-foreground font-semibold\">\n                    {pair.from} / {pair.to}\n                  </span>\n                  <span\n                    className={cn(\n                      'flex items-center text-xs font-medium',\n                      pair.trend === 'up' ? 'text-success' : 'text-destructive',\n                    )}\n                  >\n                    {pair.trend === 'up' ? <ArrowUpRight className=\"size-3\" /> : <ArrowDownRight className=\"size-3\" />}\n                    {pair.change24h > 0 ? `+${pair.change24h}%` : `${pair.change24h}%`}\n                  </span>\n                </div>\n\n                <div className=\"text-foreground text-sm font-bold tabular-nums\">{getPairRate(pair.from, pair.to)}</div>\n              </button>\n            )\n          })}\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/CurrencyConverterWidget.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/select.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Wise and Revolut-style real-time multi-currency exchange calculator and transfer fee estimator with live mid-market rates, transparent fee breakdown rail, bank savings comparison, and quick-rate ticker.",
  "categories": [
    "finance",
    "fintech",
    "billing",
    "commerce"
  ]
}