{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cart-drawer",
  "title": "Cart Drawer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/cart-drawer/CartDrawer.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { Leaf, Lock, Minus, Plus, RotateCcw, ShieldCheck, ShoppingBag, Tag, Trash2, Truck, X } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Progress } from '@/components/ui/progress'\nimport { Separator } from '@/components/ui/separator'\n\nexport interface CartItem {\n  id: string\n  name: string\n  variant: string\n  price: number\n  originalPrice?: number\n  qty: number\n  inStock?: boolean\n  image: string\n}\n\nexport interface CartDrawerProps {\n  variant?: 'drawer' | 'page'\n  items?: CartItem[]\n  currency?: string\n  freeShippingThreshold?: number\n  taxRate?: number\n  initialPromoCode?: string\n  className?: string\n  onCheckout?: (items: CartItem[], total: number) => void\n  onContinueShopping?: () => void\n  onClose?: () => void\n  onUpdateQuantity?: (id: string, qty: number) => void\n  onRemoveItem?: (id: string) => void\n  onApplyPromo?: (code: string) => void\n  onRemovePromo?: () => void\n}\n\nconst DEFAULT_ITEMS: CartItem[] = [\n  {\n    id: 'item-1',\n    name: 'Aero Minimalist Runner',\n    variant: 'Size: 10.5 · Color: Matte Black',\n    price: 120,\n    originalPrice: 140,\n    qty: 1,\n    inStock: true,\n    image: 'https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=300&auto=format&fit=crop&q=80',\n  },\n  {\n    id: 'item-2',\n    name: 'Technical Shell Parka',\n    variant: 'Size: L · Color: Mineral Gray',\n    price: 95,\n    originalPrice: 110,\n    qty: 1,\n    inStock: true,\n    image: 'https://images.unsplash.com/photo-1591047139829-d91aecb6caea?w=300&auto=format&fit=crop&q=80',\n  },\n  {\n    id: 'item-3',\n    name: 'Minimalist Leather Cardholder',\n    variant: 'Size: Slim · Color: Saddle Brown',\n    price: 70,\n    originalPrice: 85,\n    qty: 1,\n    inStock: true,\n    image: 'https://images.unsplash.com/photo-1627123424574-724758594e93?w=300&auto=format&fit=crop&q=80',\n  },\n]\n\nexport function CartDrawer({\n  variant = 'drawer',\n  items = DEFAULT_ITEMS,\n  currency = 'USD',\n  freeShippingThreshold = 300,\n  taxRate = 0.08,\n  initialPromoCode = '',\n  className,\n  onCheckout,\n  onContinueShopping,\n  onClose,\n  onUpdateQuantity,\n  onRemoveItem,\n  onApplyPromo,\n  onRemovePromo,\n}: CartDrawerProps) {\n  const [cartItems, setCartItems] = React.useState<CartItem[]>(() => items.map((item) => ({ ...item })))\n  const [promoCodeInput, setPromoCodeInput] = React.useState('')\n  const [appliedPromo, setAppliedPromo] = React.useState<string>(initialPromoCode)\n  const [promoDiscount, setPromoDiscount] = React.useState<number>(initialPromoCode ? 20 : 0)\n  const [promoError, setPromoError] = React.useState('')\n  const [promoSuccess, setPromoSuccess] = React.useState('')\n\n  React.useEffect(() => {\n    setCartItems(items.map((item) => ({ ...item })))\n  }, [items])\n\n  const totalItemsCount = React.useMemo(() => cartItems.reduce((acc, item) => acc + item.qty, 0), [cartItems])\n\n  const subtotal = React.useMemo(() => cartItems.reduce((acc, item) => acc + item.price * item.qty, 0), [cartItems])\n\n  const isFreeShippingUnlocked = subtotal >= freeShippingThreshold && cartItems.length > 0\n  const amountAwayFromFreeShipping = Math.max(0, freeShippingThreshold - subtotal)\n  const shippingProgress =\n    cartItems.length === 0 ? 0 : Math.min(100, Math.round((subtotal / freeShippingThreshold) * 100))\n  const shippingFee = cartItems.length === 0 ? 0 : isFreeShippingUnlocked ? 0 : 15\n  const discountedSubtotal = Math.max(0, subtotal - promoDiscount)\n  const estimatedTax = cartItems.length === 0 ? 0 : Number((discountedSubtotal * taxRate).toFixed(2))\n  const total = cartItems.length === 0 ? 0 : Number((discountedSubtotal + shippingFee + estimatedTax).toFixed(2))\n\n  const formatCurrency = React.useCallback(\n    (amount: number) => {\n      try {\n        return new Intl.NumberFormat('en-US', {\n          style: 'currency',\n          currency,\n          minimumFractionDigits: 2,\n        }).format(amount)\n      } catch {\n        return `$${amount.toFixed(2)}`\n      }\n    },\n    [currency],\n  )\n\n  const updateQuantity = (id: string, delta: number) => {\n    setCartItems((prev) =>\n      prev.flatMap((item) => {\n        if (item.id !== id) return [item]\n        const newQty = item.qty + delta\n        if (newQty <= 0) {\n          onRemoveItem?.(id)\n          return []\n        }\n        onUpdateQuantity?.(id, newQty)\n        return [{ ...item, qty: newQty }]\n      }),\n    )\n  }\n\n  const removeItem = (id: string) => {\n    setCartItems((prev) => prev.filter((item) => item.id !== id))\n    onRemoveItem?.(id)\n  }\n\n  const handleApplyPromo = () => {\n    setPromoError('')\n    setPromoSuccess('')\n    const trimmed = promoCodeInput.trim().toUpperCase()\n    if (!trimmed) return\n\n    if (trimmed === 'SUMMER20' || trimmed === 'SAVE20') {\n      setAppliedPromo(trimmed)\n      setPromoDiscount(20)\n      setPromoSuccess('$20.00 coupon discount applied!')\n      setPromoCodeInput('')\n      onApplyPromo?.(trimmed)\n    } else if (trimmed === 'SAVE10') {\n      setAppliedPromo(trimmed)\n      setPromoDiscount(10)\n      setPromoSuccess('$10.00 coupon discount applied!')\n      setPromoCodeInput('')\n      onApplyPromo?.(trimmed)\n    } else {\n      setAppliedPromo(trimmed)\n      setPromoDiscount(15)\n      setPromoSuccess('Promo code applied!')\n      setPromoCodeInput('')\n      onApplyPromo?.(trimmed)\n    }\n  }\n\n  const handleRemovePromo = () => {\n    setAppliedPromo('')\n    setPromoDiscount(0)\n    setPromoSuccess('')\n    setPromoError('')\n    onRemovePromo?.()\n  }\n\n  const handleCheckout = () => {\n    onCheckout?.(cartItems, total)\n  }\n\n  const resetCart = () => {\n    setCartItems(DEFAULT_ITEMS.map((item) => ({ ...item })))\n  }\n\n  return (\n    <div data-slot=\"cart-drawer\" className={cn('w-full', className)}>\n      {variant === 'drawer' ? (\n        /* DRAWER VARIANT */\n        <div className=\"bg-card text-card-foreground border-border/80 mx-auto flex h-full max-h-[820px] min-h-[640px] w-full max-w-md flex-col overflow-hidden rounded-2xl border shadow-xs\">\n          {/* Drawer Header */}\n          <div className=\"border-border/60 flex shrink-0 items-center justify-between border-b px-5 py-4\">\n            <div className=\"flex items-center gap-2\">\n              <h2 className=\"text-base font-semibold tracking-tight\">Shopping Cart</h2>\n              {totalItemsCount > 0 && (\n                <Badge variant=\"secondary\" className=\"tabular-nums\">\n                  {totalItemsCount}\n                </Badge>\n              )}\n            </div>\n            <Button variant=\"ghost\" size=\"icon-sm\" aria-label=\"Close cart drawer\" onClick={onClose}>\n              <X className=\"size-4\" />\n            </Button>\n          </div>\n\n          {/* Free Shipping Meter */}\n          {cartItems.length > 0 && (\n            <div className=\"bg-muted/30 border-border/40 shrink-0 border-b px-5 py-3.5\">\n              <div className=\"flex items-center justify-between gap-2 text-xs\">\n                {isFreeShippingUnlocked ? (\n                  <span className=\"text-primary flex items-center gap-1.5 font-medium\">\n                    <Truck className=\"size-3.5\" />\n                    You&apos;ve unlocked Free Express Shipping!\n                  </span>\n                ) : (\n                  <span className=\"text-muted-foreground\">\n                    🎉 You're{' '}\n                    <strong className=\"text-foreground font-semibold tabular-nums\">\n                      {formatCurrency(amountAwayFromFreeShipping)}\n                    </strong>{' '}\n                    away from Free Shipping!\n                  </span>\n                )}\n                <span className=\"text-muted-foreground font-medium tabular-nums\">{shippingProgress}%</span>\n              </div>\n              <Progress value={shippingProgress} className=\"mt-2 h-1.5\" />\n            </div>\n          )}\n\n          {/* Drawer Body: Line Items or Empty State */}\n          <div className=\"flex-1 overflow-y-auto p-5\">\n            {cartItems.length === 0 ? (\n              <div className=\"flex h-full flex-col items-center justify-center py-12 text-center\">\n                <div className=\"bg-muted text-muted-foreground mb-4 flex size-14 items-center justify-center rounded-full\">\n                  <ShoppingBag className=\"size-7 stroke-[1.5]\" />\n                </div>\n                <h3 className=\"text-base font-semibold\">Your cart is empty</h3>\n                <p className=\"text-muted-foreground mt-1 max-w-xs text-xs leading-relaxed\">\n                  Looks like you haven't added any products to your cart yet. Explore our latest items!\n                </p>\n                <Button className=\"mt-5 gap-2\" size=\"sm\" onClick={resetCart}>\n                  <ShoppingBag className=\"size-3.5\" />\n                  Explore Products\n                </Button>\n              </div>\n            ) : (\n              <div className=\"space-y-4\">\n                <ul className=\"divide-border/60 divide-y\" role=\"list\">\n                  {cartItems.map((item) => (\n                    <li key={item.id} className=\"flex gap-3.5 py-4 first:pt-0 last:pb-0\">\n                      <div className=\"border-border/60 bg-muted/40 relative size-20 shrink-0 overflow-hidden rounded-lg border shadow-xs\">\n                        <img src={item.image} alt={item.name} className=\"size-full object-cover\" />\n                      </div>\n\n                      <div className=\"flex min-w-0 flex-1 flex-col justify-between\">\n                        <div>\n                          <div className=\"flex items-start justify-between gap-2\">\n                            <h3 className=\"text-foreground truncate text-sm leading-snug font-medium\">{item.name}</h3>\n                            <Button\n                              variant=\"ghost\"\n                              size=\"icon-sm\"\n                              className=\"text-muted-foreground hover:text-destructive -mt-1 -mr-1.5 size-7 shrink-0\"\n                              aria-label={`Remove ${item.name} from cart`}\n                              onClick={() => removeItem(item.id)}\n                            >\n                              <Trash2 className=\"size-3.5\" />\n                            </Button>\n                          </div>\n                          <p className=\"text-muted-foreground mt-0.5 text-xs\">{item.variant}</p>\n                          <div className=\"mt-1 flex items-center gap-1.5\">\n                            <span className=\"bg-success size-1.5 rounded-full\" />\n                            <span className=\"text-success text-xs font-medium\">In stock</span>\n                          </div>\n                        </div>\n\n                        <div className=\"mt-2.5 flex items-center justify-between\">\n                          <div className=\"border-border/80 bg-background flex items-center rounded-md border shadow-xs\">\n                            <Button\n                              variant=\"ghost\"\n                              size=\"icon-sm\"\n                              className=\"size-7 rounded-none rounded-l-md\"\n                              aria-label={`Decrease quantity for ${item.name}`}\n                              onClick={() => updateQuantity(item.id, -1)}\n                            >\n                              <Minus className=\"size-3\" />\n                            </Button>\n                            <span className=\"w-7 text-center text-xs font-medium tabular-nums\">{item.qty}</span>\n                            <Button\n                              variant=\"ghost\"\n                              size=\"icon-sm\"\n                              className=\"size-7 rounded-none rounded-r-md\"\n                              aria-label={`Increase quantity for ${item.name}`}\n                              onClick={() => updateQuantity(item.id, 1)}\n                            >\n                              <Plus className=\"size-3\" />\n                            </Button>\n                          </div>\n\n                          <div className=\"text-right\">\n                            {item.originalPrice && (\n                              <span className=\"text-muted-foreground mr-1.5 text-xs tabular-nums line-through\">\n                                {formatCurrency(item.originalPrice * item.qty)}\n                              </span>\n                            )}\n                            <span className=\"text-foreground text-sm font-semibold tabular-nums\">\n                              {formatCurrency(item.price * item.qty)}\n                            </span>\n                          </div>\n                        </div>\n                      </div>\n                    </li>\n                  ))}\n                </ul>\n\n                <Separator className=\"my-3\" />\n\n                {/* Promo Code Section */}\n                <div className=\"space-y-2\">\n                  {appliedPromo ? (\n                    <div className=\"bg-primary/5 border-primary/20 flex items-center justify-between rounded-lg border px-3 py-2 text-xs\">\n                      <div className=\"flex items-center gap-2\">\n                        <Tag className=\"text-primary size-3.5\" />\n                        <span className=\"text-foreground font-medium\">{appliedPromo}</span>\n                        <span className=\"text-success text-success font-semibold tabular-nums\">\n                          -{formatCurrency(promoDiscount)}\n                        </span>\n                      </div>\n                      <Button\n                        variant=\"ghost\"\n                        size=\"icon-sm\"\n                        className=\"text-muted-foreground hover:text-foreground size-6\"\n                        aria-label=\"Remove promo code\"\n                        onClick={handleRemovePromo}\n                      >\n                        <X className=\"size-3.5\" />\n                      </Button>\n                    </div>\n                  ) : (\n                    <div className=\"flex gap-2\">\n                      <Input\n                        value={promoCodeInput}\n                        onChange={(e) => setPromoCodeInput(e.target.value)}\n                        placeholder=\"Promo code (e.g. SUMMER20)\"\n                        size=\"small\"\n                        className=\"text-xs\"\n                        onKeyDown={(e) => {\n                          if (e.key === 'Enter') {\n                            e.preventDefault()\n                            handleApplyPromo()\n                          }\n                        }}\n                      />\n                      <Button\n                        variant=\"outline\"\n                        size=\"sm\"\n                        className=\"shrink-0 text-xs\"\n                        disabled={!promoCodeInput.trim()}\n                        onClick={handleApplyPromo}\n                      >\n                        Apply\n                      </Button>\n                    </div>\n                  )}\n                  {promoSuccess && <p className=\"text-success text-xs font-medium\">{promoSuccess}</p>}\n                  {promoError && <p className=\"text-destructive text-xs\">{promoError}</p>}\n                </div>\n              </div>\n            )}\n          </div>\n\n          {/* Drawer Footer: Summary & Actions */}\n          {cartItems.length > 0 && (\n            <div className=\"border-border/60 bg-card shrink-0 space-y-3 border-t p-5\">\n              <div className=\"space-y-1.5 text-xs\">\n                <div className=\"flex justify-between\">\n                  <span className=\"text-muted-foreground\">Subtotal</span>\n                  <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(subtotal)}</span>\n                </div>\n\n                {promoDiscount > 0 && (\n                  <div className=\"text-success flex justify-between\">\n                    <span>Coupon ({appliedPromo})</span>\n                    <span className=\"font-medium tabular-nums\">-{formatCurrency(promoDiscount)}</span>\n                  </div>\n                )}\n\n                <div className=\"flex justify-between\">\n                  <span className=\"text-muted-foreground\">Estimated Shipping</span>\n                  {shippingFee === 0 ? (\n                    <span className=\"text-success font-medium\">Free</span>\n                  ) : (\n                    <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(shippingFee)}</span>\n                  )}\n                </div>\n\n                <div className=\"flex justify-between\">\n                  <span className=\"text-muted-foreground\">Estimated Tax</span>\n                  <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(estimatedTax)}</span>\n                </div>\n\n                <Separator className=\"my-2\" />\n\n                <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 text-sm\">\n                  <span className=\"font-semibold\">Total</span>\n                  <span className=\"font-semibold tabular-nums\">{formatCurrency(total)}</span>\n                </div>\n              </div>\n\n              <div className=\"space-y-2 pt-1\">\n                <Button\n                  className=\"w-full justify-center gap-2 font-medium shadow-xs\"\n                  size=\"default\"\n                  onClick={handleCheckout}\n                >\n                  <Lock className=\"size-3.5\" />\n                  Proceed to Checkout\n                </Button>\n\n                <Button\n                  variant=\"ghost\"\n                  className=\"text-muted-foreground hover:text-foreground w-full text-xs\"\n                  size=\"sm\"\n                  onClick={onContinueShopping}\n                >\n                  Continue Shopping\n                </Button>\n              </div>\n\n              {/* Guarantee badges */}\n              <div className=\"border-border/40 text-muted-foreground grid grid-cols-1 gap-2 border-t pt-3 text-center text-xs sm:grid-cols-3\">\n                <div className=\"flex flex-col items-center gap-1\">\n                  <RotateCcw className=\"size-3.5\" />\n                  <span>30-day returns</span>\n                </div>\n                <div className=\"flex flex-col items-center gap-1\">\n                  <ShieldCheck className=\"size-3.5\" />\n                  <span>256-bit secure</span>\n                </div>\n                <div className=\"flex flex-col items-center gap-1\">\n                  <Leaf className=\"size-3.5\" />\n                  <span>Carbon neutral</span>\n                </div>\n              </div>\n            </div>\n          )}\n        </div>\n      ) : (\n        /* FULL PAGE VARIANT */\n        <div className=\"mx-auto w-full max-w-6xl space-y-6\">\n          {/* Page Header */}\n          <div className=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n            <div>\n              <h1 className=\"text-2xl font-bold tracking-tight\">Shopping Cart</h1>\n              <p className=\"text-muted-foreground mt-0.5 text-xs\">\n                Review your selected items and calculate shipping before checkout.\n              </p>\n            </div>\n            {totalItemsCount > 0 && (\n              <Badge variant=\"outline\" className=\"w-fit text-xs tabular-nums\">\n                {totalItemsCount} items in cart\n              </Badge>\n            )}\n          </div>\n\n          {/* Free Shipping Banner */}\n          {cartItems.length > 0 && (\n            <div className=\"bg-card border-border/80 rounded-xl border p-4 shadow-xs\">\n              <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n                <div className=\"flex items-center gap-2 text-xs\">\n                  {isFreeShippingUnlocked ? (\n                    <>\n                      <Truck className=\"text-primary size-4\" />\n                      <span className=\"text-primary font-semibold\">\n                        You've unlocked Free Express Shipping on this order!\n                      </span>\n                    </>\n                  ) : (\n                    <span className=\"text-muted-foreground\">\n                      🎉 You're{' '}\n                      <strong className=\"text-foreground font-semibold tabular-nums\">\n                        {formatCurrency(amountAwayFromFreeShipping)}\n                      </strong>{' '}\n                      away from Free Shipping!\n                    </span>\n                  )}\n                </div>\n                <span className=\"text-muted-foreground text-xs font-medium tabular-nums\">\n                  {shippingProgress}% completed\n                </span>\n              </div>\n              <Progress value={shippingProgress} className=\"mt-2.5 h-2\" />\n            </div>\n          )}\n\n          {/* Empty State for Page */}\n          {cartItems.length === 0 ? (\n            <div className=\"bg-card border-border/80 flex flex-col items-center justify-center rounded-2xl border py-16 text-center shadow-xs\">\n              <div className=\"bg-muted text-muted-foreground mb-4 flex size-16 items-center justify-center rounded-full\">\n                <ShoppingBag className=\"size-8 stroke-[1.5]\" />\n              </div>\n              <h2 className=\"text-lg font-semibold\">Your cart is currently empty</h2>\n              <p className=\"text-muted-foreground mt-1 max-w-sm text-sm\">\n                Before you proceed to checkout you must add some products to your shopping cart.\n              </p>\n              <Button className=\"mt-6 gap-2\" size=\"default\" onClick={resetCart}>\n                <ShoppingBag className=\"size-4\" />\n                Explore Products\n              </Button>\n            </div>\n          ) : (\n            /* Page Grid: Items (Left) & Order Summary (Right) */\n            <div className=\"grid grid-cols-1 items-start gap-8 lg:grid-cols-12\">\n              {/* Left: Line Items list */}\n              <div className=\"space-y-4 lg:col-span-8\">\n                <div className=\"bg-card border-border/80 divide-border/60 divide-y rounded-2xl border shadow-xs\">\n                  {cartItems.map((item) => (\n                    <div\n                      key={item.id}\n                      className=\"flex flex-col gap-4 p-5 sm:flex-row sm:items-center sm:justify-between\"\n                    >\n                      <div className=\"flex items-center gap-4\">\n                        <div className=\"border-border/60 bg-muted/40 relative size-20 shrink-0 overflow-hidden rounded-lg border shadow-xs\">\n                          <img src={item.image} alt={item.name} className=\"size-full object-cover\" />\n                        </div>\n                        <div>\n                          <h3 className=\"text-foreground text-sm font-semibold\">{item.name}</h3>\n                          <p className=\"text-muted-foreground mt-0.5 text-xs\">{item.variant}</p>\n                          <div className=\"mt-1.5 flex items-center gap-2\">\n                            <span className=\"bg-success size-1.5 rounded-full\" />\n                            <span className=\"text-success text-xs font-medium\">In stock</span>\n                            <span className=\"text-muted-foreground text-xs font-normal tabular-nums\">\n                              · {formatCurrency(item.price)} each\n                            </span>\n                          </div>\n                        </div>\n                      </div>\n\n                      <div className=\"flex items-center justify-between gap-6 sm:justify-end\">\n                        <div className=\"border-border/80 bg-background flex items-center rounded-md border shadow-xs\">\n                          <Button\n                            variant=\"ghost\"\n                            size=\"icon-sm\"\n                            className=\"size-8 rounded-none rounded-l-md\"\n                            aria-label={`Decrease quantity for ${item.name}`}\n                            onClick={() => updateQuantity(item.id, -1)}\n                          >\n                            <Minus className=\"size-3.5\" />\n                          </Button>\n                          <span className=\"w-8 text-center text-xs font-medium tabular-nums\">{item.qty}</span>\n                          <Button\n                            variant=\"ghost\"\n                            size=\"icon-sm\"\n                            className=\"size-8 rounded-none rounded-r-md\"\n                            aria-label={`Increase quantity for ${item.name}`}\n                            onClick={() => updateQuantity(item.id, 1)}\n                          >\n                            <Plus className=\"size-3.5\" />\n                          </Button>\n                        </div>\n\n                        <div className=\"w-24 text-right\">\n                          {item.originalPrice && (\n                            <span className=\"text-muted-foreground block text-xs tabular-nums line-through\">\n                              {formatCurrency(item.originalPrice * item.qty)}\n                            </span>\n                          )}\n                          <span className=\"text-foreground text-base font-semibold tabular-nums\">\n                            {formatCurrency(item.price * item.qty)}\n                          </span>\n                        </div>\n\n                        <Button\n                          variant=\"ghost\"\n                          size=\"icon-sm\"\n                          className=\"text-muted-foreground hover:text-destructive size-8\"\n                          aria-label={`Remove ${item.name} from cart`}\n                          onClick={() => removeItem(item.id)}\n                        >\n                          <Trash2 className=\"size-4\" />\n                        </Button>\n                      </div>\n                    </div>\n                  ))}\n                </div>\n\n                {/* Bottom bar: Guarantees */}\n                <div className=\"bg-card border-border/80 grid grid-cols-1 gap-4 rounded-xl border p-4 shadow-xs sm:grid-cols-3\">\n                  <div className=\"flex items-center gap-3 text-xs\">\n                    <div className=\"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-md\">\n                      <RotateCcw className=\"size-4\" />\n                    </div>\n                    <div>\n                      <p className=\"font-medium\">Free 30-Day Returns</p>\n                      <p className=\"text-muted-foreground\">Hassle-free return policy</p>\n                    </div>\n                  </div>\n                  <div className=\"flex items-center gap-3 text-xs\">\n                    <div className=\"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-md\">\n                      <ShieldCheck className=\"size-4\" />\n                    </div>\n                    <div>\n                      <p className=\"font-medium\">256-Bit SSL Security</p>\n                      <p className=\"text-muted-foreground\">Bank-grade data encryption</p>\n                    </div>\n                  </div>\n                  <div className=\"flex items-center gap-3 text-xs\">\n                    <div className=\"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-md\">\n                      <Leaf className=\"size-4\" />\n                    </div>\n                    <div>\n                      <p className=\"font-medium\">Carbon Neutral</p>\n                      <p className=\"text-muted-foreground\">Offset delivery emissions</p>\n                    </div>\n                  </div>\n                </div>\n              </div>\n\n              {/* Right: Sticky Order Summary Card */}\n              <div className=\"space-y-4 lg:sticky lg:top-6 lg:col-span-4\">\n                <div className=\"bg-card border-border/80 space-y-4 rounded-2xl border p-5 shadow-xs\">\n                  <h2 className=\"text-base font-semibold\">Order Summary</h2>\n\n                  {/* Promo Input */}\n                  <div className=\"space-y-2\">\n                    <label className=\"text-muted-foreground text-xs font-medium\">Have a coupon code?</label>\n                    {appliedPromo ? (\n                      <div className=\"bg-primary/5 border-primary/20 flex items-center justify-between rounded-lg border px-3 py-2 text-xs\">\n                        <div className=\"flex items-center gap-2\">\n                          <Tag className=\"text-primary size-3.5\" />\n                          <span className=\"text-foreground font-medium\">{appliedPromo}</span>\n                          <span className=\"text-success text-success font-semibold tabular-nums\">\n                            -{formatCurrency(promoDiscount)}\n                          </span>\n                        </div>\n                        <Button\n                          variant=\"ghost\"\n                          size=\"icon-sm\"\n                          className=\"text-muted-foreground hover:text-foreground size-6\"\n                          aria-label=\"Remove coupon\"\n                          onClick={handleRemovePromo}\n                        >\n                          <X className=\"size-3.5\" />\n                        </Button>\n                      </div>\n                    ) : (\n                      <div className=\"flex gap-2\">\n                        <Input\n                          value={promoCodeInput}\n                          onChange={(e) => setPromoCodeInput(e.target.value)}\n                          placeholder=\"Enter code (SUMMER20)\"\n                          size=\"small\"\n                          className=\"text-xs\"\n                          onKeyDown={(e) => {\n                            if (e.key === 'Enter') {\n                              e.preventDefault()\n                              handleApplyPromo()\n                            }\n                          }}\n                        />\n                        <Button\n                          variant=\"outline\"\n                          size=\"sm\"\n                          className=\"shrink-0 text-xs\"\n                          disabled={!promoCodeInput.trim()}\n                          onClick={handleApplyPromo}\n                        >\n                          Apply\n                        </Button>\n                      </div>\n                    )}\n                  </div>\n\n                  <Separator />\n\n                  {/* Cost Breakdown */}\n                  <div className=\"space-y-2 text-xs\">\n                    <div className=\"flex justify-between\">\n                      <span className=\"text-muted-foreground\">Subtotal</span>\n                      <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(subtotal)}</span>\n                    </div>\n\n                    {promoDiscount > 0 && (\n                      <div className=\"text-success flex justify-between\">\n                        <span>Coupon ({appliedPromo})</span>\n                        <span className=\"font-medium tabular-nums\">-{formatCurrency(promoDiscount)}</span>\n                      </div>\n                    )}\n\n                    <div className=\"flex justify-between\">\n                      <span className=\"text-muted-foreground\">Estimated Shipping</span>\n                      {shippingFee === 0 ? (\n                        <span className=\"text-success font-medium\">Free</span>\n                      ) : (\n                        <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(shippingFee)}</span>\n                      )}\n                    </div>\n\n                    <div className=\"flex justify-between\">\n                      <span className=\"text-muted-foreground\">Estimated Tax (8%)</span>\n                      <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(estimatedTax)}</span>\n                    </div>\n\n                    <Separator className=\"my-2\" />\n\n                    <div className=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 text-base font-semibold\">\n                      <span>Total</span>\n                      <span className=\"tabular-nums\">{formatCurrency(total)}</span>\n                    </div>\n                  </div>\n\n                  <Button\n                    className=\"w-full justify-center gap-2 font-medium shadow-xs\"\n                    size=\"lg\"\n                    onClick={handleCheckout}\n                  >\n                    <Lock className=\"size-4\" />\n                    Proceed to Checkout\n                  </Button>\n\n                  <Button\n                    variant=\"ghost\"\n                    className=\"text-muted-foreground hover:text-foreground w-full text-xs\"\n                    size=\"sm\"\n                    onClick={onContinueShopping}\n                  >\n                    Continue Shopping\n                  </Button>\n                </div>\n              </div>\n            </div>\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/CartDrawer.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/input.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Shopping cart drawer & full cart page view featuring free shipping progress meter, interactive line items with quantity steppers and variant tags, promo code application, order summary with tax & shipping calculation, trust badges, and empty state.",
  "categories": [
    "commerce",
    "ecommerce"
  ]
}