{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "leaflet-neighborhood-walkscore-card",
  "title": "Leaflet Neighborhood Walkscore Card",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/leaflet-neighborhood-walkscore-card/LeafletNeighborhoodWalkscoreCard.vue",
      "content": "<script setup lang=\"ts\">\nimport { ref, computed } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport {\n  Footprints,\n  Bus,\n  Bike,\n  MapPin,\n  Search,\n  Navigation,\n  School,\n  TreePine,\n  Coffee,\n  GraduationCap,\n  UtensilsCrossed,\n  Car,\n  Train,\n  Clock,\n  Share2,\n  Bookmark,\n  Check,\n  ArrowUpRight,\n  ShieldCheck,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card'\nimport { Progress } from '@/components/ui/progress'\nimport { Separator } from '@/components/ui/separator'\nimport { LeafletCircle, LeafletMap, LeafletMarker } from '@/components/ui/leaflet-map'\n\nexport type PoiCategoryType = 'all' | 'transit' | 'dining' | 'schools' | 'parks'\nexport type CommuteMode = 'all' | 'transit' | 'drive'\n\nexport interface MobilityScore {\n  score: number\n  maxScore?: number\n  label: string\n  verdict: string\n  description: string\n  verdictClass: string\n  gaugeColor: string\n  subtext: string\n  highlights: string[]\n}\n\nexport interface PoiItem {\n  id: string\n  name: string\n  category: 'transit' | 'dining' | 'schools' | 'parks'\n  categoryLabel: string\n  distance: string\n  timeWalk?: string\n  timeDrive?: string\n  rating?: string\n  badge?: string\n  description: string\n  address: string\n  coords?: [number, number]\n}\n\nexport interface CommuteDestination {\n  id: string\n  name: string\n  region: string\n  distance: string\n  transitTime: number\n  transitLabel: string\n  transitRoute: string\n  driveTime: number\n  driveLabel: string\n  driveRoute: string\n  peakRushTime?: string\n}\n\nexport interface LeafletNeighborhoodWalkscoreCardProps {\n  title?: string\n  address?: string\n  neighborhood?: string\n  city?: string\n  zipCode?: string\n  walkScore?: MobilityScore\n  transitScore?: MobilityScore\n  bikeScore?: MobilityScore\n  pois?: PoiItem[]\n  commutes?: CommuteDestination[]\n  class?: HTMLAttributes['class']\n}\n\nconst defaultWalkScore: MobilityScore = {\n  score: 94,\n  maxScore: 100,\n  label: 'Walk Score®',\n  verdict: \"Walker's Paradise\",\n  description: 'Daily errands do not require a car',\n  verdictClass: 'text-success',\n  gaugeColor: '#10b981',\n  subtext: '94 out of 100 on walkable street accessibility',\n  highlights: ['48 amenities within 10-min walk', '98% continuous sidewalks', 'Pedestrian safety grade: A+'],\n}\n\nconst defaultTransitScore: MobilityScore = {\n  score: 82,\n  maxScore: 100,\n  label: 'Transit Score®',\n  verdict: 'Excellent Transit',\n  description: '6 nearby bus & light rail routes',\n  verdictClass: 'text-info',\n  gaugeColor: '#0ea5e9',\n  subtext: '82 out of 100 on public transportation connectivity',\n  highlights: ['Metro A Line station in 4 min', '5 frequent municipal bus routes', '18 min direct train to DTLA'],\n}\n\nconst defaultBikeScore: MobilityScore = {\n  score: 88,\n  maxScore: 100,\n  label: 'Bike Score®',\n  verdict: 'Very Bikeable',\n  description: 'Dedicated bike lanes and flat terrain',\n  verdictClass: 'text-chart-1',\n  gaugeColor: 'var(--chart-1)',\n  subtext: '88 out of 100 on cycling infrastructure & slope',\n  highlights: ['14 miles of protected bike lanes', '<2% average street gradient', '3 bikeshare docks nearby'],\n}\n\nconst defaultPois: PoiItem[] = [\n  {\n    id: 'poi-1',\n    name: 'Metro A Line Station',\n    category: 'transit',\n    categoryLabel: 'Public Transit',\n    distance: '0.2 mi',\n    timeWalk: '4 min walk',\n    badge: 'Light Rail',\n    description: 'High-frequency light rail connecting Pasadena directly to Downtown LA and Long Beach.',\n    address: 'Del Mar Ave & S Raymond Ave',\n  },\n  {\n    id: 'poi-2',\n    name: 'Pasadena Transit Bus Stop',\n    category: 'transit',\n    categoryLabel: 'Public Transit',\n    distance: '0.1 mi',\n    timeWalk: '2 min walk',\n    badge: 'Local Transit',\n    description: 'Direct routes 10 & 20 connecting South Lake District to Old Town & City Hall.',\n    address: 'S Lake Ave & E Green St',\n  },\n  {\n    id: 'poi-3',\n    name: 'Memorial Park Station',\n    category: 'transit',\n    categoryLabel: 'Public Transit',\n    distance: '0.5 mi',\n    timeWalk: '10 min walk',\n    badge: 'Light Rail',\n    description: 'Alternative metro access with regional bus connection bays and bike lockups.',\n    address: '125 E Holly St',\n  },\n  {\n    id: 'poi-4',\n    name: 'Blue Bottle Coffee',\n    category: 'dining',\n    categoryLabel: 'Dining & Coffee',\n    distance: '0.1 mi',\n    timeWalk: '2 min walk',\n    rating: '4.8 ★',\n    badge: 'Artisanal Cafe',\n    description: 'Specialty pour-over coffee, single-origin espresso drinks, and fresh bakery pastries.',\n    address: '60 S Lake Ave',\n  },\n  {\n    id: 'poi-5',\n    name: 'Whole Foods Market',\n    category: 'dining',\n    categoryLabel: 'Dining & Coffee',\n    distance: '0.3 mi',\n    timeWalk: '6 min walk',\n    rating: '4.7 ★',\n    badge: 'Organic Grocery',\n    description: 'Full-service natural grocer with organic produce, prepared hot bar, and wellness center.',\n    address: '3751 E Foothill Blvd / Arroyo Pkwy',\n  },\n  {\n    id: 'poi-6',\n    name: \"Trader Joe's\",\n    category: 'dining',\n    categoryLabel: 'Dining & Coffee',\n    distance: '0.4 mi',\n    timeWalk: '8 min walk',\n    rating: '4.9 ★',\n    badge: 'Grocery',\n    description: 'Neighborhood market renowned for unique provisions, fresh bakery, and wine selection.',\n    address: '610 S Lake Ave',\n  },\n  {\n    id: 'poi-7',\n    name: 'Urth Caffe Pasadena',\n    category: 'dining',\n    categoryLabel: 'Dining & Coffee',\n    distance: '0.2 mi',\n    timeWalk: '5 min walk',\n    rating: '4.6 ★',\n    badge: 'Organic Eatery',\n    description: 'Vibrant indoor/outdoor patio serving farm-to-table organic breakfast, lunch, and matcha.',\n    address: '594 E Colorado Blvd',\n  },\n  {\n    id: 'poi-8',\n    name: 'Pasadena High School',\n    category: 'schools',\n    categoryLabel: 'Schools & Education',\n    distance: '0.6 mi',\n    timeWalk: '12 min walk',\n    rating: '9/10',\n    badge: 'Public 9-12',\n    description: 'Top-rated public high school with Law and Creative Arts academies and AP honors programs.',\n    address: '2925 E Sierra Madre Blvd',\n  },\n  {\n    id: 'poi-9',\n    name: 'Caltech Campus',\n    category: 'schools',\n    categoryLabel: 'Schools & Education',\n    distance: '0.8 mi',\n    timeWalk: '15 min walk',\n    rating: 'Top Tier',\n    badge: 'Higher Education',\n    description: 'World-renowned private science & engineering research university campus and open grounds.',\n    address: '1200 E California Blvd',\n  },\n  {\n    id: 'poi-10',\n    name: 'McKinley Elementary School',\n    category: 'schools',\n    categoryLabel: 'Schools & Education',\n    distance: '0.4 mi',\n    timeWalk: '8 min walk',\n    rating: '8/10',\n    badge: 'Public K-8',\n    description: 'STEAM-focused neighborhood magnet school with dual-language immersion track.',\n    address: '325 S Oak Knoll Ave',\n  },\n  {\n    id: 'poi-11',\n    name: 'Central Park',\n    category: 'parks',\n    categoryLabel: 'Parks & Recreation',\n    distance: '0.3 mi',\n    timeWalk: '6 min walk',\n    rating: '4.8 ★',\n    badge: 'Public Park',\n    description: 'Historic shaded park with rolling green lawns, dedicated dog park, and lawn bowling greens.',\n    address: '275 S Raymond Ave',\n  },\n  {\n    id: 'poi-12',\n    name: 'Rose Bowl Aquatics Center',\n    category: 'parks',\n    categoryLabel: 'Parks & Recreation',\n    distance: '1.4 mi',\n    timeDrive: '5 min drive',\n    rating: '4.9 ★',\n    badge: 'Sports Complex',\n    description: 'Twin Olympic 50-meter pools, fitness facilities, and adjacent Arroyo Seco running trails.',\n    address: '360 N Arroyo Blvd',\n  },\n]\n\nconst defaultCommutes: CommuteDestination[] = [\n  {\n    id: 'commute-dtla',\n    name: 'Downtown Los Angeles',\n    region: 'Financial District & Union Station',\n    distance: '10.4 mi',\n    transitTime: 18,\n    transitLabel: '18m by train',\n    transitRoute: 'Metro A Line (Direct Express)',\n    driveTime: 24,\n    driveLabel: '24m by car',\n    driveRoute: 'via CA-110 S Freeway',\n    peakRushTime: '28-34m at 8:30 AM',\n  },\n  {\n    id: 'commute-sm',\n    name: 'Santa Monica',\n    region: 'Silicon Beach & Pier',\n    distance: '26.2 mi',\n    transitTime: 62,\n    transitLabel: '62m by train',\n    transitRoute: 'Metro A Line → Metro E Line',\n    driveTime: 45,\n    driveLabel: '45m by car',\n    driveRoute: 'via I-10 W / CA-110 S',\n    peakRushTime: '55-68m at 8:30 AM',\n  },\n  {\n    id: 'commute-burbank',\n    name: 'Burbank Media District',\n    region: 'Warner Bros & Disney Studios',\n    distance: '12.1 mi',\n    transitTime: 38,\n    transitLabel: '38m by transit',\n    transitRoute: 'Metro Bus 501 Rapid',\n    driveTime: 22,\n    driveLabel: '22m by car',\n    driveRoute: 'via CA-134 W Express',\n    peakRushTime: '26-32m at 8:30 AM',\n  },\n  {\n    id: 'commute-century',\n    name: 'Century City / Westwood',\n    region: 'Fox Studios & UCLA Area',\n    distance: '21.5 mi',\n    transitTime: 54,\n    transitLabel: '54m by transit',\n    transitRoute: 'Commuter Express 423',\n    driveTime: 38,\n    driveLabel: '38m by car',\n    driveRoute: 'via CA-134 W to I-405 S',\n    peakRushTime: '48-58m at 8:30 AM',\n  },\n]\n\nconst props = withDefaults(defineProps<LeafletNeighborhoodWalkscoreCardProps>(), {\n  title: 'Neighborhood & Location Intelligence',\n  address: '742 Evergreen Terrace, Pasadena, CA 91101',\n  neighborhood: 'South Lake Commercial & Arts District',\n  city: 'Pasadena',\n  zipCode: '91101',\n})\n\nconst activeWalkScore = computed(() => props.walkScore ?? defaultWalkScore)\nconst activeTransitScore = computed(() => props.transitScore ?? defaultTransitScore)\nconst activeBikeScore = computed(() => props.bikeScore ?? defaultBikeScore)\nconst activePois = computed(() => props.pois ?? defaultPois)\nconst activeCommutes = computed(() => props.commutes ?? defaultCommutes)\n\nconst selectedCategory = ref<PoiCategoryType>('all')\nconst searchQuery = ref('')\nconst selectedCommuteMode = ref<CommuteMode>('all')\nconst isSaved = ref(false)\nconst isCopied = ref(false)\n\nfunction resetFilters() {\n  searchQuery.value = ''\n  selectedCategory.value = 'all'\n}\n\nconst categoriesList = computed(() => [\n  { id: 'all' as const, label: 'All Places', count: activePois.value.length },\n  {\n    id: 'transit' as const,\n    label: 'Public Transit',\n    count: activePois.value.filter((p) => p.category === 'transit').length,\n  },\n  {\n    id: 'dining' as const,\n    label: 'Dining & Coffee',\n    count: activePois.value.filter((p) => p.category === 'dining').length,\n  },\n  {\n    id: 'schools' as const,\n    label: 'Schools & Education',\n    count: activePois.value.filter((p) => p.category === 'schools').length,\n  },\n  {\n    id: 'parks' as const,\n    label: 'Parks & Rec',\n    count: activePois.value.filter((p) => p.category === 'parks').length,\n  },\n])\n\nconst filteredPois = computed(() => {\n  return activePois.value.filter((poi) => {\n    const matchesCat = selectedCategory.value === 'all' || poi.category === selectedCategory.value\n    const matchesSearch =\n      searchQuery.value.trim() === '' ||\n      poi.name.toLowerCase().includes(searchQuery.value.toLowerCase()) ||\n      poi.description.toLowerCase().includes(searchQuery.value.toLowerCase()) ||\n      poi.address.toLowerCase().includes(searchQuery.value.toLowerCase()) ||\n      (poi.badge && poi.badge.toLowerCase().includes(searchQuery.value.toLowerCase()))\n    return matchesCat && matchesSearch\n  })\n})\n\nfunction handleCopyAddress() {\n  if (typeof navigator !== 'undefined' && navigator.clipboard) {\n    navigator.clipboard.writeText(`${props.address}, ${props.neighborhood}`)\n    isCopied.value = true\n    setTimeout(() => {\n      isCopied.value = false\n    }, 2000)\n  }\n}\n\nfunction handleToggleSave() {\n  isSaved.value = !isSaved.value\n}\n\n// Circular gauge calculation helper (radius 38, perimeter ~238.76)\nconst circumference = 2 * Math.PI * 38\nfunction getGaugeDashOffset(score: number): number {\n  const clamped = Math.min(100, Math.max(0, score))\n  return circumference - (clamped / 100) * circumference\n}\n\n// Subject property (742 Evergreen Terrace, Pasadena) — map center, home marker,\n// and the 15-minute walkshed circle all anchor here.\nconst HOME_CENTER: [number, number] = [-118.1445, 34.1478]\n// ~15-minute pedestrian catchment (~1.2 km at typical walking speed).\nconst WALK_RADIUS_METERS = 1200\n\nconst defaultPoiCoords: Record<string, [number, number]> = {\n  'poi-1': [-118.148, 34.141],\n  'poi-2': [-118.132, 34.152],\n  'poi-3': [-118.149, 34.148],\n  'poi-4': [-118.133, 34.144],\n  'poi-5': [-118.149, 34.135],\n  'poi-6': [-118.132, 34.136],\n  'poi-7': [-118.136, 34.146],\n  'poi-8': [-118.125, 34.155],\n  'poi-9': [-118.138, 34.138],\n  'poi-10': [-118.148, 34.143],\n  'poi-11': [-118.142, 34.133],\n}\n\nfunction getPoiCoords(poi: PoiItem): [number, number] {\n  if (poi.coords) return poi.coords\n  return (\n    defaultPoiCoords[poi.id] || [\n      HOME_CENTER[0] + Math.sin(poi.name.length) * 0.008,\n      HOME_CENTER[1] + Math.cos(poi.name.length) * 0.008,\n    ]\n  )\n}\n</script>\n\n<template>\n  <div :class=\"cn('w-full space-y-6', props.class)\" data-slot=\"leaflet-neighborhood-walkscore-card\">\n    <!-- Header Banner Card -->\n    <Card class=\"border-border/80 bg-card text-card-foreground shadow-xs\">\n      <CardHeader class=\"p-4 sm:p-6\">\n        <div class=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n          <div class=\"space-y-2\">\n            <!-- Badges Bar -->\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <Badge wrap variant=\"outline\" class=\"gap-1.5 font-medium\">\n                <MapPin class=\"text-primary size-3.5\" />\n                <span>{{ props.city }} · {{ props.zipCode }}</span>\n              </Badge>\n              <Badge wrap variant=\"success\" class=\"gap-1 font-medium\">\n                <Footprints class=\"size-3.5\" />\n                <span>Walker's Paradise</span>\n              </Badge>\n              <Badge wrap variant=\"secondary\" class=\"font-medium\"> Urban Transit Hub </Badge>\n            </div>\n\n            <!-- Title & Address -->\n            <div>\n              <h1 class=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">\n                {{ props.title }}\n              </h1>\n              <p class=\"text-foreground mt-1 text-sm font-semibold sm:text-base\">\n                {{ props.address }}\n              </p>\n              <p class=\"text-muted-foreground mt-0.5 text-xs sm:text-sm\">\n                Neighborhood: <span class=\"text-foreground font-medium\">{{ props.neighborhood }}</span>\n              </p>\n            </div>\n          </div>\n\n          <!-- Top Actions -->\n          <div class=\"flex flex-wrap items-center gap-2 self-start lg:self-auto\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              class=\"h-8 gap-1.5 text-xs font-medium shadow-xs\"\n              @click=\"handleCopyAddress\"\n            >\n              <Check v-if=\"isCopied\" class=\"text-success size-3.5\" />\n              <Share2 v-else class=\"size-3.5\" />\n              <span>{{ isCopied ? 'Address Copied' : 'Share Location' }}</span>\n            </Button>\n\n            <Button\n              :variant=\"isSaved ? 'default' : 'outline'\"\n              size=\"sm\"\n              class=\"h-8 gap-1.5 text-xs font-medium shadow-xs\"\n              @click=\"handleToggleSave\"\n            >\n              <Bookmark :class=\"['size-3.5', isSaved ? 'fill-current' : '']\" />\n              <span>{{ isSaved ? 'Saved Neighborhood' : 'Save Area' }}</span>\n            </Button>\n          </div>\n        </div>\n      </CardHeader>\n    </Card>\n\n    <!-- Section 1: 3 Primary Mobility Score Cards -->\n    <div class=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n      <!-- Card 1: Walk Score -->\n      <Card class=\"border-border/80 bg-card text-card-foreground hover:border-success/40 shadow-xs transition-colors\">\n        <CardHeader class=\"p-4 pb-2 sm:p-5 sm:pb-2\">\n          <div class=\"flex items-center justify-between\">\n            <div class=\"flex items-center gap-2\">\n              <div\n                class=\"border-success/30 bg-success/10 text-success flex size-8 items-center justify-center rounded-lg border\"\n              >\n                <Footprints class=\"size-4\" />\n              </div>\n              <div>\n                <CardTitle class=\"text-sm font-semibold\">{{ activeWalkScore.label }}</CardTitle>\n                <CardDescription class=\"text-xs\">Pedestrian Index</CardDescription>\n              </div>\n            </div>\n            <Badge wrap variant=\"success\" class=\"text-xs font-semibold\"> {{ activeWalkScore.score }}/100 </Badge>\n          </div>\n        </CardHeader>\n\n        <CardContent class=\"space-y-4 p-4 pt-2 sm:p-5 sm:pt-2\">\n          <!-- Circular Gauge & Score Verdict -->\n          <div class=\"flex items-center gap-4 pt-1\">\n            <div class=\"relative flex size-20 shrink-0 items-center justify-center\">\n              <svg class=\"size-20 -rotate-90\" viewBox=\"0 0 96 96\">\n                <circle\n                  cx=\"48\"\n                  cy=\"48\"\n                  r=\"38\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  stroke-width=\"7\"\n                  class=\"text-muted/40\"\n                />\n                <circle\n                  cx=\"48\"\n                  cy=\"48\"\n                  r=\"38\"\n                  fill=\"none\"\n                  :stroke=\"activeWalkScore.gaugeColor\"\n                  stroke-width=\"7\"\n                  stroke-linecap=\"round\"\n                  :stroke-dasharray=\"circumference\"\n                  :stroke-dashoffset=\"getGaugeDashOffset(activeWalkScore.score)\"\n                  class=\"transition-colors duration-700 ease-out\"\n                />\n              </svg>\n              <div class=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n                <span class=\"text-foreground font-mono text-xl font-bold tracking-tight tabular-nums\">\n                  {{ activeWalkScore.score }}\n                </span>\n                <span class=\"text-muted-foreground text-xs font-medium\">/ 100</span>\n              </div>\n            </div>\n\n            <div class=\"space-y-1\">\n              <div class=\"text-foreground text-sm font-bold tracking-tight\">\n                {{ activeWalkScore.verdict }}\n              </div>\n              <p class=\"text-success text-xs leading-relaxed font-semibold\">\n                {{ activeWalkScore.description }}\n              </p>\n            </div>\n          </div>\n\n          <Separator class=\"bg-border/60\" />\n\n          <!-- Key Highlights -->\n          <div class=\"space-y-1.5\">\n            <p class=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Mobility Highlights</p>\n            <ul class=\"space-y-1 text-xs\">\n              <li\n                v-for=\"(item, idx) in activeWalkScore.highlights\"\n                :key=\"idx\"\n                class=\"text-foreground flex items-center gap-2\"\n              >\n                <Check class=\"text-success size-3.5 shrink-0\" />\n                <span>{{ item }}</span>\n              </li>\n            </ul>\n          </div>\n        </CardContent>\n      </Card>\n\n      <!-- Card 2: Transit Score -->\n      <Card class=\"border-border/80 bg-card text-card-foreground hover:border-info/40 shadow-xs transition-colors\">\n        <CardHeader class=\"p-4 pb-2 sm:p-5 sm:pb-2\">\n          <div class=\"flex items-center justify-between\">\n            <div class=\"flex items-center gap-2\">\n              <div\n                class=\"border-info/30 bg-info/10 text-info flex size-8 items-center justify-center rounded-lg border\"\n              >\n                <Bus class=\"size-4\" />\n              </div>\n              <div>\n                <CardTitle class=\"text-sm font-semibold\">{{ activeTransitScore.label }}</CardTitle>\n                <CardDescription class=\"text-xs\">Transit Connectivity</CardDescription>\n              </div>\n            </div>\n            <Badge wrap variant=\"info\" class=\"text-xs font-semibold\"> {{ activeTransitScore.score }}/100 </Badge>\n          </div>\n        </CardHeader>\n\n        <CardContent class=\"space-y-4 p-4 pt-2 sm:p-5 sm:pt-2\">\n          <!-- Circular Gauge & Score Verdict -->\n          <div class=\"flex items-center gap-4 pt-1\">\n            <div class=\"relative flex size-20 shrink-0 items-center justify-center\">\n              <svg class=\"size-20 -rotate-90\" viewBox=\"0 0 96 96\">\n                <circle\n                  cx=\"48\"\n                  cy=\"48\"\n                  r=\"38\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  stroke-width=\"7\"\n                  class=\"text-muted/40\"\n                />\n                <circle\n                  cx=\"48\"\n                  cy=\"48\"\n                  r=\"38\"\n                  fill=\"none\"\n                  :stroke=\"activeTransitScore.gaugeColor\"\n                  stroke-width=\"7\"\n                  stroke-linecap=\"round\"\n                  :stroke-dasharray=\"circumference\"\n                  :stroke-dashoffset=\"getGaugeDashOffset(activeTransitScore.score)\"\n                  class=\"transition-colors duration-700 ease-out\"\n                />\n              </svg>\n              <div class=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n                <span class=\"text-foreground font-mono text-xl font-bold tracking-tight tabular-nums\">\n                  {{ activeTransitScore.score }}\n                </span>\n                <span class=\"text-muted-foreground text-xs font-medium\">/ 100</span>\n              </div>\n            </div>\n\n            <div class=\"space-y-1\">\n              <div class=\"text-foreground text-sm font-bold tracking-tight\">\n                {{ activeTransitScore.verdict }}\n              </div>\n              <p class=\"text-info text-xs leading-relaxed font-semibold\">\n                {{ activeTransitScore.description }}\n              </p>\n            </div>\n          </div>\n\n          <Separator class=\"bg-border/60\" />\n\n          <!-- Key Highlights -->\n          <div class=\"space-y-1.5\">\n            <p class=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Transit Highlights</p>\n            <ul class=\"space-y-1 text-xs\">\n              <li\n                v-for=\"(item, idx) in activeTransitScore.highlights\"\n                :key=\"idx\"\n                class=\"text-foreground flex items-center gap-2\"\n              >\n                <Check class=\"text-info size-3.5 shrink-0\" />\n                <span>{{ item }}</span>\n              </li>\n            </ul>\n          </div>\n        </CardContent>\n      </Card>\n\n      <!-- Card 3: Bike Score -->\n      <Card class=\"border-border/80 bg-card text-card-foreground hover:border-chart-1/40 shadow-xs transition-colors\">\n        <CardHeader class=\"p-4 pb-2 sm:p-5 sm:pb-2\">\n          <div class=\"flex items-center justify-between\">\n            <div class=\"flex items-center gap-2\">\n              <div\n                class=\"border-chart-1/30 bg-chart-1/10 text-chart-1 flex size-8 items-center justify-center rounded-lg border\"\n              >\n                <Bike class=\"size-4\" />\n              </div>\n              <div>\n                <CardTitle class=\"text-sm font-semibold\">{{ activeBikeScore.label }}</CardTitle>\n                <CardDescription class=\"text-xs\">Cycling Grid</CardDescription>\n              </div>\n            </div>\n            <Badge wrap variant=\"outline\" class=\"text-xs font-semibold\"> {{ activeBikeScore.score }}/100 </Badge>\n          </div>\n        </CardHeader>\n\n        <CardContent class=\"space-y-4 p-4 pt-2 sm:p-5 sm:pt-2\">\n          <!-- Circular Gauge & Score Verdict -->\n          <div class=\"flex items-center gap-4 pt-1\">\n            <div class=\"relative flex size-20 shrink-0 items-center justify-center\">\n              <svg class=\"size-20 -rotate-90\" viewBox=\"0 0 96 96\">\n                <circle\n                  cx=\"48\"\n                  cy=\"48\"\n                  r=\"38\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  stroke-width=\"7\"\n                  class=\"text-muted/40\"\n                />\n                <circle\n                  cx=\"48\"\n                  cy=\"48\"\n                  r=\"38\"\n                  fill=\"none\"\n                  :stroke=\"activeBikeScore.gaugeColor\"\n                  stroke-width=\"7\"\n                  stroke-linecap=\"round\"\n                  :stroke-dasharray=\"circumference\"\n                  :stroke-dashoffset=\"getGaugeDashOffset(activeBikeScore.score)\"\n                  class=\"transition-colors duration-700 ease-out\"\n                />\n              </svg>\n              <div class=\"absolute inset-0 flex flex-col items-center justify-center text-center\">\n                <span class=\"text-foreground font-mono text-xl font-bold tracking-tight tabular-nums\">\n                  {{ activeBikeScore.score }}\n                </span>\n                <span class=\"text-muted-foreground text-xs font-medium\">/ 100</span>\n              </div>\n            </div>\n\n            <div class=\"space-y-1\">\n              <div class=\"text-foreground text-sm font-bold tracking-tight\">\n                {{ activeBikeScore.verdict }}\n              </div>\n              <p class=\"text-chart-1 text-xs leading-relaxed font-semibold\">\n                {{ activeBikeScore.description }}\n              </p>\n            </div>\n          </div>\n\n          <Separator class=\"bg-border/60\" />\n\n          <!-- Key Highlights -->\n          <div class=\"space-y-1.5\">\n            <p class=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Cycling Highlights</p>\n            <ul class=\"space-y-1 text-xs\">\n              <li\n                v-for=\"(item, idx) in activeBikeScore.highlights\"\n                :key=\"idx\"\n                class=\"text-foreground flex items-center gap-2\"\n              >\n                <Check class=\"text-chart-1 size-3.5 shrink-0\" />\n                <span>{{ item }}</span>\n              </li>\n            </ul>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n\n    <!-- Section 2: Commute Time Estimator -->\n    <div class=\"space-y-3\">\n      <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <h2 class=\"text-foreground text-sm font-semibold tracking-tight\">Commute Time Estimator</h2>\n          <p class=\"text-muted-foreground text-xs\">\n            Estimated travel duration from 742 Evergreen Terrace to key employment & lifestyle hubs.\n          </p>\n        </div>\n\n        <!-- Mode selector filters -->\n        <div class=\"border-border/80 bg-muted/40 flex items-center rounded-lg border p-1 text-xs\">\n          <button\n            type=\"button\"\n            :class=\"[\n              'focus-visible:ring-ring rounded-md px-2.5 py-1 font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              selectedCommuteMode === 'all'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            ]\"\n            @click=\"selectedCommuteMode = 'all'\"\n          >\n            All Modes\n          </button>\n          <button\n            type=\"button\"\n            :class=\"[\n              'focus-visible:ring-ring flex items-center gap-1 rounded-md px-2.5 py-1 font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              selectedCommuteMode === 'transit'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            ]\"\n            @click=\"selectedCommuteMode = 'transit'\"\n          >\n            <Train class=\"size-3\" />\n            <span>Transit</span>\n          </button>\n          <button\n            type=\"button\"\n            :class=\"[\n              'focus-visible:ring-ring flex items-center gap-1 rounded-md px-2.5 py-1 font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              selectedCommuteMode === 'drive'\n                ? 'bg-background text-foreground shadow-xs'\n                : 'text-muted-foreground hover:text-foreground',\n            ]\"\n            @click=\"selectedCommuteMode = 'drive'\"\n          >\n            <Car class=\"size-3\" />\n            <span>Driving</span>\n          </button>\n        </div>\n      </div>\n\n      <Card class=\"border-border/80 bg-card text-card-foreground overflow-hidden shadow-xs\">\n        <div class=\"divide-border/60 divide-y\">\n          <div\n            v-for=\"commute in activeCommutes\"\n            :key=\"commute.id\"\n            class=\"hover:bg-muted/15 p-4 transition-colors sm:p-5\"\n          >\n            <div class=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n              <!-- Destination Info -->\n              <div class=\"space-y-1\">\n                <div class=\"flex items-center gap-2\">\n                  <h3 class=\"text-foreground text-sm font-semibold\">{{ commute.name }}</h3>\n                  <span class=\"text-muted-foreground font-mono text-xs tabular-nums\">· {{ commute.distance }}</span>\n                </div>\n                <p class=\"text-muted-foreground text-xs\">{{ commute.region }}</p>\n              </div>\n\n              <!-- Time Badges & Routes -->\n              <div class=\"flex flex-wrap items-center gap-3\">\n                <!-- Transit Mode Pill -->\n                <div\n                  v-if=\"selectedCommuteMode === 'all' || selectedCommuteMode === 'transit'\"\n                  class=\"border-info/20 bg-info/10 flex items-center gap-2 rounded-lg border px-3 py-1.5 text-xs\"\n                >\n                  <Train class=\"text-info size-3.5\" />\n                  <div>\n                    <span class=\"text-foreground font-mono font-semibold tabular-nums\">\n                      {{ commute.transitLabel }}\n                    </span>\n                    <span class=\"text-muted-foreground hidden sm:inline\"> — {{ commute.transitRoute }}</span>\n                  </div>\n                </div>\n\n                <!-- Drive Mode Pill -->\n                <div\n                  v-if=\"selectedCommuteMode === 'all' || selectedCommuteMode === 'drive'\"\n                  class=\"border-success/20 bg-success/10 flex items-center gap-2 rounded-lg border px-3 py-1.5 text-xs\"\n                >\n                  <Car class=\"text-success size-3.5\" />\n                  <div>\n                    <span class=\"text-foreground font-mono font-semibold tabular-nums\">\n                      {{ commute.driveLabel }}\n                    </span>\n                    <span class=\"text-muted-foreground hidden sm:inline\"> — {{ commute.driveRoute }}</span>\n                  </div>\n                </div>\n\n                <!-- Peak Rush Info -->\n                <div\n                  v-if=\"commute.peakRushTime\"\n                  class=\"text-muted-foreground flex items-center gap-1 font-mono text-xs tabular-nums\"\n                >\n                  <Clock class=\"text-muted-foreground size-3\" />\n                  <span>Rush: {{ commute.peakRushTime }}</span>\n                </div>\n              </div>\n            </div>\n\n            <!-- Visual Progress Bar for Comparative Duration -->\n            <div class=\"mt-3 grid grid-cols-1 gap-2 pt-1 sm:grid-cols-2\">\n              <div v-if=\"selectedCommuteMode === 'all' || selectedCommuteMode === 'transit'\" class=\"space-y-1\">\n                <div class=\"text-muted-foreground flex items-center justify-between text-xs\">\n                  <span>Transit Duration</span>\n                  <span class=\"font-mono tabular-nums\">{{ commute.transitTime }} min</span>\n                </div>\n                <Progress :model-value=\"Math.min(100, (commute.transitTime / 70) * 100)\" class=\"bg-muted h-1.5\" />\n              </div>\n\n              <div v-if=\"selectedCommuteMode === 'all' || selectedCommuteMode === 'drive'\" class=\"space-y-1\">\n                <div class=\"text-muted-foreground flex items-center justify-between text-xs\">\n                  <span>Driving Duration</span>\n                  <span class=\"font-mono tabular-nums\">{{ commute.driveTime }} min</span>\n                </div>\n                <Progress :model-value=\"Math.min(100, (commute.driveTime / 70) * 100)\" class=\"bg-muted h-1.5\" />\n              </div>\n            </div>\n          </div>\n        </div>\n      </Card>\n    </div>\n\n    <!-- Section 3: Nearby Points of Interest Categorized List -->\n    <div class=\"space-y-3\">\n      <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <h2 class=\"text-foreground text-sm font-semibold tracking-tight\">Nearby Points of Interest</h2>\n          <p class=\"text-muted-foreground text-xs\">\n            Key transit hubs, dining, specialty cafes, schools, and parks located within walking distance.\n          </p>\n        </div>\n\n        <div class=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n          <Navigation class=\"text-primary size-3.5\" />\n          <span class=\"font-mono tabular-nums\">{{ activePois.length }} verified local venues</span>\n        </div>\n      </div>\n\n      <!-- Controls: Category Filter Tabs & Search Bar -->\n      <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n        <!-- Category Filter Tabs -->\n        <div class=\"flex flex-wrap items-center gap-1.5\">\n          <button\n            v-for=\"cat in categoriesList\"\n            :key=\"cat.id\"\n            type=\"button\"\n            :class=\"[\n              'focus-visible:ring-ring rounded-md border px-3 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n              selectedCategory === cat.id\n                ? 'border-primary bg-primary text-primary-foreground shadow-xs'\n                : 'border-border/80 bg-card text-muted-foreground hover:bg-muted hover:text-foreground',\n            ]\"\n            @click=\"selectedCategory = cat.id\"\n          >\n            {{ cat.label }}\n            <span\n              :class=\"[\n                'ml-1 font-mono tabular-nums',\n                selectedCategory === cat.id ? 'opacity-80' : 'text-muted-foreground',\n              ]\"\n            >\n              ({{ cat.count }})\n            </span>\n          </button>\n        </div>\n\n        <!-- Search Input -->\n        <div class=\"relative w-full sm:w-64\">\n          <Search class=\"text-muted-foreground pointer-events-none absolute top-2.5 left-2.5 size-3.5\" />\n          <input\n            v-model=\"searchQuery\"\n            type=\"text\"\n            placeholder=\"Search venue or street...\"\n            class=\"border-border bg-background placeholder:text-muted-foreground focus-visible:ring-ring h-8 w-full rounded-md border pr-3 pl-8 text-xs focus-visible:ring-2 focus-visible:outline-none\"\n          />\n        </div>\n      </div>\n\n      <!-- Interactive 15-Minute Walkshed & POI Map -->\n      <Card class=\"overflow-hidden\">\n        <CardHeader class=\"border-border/70 border-b p-4 pb-3 sm:p-5 sm:pb-3\">\n          <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n            <div>\n              <CardTitle class=\"flex items-center gap-2 text-base font-semibold\">\n                <Navigation class=\"text-success size-4\" />\n                <span>15-Minute Walkshed & Amenity Locator</span>\n              </CardTitle>\n              <CardDescription>\n                Free OpenStreetMap/Esri basemap — no API key — with a 15-minute walk radius and categorized local\n                destinations.\n              </CardDescription>\n            </div>\n            <Badge variant=\"outline\" class=\"w-fit gap-1 font-mono text-xs\">\n              <Footprints class=\"text-success size-3\" />\n              <span>98 Walk Score Paradise</span>\n            </Badge>\n          </div>\n        </CardHeader>\n        <div class=\"relative h-72 w-full sm:h-96\">\n          <LeafletMap variant=\"light\" :center=\"HOME_CENTER\" :zoom=\"14\" class=\"size-full\">\n            <!-- 15-min Walk Radius Circle -->\n            <LeafletCircle\n              :center=\"HOME_CENTER\"\n              :radius=\"WALK_RADIUS_METERS\"\n              color=\"#10b981\"\n              :weight=\"1.5\"\n              :opacity=\"0.6\"\n              dash-array=\"4 4\"\n              :fill=\"true\"\n              fill-color=\"#10b981\"\n              :fill-opacity=\"0.12\"\n            />\n\n            <!-- Home Property Marker -->\n            <LeafletMarker :lng-lat=\"HOME_CENTER\" anchor=\"center\" :z-index-offset=\"30\">\n              <div class=\"relative flex size-9 items-center justify-center\">\n                <span class=\"bg-warning absolute inline-flex size-full animate-ping rounded-full opacity-60\" />\n                <div\n                  class=\"bg-warning relative flex size-7 items-center justify-center rounded-full border-2 border-white text-white shadow-lg\"\n                >\n                  <MapPin class=\"size-4\" />\n                </div>\n              </div>\n            </LeafletMarker>\n\n            <!-- Filtered POI Markers -->\n            <LeafletMarker v-for=\"poi in filteredPois\" :key=\"poi.id\" :lng-lat=\"getPoiCoords(poi)\" anchor=\"center\">\n              <div\n                class=\"border-background bg-background flex size-7 cursor-pointer items-center justify-center rounded-full border-2 shadow-md select-none\"\n                :title=\"poi.name\"\n              >\n                <Coffee v-if=\"poi.category === 'dining'\" class=\"text-warning size-3.5\" />\n                <Train v-else-if=\"poi.category === 'transit'\" class=\"text-info size-3.5\" />\n                <School v-else-if=\"poi.category === 'schools'\" class=\"text-chart-2 size-3.5\" />\n                <TreePine v-else class=\"text-success size-3.5\" />\n              </div>\n            </LeafletMarker>\n          </LeafletMap>\n        </div>\n      </Card>\n\n      <!-- POIs Grid -->\n      <div v-if=\"filteredPois.length > 0\" class=\"grid grid-cols-1 gap-3 md:grid-cols-2\">\n        <Card\n          v-for=\"poi in filteredPois\"\n          :key=\"poi.id\"\n          class=\"border-border/80 bg-card text-card-foreground hover:border-border transition-colors hover:shadow-xs\"\n        >\n          <CardContent class=\"p-4 sm:p-4\">\n            <div class=\"flex items-start gap-3\">\n              <!-- Icon Box based on category -->\n              <div\n                :class=\"[\n                  'flex size-9 shrink-0 items-center justify-center rounded-lg border',\n                  poi.category === 'transit'\n                    ? 'border-info/30 bg-info/10 text-info'\n                    : poi.category === 'dining'\n                      ? 'border-warning/30 bg-warning/10 text-warning'\n                      : poi.category === 'schools'\n                        ? 'border-chart-2/30 bg-chart-2/10 text-chart-2'\n                        : 'border-success/30 bg-success/10 text-success',\n                ]\"\n              >\n                <Train v-if=\"poi.category === 'transit' && poi.badge === 'Light Rail'\" class=\"size-4\" />\n                <Bus v-else-if=\"poi.category === 'transit'\" class=\"size-4\" />\n                <Coffee v-else-if=\"poi.category === 'dining' && poi.name.includes('Coffee')\" class=\"size-4\" />\n                <UtensilsCrossed v-else-if=\"poi.category === 'dining'\" class=\"size-4\" />\n                <GraduationCap v-else-if=\"poi.category === 'schools' && poi.name.includes('Caltech')\" class=\"size-4\" />\n                <School v-else-if=\"poi.category === 'schools'\" class=\"size-4\" />\n                <TreePine v-else class=\"size-4\" />\n              </div>\n\n              <!-- Main POI Details -->\n              <div class=\"min-w-0 flex-1 space-y-1\">\n                <div class=\"flex items-start justify-between gap-2\">\n                  <h3 class=\"text-foreground truncate text-sm font-semibold\">\n                    {{ poi.name }}\n                  </h3>\n\n                  <!-- Distance / Walk Time Pill -->\n                  <div\n                    class=\"bg-muted/70 text-foreground border-border/60 shrink-0 rounded-md border px-2 py-0.5 font-mono text-xs font-medium tabular-nums\"\n                  >\n                    <span>{{ poi.distance }}</span>\n                    <span v-if=\"poi.timeWalk\" class=\"text-muted-foreground\"> · {{ poi.timeWalk }}</span>\n                    <span v-else-if=\"poi.timeDrive\" class=\"text-muted-foreground\"> · {{ poi.timeDrive }}</span>\n                  </div>\n                </div>\n\n                <p class=\"text-muted-foreground line-clamp-2 text-xs leading-relaxed\">\n                  {{ poi.description }}\n                </p>\n\n                <div class=\"flex flex-wrap items-center justify-between gap-2 pt-1.5 text-xs\">\n                  <span class=\"text-muted-foreground truncate\">{{ poi.address }}</span>\n                  <div class=\"flex items-center gap-1.5\">\n                    <Badge\n                      wrap\n                      v-if=\"poi.rating\"\n                      variant=\"secondary\"\n                      class=\"font-mono text-xs font-semibold tabular-nums\"\n                    >\n                      {{ poi.rating }}\n                    </Badge>\n                    <Badge wrap v-if=\"poi.badge\" variant=\"outline\" class=\"text-xs\">\n                      {{ poi.badge }}\n                    </Badge>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </CardContent>\n        </Card>\n      </div>\n\n      <!-- Empty State when filter yields nothing -->\n      <Card v-else class=\"border-border/80 bg-card text-card-foreground p-8 text-center shadow-xs\">\n        <div class=\"mx-auto flex max-w-sm flex-col items-center justify-center space-y-2\">\n          <Search class=\"text-muted-foreground size-8\" />\n          <p class=\"text-foreground text-sm font-semibold\">No points of interest match \"{{ searchQuery }}\"</p>\n          <p class=\"text-muted-foreground text-xs\">\n            Try searching for other amenities like \"coffee\", \"market\", \"school\", or clear the filter.\n          </p>\n          <Button variant=\"outline\" size=\"sm\" class=\"mt-2 text-xs\" @click=\"resetFilters\"> Clear Filters </Button>\n        </div>\n      </Card>\n    </div>\n\n    <!-- Section 4: Quick Neighborhood Summary Footnote -->\n    <Card class=\"border-border/80 bg-muted/25 text-card-foreground p-4 shadow-xs sm:p-5\">\n      <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div class=\"space-y-1\">\n          <div class=\"flex items-center gap-2\">\n            <ShieldCheck class=\"text-success size-4\" />\n            <p class=\"text-foreground text-xs font-semibold\">Official Location Score Intelligence Verification</p>\n          </div>\n          <p class=\"text-muted-foreground text-xs\">\n            Calculated based on standard 15-minute pedestrian catchment models, municipal route timetables, and GIS road\n            grades.\n          </p>\n        </div>\n\n        <div class=\"flex items-center gap-3\">\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"h-8 gap-1.5 text-xs font-medium shadow-xs\"\n            @click=\"handleCopyAddress\"\n          >\n            <ArrowUpRight class=\"size-3.5\" />\n            <span>Open in Maps</span>\n          </Button>\n        </div>\n      </div>\n    </Card>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/LeafletNeighborhoodWalkscoreCard.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/progress.json",
    "https://uipkge.dev/r/vue/separator.json",
    "https://uipkge.dev/r/vue/leaflet-map.json"
  ],
  "description": "Real estate neighborhood intelligence widget on free OpenStreetMap/Esri tiles — no API key. Walk Score, Transit Score, Bike Score, categorized points of interest (transit, dining, schools, parks), a 15-minute walk radius, and commute time estimator.",
  "categories": [
    "real-estate",
    "app",
    "dashboard",
    "marketing"
  ]
}