{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "returns-portal",
  "title": "Returns Portal",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/returns-portal/ReturnsPortal.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport {\n  Check,\n  CheckCircle2,\n  ChevronLeft,\n  ChevronRight,\n  CreditCard,\n  Download,\n  Printer,\n  RefreshCw,\n  ShieldCheck,\n  Gift,\n  Shirt,\n  Truck,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { Input } from '@/components/ui/input'\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Stepper } from '@/components/ui/stepper'\n\nexport interface OrderItem {\n  id: string\n  name: string\n  variant: string\n  sku: string\n  price: number\n  maxQty: number\n}\n\nconst props = withDefaults(\n  defineProps<{\n    initialStep?: number\n    initialOrderNumber?: string\n    initialEmail?: string\n    class?: HTMLAttributes['class']\n  }>(),\n  {\n    initialStep: 1,\n    initialOrderNumber: '#ORD-84920',\n    initialEmail: 'sarah.connor@example.com',\n  },\n)\n\nconst steps = [\n  { id: 1, title: 'Find Order' },\n  { id: 2, title: 'Select Items' },\n  { id: 3, title: 'Choose Resolution' },\n  { id: 4, title: 'Confirm & Print' },\n]\n\nconst orderItems: OrderItem[] = [\n  {\n    id: 'item-1',\n    name: 'Merino Wool Crewneck Sweater',\n    variant: 'Midnight Navy / Size L',\n    sku: 'MWC-NAV-L',\n    price: 120,\n    maxQty: 1,\n  },\n  {\n    id: 'item-2',\n    name: 'Classic Canvas High-Tops',\n    variant: 'Off-White / US 10.5',\n    sku: 'CCHT-OW-105',\n    price: 85,\n    maxQty: 1,\n  },\n  {\n    id: 'item-3',\n    name: 'Tailored Chino Trousers',\n    variant: 'Olive / 32x32',\n    sku: 'TCT-OLV-32',\n    price: 95,\n    maxQty: 2,\n  },\n]\n\nconst returnReasonsList = ['Wrong size', 'Item defective', 'Not as described', 'Changed mind', 'Arrived late']\n\nconst exchangeSizesList = ['Small (S)', 'Medium (M)', 'Large (L)', 'Extra Large (XL)']\n\nconst step = ref(props.initialStep)\nconst orderNumber = ref(props.initialOrderNumber)\nconst email = ref(props.initialEmail)\n\nconst selectedItems = ref<Record<string, boolean>>({\n  'item-1': true,\n  'item-2': false,\n  'item-3': false,\n})\n\nconst returnQuantities = ref<Record<string, number>>({\n  'item-1': 1,\n  'item-2': 1,\n  'item-3': 1,\n})\n\nconst returnReasons = ref<Record<string, string>>({\n  'item-1': 'Wrong size',\n  'item-2': 'Changed mind',\n  'item-3': 'Item defective',\n})\n\nconst resolution = ref<'exchange' | 'store-credit' | 'original-payment'>('store-credit')\nconst exchangeSize = ref('Medium (M)')\nconst isDownloaded = ref(false)\n\nwatch(\n  () => props.initialStep,\n  (val) => {\n    step.value = val\n  },\n)\n\nconst selectedItemsCount = computed(() => {\n  return orderItems.reduce((acc, item) => {\n    if (selectedItems.value[item.id]) {\n      return acc + (returnQuantities.value[item.id] || 1)\n    }\n    return acc\n  }, 0)\n})\n\nconst itemsSubtotal = computed(() => {\n  return orderItems.reduce((acc, item) => {\n    if (selectedItems.value[item.id]) {\n      return acc + item.price * (returnQuantities.value[item.id] || 1)\n    }\n    return acc\n  }, 0)\n})\n\nconst storeCreditBonus = computed(() => {\n  return itemsSubtotal.value * 0.1\n})\n\nconst totalStoreCredit = computed(() => {\n  return itemsSubtotal.value + storeCreditBonus.value\n})\n\nfunction formatCurrency(val: number) {\n  return new Intl.NumberFormat('en-US', {\n    style: 'currency',\n    currency: 'USD',\n  }).format(val)\n}\n\nfunction onStepperInput(value: number) {\n  if (value < step.value && step.value !== 4) {\n    step.value = value\n  }\n}\n\nfunction goToNext() {\n  if (step.value < 4) {\n    step.value += 1\n  }\n}\n\nfunction goToPrevious() {\n  if (step.value > 1 && step.value < 4) {\n    step.value -= 1\n  }\n}\n\nfunction toggleItemSelection(id: string) {\n  selectedItems.value[id] = !selectedItems.value[id]\n}\n\nfunction reset() {\n  step.value = 1\n  isDownloaded.value = false\n  selectedItems.value = {\n    'item-1': true,\n    'item-2': false,\n    'item-3': false,\n  }\n  returnQuantities.value = {\n    'item-1': 1,\n    'item-2': 1,\n    'item-3': 1,\n  }\n  returnReasons.value = {\n    'item-1': 'Wrong size',\n    'item-2': 'Changed mind',\n    'item-3': 'Item defective',\n  }\n  resolution.value = 'store-credit'\n  exchangeSize.value = 'Medium (M)'\n}\n</script>\n\n<template>\n  <Card data-slot=\"returns-portal\" :class=\"cn('border-border mx-auto w-full max-w-3xl shadow-xs', props.class)\">\n    <CardHeader class=\"pb-4\">\n      <div class=\"flex items-center justify-between gap-4\">\n        <div>\n          <CardTitle class=\"text-base font-semibold\">Returns & Exchange Portal</CardTitle>\n          <CardDescription class=\"text-xs\"\n            >Self-serve return, exchange, or refund for your recent order.</CardDescription\n          >\n        </div>\n        <Badge variant=\"outline\" class=\"shrink-0 text-xs\">\n          <Truck class=\"text-muted-foreground mr-1 size-3\" />\n          Prepaid Shipping\n        </Badge>\n      </div>\n    </CardHeader>\n\n    <CardContent class=\"space-y-6\">\n      <Stepper :steps=\"steps\" :model-value=\"step\" class=\"mb-6\" @update:model-value=\"onStepperInput\" />\n\n      <!-- Step 1: Find Order -->\n      <div v-if=\"step === 1\" class=\"space-y-5\">\n        <div class=\"space-y-1\">\n          <h3 class=\"text-foreground text-sm font-semibold\">Find your order</h3>\n          <p class=\"text-muted-foreground text-xs\">\n            Enter your order number and email address to start a return or exchange.\n          </p>\n        </div>\n\n        <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n          <div class=\"space-y-1.5\">\n            <label for=\"returns-order-number\" class=\"text-foreground text-xs font-medium\">Order number</label>\n            <Input id=\"returns-order-number\" v-model=\"orderNumber\" placeholder=\"#ORD-84920\" autocomplete=\"off\" />\n            <p class=\"text-muted-foreground text-xs\">Found on your order confirmation email.</p>\n          </div>\n\n          <div class=\"space-y-1.5\">\n            <label for=\"returns-email\" class=\"text-foreground text-xs font-medium\">Email address</label>\n            <Input\n              id=\"returns-email\"\n              v-model=\"email\"\n              type=\"email\"\n              placeholder=\"sarah.connor@example.com\"\n              autocomplete=\"email\"\n            />\n            <p class=\"text-muted-foreground text-xs\">The email address used at checkout.</p>\n          </div>\n        </div>\n\n        <div class=\"border-border bg-muted/40 flex items-start gap-3 rounded-lg border p-3.5\">\n          <ShieldCheck class=\"text-primary mt-0.5 size-4 shrink-0\" />\n          <div class=\"space-y-0.5 text-xs\">\n            <p class=\"text-foreground font-medium\">30-Day Hassle-Free Return Policy</p>\n            <p class=\"text-muted-foreground\">\n              Eligible items can be returned within 30 days of delivery. Free shipping on all exchanges and store credit\n              requests.\n            </p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Step 2: Select Items -->\n      <div v-else-if=\"step === 2\" class=\"space-y-5\">\n        <div class=\"flex flex-wrap items-center justify-between gap-2\">\n          <div class=\"min-w-[12rem]\">\n            <h3 class=\"text-foreground text-sm font-semibold\">Select items to return</h3>\n            <p class=\"text-muted-foreground text-xs\">\n              Order {{ orderNumber || '#ORD-84920' }} • Placed Oct 14, 2026 • 3 items eligible\n            </p>\n          </div>\n          <Badge variant=\"secondary\" class=\"text-xs\"> {{ selectedItemsCount }} of 3 selected </Badge>\n        </div>\n\n        <div class=\"space-y-3\">\n          <div\n            v-for=\"item in orderItems\"\n            :key=\"item.id\"\n            :class=\"\n              cn(\n                'rounded-lg border p-4 transition-colors',\n                selectedItems[item.id]\n                  ? 'border-primary/50 bg-primary/[0.02] dark:bg-primary/10 shadow-xs'\n                  : 'border-border bg-card hover:bg-muted/20',\n              )\n            \"\n          >\n            <div class=\"flex items-start gap-3.5\">\n              <div class=\"pt-0.5\">\n                <Checkbox\n                  :id=\"`check-${item.id}`\"\n                  :model-value=\"selectedItems[item.id]\"\n                  @update:model-value=\"toggleItemSelection(item.id)\"\n                />\n              </div>\n\n              <div\n                class=\"border-border bg-muted/60 text-muted-foreground flex size-12 shrink-0 items-center justify-center rounded-md border\"\n              >\n                <Shirt class=\"size-6\" />\n              </div>\n\n              <div class=\"min-w-0 flex-1\">\n                <div class=\"flex items-start justify-between gap-2\">\n                  <div>\n                    <label\n                      :for=\"`check-${item.id}`\"\n                      class=\"text-foreground cursor-pointer text-sm font-medium select-none\"\n                    >\n                      {{ item.name }}\n                    </label>\n                    <p class=\"text-muted-foreground text-xs\">{{ item.variant }} • SKU: {{ item.sku }}</p>\n                  </div>\n                  <span class=\"text-foreground shrink-0 text-sm font-semibold\">\n                    {{ formatCurrency(item.price) }}\n                  </span>\n                </div>\n              </div>\n            </div>\n\n            <div\n              v-if=\"selectedItems[item.id]\"\n              class=\"border-border/60 mt-3.5 grid grid-cols-1 gap-3 border-t pt-3.5 sm:grid-cols-2\"\n            >\n              <div class=\"space-y-1.5\">\n                <label class=\"text-foreground text-xs font-medium\">Qty to return</label>\n                <Select\n                  :model-value=\"String(returnQuantities[item.id] || 1)\"\n                  @update:model-value=\"(val) => (returnQuantities[item.id] = Number(val))\"\n                >\n                  <SelectTrigger class=\"h-8 w-full text-xs\">\n                    <SelectValue placeholder=\"Qty\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem v-for=\"q in item.maxQty\" :key=\"q\" :value=\"String(q)\">\n                      {{ q }} {{ q === 1 ? 'item' : 'items' }} (of {{ item.maxQty }})\n                    </SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n\n              <div class=\"space-y-1.5\">\n                <label class=\"text-foreground text-xs font-medium\">Return reason</label>\n                <Select v-model=\"returnReasons[item.id]\">\n                  <SelectTrigger class=\"h-8 w-full text-xs\">\n                    <SelectValue placeholder=\"Select reason\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem v-for=\"reason in returnReasonsList\" :key=\"reason\" :value=\"reason\">\n                      {{ reason }}\n                    </SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"border-border bg-muted/40 flex items-center justify-between rounded-lg border p-3 text-xs\">\n          <span class=\"text-muted-foreground\">\n            <template v-if=\"selectedItemsCount > 0\">\n              <span class=\"text-foreground font-medium\">{{ selectedItemsCount }}</span> item{{\n                selectedItemsCount === 1 ? '' : 's'\n              }}\n              selected\n            </template>\n            <template v-else> No items selected yet </template>\n          </span>\n          <span class=\"text-foreground font-medium\"> Estimated Value: {{ formatCurrency(itemsSubtotal) }} </span>\n        </div>\n      </div>\n\n      <!-- Step 3: Choose Resolution -->\n      <div v-else-if=\"step === 3\" class=\"space-y-5\">\n        <div class=\"space-y-1\">\n          <h3 class=\"text-foreground text-sm font-semibold\">Choose return resolution</h3>\n          <p class=\"text-muted-foreground text-xs\">Select how you would like your return or refund handled.</p>\n        </div>\n\n        <RadioGroup v-model=\"resolution\" class=\"gap-3\">\n          <!-- Option A: Exchange -->\n          <div\n            :class=\"\n              cn(\n                'flex cursor-pointer flex-col gap-3 rounded-lg border p-4 transition-colors',\n                resolution === 'exchange'\n                  ? 'border-primary bg-primary/[0.02] dark:bg-primary/10 shadow-xs'\n                  : 'border-border hover:bg-muted/40',\n              )\n            \"\n            @click=\"resolution = 'exchange'\"\n          >\n            <div class=\"flex items-start gap-3\">\n              <RadioGroupItem id=\"res-exchange\" value=\"exchange\" class=\"mt-0.5\" />\n              <div class=\"flex-1 space-y-1\">\n                <div class=\"flex items-center gap-2\">\n                  <RefreshCw class=\"text-primary size-4\" />\n                  <label for=\"res-exchange\" class=\"text-foreground cursor-pointer text-sm font-medium\">\n                    Exchange for different size / color\n                  </label>\n                  <Badge variant=\"outline\" class=\"text-xs\">Free shipping</Badge>\n                </div>\n                <p class=\"text-muted-foreground text-xs\">\n                  Reserve replacement item immediately. Ships as soon as carrier scans the return package.\n                </p>\n              </div>\n            </div>\n\n            <div\n              v-if=\"resolution === 'exchange'\"\n              class=\"border-border/60 mt-1 space-y-1.5 border-t pt-3 pl-7\"\n              @click.stop\n            >\n              <label class=\"text-foreground text-xs font-medium\">Select replacement size</label>\n              <Select v-model=\"exchangeSize\">\n                <SelectTrigger class=\"h-8 w-full max-w-xs text-xs\">\n                  <SelectValue placeholder=\"Select replacement size\" />\n                </SelectTrigger>\n                <SelectContent>\n                  <SelectItem v-for=\"size in exchangeSizesList\" :key=\"size\" :value=\"size\">\n                    {{ size }}\n                  </SelectItem>\n                </SelectContent>\n              </Select>\n            </div>\n          </div>\n\n          <!-- Option B: Store Credit (+10% Bonus) -->\n          <div\n            :class=\"\n              cn(\n                'flex cursor-pointer flex-col gap-3 rounded-lg border p-4 transition-colors',\n                resolution === 'store-credit'\n                  ? 'border-primary bg-primary/[0.02] dark:bg-primary/10 shadow-xs'\n                  : 'border-border hover:bg-muted/40',\n              )\n            \"\n            @click=\"resolution = 'store-credit'\"\n          >\n            <div class=\"flex items-start gap-3\">\n              <RadioGroupItem id=\"res-store-credit\" value=\"store-credit\" class=\"mt-0.5\" />\n              <div class=\"flex-1 space-y-1\">\n                <div class=\"flex flex-wrap items-center gap-2\">\n                  <Gift class=\"text-success size-4\" />\n                  <label for=\"res-store-credit\" class=\"text-foreground cursor-pointer text-sm font-medium\">\n                    Store Credit (+10% Bonus value)\n                  </label>\n                  <Badge variant=\"success\" class=\"text-xs\">+10% Bonus</Badge>\n                  <Badge variant=\"secondary\" class=\"text-xs\">Fastest refund</Badge>\n                </div>\n                <p class=\"text-muted-foreground text-xs\">\n                  Get <span class=\"text-foreground font-medium\">{{ formatCurrency(totalStoreCredit) }}</span> in store\n                  credit ({{ formatCurrency(itemsSubtotal) }} + {{ formatCurrency(storeCreditBonus) }} bonus). Digital\n                  card delivered by email instantly upon drop-off scan.\n                </p>\n              </div>\n            </div>\n          </div>\n\n          <!-- Option C: Original Payment Method -->\n          <div\n            :class=\"\n              cn(\n                'flex cursor-pointer flex-col gap-3 rounded-lg border p-4 transition-colors',\n                resolution === 'original-payment'\n                  ? 'border-primary bg-primary/[0.02] dark:bg-primary/10 shadow-xs'\n                  : 'border-border hover:bg-muted/40',\n              )\n            \"\n            @click=\"resolution = 'original-payment'\"\n          >\n            <div class=\"flex items-start gap-3\">\n              <RadioGroupItem id=\"res-original\" value=\"original-payment\" class=\"mt-0.5\" />\n              <div class=\"flex-1 space-y-1\">\n                <div class=\"flex flex-wrap items-center gap-2\">\n                  <CreditCard class=\"text-muted-foreground size-4\" />\n                  <label for=\"res-original\" class=\"text-foreground cursor-pointer text-sm font-medium\">\n                    Original Payment Method\n                  </label>\n                  <Badge variant=\"outline\" class=\"text-xs\">Visa •••• 4242</Badge>\n                </div>\n                <p class=\"text-muted-foreground text-xs\">\n                  Refund of {{ formatCurrency(itemsSubtotal) }} back to your card. Processed in 3–5 business days after\n                  carrier drop-off.\n                </p>\n              </div>\n            </div>\n          </div>\n        </RadioGroup>\n\n        <!-- Summary calculation box -->\n        <div class=\"border-border bg-muted/40 space-y-2 rounded-lg border p-4 text-xs\">\n          <div class=\"text-muted-foreground flex items-center justify-between\">\n            <span>Selected items subtotal</span>\n            <span class=\"text-foreground font-medium\">{{ formatCurrency(itemsSubtotal) }}</span>\n          </div>\n          <div v-if=\"resolution === 'store-credit'\" class=\"text-success flex items-center justify-between\">\n            <span>Bonus store credit (+10%)</span>\n            <span class=\"font-medium\">+{{ formatCurrency(storeCreditBonus) }}</span>\n          </div>\n          <div class=\"text-muted-foreground flex items-center justify-between\">\n            <span>Prepaid return shipping</span>\n            <span class=\"text-success font-medium\">FREE</span>\n          </div>\n          <div\n            class=\"border-border text-foreground flex items-center justify-between border-t pt-2 text-sm font-semibold\"\n          >\n            <span>\n              {{\n                resolution === 'store-credit'\n                  ? 'Total Store Credit'\n                  : resolution === 'exchange'\n                    ? 'Exchange Value'\n                    : 'Total Refund'\n              }}\n            </span>\n            <span :class=\"resolution === 'store-credit' ? 'text-success' : ''\">\n              {{ resolution === 'store-credit' ? formatCurrency(totalStoreCredit) : formatCurrency(itemsSubtotal) }}\n            </span>\n          </div>\n        </div>\n      </div>\n\n      <!-- Step 4: Confirmation & Label -->\n      <div v-else class=\"space-y-6\">\n        <div class=\"space-y-2 py-2 text-center\">\n          <div\n            class=\"border-success/20 bg-success/10 text-success relative mx-auto flex size-12 items-center justify-center rounded-full border\"\n          >\n            <CheckCircle2 class=\"size-6\" />\n          </div>\n          <h3 class=\"text-foreground text-base font-semibold\">Return Authorized & Confirmed</h3>\n          <p class=\"text-muted-foreground mx-auto max-w-md text-xs\">\n            Your return request has been submitted. A prepaid shipping label and confirmation receipt have been sent to\n            <span class=\"text-foreground font-medium\">{{ email || 'sarah.connor@example.com' }}</span\n            >.\n          </p>\n        </div>\n\n        <!-- Return Details Overview -->\n        <div class=\"border-border bg-muted/20 space-y-3 rounded-lg border p-4\">\n          <div class=\"border-border flex flex-wrap items-center justify-between gap-2 border-b pb-3\">\n            <div class=\"space-y-0.5\">\n              <span class=\"text-muted-foreground text-xs\">Return ID</span>\n              <p class=\"text-foreground font-mono text-sm font-semibold\">#RET-2026-849</p>\n            </div>\n            <Badge variant=\"success\" class=\"gap-1 text-xs\"> <Check class=\"size-3\" /> Authorized </Badge>\n          </div>\n\n          <div class=\"grid grid-cols-1 gap-3 text-xs sm:grid-cols-3\">\n            <div class=\"space-y-0.5\">\n              <span class=\"text-muted-foreground\">Carrier</span>\n              <p class=\"text-foreground font-medium\">USPS Ground Advantage™</p>\n            </div>\n            <div class=\"space-y-0.5\">\n              <span class=\"text-muted-foreground\">Tracking Number</span>\n              <p class=\"text-foreground font-mono font-medium\">9400 1118 9956 2849</p>\n            </div>\n            <div class=\"space-y-0.5\">\n              <span class=\"text-muted-foreground\">Selected Resolution</span>\n              <p class=\"text-foreground font-medium\">\n                {{\n                  resolution === 'store-credit'\n                    ? `Store Credit (${formatCurrency(totalStoreCredit)})`\n                    : resolution === 'exchange'\n                      ? `Exchange (${exchangeSize})`\n                      : `Refund to Visa •••• 4242`\n                }}\n              </p>\n            </div>\n          </div>\n        </div>\n\n        <!-- Action Download Buttons -->\n        <div class=\"flex flex-col gap-3 sm:flex-row\">\n          <Button aria-label=\"Download attachment\" class=\"flex-1 gap-2\" size=\"default\" @click=\"isDownloaded = true\">\n            <Download class=\"size-4\" />\n            {{ isDownloaded ? 'Label Downloaded (PDF)' : 'Download Prepaid Shipping Label (PDF)' }}\n          </Button>\n          <Button variant=\"outline\" class=\"gap-2\" size=\"default\">\n            <Printer class=\"size-4\" />\n            Print Return Slip\n          </Button>\n        </div>\n\n        <!-- Drop-off instructions & QR code card -->\n        <div class=\"border-border bg-card space-y-4 rounded-lg border p-4\">\n          <div class=\"flex items-center justify-between\">\n            <h4 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">\n              Carrier Drop-off Pass & Instructions\n            </h4>\n            <Badge variant=\"outline\" class=\"text-xs\">No printer required</Badge>\n          </div>\n\n          <div class=\"grid grid-cols-1 items-center gap-4 sm:grid-cols-3\">\n            <div class=\"space-y-3 text-xs sm:col-span-2\">\n              <div class=\"flex items-start gap-2.5\">\n                <div\n                  class=\"bg-muted text-foreground mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full text-xs font-medium\"\n                >\n                  1\n                </div>\n                <div class=\"space-y-0.5\">\n                  <p class=\"text-foreground font-medium\">Pack your items</p>\n                  <p class=\"text-muted-foreground\">\n                    Place returned items with tags inside the original shipping bag or any sturdy box.\n                  </p>\n                </div>\n              </div>\n\n              <div class=\"flex items-start gap-2.5\">\n                <div\n                  class=\"bg-muted text-foreground mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full text-xs font-medium\"\n                >\n                  2\n                </div>\n                <div class=\"space-y-0.5\">\n                  <p class=\"text-foreground font-medium\">Attach label or show QR code</p>\n                  <p class=\"text-muted-foreground\">\n                    Tape the downloaded shipping label to the box, or present the digital QR pass at the drop-off\n                    counter.\n                  </p>\n                </div>\n              </div>\n\n              <div class=\"flex items-start gap-2.5\">\n                <div\n                  class=\"bg-muted text-foreground mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full text-xs font-medium\"\n                >\n                  3\n                </div>\n                <div class=\"space-y-0.5\">\n                  <p class=\"text-foreground font-medium\">Drop off before Nov 15, 2026</p>\n                  <p class=\"text-muted-foreground\">\n                    Bring to any USPS Post Office, USPS drop box, or authorized FedEx shipping point.\n                  </p>\n                </div>\n              </div>\n            </div>\n\n            <!-- QR code visual -->\n            <div\n              class=\"border-border bg-muted/40 flex flex-col items-center justify-center space-y-2 rounded-lg border p-3 text-center sm:col-span-1\"\n            >\n              <svg\n                class=\"text-foreground size-24\"\n                viewBox=\"0 0 100 100\"\n                fill=\"currentColor\"\n                aria-label=\"Prepaid return shipping QR dropoff code\"\n              >\n                <!-- Top-left finder -->\n                <rect x=\"10\" y=\"10\" width=\"24\" height=\"24\" rx=\"2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" />\n                <rect x=\"17\" y=\"17\" width=\"10\" height=\"10\" rx=\"1\" fill=\"currentColor\" />\n                <!-- Top-right finder -->\n                <rect x=\"66\" y=\"10\" width=\"24\" height=\"24\" rx=\"2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" />\n                <rect x=\"73\" y=\"17\" width=\"10\" height=\"10\" rx=\"1\" fill=\"currentColor\" />\n                <!-- Bottom-left finder -->\n                <rect x=\"10\" y=\"66\" width=\"24\" height=\"24\" rx=\"2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" />\n                <rect x=\"17\" y=\"73\" width=\"10\" height=\"10\" rx=\"1\" fill=\"currentColor\" />\n                <!-- Data dots -->\n                <rect x=\"42\" y=\"12\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"52\" y=\"12\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"42\" y=\"24\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"52\" y=\"24\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"12\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"24\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"36\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"48\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"60\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"72\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"84\" y=\"42\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"42\" y=\"54\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"54\" y=\"54\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"66\" y=\"54\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"78\" y=\"54\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"42\" y=\"66\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"54\" y=\"66\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"66\" y=\"78\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"78\" y=\"66\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"42\" y=\"78\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"54\" y=\"78\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n                <rect x=\"84\" y=\"78\" width=\"6\" height=\"6\" rx=\"1\" fill=\"currentColor\" />\n              </svg>\n              <span class=\"text-foreground font-mono text-xs font-semibold\">RET-2026-849</span>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"pt-2 text-center\">\n          <Button variant=\"ghost\" size=\"sm\" class=\"text-muted-foreground hover:text-foreground text-xs\" @click=\"reset\">\n            Start another return\n          </Button>\n        </div>\n      </div>\n    </CardContent>\n\n    <CardFooter v-if=\"step < 4\" class=\"border-border flex flex-wrap items-center justify-between gap-2 border-t pt-2\">\n      <Button v-if=\"step > 1\" variant=\"ghost\" size=\"sm\" @click=\"goToPrevious\">\n        <ChevronLeft class=\"mr-1 size-4\" />\n        Back\n      </Button>\n      <div v-else />\n\n      <span class=\"text-muted-foreground text-xs\">Step {{ step }} of 4</span>\n\n      <Button v-if=\"step === 1\" size=\"sm\" :disabled=\"!orderNumber.trim() || !email.trim()\" @click=\"goToNext\">\n        Find Order\n        <ChevronRight class=\"ml-1 size-4\" />\n      </Button>\n\n      <Button v-else-if=\"step === 2\" size=\"sm\" :disabled=\"selectedItemsCount === 0\" @click=\"goToNext\">\n        Choose Resolution\n        <ChevronRight class=\"ml-1 size-4\" />\n      </Button>\n\n      <Button v-else-if=\"step === 3\" size=\"sm\" @click=\"goToNext\">\n        Confirm & Print Label\n        <Check class=\"ml-1 size-4\" />\n      </Button>\n    </CardFooter>\n  </Card>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/ReturnsPortal.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/checkbox.json",
    "https://uipkge.dev/r/vue/input.json",
    "https://uipkge.dev/r/vue/radio-group.json",
    "https://uipkge.dev/r/vue/select.json",
    "https://uipkge.dev/r/vue/stepper.json"
  ],
  "description": "Self-serve e-commerce returns & exchange portal wizard: Stepper header (Find Order → Select Items → Choose Resolution → Confirm & Print Label), order lookup with email and order number, item selection list with return reasons and quantities, resolution selector (size exchange, store credit with +10% bonus, or original payment refund), and confirmation screen with printable prepaid shipping label, QR code drop-off instructions, and return summary.",
  "categories": [
    "commerce",
    "ecommerce",
    "app"
  ]
}