{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card-hover-expand",
  "type": "registry:block",
  "title": "Card Hover Expand",
  "description": "A card row where the hovered card grows wider, its photo fades in and the title drops to the bottom over a gradient. Every card stays expanded on small screens. Pure CSS.",
  "dependencies": [],
  "registryDependencies": [],
  "cssVars": {
    "theme": {}
  },
  "files": [
    {
      "path": "components/tweenui/card-hover-expand.tsx",
      "type": "registry:component",
      "target": "components/tweenui/card-hover-expand.tsx",
      "content": "'use client';\n\nimport { useState, type ComponentPropsWithoutRef } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface CardHoverExpandItem {\n  /** Large index shown in the corner, e.g. \".01\". */\n  step: string;\n  /** Small eyebrow above the title. */\n  label: string;\n  /** Card heading. */\n  title: string;\n  /** Photo revealed on the expanded card. */\n  image: string;\n  /** Alt text for the photo. */\n  imageAlt: string;\n}\n\nexport interface CardHoverExpandProps extends ComponentPropsWithoutRef<'div'> {\n  /** Cards in the row. Defaults to a 3-card sample. */\n  cards?: CardHoverExpandItem[];\n}\n\nconst DEFAULT_CARDS: CardHoverExpandItem[] = [\n  {\n    step: '.01',\n    label: 'Motion first',\n    title: 'Hover systems that feel native',\n    image: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=800&h=1000&fit=crop',\n    imageAlt: 'Team reviewing hover interactions on a whiteboard',\n  },\n  {\n    step: '.02',\n    label: 'Copy and own',\n    title: 'Drop in the source, keep the motion',\n    image: 'https://images.unsplash.com/photo-1517180102446-f3ece451e9d8?w=800&h=1000&fit=crop',\n    imageAlt: 'Developer working with component source in an editor',\n  },\n  {\n    step: '.03',\n    label: 'Ship ready',\n    title: 'Reduced-motion built in from the start',\n    image: 'https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=800&h=1000&fit=crop',\n    imageAlt: 'Team shipping a product together',\n  },\n];\n\nexport default function CardHoverExpand({\n  cards = DEFAULT_CARDS,\n  className,\n  ...props\n}: CardHoverExpandProps) {\n  const [activeIndex, setActiveIndex] = useState(0);\n\n  return (\n    <div\n      data-card-hover-expand\n      data-active-card={activeIndex}\n      className={cn(\n        'grid w-full grid-cols-1 gap-6 md:grid-cols-2 lg:flex lg:items-stretch lg:justify-center',\n        className\n      )}\n      {...props}\n    >\n      {cards.map((card, index) => {\n        const active = activeIndex === index;\n\n        return (\n          <article\n            key={card.step + card.title}\n            data-expand-card\n            data-active={active ? 'true' : undefined}\n            tabIndex={0}\n            onMouseEnter={() => setActiveIndex(index)}\n            onFocus={() => setActiveIndex(index)}\n            className={cn(\n              'relative h-[500px] w-full overflow-hidden rounded-2xl border border-[#045f64]/20 bg-white p-6 transition-all duration-700 ease-out outline-none motion-reduce:transition-none',\n              'focus-visible:ring-2 focus-visible:ring-[#045f64] dark:border-[#045f64]/40 dark:bg-[#12161F] dark:ring-offset-[#12161F]',\n              'lg:w-[28%]',\n              active && 'lg:w-[40%]'\n            )}\n          >\n            <figure\n              className={cn(\n                'absolute inset-0 size-full opacity-100 transition-opacity duration-700 ease-out motion-reduce:transition-none lg:opacity-0',\n                active && 'lg:opacity-100'\n              )}\n            >\n              <img src={card.image} alt={card.imageAlt} className=\"size-full object-cover\" />\n            </figure>\n            <div\n              className={cn(\n                'absolute inset-0 bg-linear-to-t from-black to-transparent to-55% opacity-100 transition-opacity duration-700 ease-out motion-reduce:transition-none lg:opacity-0',\n                active && 'lg:opacity-100'\n              )}\n            />\n            <div\n              className={cn(\n                'absolute top-6 left-6 z-30 max-w-[15rem] translate-y-[calc(500px-100%-5rem)] space-y-3 transition-transform duration-700 ease-out motion-reduce:transition-none lg:translate-y-0',\n                active && 'lg:translate-y-[calc(500px-100%-5rem)]'\n              )}\n            >\n              <p\n                className={cn(\n                  'text-sm text-[#c6f56f] transition-colors duration-500 motion-reduce:transition-none lg:text-[#045f64] dark:lg:text-[#9fd4d6]',\n                  active && 'lg:text-[#c6f56f] dark:lg:text-[#c6f56f]'\n                )}\n              >\n                {card.label}\n              </p>\n              <h3\n                className={cn(\n                  'text-lg font-medium text-white transition-colors duration-500 motion-reduce:transition-none md:text-xl lg:text-[#12161F] dark:lg:text-white',\n                  active && 'lg:text-white dark:lg:text-white'\n                )}\n              >\n                {card.title}\n              </h3>\n            </div>\n            <p\n              className={cn(\n                'absolute right-6 bottom-6 z-30 text-4xl font-medium text-white transition-colors duration-500 motion-reduce:transition-none md:text-5xl lg:text-[#12161F] dark:lg:text-white',\n                active && 'lg:text-white dark:lg:text-white'\n              )}\n            >\n              {card.step}\n            </p>\n          </article>\n        );\n      })}\n    </div>\n  );\n}\n"
    }
  ],
  "docs": "Docs, props and examples: https://tween-ui.vercel.app/block/card-hover-expand\nThe sample content loads images from images.unsplash.com. Replace them with your own before shipping."
}