{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "property-listing-card",
  "title": "Property Listing Card",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/property-listing-card/PropertyListingCard.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  BadgeCheck,\n  Bath,\n  BedDouble,\n  Box,\n  Calculator,\n  Calendar,\n  Camera,\n  Check,\n  ChevronLeft,\n  ChevronRight,\n  Compass,\n  Heart,\n  Mail,\n  MapPin,\n  Maximize2,\n  Share2,\n} from 'lucide-react'\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Separator } from '@/components/ui/separator'\nimport { cn } from '@/lib/utils'\n\nexport interface PropertyItem {\n  id: string\n  title: string\n  propertyType: string\n  category: 'all' | 'single-family' | 'waterfront' | 'penthouse'\n  price: number\n  mortgageEst: string\n  address: {\n    street: string\n    cityStateZip: string\n    neighborhood: string\n  }\n  specs: {\n    beds: number\n    baths: number\n    sqft: number\n    pricePerSqft: number\n    yearBuilt: number\n    lotSize: string\n  }\n  badge: {\n    label: string\n    variant: 'default' | 'secondary' | 'outline' | 'destructive'\n  }\n  hasVirtualTour: boolean\n  openHouse: string\n  totalPhotos: number\n  images: string[]\n  tags: string[]\n  agent: {\n    name: string\n    brokerage: string\n    avatar: string\n    initials: string\n    badge: string\n  }\n}\n\nexport interface PropertyListingCardProps {\n  className?: string\n}\n\nconst PROPERTIES: PropertyItem[] = [\n  {\n    id: 'prop-pasadena',\n    title: 'Mid-Century Modern Architectural Sanctuary',\n    propertyType: 'Single Family Residence',\n    category: 'single-family',\n    price: 1245000,\n    mortgageEst: 'Est. $6,420 / mo',\n    address: {\n      street: '742 Evergreen Terrace',\n      cityStateZip: 'Pasadena, CA 91101',\n      neighborhood: 'San Rafael Hills',\n    },\n    specs: {\n      beds: 4,\n      baths: 3.5,\n      sqft: 2850,\n      pricePerSqft: 437,\n      yearBuilt: 1962,\n      lotSize: '0.34 Acres',\n    },\n    badge: {\n      label: 'New Listing',\n      variant: 'default',\n    },\n    hasVirtualTour: true,\n    openHouse: 'Open Sun 1:00 – 4:00 PM',\n    totalPhotos: 18,\n    images: [\n      'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600566753190-17f0baa2a6c3?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600566753086-00f18fb6b3ea?w=1200&auto=format&fit=crop&q=80',\n    ],\n    tags: ['Swimming Pool', 'Solar Panels', '2-Car Garage', 'Modern Kitchen', 'Mountain View'],\n    agent: {\n      name: 'Elena Rostova',\n      brokerage: \"Sotheby's International Realty\",\n      avatar: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=200&auto=format&fit=crop&q=80',\n      initials: 'ER',\n      badge: 'Top 1% Producer',\n    },\n  },\n  {\n    id: 'prop-carmel',\n    title: 'Coastal Craftsman Villa with Ocean Vista',\n    propertyType: 'Luxury Waterfront Estate',\n    category: 'waterfront',\n    price: 2890000,\n    mortgageEst: 'Est. $14,850 / mo',\n    address: {\n      street: '1840 Ocean View Avenue',\n      cityStateZip: 'Carmel-by-the-Sea, CA 93921',\n      neighborhood: 'Point Lobos Highlands',\n    },\n    specs: {\n      beds: 5,\n      baths: 4.5,\n      sqft: 4120,\n      pricePerSqft: 701,\n      yearBuilt: 2021,\n      lotSize: '0.52 Acres',\n    },\n    badge: {\n      label: 'Price Drop $100k',\n      variant: 'secondary',\n    },\n    hasVirtualTour: true,\n    openHouse: 'Private Viewings Only',\n    totalPhotos: 24,\n    images: [\n      'https://images.unsplash.com/photo-1512917774080-9991f1c4c750?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600210492486-724fe5c67fb0?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600585152220-90363fe7e115?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1584622650111-993a426fbf0a?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1600573472592-401b489a3cdc?w=1200&auto=format&fit=crop&q=80',\n    ],\n    tags: ['Ocean Frontage', 'Wine Cellar', 'Infinity Pool', 'Smart Automation', 'Chef Kitchen'],\n    agent: {\n      name: 'Marcus Vance',\n      brokerage: 'Compass Premier Collection',\n      avatar: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?w=200&auto=format&fit=crop&q=80',\n      initials: 'MV',\n      badge: 'Luxury Director',\n    },\n  },\n  {\n    id: 'prop-downtown',\n    title: 'Skyline Glass Penthouse & Private Terrace',\n    propertyType: 'High-Rise Penthouse Condo',\n    category: 'penthouse',\n    price: 895000,\n    mortgageEst: 'Est. $4,680 / mo',\n    address: {\n      street: '450 S Grand Avenue, Unit 38B',\n      cityStateZip: 'Los Angeles, CA 90071',\n      neighborhood: 'Bunker Hill Downtown',\n    },\n    specs: {\n      beds: 2,\n      baths: 2.0,\n      sqft: 1640,\n      pricePerSqft: 545,\n      yearBuilt: 2019,\n      lotSize: 'HOA $620 / mo',\n    },\n    badge: {\n      label: 'Just Listed',\n      variant: 'default',\n    },\n    hasVirtualTour: true,\n    openHouse: 'Open Sat 2:00 – 5:00 PM',\n    totalPhotos: 14,\n    images: [\n      'https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1556911220-e15b29be8c8f?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1513694203232-719a280e022f?w=1200&auto=format&fit=crop&q=80',\n      'https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=1200&auto=format&fit=crop&q=80',\n    ],\n    tags: ['Private Terrace', '24/7 Concierge', 'Floor-to-Ceiling Windows', 'EV Parking', 'Fitness Center'],\n    agent: {\n      name: 'Aria Chen',\n      brokerage: 'Coldwell Banker Global Luxury',\n      avatar: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=200&auto=format&fit=crop&q=80',\n      initials: 'AC',\n      badge: 'Downtown Specialist',\n    },\n  },\n]\n\nexport function PropertyListingCard({ className }: PropertyListingCardProps) {\n  const [activePhotoIndex, setActivePhotoIndex] = React.useState<Record<string, number>>({\n    'prop-pasadena': 0,\n    'prop-carmel': 0,\n    'prop-downtown': 0,\n  })\n  const [wishlistedIds, setWishlistedIds] = React.useState<Set<string>>(new Set(['prop-pasadena']))\n  const [scheduledTourIds, setScheduledTourIds] = React.useState<Set<string>>(new Set())\n  const [contactedAgentIds, setContactedAgentIds] = React.useState<Set<string>>(new Set())\n  const [copiedLinkId, setCopiedLinkId] = React.useState<string | null>(null)\n  const [activeCategoryFilter, setActiveCategoryFilter] = React.useState<string>('all')\n  const [activeTourModalId, setActiveTourModalId] = React.useState<string | null>(null)\n\n  const getPhotoIndex = (id: string): number => {\n    return activePhotoIndex[id] ?? 0\n  }\n\n  const prevPhoto = (id: string, total: number) => {\n    const current = getPhotoIndex(id)\n    setActivePhotoIndex((prev) => ({\n      ...prev,\n      [id]: (current - 1 + total) % total,\n    }))\n  }\n\n  const nextPhoto = (id: string, total: number) => {\n    const current = getPhotoIndex(id)\n    setActivePhotoIndex((prev) => ({\n      ...prev,\n      [id]: (current + 1) % total,\n    }))\n  }\n\n  const setPhoto = (id: string, index: number) => {\n    setActivePhotoIndex((prev) => ({\n      ...prev,\n      [id]: index,\n    }))\n  }\n\n  const toggleWishlist = (id: string) => {\n    setWishlistedIds((prev) => {\n      const next = new Set(prev)\n      if (next.has(id)) {\n        next.delete(id)\n      } else {\n        next.add(id)\n      }\n      return next\n    })\n  }\n\n  const isWishlisted = (id: string): boolean => {\n    return wishlistedIds.has(id)\n  }\n\n  const toggleScheduleTour = (id: string) => {\n    setScheduledTourIds((prev) => {\n      const next = new Set(prev)\n      if (next.has(id)) {\n        next.delete(id)\n      } else {\n        next.add(id)\n      }\n      return next\n    })\n  }\n\n  const isTourScheduled = (id: string): boolean => {\n    return scheduledTourIds.has(id)\n  }\n\n  const toggleContactAgent = (id: string) => {\n    setContactedAgentIds((prev) => {\n      const next = new Set(prev)\n      if (next.has(id)) {\n        next.delete(id)\n      } else {\n        next.add(id)\n      }\n      return next\n    })\n  }\n\n  const isAgentContacted = (id: string): boolean => {\n    return contactedAgentIds.has(id)\n  }\n\n  const shareListing = (id: string) => {\n    const url = `https://uipkge.dev/listings/${id}`\n    if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {\n      navigator.clipboard.writeText(url)\n    }\n    setCopiedLinkId(id)\n    setTimeout(() => {\n      setCopiedLinkId((curr) => (curr === id ? null : curr))\n    }, 2000)\n  }\n\n  const toggleVirtualTour = (id: string) => {\n    setActiveTourModalId((curr) => (curr === id ? null : id))\n  }\n\n  const formatPrice = (amount: number): string => {\n    return new Intl.NumberFormat('en-US', {\n      style: 'currency',\n      currency: 'USD',\n      maximumFractionDigits: 0,\n    }).format(amount)\n  }\n\n  const filteredProperties = React.useMemo(() => {\n    if (activeCategoryFilter === 'all') {\n      return PROPERTIES\n    }\n    return PROPERTIES.filter((p) => p.category === activeCategoryFilter)\n  }, [activeCategoryFilter])\n\n  return (\n    <section\n      data-slot=\"property-listing-card\"\n      className={cn('bg-background text-foreground w-full space-y-6', className)}\n    >\n      {/* Header & Category Switcher */}\n      <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div className=\"space-y-1\">\n          <div className=\"flex items-center gap-2.5\">\n            <h2 className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">Featured Property Listings</h2>\n            <Badge wrap variant=\"secondary\" className=\"text-xs font-normal tabular-nums\">\n              {filteredProperties.length} Active\n            </Badge>\n          </div>\n          <p className=\"text-muted-foreground text-xs sm:text-sm\">\n            Browse verified real estate properties with interactive photo galleries, mortgage calculations, and 3D\n            walkthroughs.\n          </p>\n        </div>\n\n        {/* Category Filter Pills */}\n        <div className=\"border-border/80 bg-muted/40 flex flex-wrap items-center gap-1.5 rounded-lg border p-1\">\n          <button\n            type=\"button\"\n            className={cn(\n              'focus-visible:ring-ring min-h-6 rounded-md px-3 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              activeCategoryFilter === 'all'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            )}\n            onClick={() => setActiveCategoryFilter('all')}\n          >\n            All Homes\n          </button>\n          <button\n            type=\"button\"\n            className={cn(\n              'focus-visible:ring-ring min-h-6 rounded-md px-3 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              activeCategoryFilter === 'single-family'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            )}\n            onClick={() => setActiveCategoryFilter('single-family')}\n          >\n            Single Family\n          </button>\n          <button\n            type=\"button\"\n            className={cn(\n              'focus-visible:ring-ring min-h-6 rounded-md px-3 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              activeCategoryFilter === 'waterfront'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            )}\n            onClick={() => setActiveCategoryFilter('waterfront')}\n          >\n            Waterfront\n          </button>\n          <button\n            type=\"button\"\n            className={cn(\n              'focus-visible:ring-ring min-h-6 rounded-md px-3 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              activeCategoryFilter === 'penthouse'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            )}\n            onClick={() => setActiveCategoryFilter('penthouse')}\n          >\n            Penthouse\n          </button>\n        </div>\n      </div>\n\n      {/* Properties Grid */}\n      <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3\">\n        {filteredProperties.map((prop) => {\n          const currentIndex = getPhotoIndex(prop.id)\n          const wishlisted = isWishlisted(prop.id)\n          const tourScheduled = isTourScheduled(prop.id)\n          const agentContacted = isAgentContacted(prop.id)\n          const copied = copiedLinkId === prop.id\n          const tourModalActive = activeTourModalId === prop.id\n\n          return (\n            <Card\n              key={prop.id}\n              className=\"group border-border bg-card hover:border-border/80 relative flex flex-col justify-between overflow-hidden rounded-xl border shadow-xs transition-colors duration-300 hover:shadow-md\"\n            >\n              {/* 1. Image Carousel Gallery Hero (16:9 Aspect Ratio) */}\n              <div className=\"bg-muted relative aspect-video w-full overflow-hidden\">\n                {/* Active Image */}\n                <img\n                  src={prop.images[currentIndex]}\n                  alt={`${prop.title} - Photo ${currentIndex + 1}`}\n                  className=\"size-full object-cover object-center transition-transform duration-500 ease-out group-hover:scale-105\"\n                  loading=\"lazy\"\n                />\n\n                {/* Gradient Overlays for High-Contrast Readable Badges */}\n                <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-black/75 via-black/15 to-black/60\" />\n\n                {/* Top Overlay: Badges and Wishlist Button */}\n                <div className=\"absolute inset-x-3 top-3 z-10 flex items-start justify-between gap-2\">\n                  <div className=\"flex flex-wrap items-center gap-1.5\">\n                    <Badge wrap variant={prop.badge.variant} className=\"text-xs font-semibold shadow-xs\">\n                      {\n                        {\n                          default: prop.badge.label,\n                          secondary: prop.badge.label,\n                          outline: prop.badge.label,\n                          destructive: prop.badge.label,\n                        }[prop.badge.variant]\n                      }\n                    </Badge>\n                    {prop.hasVirtualTour && (\n                      <button\n                        type=\"button\"\n                        className=\"inline-flex min-h-6 items-center gap-1 rounded-full border border-white/25 bg-black/60 px-2.5 py-0.5 text-xs font-medium text-white shadow-xs backdrop-blur-md transition-colors hover:bg-black/80 focus-visible:ring-2 focus-visible:ring-white focus-visible:outline-none\"\n                        title={tourModalActive ? 'Exit 3D Tour Mode' : 'Explore 3D Virtual Tour'}\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          toggleVirtualTour(prop.id)\n                        }}\n                      >\n                        <Box className=\"text-success size-3\" />\n                        <span>Virtual Tour 3D</span>\n                      </button>\n                    )}\n                  </div>\n\n                  {/* Wishlist Heart Button */}\n                  <button\n                    type=\"button\"\n                    aria-label=\"Save property to wishlist\"\n                    className={cn(\n                      'flex size-8 shrink-0 items-center justify-center rounded-full border border-white/20 bg-black/50 text-white shadow-xs backdrop-blur-md transition-colors hover:bg-black/75 focus-visible:ring-2 focus-visible:ring-white focus-visible:outline-none',\n                      wishlisted ? 'text-destructive hover:text-destructive' : 'text-white',\n                    )}\n                    onClick={(e) => {\n                      e.stopPropagation()\n                      toggleWishlist(prop.id)\n                    }}\n                  >\n                    <Heart className={cn('size-4', wishlisted ? 'fill-destructive text-destructive' : '')} />\n                  </button>\n                </div>\n\n                {/* Chevron Carousel Controls (Appear on hover or focus) */}\n                <button\n                  type=\"button\"\n                  aria-label=\"Previous property photo\"\n                  className=\"absolute top-1/2 left-2.5 z-10 flex size-8 -translate-y-1/2 items-center justify-center rounded-full border border-white/20 bg-black/55 text-white opacity-0 shadow-xs backdrop-blur-md transition-colors group-hover:opacity-100 hover:bg-black/80 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-white focus-visible:outline-none\"\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    prevPhoto(prop.id, prop.images.length)\n                  }}\n                >\n                  <ChevronLeft className=\"size-4\" />\n                </button>\n                <button\n                  type=\"button\"\n                  aria-label=\"Next property photo\"\n                  className=\"absolute top-1/2 right-2.5 z-10 flex size-8 -translate-y-1/2 items-center justify-center rounded-full border border-white/20 bg-black/55 text-white opacity-0 shadow-xs backdrop-blur-md transition-colors group-hover:opacity-100 hover:bg-black/80 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-white focus-visible:outline-none\"\n                  onClick={(e) => {\n                    e.stopPropagation()\n                    nextPhoto(prop.id, prop.images.length)\n                  }}\n                >\n                  <ChevronRight className=\"size-4\" />\n                </button>\n\n                {/* Bottom Hero Overlay: Photo Counter, Dots, and Open House Tag */}\n                <div className=\"absolute inset-x-3 bottom-3 z-10 flex items-center justify-between gap-2\">\n                  {/* Photo Counter Pill */}\n                  <span className=\"inline-flex items-center gap-1.5 rounded-full border border-white/20 bg-black/60 px-2.5 py-0.5 text-xs font-medium text-white tabular-nums backdrop-blur-md\">\n                    <Camera className=\"size-3 text-white/80\" />\n                    {currentIndex + 1} / {prop.totalPhotos} Photos\n                  </span>\n\n                  {/* Image Dots / Indicators */}\n                  <div className=\"flex items-center gap-1 rounded-full bg-black/40 px-2 py-1 backdrop-blur-xs\">\n                    {prop.images.map((_, index) => (\n                      <button\n                        key={index}\n                        type=\"button\"\n                        aria-label={`Jump to photo ${index + 1}`}\n                        className={cn(\n                          'rounded-full transition-colors focus-visible:ring-1 focus-visible:ring-white focus-visible:outline-none',\n                          currentIndex === index ? 'h-1.5 w-3.5 bg-white' : 'size-1.5 bg-white/50 hover:bg-white/80',\n                        )}\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          setPhoto(prop.id, index)\n                        }}\n                      />\n                    ))}\n                  </div>\n                </div>\n\n                {/* Virtual Tour Active Banner Callout */}\n                {tourModalActive && (\n                  <div className=\"absolute inset-0 z-20 flex flex-col items-center justify-center bg-black/85 p-4 text-center backdrop-blur-sm transition-colors\">\n                    <Compass className=\"text-success size-8 animate-spin\" />\n                    <h4 className=\"mt-2 text-sm font-semibold text-white\">3D Virtual Space Initialized</h4>\n                    <p className=\"mt-1 max-w-xs text-xs text-white/80\">\n                      Interactive 360° LiDAR spatial model active for {prop.address.street}.\n                    </p>\n                    <Button\n                      size=\"sm\"\n                      variant=\"secondary\"\n                      className=\"mt-3 text-xs\"\n                      onClick={(e) => {\n                        e.stopPropagation()\n                        setActiveTourModalId(null)\n                      }}\n                    >\n                      Close 3D View\n                    </Button>\n                  </div>\n                )}\n              </div>\n\n              {/* 2. Card Content & Specifications */}\n              <CardContent className=\"flex flex-1 flex-col justify-between space-y-4 p-5\">\n                <div className=\"space-y-3.5\">\n                  {/* Price & Mortgage Estimate Row */}\n                  <div className=\"flex flex-wrap items-start justify-between gap-3\">\n                    <div className=\"space-y-1\">\n                      <div className=\"flex items-baseline gap-2\">\n                        <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">\n                          {formatPrice(prop.price)}\n                        </span>\n                      </div>\n                      <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs font-normal tabular-nums\">\n                        <Calculator className=\"text-muted-foreground/80 size-3.5 shrink-0\" />\n                        <span>{prop.mortgageEst}</span>\n                      </div>\n                    </div>\n                    <Badge wrap variant=\"secondary\" className=\"shrink-0 text-xs font-normal\">\n                      {prop.propertyType}\n                    </Badge>\n                  </div>\n\n                  {/* Specs Pill Grid (Beds, Baths, SqFt, $/SqFt) */}\n                  <div className=\"grid grid-cols-4 gap-1.5 py-0.5\">\n                    {/* Beds */}\n                    <div className=\"border-border/60 bg-muted/40 flex flex-col items-center justify-center rounded-lg border p-2 text-center\">\n                      <div className=\"text-muted-foreground flex items-center gap-1\">\n                        <BedDouble className=\"size-3.5\" />\n                        <span className=\"text-foreground text-xs font-semibold tabular-nums\">{prop.specs.beds}</span>\n                      </div>\n                      <span className=\"text-muted-foreground text-xs\">Beds</span>\n                    </div>\n\n                    {/* Baths */}\n                    <div className=\"border-border/60 bg-muted/40 flex flex-col items-center justify-center rounded-lg border p-2 text-center\">\n                      <div className=\"text-muted-foreground flex items-center gap-1\">\n                        <Bath className=\"size-3.5\" />\n                        <span className=\"text-foreground text-xs font-semibold tabular-nums\">{prop.specs.baths}</span>\n                      </div>\n                      <span className=\"text-muted-foreground text-xs\">Baths</span>\n                    </div>\n\n                    {/* Sq Ft */}\n                    <div className=\"border-border/60 bg-muted/40 flex flex-col items-center justify-center rounded-lg border p-2 text-center\">\n                      <div className=\"text-muted-foreground flex items-center gap-1\">\n                        <Maximize2 className=\"size-3.5\" />\n                        <span className=\"text-foreground text-xs font-semibold tabular-nums\">\n                          {prop.specs.sqft.toLocaleString()}\n                        </span>\n                      </div>\n                      <span className=\"text-muted-foreground text-xs\">Sq Ft</span>\n                    </div>\n\n                    {/* Price Per Sq Ft */}\n                    <div className=\"border-border/60 bg-muted/40 flex flex-col items-center justify-center rounded-lg border p-2 text-center\">\n                      <div className=\"text-muted-foreground flex items-center gap-0.5\">\n                        <span className=\"text-foreground text-xs font-semibold tabular-nums\">\n                          ${prop.specs.pricePerSqft}\n                        </span>\n                      </div>\n                      <span className=\"text-muted-foreground text-xs\">/ sqft</span>\n                    </div>\n                  </div>\n\n                  {/* Address & Neighborhood */}\n                  <div className=\"space-y-1\">\n                    <h3\n                      className=\"text-foreground hover:text-primary line-clamp-1 cursor-pointer text-sm font-semibold tracking-tight transition-colors\"\n                      title={prop.address.street}\n                    >\n                      {prop.address.street}\n                    </h3>\n                    <p className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                      <MapPin className=\"text-muted-foreground/80 size-3.5 shrink-0\" />\n                      <span className=\"truncate\">{prop.address.cityStateZip}</span>\n                      <span>·</span>\n                      <span className=\"text-foreground/85 shrink-0 font-medium\">{prop.address.neighborhood}</span>\n                    </p>\n                  </div>\n\n                  {/* Key Features Tags */}\n                  <div className=\"flex flex-wrap gap-1.5 pt-0.5\">\n                    {prop.tags.map((tag) => (\n                      <Badge\n                        wrap\n                        key={tag}\n                        variant=\"outline\"\n                        className=\"border-border/70 bg-muted/30 text-muted-foreground hover:bg-muted/60 text-xs font-normal transition-colors\"\n                      >\n                        {tag}\n                      </Badge>\n                    ))}\n                  </div>\n                </div>\n\n                {/* Footer Area: Agent Attribution & Action Buttons */}\n                <div className=\"space-y-3.5 pt-2\">\n                  <Separator />\n\n                  {/* Agent / Broker Attribution */}\n                  <div className=\"flex items-center justify-between gap-3\">\n                    <div className=\"flex min-w-0 items-center gap-2.5\">\n                      <Avatar size=\"sm\" className=\"border-border size-8 border shadow-2xs\">\n                        <AvatarImage src={prop.agent.avatar} alt={prop.agent.name} />\n                        <AvatarFallback className=\"bg-primary/10 text-primary text-xs font-semibold\">\n                          {\n                            {\n                              fallback: prop.agent.initials,\n                            }.fallback\n                          }\n                        </AvatarFallback>\n                      </Avatar>\n                      <div className=\"min-w-0\">\n                        <p className=\"text-foreground flex items-center gap-1 truncate text-xs font-semibold\">\n                          <span>Listed by {prop.agent.name}</span>\n                          <BadgeCheck className=\"text-primary size-3 shrink-0\" />\n                        </p>\n                        <p className=\"text-muted-foreground truncate text-xs\">{prop.agent.brokerage}</p>\n                      </div>\n                    </div>\n\n                    {/* Share Action Button */}\n                    <Button\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className=\"text-muted-foreground hover:text-foreground size-8 shrink-0 rounded-full\"\n                      title={copied ? 'Listing link copied!' : 'Share listing'}\n                      onClick={() => shareListing(prop.id)}\n                    >\n                      {copied ? <Check className=\"text-success size-3.5\" /> : <Share2 className=\"size-3.5\" />}\n                      <span className=\"sr-only\">Share listing</span>\n                    </Button>\n                  </div>\n\n                  {/* Action Buttons: Schedule Tour & Contact Agent */}\n                  <div className=\"grid grid-cols-2 gap-2\">\n                    <Button\n                      size=\"sm\"\n                      className=\"w-full gap-1.5 text-xs font-medium shadow-xs\"\n                      variant={tourScheduled ? 'secondary' : 'default'}\n                      onClick={() => toggleScheduleTour(prop.id)}\n                    >\n                      {tourScheduled ? <Check className=\"text-success size-3.5\" /> : <Calendar className=\"size-3.5\" />}\n                      <span>{tourScheduled ? 'Tour Booked ✓' : 'Schedule Tour'}</span>\n                    </Button>\n\n                    <Button\n                      variant=\"outline\"\n                      size=\"sm\"\n                      className={cn(\n                        'w-full gap-1.5 text-xs font-medium',\n                        agentContacted ? 'border-success/50 bg-success/10 text-success' : '',\n                      )}\n                      onClick={() => toggleContactAgent(prop.id)}\n                    >\n                      {agentContacted ? <Check className=\"text-success size-3.5\" /> : <Mail className=\"size-3.5\" />}\n                      <span>{agentContacted ? 'Message Sent' : 'Contact Agent'}</span>\n                    </Button>\n                  </div>\n                </div>\n              </CardContent>\n            </Card>\n          )\n        })}\n      </div>\n    </section>\n  )\n}\n\nexport default PropertyListingCard\n",
      "type": "registry:block",
      "target": "~/components/blocks/PropertyListingCard.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/avatar.json",
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Zillow and Redfin style real estate property listing card featuring interactive photo carousels with 16:9 aspect ratios, price and mortgage estimation, specification pills (beds, baths, square footage, price/sqft), address, key feature tags, listing agent attribution, and direct tour scheduling actions.",
  "categories": [
    "real-estate",
    "hospitality",
    "marketing",
    "ecommerce"
  ]
}