I came up with a solution I'm pretty satisfied with. In my original description of my goal I said I just the stylesheet to be applied dynamically, but to be more complete I ideally wanted the stylesheet
and the view HTML partial to be applied dynamically. That way a theme developer wouldn't be limited to just modifications that were cosmetic (CSS) but could actually make structural modifications. The solution I arrived at does this!
The Solution
To start with, my route definition looks like this...
$routeProvider.when('/:themeId', {
templateUrl: 'views/main-view-shim.html',
controller: 'MainCtrl'
});
Then, my "main-view-shim.html" file contains a single <div>, using the ng-include directive to dynamically select the right HTML view partial...
<div ng-include="'themes/' + themeId + '/views/main.html'"></div>
Finally, in the "themes/[someThemeName]/views/main.html" file, I link to the appropriate stylesheet like so...
<link rel="stylesheet" ng-href="themes/{{themeId}}/styles/main.css">
<!-- other HTML here -->
Luckily, the consensus seems to be that unlike older HTML specs, HTML5 does allow a <link> in the body of an HTML page and not just in the head. The only potential issue is that the HTML may be displayed unstyled for a bit if the CSS file takes a while to load, but in my experience so far that hasn't happened although I'm sure the possibility is real over slower connections with large CSS files. But in my case this is a perfectly acceptable tradeoff.