{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "cart-drawer",
  "title": "Cart Drawer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-svelte/blocks/cart-drawer/CartDrawer.svelte",
      "content": "<script lang=\"ts\" module>\n  export 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\n  export const 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\n  export interface CartDrawerProps {\n    variant?: 'drawer' | 'page'\n    items?: CartItem[]\n    currency?: string\n    freeShippingThreshold?: number\n    taxRate?: number\n    initialPromoCode?: string\n    class?: 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</script>\n\n<script lang=\"ts\">\n  import { Leaf, Lock, Minus, Plus, RotateCcw, ShieldCheck, ShoppingBag, Tag, Trash2, Truck, X } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Input } from '$lib/components/ui/input'\n  import { Progress } from '$lib/components/ui/progress'\n  import { Separator } from '$lib/components/ui/separator'\n\n  let {\n    variant = 'drawer',\n    items = DEFAULT_ITEMS,\n    currency = 'USD',\n    freeShippingThreshold = 300,\n    taxRate = 0.08,\n    initialPromoCode = '',\n    class: className,\n    onCheckout,\n    onContinueShopping,\n    onClose,\n    onUpdateQuantity,\n    onRemoveItem,\n    onApplyPromo,\n    onRemovePromo,\n  }: CartDrawerProps = $props()\n\n  let cartItems = $state<CartItem[]>(items.map((item) => ({ ...item })))\n  let promoCodeInput = $state('')\n  let appliedPromo = $state(initialPromoCode)\n  let promoDiscount = $state(initialPromoCode ? 20 : 0)\n  let promoError = $state('')\n  let promoSuccess = $state('')\n\n  $effect(() => {\n    cartItems = items.map((item) => ({ ...item }))\n  })\n\n  const totalItemsCount = $derived(cartItems.reduce((acc, item) => acc + item.qty, 0))\n  const subtotal = $derived(cartItems.reduce((acc, item) => acc + item.price * item.qty, 0))\n  const isFreeShippingUnlocked = $derived(subtotal >= freeShippingThreshold && cartItems.length > 0)\n  const amountAwayFromFreeShipping = $derived(Math.max(0, freeShippingThreshold - subtotal))\n  const shippingProgress = $derived(\n    cartItems.length === 0 ? 0 : Math.min(100, Math.round((subtotal / freeShippingThreshold) * 100)),\n  )\n  const shippingFee = $derived(cartItems.length === 0 ? 0 : isFreeShippingUnlocked ? 0 : 15)\n  const discountedSubtotal = $derived(Math.max(0, subtotal - promoDiscount))\n  const estimatedTax = $derived(cartItems.length === 0 ? 0 : Number((discountedSubtotal * taxRate).toFixed(2)))\n  const total = $derived(\n    cartItems.length === 0 ? 0 : Number((discountedSubtotal + shippingFee + estimatedTax).toFixed(2)),\n  )\n\n  function formatCurrency(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\n  function updateQuantity(id: string, delta: number) {\n    const item = cartItems.find((i) => i.id === id)\n    if (!item) return\n    const newQty = item.qty + delta\n    if (newQty <= 0) {\n      removeItem(id)\n    } else {\n      item.qty = newQty\n      onUpdateQuantity?.(id, newQty)\n    }\n  }\n\n  function removeItem(id: string) {\n    cartItems = cartItems.filter((i) => i.id !== id)\n    onRemoveItem?.(id)\n  }\n\n  function handleApplyPromo() {\n    promoError = ''\n    promoSuccess = ''\n    const trimmed = promoCodeInput.trim().toUpperCase()\n    if (!trimmed) return\n\n    if (trimmed === 'SUMMER20' || trimmed === 'SAVE20') {\n      appliedPromo = trimmed\n      promoDiscount = 20\n      promoSuccess = '$20.00 coupon discount applied!'\n      promoCodeInput = ''\n      onApplyPromo?.(trimmed)\n    } else if (trimmed === 'SAVE10') {\n      appliedPromo = trimmed\n      promoDiscount = 10\n      promoSuccess = '$10.00 coupon discount applied!'\n      promoCodeInput = ''\n      onApplyPromo?.(trimmed)\n    } else {\n      appliedPromo = trimmed\n      promoDiscount = 15\n      promoSuccess = 'Promo code applied!'\n      promoCodeInput = ''\n      onApplyPromo?.(trimmed)\n    }\n  }\n\n  function handleRemovePromo() {\n    appliedPromo = ''\n    promoDiscount = 0\n    promoSuccess = ''\n    promoError = ''\n    onRemovePromo?.()\n  }\n\n  function resetCart() {\n    cartItems = DEFAULT_ITEMS.map((item) => ({ ...item }))\n  }\n</script>\n\n<div data-slot=\"cart-drawer\" class={cn('w-full', className)}>\n  {#if variant === 'drawer'}\n    <div\n      class=\"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    >\n      <!-- Drawer Header -->\n      <div class=\"border-border/60 flex shrink-0 items-center justify-between border-b px-5 py-4\">\n        <div class=\"flex items-center gap-2\">\n          <h2 class=\"text-base font-semibold tracking-tight\">Shopping Cart</h2>\n          {#if totalItemsCount > 0}\n            <Badge variant=\"secondary\" class=\"tabular-nums\">\n              {totalItemsCount}\n            </Badge>\n          {/if}\n        </div>\n        <Button variant=\"ghost\" size=\"icon-sm\" aria-label=\"Close cart drawer\" onclick={() => onClose?.()}>\n          <X class=\"size-4\" />\n        </Button>\n      </div>\n\n      <!-- Free Shipping Meter -->\n      {#if cartItems.length > 0}\n        <div class=\"bg-muted/30 border-border/40 shrink-0 border-b px-5 py-3.5\">\n          <div class=\"flex items-center justify-between gap-2 text-xs\">\n            {#if isFreeShippingUnlocked}\n              <span class=\"text-primary flex items-center gap-1.5 font-medium\">\n                <Truck class=\"size-3.5\" />\n                You've unlocked Free Express Shipping!\n              </span>\n            {:else}\n              <span class=\"text-muted-foreground\">\n                🎉 You're\n                <strong class=\"text-foreground font-semibold tabular-nums\">\n                  {formatCurrency(amountAwayFromFreeShipping)}\n                </strong>\n                away from Free Shipping!\n              </span>\n            {/if}\n            <span class=\"text-muted-foreground font-medium tabular-nums\">{shippingProgress}%</span>\n          </div>\n          <Progress value={shippingProgress} class=\"mt-2 h-1.5\" />\n        </div>\n      {/if}\n\n      <!-- Drawer Body: Line Items or Empty State -->\n      <div class=\"flex-1 overflow-y-auto p-5\">\n        {#if cartItems.length === 0}\n          <div class=\"flex h-full flex-col items-center justify-center py-12 text-center\">\n            <div class=\"bg-muted text-muted-foreground mb-4 flex size-14 items-center justify-center rounded-full\">\n              <ShoppingBag class=\"size-7 stroke-[1.5]\" />\n            </div>\n            <h3 class=\"text-base font-semibold\">Your cart is empty</h3>\n            <p class=\"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 class=\"mt-5 gap-2\" size=\"sm\" onclick={resetCart}>\n              <ShoppingBag class=\"size-3.5\" />\n              Explore Products\n            </Button>\n          </div>\n        {:else}\n          <div class=\"space-y-4\">\n            <ul class=\"divide-border/60 divide-y\" role=\"list\">\n              {#each cartItems as item (item.id)}\n                <li class=\"flex gap-3.5 py-4 first:pt-0 last:pb-0\">\n                  <div\n                    class=\"border-border/60 bg-muted/40 relative size-20 shrink-0 overflow-hidden rounded-lg border shadow-xs\"\n                  >\n                    <img src={item.image} alt={item.name} class=\"size-full object-cover\" />\n                  </div>\n\n                  <div class=\"flex min-w-0 flex-1 flex-col justify-between\">\n                    <div>\n                      <div class=\"flex items-start justify-between gap-2\">\n                        <h3 class=\"text-foreground truncate text-sm leading-snug font-medium\">\n                          {item.name}\n                        </h3>\n                        <Button\n                          variant=\"ghost\"\n                          size=\"icon-sm\"\n                          class=\"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 class=\"size-3.5\" />\n                        </Button>\n                      </div>\n                      <p class=\"text-muted-foreground mt-0.5 text-xs\">\n                        {item.variant}\n                      </p>\n                      <div class=\"mt-1 flex items-center gap-1.5\">\n                        <span class=\"bg-success size-1.5 rounded-full\"></span>\n                        <span class=\"text-success text-xs font-medium\">In stock</span>\n                      </div>\n                    </div>\n\n                    <div class=\"mt-2.5 flex items-center justify-between\">\n                      <div class=\"border-border/80 bg-background flex items-center rounded-md border shadow-xs\">\n                        <Button\n                          variant=\"ghost\"\n                          size=\"icon-sm\"\n                          class=\"size-7 rounded-none rounded-l-md\"\n                          aria-label=\"Decrease quantity for {item.name}\"\n                          onclick={() => updateQuantity(item.id, -1)}\n                        >\n                          <Minus class=\"size-3\" />\n                        </Button>\n                        <span class=\"w-7 text-center text-xs font-medium tabular-nums\">{item.qty}</span>\n                        <Button\n                          variant=\"ghost\"\n                          size=\"icon-sm\"\n                          class=\"size-7 rounded-none rounded-r-md\"\n                          aria-label=\"Increase quantity for {item.name}\"\n                          onclick={() => updateQuantity(item.id, 1)}\n                        >\n                          <Plus class=\"size-3\" />\n                        </Button>\n                      </div>\n\n                      <div class=\"text-right\">\n                        {#if item.originalPrice}\n                          <span class=\"text-muted-foreground mr-1.5 text-xs tabular-nums line-through\">\n                            {formatCurrency(item.originalPrice * item.qty)}\n                          </span>\n                        {/if}\n                        <span class=\"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              {/each}\n            </ul>\n\n            <Separator class=\"my-3\" />\n\n            <!-- Promo Code Section -->\n            <div class=\"space-y-2\">\n              {#if appliedPromo}\n                <div\n                  class=\"bg-primary/5 border-primary/20 flex items-center justify-between rounded-lg border px-3 py-2 text-xs\"\n                >\n                  <div class=\"flex items-center gap-2\">\n                    <Tag class=\"text-primary size-3.5\" />\n                    <span class=\"text-foreground font-medium\">{appliedPromo}</span>\n                    <span class=\"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                    class=\"text-muted-foreground hover:text-foreground size-6\"\n                    aria-label=\"Remove promo code\"\n                    onclick={handleRemovePromo}\n                  >\n                    <X class=\"size-3.5\" />\n                  </Button>\n                </div>\n              {:else}\n                <div class=\"flex gap-2\">\n                  <Input\n                    bind:value={promoCodeInput}\n                    placeholder=\"Promo code (e.g. SUMMER20)\"\n                    size=\"small\"\n                    class=\"text-xs\"\n                    onkeydown={(e) => e.key === 'Enter' && (e.preventDefault(), handleApplyPromo())}\n                  />\n                  <Button\n                    variant=\"outline\"\n                    size=\"sm\"\n                    class=\"shrink-0 text-xs\"\n                    disabled={!promoCodeInput.trim()}\n                    onclick={handleApplyPromo}\n                  >\n                    Apply\n                  </Button>\n                </div>\n              {/if}\n              {#if promoSuccess}\n                <p class=\"text-success text-xs font-medium\">\n                  {promoSuccess}\n                </p>\n              {/if}\n              {#if promoError}\n                <p class=\"text-destructive text-xs\">\n                  {promoError}\n                </p>\n              {/if}\n            </div>\n          </div>\n        {/if}\n      </div>\n\n      <!-- Drawer Footer: Summary & Actions -->\n      {#if cartItems.length > 0}\n        <div class=\"border-border/60 bg-card shrink-0 space-y-3 border-t p-5\">\n          <div class=\"space-y-1.5 text-xs\">\n            <div class=\"flex justify-between\">\n              <span class=\"text-muted-foreground\">Subtotal</span>\n              <span class=\"text-foreground font-medium tabular-nums\">{formatCurrency(subtotal)}</span>\n            </div>\n\n            {#if promoDiscount > 0}\n              <div class=\"text-success flex justify-between\">\n                <span>Coupon ({appliedPromo})</span>\n                <span class=\"font-medium tabular-nums\">-{formatCurrency(promoDiscount)}</span>\n              </div>\n            {/if}\n\n            <div class=\"flex justify-between\">\n              <span class=\"text-muted-foreground\">Estimated Shipping</span>\n              {#if shippingFee === 0}\n                <span class=\"text-success font-medium\">Free</span>\n              {:else}\n                <span class=\"text-foreground font-medium tabular-nums\">{formatCurrency(shippingFee)}</span>\n              {/if}\n            </div>\n\n            <div class=\"flex justify-between\">\n              <span class=\"text-muted-foreground\">Estimated Tax</span>\n              <span class=\"text-foreground font-medium tabular-nums\">{formatCurrency(estimatedTax)}</span>\n            </div>\n\n            <Separator class=\"my-2\" />\n\n            <div class=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 text-sm\">\n              <span class=\"font-semibold\">Total</span>\n              <span class=\"font-semibold tabular-nums\">{formatCurrency(total)}</span>\n            </div>\n          </div>\n\n          <div class=\"space-y-2 pt-1\">\n            <Button\n              class=\"w-full justify-center gap-2 font-medium shadow-xs\"\n              size=\"default\"\n              onclick={() => onCheckout?.(cartItems, total)}\n            >\n              <Lock class=\"size-3.5\" />\n              Proceed to Checkout\n            </Button>\n\n            <Button\n              variant=\"ghost\"\n              class=\"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\n            class=\"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          >\n            <div class=\"flex flex-col items-center gap-1\">\n              <RotateCcw class=\"size-3.5\" />\n              <span>30-day returns</span>\n            </div>\n            <div class=\"flex flex-col items-center gap-1\">\n              <ShieldCheck class=\"size-3.5\" />\n              <span>256-bit secure</span>\n            </div>\n            <div class=\"flex flex-col items-center gap-1\">\n              <Leaf class=\"size-3.5\" />\n              <span>Carbon neutral</span>\n            </div>\n          </div>\n        </div>\n      {/if}\n    </div>\n  {:else}\n    <!-- FULL PAGE VARIANT -->\n    <div class=\"mx-auto w-full max-w-6xl space-y-6\">\n      <!-- Page Header -->\n      <div class=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <h1 class=\"text-2xl font-bold tracking-tight\">Shopping Cart</h1>\n          <p class=\"text-muted-foreground mt-0.5 text-xs\">\n            Review your selected items and calculate shipping before checkout.\n          </p>\n        </div>\n        {#if totalItemsCount > 0}\n          <Badge variant=\"outline\" class=\"w-fit text-xs tabular-nums\">\n            {totalItemsCount} items in cart\n          </Badge>\n        {/if}\n      </div>\n\n      <!-- Free Shipping Banner -->\n      {#if cartItems.length > 0}\n        <div class=\"bg-card border-border/80 rounded-xl border p-4 shadow-xs\">\n          <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n            <div class=\"flex items-center gap-2 text-xs\">\n              {#if isFreeShippingUnlocked}\n                <Truck class=\"text-primary size-4\" />\n              {/if}\n              {#if isFreeShippingUnlocked}\n                <span class=\"text-primary font-semibold\"> You've unlocked Free Express Shipping on this order! </span>\n              {:else}\n                <span class=\"text-muted-foreground\">\n                  🎉 You're\n                  <strong class=\"text-foreground font-semibold tabular-nums\">\n                    {formatCurrency(amountAwayFromFreeShipping)}\n                  </strong>\n                  away from Free Shipping!\n                </span>\n              {/if}\n            </div>\n            <span class=\"text-muted-foreground text-xs font-medium tabular-nums\">{shippingProgress}% completed</span>\n          </div>\n          <Progress value={shippingProgress} class=\"mt-2.5 h-2\" />\n        </div>\n      {/if}\n\n      <!-- Empty State for Page -->\n      {#if cartItems.length === 0}\n        <div\n          class=\"bg-card border-border/80 flex flex-col items-center justify-center rounded-2xl border py-16 text-center shadow-xs\"\n        >\n          <div class=\"bg-muted text-muted-foreground mb-4 flex size-16 items-center justify-center rounded-full\">\n            <ShoppingBag class=\"size-8 stroke-[1.5]\" />\n          </div>\n          <h2 class=\"text-lg font-semibold\">Your cart is currently empty</h2>\n          <p class=\"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 class=\"mt-6 gap-2\" size=\"default\" onclick={resetCart}>\n            <ShoppingBag class=\"size-4\" />\n            Explore Products\n          </Button>\n        </div>\n      {:else}\n        <!-- Page Grid: Items (Left) & Order Summary (Right) -->\n        <div class=\"grid grid-cols-1 items-start gap-8 lg:grid-cols-12\">\n          <!-- Left: Line Items list -->\n          <div class=\"space-y-4 lg:col-span-8\">\n            <div class=\"bg-card border-border/80 divide-border/60 divide-y rounded-2xl border shadow-xs\">\n              {#each cartItems as item (item.id)}\n                <div class=\"flex flex-col gap-4 p-5 sm:flex-row sm:items-center sm:justify-between\">\n                  <div class=\"flex items-center gap-4\">\n                    <div\n                      class=\"border-border/60 bg-muted/40 relative size-20 shrink-0 overflow-hidden rounded-lg border shadow-xs\"\n                    >\n                      <img src={item.image} alt={item.name} class=\"size-full object-cover\" />\n                    </div>\n                    <div>\n                      <h3 class=\"text-foreground text-sm font-semibold\">\n                        {item.name}\n                      </h3>\n                      <p class=\"text-muted-foreground mt-0.5 text-xs\">\n                        {item.variant}\n                      </p>\n                      <div class=\"mt-1.5 flex items-center gap-2\">\n                        <span class=\"bg-success size-1.5 rounded-full\"></span>\n                        <span class=\"text-success text-xs font-medium\">In stock</span>\n                        <span class=\"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 class=\"flex items-center justify-between gap-6 sm:justify-end\">\n                    <div class=\"border-border/80 bg-background flex items-center rounded-md border shadow-xs\">\n                      <Button\n                        variant=\"ghost\"\n                        size=\"icon-sm\"\n                        class=\"size-8 rounded-none rounded-l-md\"\n                        aria-label=\"Decrease quantity for {item.name}\"\n                        onclick={() => updateQuantity(item.id, -1)}\n                      >\n                        <Minus class=\"size-3.5\" />\n                      </Button>\n                      <span class=\"w-8 text-center text-xs font-medium tabular-nums\">{item.qty}</span>\n                      <Button\n                        variant=\"ghost\"\n                        size=\"icon-sm\"\n                        class=\"size-8 rounded-none rounded-r-md\"\n                        aria-label=\"Increase quantity for {item.name}\"\n                        onclick={() => updateQuantity(item.id, 1)}\n                      >\n                        <Plus class=\"size-3.5\" />\n                      </Button>\n                    </div>\n\n                    <div class=\"w-24 text-right\">\n                      {#if item.originalPrice}\n                        <span class=\"text-muted-foreground block text-xs tabular-nums line-through\">\n                          {formatCurrency(item.originalPrice * item.qty)}\n                        </span>\n                      {/if}\n                      <span class=\"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                      class=\"text-muted-foreground hover:text-destructive size-8\"\n                      aria-label=\"Remove {item.name} from cart\"\n                      onclick={() => removeItem(item.id)}\n                    >\n                      <Trash2 class=\"size-4\" />\n                    </Button>\n                  </div>\n                </div>\n              {/each}\n            </div>\n\n            <!-- Bottom bar: Guarantees -->\n            <div class=\"bg-card border-border/80 grid grid-cols-1 gap-4 rounded-xl border p-4 shadow-xs sm:grid-cols-3\">\n              <div class=\"flex items-center gap-3 text-xs\">\n                <div class=\"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-md\">\n                  <RotateCcw class=\"size-4\" />\n                </div>\n                <div>\n                  <p class=\"font-medium\">Free 30-Day Returns</p>\n                  <p class=\"text-muted-foreground\">Hassle-free return policy</p>\n                </div>\n              </div>\n              <div class=\"flex items-center gap-3 text-xs\">\n                <div class=\"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-md\">\n                  <ShieldCheck class=\"size-4\" />\n                </div>\n                <div>\n                  <p class=\"font-medium\">256-Bit SSL Security</p>\n                  <p class=\"text-muted-foreground\">Bank-grade data encryption</p>\n                </div>\n              </div>\n              <div class=\"flex items-center gap-3 text-xs\">\n                <div class=\"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-md\">\n                  <Leaf class=\"size-4\" />\n                </div>\n                <div>\n                  <p class=\"font-medium\">Carbon Neutral</p>\n                  <p class=\"text-muted-foreground\">Offset delivery emissions</p>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <!-- Right: Sticky Order Summary Card -->\n          <div class=\"space-y-4 lg:sticky lg:top-6 lg:col-span-4\">\n            <div class=\"bg-card border-border/80 space-y-4 rounded-2xl border p-5 shadow-xs\">\n              <h2 class=\"text-base font-semibold\">Order Summary</h2>\n\n              <!-- Promo Input -->\n              <div class=\"space-y-2\">\n                <span class=\"text-muted-foreground text-xs font-medium\">Have a coupon code?</span>\n                {#if appliedPromo}\n                  <div\n                    class=\"bg-primary/5 border-primary/20 flex items-center justify-between rounded-lg border px-3 py-2 text-xs\"\n                  >\n                    <div class=\"flex items-center gap-2\">\n                      <Tag class=\"text-primary size-3.5\" />\n                      <span class=\"text-foreground font-medium\">{appliedPromo}</span>\n                      <span class=\"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                      class=\"text-muted-foreground hover:text-foreground size-6\"\n                      aria-label=\"Remove coupon\"\n                      onclick={handleRemovePromo}\n                    >\n                      <X class=\"size-3.5\" />\n                    </Button>\n                  </div>\n                {:else}\n                  <div class=\"flex gap-2\">\n                    <Input\n                      bind:value={promoCodeInput}\n                      placeholder=\"Enter code (SUMMER20)\"\n                      size=\"small\"\n                      class=\"text-xs\"\n                      onkeydown={(e) => e.key === 'Enter' && (e.preventDefault(), handleApplyPromo())}\n                    />\n                    <Button\n                      variant=\"outline\"\n                      size=\"sm\"\n                      class=\"shrink-0 text-xs\"\n                      disabled={!promoCodeInput.trim()}\n                      onclick={handleApplyPromo}\n                    >\n                      Apply\n                    </Button>\n                  </div>\n                {/if}\n              </div>\n\n              <Separator />\n\n              <!-- Cost Breakdown -->\n              <div class=\"space-y-2 text-xs\">\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Subtotal</span>\n                  <span class=\"text-foreground font-medium tabular-nums\">{formatCurrency(subtotal)}</span>\n                </div>\n\n                {#if promoDiscount > 0}\n                  <div class=\"text-success flex justify-between\">\n                    <span>Coupon ({appliedPromo})</span>\n                    <span class=\"font-medium tabular-nums\">-{formatCurrency(promoDiscount)}</span>\n                  </div>\n                {/if}\n\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Estimated Shipping</span>\n                  {#if shippingFee === 0}\n                    <span class=\"text-success font-medium\">Free</span>\n                  {:else}\n                    <span class=\"text-foreground font-medium tabular-nums\">{formatCurrency(shippingFee)}</span>\n                  {/if}\n                </div>\n\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Estimated Tax (8%)</span>\n                  <span class=\"text-foreground font-medium tabular-nums\">{formatCurrency(estimatedTax)}</span>\n                </div>\n\n                <Separator class=\"my-2\" />\n\n                <div class=\"flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 text-base font-semibold\">\n                  <span>Total</span>\n                  <span class=\"tabular-nums\">{formatCurrency(total)}</span>\n                </div>\n              </div>\n\n              <Button\n                class=\"w-full justify-center gap-2 font-medium shadow-xs\"\n                size=\"lg\"\n                onclick={() => onCheckout?.(cartItems, total)}\n              >\n                <Lock class=\"size-4\" />\n                Proceed to Checkout\n              </Button>\n\n              <Button\n                variant=\"ghost\"\n                class=\"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      {/if}\n    </div>\n  {/if}\n</div>\n",
      "type": "registry:block",
      "target": "~/src/lib/components/blocks/cart-drawer/CartDrawer.svelte"
    }
  ],
  "dependencies": [
    "@lucide/svelte"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/badge.json",
    "https://uipkge.dev/r/svelte/button.json",
    "https://uipkge.dev/r/svelte/input.json",
    "https://uipkge.dev/r/svelte/progress.json",
    "https://uipkge.dev/r/svelte/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"
  ]
}