diff --git a/TODO.md b/TODO.md
index f1d36c3..4646042 100644
--- a/TODO.md
+++ b/TODO.md
@@ -325,6 +325,7 @@ This file is the single source of truth for roadmap and delivery progress.
- [2026-02-12] Page editor now supports locale translations in `/pages/:id`; public page rendering uses locale-aware page lookup with base-content fallback.
- [2026-02-12] Public rendering integration advanced with locale-aware navigation/news translations and a new public commission request entry route (`/[locale]/commissions`) that creates/reuses customer records and opens a `new` commission.
- [2026-02-12] Public portfolio baseline added with `/{locale}/portfolio` and `/{locale}/portfolio/{slug}`, including published-artwork filters (gallery/album/category/tag), rendition image streaming via web `/api/media/file/:id`, and media-aware artwork detail rendering.
+- [2026-02-12] Public UX pass: commission request flow now reports explicit invalid budget range errors, and header navigation now falls back to localized defaults (`home`, `portfolio`, `news`, `commissions`) when no CMS menu exists; seed data now creates those default menu entries.
## How We Use This File
diff --git a/apps/web/src/app/[locale]/commissions/page.tsx b/apps/web/src/app/[locale]/commissions/page.tsx
index ba11093..46cd106 100644
--- a/apps/web/src/app/[locale]/commissions/page.tsx
+++ b/apps/web/src/app/[locale]/commissions/page.tsx
@@ -69,6 +69,13 @@ export default async function PublicCommissionRequestPage({
async function submitCommissionRequestAction(formData: FormData) {
"use server"
+ const budgetMin = readNullableNumber(formData, "budgetMin")
+ const budgetMax = readNullableNumber(formData, "budgetMax")
+
+ if (budgetMin != null && budgetMax != null && budgetMax < budgetMin) {
+ redirect(buildRedirect(locale, { error: "budget_range_invalid" }))
+ }
+
try {
await createPublicCommissionRequest({
customerName: readInputString(formData, "customerName"),
@@ -77,8 +84,8 @@ export default async function PublicCommissionRequestPage({
customerInstagram: readNullableString(formData, "customerInstagram"),
title: readInputString(formData, "title"),
description: readNullableString(formData, "description"),
- budgetMin: readNullableNumber(formData, "budgetMin"),
- budgetMax: readNullableNumber(formData, "budgetMax"),
+ budgetMin,
+ budgetMax,
})
} catch {
redirect(buildRedirect(locale, { error: "submission_failed" }))
@@ -110,6 +117,11 @@ export default async function PublicCommissionRequestPage({
{t("error")}
) : null}
+ {error === "budget_range_invalid" ? (
+