Visualforce requires ng-app to have a value to pass its own syntax checker. If a value is passed to ng-app to get past Visualforce then that value is interpreted by Angular as a module used to bootstrap your page and must be defined.

In the example above I created a module called "noop" that literally does nothing but take-up space to make something else work.

Now my page behaved just like W3Schools said it should.

Having Googled around some more, I found multiple tutorials and videos introducing the neat things people have done with Visualforce and Angular, but all of them are too complicated for the absolute novice. But the search pages did alert me that Salesforce is so geeked about the combination of Angular and Visualforce that they've created an app for the appexchange that installs angular, underbar, bootstrap, and several other JS libraries. The app is called Angilar MP [sic]. The page gives instructions for how to install it into your org and includes some demo pages showing how to put more complicated examples together.

Since the app loads all those Javascript libraries into a staticresource we can re-write our application to look just a tad more Visualforce-like.

All it really does is replace the <script src="..." /> with <apex:includeScript value="..." /> and use the staticresource's Angular JS source.

PS If you're not already familiar with it, another of the cool resources include in the package is UnderscoreJS. Lots of cool Javascript utility functions in there I wish I'd known were around years ago. Regardless, they'll make my current pages easier to write.