

Glad you got it working!
My hypothesis is that it was DNS (channeling Jeff Geerling here). Since Pihole is your DNS (makes sense), it may have recognized that address as its own and given you its IP. By resolving the naming collision, you fixed the problem because the name is now unambiguous.
These problems can happen very easily when you’re using DHCP and sharing a network and domain name between your clients and upstreams, so I think using home.arpa for one and your other domain for the other was a good idea.
Your diagram is almost right, but I think it will help to understand more of the details. It’s important to understand the difference between DNS (domain name lookup) and IP routing.
To break your diagram down more, this is what happens when any computer looks up your website:
GET / HTTP/1.1 Host: example.com ...lots more headers... <blank line>That’s all very simplified, of course.
As others pointed out, things may seem to work differently from the “inside”, if hairpinning is not available or enabled. This is not related to DNS, but to IP routing. The firewall doing NAT can get confused and not know what to do when an internal request goes to an external IP that it itself has. When it turns that around and routes it back to the internal network, that’s called hairpinning.
One “fix” for this, often used in enterprises, is to use so-called split DNS. All that means is that if you’re asking your internal DNS server for an internal name, it will give you the internal address (192.168.1.123 for example), but an external client would get an external IP.
TL;DR: DNS and IP routing are separate concerns and happen at different parts of the TCP/IP stack.