{"version":1,"id":"product-grid-list","framework":"next","kind":"block","files":[{"path":"src/blocks/gfa/product-grid-list.tsx","content":"\"use client\";\n\nimport Image from \"next/image\";\nimport { ArrowUpRight } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type ProductGridItem = {\n  id: string;\n  brand: string;\n  category: string;\n  name: string;\n  price: string;\n  imageSrc: string;\n  imageAlt: string;\n  href?: string;\n};\n\nexport type ProductGridListProps = {\n  items: ProductGridItem[];\n  className?: string;\n};\n\nconst arrowBadgeClassName = cn(\n  \"pointer-events-none absolute right-4 top-4 z-10 flex size-8 items-center justify-center rounded-full\",\n  \"bg-background/90 text-muted-foreground shadow-sm ring-1 ring-border/50\",\n  \"transition-colors group-hover:bg-background group-hover:text-foreground\",\n  \"dark:bg-zinc-800 dark:text-zinc-300 dark:ring-zinc-700/60\",\n  \"group-hover:dark:bg-zinc-700 group-hover:dark:text-zinc-100\",\n);\n\nconst cardSurfaceClassName = cn(\n  \"group relative flex min-h-[300px] flex-col overflow-hidden rounded-2xl\",\n  \"bg-[oklch(0.93_0_0)]\",\n  \"dark:bg-[oklch(0.19_0_0)]\",\n);\n\nfunction ProductGridCard({ item }: { item: ProductGridItem }) {\n  const meta = `${item.brand} · ${item.category}`;\n  const linkLabel = `View ${item.name}`;\n  const isExternal = Boolean(item.href?.startsWith(\"http\"));\n\n  const content = (\n    <>\n      <span className={arrowBadgeClassName} aria-hidden>\n        <ArrowUpRight className=\"size-3.5\" strokeWidth={2} />\n      </span>\n\n      <div className=\"flex flex-1 items-center justify-center px-6 pb-2 pt-12\">\n        <div className=\"flex h-[180px] w-full max-w-[260px] items-center justify-center overflow-hidden rounded-xl bg-[oklch(0.92_0_0)] dark:bg-[oklch(0.21_0_0)]\">\n          <Image\n            src={item.imageSrc}\n            alt={item.href ? \"\" : item.imageAlt}\n            width={280}\n            height={200}\n            className=\"max-h-[168px] w-auto rounded-lg object-contain transition-transform duration-500 ease-out group-hover:scale-[1.03]\"\n            sizes=\"(max-width: 640px) 100vw, 260px\"\n          />\n        </div>\n      </div>\n\n      <div className=\"flex items-end justify-between gap-4 px-5 pb-5\">\n        <div className=\"min-w-0 space-y-1\">\n          <p className=\"truncate text-[13px] font-medium text-muted-foreground\">{meta}</p>\n          <p className=\"truncate text-[15px] font-semibold tracking-tight text-foreground\">{item.name}</p>\n        </div>\n        <p className=\"shrink-0 text-[15px] font-semibold tabular-nums tracking-tight text-foreground\">\n          {item.price}\n        </p>\n      </div>\n    </>\n  );\n\n  if (item.href) {\n    return (\n      <a\n        href={item.href}\n        target={isExternal ? \"_blank\" : undefined}\n        rel={isExternal ? \"noopener noreferrer\" : undefined}\n        aria-label={linkLabel}\n        className={cn(\n          cardSurfaceClassName,\n          \"cursor-pointer no-underline text-inherit\",\n          \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n        )}\n      >\n        {content}\n      </a>\n    );\n  }\n\n  return <article className={cardSurfaceClassName}>{content}</article>;\n}\n\nexport function ProductGridList({ items, className }: ProductGridListProps) {\n  return (\n    <ul\n      className={cn(\n        \"grid w-full list-none grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 lg:gap-5\",\n        className,\n      )}\n    >\n      {items.map((item) => (\n        <li key={item.id}>\n          <ProductGridCard item={item} />\n        </li>\n      ))}\n    </ul>\n  );\n}\n"}],"meta":{"studioName":"GFA Development & Design Studio","siteUrl":"https://ui.gkhn.dev"}}