diff --git a/lang/es.json b/lang/es.json
index efcc2b9a..6eeb243c 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -1008,6 +1008,7 @@
"Period": "Período",
"Period Duration (days)": "Duración del Período (días)",
"Period Type": "Tipo de Período",
+ "Period and carry-over settings cannot be changed after a budget is created because budgets are calculated historically. If you need different settings, delete this budget and create a new one.": "La configuración de período y arrastre no se puede cambiar después de crear un presupuesto porque los presupuestos se calculan históricamente. Si necesitas una configuración diferente, elimina este presupuesto y crea uno nuevo.",
"Personal transfers": "Transferencias personales",
"Peruvian Sol": "Sol peruano",
"Pick whichever plan fits you, paste the matching code at checkout, and you are set.": "Elige el plan que prefieras, pega el código correspondiente al pagar y listo.",
diff --git a/resources/js/components/budgets/edit-budget-dialog.test.tsx b/resources/js/components/budgets/edit-budget-dialog.test.tsx
new file mode 100644
index 00000000..3b9e8974
--- /dev/null
+++ b/resources/js/components/budgets/edit-budget-dialog.test.tsx
@@ -0,0 +1,53 @@
+import type { Budget } from '@/types/budget';
+import { render, screen } from '@testing-library/react';
+import { describe, expect, it, vi } from 'vitest';
+import { EditBudgetDialog } from './edit-budget-dialog';
+
+vi.mock('@inertiajs/react', () => ({
+ router: {
+ patch: vi.fn(),
+ },
+}));
+
+vi.mock('@/actions/App/Http/Controllers/BudgetController', () => ({
+ update: () => ({ url: '/budgets/budget-1' }),
+}));
+
+vi.mock('@/components/ui/amount-input', () => ({
+ AmountInput: () => ,
+}));
+
+function makeBudget(): Budget {
+ return {
+ id: 'budget-1',
+ user_id: 'user-1',
+ name: 'Monthly budget',
+ period_type: 'monthly',
+ period_start_day: 1,
+ category_id: null,
+ label_id: null,
+ rollover_type: 'carry_over',
+ created_at: '2026-05-26T00:00:00.000000Z',
+ updated_at: '2026-05-26T00:00:00.000000Z',
+ deleted_at: null,
+ };
+}
+
+describe('EditBudgetDialog', () => {
+ it('explains locked budget period and carry-over fields', () => {
+ render(
+