{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "neighborhood-walkscore-card",
  "title": "Neighborhood Walkscore Card",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/neighborhood-walkscore-card/neighborhood-walkscore-card.component.ts",
      "content": "// Real estate neighborhood intelligence widget: Walk/Transit/Bike score gauges,\n// commute time estimator, categorized points of interest with search, and a Mapbox\n// 15-minute walkshed with amenity markers. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport {\n  ArrowUpRight,\n  Bike,\n  Bookmark,\n  Bus,\n  Car,\n  Check,\n  Clock,\n  Coffee,\n  Footprints,\n  GraduationCap,\n  LucideAngularModule,\n  MapPin,\n  Navigation,\n  School,\n  Search,\n  Share2,\n  ShieldCheck,\n  Train,\n  TreePine,\n  UtensilsCrossed,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiMapComponent, UiMapLayerComponent, UiMapMarkerComponent, UiMapSourceComponent } from '@/ui/map/map.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\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\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 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\nconst HOME_CENTER: [number, number] = [-118.138, 34.145]\n\n/** Circular gauge geometry (radius 38, perimeter ~238.76). Exported for specs. */\nexport const GAUGE_CIRCUMFERENCE = 2 * Math.PI * 38\n\nexport function getGaugeDashOffset(score: number): number {\n  const clamped = Math.min(100, Math.max(0, score))\n  return GAUGE_CIRCUMFERENCE - (clamped / 100) * GAUGE_CIRCUMFERENCE\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-neighborhood-walkscore-card, [ui-neighborhood-walkscore-card]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiMapComponent,\n    UiMapLayerComponent,\n    UiMapMarkerComponent,\n    UiMapSourceComponent,\n    UiProgressComponent,\n    UiSeparatorComponent,\n  ],\n  template: `\n    <div data-slot=\"neighborhood-walkscore-card\" [class]=\"rootClass\">\n      <!-- Header Banner Card -->\n      <div ui-card class=\"border-border/80 bg-card text-card-foreground shadow-xs\">\n        <div ui-card-header 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                <span ui-badge wrap variant=\"outline\" class=\"gap-1.5 font-medium\">\n                  <lucide-icon [img]=\"MapPin\" class=\"text-primary size-3.5\" />\n                  <span>{{ city }} &middot; {{ zipCode }}</span>\n                </span>\n                <span ui-badge wrap variant=\"success\" class=\"gap-1 font-medium\">\n                  <lucide-icon [img]=\"Footprints\" class=\"size-3.5\" />\n                  <span>Walker's Paradise</span>\n                </span>\n                <span ui-badge wrap variant=\"secondary\" class=\"font-medium\">Urban Transit Hub</span>\n              </div>\n\n              <!-- Title & Address -->\n              <div>\n                <h1 class=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">{{ title }}</h1>\n                <p class=\"text-foreground mt-1 text-sm font-semibold sm:text-base\">{{ address }}</p>\n                <p class=\"text-muted-foreground mt-0.5 text-xs sm:text-sm\">\n                  Neighborhood: <span class=\"text-foreground font-medium\">{{ 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                ui-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                @if (isCopied()) {\n                  <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n                } @else {\n                  <lucide-icon [img]=\"Share2\" class=\"size-3.5\" />\n                }\n                <span>{{ isCopied() ? 'Address Copied' : 'Share Location' }}</span>\n              </button>\n\n              <button\n                ui-button\n                [variant]=\"isSaved() ? 'default' : 'outline'\"\n                size=\"sm\"\n                class=\"h-8 gap-1.5 text-xs font-medium shadow-xs\"\n                (click)=\"isSaved.set(!isSaved())\"\n              >\n                <lucide-icon [img]=\"Bookmark\" [class]=\"isSaved() ? 'size-3.5 fill-current' : 'size-3.5'\" />\n                <span>{{ isSaved() ? 'Saved Neighborhood' : 'Save Area' }}</span>\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\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        <div\n          ui-card\n          class=\"border-border/80 bg-card text-card-foreground hover:border-success/40 shadow-xs transition-colors\"\n        >\n          <div ui-card-header 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                  <lucide-icon [img]=\"Footprints\" class=\"size-4\" />\n                </div>\n                <div>\n                  <h3 ui-card-title class=\"text-sm font-semibold\">{{ walkScore.label }}</h3>\n                  <p ui-card-description class=\"text-xs\">Pedestrian Index</p>\n                </div>\n              </div>\n              <span ui-badge wrap variant=\"success\" class=\"text-xs font-semibold\">{{ walkScore.score }}/100</span>\n            </div>\n          </div>\n\n          <div ui-card-content 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                    [attr.stroke]=\"walkScore.gaugeColor\"\n                    stroke-width=\"7\"\n                    stroke-linecap=\"round\"\n                    [attr.stroke-dasharray]=\"gaugeCircumference\"\n                    [attr.stroke-dashoffset]=\"gaugeOffset(walkScore.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                    {{ walkScore.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\">{{ walkScore.verdict }}</div>\n                <p class=\"text-success text-xs leading-relaxed font-semibold\">{{ walkScore.description }}</p>\n              </div>\n            </div>\n\n            <ui-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                @for (item of walkScore.highlights; track item) {\n                  <li class=\"text-foreground flex items-center gap-2\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3.5 shrink-0\" />\n                    <span>{{ item }}</span>\n                  </li>\n                }\n              </ul>\n            </div>\n          </div>\n        </div>\n\n        <!-- Card 2: Transit Score -->\n        <div\n          ui-card\n          class=\"border-border/80 bg-card text-card-foreground hover:border-info/40 shadow-xs transition-colors\"\n        >\n          <div ui-card-header 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                  <lucide-icon [img]=\"Bus\" class=\"size-4\" />\n                </div>\n                <div>\n                  <h3 ui-card-title class=\"text-sm font-semibold\">{{ transitScore.label }}</h3>\n                  <p ui-card-description class=\"text-xs\">Transit Connectivity</p>\n                </div>\n              </div>\n              <span ui-badge wrap variant=\"info\" class=\"text-xs font-semibold\">{{ transitScore.score }}/100</span>\n            </div>\n          </div>\n\n          <div ui-card-content 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                    [attr.stroke]=\"transitScore.gaugeColor\"\n                    stroke-width=\"7\"\n                    stroke-linecap=\"round\"\n                    [attr.stroke-dasharray]=\"gaugeCircumference\"\n                    [attr.stroke-dashoffset]=\"gaugeOffset(transitScore.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                    {{ transitScore.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\">{{ transitScore.verdict }}</div>\n                <p class=\"text-info text-xs leading-relaxed font-semibold\">{{ transitScore.description }}</p>\n              </div>\n            </div>\n\n            <ui-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                @for (item of transitScore.highlights; track item) {\n                  <li class=\"text-foreground flex items-center gap-2\">\n                    <lucide-icon [img]=\"Check\" class=\"text-info size-3.5 shrink-0\" />\n                    <span>{{ item }}</span>\n                  </li>\n                }\n              </ul>\n            </div>\n          </div>\n        </div>\n\n        <!-- Card 3: Bike Score -->\n        <div\n          ui-card\n          class=\"border-border/80 bg-card text-card-foreground hover:border-chart-1/40 shadow-xs transition-colors\"\n        >\n          <div ui-card-header 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                  <lucide-icon [img]=\"Bike\" class=\"size-4\" />\n                </div>\n                <div>\n                  <h3 ui-card-title class=\"text-sm font-semibold\">{{ bikeScore.label }}</h3>\n                  <p ui-card-description class=\"text-xs\">Cycling Grid</p>\n                </div>\n              </div>\n              <span ui-badge wrap variant=\"outline\" class=\"text-xs font-semibold\">{{ bikeScore.score }}/100</span>\n            </div>\n          </div>\n\n          <div ui-card-content 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                    [attr.stroke]=\"bikeScore.gaugeColor\"\n                    stroke-width=\"7\"\n                    stroke-linecap=\"round\"\n                    [attr.stroke-dasharray]=\"gaugeCircumference\"\n                    [attr.stroke-dashoffset]=\"gaugeOffset(bikeScore.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                    {{ bikeScore.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\">{{ bikeScore.verdict }}</div>\n                <p class=\"text-chart-1 text-xs leading-relaxed font-semibold\">{{ bikeScore.description }}</p>\n              </div>\n            </div>\n\n            <ui-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                @for (item of bikeScore.highlights; track item) {\n                  <li class=\"text-foreground flex items-center gap-2\">\n                    <lucide-icon [img]=\"Check\" class=\"text-chart-1 size-3.5 shrink-0\" />\n                    <span>{{ item }}</span>\n                  </li>\n                }\n              </ul>\n            </div>\n          </div>\n        </div>\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 type=\"button\" [class]=\"commuteModeClass('all')\" (click)=\"selectedCommuteMode.set('all')\">\n              All Modes\n            </button>\n            <button\n              type=\"button\"\n              [class]=\"commuteModeIconClass('transit')\"\n              (click)=\"selectedCommuteMode.set('transit')\"\n            >\n              <lucide-icon [img]=\"Train\" class=\"size-3\" />\n              <span>Transit</span>\n            </button>\n            <button type=\"button\" [class]=\"commuteModeIconClass('drive')\" (click)=\"selectedCommuteMode.set('drive')\">\n              <lucide-icon [img]=\"Car\" class=\"size-3\" />\n              <span>Driving</span>\n            </button>\n          </div>\n        </div>\n\n        <div ui-card class=\"border-border/80 bg-card text-card-foreground overflow-hidden shadow-xs\">\n          <div class=\"divide-border/60 divide-y\">\n            @for (commute of commutes; track commute.id) {\n              <div class=\"hover:bg-muted/15 p-4 transition-colors sm:p-5\">\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\">\n                        &middot; {{ commute.distance }}\n                      </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                    @if (selectedCommuteMode() === 'all' || selectedCommuteMode() === 'transit') {\n                      <div\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                        <lucide-icon [img]=\"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\n                    <!-- Drive Mode Pill -->\n                    @if (selectedCommuteMode() === 'all' || selectedCommuteMode() === 'drive') {\n                      <div\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                        <lucide-icon [img]=\"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\n                    <!-- Peak Rush Info -->\n                    @if (commute.peakRushTime) {\n                      <div class=\"text-muted-foreground flex items-center gap-1 font-mono text-xs tabular-nums\">\n                        <lucide-icon [img]=\"Clock\" class=\"text-muted-foreground size-3\" />\n                        <span>Rush: {{ commute.peakRushTime }}</span>\n                      </div>\n                    }\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                  @if (selectedCommuteMode() === 'all' || selectedCommuteMode() === 'transit') {\n                    <div 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                      <ui-progress [value]=\"commutePct(commute.transitTime)\" class=\"bg-muted h-1.5\" />\n                    </div>\n                  }\n\n                  @if (selectedCommuteMode() === 'all' || selectedCommuteMode() === 'drive') {\n                    <div 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                      <ui-progress [value]=\"commutePct(commute.driveTime)\" class=\"bg-muted h-1.5\" />\n                    </div>\n                  }\n                </div>\n              </div>\n            }\n          </div>\n        </div>\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            <lucide-icon [img]=\"Navigation\" class=\"text-primary size-3.5\" />\n            <span class=\"font-mono tabular-nums\">{{ pois.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            @for (cat of categoriesList(); track cat.id) {\n              <button type=\"button\" [class]=\"categoryClass(cat.id)\" (click)=\"selectedCategory.set(cat.id)\">\n                {{ cat.label }}\n                <span [class]=\"categoryCountClass(cat.id)\">({{ cat.count }})</span>\n              </button>\n            }\n          </div>\n\n          <!-- Search Input -->\n          <div class=\"relative w-full sm:w-64\">\n            <lucide-icon\n              [img]=\"Search\"\n              class=\"text-muted-foreground pointer-events-none absolute top-2.5 left-2.5 size-3.5\"\n            />\n            <input\n              type=\"text\"\n              [value]=\"searchQuery()\"\n              (input)=\"searchQuery.set($any($event.target).value)\"\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        <div ui-card class=\"overflow-hidden\">\n          <div ui-card-header 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                <h3 ui-card-title class=\"flex items-center gap-2 text-base font-semibold\">\n                  <lucide-icon [img]=\"Navigation\" class=\"text-success size-4\" />\n                  <span>15-Minute Walkshed & Amenity Locator</span>\n                </h3>\n                <p ui-card-description>\n                  Mapbox street basemap with 15-minute isochrone walking perimeter and categorized local destinations.\n                </p>\n              </div>\n              <span ui-badge wrap variant=\"outline\" class=\"w-fit gap-1 font-mono text-xs\">\n                <lucide-icon [img]=\"Footprints\" class=\"text-success size-3\" />\n                <span>98 Walk Score Paradise</span>\n              </span>\n            </div>\n          </div>\n          <div class=\"relative h-72 w-full sm:h-96\">\n            <ui-map\n              variant=\"dark\"\n              [accessToken]=\"accessToken ?? ''\"\n              [center]=\"homeCenter\"\n              [zoom]=\"14.2\"\n              class=\"size-full\"\n            >\n              <!-- Isochrone 15-min Walk Circle -->\n              <ui-map-source id=\"walkshed-source\" type=\"geojson\" [data]=\"walkshedGeoJson()\">\n                <ui-map-layer id=\"walkshed-fill\" type=\"fill\" [paint]=\"walkshedFillPaint\" />\n                <ui-map-layer id=\"walkshed-line\" type=\"line\" [paint]=\"walkshedLinePaint\" />\n              </ui-map-source>\n\n              <!-- Home Property Marker -->\n              <ui-map-marker [lngLat]=\"homeCenter\" anchor=\"center\">\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\"></span>\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                    <lucide-icon [img]=\"MapPin\" class=\"size-4\" />\n                  </div>\n                </div>\n              </ui-map-marker>\n\n              <!-- Filtered POI Markers -->\n              @for (poi of filteredPois(); track poi.id) {\n                <ui-map-marker [lngLat]=\"poiCoords(poi)\" anchor=\"center\">\n                  <div\n                    class=\"border-background bg-background flex size-7 items-center justify-center rounded-full border-2 shadow-md\"\n                    [attr.title]=\"poi.name\"\n                  >\n                    @if (poi.category === 'dining') {\n                      <lucide-icon [img]=\"Coffee\" class=\"text-warning size-3.5\" />\n                    } @else if (poi.category === 'transit') {\n                      <lucide-icon [img]=\"Train\" class=\"text-info size-3.5\" />\n                    } @else if (poi.category === 'schools') {\n                      <lucide-icon [img]=\"School\" class=\"text-chart-2 size-3.5\" />\n                    } @else {\n                      <lucide-icon [img]=\"TreePine\" class=\"text-success size-3.5\" />\n                    }\n                  </div>\n                </ui-map-marker>\n              }\n            </ui-map>\n          </div>\n        </div>\n\n        <!-- POIs Grid -->\n        @if (filteredPois().length > 0) {\n          <div class=\"grid grid-cols-1 gap-3 md:grid-cols-2\">\n            @for (poi of filteredPois(); track poi.id) {\n              <div\n                ui-card\n                class=\"border-border/80 bg-card text-card-foreground hover:border-border transition-colors hover:shadow-xs\"\n              >\n                <div ui-card-content class=\"p-4 sm:p-4\">\n                  <div class=\"flex items-start gap-3\">\n                    <!-- Icon Box based on category -->\n                    <div [class]=\"poiIconClass(poi)\">\n                      @if (poi.category === 'transit' && poi.badge === 'Light Rail') {\n                        <lucide-icon [img]=\"Train\" class=\"size-4\" />\n                      } @else if (poi.category === 'transit') {\n                        <lucide-icon [img]=\"Bus\" class=\"size-4\" />\n                      } @else if (poi.category === 'dining' && poi.name.includes('Coffee')) {\n                        <lucide-icon [img]=\"Coffee\" class=\"size-4\" />\n                      } @else if (poi.category === 'dining') {\n                        <lucide-icon [img]=\"UtensilsCrossed\" class=\"size-4\" />\n                      } @else if (poi.category === 'schools' && poi.name.includes('Caltech')) {\n                        <lucide-icon [img]=\"GraduationCap\" class=\"size-4\" />\n                      } @else if (poi.category === 'schools') {\n                        <lucide-icon [img]=\"School\" class=\"size-4\" />\n                      } @else {\n                        <lucide-icon [img]=\"TreePine\" class=\"size-4\" />\n                      }\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\">{{ poi.name }}</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                          @if (poi.timeWalk) {\n                            <span class=\"text-muted-foreground\"> &middot; {{ poi.timeWalk }}</span>\n                          }\n                          @if (poi.timeDrive) {\n                            <span class=\"text-muted-foreground\"> &middot; {{ poi.timeDrive }}</span>\n                          }\n                        </div>\n                      </div>\n\n                      <p class=\"text-muted-foreground line-clamp-2 text-xs leading-relaxed\">{{ poi.description }}</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                          @if (poi.rating) {\n                            <span\n                              ui-badge\n                              wrap\n                              variant=\"secondary\"\n                              class=\"font-mono text-xs font-semibold tabular-nums\"\n                            >\n                              {{ poi.rating }}\n                            </span>\n                          }\n                          @if (poi.badge) {\n                            <span ui-badge wrap variant=\"outline\" class=\"text-xs\">{{ poi.badge }}</span>\n                          }\n                        </div>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            }\n          </div>\n        } @else {\n          <!-- Empty State when filter yields nothing -->\n          <div ui-card 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              <lucide-icon [img]=\"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 ui-button variant=\"outline\" size=\"sm\" class=\"mt-2 text-xs\" (click)=\"clearFilters()\">\n                Clear Filters\n              </button>\n            </div>\n          </div>\n        }\n      </div>\n\n      <!-- Section 4: Quick Neighborhood Summary Footnote -->\n      <div ui-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              <lucide-icon [img]=\"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\n              road grades.\n            </p>\n          </div>\n\n          <div class=\"flex items-center gap-3\">\n            <button\n              ui-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              <lucide-icon [img]=\"ArrowUpRight\" class=\"size-3.5\" />\n              <span>Open in Maps</span>\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiNeighborhoodWalkscoreCardComponent {\n  protected readonly ArrowUpRight = ArrowUpRight\n  protected readonly Bike = Bike\n  protected readonly Bookmark = Bookmark\n  protected readonly Bus = Bus\n  protected readonly Car = Car\n  protected readonly Check = Check\n  protected readonly Clock = Clock\n  protected readonly Coffee = Coffee\n  protected readonly Footprints = Footprints\n  protected readonly GraduationCap = GraduationCap\n  protected readonly MapPin = MapPin\n  protected readonly Navigation = Navigation\n  protected readonly School = School\n  protected readonly Search = Search\n  protected readonly Share2 = Share2\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Train = Train\n  protected readonly TreePine = TreePine\n  protected readonly UtensilsCrossed = UtensilsCrossed\n\n  protected readonly gaugeCircumference = GAUGE_CIRCUMFERENCE\n  protected readonly homeCenter = HOME_CENTER\n\n  protected readonly walkshedFillPaint = { 'fill-color': 'rgba(16, 185, 129, 0.12)' }\n  protected readonly walkshedLinePaint = {\n    'line-color': 'rgba(16, 185, 129, 0.6)',\n    'line-width': 1.5,\n    'line-dasharray': [2, 2],\n  }\n\n  @Input() title = 'Neighborhood & Location Intelligence'\n  @Input() address = '742 Evergreen Terrace, Pasadena, CA 91101'\n  @Input() neighborhood = 'South Lake Commercial & Arts District'\n  @Input() city = 'Pasadena'\n  @Input() zipCode = '91101'\n  @Input() walkScore: MobilityScore = defaultWalkScore\n  @Input() transitScore: MobilityScore = defaultTransitScore\n  @Input() bikeScore: MobilityScore = defaultBikeScore\n  @Input() pois: PoiItem[] = defaultPois\n  @Input() commutes: CommuteDestination[] = defaultCommutes\n  @Input() accessToken?: string\n  @Input('class') className?: string\n\n  readonly selectedCategory = signal<PoiCategoryType>('all')\n  readonly searchQuery = signal('')\n  readonly selectedCommuteMode = signal<CommuteMode>('all')\n  readonly isSaved = signal(false)\n  readonly isCopied = signal(false)\n\n  readonly categoriesList = computed(() => {\n    const pois = this.pois\n    return [\n      { id: 'all' as const, label: 'All Places', count: pois.length },\n      { id: 'transit' as const, label: 'Public Transit', count: pois.filter((p) => p.category === 'transit').length },\n      { id: 'dining' as const, label: 'Dining & Coffee', count: pois.filter((p) => p.category === 'dining').length },\n      {\n        id: 'schools' as const,\n        label: 'Schools & Education',\n        count: pois.filter((p) => p.category === 'schools').length,\n      },\n      { id: 'parks' as const, label: 'Parks & Rec', count: pois.filter((p) => p.category === 'parks').length },\n    ]\n  })\n\n  readonly filteredPois = computed(() => {\n    const pois = this.pois\n    const selected = this.selectedCategory()\n    const query = this.searchQuery().trim().toLowerCase()\n    return pois.filter((poi) => {\n      const matchesCat = selected === 'all' || poi.category === selected\n      const matchesSearch =\n        query === '' ||\n        poi.name.toLowerCase().includes(query) ||\n        poi.description.toLowerCase().includes(query) ||\n        poi.address.toLowerCase().includes(query) ||\n        (poi.badge?.toLowerCase().includes(query) ?? false)\n      return matchesCat && matchesSearch\n    })\n  })\n\n  readonly walkshedGeoJson = computed(() => {\n    const [centerLng, centerLat] = HOME_CENTER\n    const radius = 0.011\n    const points = 36\n    const coordinates: [number, number][] = []\n    for (let i = 0; i <= points; i++) {\n      const angle = (i * 2 * Math.PI) / points\n      coordinates.push([centerLng + Math.cos(angle) * radius * 1.2, centerLat + Math.sin(angle) * radius])\n    }\n    return {\n      type: 'Feature' as const,\n      properties: {},\n      geometry: { type: 'Polygon' as const, coordinates: [coordinates] },\n    }\n  })\n\n  get rootClass(): string {\n    return cn('w-full space-y-6', this.className)\n  }\n\n  gaugeOffset(score: number): number {\n    return getGaugeDashOffset(score)\n  }\n\n  commutePct(minutes: number): number {\n    return Math.min(100, (minutes / 70) * 100)\n  }\n\n  categoryCount(id: PoiCategoryType): number {\n    return this.categoriesList().find((c) => c.id === id)?.count ?? 0\n  }\n\n  categoryClass(id: PoiCategoryType): string {\n    return cn(\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      this.selectedCategory() === 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  }\n\n  categoryCountClass(id: PoiCategoryType): string {\n    return cn('ml-1 font-mono tabular-nums', this.selectedCategory() === id ? 'opacity-80' : 'text-muted-foreground')\n  }\n\n  commuteModeClass(mode: CommuteMode): string {\n    return cn(\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      this.selectedCommuteMode() === mode\n        ? 'bg-background text-foreground shadow-xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  commuteModeIconClass(mode: CommuteMode): string {\n    return cn(\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      this.selectedCommuteMode() === mode\n        ? 'bg-background text-foreground shadow-xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  poiIconClass(poi: PoiItem): string {\n    return cn(\n      'flex size-9 shrink-0 items-center justify-center rounded-lg border',\n      poi.category === 'transit' && 'border-info/30 bg-info/10 text-info',\n      poi.category === 'dining' && 'border-warning/30 bg-warning/10 text-warning',\n      poi.category === 'schools' && 'border-chart-2/30 bg-chart-2/10 text-chart-2',\n      poi.category === 'parks' && 'border-success/30 bg-success/10 text-success',\n    )\n  }\n\n  poiCoords(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\n  clearFilters(): void {\n    this.searchQuery.set('')\n    this.selectedCategory.set('all')\n  }\n\n  handleCopyAddress(): void {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      void navigator.clipboard.writeText(`${this.address}, ${this.neighborhood}`)\n      this.isCopied.set(true)\n      setTimeout(() => this.isCopied.set(false), 2000)\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/neighborhood-walkscore-card/neighborhood-walkscore-card.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/neighborhood-walkscore-card/index.ts",
      "content": "export {\n  UiNeighborhoodWalkscoreCardComponent,\n  getGaugeDashOffset,\n  GAUGE_CIRCUMFERENCE,\n  type PoiCategoryType,\n  type CommuteMode,\n  type MobilityScore,\n  type PoiItem,\n  type CommuteDestination,\n} from './neighborhood-walkscore-card.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/neighborhood-walkscore-card/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/progress.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/map.json"
  ],
  "description": "Real estate neighborhood intelligence widget with Walk Score, Transit Score, Bike Score, categorized points of interest (transit, dining, schools, parks), and commute time estimator.",
  "categories": [
    "real-estate",
    "app",
    "dashboard",
    "marketing"
  ]
}