"use client"; const LEVELS = [ { label: "Weak", bar: "bg-red-500", text: "text-red-600" }, { label: "Fair", bar: "bg-amber-500", text: "text-amber-600" }, { label: "Good", bar: "bg-brand-500", text: "text-brand-600" }, { label: "Strong", bar: "bg-green-500", text: "text-green-600" }, ] as const; /** A purely visual affordance - length/variety heuristics scored 0-4, shown * as an animated bar. Doesn't gate submission or loosen the real policy * (still enforced by the password field's own Zod schema). */ function scorePassword(password: string): number { if (!password) return 0; let score = 0; if (password.length >= 10) score += 1; if (password.length >= 14) score += 1; if (/[^a-zA-Z0-9]/.test(password)) score += 1; if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score += 1; return Math.min(score, 4); } export function PasswordStrengthMeter({ password }: { password: string }) { const score = scorePassword(password); if (!password) return null; const level = LEVELS[Math.max(score - 1, 0)] ?? LEVELS[0]; const widthPercent = (score / 4) * 100; return (

{level.label}

); }