{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "isochrone-reachability-map",
  "title": "Isochrone Reachability Map",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/isochrone-reachability-map/IsochroneReachabilityMap.tsx",
      "content": "'use client'\n\nimport { useState, useRef } from 'react'\nimport { Map, MapMarker, MapSource, MapLayer, type MapRef } from '@/components/ui/map'\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'\nimport { Badge } from '@/components/ui/badge'\n\nexport interface IsochroneReachabilityMapProps {\n  accessToken?: string\n}\n\nexport function IsochroneReachabilityMap({ accessToken }: IsochroneReachabilityMapProps) {\n  const mapRef = useRef<MapRef | null>(null)\n  const [selectedTime, setSelectedTime] = useState<10 | 20 | 30>(20)\n\n  const hubLocation: [number, number] = [-87.6298, 41.8781] // Chicago Loop\n\n  function createIsochroneCoords(radiusMiles: number): [number, number][] {\n    const points: [number, number][] = []\n    const steps = 36\n    const latDelta = radiusMiles / 69\n    const lngDelta = radiusMiles / (69 * Math.cos((41.8781 * Math.PI) / 180))\n    for (let i = 0; i <= steps; i++) {\n      const angle = (i / steps) * 2 * Math.PI\n      const jitter = 1 + Math.sin(angle * 3) * 0.12\n      const lng = hubLocation[0] + lngDelta * Math.cos(angle) * jitter\n      const lat = hubLocation[1] + latDelta * Math.sin(angle) * jitter\n      points.push([lng, lat])\n    }\n    return points\n  }\n\n  const isochrones = {\n    10: { coords: createIsochroneCoords(2.8), pop: '340K', jobs: '520K', color: '#10b981', label: '10 Min Commute' },\n    20: { coords: createIsochroneCoords(6.2), pop: '1.24M', jobs: '890K', color: '#3b82f6', label: '20 Min Commute' },\n    30: { coords: createIsochroneCoords(11.5), pop: '2.85M', jobs: '1.45M', color: '#f59e0b', label: '30 Min Commute' },\n  }\n\n  return (\n    <div className=\"grid gap-4 lg:grid-cols-[1fr_320px]\">\n      <div className=\"border-border bg-card relative h-[480px] overflow-hidden rounded-xl border\">\n        <Map\n          ref={mapRef}\n          accessToken={accessToken}\n          variant=\"light\"\n          center={hubLocation}\n          zoom={10.8}\n          className=\"h-full w-full\"\n        >\n          {/* 30m Isochrone Fill & Line */}\n          <MapSource\n            id=\"iso-30\"\n            options={{\n              type: 'geojson',\n              data: {\n                type: 'Feature',\n                properties: {},\n                geometry: { type: 'Polygon', coordinates: [isochrones[30].coords] },\n              },\n            }}\n          />\n          <MapLayer\n            id=\"iso-30-fill\"\n            options={{\n              type: 'fill',\n              source: 'iso-30',\n              paint: { 'fill-color': '#f59e0b', 'fill-opacity': selectedTime >= 30 ? 0.15 : 0.04 },\n            }}\n          />\n          <MapLayer\n            id=\"iso-30-line\"\n            options={{\n              type: 'line',\n              source: 'iso-30',\n              paint: { 'line-color': '#f59e0b', 'line-width': 1.5, 'line-dasharray': [2, 2] },\n            }}\n          />\n\n          {/* 20m Isochrone Fill & Line */}\n          <MapSource\n            id=\"iso-20\"\n            options={{\n              type: 'geojson',\n              data: {\n                type: 'Feature',\n                properties: {},\n                geometry: { type: 'Polygon', coordinates: [isochrones[20].coords] },\n              },\n            }}\n          />\n          <MapLayer\n            id=\"iso-20-fill\"\n            options={{\n              type: 'fill',\n              source: 'iso-20',\n              paint: { 'fill-color': '#3b82f6', 'fill-opacity': selectedTime >= 20 ? 0.22 : 0.06 },\n            }}\n          />\n          <MapLayer\n            id=\"iso-20-line\"\n            options={{\n              type: 'line',\n              source: 'iso-20',\n              paint: { 'line-color': '#3b82f6', 'line-width': 2 },\n            }}\n          />\n\n          {/* 10m Isochrone Fill & Line */}\n          <MapSource\n            id=\"iso-10\"\n            options={{\n              type: 'geojson',\n              data: {\n                type: 'Feature',\n                properties: {},\n                geometry: { type: 'Polygon', coordinates: [isochrones[10].coords] },\n              },\n            }}\n          />\n          <MapLayer\n            id=\"iso-10-fill\"\n            options={{\n              type: 'fill',\n              source: 'iso-10',\n              paint: { 'fill-color': '#10b981', 'fill-opacity': 0.3 },\n            }}\n          />\n          <MapLayer\n            id=\"iso-10-line\"\n            options={{\n              type: 'line',\n              source: 'iso-10',\n              paint: { 'line-color': '#10b981', 'line-width': 2.5 },\n            }}\n          />\n\n          {/* Central Hub Marker */}\n          <MapMarker lngLat={hubLocation} anchor=\"center\">\n            <div className=\"relative flex items-center justify-center\">\n              <span className=\"bg-primary/30 absolute size-6 animate-ping rounded-full\" />\n              <div className=\"bg-primary text-primary-foreground ring-background flex size-6 items-center justify-center rounded-full font-mono text-xs font-bold shadow-md ring-2\">\n                ★\n              </div>\n            </div>\n          </MapMarker>\n        </Map>\n      </div>\n\n      {/* Isochrone Analytics Card */}\n      <Card className=\"flex flex-col justify-between\">\n        <CardHeader>\n          <div className=\"flex items-center justify-between\">\n            <Badge variant=\"outline\" className=\"font-mono text-xs\">\n              COMMUTE ANALYSIS\n            </Badge>\n            <Badge className=\"border-info/20 bg-info/10 text-info\">Drive-Time</Badge>\n          </div>\n          <CardTitle className=\"mt-2 text-lg\">Reachability Zones</CardTitle>\n          <CardDescription>Transit reachability from Downtown Distribution Hub.</CardDescription>\n        </CardHeader>\n        <CardContent className=\"space-y-4\">\n          <div className=\"border-border bg-muted grid grid-cols-3 gap-1 rounded-lg border p-1 text-xs\">\n            {([10, 20, 30] as const).map((t) => (\n              <button\n                key={t}\n                type=\"button\"\n                className={`rounded-md py-1.5 font-medium transition-colors ${\n                  selectedTime === t\n                    ? 'bg-background text-foreground shadow-xs'\n                    : 'text-muted-foreground hover:text-foreground'\n                }`}\n                onClick={() => setSelectedTime(t)}\n              >\n                {t} mins\n              </button>\n            ))}\n          </div>\n\n          <div className=\"border-border space-y-3 border-t pt-3\">\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-muted-foreground text-xs\">Population Reach</span>\n              <span className=\"text-foreground font-mono text-base font-bold\">{isochrones[selectedTime].pop}</span>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-muted-foreground text-xs\">Workforce / Labor Pool</span>\n              <span className=\"text-foreground font-mono text-base font-bold\">{isochrones[selectedTime].jobs}</span>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-muted-foreground text-xs\">Service Band</span>\n              <span className=\"font-mono text-xs font-semibold\" style={{ color: isochrones[selectedTime].color }}>\n                {isochrones[selectedTime].label}\n              </span>\n            </div>\n          </div>\n\n          <div className=\"border-border text-muted-foreground space-y-2 border-t pt-3 text-xs\">\n            <div className=\"flex items-center gap-2\">\n              <span className=\"bg-success size-2 rounded-full\" />\n              <span>Green ring: 10-minute urban core</span>\n            </div>\n            <div className=\"flex items-center gap-2\">\n              <span className=\"bg-info size-2 rounded-full\" />\n              <span>Blue ring: 20-minute metropolitan belt</span>\n            </div>\n            <div className=\"flex items-center gap-2\">\n              <span className=\"bg-warning size-2 rounded-full\" />\n              <span>Amber ring: 30-minute outer ring</span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/IsochroneReachabilityMap.tsx"
    }
  ],
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/map.json"
  ],
  "description": "Drive-time reachability zones showing 10m, 20m, and 30m commute polygons with workforce population metrics.",
  "categories": [
    "logistics",
    "geo",
    "map"
  ]
}