diff --git a/src/components/expenses/expense-form-dialog.tsx b/src/components/expenses/expense-form-dialog.tsx
index 0c330184..9e801a93 100644
--- a/src/components/expenses/expense-form-dialog.tsx
+++ b/src/components/expenses/expense-form-dialog.tsx
@@ -11,6 +11,8 @@ import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
+import { FormErrorSummary } from '@/components/forms/form-error-summary';
+import { useFormScrollToError } from '@/hooks/use-form-scroll-to-error';
import {
Select,
SelectContent,
@@ -75,6 +77,11 @@ export function ExpenseFormDialog({ open, onOpenChange, expense }: ExpenseFormDi
paymentStatus: 'unpaid',
},
});
+ // Scroll-to-first-error wrapper around handleSubmit. On validation
+ // failure it auto-scrolls + focuses the first errored input so reps
+ // can see what failed without hunting (especially important on tall
+ // drawer-based forms like this one).
+ const onSubmitWithScroll = useFormScrollToError(handleSubmit, errors);
useEffect(() => {
if (open && expense) {
@@ -208,7 +215,19 @@ export function ExpenseFormDialog({ open, onOpenChange, expense }: ExpenseFormDi