{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "pricing-feature-addon-builder",
  "title": "Pricing Feature Addon Builder",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/pricing-feature-addon-builder/PricingFeatureAddonBuilder.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { ArrowRight, Calculator, Check, CreditCard } from 'lucide-vue-next'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { cn } from '@/lib/utils'\n\nexport interface PricingPlan {\n  id: string\n  name: string\n  monthlyPrice: number\n  description: string\n  includedSeats: number\n}\n\nexport interface PricingAddon {\n  id: string\n  name: string\n  monthlyPrice: number\n  description: string\n  category: string\n}\n\nexport interface PricingFeatureAddonBuilderProps {\n  title?: string\n  description?: string\n  plans?: PricingPlan[]\n  addons?: PricingAddon[]\n  class?: string\n}\n\nconst DEFAULT_PLANS: PricingPlan[] = [\n  {\n    id: 'starter',\n    name: 'Starter Tier',\n    monthlyPrice: 29,\n    description: 'For indie developers and early-stage prototypes needing unbundled speed.',\n    includedSeats: 2,\n  },\n  {\n    id: 'growth',\n    name: 'Growth Core',\n    monthlyPrice: 99,\n    description: 'For scaling product engineering teams building high-conversion platforms.',\n    includedSeats: 5,\n  },\n  {\n    id: 'scale',\n    name: 'Scale Enterprise',\n    monthlyPrice: 299,\n    description: 'For mission-critical production clusters requiring sub-10ms global edge delivery.',\n    includedSeats: 15,\n  },\n]\n\nconst DEFAULT_ADDONS: PricingAddon[] = [\n  {\n    id: 'dedicated-ip',\n    name: 'Dedicated Static Edge IP',\n    monthlyPrice: 49,\n    description: 'Static IPv4/IPv6 address allocations with zero-reputation penalty.',\n    category: 'Network',\n  },\n  {\n    id: 'audit-logs',\n    name: 'Immutable SOC2 Audit Logs',\n    monthlyPrice: 79,\n    description: 'Cryptographically signed telemetry logs with 365-day cold storage retention.',\n    category: 'Security',\n  },\n  {\n    id: 'multi-region',\n    name: 'Multi-Region Active-Active Mesh',\n    monthlyPrice: 129,\n    description: 'Synchronized cross-continental database replicas and automatic DNS failover.',\n    category: 'Reliability',\n  },\n  {\n    id: 'priority-sla',\n    name: '1-Hour Enterprise Response SLA',\n    monthlyPrice: 199,\n    description: 'Direct Slack / Discord hotline with senior design engineering staff.',\n    category: 'Support',\n  },\n]\n\nconst props = withDefaults(defineProps<PricingFeatureAddonBuilderProps>(), {\n  title: 'Build your custom plan with transparent, zero-surprise pricing.',\n  description:\n    'Select your base tier, adjust seat allocations, and toggle modular enterprise add-ons with real-time invoice calculations.',\n})\n\nconst activePlans = computed(() => props.plans ?? DEFAULT_PLANS)\nconst activeAddons = computed(() => props.addons ?? DEFAULT_ADDONS)\n\nconst selectedPlanId = ref('growth')\nconst selectedAddonIds = ref<string[]>(['dedicated-ip', 'audit-logs'])\nconst seatCount = ref(8)\nconst isAnnual = ref(true)\n\nconst selectedPlan = computed(() => {\n  return activePlans.value.find((p) => p.id === selectedPlanId.value) || activePlans.value[0]\n})\n\nconst extraSeats = computed(() => {\n  return Math.max(0, seatCount.value - selectedPlan.value.includedSeats)\n})\n\nconst extraSeatCost = computed(() => extraSeats.value * 15)\n\nconst totalAddonsCost = computed(() => {\n  return activeAddons.value\n    .filter((a) => selectedAddonIds.value.includes(a.id))\n    .reduce((sum, a) => sum + a.monthlyPrice, 0)\n})\n\nconst monthlySubtotal = computed(() => {\n  return selectedPlan.value.monthlyPrice + extraSeatCost.value + totalAddonsCost.value\n})\n\nconst finalMonthlyRate = computed(() => {\n  if (isAnnual.value) {\n    return Math.round(monthlySubtotal.value * 0.8)\n  }\n  return monthlySubtotal.value\n})\n\nconst annualSavings = computed(() => {\n  return (monthlySubtotal.value - Math.round(monthlySubtotal.value * 0.8)) * 12\n})\n\nfunction toggleAddon(addonId: string) {\n  if (selectedAddonIds.value.includes(addonId)) {\n    selectedAddonIds.value = selectedAddonIds.value.filter((id) => id !== addonId)\n  } else {\n    selectedAddonIds.value.push(addonId)\n  }\n}\n</script>\n\n<template>\n  <section\n    data-slot=\"pricing-feature-addon-builder\"\n    :class=\"cn('bg-background relative overflow-hidden py-16 sm:py-24', props.class)\"\n  >\n    <div class=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n      <!-- Section Header -->\n      <div class=\"mx-auto max-w-3xl space-y-4 text-center\">\n        <a\n          href=\"#pricing-calculator\"\n          class=\"group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors\"\n        >\n          <Calculator class=\"text-primary size-3.5\" />\n          <span>Real-time Add-on Cost Synthesizer</span>\n          <ArrowRight class=\"text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5\" />\n        </a>\n\n        <h2 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">\n          {{ title }}\n        </h2>\n\n        <p class=\"text-muted-foreground text-base sm:text-lg\">\n          {{ description }}\n        </p>\n\n        <!-- Billing Cadence Toggle -->\n        <div class=\"flex items-center justify-center gap-3 pt-2\">\n          <span\n            class=\"text-xs font-medium\"\n            :class=\"!isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground'\"\n          >\n            Monthly Billing\n          </span>\n          <button\n            type=\"button\"\n            class=\"bg-muted focus-visible:ring-ring relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus-visible:ring-2 focus-visible:outline-none\"\n            :class=\"isAnnual ? 'bg-primary' : 'bg-muted'\"\n            @click=\"isAnnual = !isAnnual\"\n          >\n            <span\n              class=\"bg-background pointer-events-none inline-block size-5 transform rounded-full shadow-lg ring-0 transition duration-200 ease-in-out\"\n              :class=\"isAnnual ? 'translate-x-5' : 'translate-x-0'\"\n            />\n          </button>\n          <span\n            class=\"flex items-center gap-1.5 text-xs font-medium\"\n            :class=\"isAnnual ? 'text-foreground font-semibold' : 'text-muted-foreground'\"\n          >\n            <span>Annual Billing</span>\n            <Badge variant=\"outline\" class=\"border-success/30 bg-success/10 text-success text-xs\"> Save 20% </Badge>\n          </span>\n        </div>\n      </div>\n\n      <!-- Add-on Builder Workbench -->\n      <div class=\"mt-12 grid grid-cols-1 gap-6 lg:grid-cols-12\">\n        <!-- Left: Plan Selection & Addon Toggles (7 Cols) -->\n        <div class=\"space-y-6 lg:col-span-7\">\n          <!-- Step 1: Base Tier Cards -->\n          <div class=\"space-y-3\">\n            <div class=\"text-muted-foreground text-xs font-bold tracking-wider uppercase\">\n              Step 1: Choose Base Core Tier\n            </div>\n            <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n              <button\n                v-for=\"plan in activePlans\"\n                :key=\"plan.id\"\n                type=\"button\"\n                :class=\"\n                  cn(\n                    'flex flex-col justify-between rounded-xl border p-4 text-left transition-colors',\n                    selectedPlanId === plan.id\n                      ? 'border-primary bg-primary/5 ring-primary/20 shadow-xs ring-1'\n                      : 'border-border bg-card hover:bg-muted/40 text-muted-foreground hover:text-foreground',\n                  )\n                \"\n                @click=\"selectedPlanId = plan.id\"\n              >\n                <div>\n                  <div class=\"text-foreground text-xs font-bold\">{{ plan.name }}</div>\n                  <div class=\"text-foreground mt-1 font-mono text-lg font-bold\">\n                    ${{ plan.monthlyPrice }}<span class=\"text-muted-foreground text-xs font-normal\">/mo</span>\n                  </div>\n                </div>\n                <div class=\"text-muted-foreground mt-2 text-xs\">Includes {{ plan.includedSeats }} engineer seats</div>\n              </button>\n            </div>\n          </div>\n\n          <!-- Step 2: Seat Allocation Slider -->\n          <Card class=\"border-border bg-card/60 shadow-2xs\">\n            <CardContent class=\"space-y-2.5 p-4\">\n              <div class=\"flex items-center justify-between text-xs\">\n                <span class=\"text-foreground font-bold\">Engineer Team Seats</span>\n                <span class=\"text-foreground font-mono text-sm font-bold\"\n                  >{{ seatCount }} seats (${{ extraSeatCost }}/mo extra)</span\n                >\n              </div>\n              <input\n                v-model.number=\"seatCount\"\n                type=\"range\"\n                min=\"2\"\n                max=\"50\"\n                step=\"1\"\n                class=\"accent-primary w-full cursor-pointer\"\n              />\n              <div class=\"text-muted-foreground flex justify-between font-mono text-xs\">\n                <span>2 seats</span>\n                <span>50 seats</span>\n              </div>\n            </CardContent>\n          </Card>\n\n          <!-- Step 3: Enterprise Add-ons Checklist -->\n          <div class=\"space-y-3\">\n            <div class=\"text-muted-foreground text-xs font-bold tracking-wider uppercase\">\n              Step 3: Select Modular Capabilities\n            </div>\n            <div class=\"grid grid-cols-1 gap-2.5\">\n              <button\n                v-for=\"addon in activeAddons\"\n                :key=\"addon.id\"\n                type=\"button\"\n                :class=\"\n                  cn(\n                    'flex items-center justify-between rounded-xl border p-3.5 text-left transition-colors',\n                    selectedAddonIds.includes(addon.id)\n                      ? 'border-primary/60 bg-primary/5 shadow-2xs'\n                      : 'border-border bg-card hover:bg-muted/30 text-muted-foreground hover:text-foreground',\n                  )\n                \"\n                @click=\"toggleAddon(addon.id)\"\n              >\n                <div class=\"flex min-w-0 items-center gap-3\">\n                  <div\n                    :class=\"\n                      cn(\n                        'flex size-5 shrink-0 items-center justify-center rounded border transition-colors',\n                        selectedAddonIds.includes(addon.id)\n                          ? 'border-primary bg-primary text-primary-foreground'\n                          : 'border-border bg-background',\n                      )\n                    \"\n                  >\n                    <Check v-if=\"selectedAddonIds.includes(addon.id)\" class=\"size-3.5\" />\n                  </div>\n                  <div class=\"min-w-0 space-y-0.5\">\n                    <div class=\"flex items-center gap-2\">\n                      <span class=\"text-foreground text-xs font-bold\">{{ addon.name }}</span>\n                      <Badge variant=\"outline\" class=\"border-border text-muted-foreground text-xs\">\n                        {{ addon.category }}\n                      </Badge>\n                    </div>\n                    <div class=\"text-muted-foreground truncate text-xs\">{{ addon.description }}</div>\n                  </div>\n                </div>\n\n                <div class=\"text-foreground shrink-0 pl-2 font-mono text-xs font-bold\">\n                  +${{ addon.monthlyPrice }}<span class=\"text-muted-foreground text-xs font-normal\">/mo</span>\n                </div>\n              </button>\n            </div>\n          </div>\n        </div>\n\n        <!-- Right: Real-time Invoice Estimate Card (5 Cols) -->\n        <div class=\"lg:col-span-5\">\n          <Card class=\"border-border bg-card sticky top-8 shadow-sm\">\n            <CardContent class=\"space-y-6 p-6\">\n              <div class=\"border-border flex items-center justify-between border-b pb-3\">\n                <div class=\"flex items-center gap-2\">\n                  <CreditCard class=\"text-primary size-4\" />\n                  <span class=\"text-foreground text-sm font-semibold\">Estimated Monthly Invoice</span>\n                </div>\n                <Badge variant=\"outline\" class=\"border-border text-primary font-mono text-xs\">\n                  {{ isAnnual ? 'Annualized' : 'Monthly' }}\n                </Badge>\n              </div>\n\n              <!-- Price Breakdown List -->\n              <div class=\"space-y-3 text-xs\">\n                <div class=\"text-muted-foreground flex justify-between\">\n                  <span>{{ selectedPlan.name }}</span>\n                  <span class=\"text-foreground font-mono\">${{ selectedPlan.monthlyPrice }}.00</span>\n                </div>\n\n                <div v-if=\"extraSeats > 0\" class=\"text-muted-foreground flex justify-between\">\n                  <span>Extra Seats ({{ extraSeats }} &times; $15)</span>\n                  <span class=\"text-foreground font-mono\">${{ extraSeatCost }}.00</span>\n                </div>\n\n                <div\n                  v-for=\"addon in activeAddons.filter((a) => selectedAddonIds.includes(a.id))\"\n                  :key=\"addon.id\"\n                  class=\"text-muted-foreground flex justify-between\"\n                >\n                  <span class=\"truncate pr-2\">{{ addon.name }}</span>\n                  <span class=\"text-foreground font-mono\">${{ addon.monthlyPrice }}.00</span>\n                </div>\n\n                <div\n                  v-if=\"isAnnual\"\n                  class=\"border-border/60 text-success flex justify-between border-t pt-2 font-medium\"\n                >\n                  <span>Annual Billing Discount (20%)</span>\n                  <span class=\"font-mono\">&minus;${{ monthlySubtotal - finalMonthlyRate }}.00</span>\n                </div>\n              </div>\n\n              <!-- Total Sum Band -->\n              <div class=\"border-border bg-muted/40 space-y-1 rounded-lg border p-4\">\n                <div class=\"text-muted-foreground text-xs font-medium\">Net Monthly Investment</div>\n                <div class=\"flex items-baseline gap-1.5\">\n                  <span class=\"text-foreground font-mono text-3xl font-bold tracking-tight\">\n                    ${{ finalMonthlyRate }}\n                  </span>\n                  <span class=\"text-muted-foreground font-mono text-xs\">/ month</span>\n                </div>\n                <div v-if=\"isAnnual\" class=\"text-success text-xs font-medium\">\n                  Billed annually (${{ finalMonthlyRate * 12 }}/yr &bull; Save ${{ annualSavings }}/yr)\n                </div>\n              </div>\n\n              <Button class=\"w-full gap-2 shadow-xs\" size=\"lg\">\n                <span>Start 14-Day Free Evaluation</span>\n                <ArrowRight class=\"size-4\" />\n              </Button>\n            </CardContent>\n          </Card>\n        </div>\n      </div>\n    </div>\n  </section>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/pricing-feature-addon-builder/PricingFeatureAddonBuilder.vue"
    },
    {
      "path": "packages/registry-vue/blocks/pricing-feature-addon-builder/index.ts",
      "content": "export { default as PricingFeatureAddonBuilder } from './PricingFeatureAddonBuilder.vue'\nexport type { PricingFeatureAddonBuilderProps, PricingPlan, PricingAddon } from './PricingFeatureAddonBuilder.vue'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/pricing-feature-addon-builder/index.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/card.json"
  ],
  "description": "Interactive add-on pricing calculator with tier bundling, seat scaling, and real-time invoice generation.",
  "categories": [
    "pricing",
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "pricing"
}