/* ============================================================ Lập kế hoạch — bottom-up: mỗi khóa có phễu riêng, tổng cộng dồn. Mọi số đều chỉnh được · thêm/bớt khóa & hạng mục · lưu theo tháng. ============================================================ */ const PLAN_DRAFT_KEY = 'aau.draft.v2'; const uid = (p) => p + Math.random().toString(36).slice(2, 8); function loadDrafts() { try { return JSON.parse(localStorage.getItem(PLAN_DRAFT_KEY)) || {}; } catch (e) { return {}; } } // stepper nhỏ +/- cho số có biên function PlanStepper({ value, onChange, step = 1, min = 0, max = Infinity, fmt = (v) => v, w = 56 }) { const set = (v) => onChange(Math.max(min, Math.min(max, Math.round(v * 1000) / 1000))); return (