diff --git a/movie-group-8/src/components/Navbar.vue b/movie-group-8/src/components/Navbar.vue
index 64d7e5700bc6baec7c66c76e9357bbc787de6f9e..ea83fa1aa0b41228417ff9b2171d64bbefc33573 100644
--- a/movie-group-8/src/components/Navbar.vue
+++ b/movie-group-8/src/components/Navbar.vue
@@ -11,6 +11,7 @@
     <div class="absolute left-1/2 transform -translate-x-1/2 w-full max-w-md">
       <input
         v-model="searchQuery"
+        @keyup.enter="handleSearch"
         type="text"
         placeholder="Search..."
         class="w-full px-4 py-2 pr-10 rounded-full bg-neutral-700 text-white placeholder-gray-400 focus:ring-2 focus:ring-white focus:outline-none"
@@ -83,13 +84,12 @@ const route = useRoute();
 const router = useRouter();
 const isLoggedIn = ref(false);
 const userPhotoURL = ref(''); 
+const searchQuery = ref('');
 
 const navigation = ref([
   { name: 'Films', href: '/films', authRequired: true },
   { name: 'Watchlist', href: '/watchlist', authRequired: true },
-  { name: 'Top Rated', href: '/top-rated', authRequired: true },
   { name: 'Social', href: '/social', authRequired: true },
-
 ]);
 
 // Compute the current route to match against the navigation links
@@ -127,4 +127,10 @@ const handleSignOut = () => {
       console.error("Error signing out:", error);
     });
 };
+
+function handleSearch() {
+  if (searchQuery.value.trim()) {
+    router.push({ path: '/films', query: { q: searchQuery.value.trim() } });
+  }
+}
 </script>
diff --git a/movie-group-8/src/components/WatchlistButton.vue b/movie-group-8/src/components/WatchlistButton.vue
index 91458232887237079c738f99224113fc42242682..7e68baada3c94af92dcf9ced1496881420471486 100644
--- a/movie-group-8/src/components/WatchlistButton.vue
+++ b/movie-group-8/src/components/WatchlistButton.vue
@@ -4,8 +4,8 @@
     @click="toggleWatchlist"
     class="mt-2 px-3 py-1 rounded text-white text-sm transition"
     :class="isInWatchlist
-      ? 'bg-red-600 hover:bg-red-700'
-      : 'bg-green-600 hover:bg-green-700'"
+      ? 'bg-red-600 hover:bg-red-700 border border-white'
+      : 'bg-neutral-700 hover:bg-neutral-800 border border-white'"
   >
     {{ isInWatchlist ? 'Remove from Watchlist' : 'Add to Watchlist' }}
   </button>
diff --git a/movie-group-8/src/stores/WatchlistStore.js b/movie-group-8/src/stores/WatchlistStore.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7cc82583eaabf3af1422f5c24b982991e0844e0
--- /dev/null
+++ b/movie-group-8/src/stores/WatchlistStore.js
@@ -0,0 +1,25 @@
+import { reactive } from 'vue';
+
+export const WatchlistStore = reactive({
+  watchlist: JSON.parse(localStorage.getItem('watchlist') || '[]'),
+
+  add(movie) {
+    if (!this.watchlist.find(m => m.id === movie.id)) {
+      this.watchlist.push(movie);
+      this.save();
+    }
+  },
+
+  remove(movie) {
+    this.watchlist = this.watchlist.filter(m => m.id !== movie.id);
+    this.save();
+  },
+
+  isInWatchlist(movie) {
+    return this.watchlist.some(m => m.id === movie.id);
+  },
+
+  save() {
+    localStorage.setItem('watchlist', JSON.stringify(this.watchlist));
+  }
+});
diff --git a/movie-group-8/src/views/Films.vue b/movie-group-8/src/views/Films.vue
index 2343d26e7e79942a734e33569c7a9d2b783a2e5a..05b38809ea0761ad318f2f634ff36f8cc770a2f1 100644
--- a/movie-group-8/src/views/Films.vue
+++ b/movie-group-8/src/views/Films.vue
@@ -1,107 +1,148 @@
 <template>
