{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "product-detail-page",
  "title": "Product Detail Page",
  "type": "registry:page",
  "files": [
    {
      "path": "packages/registry-vue/blocks/product-detail-page/ProductDetailPage.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ChevronRight } from 'lucide-vue-next'\n\n// Import sub-blocks to compose the canonical enterprise PDP\nimport FlashSaleOfferBar from '../flash-sale-offer-bar/FlashSaleOfferBar.vue'\nimport TechnicalSpecsSheet from '../technical-specs-sheet/TechnicalSpecsSheet.vue'\nimport ProductQaCommunity from '../product-qa-community/ProductQaCommunity.vue'\nimport CustomerReviews from '../customer-reviews/CustomerReviews.vue'\nimport FrequentlyBoughtTogether from '../frequently-bought-together/FrequentlyBoughtTogether.vue'\nimport ProductGalleryBuyBox from './ProductGalleryBuyBox.vue'\nimport { variants } from './product-variants'\n\nconst selectedVariantId = ref(variants[0].id)\n\nconst currentVariant = computed(() => {\n  return variants.find((v) => v.id === selectedVariantId.value) || variants[0]\n})\n\nfunction handleSelectVariant(id: string) {\n  selectedVariantId.value = id\n}\n</script>\n\n<template>\n  <div data-slot=\"product-detail-page\" class=\"bg-background text-foreground w-full space-y-10\">\n    <!-- Breadcrumb Navigation Bar -->\n    <nav class=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n      <span class=\"hover:text-foreground cursor-pointer\">Storefront</span>\n      <ChevronRight class=\"size-3.5\" />\n      <span class=\"hover:text-foreground cursor-pointer\">Pro Audio & Reference</span>\n      <ChevronRight class=\"size-3.5\" />\n      <span class=\"hover:text-foreground cursor-pointer\">Planar Magnetic</span>\n      <ChevronRight class=\"size-3.5\" />\n      <span class=\"text-foreground font-medium\">APX-950-PRO Reference Monitor</span>\n    </nav>\n\n    <!-- Main Hero Split: Gallery & Buy Box -->\n    <ProductGalleryBuyBox :selected-variant-id=\"selectedVariantId\" :on-select-variant=\"handleSelectVariant\" />\n\n    <!-- Section 2: Flash Sale & Multi-Buy Tier Deal Bar -->\n    <div class=\"space-y-3\">\n      <FlashSaleOfferBar\n        saleTitle=\"Audio Pro Week: Limited Master Batch 04\"\n        :claimedPercent=\"82\"\n        :itemsLeft=\"currentVariant.stockCount\"\n      />\n    </div>\n\n    <!-- Section 3: Frequently Bought Together Bundle -->\n    <div class=\"space-y-4\">\n      <FrequentlyBoughtTogether />\n    </div>\n\n    <!-- Section 4: Engineering & Technical Specifications Sheet -->\n    <div class=\"space-y-4\">\n      <TechnicalSpecsSheet modelNumber=\"APX-950-PRO\" revision=\"Studio Edition 2026\" />\n    </div>\n\n    <!-- Section 5: Verified Customer Reviews & Photo Breakdown -->\n    <div class=\"space-y-4\">\n      <CustomerReviews />\n    </div>\n\n    <!-- Section 6: Customer & Staff Q&A Community -->\n    <div class=\"space-y-4\">\n      <ProductQaCommunity productName=\"Apex Pro Reference Planar Headphones\" />\n    </div>\n  </div>\n</template>\n",
      "type": "registry:page",
      "target": "~/app/components/blocks/ProductDetailPage.vue"
    },
    {
      "path": "packages/registry-vue/blocks/product-detail-page/ProductGalleryBuyBox.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n  Star,\n  ShieldCheck,\n  Truck,\n  RotateCcw,\n  Heart,\n  Share2,\n  Plus,\n  Minus,\n  ShoppingCart,\n  Zap,\n  Flame,\n} from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Separator } from '@/components/ui/separator'\n\nimport { variants, type ProductVariant } from './product-variants'\n\nconst props = defineProps<{\n  selectedVariantId: string\n  onSelectVariant: (id: string) => void\n}>()\n\nconst activeImageIndex = ref(0)\nconst quantity = ref(1)\nconst selectedCable = ref<'4.4mm' | '3.5mm' | 'xlr'>('4.4mm')\nconst isWishlisted = ref(false)\nconst addExtendedWarranty = ref(true)\nconst zipCode = ref('94103')\n\nconst currentVariant = computed(() => {\n  return variants.find((v) => v.id === props.selectedVariantId) || variants[0]\n})\n\nconst activeImageUrl = computed(() => {\n  return currentVariant.value.images[activeImageIndex.value]?.url || currentVariant.value.images[0].url\n})\n\nconst finalPrice = computed(() => {\n  let base = currentVariant.value.price * quantity.value\n  if (addExtendedWarranty.value) base += 49\n  return base\n})\n\nfunction selectVariant(v: ProductVariant) {\n  props.onSelectVariant(v.id)\n  activeImageIndex.value = 0\n}\n\nfunction incrementQty() {\n  if (quantity.value < currentVariant.value.stockCount) {\n    quantity.value++\n  }\n}\n\nfunction decrementQty() {\n  if (quantity.value > 1) {\n    quantity.value--\n  }\n}\n\nfunction handleAddToCart() {\n  alert(\n    `Added ${quantity.value}x ${currentVariant.value.name} (${selectedCable.value}) to cart. Total: $${finalPrice.value}`,\n  )\n}\n\nfunction shareLink() {\n  alert('Share link copied to clipboard!')\n}\n\nfunction handleExpressBuy() {\n  alert(`Initiating Express Apple Pay checkout for $${finalPrice.value}...`)\n}\n</script>\n\n<template>\n  <div class=\"grid grid-cols-1 gap-8 lg:grid-cols-12 lg:gap-12\">\n    <!-- Left Column: Interactive Image Gallery (7 Cols) -->\n    <div class=\"space-y-4 lg:col-span-7\">\n      <!-- Main Large Showcase Image -->\n      <div class=\"border-border bg-muted/30 relative aspect-4/3 w-full overflow-hidden rounded-xl border shadow-xs\">\n        <img\n          :src=\"activeImageUrl\"\n          :alt=\"currentVariant.name\"\n          class=\"size-full object-cover transition-transform duration-300 hover:scale-105\"\n        />\n\n        <!-- Overlaid Badges -->\n        <div class=\"absolute top-3 left-3 flex flex-wrap gap-1.5\">\n          <Badge variant=\"default\" class=\"h-6 font-mono text-xs font-semibold uppercase\"> 2026 Flagship </Badge>\n          <Badge variant=\"secondary\" class=\"text-success h-6 font-mono text-xs\"> Laboratory Calibrated </Badge>\n        </div>\n\n        <!-- Quick Action Floating Buttons -->\n        <div class=\"absolute top-3 right-3 flex flex-col gap-2\">\n          <button\n            type=\"button\"\n            :class=\"[\n              'border-border bg-background/90 flex size-8 items-center justify-center rounded-full border shadow-2xs backdrop-blur-xs transition-colors',\n              isWishlisted ? 'text-destructive' : 'text-muted-foreground hover:text-foreground',\n            ]\"\n            @click=\"isWishlisted = !isWishlisted\"\n          >\n            <Heart class=\"size-4\" :class=\"{ 'fill-current': isWishlisted }\" />\n          </button>\n          <button\n            type=\"button\"\n            class=\"border-border bg-background/90 text-muted-foreground hover:text-foreground flex size-8 items-center justify-center rounded-full border shadow-2xs backdrop-blur-xs transition-colors\"\n            @click=\"shareLink\"\n          >\n            <Share2 class=\"size-4\" />\n          </button>\n        </div>\n      </div>\n\n      <!-- Thumbnail Selector Row -->\n      <div class=\"grid grid-cols-4 gap-3\">\n        <button\n          v-for=\"(img, idx) in currentVariant.images\"\n          :key=\"img.id\"\n          type=\"button\"\n          :class=\"[\n            'bg-muted/20 relative aspect-4/3 overflow-hidden rounded-lg border transition-colors',\n            activeImageIndex === idx\n              ? 'border-primary ring-primary/40 ring-2'\n              : 'border-border opacity-70 hover:opacity-100',\n          ]\"\n          @click=\"activeImageIndex = idx\"\n        >\n          <img :src=\"img.url\" :alt=\"img.alt\" class=\"size-full object-cover\" />\n        </button>\n      </div>\n\n      <!-- Value Assurance Micro-Bar -->\n      <div class=\"border-border bg-muted/20 grid grid-cols-3 gap-3 rounded-lg border p-3 text-center text-xs\">\n        <div class=\"flex flex-col items-center gap-1\">\n          <Truck class=\"text-primary size-4\" />\n          <span class=\"text-foreground font-medium\">Free 2-Day Air</span>\n          <span class=\"text-muted-foreground text-xs\">Orders over $150</span>\n        </div>\n        <div class=\"border-border/80 flex flex-col items-center gap-1 border-x px-2\">\n          <RotateCcw class=\"text-success size-4\" />\n          <span class=\"text-foreground font-medium\">45-Day Trial</span>\n          <span class=\"text-muted-foreground text-xs\">Zero-risk return</span>\n        </div>\n        <div class=\"flex flex-col items-center gap-1\">\n          <ShieldCheck class=\"text-info size-4\" />\n          <span class=\"text-foreground font-medium\">3-Yr Warranty</span>\n          <span class=\"text-muted-foreground text-xs\">Direct factory support</span>\n        </div>\n      </div>\n    </div>\n\n    <!-- Right Column: Buy Box & Product Configuration (5 Cols) -->\n    <div class=\"space-y-6 lg:col-span-5\">\n      <!-- Title & Rating Header -->\n      <div class=\"space-y-2\">\n        <div class=\"text-muted-foreground flex items-center gap-2 font-mono text-xs\">\n          <span>SKU: {{ currentVariant.sku }}</span>\n          <span>·</span>\n          <span>Made in Germany</span>\n        </div>\n\n        <h1 class=\"text-foreground text-2xl font-bold tracking-tight sm:text-3xl\">\n          Apex Pro Reference Planar Studio Headphones\n        </h1>\n\n        <!-- Reviews summary badge -->\n        <div class=\"flex items-center gap-2 pt-1 text-xs\">\n          <div class=\"text-warning flex items-center gap-1\">\n            <Star class=\"fill-warning size-3.5\" />\n            <Star class=\"fill-warning size-3.5\" />\n            <Star class=\"fill-warning size-3.5\" />\n            <Star class=\"fill-warning size-3.5\" />\n            <Star class=\"fill-warning size-3.5\" />\n          </div>\n          <span class=\"text-foreground font-semibold\">4.9</span>\n          <span class=\"text-muted-foreground\">(342 Verified Mastering Reviews)</span>\n        </div>\n      </div>\n\n      <Separator />\n\n      <!-- Price Section with Live Discount -->\n      <div class=\"space-y-1.5\">\n        <div class=\"flex items-baseline gap-3\">\n          <span class=\"text-foreground text-3xl font-extrabold tracking-tight\"> ${{ currentVariant.price }} </span>\n          <span class=\"text-muted-foreground text-base line-through\"> ${{ currentVariant.originalPrice }} </span>\n          <Badge variant=\"secondary\" class=\"text-success font-mono text-xs font-bold\">\n            Save ${{ currentVariant.originalPrice - currentVariant.price }} (20% OFF)\n          </Badge>\n        </div>\n        <p class=\"text-muted-foreground text-xs\">\n          Interest-free installments of ${{ (currentVariant.price / 4).toFixed(2) }}/mo with Affirm or Klarna.\n        </p>\n      </div>\n\n      <!-- Variant Color Selector -->\n      <div class=\"space-y-2.5\">\n        <div class=\"flex items-center justify-between text-xs\">\n          <span class=\"text-foreground font-medium\">Finish / Enclosure:</span>\n          <span class=\"text-muted-foreground font-mono font-semibold\">{{ currentVariant.name }}</span>\n        </div>\n\n        <div class=\"flex items-center gap-3\">\n          <button\n            v-for=\"v in variants\"\n            :key=\"v.id\"\n            type=\"button\"\n            :class=\"[\n              'group relative flex size-9 items-center justify-center rounded-full border transition-colors',\n              selectedVariantId === v.id\n                ? 'border-primary ring-primary ring-offset-background ring-2 ring-offset-2'\n                : 'border-border hover:border-muted-foreground',\n            ]\"\n            @click=\"selectVariant(v)\"\n          >\n            <span\n              class=\"size-6 rounded-full border border-black/10 shadow-2xs\"\n              :style=\"{ backgroundColor: v.colorHex }\"\n            />\n          </button>\n        </div>\n      </div>\n\n      <!-- Cable Termination Selector -->\n      <div class=\"space-y-2.5\">\n        <div class=\"flex items-center justify-between text-xs\">\n          <span class=\"text-foreground font-medium\">Primary Studio Cable Termination:</span>\n          <span class=\"text-primary font-mono text-xs\">Included in package</span>\n        </div>\n\n        <div class=\"grid grid-cols-3 gap-2 text-xs\">\n          <button\n            type=\"button\"\n            :class=\"[\n              'rounded-lg border p-2.5 text-center transition-colors',\n              selectedCable === '4.4mm'\n                ? 'border-primary bg-primary/5 text-primary ring-primary font-semibold ring-1'\n                : 'border-border bg-card text-foreground hover:bg-muted/40',\n            ]\"\n            @click=\"selectedCable = '4.4mm'\"\n          >\n            <div class=\"font-mono text-xs font-semibold\">4.4mm Balanced</div>\n            <div class=\"text-muted-foreground text-xs\">Pentaconn TRRRS</div>\n          </button>\n\n          <button\n            type=\"button\"\n            :class=\"[\n              'rounded-lg border p-2.5 text-center transition-colors',\n              selectedCable === '3.5mm'\n                ? 'border-primary bg-primary/5 text-primary ring-primary font-semibold ring-1'\n                : 'border-border bg-card text-foreground hover:bg-muted/40',\n            ]\"\n            @click=\"selectedCable = '3.5mm'\"\n          >\n            <div class=\"font-mono text-xs font-semibold\">3.5mm SE + 6.35mm</div>\n            <div class=\"text-muted-foreground text-xs\">Screw Adapter</div>\n          </button>\n\n          <button\n            type=\"button\"\n            :class=\"[\n              'rounded-lg border p-2.5 text-center transition-colors',\n              selectedCable === 'xlr'\n                ? 'border-primary bg-primary/5 text-primary ring-primary font-semibold ring-1'\n                : 'border-border bg-card text-foreground hover:bg-muted/40',\n            ]\"\n            @click=\"selectedCable = 'xlr'\"\n          >\n            <div class=\"font-mono text-xs font-semibold\">4-Pin XLR Pro</div>\n            <div class=\"text-muted-foreground text-xs\">Neutrik Studio</div>\n          </button>\n        </div>\n      </div>\n\n      <!-- Add-on Warranty Checkbox -->\n      <label\n        class=\"border-border bg-muted/20 hover:bg-muted/30 flex cursor-pointer items-start gap-3 rounded-lg border p-3 text-xs transition-colors\"\n      >\n        <input\n          v-model=\"addExtendedWarranty\"\n          type=\"checkbox\"\n          class=\"border-border text-primary focus:ring-primary mt-0.5 size-4 rounded\"\n        />\n        <div class=\"space-y-0.5\">\n          <div class=\"flex items-center justify-between\">\n            <span class=\"text-foreground font-semibold\">Add 3-Year Apex Care+ Accidental Protection</span>\n            <span class=\"text-foreground font-mono font-bold\">+$49.00</span>\n          </div>\n          <p class=\"text-muted-foreground text-xs\">\n            Covers accidental drops, driver voice-coil failure, and free earpad replacement.\n          </p>\n        </div>\n      </label>\n\n      <!-- Stock Telemetry & Urgency Notice -->\n      <div class=\"space-y-1.5 rounded-lg border border-orange-500/30 bg-orange-500/5 p-3 text-xs\">\n        <div class=\"flex items-center justify-between\">\n          <div class=\"flex items-center gap-1.5 font-semibold text-orange-600 dark:text-orange-400\">\n            <Flame class=\"size-3.5 fill-current\" />\n            <span>Fulfillment Hub Stock Level</span>\n          </div>\n          <span class=\"text-foreground font-mono font-bold\">{{ currentVariant.stockCount }} units remaining</span>\n        </div>\n        <p class=\"text-muted-foreground text-xs\">\n          High demand: 18 sound engineers have this item in their active checkout carts.\n        </p>\n      </div>\n\n      <!-- Quantity & Add to Cart Controls -->\n      <div class=\"space-y-3 pt-2\">\n        <div class=\"flex items-center gap-3\">\n          <!-- Stepper -->\n          <div class=\"border-border bg-background flex h-10 items-center rounded-lg border shadow-2xs\">\n            <button\n              type=\"button\"\n              class=\"text-muted-foreground hover:text-foreground flex size-9 items-center justify-center\"\n              @click=\"decrementQty\"\n            >\n              <Minus class=\"size-3.5\" />\n            </button>\n            <span class=\"text-foreground w-8 text-center font-mono text-xs font-semibold\">{{ quantity }}</span>\n            <button\n              type=\"button\"\n              class=\"text-muted-foreground hover:text-foreground flex size-9 items-center justify-center\"\n              @click=\"incrementQty\"\n            >\n              <Plus class=\"size-3.5\" />\n            </button>\n          </div>\n\n          <!-- Primary Add to Cart -->\n          <Button class=\"h-10 flex-1 gap-2 font-medium shadow-xs\" @click=\"handleAddToCart\">\n            <ShoppingCart class=\"size-4\" />\n            <span>Add to Cart · ${{ finalPrice }}</span>\n          </Button>\n        </div>\n\n        <!-- 1-Click Apple Pay / Instant Buy -->\n        <Button\n          variant=\"secondary\"\n          class=\"border-border h-10 w-full gap-2 border font-semibold shadow-2xs\"\n          @click=\"handleExpressBuy\"\n        >\n          <Zap class=\"fill-warning text-warning size-4\" />\n          <span>Instant 1-Click Checkout (Apple Pay / G-Pay)</span>\n        </Button>\n      </div>\n\n      <!-- Shipping Zip Code Estimator -->\n      <div class=\"border-border bg-muted/20 flex items-center gap-2 rounded-lg border p-2.5 text-xs\">\n        <Truck class=\"text-muted-foreground size-4 shrink-0\" />\n        <span class=\"text-muted-foreground\">Deliver to:</span>\n        <Input v-model=\"zipCode\" maxlength=\"5\" class=\"h-7 w-20 text-center font-mono text-xs\" />\n        <span class=\"text-foreground font-medium\">Fast Delivery: <strong>Tomorrow, 2:00 PM</strong></span>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:page",
      "target": "~/app/components/blocks/ProductGalleryBuyBox.vue"
    },
    {
      "path": "packages/registry-vue/blocks/product-detail-page/product-variants.ts",
      "content": "export interface ProductVariant {\n  id: string\n  name: string\n  colorHex: string\n  sku: string\n  inStock: boolean\n  stockCount: number\n  price: number\n  originalPrice: number\n  images: { id: string; url: string; alt: string }[]\n}\n\nexport const variants: ProductVariant[] = [\n  {\n    id: 'var-black',\n    name: 'Obsidian Matte Black',\n    colorHex: '#18181b',\n    sku: 'APX-950-BLK',\n    inStock: true,\n    stockCount: 14,\n    price: 599,\n    originalPrice: 749,\n    images: [\n      {\n        id: 'img-1',\n        url: 'https://images.unsplash.com/photo-1546435770-a3e426bf472b?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Reference Studio Headphones on Wood Desk',\n      },\n      {\n        id: 'img-2',\n        url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro CNC Aluminum Driver Open Back View',\n      },\n      {\n        id: 'img-3',\n        url: 'https://images.unsplash.com/photo-1583394838336-acd977736f90?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Lambskin Magnetic Earpads Angle',\n      },\n      {\n        id: 'img-4',\n        url: 'https://images.unsplash.com/photo-1484704849700-f032a568e944?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Studio Audio Cable Interconnects',\n      },\n    ],\n  },\n  {\n    id: 'var-silver',\n    name: 'Lunar Silver Aluminum',\n    colorHex: '#94a3b8',\n    sku: 'APX-950-SLV',\n    inStock: true,\n    stockCount: 6,\n    price: 599,\n    originalPrice: 749,\n    images: [\n      {\n        id: 'img-2',\n        url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Lunar Silver Open Back View',\n      },\n      {\n        id: 'img-1',\n        url: 'https://images.unsplash.com/photo-1546435770-a3e426bf472b?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Silver Edition Desk Shot',\n      },\n      {\n        id: 'img-3',\n        url: 'https://images.unsplash.com/photo-1583394838336-acd977736f90?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Earpads Detail',\n      },\n    ],\n  },\n  {\n    id: 'var-navy',\n    name: 'Midnight Studio Navy',\n    colorHex: '#1e293b',\n    sku: 'APX-950-NVY',\n    inStock: true,\n    stockCount: 3,\n    price: 629,\n    originalPrice: 779,\n    images: [\n      {\n        id: 'img-3',\n        url: 'https://images.unsplash.com/photo-1583394838336-acd977736f90?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Midnight Navy Studio Edition',\n      },\n      {\n        id: 'img-1',\n        url: 'https://images.unsplash.com/photo-1546435770-a3e426bf472b?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Navy Perspective',\n      },\n      {\n        id: 'img-2',\n        url: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=900&auto=format&fit=crop&q=80',\n        alt: 'Apex Pro Navy Driver Housing',\n      },\n    ],\n  },\n]\n",
      "type": "registry:page",
      "target": "~/app/components/blocks/product-variants.ts"
    }
  ],
  "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/input.json",
    "https://uipkge.dev/r/vue/separator.json"
  ],
  "description": "Flagship e-commerce product detail page with multi-angle gallery, finish & cable selectors, stock urgency counter, warranty upsell, flash sale countdown bar, frequently bought together bundle, technical specs sheet, customer reviews breakdown, and community Q&A.",
  "categories": [
    "commerce",
    "ecommerce"
  ]
}