{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "pricing-with-switch",
  "type": "registry:block",
  "title": "Pricing with Switch",
  "description": "A pricing section with a monthly/yearly billing toggle, animated card reveal.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": ["@scrollxui/button", "@scrollxui/card"],
  "dependencies": ["lucide-react", "motion"],
  "files": [
    {
      "type": "registry:component",
      "path": "registry/blocks/pricing-sections/pricing-with-switch.tsx",
      "content": "'use client';\n\nimport { useState } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimport { cn } from '@/lib/utils';\nimport { Check } from 'lucide-react';\nimport {\n  Card,\n  CardContent,\n  CardHeader,\n  CardTitle,\n  CardDescription,\n} from '@/components/ui/card';\nimport { Button } from '@/components/ui/button';\n\ninterface PricingTier {\n  name: string;\n  description: string;\n  monthlyPrice: number;\n  yearlyPrice: number;\n  features: string[];\n  buttonText: string;\n  popular?: boolean;\n}\n\ninterface PricingSwitchProps {\n  title?: string;\n  subtitle?: string;\n  description?: string;\n  tiers?: PricingTier[];\n  className?: string;\n}\n\nconst defaultTiers: PricingTier[] = [\n  {\n    name: 'Starter',\n    description: 'Perfect for individuals just getting started',\n    monthlyPrice: 9,\n    yearlyPrice: 7,\n    features: [\n      '10,000 Words / Month',\n      '5 Projects',\n      'Basic Analytics',\n      'Email Support',\n    ],\n    buttonText: 'Get Started',\n    popular: false,\n  },\n  {\n    name: 'Advanced',\n    description: 'Access all of your translation features',\n    monthlyPrice: 29,\n    yearlyPrice: 23,\n    features: [\n      '40,000 Words / Month',\n      'Unlimited Requests',\n      'Priority Support',\n      'Advanced Analytics',\n    ],\n    buttonText: 'Subscribe',\n    popular: true,\n  },\n  {\n    name: 'Enterprise',\n    description: 'For teams that need full control and scale',\n    monthlyPrice: 79,\n    yearlyPrice: 63,\n    features: [\n      'Unlimited Words',\n      'Custom Integrations',\n      'Dedicated Manager',\n      'SLA Guarantee',\n    ],\n    buttonText: 'Contact Sales',\n    popular: false,\n  },\n];\n\nconst smoothEase = [0.25, 0.1, 0.25, 1] as const;\nconst GRADIENT = 'linear-gradient(135deg, #f43f5e, #fb923c)';\n\nexport default function PricingSwitch({\n  title = 'Simple, Transparent Pricing',\n  subtitle = 'Pricing',\n  description = 'Choose the plan that works best for you. Upgrade or downgrade at any time.',\n  tiers = defaultTiers,\n  className,\n}: PricingSwitchProps) {\n  const [isYearly, setIsYearly] = useState(false);\n\n  return (\n    <section\n      className={cn(\n        'relative bg-zinc-50 dark:bg-zinc-950 w-full overflow-hidden py-20',\n        className,\n      )}\n    >\n      <div className='mx-auto max-w-7xl px-4 sm:px-6'>\n        <div className='flex flex-col items-center text-center gap-4 mb-12'>\n          <motion.div\n            initial={{ opacity: 0, y: -12 }}\n            whileInView={{ opacity: 1, y: 0 }}\n            viewport={{ once: true }}\n            transition={{ duration: 0.8, ease: smoothEase }}\n            className='inline-flex items-center px-4 py-1.5 rounded-full bg-rose-500/10 border border-rose-400/30'\n          >\n            <span className='text-sm text-rose-500 font-medium'>\n              {subtitle}\n            </span>\n          </motion.div>\n\n          <motion.h2\n            initial={{ opacity: 0, y: 14 }}\n            whileInView={{ opacity: 1, y: 0 }}\n            viewport={{ once: true }}\n            transition={{ duration: 0.9, delay: 0.15, ease: smoothEase }}\n            className='text-4xl md:text-5xl lg:text-6xl font-bold text-zinc-900 dark:text-white'\n          >\n            {title}\n          </motion.h2>\n\n          <motion.p\n            initial={{ opacity: 0, y: 14 }}\n            whileInView={{ opacity: 1, y: 0 }}\n            viewport={{ once: true }}\n            transition={{ duration: 0.9, delay: 0.3, ease: smoothEase }}\n            className='text-lg text-zinc-500 dark:text-zinc-400 max-w-md'\n          >\n            {description}\n          </motion.p>\n\n          <motion.div\n            initial={{ opacity: 0, y: 14 }}\n            whileInView={{ opacity: 1, y: 0 }}\n            viewport={{ once: true }}\n            transition={{ duration: 0.9, delay: 0.4, ease: smoothEase }}\n            className='flex items-center bg-zinc-100 dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-full px-1 py-1 mt-2 gap-1'\n          >\n            {[\n              { label: 'Monthly', yearly: false },\n              { label: 'Yearly', yearly: true },\n            ].map(({ label, yearly }) => {\n              const isActive = isYearly === yearly;\n              return (\n                <button\n                  key={label}\n                  onClick={() => setIsYearly(yearly)}\n                  className='w-28 py-2 rounded-full text-sm font-semibold transition-colors duration-200 flex items-center justify-center gap-2'\n                >\n                  <span\n                    className={cn(\n                      'transition-colors duration-200',\n                      isActive\n                        ? 'text-zinc-900 dark:text-white'\n                        : 'text-zinc-400 dark:text-zinc-500',\n                    )}\n                  >\n                    {label}\n                  </span>\n                  {yearly && (\n                    <span className='inline-flex items-center px-2 py-0.5 rounded-full text-xs font-semibold bg-rose-100 text-rose-500 dark:bg-rose-500/20 dark:text-rose-400'>\n                      -20%\n                    </span>\n                  )}\n                </button>\n              );\n            })}\n          </motion.div>\n        </div>\n\n        <div className='grid grid-cols-1 sm:grid-cols-3 gap-6 max-w-5xl mx-auto items-center'>\n          {tiers.map((tier, index) => {\n            const price = isYearly ? tier.yearlyPrice : tier.monthlyPrice;\n            const isPopular = tier.popular;\n\n            return (\n              <motion.div\n                key={tier.name}\n                initial={{ opacity: 0, y: 28 }}\n                whileInView={{ opacity: 1, y: 0 }}\n                viewport={{ once: true }}\n                transition={{\n                  duration: 1.0,\n                  delay: 0.2 + index * 0.2,\n                  ease: smoothEase,\n                }}\n                className={cn('min-w-0', isPopular ? 'sm:-mt-6 sm:mb-6' : '')}\n              >\n                {isPopular ? (\n                  <div\n                    className='relative p-0.5 rounded-3xl'\n                    style={{ background: GRADIENT }}\n                  >\n                    <Card className='relative rounded-[22px] overflow-visible border-0 bg-white dark:bg-zinc-900'>\n                      <div\n                        className='absolute -top-px left-1/2 -translate-x-1/2 px-5 py-1.5 rounded-b-2xl text-white text-xs font-semibold tracking-wide whitespace-nowrap z-10'\n                        style={{ background: GRADIENT }}\n                      >\n                        Popular\n                      </div>\n\n                      <CardHeader className='px-6 pt-10 pb-0'>\n                        <CardTitle className='text-2xl font-bold text-zinc-900 dark:text-white mb-1'>\n                          {tier.name}\n                        </CardTitle>\n                        <CardDescription className='text-sm text-zinc-500 dark:text-zinc-400'>\n                          {tier.description}\n                        </CardDescription>\n\n                        <div className='border border-dashed border-zinc-300 dark:border-zinc-700 rounded-2xl px-4 py-3 mt-6 text-center'>\n                          <AnimatePresence mode='wait'>\n                            <motion.div\n                              key={`${tier.name}-${isYearly}`}\n                              initial={{ opacity: 0, y: -8 }}\n                              animate={{ opacity: 1, y: 0 }}\n                              exit={{ opacity: 0, y: 8 }}\n                              transition={{ duration: 0.35, ease: smoothEase }}\n                              className='flex items-baseline justify-center gap-1'\n                            >\n                              <span className='text-4xl font-bold text-zinc-900 dark:text-white'>\n                                ${price}\n                              </span>\n                              <span className='text-zinc-400 text-sm'>\n                                /month\n                              </span>\n                            </motion.div>\n                          </AnimatePresence>\n                          {isYearly && (\n                            <p className='text-xs text-zinc-400 mt-1'>\n                              billed annually\n                            </p>\n                          )}\n                        </div>\n                      </CardHeader>\n\n                      <CardContent className='px-6 pt-6 pb-8 flex flex-col gap-6'>\n                        <div className='flex flex-col gap-3'>\n                          {tier.features.map((feature, fi) => (\n                            <div key={fi} className='flex items-center gap-3'>\n                              <div\n                                className='w-5 h-5 rounded flex items-center justify-center shrink-0'\n                                style={{ background: GRADIENT }}\n                              >\n                                <Check\n                                  className='w-3 h-3 text-white'\n                                  strokeWidth={3}\n                                />\n                              </div>\n                              <span className='text-sm text-zinc-600 dark:text-zinc-400'>\n                                {feature}\n                              </span>\n                            </div>\n                          ))}\n                        </div>\n\n                        <Button\n                          className='w-full rounded-2xl h-11 font-semibold text-white text-sm hover:opacity-90 transition-opacity border-0'\n                          style={{ background: GRADIENT }}\n                        >\n                          {tier.buttonText}\n                        </Button>\n                      </CardContent>\n                    </Card>\n                  </div>\n                ) : (\n                  <Card className='rounded-3xl overflow-hidden border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 h-full'>\n                    <CardHeader className='px-6 pt-8 pb-0'>\n                      <CardTitle className='text-2xl font-bold text-zinc-900 dark:text-white mb-1'>\n                        {tier.name}\n                      </CardTitle>\n                      <CardDescription className='text-sm text-zinc-500 dark:text-zinc-400'>\n                        {tier.description}\n                      </CardDescription>\n\n                      <div className='border border-dashed border-zinc-200 dark:border-zinc-700 rounded-2xl px-4 py-3 mt-6 text-center'>\n                        <AnimatePresence mode='wait'>\n                          <motion.div\n                            key={`${tier.name}-${isYearly}`}\n                            initial={{ opacity: 0, y: -8 }}\n                            animate={{ opacity: 1, y: 0 }}\n                            exit={{ opacity: 0, y: 8 }}\n                            transition={{ duration: 0.35, ease: smoothEase }}\n                            className='flex items-baseline justify-center gap-1'\n                          >\n                            <span className='text-4xl font-bold text-zinc-900 dark:text-white'>\n                              ${price}\n                            </span>\n                            <span className='text-zinc-400 text-sm'>\n                              /month\n                            </span>\n                          </motion.div>\n                        </AnimatePresence>\n                        {isYearly && (\n                          <p className='text-xs text-zinc-400 mt-1'>\n                            billed annually\n                          </p>\n                        )}\n                      </div>\n                    </CardHeader>\n\n                    <CardContent className='px-6 pt-6 pb-8 flex flex-col gap-6'>\n                      <div className='flex flex-col gap-3'>\n                        {tier.features.map((feature, fi) => (\n                          <div key={fi} className='flex items-center gap-3'>\n                            <div className='w-5 h-5 rounded bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center shrink-0'>\n                              <Check\n                                className='w-3 h-3 text-zinc-500 dark:text-zinc-400'\n                                strokeWidth={3}\n                              />\n                            </div>\n                            <span className='text-sm text-zinc-600 dark:text-zinc-400'>\n                              {feature}\n                            </span>\n                          </div>\n                        ))}\n                      </div>\n\n                      <Button\n                        className='w-full rounded-2xl h-11 font-semibold text-sm bg-zinc-900 hover:bg-zinc-800 dark:bg-zinc-800 dark:hover:bg-zinc-700 text-white transition-colors'\n                        variant='default'\n                      >\n                        {tier.buttonText}\n                      </Button>\n                    </CardContent>\n                  </Card>\n                )}\n              </motion.div>\n            );\n          })}\n        </div>\n      </div>\n    </section>\n  );\n}"
    }
  ]
}
