CSS doesn't really support this: making an element less opaque usually also makes the children less opaque. This isn't an issue for background colors, where you can control the alpha using RGBA, but for images, things are more complicated. Here's a hacky workaround using tags, adapted from this awesome trick here:
tw-story[tags~='start'] #bg-hack {
display: block;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
tw-story[tags~='start'] #bg-hack::after {
background-image: url("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRSx5dqbks2oE0Blq53u5u91-PK8Yg0ARpB31XQ_YEeWUiQeVIuMs2X34oX");
background-size: cover;
opacity: 0.5; /*whatever you want*/
height: 100%;
width: 100%;
position: absolute;
z-index: -1;
content: "";
}
Then, in JavaScript:
$(function () {
var $bgHack = $(document.createElement('div'));
$bgHack.attr('id', 'bg-hack');
$('tw-story').append($bgHack);
});
I'm not sure how you've structured things using 'html.start' as a selector. I recommend moving to tags if possible, since it's the semi-official way of doing styling in Harlowe. If you can't/don't want to, you can just change the selectors in the CSS to reflect your system and things should work.
I tested this in the web version of Twine 2.1.3 with Harlowe 2.0.1 and in Chrome.
Reportedly works on Firefox, Safari, and IE9+ as well, according to the above link.