To prevent a variable from going below 0 in harlowe you kinda have to do it manually, like so:
(link: "Insult him")[\
"Yore're stoopid!" you shout.
He responds, "No u!"(set: $popularity to it - 10)(if: $popularity < 0)[(set: $popularity to 0)]
\]
So if $popularity was 5, now it's 0 and not -5.
If you're going to do this a lot, it's a little less cumbersome to put the (if:) code you'd normally copy-paste everywhere into it's own passage and use the (display:) macro, like so:
<!-- This is in a passage titled "Clamp Popularity" (make sure to collapse whitespace!)-->
{
(if: $popularity < 0)[(set: $popularity to 0)]
}
<!-- This is in the main passage -->
(link: "Insult him")[\
"Yore're stoopid!" you shout.
He responds, "No u!"(set: $popularity to it - 10)(display: "Clamp Popularity")
\]
Maybe a bit unnecessary here, but this sort of thing really shines when you want to make sure a variable that stays between both a minimum and maximum value. For example: forcing $health to be between 0 and $maxHealth.
Money is a bit more complicated though, since you need to check if you're going to go under 0 before the player can even buy something.
There are many different ways to do this depending entirely on stylistic preference, but here's an easy one:
(link: "Buy Sandwich ($3.50)")[\
(if: $money < 3.50)[You rummage around in your pockets. "Dang, a little short on cash."]\
(else:)[You buy the sandwich. Hot Italian, your favorite.(set: $money to it - 3.50)]
\]
Again, there are all sorts of ways to do this, but I hope this helps.