diff --git a/fe/src/components/CreateExpenseForm.vue b/fe/src/components/CreateExpenseForm.vue
new file mode 100644
index 0000000..8bd66a0
--- /dev/null
+++ b/fe/src/components/CreateExpenseForm.vue
@@ -0,0 +1,346 @@
+<template>
+  <div class="modal-backdrop open" @click.self="closeForm">
+    <div class="modal-container" ref="formModalRef" style="min-width: 550px;">
+      <div class="modal-header">
+        <h3>Create New Expense</h3>
+        <button class="close-button" @click="closeForm" aria-label="Close">
+          <svg class="icon">
+            <use xlink:href="#icon-close" />
+          </svg>
+        </button>
+      </div>
+      <div class="modal-body">
+        <form @submit.prevent="handleSubmit" class="expense-form">
+          <div class="form-group">
+            <label for="description" class="form-label">Description</label>
+            <input
+              type="text"
+              id="description"
+              v-model="formData.description"
+              class="form-input"
+              required
+              placeholder="What was this expense for?"
+            />
+          </div>
+
+          <div class="form-group">
+            <label for="totalAmount" class="form-label">Total Amount</label>
+            <div class="amount-input-group">
+              <span class="currency-symbol">$</span>
+              <input
+                type="number"
+                id="totalAmount"
+                v-model.number="formData.total_amount"
+                class="form-input"
+                required
+                min="0.01"
+                step="0.01"
+                placeholder="0.00"
+              />
+            </div>
+          </div>
+
+          <div class="form-group">
+            <label for="splitType" class="form-label">Split Type</label>
+            <select
+              id="splitType"
+              v-model="formData.split_type"
+              class="form-input"
+              required
+            >
+              <option value="EQUAL">Equal Split</option>
+              <option value="EXACT_AMOUNTS">Exact Amounts</option>
+              <option value="PERCENTAGE">Percentage</option>
+              <option value="SHARES">Shares</option>
+              <option value="ITEM_BASED">Item Based</option>
+            </select>
+          </div>
+
+          <div class="form-group">
+            <label for="expenseDate" class="form-label">Date</label>
+            <input
+              type="date"
+              id="expenseDate"
+              v-model="formData.expense_date"
+              class="form-input"
+              :max="today"
+            />
+          </div>
+
+          <div v-if="formData.split_type !== 'EQUAL'" class="form-group">
+            <label class="form-label">Split Details</label>
+            <div v-if="formData.split_type === 'EXACT_AMOUNTS'" class="splits-container">
+              <div v-for="(split, index) in formData.splits_in" :key="index" class="split-item">
+                <input
+                  type="number"
+                  v-model.number="split.owed_amount"
+                  class="form-input"
+                  min="0.01"
+                  step="0.01"
+                  placeholder="Amount"
+                />
+                <button
+                  type="button"
+                  class="btn btn-danger btn-sm"
+                  @click="removeSplit(index)"
+                  :disabled="formData.splits_in.length <= 1"
+                >
+                  <svg class="icon icon-sm">
+                    <use xlink:href="#icon-trash" />
+                  </svg>
+                </button>
+              </div>
+              <button
+                type="button"
+                class="btn btn-secondary btn-sm"
+                @click="addSplit"
+              >
+                Add Split
+              </button>
+            </div>
+            <!-- Add other split type inputs here -->
+          </div>
+
+          <div class="form-actions">
+            <button type="button" class="btn btn-neutral" @click="closeForm">Cancel</button>
+            <button
+              type="submit"
+              class="btn btn-primary ml-2"
+              :disabled="isSubmitting"
+            >
+              <span v-if="isSubmitting" class="spinner-dots-sm"><span /><span /><span /></span>
+              <span v-else>Create Expense</span>
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, computed } from 'vue';
+import { apiClient, API_ENDPOINTS } from '@/config/api';
+import { useNotificationStore } from '@/stores/notifications';
+import type { ExpenseCreate } from '@/types/expense';
+import { onClickOutside } from '@vueuse/core';
+
+const props = defineProps<{
+  listId?: number;
+  groupId?: number;
+  itemId?: number;
+}>();
+
+const emit = defineEmits<{
+  (e: 'close'): void;
+  (e: 'created', expense: any): void;
+}>();
+
+const notificationStore = useNotificationStore();
+const formModalRef = ref<HTMLElement | null>(null);
+const isSubmitting = ref(false);
+
+const today = computed(() => {
+  const date = new Date();
+  return date.toISOString().split('T')[0];
+});
+
+const formData = ref<ExpenseCreate>({
+  description: '',
+  total_amount: 0,
+  currency: 'USD',
+  expense_date: today.value,
+  split_type: 'EQUAL',
+  list_id: props.listId,
+  group_id: props.groupId,
+  item_id: props.itemId,
+  paid_by_user_id: 0, // Will be set from auth store
+  splits_in: [{ owed_amount: 0 }]
+});
+
+const addSplit = () => {
+  formData.value.splits_in?.push({ owed_amount: 0 });
+};
+
+const removeSplit = (index: number) => {
+  if (formData.value.splits_in && formData.value.splits_in.length > 1) {
+    formData.value.splits_in.splice(index, 1);
+  }
+};
+
+const closeForm = () => {
+  emit('close');
+};
+
+const handleSubmit = async () => {
+  if (!formData.value.description || !formData.value.total_amount) {
+    notificationStore.addNotification({
+      message: 'Please fill in all required fields',
+      type: 'warning'
+    });
+    return;
+  }
+
+  isSubmitting.value = true;
+  try {
+    const response = await apiClient.post(API_ENDPOINTS.EXPENSES.CREATE, formData.value);
+    emit('created', response.data);
+    closeForm();
+    notificationStore.addNotification({
+      message: 'Expense created successfully',
+      type: 'success'
+    });
+  } catch (err) {
+    notificationStore.addNotification({
+      message: (err instanceof Error ? err.message : String(err)) || 'Failed to create expense',
+      type: 'error'
+    });
+  } finally {
+    isSubmitting.value = false;
+  }
+};
+
+onClickOutside(formModalRef, closeForm);
+</script>
+
+<style scoped>
+.expense-form {
+  display: flex;
+  flex-direction: column;
+  gap: 1rem;
+}
+
+.form-group {
+  display: flex;
+  flex-direction: column;
+  gap: 0.5rem;
+}
+
+.form-label {
+  font-weight: 600;
+  color: #333;
+}
+
+.form-input {
+  padding: 0.75rem;
+  border: 2px solid #111;
+  border-radius: 8px;
+  font-size: 1rem;
+  width: 100%;
+}
+
+.amount-input-group {
+  position: relative;
+  display: flex;
+  align-items: center;
+}
+
+.currency-symbol {
+  position: absolute;
+  left: 1rem;
+  color: #666;
+}
+
+.amount-input-group .form-input {
+  padding-left: 2rem;
+}
+
+.splits-container {
+  display: flex;
+  flex-direction: column;
+  gap: 0.5rem;
+}
+
+.split-item {
+  display: flex;
+  gap: 0.5rem;
+  align-items: center;
+}
+
+.form-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 0.5rem;
+  margin-top: 1rem;
+}
+
+.btn {
+  padding: 0.75rem 1.5rem;
+  border-radius: 8px;
+  font-weight: 600;
+  cursor: pointer;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: 0.5rem;
+}
+
+.btn-primary {
+  background: #111;
+  color: white;
+  border: none;
+}
+
+.btn-neutral {
+  background: #f5f5f5;
+  color: #333;
+  border: 2px solid #ddd;
+}
+
+.btn-danger {
+  background: #fee2e2;
+  color: #dc2626;
+  border: none;
+}
+
+.btn-secondary {
+  background: #e5e7eb;
+  color: #374151;
+  border: none;
+}
+
+.btn-sm {
+  padding: 0.5rem;
+  font-size: 0.875rem;
+}
+
+.btn:disabled {
+  opacity: 0.5;
+  cursor: not-allowed;
+}
+
+.ml-2 {
+  margin-left: 0.5rem;
+}
+
+.spinner-dots-sm {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.2rem;
+}
+
+.spinner-dots-sm span {
+  width: 4px;
+  height: 4px;
+  background-color: white;
+  border-radius: 50%;
+  animation: dot-pulse 1.4s infinite ease-in-out both;
+}
+
+.spinner-dots-sm span:nth-child(1) {
+  animation-delay: -0.32s;
+}
+
+.spinner-dots-sm span:nth-child(2) {
+  animation-delay: -0.16s;
+}
+
+@keyframes dot-pulse {
+  0%, 80%, 100% {
+    transform: scale(0);
+  }
+  40% {
+    transform: scale(1);
+  }
+}
+</style>
diff --git a/fe/src/components/SettleShareModal.vue b/fe/src/components/SettleShareModal.vue
index 2d517d7..c7c02d8 100644
--- a/fe/src/components/SettleShareModal.vue
+++ b/fe/src/components/SettleShareModal.vue
@@ -1,53 +1,47 @@
 <template>