-  <div class="films-container">
-    <!-- Centered search bar pushed down slightly -->
-    <div class="search-wrapper">
-      <input
-        v-model="term"
-        @keyup.enter="onSearch"
-        placeholder="Search movies…"
-        class="search-input"
-      />
-    </div>
-
-    <div v-if="loading" class="loading">Loading…</div>
-    <div v-else-if="error" class="error">Error: {{ error.message }}</div>
+  <div class="bg-neutral-900 min-h-screen py-10 px-6 sm:px-10">
+    <div class="max-w-[85rem] mx-auto mt-12">
+      <!-- Title and Filters -->
+      <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-10">
+        <h2 class="text-3xl font-semibold text-white">
+          {{ computedTitle }}
+        </h2>
+        <div class="flex flex-col sm:flex-row sm:items-center gap-4">
+          <select v-model="genre" @change="fetchFiltered" class="px-4 py-2 rounded-lg border border-neutral-700 bg-neutral-800 text-white">
+            <option value="">All Genres</option>
+            <option v-for="g in genres" :key="g.id" :value="g.id">{{ g.name }}</option>
+          </select>
+          <select v-model.number="year" @change="fetchFiltered" class="px-4 py-2 rounded-lg border border-neutral-700 bg-neutral-800 text-white">
+            <option value="">All Years</option>
+            <option v-for="y in years" :key="y" :value="y">{{ y }}</option>
+          </select>
+        </div>
+      </div>
 
-    <!-- Movie grid -->
-    <MovieList :movies="results" />
+      <!-- Movie Cards -->
+      <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
+        <div
+          v-for="movie in results"
+          :key="movie.id"
+          @click="goToMovie(movie.id)"
+          class="group flex flex-col h-full bg-neutral-800 hover:bg-neutral-700 cursor-pointer border border-gray-200 shadow-2xs rounded-xl dark:border-neutral-700 dark:shadow-neutral-700/70 text-sm transition-colors duration-150"
+        >
+          <div class="rounded-t-xl overflow-hidden">
+            <img v-if="movie.poster_path" :src="imgUrl(movie.poster_path)" alt="" class="w-full object-contain rounded-t-xl"/>
+          </div>
+          <div class="p-3 flex flex-col flex-grow">
+            <h3 class="text-base font-semibold text-gray-200 dark:hover:text-white">
+              {{ movie.title }}
+            </h3>
+            <p class="mt-2 text-gray-400 dark:text-neutral-400 line-clamp-3">
+              {{ movie.overview || 'No description available.' }}
+            </p>
+          </div>
+          <div class="mt-auto flex justify-between items-center border-t border-gray-200 dark:border-neutral-700 px-3 py-2">
+            <span class="text-xs font-semibold text-blue-400">
+              ⭐ {{ movie.vote_average.toFixed(1) }}
+            </span>
+            <WatchlistButton :movie="movie" @click.stop />
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script setup>
-import { ref, onMounted } from 'vue'
+import { ref, onMounted, computed, watch } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
 import axios from 'axios'
-import MovieList from '../components/MovieList.vue'
+import WatchlistButton from '@/components/WatchlistButton.vue'
 
 const API_KEY = import.meta.env.VITE_TMDB_API_KEY
-const BASE    = import.meta.env.VITE_TMDB_BASE
+const BASE = import.meta.env.VITE_TMDB_BASE
 
-const term    = ref('')
+const route = useRoute()
+const router = useRouter()
+
+const term = ref(route.query.q || '')
 const results = ref([])
+const genres = ref([])
+const genre = ref('')
+const year = ref('')
 const loading = ref(false)
