diff --git a/package-lock.json b/package-lock.json
index 524f51f..83055d2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,16 +29,19 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"framer-motion": "^12.42.2",
+ "leaflet": "^1.9.4",
"lucide-react": "^1.25.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-hook-form": "^7.82.0",
+ "react-leaflet": "^5.0.0",
"react-router-dom": "^7.18.1",
"tailwind-merge": "^3.6.0",
"zod": "^4.4.3"
},
"devDependencies": {
"@tailwindcss/vite": "^4.3.3",
+ "@types/leaflet": "^1.9.21",
"@types/node": "^24.13.3",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
@@ -1488,6 +1491,17 @@
"integrity": "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==",
"license": "MIT"
},
+ "node_modules/@react-leaflet/core": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz",
+ "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==",
+ "license": "Hippocratic-2.1",
+ "peerDependencies": {
+ "leaflet": "^1.9.0",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ }
+ },
"node_modules/@rolldown/binding-android-arm64": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz",
@@ -2378,6 +2392,23 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/geojson": {
+ "version": "7946.0.16",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
+ "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/leaflet": {
+ "version": "1.9.21",
+ "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz",
+ "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "24.13.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
@@ -3025,6 +3056,12 @@
"jiti": "lib/jiti-cli.mjs"
}
},
+ "node_modules/leaflet": {
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
+ "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/lightningcss": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
@@ -3536,6 +3573,20 @@
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
+ "node_modules/react-leaflet": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz",
+ "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==",
+ "license": "Hippocratic-2.1",
+ "dependencies": {
+ "@react-leaflet/core": "^3.0.0"
+ },
+ "peerDependencies": {
+ "leaflet": "^1.9.0",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ }
+ },
"node_modules/react-remove-scroll": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
diff --git a/package.json b/package.json
index ca451da..45f4392 100644
--- a/package.json
+++ b/package.json
@@ -31,16 +31,19 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"framer-motion": "^12.42.2",
+ "leaflet": "^1.9.4",
"lucide-react": "^1.25.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-hook-form": "^7.82.0",
+ "react-leaflet": "^5.0.0",
"react-router-dom": "^7.18.1",
"tailwind-merge": "^3.6.0",
"zod": "^4.4.3"
},
"devDependencies": {
"@tailwindcss/vite": "^4.3.3",
+ "@types/leaflet": "^1.9.21",
"@types/node": "^24.13.3",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
diff --git a/src/components/BusCard/BusCard.tsx b/src/components/BusCard/BusCard.tsx
index f44453e..e0511d9 100644
--- a/src/components/BusCard/BusCard.tsx
+++ b/src/components/BusCard/BusCard.tsx
@@ -5,9 +5,11 @@ import type { BusRoute } from '@/types';
interface BusCardProps {
route: BusRoute;
+ isSelected?: boolean;
+ onSelect?: () => void;
}
-export default function BusCard({ route }: BusCardProps) {
+export default function BusCard({ route, isSelected, onSelect }: BusCardProps) {
const [expanded, setExpanded] = useState(false);
return (
@@ -15,8 +17,14 @@ export default function BusCard({ route }: BusCardProps) {
layout
whileHover={{ y: -3 }}
transition={{ duration: 0.2 }}
- className="bg-white border border-[#E5E7EB] rounded-2xl overflow-hidden"
- style={{ boxShadow: '0 2px 15px -3px rgba(0,0,0,0.07)' }}
+ onClick={onSelect}
+ className={`bg-white border rounded-2xl overflow-hidden cursor-pointer transition-all ${
+ isSelected ? 'border-transparent shadow-lg scale-[1.01]' : 'border-[#E5E7EB]'
+ }`}
+ style={{
+ boxShadow: isSelected ? `0 10px 25px -5px ${route.color}25, 0 8px 10px -6px ${route.color}25` : '0 2px 15px -3px rgba(0,0,0,0.07)',
+ outline: isSelected ? `2px solid ${route.color}` : 'none'
+ }}
>
{/* Color Strip */}
@@ -71,7 +79,10 @@ export default function BusCard({ route }: BusCardProps) {
{/* Toggle Stops */}