-  <div v-if="show" class="modal-backdrop-settle" @click.self="onCancel">
-    <div class="modal-container-settle">
-      <div class="modal-header-settle">
-        <h3>Settle Your Share</h3>
-        <button class="close-button-settle" @click="onCancel" aria-label="Close">&times;</button>
+  <div v-if="show" class="modal-backdrop open" @click.self="$emit('cancel')">
+    <div class="modal-container" ref="modalRef" style="min-width: 550px;">
+      <div class="modal-header">
+        <h3>Settle Share</h3>
+        <button class="close-button" @click="$emit('cancel')" aria-label="Close">
+          <svg class="icon">
+            <use xlink:href="#icon-close" />
+          </svg>
+        </button>
       </div>
-      <div class="modal-body-settle" v-if="split">
-        <p>You are about to settle your share for this expense.</p>
-        <div class="info-item">
-          <span>Owed by:</span>
-          <strong>{{ split.user?.name || split.user?.email || `User ID ${split.user_id}` }}</strong>
+      <div class="modal-body">
+        <div v-if="isLoading" class="text-center">
+          <div class="spinner-dots"><span /><span /><span /></div>
+          <p>Processing settlement...</p>
         </div>
-        <div class="info-item">
-          <span>Original Share:</span>
-          <strong>{{ formatCurrency(split.owed_amount) }}</strong>
+        <div v-else>
+          <p>Settle amount for {{ split?.user?.name || split?.user?.email || `User ID: ${split?.user_id}` }}:</p>
+          <div class="form-group">
+            <label for="settleAmount" class="form-label">Amount</label>
+            <input
+              type="number"
+              v-model="amount"
+              class="form-input"
+              id="settleAmount"
+              required
+              :disabled="isLoading"
+              step="0.01"
+              min="0"
+            />
+            <p v-if="error" class="form-error-text">{{ error }}</p>
+          </div>
         </div>
-        <div class="info-item">
-          <span>Already Paid:</span>
-          <strong>{{ formatCurrency(paidAmount) }}</strong>
-        </div>
-        <hr class="my-3-settle" />
-        <div class="info-item">
-          <span>Amount to Settle Now:</span>
-          <strong class="amount-to-settle">{{ formatCurrency(remainingAmount) }}</strong>
-        </div>
-        <!-- For MVP, amount is fixed to remaining. Input field removed. -->
-        <!-- 
-        <div class="form-group-settle">
-          <label for="amountToSettle" class="form-label-settle">Amount to Settle:</label>
-          <input 
-            type="number" 
-            id="amountToSettle" 
-            class="form-input-settle" 
-            v-model="amountToSettleInput" 
-            step="0.01"
-            :readonly="true" // For MVP, fixed to remaining amount
-          />
-        </div>
-        -->
       </div>
-      <div class="modal-footer-settle">
-        <button type="button" class="btn-neutral-settle" @click="onCancel" :disabled="isLoading">Cancel</button>
-        <button 
-          type="button" 
-          class="btn-primary-settle ml-2-settle" 
-          @click="onConfirm" 
-          :disabled="isLoading || remainingAmount <= 0">
-          <span v-if="isLoading" class="spinner-dots-sm-settle"><span /><span /><span /></span>
-          <span v-else>Confirm Payment</span>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-neutral" @click="$emit('cancel')" :disabled="isLoading">Cancel</button>
+        <button
+          type="button"
+          class="btn btn-primary ml-2"
+          @click="handleConfirm"
+          :disabled="isLoading || !isValid"
+        >
+          <span v-if="isLoading" class="spinner-dots-sm"><span /><span /><span /></span>
+          <span v-else>Confirm</span>
         </button>
       </div>
     </div>
@@ -55,90 +49,66 @@
 </template>
 
 <script setup lang="ts">
-import { computed, ref, watch, PropType } from 'vue';
-import { Decimal } from 'decimal.js'; // For precise arithmetic
+import { ref, computed, watch } from 'vue'
+import { onClickOutside } from '@vueuse/core'
+import type { ExpenseSplit } from '@/types/expense'
+import { Decimal } from 'decimal.js'
 