-const error   = ref(null)
-
-async function search(query) {
-  loading.value = true
-  error.value   = null
-  try {
-    const { data } = await axios.get(`${BASE}/search/movie`, {
-      params: { api_key: API_KEY, query }
-    })
-    results.value = data.results
-  } catch (e) {
-    error.value = e
-  } finally {
-    loading.value = false
-  }
+const error = ref(null)
+
+const years = Array.from({ length: 25 }, (_, i) => 2000 + i)
+
+function imgUrl(path) {
+  return `https://image.tmdb.org/t/p/w342${path}`
 }
 
-async function fetchPopular() {
-  loading.value = true
-  error.value   = null
-  try {
-    const { data } = await axios.get(`${BASE}/movie/popular`, {
-      params: { api_key: API_KEY }
-    })
-    results.value = data.results
-  } catch (e) {
-    error.value = e
-  } finally {
-    loading.value = false
-  }
+async function fetchGenres() {
+  const { data } = await axios.get(`${BASE}/genre/movie/list`, {
+    params: { api_key: API_KEY },
+  })
+  genres.value = data.genres
 }
 
-function onSearch() {
-  if (term.value.trim()) {
-    search(term.value)
-  } else {
-    fetchPopular()
-  }
+async function fetchTopRated() {
+  const { data } = await axios.get(`${BASE}/movie/top_rated`, {
+    params: { api_key: API_KEY },
+  })
+  results.value = data.results
 }
 
-onMounted(fetchPopular)
-</script>
+async function fetchFiltered() {
+  let url = `${BASE}/discover/movie`
+  const params = {
+    api_key: API_KEY,
+    sort_by: 'vote_average.desc',
+    'vote_count.gte': 100,
+    with_genres: genre.value || undefined,
+    primary_release_year: year.value || undefined,
+  }
 
-<style scoped>
-.films-container {
-  padding-top: 5rem; /* adjust to nav height + spacing */
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  width: 100%;
+  const { data } = await axios.get(url, { params })
+  results.value = data.results
 }
 
-.search-wrapper {
-  width: 100%;
-  max-width: 500px;
-  margin-bottom: 1.5rem;
-  display: flex;
-  justify-content: center;
-  color: white;
+async function onSearch() {
+  if (!term.value) return fetchTopRated()
+  const { data } = await axios.get(`${BASE}/search/movie`, {
+    params: { api_key: API_KEY, query: term.value },
+  })
+  results.value = data.results
 }
 
-.search-input {
-  width: 100%;
-  padding: 0.75rem 1rem;
-  font-size: 1.1rem;
-  border: 1px solid #ccc;
-  border-radius: 4px;
-  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+watch(() => route.query.q, async (newQuery) => {
+  term.value = newQuery || ''
+  await onSearch()
+})
+
+function goToMovie(id) {
+  router.push(`/films/${id}`)
 }
 
-.loading,
-.error {
-  margin: 1rem 0;
-  font-weight: bold;
+const computedTitle = computed(() => {
+  const genreName = genres.value.find(g => g.id === Number(genre.value))?.name
+  if (genreName && year.value) return `Top Rated ${genreName} ${year.value}`
+  if (genreName) return `Top Rated ${genreName}`
+  if (year.value) return `Top Rated ${year.value}`
+  return 'Top Rated'
+})
+
+onMounted(async () => {
+  await fetchGenres()
+  if (term.value) {
+    await onSearch()
+  } else {
+    await fetchTopRated()
+  }
+})
+</script>
+
+<style scoped>
+.line-clamp-3 {
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
 }
 </style>
diff --git a/movie-group-8/src/views/Home.vue b/movie-group-8/src/views/Home.vue
index 04089a56d0655779a1cbdd2d067b22e84be646be..1a9c377eb4f21196b953e02fe6d1182681642b63 100644
--- a/movie-group-8/src/views/Home.vue
+++ b/movie-group-8/src/views/Home.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="h-full bg-neutral-900 p-6">
+    <div class="min-h-screen bg-neutral-900 p-6">
       <div class="max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto dark">
         <div class="relative p-6 md:p-16">
           <div class="relative z-10 lg:grid lg:grid-cols-12 lg:gap-16 lg:items-center">