{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "lead-capture-popup",
  "title": "Lead Capture Popup",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/lead-capture-popup/LeadCapturePopup.vue",
      "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue'\nimport { computed, onMounted, onUnmounted, ref } from 'vue'\nimport { ArrowRight, Check, CheckCircle2, Clock, Copy, Gift, RotateCcw, Star, X } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\n\ninterface Props {\n  headline?: string\n  subtitle?: string\n  discountCode?: string\n  discountPercent?: number\n  initialSeconds?: number\n  socialProofRating?: string\n  socialProofCount?: string\n  initialSubmitted?: boolean\n  class?: HTMLAttributes['class']\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n  headline: 'Unlock 20% Off Your First Order',\n  subtitle: 'Join 45,000+ engineers receiving our weekly curated component teardowns and architectural breakdowns.',\n  discountCode: 'WELCOME20',\n  discountPercent: 20,\n  initialSeconds: 599,\n  socialProofRating: '4.9/5',\n  socialProofCount: '1,200+ developers',\n  initialSubmitted: false,\n})\n\nconst emit = defineEmits<{\n  (e: 'submit', payload: { email: string; discountCode: string }): void\n  (e: 'dismiss'): void\n  (e: 'copy', code: string): void\n  (e: 'reset'): void\n}>()\n\nconst email = ref('')\nconst isSubmitted = ref(props.initialSubmitted)\nconst isDismissed = ref(false)\nconst copied = ref(false)\nconst timeLeft = ref(props.initialSeconds)\n\nlet timer: ReturnType<typeof setInterval> | null = null\n\nconst formattedTime = computed(() => {\n  const mins = Math.floor(timeLeft.value / 60)\n  const secs = timeLeft.value % 60\n  return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`\n})\n\nonMounted(() => {\n  timer = setInterval(() => {\n    if (timeLeft.value > 0) {\n      timeLeft.value--\n    } else if (timer) {\n      clearInterval(timer)\n    }\n  }, 1000)\n})\n\nonUnmounted(() => {\n  if (timer) clearInterval(timer)\n})\n\nfunction handleSubmit() {\n  if (!email.value || !email.value.includes('@')) return\n  isSubmitted.value = true\n  emit('submit', { email: email.value, discountCode: props.discountCode })\n}\n\nfunction handleDismiss() {\n  isDismissed.value = true\n  emit('dismiss')\n}\n\nfunction handleReset() {\n  isSubmitted.value = false\n  isDismissed.value = false\n  email.value = ''\n  copied.value = false\n  timeLeft.value = props.initialSeconds\n  emit('reset')\n}\n\nfunction copyCoupon() {\n  navigator.clipboard?.writeText(props.discountCode)\n  copied.value = true\n  emit('copy', props.discountCode)\n  setTimeout(() => {\n    copied.value = false\n  }, 2000)\n}\n\ndefineExpose({\n  reset: handleReset,\n  open: () => {\n    isDismissed.value = false\n  },\n})\n</script>\n\n<template>\n  <div v-if=\"!isDismissed\" data-slot=\"lead-capture-popup\" :class=\"cn('w-full', props.class)\">\n    <div\n      class=\"bg-card text-card-foreground border-border relative mx-auto w-full max-w-lg overflow-hidden rounded-2xl border p-6 shadow-xl sm:p-8\"\n    >\n      <!-- Top Right Dismiss Button -->\n      <button\n        type=\"button\"\n        aria-label=\"Dismiss popup\"\n        class=\"text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute top-4 right-4 rounded-full p-1.5 transition-colors focus-visible:ring-2 focus-visible:outline-hidden\"\n        @click=\"handleDismiss\"\n      >\n        <X class=\"size-4\" />\n      </button>\n\n      <!-- FORM STATE -->\n      <div v-if=\"!isSubmitted\" class=\"relative z-10 space-y-6\">\n        <!-- Top Badge -->\n        <div class=\"flex items-center\">\n          <Badge\n            variant=\"secondary\"\n            class=\"border-primary/20 bg-primary/10 text-primary inline-flex items-center gap-1.5 px-3 py-1 text-xs font-medium\"\n          >\n            <Gift class=\"text-primary size-3.5\" />\n            Limited Time Welcome Gift\n          </Badge>\n        </div>\n\n        <!-- Urgency Countdown Bar -->\n        <div\n          class=\"border-warning/20 bg-warning/10 text-foreground text-warning flex items-center justify-between gap-2 rounded-lg border px-3.5 py-2 text-xs\"\n        >\n          <div class=\"flex items-center gap-2\">\n            <Clock class=\"text-warning size-4 shrink-0\" />\n            <span class=\"font-medium\">Claim your {{ discountPercent }}% discount code before the timer expires:</span>\n          </div>\n          <span\n            class=\"bg-warning/20 text-foreground dark:text-foreground rounded px-2 py-0.5 font-mono text-xs font-bold tabular-nums\"\n          >\n            {{ formattedTime }}\n          </span>\n        </div>\n\n        <!-- Headline & Subtitle -->\n        <div class=\"space-y-2\">\n          <h2 class=\"text-foreground text-2xl font-bold tracking-tight sm:text-3xl\">\n            {{ headline }}\n          </h2>\n          <p class=\"text-muted-foreground text-sm leading-relaxed\">\n            {{ subtitle }}\n          </p>\n        </div>\n\n        <!-- Value Bullet Points (3 items with emerald checkmarks) -->\n        <ul class=\"space-y-2.5\" role=\"list\">\n          <li class=\"text-muted-foreground flex items-center gap-2.5 text-xs sm:text-sm\">\n            <span class=\"bg-success/15 text-success flex size-4 shrink-0 items-center justify-center rounded-full\">\n              <Check class=\"size-2.5 stroke-[3]\" />\n            </span>\n            <span>No spam ever &mdash; high-signal engineering teardowns</span>\n          </li>\n          <li class=\"text-muted-foreground flex items-center gap-2.5 text-xs sm:text-sm\">\n            <span class=\"bg-success/15 text-success flex size-4 shrink-0 items-center justify-center rounded-full\">\n              <Check class=\"size-2.5 stroke-[3]\" />\n            </span>\n            <span>1-click unsubscribe anytime with zero friction</span>\n          </li>\n          <li class=\"text-muted-foreground flex items-center gap-2.5 text-xs sm:text-sm\">\n            <span class=\"bg-success/15 text-success flex size-4 shrink-0 items-center justify-center rounded-full\">\n              <Check class=\"size-2.5 stroke-[3]\" />\n            </span>\n            <span>Instant coupon delivery straight to your screen &amp; inbox</span>\n          </li>\n        </ul>\n\n        <!-- Email Capture Form -->\n        <form class=\"space-y-3 pt-1\" @submit.prevent=\"handleSubmit\">\n          <Input\n            v-model=\"email\"\n            type=\"email\"\n            placeholder=\"engineer@company.com\"\n            required\n            autocomplete=\"email\"\n            aria-label=\"Email address\"\n            class=\"border-border bg-background focus-visible:ring-primary h-11 text-sm shadow-xs focus-visible:ring-2\"\n          />\n\n          <Button type=\"submit\" size=\"lg\" class=\"h-11 w-full justify-center gap-2 text-sm font-semibold shadow-xs\">\n            Claim My {{ discountPercent }}% Discount\n            <ArrowRight class=\"size-4\" />\n          </Button>\n        </form>\n\n        <!-- Social Proof Line -->\n        <div class=\"text-muted-foreground flex items-center justify-center gap-1.5 text-xs\">\n          <div class=\"text-warning flex items-center gap-0.5\" aria-hidden=\"true\">\n            <Star class=\"size-3.5 fill-current\" />\n            <Star class=\"size-3.5 fill-current\" />\n            <Star class=\"size-3.5 fill-current\" />\n            <Star class=\"size-3.5 fill-current\" />\n            <Star class=\"size-3.5 fill-current\" />\n          </div>\n          <span class=\"text-foreground font-medium\">{{ socialProofRating }}</span>\n          <span>rating by {{ socialProofCount }}</span>\n        </div>\n\n        <!-- Dismiss / Decline link -->\n        <div class=\"text-center\">\n          <button\n            type=\"button\"\n            class=\"text-muted-foreground hover:text-foreground focus-visible:ring-ring min-h-6 rounded text-xs underline underline-offset-4 transition-colors focus-visible:ring-2 focus-visible:outline-hidden\"\n            @click=\"handleDismiss\"\n          >\n            No thanks, I prefer paying full price\n          </button>\n        </div>\n      </div>\n\n      <!-- SUCCESS STATE -->\n      <div v-else class=\"relative z-10 space-y-5 text-center\">\n        <div class=\"bg-success/10 text-success mx-auto flex size-12 items-center justify-center rounded-full\">\n          <CheckCircle2 class=\"size-6\" />\n        </div>\n\n        <div class=\"space-y-1.5\">\n          <Badge variant=\"outline\" class=\"border-success/30 bg-success/10 text-success font-medium\">\n            {{ discountPercent }}% Discount Unlocked\n          </Badge>\n          <h3 class=\"text-foreground text-2xl font-bold tracking-tight sm:text-3xl\">You&rsquo;re all set!</h3>\n          <p class=\"text-muted-foreground text-xs sm:text-sm\">\n            We&rsquo;ve dispatched your code and welcome gift to\n            <span class=\"text-foreground font-medium\">{{ email || 'engineer@company.com' }}</span\n            >.\n          </p>\n        </div>\n\n        <!-- Coupon Card Box -->\n        <div class=\"border-border bg-muted/40 relative space-y-3 rounded-xl border-2 border-dashed p-4\">\n          <span class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n            Your Exclusive Coupon Code\n          </span>\n          <div class=\"flex items-center justify-center gap-2\">\n            <code\n              class=\"border-border bg-background text-foreground rounded-lg border px-3 py-1.5 font-mono text-xl font-bold tracking-widest sm:text-2xl\"\n            >\n              {{ discountCode }}\n            </code>\n            <Button\n              variant=\"secondary\"\n              size=\"sm\"\n              class=\"gap-1.5 shadow-xs\"\n              :aria-label=\"copied ? 'Copied code' : 'Copy discount code'\"\n              @click=\"copyCoupon\"\n            >\n              <Check v-if=\"copied\" class=\"text-success size-3.5\" />\n              <Copy v-else class=\"size-3.5\" />\n              <span>{{ copied ? 'Copied!' : 'Copy Code' }}</span>\n            </Button>\n          </div>\n          <p class=\"text-muted-foreground text-xs\">\n            Valid for the next <span class=\"font-mono font-medium\">{{ formattedTime }}</span> at checkout.\n          </p>\n        </div>\n\n        <div class=\"space-y-2 pt-2\">\n          <Button class=\"h-11 w-full justify-center gap-2 text-sm font-semibold shadow-xs\" @click=\"handleDismiss\">\n            Start Exploring Components\n            <ArrowRight class=\"size-4\" />\n          </Button>\n          <button\n            type=\"button\"\n            class=\"text-muted-foreground hover:text-foreground focus-visible:ring-ring min-h-6 rounded text-xs underline underline-offset-4 transition-colors focus-visible:ring-2 focus-visible:outline-hidden\"\n            @click=\"handleReset\"\n          >\n            Enter a different email\n          </button>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Reopen trigger fallback when dismissed -->\n  <div\n    v-else\n    class=\"flex flex-col items-center justify-center p-8 text-center\"\n    data-slot=\"lead-capture-popup-dismissed\"\n  >\n    <p class=\"text-muted-foreground text-sm\">Popup was dismissed.</p>\n    <Button variant=\"outline\" size=\"sm\" class=\"mt-3 gap-2\" @click=\"handleReset\">\n      <RotateCcw class=\"text-primary size-3.5\" />\n      Reopen Welcome Popup\n    </Button>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/LeadCapturePopup.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/input.json",
    "https://uipkge.dev/r/vue/badge.json"
  ],
  "description": "High-conversion exit-intent discount popup and newsletter lead generator with live ticking countdown timer, emerald value props, star rating social proof, and coupon code reveal.",
  "categories": [
    "marketing"
  ]
}