{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <educlopez93@gmail.com>","css":{},"dependencies":["motion"],"description":"Modern pricing block with three tiers","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport SmoothButton from \"@/components/smoothui/smooth-button\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nconst CARD_ANIMATION_DELAY = 0.1;\n\ninterface PriceFlowProps {\n  className?: string;\n  value: number;\n}\n\nfunction PriceFlow({ value, className = \"\" }: PriceFlowProps) {\n  const [prevValue, setPrevValue] = useState(value);\n  const prevTensRef = useRef<HTMLSpanElement>(null);\n  const nextTensRef = useRef<HTMLSpanElement>(null);\n  const prevOnesRef = useRef<HTMLSpanElement>(null);\n  const nextOnesRef = useRef<HTMLSpanElement>(null);\n\n  useEffect(() => {\n    if (value !== prevValue) {\n      const prevTens = prevTensRef.current;\n      const nextTens = nextTensRef.current;\n      const prevOnes = prevOnesRef.current;\n      const nextOnes = nextOnesRef.current;\n\n      if (\n        prevTens &&\n        nextTens &&\n        Math.floor(value / 10) !== Math.floor(prevValue / 10)\n      ) {\n        if (Math.floor(value / 10) > Math.floor(prevValue / 10)) {\n          prevTens.classList.add(\"slide-out-up\");\n          nextTens.classList.add(\"slide-in-up\");\n        } else {\n          prevTens.classList.add(\"slide-out-down\");\n          nextTens.classList.add(\"slide-in-down\");\n        }\n\n        const handleTensAnimationEnd = () => {\n          prevTens.classList.remove(\"slide-out-up\", \"slide-out-down\");\n          nextTens.classList.remove(\"slide-in-up\", \"slide-in-down\");\n          prevTens.removeEventListener(\"animationend\", handleTensAnimationEnd);\n        };\n\n        prevTens.addEventListener(\"animationend\", handleTensAnimationEnd);\n      }\n\n      if (prevOnes && nextOnes && value % 10 !== prevValue % 10) {\n        setTimeout(() => {\n          if (value % 10 > prevValue % 10) {\n            prevOnes.classList.add(\"slide-out-up\");\n            nextOnes.classList.add(\"slide-in-up\");\n          } else {\n            prevOnes.classList.add(\"slide-out-down\");\n            nextOnes.classList.add(\"slide-in-down\");\n          }\n\n          const handleOnesAnimationEnd = () => {\n            prevOnes.classList.remove(\"slide-out-up\", \"slide-out-down\");\n            nextOnes.classList.remove(\"slide-in-up\", \"slide-in-down\");\n            prevOnes.removeEventListener(\n              \"animationend\",\n              handleOnesAnimationEnd\n            );\n          };\n\n          prevOnes.addEventListener(\"animationend\", handleOnesAnimationEnd);\n        }, 50);\n      }\n\n      setPrevValue(value);\n    }\n  }, [value, prevValue]);\n\n  const formatValue = (val: number) => val.toString().padStart(2, \"0\");\n  const prevFormatted = formatValue(prevValue);\n  const currentFormatted = formatValue(value);\n\n  return (\n    <span className={cn(\"relative inline-flex items-center\", className)}>\n      <span className=\"relative inline-block overflow-hidden\">\n        <span\n          className=\"absolute inset-0 flex items-center justify-center\"\n          ref={prevTensRef}\n          style={{ transform: \"translateY(-100%)\" }}\n        >\n          {prevFormatted[0]}\n        </span>\n        <span\n          className=\"flex items-center justify-center\"\n          ref={nextTensRef}\n          style={{ transform: \"translateY(0%)\" }}\n        >\n          {currentFormatted[0]}\n        </span>\n      </span>\n      <span className=\"relative inline-block overflow-hidden\">\n        <span\n          className=\"absolute inset-0 flex items-center justify-center\"\n          ref={prevOnesRef}\n          style={{ transform: \"translateY(-100%)\" }}\n        >\n          {prevFormatted[1]}\n        </span>\n        <span\n          className=\"flex items-center justify-center\"\n          ref={nextOnesRef}\n          style={{ transform: \"translateY(0%)\" }}\n        >\n          {currentFormatted[1]}\n        </span>\n      </span>\n    </span>\n  );\n}\n\nexport function PricingModern() {\n  const shouldReduceMotion = useReducedMotion();\n  const [isAnnual, setIsAnnual] = useState(true);\n\n  return (\n    <section>\n      <div className=\"relative bg-muted/50 py-16 md:py-32\">\n        <div className=\"mx-auto max-w-5xl px-6\">\n          <div className=\"mx-auto max-w-2xl text-center\">\n            <h2 className=\"text-balance font-bold text-3xl md:text-4xl lg:text-5xl lg:tracking-tight\">\n              Choose your perfect plan\n            </h2>\n            <p className=\"mx-auto mt-4 max-w-xl text-balance text-foreground/70 text-lg\">\n              Modern pricing plans designed for teams of all sizes. Scale your\n              business with confidence.\n            </p>\n            <div className=\"my-12\">\n              <div\n                className=\"relative mx-auto grid w-fit grid-cols-2 rounded-full border bg-background p-1 *:block *:h-8 *:w-24 *:rounded-full *:text-foreground *:text-sm *:hover:opacity-75\"\n                data-period={isAnnual ? \"annually\" : \"monthly\"}\n              >\n                <div\n                  aria-hidden=\"true\"\n                  className={`pointer-events-none absolute inset-1 w-1/2 rounded-full border border-transparent bg-brand shadow ring-1 ring-foreground/5 transition-transform duration-500 ease-in-out ${\n                    isAnnual ? \"translate-x-full\" : \"translate-x-0\"\n                  }`}\n                />\n                <button\n                  className=\"relative duration-500 data-[active=true]:font-medium data-[active=true]:text-white\"\n                  data-active={!isAnnual}\n                  onClick={() => setIsAnnual(false)}\n                  type=\"button\"\n                >\n                  Monthly\n                </button>\n                <button\n                  className=\"relative duration-500 data-[active=true]:font-medium data-[active=true]:text-white\"\n                  data-active={isAnnual}\n                  onClick={() => setIsAnnual(true)}\n                  type=\"button\"\n                >\n                  Annually\n                </button>\n              </div>\n            </div>\n          </div>\n          <div className=\"container\">\n            <div className=\"mx-auto max-w-6xl\">\n              <div className=\"grid grid-cols-1 gap-6 *:p-8 md:grid-cols-3\">\n                {/* Basic Plan */}\n                <motion.div\n                  animate={\n                    shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n                  }\n                  className=\"group relative flex h-[650px] cursor-pointer flex-col overflow-hidden rounded-2xl border bg-background p-8\"\n                  data-animate-card\n                  initial={\n                    shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 40 }\n                  }\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : { duration: 0.3, ease: [0.22, 1, 0.36, 1] }\n                  }\n                >\n                  <div className=\"card-content relative z-10 flex h-full flex-col\">\n                    {/* Title */}\n                    <h3 className=\"mb-4 font-bold text-2xl text-foreground\">\n                      Basic\n                    </h3>\n                    {/* Price & Duration */}\n                    <div className=\"mb-6\">\n                      <span className=\"font-semibold text-3xl text-foreground\">\n                        <PriceFlow value={isAnnual ? 10 : 15} />€\n                      </span>\n                      <span className=\"mx-2 text-foreground/70\">•</span>\n                      <span className=\"text-foreground/70\">\n                        Perfect for startups\n                      </span>\n                    </div>\n                    {/* CTA Button */}\n                    <SmoothButton className=\"mb-6 w-full\" variant=\"outline\">\n                      Get Started\n                    </SmoothButton>\n                    {/* Description */}\n                    <p className=\"mb-6 flex-grow text-foreground/70 text-sm leading-relaxed\">\n                      Essential features for growing businesses. Get started\n                      with everything you need to launch your project.\n                    </p>\n                    {/* What's Included */}\n                    <div className=\"space-y-4\">\n                      <h4 className=\"font-medium text-foreground/70 text-xs uppercase tracking-wider\">\n                        What&apos;s included:\n                      </h4>\n                      <ul className=\"space-y-3\">\n                        {[\n                          \"1 Project\",\n                          \"Email Support\",\n                          \"Core Features\",\n                          \"Basic Analytics\",\n                          \"Standard Security\",\n                          \"Community Access\",\n                        ].map((item) => (\n                          <li\n                            className=\"flex items-center gap-3 text-foreground text-sm\"\n                            key={item}\n                          >\n                            <div className=\"flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-foreground\">\n                              <svg\n                                aria-hidden=\"true\"\n                                className=\"h-2 w-2 text-background\"\n                                fill=\"currentColor\"\n                                viewBox=\"0 0 20 20\"\n                              >\n                                <path\n                                  clipRule=\"evenodd\"\n                                  d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n                                  fillRule=\"evenodd\"\n                                />\n                              </svg>\n                            </div>\n                            {item}\n                          </li>\n                        ))}\n                      </ul>\n                    </div>\n                  </div>\n                </motion.div>\n                {/* Pro Plan (Featured) */}\n                <motion.div\n                  animate={\n                    shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n                  }\n                  className=\"group relative flex h-[650px] cursor-pointer flex-col overflow-hidden rounded-2xl border bg-primary p-8\"\n                  data-animate-card\n                  initial={\n                    shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 40 }\n                  }\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : {\n                          delay: CARD_ANIMATION_DELAY,\n                          duration: 0.3,\n                          ease: [0.22, 1, 0.36, 1],\n                        }\n                  }\n                >\n                  {/* Gradient Accent */}\n                  <div className=\"gradient-accent absolute top-0 right-0 h-4 w-32 rounded-bl-2xl bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400\" />\n\n                  <div className=\"card-content relative z-10 flex h-full flex-col\">\n                    {/* Title */}\n                    <h3 className=\"mb-4 flex items-center gap-2 font-bold text-2xl text-foreground\">\n                      Pro{\" \"}\n                      <div className=\"rounded-full bg-brand px-2 py-1 font-bold text-white text-xs\">\n                        Most Popular\n                      </div>\n                    </h3>\n                    {/* Price & Duration */}\n                    <div className=\"mb-6\">\n                      <span className=\"font-semibold text-3xl text-foreground\">\n                        <PriceFlow value={isAnnual ? 25 : 35} />€\n                      </span>\n                      <span className=\"mx-2 text-foreground/70\">•</span>\n                      <span className=\"text-foreground/70\">Best for teams</span>\n                    </div>\n                    {/* CTA Button */}\n                    <SmoothButton className=\"mb-6 w-full\" variant=\"candy\">\n                      Get Started\n                    </SmoothButton>\n                    {/* Description */}\n                    <p className=\"mb-6 flex-grow text-foreground/70 text-sm leading-relaxed\">\n                      Advanced features for professional teams. Everything you\n                      need to scale your business with confidence.\n                    </p>\n                    {/* What's Included */}\n                    <div className=\"space-y-4\">\n                      <h4 className=\"font-medium text-foreground/70 text-xs uppercase tracking-wider\">\n                        What&apos;s included:\n                      </h4>\n                      <ul className=\"space-y-3\">\n                        {[\n                          \"Unlimited Projects\",\n                          \"Priority Support\",\n                          \"Team Collaboration\",\n                          \"Advanced Analytics\",\n                          \"Custom Integrations\",\n                          \"API Access\",\n                          \"White-label Options\",\n                          \"Priority Updates\",\n                        ].map((item) => (\n                          <li\n                            className=\"flex items-center gap-3 text-foreground text-sm\"\n                            key={item}\n                          >\n                            <div className=\"flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-foreground\">\n                              <svg\n                                aria-hidden=\"true\"\n                                className=\"h-2 w-2 text-background\"\n                                fill=\"currentColor\"\n                                viewBox=\"0 0 20 20\"\n                              >\n                                <path\n                                  clipRule=\"evenodd\"\n                                  d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n                                  fillRule=\"evenodd\"\n                                />\n                              </svg>\n                            </div>\n                            {item}\n                          </li>\n                        ))}\n                      </ul>\n                    </div>\n                  </div>\n                </motion.div>\n                {/* Enterprise Plan */}\n                <motion.div\n                  animate={\n                    shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n                  }\n                  className=\"group relative flex h-[650px] cursor-pointer flex-col overflow-hidden rounded-2xl border bg-background p-8\"\n                  data-animate-card\n                  initial={\n                    shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 40 }\n                  }\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : {\n                          delay: CARD_ANIMATION_DELAY * 2,\n                          duration: 0.3,\n                          ease: [0.22, 1, 0.36, 1],\n                        }\n                  }\n                >\n                  <div className=\"card-content relative z-10 flex h-full flex-col\">\n                    {/* Title */}\n                    <h3 className=\"mb-4 font-bold text-2xl text-foreground\">\n                      Enterprise\n                    </h3>\n                    {/* Price & Duration */}\n                    <div className=\"mb-6\">\n                      <span className=\"font-semibold text-3xl text-foreground\">\n                        Custom\n                      </span>\n                      <span className=\"mx-2 text-foreground/70\">•</span>\n                      <span className=\"text-foreground/70\">\n                        Tailored solutions\n                      </span>\n                    </div>\n                    {/* CTA Button */}\n                    <SmoothButton className=\"mb-6 w-full\" variant=\"outline\">\n                      Contact Sales\n                    </SmoothButton>\n                    {/* Description */}\n                    <p className=\"mb-6 flex-grow text-foreground/70 text-sm leading-relaxed\">\n                      Custom solutions for large organizations. Get dedicated\n                      support and tailored features for your enterprise needs.\n                    </p>\n                    {/* What's Included */}\n                    <div className=\"space-y-4\">\n                      <h4 className=\"font-medium text-foreground/70 text-xs uppercase tracking-wider\">\n                        What&apos;s included:\n                      </h4>\n                      <ul className=\"space-y-3\">\n                        {[\n                          \"Everything in Pro\",\n                          \"Dedicated Manager\",\n                          \"Custom Integrations\",\n                          \"SLA & Support\",\n                          \"On-premise Options\",\n                          \"Advanced Security\",\n                          \"Training & Onboarding\",\n                          \"24/7 Phone Support\",\n                        ].map((item) => (\n                          <li\n                            className=\"flex items-center gap-3 text-foreground text-sm\"\n                            key={item}\n                          >\n                            <div className=\"flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-foreground\">\n                              <svg\n                                aria-hidden=\"true\"\n                                className=\"h-2 w-2 text-background\"\n                                fill=\"currentColor\"\n                                viewBox=\"0 0 20 20\"\n                              >\n                                <path\n                                  clipRule=\"evenodd\"\n                                  d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n                                  fillRule=\"evenodd\"\n                                />\n                              </svg>\n                            </div>\n                            {item}\n                          </li>\n                        ))}\n                      </ul>\n                    </div>\n                  </div>\n                </motion.div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n\nexport default PricingModern;\n","path":"index.tsx","target":"components/smoothui/pricing-2/index.tsx","type":"registry:block"}],"name":"pricing-2","registryDependencies":["https://smoothui.dev/r/smooth-button.json","https://smoothui.dev/r/tokens.json"],"title":"Pricing 2","type":"registry:block"}