tl;dr install this user script, and it becomes possible to vote to close for old close reasons such as "not constructive" and "too localized".
After doing some twiddling with Stack Exchange JavaScript, I discovered it's possible to vote to close for old, now-decommissioned close reasons such as "not constructive", "not a real question", and "too localized".
While writing my own script to cast close votes, I discovered that it's possible to cast votes for reasons that can no longer be selected. Basically, the server only checks to see if the close reason ID is valid, without checking to see if the reason is one of the ones that can actually be selected.
Awesome Poodles has written a user script that adds these close reason options back into the close voting UI, as a proof of concept. (Note that the old "exact duplicate" reason is missing from that script because I couldn't figure out how to pass dupe targets to it.)
I tested this out, and this script does work for <3k users (it will cast a recommend closure flag), and it also works within Stack Overflow for Teams, where all users have binding close vote privileges.
Can this please be fixed? As far as I could tell, the only good reason for keeping this workaround was because it previously wasn't possible to close Teams questions as off-topic (only as duplicate), and this workaround would allow for it, but now that an official off-topic reason has been implemented for Teams, I see no reason to keep it around, as it allows users to vote for close reasons that were removed for good reason.