Index: petify-frontend/src/views/ProfileView.vue
===================================================================
--- petify-frontend/src/views/ProfileView.vue	(revision 92e7c7aeb21d4b882e2f8107b1676468ceb14aa7)
+++ petify-frontend/src/views/ProfileView.vue	(revision ae836471908c8a67e8fc2a25ad6c445b1c867e48)
@@ -94,5 +94,72 @@
               </button>
             </li>
+            <li class="nav-item" role="presentation">
+              <button
+                class="nav-link"
+                :class="{ active: activeTab === 'account' }"
+                @click="activeTab = 'account'"
+                type="button"
+                role="tab"
+              >
+                <i class="bi bi-shield-lock-fill"></i> Account
+              </button>
+            </li>
           </ul>
+
+          <!-- Account Tab -->
+          <div v-if="activeTab === 'account'" class="tab-content-section">
+            <h2 class="section-title">Account</h2>
+            <form class="password-form" @submit.prevent="submitPasswordChange">
+              <div v-if="passwordSuccess" class="alert alert-success" role="alert">
+                {{ passwordSuccess }}
+              </div>
+              <div v-if="passwordError" class="alert alert-danger" role="alert">
+                {{ passwordError }}
+              </div>
+
+              <div class="mb-3">
+                <label class="form-label" for="current-password">Current password</label>
+                <input
+                  id="current-password"
+                  v-model="passwordForm.currentPassword"
+                  class="form-control"
+                  type="password"
+                  autocomplete="current-password"
+                  required
+                />
+              </div>
+
+              <div class="mb-3">
+                <label class="form-label" for="new-password">New password</label>
+                <input
+                  id="new-password"
+                  v-model="passwordForm.newPassword"
+                  class="form-control"
+                  type="password"
+                  autocomplete="new-password"
+                  minlength="8"
+                  required
+                />
+              </div>
+
+              <div class="mb-4">
+                <label class="form-label" for="confirm-new-password">Confirm new password</label>
+                <input
+                  id="confirm-new-password"
+                  v-model="passwordForm.confirmPassword"
+                  class="form-control"
+                  type="password"
+                  autocomplete="new-password"
+                  minlength="8"
+                  required
+                />
+              </div>
+
+              <button class="btn btn-primary" type="submit" :disabled="isPasswordSubmitting">
+                <span v-if="isPasswordSubmitting" class="spinner-border spinner-border-sm me-2" aria-hidden="true"></span>
+                {{ isPasswordSubmitting ? 'Changing...' : 'Change password' }}
+              </button>
+            </form>
+          </div>
 
           <!-- Listings Tab -->
@@ -746,9 +813,10 @@
   type Review,
 } from '../api/reviews'
+import { changePassword } from '../api/auth'
 
 const router = useRouter()
 const auth = useAuthStore()
 
-const activeTab = ref<'listings' | 'pets' | 'create-listing' | 'favorites' | 'appointments'>('listings')
+const activeTab = ref<'listings' | 'pets' | 'create-listing' | 'favorites' | 'appointments' | 'account'>('listings')
 const listings = ref<any[]>([])
 const pets = ref<any[]>([])
@@ -782,4 +850,13 @@
 const petPhotoFile = ref<File | null>(null)
 const petPhotoPreview = ref('')
+const isPasswordSubmitting = ref(false)
+const passwordError = ref('')
+const passwordSuccess = ref('')
+
+const passwordForm = ref({
+  currentPassword: '',
+  newPassword: '',
+  confirmPassword: '',
+})
 
 const newListing = ref({
@@ -859,4 +936,41 @@
   // Fall back to petNameMap (from pets list)
   return petNameMap.value[animalId] || 'Unknown Pet'
+}
+
+async function submitPasswordChange() {
+  passwordError.value = ''
+  passwordSuccess.value = ''
+
+  if (!auth.user?.userId) {
+    passwordError.value = 'You need to be logged in to change your password.'
+    return
+  }
+  if (passwordForm.value.newPassword.length < 8) {
+    passwordError.value = 'New password must be at least 8 characters long.'
+    return
+  }
+  if (passwordForm.value.newPassword !== passwordForm.value.confirmPassword) {
+    passwordError.value = 'New passwords do not match.'
+    return
+  }
+
+  isPasswordSubmitting.value = true
+  try {
+    await changePassword({
+      userId: auth.user.userId,
+      currentPassword: passwordForm.value.currentPassword,
+      newPassword: passwordForm.value.newPassword,
+    })
+    passwordForm.value = {
+      currentPassword: '',
+      newPassword: '',
+      confirmPassword: '',
+    }
+    passwordSuccess.value = 'Password changed successfully.'
+  } catch (error: any) {
+    passwordError.value = error?.message || 'Failed to change password.'
+  } finally {
+    isPasswordSubmitting.value = false
+  }
 }
 
@@ -1670,4 +1784,8 @@
 }
 
+.password-form {
+  max-width: 520px;
+}
+
 @keyframes fadeIn {
   from {
