I can't `ping ::ffff:192.168.0.1` and have it ping my router. There is a range reserved for representing IPv4 addresses, but the stack doesn't translate.
Yes. What were you expecting? There's no way for a v4-only device to reply to a packet from a v6 source address otherwise. The source address has to be mapped to an address the v4-only device understands, and then mapped back again for the reply packets.
It does translate, but it doesn't work for ping because ping bypasses most of the stack by sending raw packets. Try something like `telnet ::ffff:192.168.0.1 80`.
You need a translator, i.e. a middle host with dual IPv4/IPv6 stack that can convert an IPv4 packet to an IPv6 packet and v.v.
By the way, it's not just theoretical, it exists and it has been standardised, see https://nicmx.github.io/Jool/en/intro-xlat.html#ipv4ipv6-tra...
If it truly encapsulated IPv4, then there wouldn't be two stacks. It would be one stack and legacy devices could snip the xtra bits (or have it done for them via a router).