{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"pricing-5","type":"registry:block","title":"Pricing 5","description":"","dependencies":["lucide-react","motion"],"registryDependencies":["https://www.diarmuradi.com/r/styles/base-nova/badge.json","https://www.diarmuradi.com/r/styles/base-nova/button.json","https://www.diarmuradi.com/r/styles/base-nova/fancy-button.json","https://www.diarmuradi.com/r/styles/base-nova/separator.json","https://www.diarmuradi.com/r/styles/base-nova/slider.json"],"files":[{"path":"pricing.tsx","type":"registry:block","content":"\"use client\"\n\nimport { useState } from \"react\"\nimport { AnimatePresence, motion, type Variants } from \"motion/react\"\n\nimport { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport { Separator } from \"@/components/ui/separator\"\nimport { Slider } from \"@/components/ui/slider\"\nimport { FancyButton } from \"@/components/fancy-button\"\nimport { ArrowUpRightIcon, CheckIcon } from 'lucide-react'\n\nconst animVariant: Variants = {\n  hidden: { opacity: 0, scaleY: 0.8, y: 8 },\n  visible: (i: number) => ({\n    opacity: 1,\n    scaleY: 1,\n    y: 0,\n    transition: {\n      delay: i * 0.02,\n      type: \"spring\",\n      damping: 20,\n      stiffness: 350,\n    },\n  }),\n}\n\ntype Tier = {\n  max: number\n  price: number\n  label: string\n}\n\nconst tiers: Tier[] = [\n  { max: 5, price: 19, label: \"Starter\" },\n  { max: 15, price: 59, label: \"Growth\" },\n  { max: 30, price: 119, label: \"Scale\" },\n  { max: 50, price: 199, label: \"Studio\" },\n]\n\nconst features = [\n  \"Unlimited video uploads\",\n  \"4K transcoding & delivery\",\n  \"Custom video player\",\n  \"Analytics & heatmaps\",\n  \"DRM content protection\",\n  \"Live streaming support\",\n  \"API & SDK access\",\n  \"Priority support (4h SLA)\",\n]\n\nexport function Pricing() {\n  const [seats, setSeats] = useState([10])\n\n  const currentTier =\n    tiers.find((t) => seats[0] <= t.max) ?? tiers[tiers.length - 1]\n\n  const priceChars = currentTier.price.toString().split(\"\")\n\n  return (\n    <section aria-label=\"Pricing\" className=\"mx-auto w-full max-w-2xl\">\n      <div className=\"flex flex-col items-center gap-8\">\n        <div className=\"flex flex-col items-center gap-4 text-center\">\n          <Badge variant=\"secondary\" className=\"h-7 w-fit\">\n            Video platform\n          </Badge>\n          <h2 className=\"text-4xl font-bold tracking-tight text-foreground sm:text-5xl\">\n            Stream, host, and scale video\n          </h2>\n          <p className=\"max-w-2xl text-lg text-muted-foreground\">\n            Slide to match your team size. Pricing adjusts in real-time, with no\n            overpaying, no hidden bandwidth fees.\n          </p>\n        </div>\n\n        <div className=\"w-full max-w-xl rounded-4xl bg-muted p-1\">\n          <div className=\"flex flex-col gap-8 rounded-3xl bg-card p-8 shadow-elevated-lg\">\n            <div className=\"flex flex-col gap-6\">\n              <div className=\"flex items-center justify-between\">\n                <h3 className=\"text-lg font-medium text-foreground\">\n                  Team members\n                </h3>\n                <Badge variant=\"secondary\">{currentTier.label}</Badge>\n              </div>\n\n              <Slider\n                value={seats}\n                onValueChange={(val) =>\n                  setSeats(Array.isArray(val) ? val : [val])\n                }\n                min={1}\n                max={50}\n                step={1}\n                className=\"w-full cursor-grab active:cursor-grabbing **:data-[slot=slider-thumb]:h-6.5 **:data-[slot=slider-thumb]:w-3 **:data-[slot=slider-thumb]:border-[3px] **:data-[slot=slider-thumb]:border-solid **:data-[slot=slider-thumb]:border-card **:data-[slot=slider-thumb]:bg-primary **:data-[slot=slider-thumb]:ring-0 **:data-[slot=slider-thumb]:hover:ring-0 **:data-[slot=slider-thumb]:focus-visible:ring-0 **:data-[slot=slider-thumb]:active:ring-0 **:data-[slot=slider-track]:h-2 **:data-[slot=slider-track]:bg-input/60\"\n              />\n\n              <div className=\"flex items-center justify-between text-sm text-muted-foreground\">\n                <span>1 seat</span>\n                <span className=\"font-medium text-foreground\">\n                  {seats[0]} {seats[0] === 1 ? \"seat\" : \"seats\"}\n                </span>\n                <span>50 seats</span>\n              </div>\n            </div>\n\n            <Separator className=\"bg-border/50\" />\n\n            <div className=\"flex flex-col items-center gap-2 text-center\">\n              <div className=\"flex items-baseline gap-1\">\n                <AnimatePresence mode=\"popLayout\">\n                  <span\n                    key=\"currency\"\n                    className=\"text-7xl font-semibold tracking-tight text-foreground\"\n                  >\n                    $\n                  </span>\n                  {priceChars.map((char, idx) => (\n                    <motion.span\n                      key={`${currentTier.price}-${idx}`}\n                      variants={animVariant}\n                      initial=\"hidden\"\n                      animate=\"visible\"\n                      custom={idx}\n                      className=\"inline-block origin-bottom text-7xl font-semibold tracking-tight text-foreground\"\n                    >\n                      {char}\n                    </motion.span>\n                  ))}\n                </AnimatePresence>\n                <span key=\"period\" className=\"text-xl text-muted-foreground\">\n                  /month\n                </span>\n              </div>\n              <p className=\"text-sm text-muted-foreground\">\n                ${(currentTier.price / seats[0]).toFixed(2)} per seat · billed\n                monthly\n              </p>\n            </div>\n\n            <FancyButton size=\"lg\" className=\"group w-full\">\n              Start free trial\n              <ArrowUpRightIcon  className=\"transition-transform duration-300 group-hover:scale-110\" />\n            </FancyButton>\n\n            <Separator className=\"bg-border/50\" />\n\n            <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n              {features.map((feature) => (\n                <div key={feature} className=\"flex items-start gap-3\">\n                  <div className=\"mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full bg-primary\">\n                    <CheckIcon  className=\"size-3 text-primary-foreground\" />\n                  </div>\n                  <span className=\"text-sm text-muted-foreground\">\n                    {feature}\n                  </span>\n                </div>\n              ))}\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  )\n}","target":"components/pricing.tsx"}]}