{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "features-03",
  "title": "Features · 03",
  "description": "Features · 03 section.",
  "dependencies": [
    "framer-motion",
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/talizen/features/features-03/features-03.tsx",
      "content": "import { useRef, useState, type WheelEvent } from \"react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport {\n  BadgeCheck,\n  Building2,\n  Code2,\n  PanelsTopLeft,\n  Ship,\n  ShoppingBag,\n  Sparkles,\n  type LucideIcon,\n} from \"lucide-react\"\n\ntype FeatureItem = {\n  id: string\n  label: string\n  eyebrow: string\n  title: string\n  description: string\n  icon: LucideIcon\n  image: string\n  imagePosition?: string\n  backdrop: string\n}\n\nconst featureItems: FeatureItem[] = [\n  {\n    id: \"editorial\",\n    label: \"Editorial\",\n    eyebrow: \"PERSONAL STORIES\",\n    title: \"Make every point of view feel cinematic.\",\n    description: \"Shape thoughtful portfolios, journals, and personal sites around your strongest visual narrative.\",\n    icon: Sparkles,\n    image:\n      \"https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=2200&q=86\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_18%_44%,rgba(78,92,126,0.42),transparent_30%),radial-gradient(circle_at_76%_24%,rgba(71,112,126,0.3),transparent_34%),linear-gradient(135deg,#090b12_0%,#141824_50%,#0b0d13_100%)]\",\n  },\n  {\n    id: \"brand\",\n    label: \"Brand sites\",\n    eyebrow: \"BRAND EXPERIENCES\",\n    title: \"Turn a bold identity into a memorable world.\",\n    description: \"Pair expressive art direction with clear storytelling for launches, campaigns, and brand moments.\",\n    icon: BadgeCheck,\n    image:\n      \"https://images.unsplash.com/photo-1557683316-973673baf926?auto=format&fit=crop&w=2200&q=86\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_22%_45%,rgba(112,76,154,0.4),transparent_32%),radial-gradient(circle_at_78%_24%,rgba(195,104,85,0.28),transparent_35%),linear-gradient(135deg,#100b17_0%,#21172a_52%,#0c0b10_100%)]\",\n  },\n  {\n    id: \"corporate\",\n    label: \"Company\",\n    eyebrow: \"COMPANY WEBSITES\",\n    title: \"Build trust before the first conversation.\",\n    description: \"Present your team, work, and expertise through an editorial experience designed for credibility.\",\n    icon: Building2,\n    image:\n      \"https://images.unsplash.com/photo-1497366754035-f200968a6e72?auto=format&fit=crop&w=2200&q=86\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_18%_45%,rgba(48,66,96,0.5),transparent_34%),radial-gradient(circle_at_76%_28%,rgba(200,158,76,0.2),transparent_33%),linear-gradient(135deg,#08111f_0%,#182339_54%,#090d16_100%)]\",\n  },\n  {\n    id: \"global\",\n    label: \"Global\",\n    eyebrow: \"GLOBAL LAUNCHES\",\n    title: \"Speak clearly to audiences everywhere.\",\n    description: \"Create focused multilingual experiences that carry your story confidently across markets.\",\n    icon: Ship,\n    image:\n      \"https://images.unsplash.com/photo-1461749280684-dccba630e2f6?auto=format&fit=crop&w=2200&q=86\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_21%_42%,rgba(42,125,136,0.38),transparent_32%),radial-gradient(circle_at_78%_31%,rgba(199,88,48,0.24),transparent_34%),linear-gradient(135deg,#071117_0%,#142931_50%,#0b0d10_100%)]\",\n  },\n  {\n    id: \"commerce\",\n    label: \"Commerce\",\n    eyebrow: \"COMMERCE EXPERIENCES\",\n    title: \"Give every product room to be desired.\",\n    description: \"Blend tactile imagery, considered details, and frictionless discovery into a modern storefront.\",\n    icon: ShoppingBag,\n    image:\n      \"https://images.unsplash.com/photo-1441986300917-64674bd600d8?auto=format&fit=crop&w=2200&q=86\",\n    imagePosition: \"object-center\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_20%_46%,rgba(186,112,62,0.38),transparent_31%),radial-gradient(circle_at_78%_26%,rgba(229,184,114,0.22),transparent_34%),linear-gradient(135deg,#130d0b_0%,#271815_52%,#0d0c0b_100%)]\",\n  },\n  {\n    id: \"tools\",\n    label: \"Digital tools\",\n    eyebrow: \"DIGITAL PRODUCTS\",\n    title: \"Make powerful software feel effortless.\",\n    description: \"Explain complex products with simple flows, sharp hierarchy, and just enough personality.\",\n    icon: Code2,\n    image:\n      \"https://images.unsplash.com/photo-1555066931-4365d14bab8c?auto=format&fit=crop&w=2200&q=86\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_20%_44%,rgba(41,133,119,0.38),transparent_31%),radial-gradient(circle_at_78%_26%,rgba(70,97,145,0.26),transparent_34%),linear-gradient(135deg,#061114_0%,#112526_52%,#080d11_100%)]\",\n  },\n  {\n    id: \"platforms\",\n    label: \"Platforms\",\n    eyebrow: \"CONNECTED PLATFORMS\",\n    title: \"Bring every workflow into one clear view.\",\n    description: \"Design focused dashboards and internal platforms that help teams move with confidence.\",\n    icon: PanelsTopLeft,\n    image:\n      \"https://images.unsplash.com/photo-1556761175-b413da4baf72?auto=format&fit=crop&w=2200&q=86\",\n    backdrop:\n      \"bg-[radial-gradient(circle_at_20%_44%,rgba(55,91,142,0.4),transparent_33%),radial-gradient(circle_at_78%_25%,rgba(91,118,151,0.24),transparent_34%),linear-gradient(135deg,#08101b_0%,#14233b_52%,#080b10_100%)]\",\n  },\n]\n\nconst visibleOffsets = [-2, -1, 0, 1, 2]\nconst offsetY = [-196, -98, 0, 98, 196]\n\nfunction getWrappedIndex(step: number) {\n  return (step % featureItems.length + featureItems.length) % featureItems.length\n}\n\nexport default function Features03({ className = \"\" }: { className?: string }) {\n  const [activeStep, setActiveStep] = useState(2)\n  const wheelLock = useRef<ReturnType<typeof setTimeout> | null>(null)\n  const activeItem = featureItems[getWrappedIndex(activeStep)]\n\n  const handleWheel = (event: WheelEvent<HTMLElement>) => {\n    if (Math.abs(event.deltaY) < 18 || wheelLock.current) return\n    setActiveStep((current) => current + (event.deltaY > 0 ? 1 : -1))\n    wheelLock.current = setTimeout(() => {\n      wheelLock.current = null\n    }, 420)\n  }\n\n  return (\n    <section\n      className={`relative isolate min-h-dvh w-full overflow-hidden bg-[#090b10] text-white lg:min-h-[760px] ${className}`}\n      aria-label=\"Website experience showcase\"\n      onWheel={handleWheel}\n      onKeyDown={(event) => {\n        if (event.key === \"ArrowDown\" || event.key === \"ArrowRight\") {\n          event.preventDefault()\n          setActiveStep((current) => current + 1)\n        }\n        if (event.key === \"ArrowUp\" || event.key === \"ArrowLeft\") {\n          event.preventDefault()\n          setActiveStep((current) => current - 1)\n        }\n      }}\n      tabIndex={0}\n    >\n      <AnimatePresence mode=\"sync\">\n        <motion.div\n          key={activeItem.id}\n          initial={{ opacity: 0 }}\n          animate={{ opacity: 1 }}\n          exit={{ opacity: 0 }}\n          transition={{ duration: 0.7, ease: [0.23, 1, 0.32, 1] }}\n          className={`pointer-events-none absolute inset-0 ${activeItem.backdrop}`}\n          aria-hidden=\"true\"\n        />\n      </AnimatePresence>\n      <div className=\"pointer-events-none absolute inset-0 bg-black/25\" aria-hidden=\"true\" />\n      <div\n        className=\"pointer-events-none absolute inset-0 opacity-25 [background-image:linear-gradient(rgba(255,255,255,0.025)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.025)_1px,transparent_1px)] [background-size:52px_52px] [mask-image:radial-gradient(circle_at_58%_50%,black,transparent_82%)]\"\n        aria-hidden=\"true\"\n      />\n\n      <div className=\"relative z-10 mx-auto flex min-h-dvh w-full max-w-[1440px] flex-col px-5 py-14 sm:px-8 lg:grid lg:min-h-[760px] lg:grid-cols-[330px_minmax(0,1fr)] lg:items-center lg:gap-8 lg:px-10 lg:py-10\">\n        <div className=\"mb-10 lg:hidden\">\n          <p className=\"text-[11px] font-semibold tracking-[0.22em] text-white/42\">EXPLORE BY FORMAT</p>\n          <div className=\"mt-5 flex gap-2 overflow-x-auto pb-2 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n            {featureItems.map((item, index) => {\n              const Icon = item.icon\n              const isActive = getWrappedIndex(activeStep) === index\n              return (\n                <button\n                  type=\"button\"\n                  key={item.id}\n                  onClick={() => setActiveStep(index)}\n                  aria-pressed={isActive}\n                  className={`inline-flex min-h-11 shrink-0 items-center gap-2 rounded-full border px-4 text-sm transition ${\n                    isActive\n                      ? \"border-white/24 bg-white/16 text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.2),0_12px_32px_rgba(0,0,0,0.22)]\"\n                      : \"border-white/10 bg-white/[0.055] text-white/48 hover:bg-white/10 hover:text-white/78\"\n                  }`}\n                >\n                  <Icon className=\"size-4\" strokeWidth={1.8} aria-hidden=\"true\" />\n                  {item.label}\n                </button>\n              )\n            })}\n          </div>\n        </div>\n\n        <div className=\"relative hidden h-[560px] lg:block\" aria-label=\"Choose a website format\">\n          <p className=\"absolute left-1/2 top-0 -translate-x-1/2 whitespace-nowrap text-[10px] font-semibold tracking-[0.22em] text-white/28\">\n            SCROLL TO EXPLORE\n          </p>\n          {visibleOffsets.map((offset, index) => {\n            const step = activeStep + offset\n            const item = featureItems[getWrappedIndex(step)]\n            const Icon = item.icon\n            const distance = Math.abs(offset)\n            const isActive = offset === 0\n\n            return (\n              <div\n                className=\"pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2\"\n                key={step}\n              >\n                <motion.button\n                  type=\"button\"\n                  onClick={() => setActiveStep(step)}\n                  initial={false}\n                  animate={{\n                    y: offsetY[index],\n                    scale: isActive ? 1 : distance === 1 ? 0.92 : 0.68,\n                    opacity: isActive ? 1 : distance === 1 ? 0.74 : 0.24,\n                    filter: `blur(${isActive ? 0 : distance === 1 ? 0.6 : 5}px)`,\n                  }}\n                  transition={{ type: \"spring\", stiffness: 340, damping: 34, mass: 0.8 }}\n                  aria-pressed={isActive}\n                  className={`pointer-events-auto flex w-[272px] cursor-pointer items-center justify-center rounded-full border text-white backdrop-blur-xl ${\n                    isActive\n                      ? \"h-[76px] gap-4 border-white/20 bg-[#4a4a4d]/90 px-6 shadow-[inset_0_1px_0_rgba(255,255,255,0.22),inset_0_-8px_18px_rgba(0,0,0,0.16),0_14px_30px_rgba(0,0,0,0.34)] hover:bg-[#555558]/95\"\n                      : \"h-[62px] gap-3 border-white/12 bg-[#464649]/80 px-5 shadow-[inset_0_1px_0_rgba(255,255,255,0.16),0_10px_24px_rgba(0,0,0,0.25)] hover:bg-[#505053]/90\"\n                  }`}\n                >\n                  <Icon\n                    className={isActive ? \"size-7 text-white/84\" : \"size-5 text-white/44\"}\n                    strokeWidth={isActive ? 1.7 : 1.9}\n                    aria-hidden=\"true\"\n                  />\n                  <span className={`whitespace-nowrap leading-none ${isActive ? \"text-2xl\" : \"text-lg font-semibold\"}`}>\n                    {item.label}\n                  </span>\n                </motion.button>\n              </div>\n            )\n          })}\n        </div>\n\n        <div className=\"flex min-w-0 items-center justify-center lg:pl-2\">\n          <div className=\"relative aspect-[16/10] w-full max-w-[980px] overflow-hidden rounded-[26px] border border-white/12 bg-black/20 shadow-[0_35px_100px_rgba(0,0,0,0.45)]\">\n            <AnimatePresence mode=\"wait\">\n              <motion.img\n                key={activeItem.id}\n                src={activeItem.image}\n                alt=\"\"\n                initial={{ opacity: 0, filter: \"blur(12px)\", scale: 1.045 }}\n                animate={{ opacity: 1, filter: \"blur(0px)\", scale: 1 }}\n                exit={{ opacity: 0, filter: \"blur(10px)\", scale: 0.965 }}\n                transition={{ duration: 0.58, ease: [0.23, 1, 0.32, 1] }}\n                className={`absolute inset-0 h-full w-full object-cover ${activeItem.imagePosition ?? \"object-center\"}`}\n              />\n            </AnimatePresence>\n            <div\n              className=\"pointer-events-none absolute inset-0 bg-[linear-gradient(90deg,rgba(6,8,13,0.68)_0%,rgba(6,8,13,0.16)_53%,rgba(6,8,13,0.04)_100%),linear-gradient(0deg,rgba(6,8,13,0.72)_0%,transparent_58%)]\"\n              aria-hidden=\"true\"\n            />\n            <AnimatePresence mode=\"wait\">\n              <motion.div\n                key={`${activeItem.id}-copy`}\n                initial={{ opacity: 0, y: 20 }}\n                animate={{ opacity: 1, y: 0 }}\n                exit={{ opacity: 0, y: -12 }}\n                transition={{ duration: 0.48, ease: [0.23, 1, 0.32, 1] }}\n                className=\"absolute inset-x-0 bottom-0 max-w-[680px] p-6 sm:p-9 lg:p-12\"\n              >\n                <p className=\"text-[10px] font-semibold tracking-[0.22em] text-white/58\">{activeItem.eyebrow}</p>\n                <h2 className=\"mt-4 max-w-[560px] text-[31px] font-medium leading-[1.02] tracking-[-0.035em] sm:text-[42px] lg:text-[54px]\">\n                  {activeItem.title}\n                </h2>\n                <p className=\"mt-4 hidden max-w-[520px] text-sm leading-6 text-white/58 sm:block\">\n                  {activeItem.description}\n                </p>\n              </motion.div>\n            </AnimatePresence>\n            <a\n              href=\"https://unsplash.com\"\n              target=\"_blank\"\n              rel=\"noreferrer\"\n              className=\"absolute right-4 top-4 rounded-full border border-white/12 bg-black/25 px-3 py-1.5 text-[9px] font-medium tracking-[0.12em] text-white/52 backdrop-blur-md transition hover:bg-black/40 hover:text-white/82 sm:right-6 sm:top-6\"\n            >\n              PHOTO / UNSPLASH\n            </a>\n          </div>\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "features"
  ],
  "type": "registry:block"
}