{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "flash-sale-offer-bar",
  "title": "Flash Sale Offer Bar",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/flash-sale-offer-bar/FlashSaleOfferBar.vue",
      "content": "<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted } from 'vue'\nimport { Flame, ShieldCheck, Tag } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\n\nexport interface TierOffer {\n  id: string\n  quantity: number\n  discountPct: number\n  label: string\n  badgeText?: string\n  popular?: boolean\n}\n\nexport interface FlashSaleProps {\n  saleTitle?: string\n  endTimeIso?: string\n  claimedPercent?: number\n  itemsLeft?: number\n  currentTier?: number\n  tiers?: TierOffer[]\n  className?: string\n}\n\nconst props = withDefaults(defineProps<FlashSaleProps>(), {\n  saleTitle: 'Lightning Deal: Limited Quantity Batch',\n  // 6 hours from now default\n  endTimeIso: () => new Date(Date.now() + 6 * 3600 * 1000 + 42 * 60 * 1000 + 19 * 1000).toISOString(),\n  claimedPercent: 78,\n  itemsLeft: 14,\n  currentTier: 2,\n  tiers: () => [\n    { id: 't1', quantity: 1, discountPct: 15, label: 'Standard Pack', badgeText: 'Save $45' },\n    {\n      id: 't2',\n      quantity: 2,\n      discountPct: 25,\n      label: 'Duo Studio Bundle',\n      badgeText: 'Save $150 · Best Value',\n      popular: true,\n    },\n    { id: 't3', quantity: 3, discountPct: 35, label: 'Team / Lab Triad', badgeText: 'Save $315' },\n  ],\n})\n\nconst emit = defineEmits<{\n  (e: 'select-tier', tier: TierOffer): void\n  (e: 'claim-deal'): void\n}>()\n\nconst selectedTierId = ref(props.tiers[1]?.id || props.tiers[0]?.id || '')\n\nconst timeLeft = ref({\n  hours: '06',\n  minutes: '42',\n  seconds: '19',\n})\n\nlet timerInterval: ReturnType<typeof setInterval> | null = null\n\nfunction updateCountdown() {\n  const target = new Date(props.endTimeIso).getTime()\n  const now = Date.now()\n  const diff = Math.max(0, target - now)\n\n  const h = Math.floor(diff / (1000 * 60 * 60))\n  const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))\n  const s = Math.floor((diff % (1000 * 60)) / 1000)\n\n  timeLeft.value = {\n    hours: String(h).padStart(2, '0'),\n    minutes: String(m).padStart(2, '0'),\n    seconds: String(s).padStart(2, '0'),\n  }\n}\n\nonMounted(() => {\n  updateCountdown()\n  timerInterval = setInterval(updateCountdown, 1000)\n})\n\nonUnmounted(() => {\n  if (timerInterval) clearInterval(timerInterval)\n})\n\nfunction handleSelectTier(tier: TierOffer) {\n  selectedTierId.value = tier.id\n  emit('select-tier', tier)\n}\n</script>\n\n<template>\n  <div\n    data-slot=\"flash-sale-offer-bar\"\n    :class=\"['border-border bg-card w-full overflow-hidden rounded-xl border shadow-xs', className]\"\n  >\n    <!-- Deal Header Banner -->\n    <div\n      class=\"border-border bg-muted/40 flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-center sm:justify-between\"\n    >\n      <div class=\"flex items-center gap-2.5\">\n        <div class=\"border-border bg-background flex size-8 items-center justify-center rounded-lg border shadow-2xs\">\n          <Flame class=\"size-4 fill-orange-500/20 text-orange-500\" />\n        </div>\n        <div>\n          <div class=\"flex items-center gap-2\">\n            <span class=\"text-foreground text-sm font-semibold tracking-tight\">{{ saleTitle }}</span>\n            <Badge variant=\"destructive\" class=\"h-5 gap-1 px-1.5 font-mono text-xs uppercase\">\n              <span class=\"bg-background size-1.5 animate-pulse rounded-full\" />\n              Live\n            </Badge>\n          </div>\n          <p class=\"text-muted-foreground text-xs\">Price locks automatically once added to cart.</p>\n        </div>\n      </div>\n\n      <!-- Live Clock Digits -->\n      <div class=\"flex items-center gap-2 self-start sm:self-auto\">\n        <span class=\"text-muted-foreground text-xs font-medium\">Ends in:</span>\n        <div class=\"text-foreground flex items-center gap-1 font-mono text-xs font-semibold\">\n          <span class=\"border-border bg-background rounded border px-1.5 py-0.5 shadow-2xs\">{{ timeLeft.hours }}h</span>\n          <span>:</span>\n          <span class=\"border-border bg-background rounded border px-1.5 py-0.5 shadow-2xs\"\n            >{{ timeLeft.minutes }}m</span\n          >\n          <span>:</span>\n          <span class=\"border-border bg-background text-destructive rounded border px-1.5 py-0.5 shadow-2xs\"\n            >{{ timeLeft.seconds }}s</span\n          >\n        </div>\n      </div>\n    </div>\n\n    <div class=\"space-y-4 p-4\">\n      <!-- Claim Progress Bar -->\n      <div class=\"space-y-1.5\">\n        <div class=\"flex items-center justify-between text-xs\">\n          <span class=\"text-foreground flex items-center gap-1.5 font-medium\">\n            <Flame class=\"text-warning size-3.5\" />\n            <span>{{ claimedPercent }}% Claimed</span>\n          </span>\n          <span class=\"text-destructive font-mono font-medium\">Only {{ itemsLeft }} units remaining in stock</span>\n        </div>\n        <div class=\"bg-muted h-2 w-full overflow-hidden rounded-full\">\n          <div\n            class=\"h-full rounded-full bg-gradient-to-r from-orange-500 to-rose-500 transition-[width] duration-500\"\n            :style=\"{ width: `${claimedPercent}%` }\"\n          />\n        </div>\n      </div>\n\n      <!-- Tier Multi-Buy Cards Grid -->\n      <div class=\"grid grid-cols-1 gap-2.5 sm:grid-cols-3\">\n        <button\n          v-for=\"tier in tiers\"\n          :key=\"tier.id\"\n          type=\"button\"\n          :class=\"[\n            'relative flex flex-col justify-between rounded-lg border p-3 text-left transition-colors',\n            selectedTierId === tier.id\n              ? 'border-primary bg-primary/5 ring-primary ring-1'\n              : 'border-border bg-card hover:border-muted-foreground/40 hover:bg-muted/30',\n          ]\"\n          @click=\"handleSelectTier(tier)\"\n        >\n          <!-- Popular ribbon -->\n          <span\n            v-if=\"tier.popular\"\n            class=\"border-border bg-primary text-primary-foreground absolute -top-2.5 right-3 rounded-full border px-2 py-0.5 text-xs font-semibold shadow-xs\"\n          >\n            MOST POPULAR\n          </span>\n\n          <div class=\"space-y-1\">\n            <div class=\"flex items-center justify-between\">\n              <span class=\"text-foreground text-xs font-semibold\"\n                >Buy {{ tier.quantity }} {{ tier.quantity > 1 ? 'Units' : 'Unit' }}</span\n              >\n              <Badge variant=\"secondary\" class=\"text-success font-mono text-xs font-bold\">\n                -{{ tier.discountPct }}% OFF\n              </Badge>\n            </div>\n            <div class=\"text-muted-foreground text-xs font-medium\">{{ tier.label }}</div>\n          </div>\n\n          <div class=\"border-border/60 mt-3 flex items-center justify-between border-t pt-2 text-xs\">\n            <span class=\"text-muted-foreground\">{{ tier.badgeText }}</span>\n            <div\n              :class=\"[\n                'flex size-4 items-center justify-center rounded-full border text-xs font-bold',\n                selectedTierId === tier.id\n                  ? 'border-primary bg-primary text-primary-foreground'\n                  : 'border-muted-foreground/40',\n              ]\"\n            >\n              ✓\n            </div>\n          </div>\n        </button>\n      </div>\n\n      <!-- Footer Guarantee & CTA Banner -->\n      <div\n        class=\"border-border bg-muted/20 flex flex-col gap-2 rounded-lg border p-3 text-xs sm:flex-row sm:items-center sm:justify-between\"\n      >\n        <div class=\"text-muted-foreground flex items-center gap-2\">\n          <ShieldCheck class=\"text-success size-4\" />\n          <span>30-day price-match guarantee · Free express 2-day dispatch</span>\n        </div>\n        <Button size=\"sm\" class=\"gap-1.5 text-xs shadow-xs\" @click=\"$emit('claim-deal')\">\n          <Tag class=\"size-3.5\" />\n          <span>Apply Tier Discount to Cart</span>\n        </Button>\n      </div>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/flash-sale-offer-bar/FlashSaleOfferBar.vue"
    },
    {
      "path": "packages/registry-vue/blocks/flash-sale-offer-bar/index.ts",
      "content": "export { default as FlashSaleOfferBar } from './FlashSaleOfferBar.vue'\nexport type { TierOffer, FlashSaleProps } from './FlashSaleOfferBar.vue'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/flash-sale-offer-bar/index.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json"
  ],
  "description": "Limited-time flash sale countdown deal bar with stock claim progress meter, tiered multi-buy volume discounts, and 1-click cart activation.",
  "categories": [
    "ecommerce",
    "marketing"
  ]
}