-// Define interfaces for props inline for clarity in this component
-interface UserInfo {
-  id: number;
-  name?: string | null;
-  email: string;
+const props = defineProps<{
+  show: boolean
+  split: ExpenseSplit | null
+  paidAmount: number
+  isLoading: boolean
+}>()
+
+const emit = defineEmits<{
+  (e: 'confirm', amount: number): void
+  (e: 'cancel'): void
+}>()
+
+const modalRef = ref<HTMLElement | null>(null)
+const amount = ref<string>('')
+const error = ref<string | null>(null)
+
+// Close modal when clicking outside
+onClickOutside(modalRef, () => {
+  emit('cancel')
+})
+
+// Reset form when modal opens
+watch(() => props.show, (newVal) => {
+  if (newVal && props.split) {
+    const alreadyPaid = new Decimal(props.paidAmount)
+    const owed = new Decimal(props.split.owed_amount)
+    const remaining = owed.minus(alreadyPaid)
+    amount.value = remaining.toFixed(2)
+    error.value = null
+  }
+})
+
+const isValid = computed(() => {
+  if (!amount.value.trim()) return false
+  const numAmount = new Decimal(amount.value)
+  if (numAmount.isNaN() || numAmount.isNegative() || numAmount.isZero()) return false
+  if (props.split) {
+    const alreadyPaid = new Decimal(props.paidAmount)
+    const owed = new Decimal(props.split.owed_amount)
+    const remaining = owed.minus(alreadyPaid)
+    return numAmount.lessThanOrEqualTo(remaining.plus(new Decimal('0.001'))) // Epsilon for float issues
+  }
+  return false
+})
+
+const handleConfirm = () => {
+  if (!isValid.value) return
+  const numAmount = parseFloat(amount.value)
+  emit('confirm', numAmount)
 }
-
-export interface ExpenseSplitInfo { // Exporting to be potentially used by parent if needed
-  id: number;
-  user_id: number;
-  owed_amount: string; // Expect string from backend for Decimal types
-  user?: UserInfo | null;
-  // Add other necessary fields from your actual ExpenseSplit type
-  // e.g. status, settlement_activities if they affect logic here (not for MVP)
-}
-
-const props = defineProps({
-  show: {
-    type: Boolean,
-    required: true,
-  },
-  split: {
-    type: Object as PropType<ExpenseSplitInfo | null>,
-    required: true,
-  },
-  paidAmount: { // Amount already paid towards this split
-    type: Number,
-    required: true,
-  },
-  isLoading: {
-    type: Boolean,
-    default: false,
-  },
-});
-
-const emit = defineEmits(['confirm', 'cancel']);
-
-const remainingAmount = computed(() => {
-  if (!props.split) return 0;
-  try {
-    const owed = new Decimal(props.split.owed_amount);
-    const paid = new Decimal(props.paidAmount);
-    const remaining = owed.minus(paid);
-    return remaining.greaterThan(0) ? remaining.toNumber() : 0;
-  } catch (e) {
-    console.error("Error calculating remaining amount:", e);
-    return 0; // Fallback in case of invalid decimal string
-  }
-});
-
-// For MVP, amountToSettle is always the full remainingAmount
-const amountToSettle = computed(() => remainingAmount.value);
-
-const onConfirm = () => {
-  if (remainingAmount.value > 0) {
-    emit('confirm', amountToSettle.value); // Emit the number value
-  }
-};
-
-const onCancel = () => {
-  emit('cancel');
-};
-
-// Helper to format currency (can be moved to a utility file)
-const formatCurrency = (value: string | number | undefined | null): string => {
-  if (value === undefined || value === null) return '$0.00';
-  let numValue: number;
-  if (typeof value === 'string') {
-    if (!value.trim()) return '$0.00';
-    numValue = parseFloat(value);
-  } else {
-    numValue = value;
-  }
-  return isNaN(numValue) ? '$0.00' : `$${numValue.toFixed(2)}`;
-};
-
 </script>
 
 <style scoped>
-.modal-backdrop-settle {
-  background-color: rgba(0, 0, 0, 0.6); /* Darker overlay */
+.modal-backdrop {
+  background-color: rgba(0, 0, 0, 0.5);
   position: fixed;
   top: 0;
   left: 0;
@@ -147,144 +117,149 @@ const formatCurrency = (value: string | number | undefined | null): string => {
   display: flex;
   align-items: center;
   justify-content: center;
-  z-index: 1050; /* Ensure it's above other elements */
+  z-index: 1000;
 }
 
-.modal-container-settle {
+.modal-container {
   background: white;
-  border-radius: 12px; /* Softer radius */
-  border: 2px solid #333; /* Slightly softer border */
-  box-shadow: 0 8px 20px rgba(0,0,0,0.25); /* Softer shadow */
+  border-radius: 18px;
+  border: 3px solid #111;
+  box-shadow: 6px 6px 0 #111;
   width: 90%;
-  max-width: 450px; /* Optimal width for a simple modal */
+  max-width: 500px;
   max-height: 90vh;
   overflow-y: auto;
-  display: flex; /* For footer alignment */
-  flex-direction: column;
+  padding: 0;
 }
 
-.modal-header-settle {
-  padding: 1rem 1.5rem;
-  border-bottom: 1px solid #e0e0e0; /* Lighter border */
+.modal-header {
+  padding: 1.5rem;
+  border-bottom: 1px solid #eee;
   display: flex;
   justify-content: space-between;
   align-items: center;
 }
 
-.modal-header-settle h3 {
-  margin: 0;
-  font-size: 1.25rem;
-  font-weight: 700;
-  color: #111;
+.modal-body {
+  padding: 1.5rem;
 }
 
-.close-button-settle {
+.modal-footer {
+  padding: 1.5rem;
+  border-top: 1px solid #eee;
+  display: flex;
+  justify-content: flex-end;
+  gap: 0.5rem;
+}
+
+.close-button {
   background: none;
   border: none;
   cursor: pointer;
-  font-size: 1.5rem;
-  line-height: 1;
-  color: #555;
-  padding: 0.5rem; /* Easier to click */
-}
-.close-button-settle:hover {
-  color: #111;
+  color: #666;
 }
 
-.modal-body-settle {
-  padding: 1.5rem;
-  line-height: 1.6;
+.form-group {
+  margin-bottom: 1rem;
 }
 
-.modal-body-settle p {
-  margin-bottom: 0.75rem;
-}
-
-.info-item {
-  display: flex;
-  justify-content: space-between;
+.form-label {
+  display: block;
   margin-bottom: 0.5rem;
-  font-size: 0.95rem;
-}
-.info-item span {
-  color: #555;
-}
-.info-item strong {
-  color: #111;
-  font-weight: 600;
-}
-.amount-to-settle {
-  font-size: 1.1rem;
-  color: var(--primary-color, #3498db) !important; /* Use theme color */
+  font-weight: 500;
 }
 
-.my-3-settle {
-  border: 0;
-  border-top: 1px solid #e0e0e0;
-  margin: 1rem 0;
-}
-
-.modal-footer-settle {
-  padding: 1rem 1.5rem;
-  border-top: 1px solid #e0e0e0;
-  display: flex;
-  justify-content: flex-end;
-  gap: 0.75rem; /* Consistent gap */
-  background-color: #f9f9f9; /* Slight distinction for footer */
-  border-bottom-left-radius: 12px; /* Match container radius */
-  border-bottom-right-radius: 12px;
-}
-
-/* Generic button styles - assuming similar to existing .btn but scoped with -settle */
-.btn-neutral-settle, .btn-primary-settle {
-  padding: 0.6rem 1.2rem;
+.form-input {
+  width: 100%;
+  padding: 0.75rem;
+  border: 2px solid #111;
   border-radius: 8px;
-  font-weight: 700;
+  font-size: 1rem;
+}
+
+.form-error-text {
+  color: #dc2626;
+  font-size: 0.875rem;
+  margin-top: 0.5rem;
+}
+
+.btn {
+  padding: 0.75rem 1.5rem;
+  border-radius: 8px;
+  font-weight: 600;
   cursor: pointer;
-  border: 2px solid #111; /* Neo-brutalist touch */
-  box-shadow: 2px 2px 0 #111; /* Neo-brutalist touch */
-  transition: transform 0.1s ease, box-shadow 0.1s ease;
+  border: none;
 }
-.btn-neutral-settle:hover, .btn-primary-settle:hover {
-  transform: translate(-1px, -1px);
-  box-shadow: 3px 3px 0 #111;
-}
-.btn-neutral-settle:disabled, .btn-primary-settle:disabled {
-  opacity: 0.6;
+
+.btn:disabled {
+  opacity: 0.5;
   cursor: not-allowed;
 }
 
-.btn-neutral-settle {
-  background-color: #f0f0f0;
+.btn-neutral {
+  background: #f3f4f6;
   color: #111;
 }
 
-.btn-primary-settle {
-  background-color: var(--primary-color, #3498db); 
+.btn-primary {
+  background: #111;
   color: white;
-  border-color: #111; /* Ensure border matches */
 }
-.ml-2-settle {
+
+.ml-2 {
   margin-left: 0.5rem;
 }
 
-.spinner-dots-sm-settle { /* For loading button */
+.text-center {
+  text-align: center;
+}
+
+.spinner-dots {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 0.3rem;
+  margin: 0 auto;
+}
+
+.spinner-dots span {
+  width: 8px;
+  height: 8px;
+  background-color: #555;
+  border-radius: 50%;
+  animation: dot-pulse 1.4s infinite ease-in-out both;
+}
+
+.spinner-dots-sm {
   display: inline-flex;
   align-items: center;
   gap: 0.2rem;
 }
-.spinner-dots-sm-settle span {
+
+.spinner-dots-sm span {
   width: 4px;
   height: 4px;
-  background-color: white; /* Assuming primary button has light text */
+  background-color: white;
   border-radius: 50%;
-  animation: dot-pulse-settle 1.4s infinite ease-in-out both;
+  animation: dot-pulse 1.4s infinite ease-in-out both;
 }
-.spinner-dots-sm-settle span:nth-child(1) { animation-delay: -0.32s; }
-.spinner-dots-sm-settle span:nth-child(2) { animation-delay: -0.16s; }
 
-@keyframes dot-pulse-settle {
-  0%, 80%, 100% { transform: scale(0); }
-  40% { transform: scale(1); }
+.spinner-dots span:nth-child(1),
+.spinner-dots-sm span:nth-child(1) {
+  animation-delay: -0.32s;
+}
+
+.spinner-dots span:nth-child(2),
+.spinner-dots-sm span:nth-child(2) {
+  animation-delay: -0.16s;
+}
+
+@keyframes dot-pulse {
+  0%, 80%, 100% {
+    transform: scale(0);
+  }
+  40% {
+    transform: scale(1);
+  }
 }
 </style>
diff --git a/fe/src/config/api-config.ts b/fe/src/config/api-config.ts
index f6bd1ae..95f0ec7 100644
--- a/fe/src/config/api-config.ts
+++ b/fe/src/config/api-config.ts
@@ -1,119 +1,119 @@
 // API Version
-export const API_VERSION = 'v1';
+export const API_VERSION = 'v1'
 
 // API Base URL
-export const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
+export const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000'
 
 // API Endpoints
 export const API_ENDPOINTS = {
-    // Auth
-    AUTH: {
-        LOGIN: '/auth/jwt/login',
-        SIGNUP: '/auth/register',
-        LOGOUT: '/auth/jwt/logout',
-        VERIFY_EMAIL: '/auth/verify',
-        RESET_PASSWORD: '/auth/forgot-password',
-        FORGOT_PASSWORD: '/auth/forgot-password',
-    },
+  // Auth
+  AUTH: {
+    LOGIN: '/auth/jwt/login',
+    SIGNUP: '/auth/register',
+    LOGOUT: '/auth/jwt/logout',
+    VERIFY_EMAIL: '/auth/verify',
+    RESET_PASSWORD: '/auth/forgot-password',
+    FORGOT_PASSWORD: '/auth/forgot-password',
+  },
 
-    // Users
-    USERS: {
-        PROFILE: '/users/me',
-        UPDATE_PROFILE: '/api/v1/users/me',
-        PASSWORD: '/api/v1/users/password',
-        AVATAR: '/api/v1/users/avatar',
-        SETTINGS: '/api/v1/users/settings',
-        NOTIFICATIONS: '/api/v1/users/notifications',
-        PREFERENCES: '/api/v1/users/preferences',
-    },
+  // Users
+  USERS: {
+    PROFILE: '/users/me',
+    UPDATE_PROFILE: '/users/me',
+    PASSWORD: '/api/v1/users/password',
+    AVATAR: '/api/v1/users/avatar',
+    SETTINGS: '/api/v1/users/settings',
+    NOTIFICATIONS: '/api/v1/users/notifications',
+    PREFERENCES: '/api/v1/users/preferences',
+  },
 
-    // Lists
-    LISTS: {
-        BASE: '/lists',
-        BY_ID: (id: string) => `/lists/${id}`,
-        ITEMS: (listId: string) => `/lists/${listId}/items`,
-        ITEM: (listId: string, itemId: string) => `/lists/${listId}/items/${itemId}`,
-        SHARE: (listId: string) => `/lists/${listId}/share`,
-        UNSHARE: (listId: string) => `/lists/${listId}/unshare`,
-        COMPLETE: (listId: string) => `/lists/${listId}/complete`,
-        REOPEN: (listId: string) => `/lists/${listId}/reopen`,
-        ARCHIVE: (listId: string) => `/lists/${listId}/archive`,
-        RESTORE: (listId: string) => `/lists/${listId}/restore`,
-        DUPLICATE: (listId: string) => `/lists/${listId}/duplicate`,
-        EXPORT: (listId: string) => `/lists/${listId}/export`,
-        IMPORT: '/lists/import',
-    },
+  // Lists
+  LISTS: {
+    BASE: '/lists',
+    BY_ID: (id: string) => `/lists/${id}`,
+    ITEMS: (listId: string) => `/lists/${listId}/items`,
+    ITEM: (listId: string, itemId: string) => `/lists/${listId}/items/${itemId}`,
+    SHARE: (listId: string) => `/lists/${listId}/share`,
+    UNSHARE: (listId: string) => `/lists/${listId}/unshare`,
+    COMPLETE: (listId: string) => `/lists/${listId}/complete`,
+    REOPEN: (listId: string) => `/lists/${listId}/reopen`,
+    ARCHIVE: (listId: string) => `/lists/${listId}/archive`,
+    RESTORE: (listId: string) => `/lists/${listId}/restore`,
+    DUPLICATE: (listId: string) => `/lists/${listId}/duplicate`,
+    EXPORT: (listId: string) => `/lists/${listId}/export`,
+    IMPORT: '/lists/import',
+  },
 
-    // Groups
-    GROUPS: {
-        BASE: '/groups',
-        BY_ID: (id: string) => `/groups/${id}`,
-        LISTS: (groupId: string) => `/groups/${groupId}/lists`,
-        MEMBERS: (groupId: string) => `/groups/${groupId}/members`,
-        MEMBER: (groupId: string, userId: string) => `/groups/${groupId}/members/${userId}`,
-        CREATE_INVITE: (groupId: string) => `/groups/${groupId}/invites`,
-        GET_ACTIVE_INVITE: (groupId: string) => `/groups/${groupId}/invites`,
-        LEAVE: (groupId: string) => `/groups/${groupId}/leave`,
-        DELETE: (groupId: string) => `/groups/${groupId}`,
-        SETTINGS: (groupId: string) => `/groups/${groupId}/settings`,
-        ROLES: (groupId: string) => `/groups/${groupId}/roles`,
-        ROLE: (groupId: string, roleId: string) => `/groups/${groupId}/roles/${roleId}`,
-    },
+  // Groups
+  GROUPS: {
+    BASE: '/groups',
+    BY_ID: (id: string) => `/groups/${id}`,
+    LISTS: (groupId: string) => `/groups/${groupId}/lists`,
+    MEMBERS: (groupId: string) => `/groups/${groupId}/members`,
+    MEMBER: (groupId: string, userId: string) => `/groups/${groupId}/members/${userId}`,
+    CREATE_INVITE: (groupId: string) => `/groups/${groupId}/invites`,
+    GET_ACTIVE_INVITE: (groupId: string) => `/groups/${groupId}/invites`,
+    LEAVE: (groupId: string) => `/groups/${groupId}/leave`,
+    DELETE: (groupId: string) => `/groups/${groupId}`,
+    SETTINGS: (groupId: string) => `/groups/${groupId}/settings`,
+    ROLES: (groupId: string) => `/groups/${groupId}/roles`,
+    ROLE: (groupId: string, roleId: string) => `/groups/${groupId}/roles/${roleId}`,
+  },
 
-    // Invites
-    INVITES: {
-        BASE: '/invites',
-        BY_ID: (id: string) => `/invites/${id}`,
-        ACCEPT: (id: string) => `/invites/accept/${id}`,
-        DECLINE: (id: string) => `/invites/decline/${id}`,
-        REVOKE: (id: string) => `/invites/revoke/${id}`,
-        LIST: '/invites',
-        PENDING: '/invites/pending',
-        SENT: '/invites/sent',
-    },
+  // Invites
+  INVITES: {
+    BASE: '/invites',
+    BY_ID: (id: string) => `/invites/${id}`,
+    ACCEPT: (id: string) => `/invites/accept/${id}`,
+    DECLINE: (id: string) => `/invites/decline/${id}`,
+    REVOKE: (id: string) => `/invites/revoke/${id}`,
+    LIST: '/invites',
+    PENDING: '/invites/pending',
+    SENT: '/invites/sent',
+  },
 
-    // Items (for direct operations like update, get by ID)
-    ITEMS: {
-        BY_ID: (itemId: string) => `/items/${itemId}`,
-    },
+  // Items (for direct operations like update, get by ID)
+  ITEMS: {
+    BY_ID: (itemId: string) => `/items/${itemId}`,
+  },
 
-    // OCR
-    OCR: {
-        PROCESS: '/ocr/extract-items',
-        STATUS: (jobId: string) => `/ocr/status/${jobId}`,
-        RESULT: (jobId: string) => `/ocr/result/${jobId}`,
-        BATCH: '/ocr/batch',
-        CANCEL: (jobId: string) => `/ocr/cancel/${jobId}`,
-        HISTORY: '/ocr/history',
-    },
+  // OCR
+  OCR: {
+    PROCESS: '/ocr/extract-items',
+    STATUS: (jobId: string) => `/ocr/status/${jobId}`,
+    RESULT: (jobId: string) => `/ocr/result/${jobId}`,
+    BATCH: '/ocr/batch',
+    CANCEL: (jobId: string) => `/ocr/cancel/${jobId}`,
+    HISTORY: '/ocr/history',
+  },
 
-    // Costs
-    COSTS: {
-        BASE: '/costs',
-        LIST_SUMMARY: (listId: string | number) => `/costs/lists/${listId}/cost-summary`,
-        GROUP_BALANCE_SUMMARY: (groupId: string | number) => `/costs/groups/${groupId}/balance-summary`,
-    },
+  // Costs
+  COSTS: {
+    BASE: '/costs',
+    LIST_SUMMARY: (listId: string | number) => `/costs/lists/${listId}/cost-summary`,
+    GROUP_BALANCE_SUMMARY: (groupId: string | number) => `/costs/groups/${groupId}/balance-summary`,
+  },
 
-    // Financials
-    FINANCIALS: {
-        EXPENSES: '/financials/expenses',
-        EXPENSE: (id: string) => `/financials/expenses/${id}`,
-        SETTLEMENTS: '/financials/settlements',
-        SETTLEMENT: (id: string) => `/financials/settlements/${id}`,
-        BALANCES: '/financials/balances',
-        BALANCE: (userId: string) => `/financials/balances/${userId}`,
-        REPORTS: '/financials/reports',
-        REPORT: (id: string) => `/financials/reports/${id}`,
-        CATEGORIES: '/financials/categories',
-        CATEGORY: (id: string) => `/financials/categories/${id}`,
-    },
+  // Financials
+  FINANCIALS: {
+    EXPENSES: '/financials/expenses',
+    EXPENSE: (id: string) => `/financials/expenses/${id}`,
+    SETTLEMENTS: '/financials/settlements',
+    SETTLEMENT: (id: string) => `/financials/settlements/${id}`,
+    BALANCES: '/financials/balances',
+    BALANCE: (userId: string) => `/financials/balances/${userId}`,
+    REPORTS: '/financials/reports',
+    REPORT: (id: string) => `/financials/reports/${id}`,
+    CATEGORIES: '/financials/categories',
+    CATEGORY: (id: string) => `/financials/categories/${id}`,
+  },
 
-    // Health
-    HEALTH: {
-        CHECK: '/health',
-        VERSION: '/health/version',
-        STATUS: '/health/status',
-        METRICS: '/health/metrics',
-        LOGS: '/health/logs',
-    },
-}; 
\ No newline at end of file
+  // Health
+  HEALTH: {
+    CHECK: '/health',
+    VERSION: '/health/version',
+    STATUS: '/health/status',
+    METRICS: '/health/metrics',
+    LOGS: '/health/logs',
+  },
+}
diff --git a/fe/src/pages/ListDetailPage.vue b/fe/src/pages/ListDetailPage.vue
index 80c9107..24d538b 100644
--- a/fe/src/pages/ListDetailPage.vue
+++ b/fe/src/pages/ListDetailPage.vue
@@ -99,7 +99,15 @@
 
     <!-- Expenses Section -->
     <section v-if="list" class="neo-expenses-section">
-      <h2 class="neo-expenses-title">Expenses</h2>
+      <div class="neo-expenses-header">
+        <h2 class="neo-expenses-title">Expenses</h2>
+        <button class="neo-action-button" @click="showCreateExpenseForm = true">
+          <svg class="icon">
+            <use xlink:href="#icon-plus" />
+          </svg>
+          Add Expense
+        </button>
+      </div>
       <div v-if="listDetailStore.isLoading && expenses.length === 0" class="neo-loading-state">
         <div class="spinner-dots" role="status"><span /><span /><span /></div>
         <p>Loading expenses...</p>
@@ -123,7 +131,7 @@
             Paid by: <strong>{{ expense.paid_by_user?.name || expense.paid_by_user?.email || `User ID: ${expense.paid_by_user_id}` }}</strong>
             on {{ new Date(expense.expense_date).toLocaleDateString() }}
           </div>
-          
+
           <div class="neo-splits-list">
             <div v-for="split in expense.splits" :key="split.id" class="neo-split-item">
               <div class="neo-split-details">
@@ -136,6 +144,14 @@
                 Paid: {{ getPaidAmountForSplitDisplay(split) }}
                 <span v-if="split.paid_at"> on {{ new Date(split.paid_at).toLocaleDateString() }}</span>
               </div>
+              <button
+                v-if="split.user_id === authStore.user?.id && split.status !== ExpenseSplitStatusEnum.PAID"
+                class="neo-button neo-button-primary"
+                @click="openSettleShareModal(expense, split)"
+                :disabled="isSettlementLoading"
+              >
+                Settle My Share
+              </button>
               <ul v-if="split.settlement_activities && split.settlement_activities.length > 0" class="neo-settlement-activities">
                 <li v-for="activity in split.settlement_activities" :key="activity.id">
                   Activity: {{ formatCurrency(activity.amount_paid) }} by {{ activity.payer?.name || `User ${activity.paid_by_user_id}`}} on {{ new Date(activity.paid_at).toLocaleDateString() }}
@@ -147,6 +163,15 @@
       </div>
     </section>
 
+    <!-- Create Expense Form -->
+    <CreateExpenseForm
+      v-if="showCreateExpenseForm"
+      :list-id="list?.id"
+      :group-id="list?.group_id"
+      @close="showCreateExpenseForm = false"
+      @created="handleExpenseCreated"
+    />
+
     <!-- OCR Dialog -->
     <div v-if="showOcrDialogState" class="modal-backdrop open" @click.self="closeOcrDialog">
       <div class="modal-container" ref="ocrModalRef" style="min-width: 400px;">
@@ -272,6 +297,35 @@
       </div>
     </div>
 
+    <!-- Settle Share Modal -->
+    <div v-if="showSettleModal" class="modal-backdrop open" @click.self="closeSettleShareModal">
+      <div class="modal-container" ref="settleModalRef" style="min-width: 550px;">
+        <div class="modal-header">
+          <h3>Settle Share</h3>
+          <button class="close-button" @click="closeSettleShareModal" aria-label="Close"><svg class="icon">
+              <use xlink:href="#icon-close" />
+            </svg></button>
+        </div>
+        <div class="modal-body">
+          <div v-if="isSettlementLoading" class="text-center">
+            <div class="spinner-dots"><span /><span /><span /></div>
+            <p>Processing settlement...</p>
+          </div>
+          <div v-else-if="settleAmountError" class="alert alert-error">{{ settleAmountError }}</div>
+          <div v-else>
+            <p>Settle amount for {{ selectedSplitForSettlement?.user?.name || selectedSplitForSettlement?.user?.email || `User ID: ${selectedSplitForSettlement?.user_id}` }}:</p>
+            <div class="form-group">
+              <label for="settleAmount" class="form-label">Amount</label>
+              <input type="number" v-model="settleAmount" class="form-input" id="settleAmount" required />
+            </div>
+          </div>
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-primary" @click="handleConfirmSettle">Confirm</button>
+        </div>
+      </div>
+    </div>
+
   </main>
 </template>
 
@@ -283,8 +337,14 @@ import { onClickOutside, useEventListener, useFileDialog, useNetwork } from '@vu
 import { useNotificationStore } from '@/stores/notifications';
 import { useOfflineStore, type CreateListItemPayload } from '@/stores/offline';
 import { useListDetailStore } from '@/stores/listDetailStore';
-import type { Expense, ExpenseSplit } from '@/types/expense'; // Ensure correct path
-import { ExpenseOverallStatusEnum, ExpenseSplitStatusEnum } from '@/types/expense'; // Ensure correct path
+import type { ListWithExpenses } from '@/types/list';
+import type { Expense, ExpenseSplit } from '@/types/expense';
+import { ExpenseOverallStatusEnum, ExpenseSplitStatusEnum } from '@/types/expense';
+import { useAuthStore } from '@/stores/auth';
+import { Decimal } from 'decimal.js';
+import type { SettlementActivityCreate } from '@/types/expense';
+import SettleShareModal from '@/components/SettleShareModal.vue';
+import CreateExpenseForm from '@/components/CreateExpenseForm.vue';
 
 
 interface Item {
@@ -325,7 +385,7 @@ const route = useRoute();
 const { isOnline } = useNetwork();
 const notificationStore = useNotificationStore();
 const offlineStore = useOfflineStore();
-const list = ref<List | null>(null); // This is for items
+const list = ref<ListWithExpenses | null>(null);
 const loading = ref(true); // For initial list (items) loading
 const error = ref<string | null>(null); // For initial list (items) loading
 const addingItem = ref(false);
@@ -363,10 +423,24 @@ const listCostSummary = ref<ListCostSummaryData | null>(null);
 const costSummaryLoading = ref(false);
 const costSummaryError = ref<string | null>(null);
 
+// Settle Share
+const authStore = useAuthStore();
+const showSettleModal = ref(false);
+const settleModalRef = ref<HTMLElement | null>(null);
+const selectedSplitForSettlement = ref<ExpenseSplit | null>(null);
+const parentExpenseOfSelectedSplit = ref<Expense | null>(null);
+const settleAmount = ref<string>('');
+const settleAmountError = ref<string | null>(null);
+const isSettlementLoading = computed(() => listDetailStore.isSettlingSplit);
+
+// Create Expense
+const showCreateExpenseForm = ref(false);
+
 
 onClickOutside(ocrModalRef, () => { showOcrDialogState.value = false; });
 onClickOutside(costSummaryModalRef, () => { showCostSummaryDialog.value = false; });
 onClickOutside(confirmModalRef, () => { showConfirmDialogState.value = false; pendingAction.value = null; });
+onClickOutside(settleModalRef, () => { showSettleModal.value = false; });
 
 
 const formatCurrency = (value: string | number | undefined | null): string => {
@@ -377,10 +451,12 @@ const formatCurrency = (value: string | number | undefined | null): string => {
   return isNaN(numValue) ? '$0.00' : `$${numValue.toFixed(2)}`;
 };
 
-const processListItems = (items: Item[]): Item[] => {
-  return items.map(item => ({
-    ...item,
-    priceInput: item.price !== null && item.price !== undefined ? item.price : ''
+const processListItems = (items: Item[]) => {
+  return items.map((i: Item) => ({
+    ...i,
+    updating: false,
+    deleting: false,
+    priceInput: i.price || '',
   }));
 };
 
@@ -389,7 +465,7 @@ const fetchListDetails = async () => { // This is for items primarily
   error.value = null;
   try {
     const response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(String(route.params.id)));
-    const rawList = response.data as List;
+    const rawList = response.data as ListWithExpenses;
     rawList.items = processListItems(rawList.items);
     list.value = rawList; // Sets item-related list data
 
@@ -398,7 +474,7 @@ const fetchListDetails = async () => { // This is for items primarily
       return item.updated_at > latest ? item.updated_at : latest;
     }, '');
 
-    if (showCostSummaryDialog.value) { 
+    if (showCostSummaryDialog.value) {
       await fetchListCostSummary();
     }
 
@@ -413,7 +489,7 @@ const checkForUpdates = async () => {
   if (!list.value) return;
   try {
     const response = await apiClient.get(API_ENDPOINTS.LISTS.BY_ID(String(list.value.id)));
-    const { updated_at: newListUpdatedAt, items: newItems } = response.data as List;
+    const { updated_at: newListUpdatedAt, items: newItems } = response.data as ListWithExpenses;
     const newLastItemUpdate = newItems.reduce((latest: string, item: Item) => item.updated_at > latest ? item.updated_at : latest, '');
 
     if ((lastListUpdate.value && newListUpdatedAt > lastListUpdate.value) ||
@@ -463,7 +539,7 @@ const onAddItem = async () => {
       }
     });
     const optimisticItem: Item = {
-      id: Date.now(), 
+      id: Date.now(),
       name: newItem.value.name,
       quantity: newItem.value.quantity,
       is_complete: false,
@@ -497,7 +573,7 @@ const updateItem = async (item: Item, newCompleteStatus: boolean) => {
   if (!list.value) return;
   item.updating = true;
   const originalCompleteStatus = item.is_complete;
-  item.is_complete = newCompleteStatus; 
+  item.is_complete = newCompleteStatus;
 
   if (!isOnline.value) {
     offlineStore.addAction({
@@ -522,7 +598,7 @@ const updateItem = async (item: Item, newCompleteStatus: boolean) => {
     );
     item.version++;
   } catch (err) {
-    item.is_complete = originalCompleteStatus; 
+    item.is_complete = originalCompleteStatus;
     notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to update item.', type: 'error' });
   } finally {
     item.updating = false;
@@ -584,14 +660,14 @@ const deleteItem = async (item: Item) => {
         itemId: String(item.id)
       }
     });
-    list.value.items = list.value.items.filter(i => i.id !== item.id);
+    list.value.items = list.value.items.filter((i: Item) => i.id !== item.id);
     item.deleting = false;
     return;
   }
 
   try {
     await apiClient.delete(API_ENDPOINTS.LISTS.ITEM(String(list.value.id), String(item.id)));
-    list.value.items = list.value.items.filter(i => i.id !== item.id);
+    list.value.items = list.value.items.filter((i: Item) => i.id !== item.id);
   } catch (err) {
     notificationStore.addNotification({ message: (err instanceof Error ? err.message : String(err)) || 'Failed to delete item.', type: 'error' });
   } finally {
@@ -625,11 +701,11 @@ const cancelConfirmation = () => {
 const openOcrDialog = () => {
   ocrItems.value = [];
   ocrError.value = null;
-  resetOcrFileDialog(); 
+  resetOcrFileDialog();
   showOcrDialogState.value = true;
   nextTick(() => {
     if (ocrFileInputRef.value) {
-      ocrFileInputRef.value.value = ''; 
+      ocrFileInputRef.value.value = '';
     }
   });
 };
@@ -672,7 +748,7 @@ const handleOcrUpload = async (file: File) => {
     ocrError.value = (err instanceof Error ? err.message : String(err)) || 'Failed to process image.';
   } finally {
     ocrLoading.value = false;
-    if (ocrFileInputRef.value) ocrFileInputRef.value.value = ''; 
+    if (ocrFileInputRef.value) ocrFileInputRef.value.value = '';
   }
 };
 
@@ -685,7 +761,7 @@ const addOcrItems = async () => {
       if (!item.name.trim()) continue;
       const response = await apiClient.post(
         API_ENDPOINTS.LISTS.ITEMS(String(list.value.id)),
-        { name: item.name, quantity: "1" } 
+        { name: item.name, quantity: "1" }
       );
       const addedItem = response.data as Item;
       list.value.items.push(processListItems([addedItem])[0]);
@@ -722,8 +798,6 @@ watch(showCostSummaryDialog, (newVal) => {
 
 // --- Expense and Settlement Status Logic ---
 const listDetailStore = useListDetailStore();
-// listWithExpenses is not directly used in template, expenses getter is used instead
-// const listWithExpenses = computed(() => listDetailStore.getList);
 const expenses = computed(() => listDetailStore.getExpenses);
 
 const getPaidAmountForSplitDisplay = (split: ExpenseSplit): string => {
@@ -772,7 +846,7 @@ useEventListener(window, 'keydown', (event: KeyboardEvent) => {
 });
 
 let touchStartX = 0;
-const SWIPE_THRESHOLD = 50; 
+const SWIPE_THRESHOLD = 50;
 
 const handleTouchStart = (event: TouchEvent) => {
   touchStartX = event.changedTouches[0].clientX;
@@ -816,6 +890,91 @@ const editItem = (item: Item) => {
   });
 };
 
+const openSettleShareModal = (expense: Expense, split: ExpenseSplit) => {
+  if (split.user_id !== authStore.user?.id) {
+    notificationStore.addNotification({ message: "You can only settle your own shares.", type: 'warning' });
+    return;
+  }
+  selectedSplitForSettlement.value = split;
+  parentExpenseOfSelectedSplit.value = expense;
+  const alreadyPaid = new Decimal(listDetailStore.getPaidAmountForSplit(split.id));
+  const owed = new Decimal(split.owed_amount);
+  const remaining = owed.minus(alreadyPaid);
+  settleAmount.value = remaining.toFixed(2);
+  settleAmountError.value = null;
+  showSettleModal.value = true;
+};
+
+const closeSettleShareModal = () => {
+  showSettleModal.value = false;
+  selectedSplitForSettlement.value = null;
+  parentExpenseOfSelectedSplit.value = null;
+  settleAmount.value = '';
+  settleAmountError.value = null;
+};
+
+const validateSettleAmount = (): boolean => {
+  settleAmountError.value = null;
+  if (!settleAmount.value.trim()) {
+    settleAmountError.value = 'Please enter an amount.';
+    return false;
+  }
+  const amount = new Decimal(settleAmount.value);
+  if (amount.isNaN() || amount.isNegative() || amount.isZero()) {
+    settleAmountError.value = 'Please enter a positive amount.';
+    return false;
+  }
+  if (selectedSplitForSettlement.value) {
+    const alreadyPaid = new Decimal(listDetailStore.getPaidAmountForSplit(selectedSplitForSettlement.value.id));
+    const owed = new Decimal(selectedSplitForSettlement.value.owed_amount);
+    const remaining = owed.minus(alreadyPaid);
+    if (amount.greaterThan(remaining.plus(new Decimal('0.001')))) { // Epsilon for float issues
+      settleAmountError.value = `Amount cannot exceed remaining: ${formatCurrency(remaining.toFixed(2))}.`;
+      return false;
+    }
+  } else {
+    settleAmountError.value = 'Error: No split selected.'; // Should not happen
+    return false;
+  }
+  return true;
+};
+
+const currentListIdForRefetch = computed(() => listDetailStore.currentList?.id || null);
+
+const handleConfirmSettle = async () => {
+  if (!selectedSplitForSettlement.value || !authStore.user?.id || !currentListIdForRefetch.value) {
+    notificationStore.addNotification({ message: 'Cannot process settlement: missing data.', type: 'error' });
+    return;
+  }
+  // Use settleAmount.value which is the confirmed amount (remaining amount for MVP)
+  const activityData: SettlementActivityCreate = {
+    expense_split_id: selectedSplitForSettlement.value.id,
+    paid_by_user_id: Number(authStore.user.id), // Convert to number
+    amount_paid: new Decimal(settleAmount.value).toString(),
+    paid_at: new Date().toISOString(),
+  };
+
+  const success = await listDetailStore.settleExpenseSplit({
+    list_id_for_refetch: String(currentListIdForRefetch.value),
+    expense_split_id: selectedSplitForSettlement.value.id,
+    activity_data: activityData,
+  });
+
+  if (success) {
+    notificationStore.addNotification({ message: 'Share settled successfully!', type: 'success' });
+    closeSettleShareModal();
+  } else {
+    notificationStore.addNotification({ message: listDetailStore.error || 'Failed to settle share.', type: 'error' });
+  }
+};
+
+const handleExpenseCreated = (expense: any) => {
+  // Refresh the expenses list
+  if (list.value?.id) {
+    listDetailStore.fetchListWithExpenses(String(list.value.id));
+  }
+};
+
 </script>
 
 <style scoped>
@@ -830,6 +989,13 @@ const editItem = (item: Item) => {
   box-shadow: 6px 6px 0 #111;
 }
 
+.neo-expenses-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 1rem;
+}
+
 .neo-expenses-title {
   font-size: 2rem;
   font-weight: 900;
@@ -1410,4 +1576,4 @@ const editItem = (item: Item) => {
     transform: scale(1);
   }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/fe/src/services/api.ts b/fe/src/services/api.ts
index c105117..e32f834 100644
--- a/fe/src/services/api.ts
+++ b/fe/src/services/api.ts
@@ -1,8 +1,8 @@
-import axios from 'axios';
-import { API_BASE_URL } from '@/config/api-config'; // api-config.ts can be moved to src/config/
-import router from '@/router'; // Import the router instance
-import { useAuthStore } from '@/stores/auth'; // Import the auth store
-import type { SettlementActivityCreate } from '@/types/expense'; // Import the type for the payload
+import axios from 'axios'
+import { API_BASE_URL } from '@/config/api-config' // api-config.ts can be moved to src/config/
+import router from '@/router' // Import the router instance
+import { useAuthStore } from '@/stores/auth' // Import the auth store
+import type { SettlementActivityCreate } from '@/types/expense' // Import the type for the payload
 
 // Create axios instance
 const api = axios.create({
@@ -11,76 +11,80 @@ const api = axios.create({
     'Content-Type': 'application/json',
   },
   withCredentials: true, // Enable sending cookies and authentication headers
-});
+})
 
 // Request interceptor
 api.interceptors.request.use(
   (config) => {
-    const token = localStorage.getItem('token'); // Or use useStorage from VueUse
+    const token = localStorage.getItem('token') // Or use useStorage from VueUse
     if (token) {
-      config.headers.Authorization = `Bearer ${token}`;
+      config.headers.Authorization = `Bearer ${token}`
     }
-    return config;
+    return config
   },
   (error) => {
-    return Promise.reject(error); // Simpler error handling
-  }
-);
+    return Promise.reject(error) // Simpler error handling
+  },
+)
 
 // Response interceptor
 api.interceptors.response.use(
   (response) => response,
   async (error) => {
-    const originalRequest = error.config;
-    const authStore = useAuthStore(); // Get auth store instance
+    const originalRequest = error.config
+    const authStore = useAuthStore() // Get auth store instance
 
     if (error.response?.status === 401 && !originalRequest._retry) {
-      originalRequest._retry = true;
+      originalRequest._retry = true
       try {
-        const refreshTokenValue = authStore.refreshToken; // Get from store for consistency
+        const refreshTokenValue = authStore.refreshToken // Get from store for consistency
         if (!refreshTokenValue) {
-          console.error('No refresh token, redirecting to login');
-          authStore.clearTokens(); // Clear tokens in store and localStorage
-          await router.push('/auth/login');
-          return Promise.reject(error);
+          console.error('No refresh token, redirecting to login')
+          authStore.clearTokens() // Clear tokens in store and localStorage
+          await router.push('/auth/login')
+          return Promise.reject(error)
         }
 
-        const response = await api.post('/auth/jwt/refresh', { // Use base 'api' instance for refresh
+        const response = await api.post('/auth/jwt/refresh', {
+          // Use base 'api' instance for refresh
           refresh_token: refreshTokenValue,
-        });
+        })
 
-        const { access_token: newAccessToken, refresh_token: newRefreshToken } = response.data;
-        authStore.setTokens({ access_token: newAccessToken, refresh_token: newRefreshToken });
+        const { access_token: newAccessToken, refresh_token: newRefreshToken } = response.data
+        authStore.setTokens({ access_token: newAccessToken, refresh_token: newRefreshToken })
 
-        originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
-        return api(originalRequest);
+        originalRequest.headers.Authorization = `Bearer ${newAccessToken}`
+        return api(originalRequest)
       } catch (refreshError) {
-        console.error('Refresh token failed:', refreshError);
-        authStore.clearTokens(); // Clear tokens in store and localStorage
-        await router.push('/auth/login');
-        return Promise.reject(refreshError);
+        console.error('Refresh token failed:', refreshError)
+        authStore.clearTokens() // Clear tokens in store and localStorage
+        await router.push('/auth/login')
+        return Promise.reject(refreshError)
       }
     }
-    return Promise.reject(error);
-  }
-);
+    return Promise.reject(error)
+  },
+)
 
 // Export the original axios too if some parts of your app used it directly
-const globalAxios = axios;
+const globalAxios = axios
 
-export { api, globalAxios };
+export { api, globalAxios }
 
-import { API_VERSION, API_ENDPOINTS } from '@/config/api-config';
+import { API_VERSION, API_ENDPOINTS } from '@/config/api-config'
 
 export const getApiUrl = (endpoint: string): string => {
+  // Don't add /api/v1 prefix for auth endpoints
+  if (endpoint.startsWith('/auth/')) {
+    return `${API_BASE_URL}${endpoint}`
+  }
   // Check if the endpoint already starts with /api/vX (like from API_ENDPOINTS)
   if (endpoint.startsWith('/api/')) {
-    return `${API_BASE_URL}${endpoint}`;
+    return `${API_BASE_URL}${endpoint}`
   }
   // Otherwise, prefix with /api/API_VERSION
-  return `${API_BASE_URL}/api/${API_VERSION}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
-};
-
+  return `${API_BASE_URL}/api/${API_VERSION}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`
+}
 
 export const apiClient = {
   get: (endpoint: string, config = {}) => api.get(getApiUrl(endpoint), config),
@@ -88,13 +92,17 @@ export const apiClient = {
   put: (endpoint: string, data = {}, config = {}) => api.put(getApiUrl(endpoint), data, config),
   patch: (endpoint: string, data = {}, config = {}) => api.patch(getApiUrl(endpoint), data, config),
   delete: (endpoint: string, config = {}) => api.delete(getApiUrl(endpoint), config),
-  
-  // Specific method for settling an expense split
-  settleExpenseSplit: (expenseSplitId: number, activityData: SettlementActivityCreate, config = {}) => {
-    // Construct the endpoint URL correctly, assuming API_VERSION is part of the base path or needs to be here
-    const endpoint = `/expense_splits/${expenseSplitId}/settle`; // Path relative to /api/API_VERSION
-    return api.post(getApiUrl(endpoint), activityData, config);
-  }
-};
 
-export { API_ENDPOINTS }; // Also re-export for convenience
\ No newline at end of file
+  // Specific method for settling an expense split
+  settleExpenseSplit: (
+    expenseSplitId: number,
+    activityData: SettlementActivityCreate,
+    config = {},
+  ) => {
+    // Construct the endpoint URL correctly, assuming API_VERSION is part of the base path or needs to be here
+    const endpoint = `/expense_splits/${expenseSplitId}/settle` // Path relative to /api/API_VERSION
+    return api.post(getApiUrl(endpoint), activityData, config)
+  },
+}
+
+export { API_ENDPOINTS } // Also re-export for convenience
diff --git a/fe/src/stores/auth.ts b/fe/src/stores/auth.ts
index 0a9276c..3580bb5 100644
--- a/fe/src/stores/auth.ts
+++ b/fe/src/stores/auth.ts
@@ -1,94 +1,94 @@
-import { API_ENDPOINTS } from '@/config/api-config';
-import { apiClient } from '@/services/api';
-import { defineStore } from 'pinia';
-import { ref, computed } from 'vue';
-import router from '@/router';
-
+import { API_ENDPOINTS } from '@/config/api-config'
+import { apiClient } from '@/services/api'
+import { defineStore } from 'pinia'
+import { ref, computed } from 'vue'
+import router from '@/router'
 
 interface AuthState {
-  accessToken: string | null;
-  refreshToken: string | null;
+  accessToken: string | null
+  refreshToken: string | null
   user: {
-    email: string;
-    name: string;
-    id?: string | number;
-  } | null;
+    email: string
+    name: string
+    id?: string | number
+  } | null
 }
 
 export const useAuthStore = defineStore('auth', () => {
   // State
-  const accessToken = ref<string | null>(localStorage.getItem('token'));
-  const refreshToken = ref<string | null>(localStorage.getItem('refreshToken'));
-  const user = ref<AuthState['user']>(null);
+  const accessToken = ref<string | null>(localStorage.getItem('token'))
+  const refreshToken = ref<string | null>(localStorage.getItem('refreshToken'))
+  const user = ref<AuthState['user']>(null)
 
   // Getters
-  const isAuthenticated = computed(() => !!accessToken.value);
-  const getUser = computed(() => user.value);
+  const isAuthenticated = computed(() => !!accessToken.value)
+  const getUser = computed(() => user.value)
 
   // Actions
   const setTokens = (tokens: { access_token: string; refresh_token?: string }) => {
-    accessToken.value = tokens.access_token;
-    localStorage.setItem('token', tokens.access_token);
+    accessToken.value = tokens.access_token
+    localStorage.setItem('token', tokens.access_token)
     if (tokens.refresh_token) {
-      refreshToken.value = tokens.refresh_token;
-      localStorage.setItem('refreshToken', tokens.refresh_token);
+      refreshToken.value = tokens.refresh_token
+      localStorage.setItem('refreshToken', tokens.refresh_token)
     }
-  };
+  }
 
   const clearTokens = () => {
-    accessToken.value = null;
-    refreshToken.value = null;
-    user.value = null;
-    localStorage.removeItem('token');
-    localStorage.removeItem('refreshToken');
-  };
+    accessToken.value = null
+    refreshToken.value = null
+    user.value = null
+    localStorage.removeItem('token')
+    localStorage.removeItem('refreshToken')
+  }
 
   const setUser = (userData: AuthState['user']) => {
-    user.value = userData;
-  };
+    user.value = userData
+  }
 
   const fetchCurrentUser = async () => {
     if (!accessToken.value) {
-      clearTokens();
-      return null;
+      clearTokens()
+      return null
     }
     try {
-      const response = await apiClient.get(API_ENDPOINTS.USERS.PROFILE);
-      setUser(response.data);
-      return response.data;
+      const response = await apiClient.get(API_ENDPOINTS.USERS.PROFILE)
+      setUser(response.data)
+      return response.data
     } catch (error: any) {
-      console.error('AuthStore: Failed to fetch current user:', error);
-      clearTokens();
-      return null;
+      console.error('AuthStore: Failed to fetch current user:', error)
+      clearTokens()
+      return null
     }
-  };
+  }
 
   const login = async (email: string, password: string) => {
-    const formData = new FormData();
-    formData.append('username', email);
-    formData.append('password', password);
+    const formData = new FormData()
+    formData.append('username', email)
+    formData.append('password', password)
 
     const response = await apiClient.post(API_ENDPOINTS.AUTH.LOGIN, formData, {
       headers: {
         'Content-Type': 'application/x-www-form-urlencoded',
       },
-    });
+    })
 
-    const { access_token, refresh_token } = response.data;
-    setTokens({ access_token, refresh_token });
-    await fetchCurrentUser();
-    return response.data;
-  };
+    const { access_token, refresh_token } = response.data
+    setTokens({ access_token, refresh_token })
+    // Skip fetching profile data
+    // await fetchCurrentUser();
+    return response.data
+  }
 
   const signup = async (userData: { name: string; email: string; password: string }) => {
-    const response = await apiClient.post(API_ENDPOINTS.AUTH.SIGNUP, userData);
-    return response.data;
-  };
+    const response = await apiClient.post(API_ENDPOINTS.AUTH.SIGNUP, userData)
+    return response.data
+  }
 
   const logout = async () => {
-    clearTokens();
-    await router.push('/auth/login');
-  };
+    clearTokens()
+    await router.push('/auth/login')
+  }
 
   return {
     accessToken,
@@ -103,5 +103,5 @@ export const useAuthStore = defineStore('auth', () => {
     login,
     signup,
     logout,
-  };
-});
+  }
+})
diff --git a/fe/src/stores/listDetailStore.ts b/fe/src/stores/listDetailStore.ts
index 0f1e880..0401ba7 100644
--- a/fe/src/stores/listDetailStore.ts
+++ b/fe/src/stores/listDetailStore.ts
@@ -1,18 +1,20 @@
-import { defineStore } from 'pinia';
-import { apiClient, API_ENDPOINTS } from '@/services/api'; 
-import type { Expense, ExpenseSplit, SettlementActivity } from '@/types/expense';
-import type { SettlementActivityCreate } from '@/types/expense'; 
-import type { List } from '@/types/list'; 
+import { defineStore } from 'pinia'
+import { apiClient, API_ENDPOINTS } from '@/services/api'
+import type { Expense, ExpenseSplit, SettlementActivity } from '@/types/expense'
+import type { SettlementActivityCreate } from '@/types/expense'
+import type { List } from '@/types/list'
+import type { AxiosResponse } from 'axios'
 
 export interface ListWithExpenses extends List {
-  expenses: Expense[];
+  id: number
+  expenses: Expense[]
 }
 
 interface ListDetailState {
-  currentList: ListWithExpenses | null;
-  isLoading: boolean;
-  error: string | null;
-  isSettlingSplit: boolean; 
+  currentList: ListWithExpenses | null
+  isLoading: boolean
+  error: string | null
+  isSettlingSplit: boolean
 }
 
 export const useListDetailStore = defineStore('listDetail', {
@@ -25,101 +27,108 @@ export const useListDetailStore = defineStore('listDetail', {
 
   actions: {
     async fetchListWithExpenses(listId: string) {
-      this.isLoading = true;
-      this.error = null;
+      this.isLoading = true
+      this.error = null
       try {
-        // This assumes API_ENDPOINTS.LISTS.BY_ID(listId) generates a path like "/lists/{id}"
-        // and getApiUrl (from services/api.ts) correctly prefixes it with API_BASE_URL and /api/API_VERSION if necessary.
-        const endpoint = API_ENDPOINTS.LISTS.BY_ID(listId); 
-        
-        const response = await apiClient.get(endpoint); 
-        this.currentList = response as ListWithExpenses; 
+        const endpoint = API_ENDPOINTS.LISTS.BY_ID(listId)
+        const response = await apiClient.get(endpoint)
+        this.currentList = response.data as ListWithExpenses
       } catch (err: any) {
-        this.error = err.response?.data?.detail || err.message || 'Failed to fetch list details';
-        this.currentList = null;
-        console.error('Error fetching list details:', err);
+        this.error = err.response?.data?.detail || err.message || 'Failed to fetch list details'
+        this.currentList = null
+        console.error('Error fetching list details:', err)
       } finally {
-        this.isLoading = false;
+        this.isLoading = false
       }
     },
 
-    async settleExpenseSplit(payload: { 
-      list_id_for_refetch: string, // ID of the list to refetch after settlement
-      expense_split_id: number, 
-      activity_data: SettlementActivityCreate 
+    async settleExpenseSplit(payload: {
+      list_id_for_refetch: string // ID of the list to refetch after settlement
+      expense_split_id: number
+      activity_data: SettlementActivityCreate
     }): Promise<boolean> {
-      this.isSettlingSplit = true;
-      this.error = null; 
+      this.isSettlingSplit = true
+      this.error = null
       try {
         // TODO: Uncomment and use when apiClient.settleExpenseSplit is available and correctly implemented in api.ts
         // For now, simulating the API call as it was not successfully added in the previous step.
-        console.warn(`Simulating settlement for split ID: ${payload.expense_split_id} with data:`, payload.activity_data);
+        console.warn(
+          `Simulating settlement for split ID: ${payload.expense_split_id} with data:`,
+          payload.activity_data,
+        )
         // const createdActivity = await apiClient.settleExpenseSplit(payload.expense_split_id, payload.activity_data);
-        // console.log('Settlement activity created (simulated):', createdActivity); 
-        await new Promise(resolve => setTimeout(resolve, 500)); // Simulate network delay
+        // console.log('Settlement activity created (simulated):', createdActivity);
+        await new Promise((resolve) => setTimeout(resolve, 500)) // Simulate network delay
         // End of placeholder for API call
 
         // Refresh list data to show updated statuses.
         // Ensure currentList is not null and its ID matches before refetching,
         // or always refetch if list_id_for_refetch is the source of truth.
         if (payload.list_id_for_refetch) {
-             await this.fetchListWithExpenses(payload.list_id_for_refetch);
+          await this.fetchListWithExpenses(payload.list_id_for_refetch)
         } else if (this.currentList?.id) {
-            // Fallback if list_id_for_refetch is not provided but currentList exists
-            await this.fetchListWithExpenses(String(this.currentList.id));
+          // Fallback if list_id_for_refetch is not provided but currentList exists
+          await this.fetchListWithExpenses(String(this.currentList.id))
         } else {
-            console.warn("Could not refetch list details: list_id_for_refetch not provided and no currentList available.");
+          console.warn(
+            'Could not refetch list details: list_id_for_refetch not provided and no currentList available.',
+          )
         }
-        
-        this.isSettlingSplit = false;
-        return true; // Indicate success
+
+        this.isSettlingSplit = false
+        return true // Indicate success
       } catch (err: any) {
-        const errorMessage = err.response?.data?.detail || err.message || 'Failed to settle expense split.';
-        this.error = errorMessage; 
-        console.error('Error settling expense split:', err);
-        this.isSettlingSplit = false;
-        return false; // Indicate failure
+        const errorMessage =
+          err.response?.data?.detail || err.message || 'Failed to settle expense split.'
+        this.error = errorMessage
+        console.error('Error settling expense split:', err)
+        this.isSettlingSplit = false
+        return false // Indicate failure
       }
     },
 
     setError(errorMessage: string) {
-        this.error = errorMessage;
-        this.isLoading = false; 
-    }
+      this.error = errorMessage
+      this.isLoading = false
+    },
   },
 
   getters: {
     getList(state: ListDetailState): ListWithExpenses | null {
-      return state.currentList;
+      return state.currentList
     },
     getExpenses(state: ListDetailState): Expense[] {
-      return state.currentList?.expenses || [];
+      return state.currentList?.expenses || []
     },
-    getPaidAmountForSplit: (state: ListDetailState) => (splitId: number): number => {
-      let totalPaid = 0;
-      if (state.currentList && state.currentList.expenses) {
-        for (const expense of state.currentList.expenses) {
-          const split = expense.splits.find(s => s.id === splitId);
-          if (split && split.settlement_activities) {
-            totalPaid = split.settlement_activities.reduce((sum, activity) => {
-              return sum + parseFloat(activity.amount_paid);
-            }, 0);
-            break; 
+    getPaidAmountForSplit:
+      (state: ListDetailState) =>
+      (splitId: number): number => {
+        let totalPaid = 0
+        if (state.currentList && state.currentList.expenses) {
+          for (const expense of state.currentList.expenses) {
+            const split = expense.splits.find((s) => s.id === splitId)
+            if (split && split.settlement_activities) {
+              totalPaid = split.settlement_activities.reduce((sum, activity) => {
+                return sum + parseFloat(activity.amount_paid)
+              }, 0)
+              break
+            }
           }
         }
-      }
-      return totalPaid;
-    },
-    getExpenseSplitById: (state: ListDetailState) => (splitId: number): ExpenseSplit | undefined => {
-        if (!state.currentList || !state.currentList.expenses) return undefined;
+        return totalPaid
+      },
+    getExpenseSplitById:
+      (state: ListDetailState) =>
+      (splitId: number): ExpenseSplit | undefined => {
+        if (!state.currentList || !state.currentList.expenses) return undefined
         for (const expense of state.currentList.expenses) {
-            const split = expense.splits.find(s => s.id === splitId);
-            if (split) return split;
+          const split = expense.splits.find((s) => s.id === splitId)
+          if (split) return split
         }
-        return undefined;
-    }
+        return undefined
+      },
   },
-});
+})
 
 // Assuming List interface might be defined in fe/src/types/list.ts
 // If not, it should be defined like this:
diff --git a/fe/src/types/item.ts b/fe/src/types/item.ts
new file mode 100644
index 0000000..8652ed6
--- /dev/null
+++ b/fe/src/types/item.ts
@@ -0,0 +1,11 @@
+export interface Item {
+  id: number
+  name: string
+  quantity?: number | null
+  is_complete: boolean
+  price?: string | null // String representation of Decimal
+  list_id: number
+  created_at: string
+  updated_at: string
+  version: number
+}
diff --git a/fe/src/types/list.ts b/fe/src/types/list.ts
new file mode 100644
index 0000000..3d912c1
--- /dev/null
+++ b/fe/src/types/list.ts
@@ -0,0 +1,18 @@
+import type { Expense } from './expense'
+import type { Item } from './item'
+
+export interface List {
+  id: number
+  name: string
+  description?: string | null
+  is_complete: boolean
+  group_id?: number | null
+  items: Item[]
+  version: number
+  updated_at: string
+  expenses?: Expense[]
+}
+
+export interface ListWithExpenses extends List {
+  expenses: Expense[]
+}