{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gallery-4",
  "title": "Grayscale Mosaic With Lightbox",
  "description": "Photo mosaic in a fixed four-by-two grid whose tiles shift from grayscale to color on hover and open a lightbox with caption and location.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "badge",
    "dialog"
  ],
  "files": [
    {
      "path": "registry/blocks/gallery/4/gallery-block.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogTitle,\n} from \"@/components/ui/dialog\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\ntype Photo = {\n  id: number\n  src: string\n  title: string\n  location: string\n}\n\nconst photos: Photo[] = [\n  {\n    id: 1,\n    src: \"https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=1200&q=80\",\n    title: \"Financial District\",\n    location: \"New York, USA\",\n  },\n  {\n    id: 2,\n    src: \"https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=700&q=80\",\n    title: \"Alpine Fog\",\n    location: \"Grindelwald, CH\",\n  },\n  {\n    id: 3,\n    src: \"https://images.unsplash.com/photo-1500534623283-312aade485b7?w=700&q=80\",\n    title: \"Coastal Dunes\",\n    location: \"Jutland, DK\",\n  },\n  {\n    id: 4,\n    src: \"https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=700&q=80\",\n    title: \"Pine Canopy\",\n    location: \"Bavaria, DE\",\n  },\n  {\n    id: 5,\n    src: \"https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?w=700&q=80\",\n    title: \"Still Water\",\n    location: \"Hallstatt, AT\",\n  },\n]\n\nexport default function GalleryBlock() {\n  const [active, setActive] = React.useState<Photo | null>(null)\n\n  return (\n    <section className=\"flex min-h-svh w-full justify-center bg-background px-6 py-16 text-foreground\">\n      <div className=\"w-full max-w-4xl\">\n        <div className=\"mb-8 flex items-end justify-between gap-4\">\n          <div>\n            <Badge variant=\"secondary\">Field Notes</Badge>\n            <h2 className=\"mt-3 font-heading text-2xl font-bold tracking-tight text-balance sm:text-3xl\">\n              Selected Work\n            </h2>\n          </div>\n          <span className=\"text-sm text-muted-foreground tabular-nums\">\n            {photos.length} Photos\n          </span>\n        </div>\n\n        <Dialog\n          open={active !== null}\n          onOpenChange={(open) => !open && setActive(null)}\n        >\n          <div className=\"grid aspect-[3/2] grid-cols-4 grid-rows-2 gap-2\">\n            {photos.map((photo, index) => (\n              <button\n                key={photo.id}\n                type=\"button\"\n                onClick={() => setActive(photo)}\n                className={\n                  \"group relative overflow-hidden rounded-lg border border-border bg-muted \" +\n                  (index === 0 ? \"col-span-2 row-span-2\" : \"\")\n                }\n              >\n                <img\n                  src={photo.src}\n                  alt={photo.title}\n                  className=\"size-full object-cover grayscale transition-all duration-300 group-hover:grayscale-0\"\n                  loading=\"lazy\"\n                />\n                <span className=\"absolute inset-0 flex items-center justify-center bg-foreground/0 opacity-0 transition-opacity group-hover:bg-foreground/10 group-hover:opacity-100\">\n                  <span className=\"flex size-9 items-center justify-center rounded-md bg-background/90 text-foreground\">\n                    <IconPlaceholder\n                      lucide=\"ZoomIn\"\n                      tabler=\"IconZoomIn\"\n                      hugeicons=\"SearchAddIcon\"\n                      phosphor=\"MagnifyingGlassPlus\"\n                      remixicon=\"RiZoomInLine\"\n                      className=\"size-4\"\n                      aria-hidden=\"true\"\n                    />\n                  </span>\n                </span>\n              </button>\n            ))}\n          </div>\n\n          <DialogContent className=\"overflow-hidden p-0 sm:max-w-2xl\">\n            {active && (\n              <>\n                <div className=\"aspect-video w-full overflow-hidden bg-muted\">\n                  <img\n                    src={active.src}\n                    alt={active.title}\n                    className=\"size-full object-cover\"\n                  />\n                </div>\n                <div className=\"p-4 pt-0\">\n                  <DialogTitle className=\"text-base\">\n                    {active.title}\n                  </DialogTitle>\n                  <DialogDescription>{active.location}</DialogDescription>\n                </div>\n              </>\n            )}\n          </DialogContent>\n        </Dialog>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/gallery-4.tsx"
    }
  ],
  "meta": {
    "height": "837px",
    "tier": "free"
  },
  "categories": [
    "gallery"
  ],
  "type": "registry:block"
}