Implicit Type Casting
In short: when mixed types meet an operator, + is the special case:
if either side is a string, both sides become strings and get joined.
Every other arithmetic operator (-, *, /, %) only understands
numbers, so it coerces both sides to numbers first. Conditions coerce to
boolean using the falsy-eight rule. Evaluate left to right, one operator at
a time, and ask at each +: "is either side a string right now?" — not
what it started as.

A fade-out that becomes text
A length field holds a string; adding seconds the careless way does not add at all:
"214" + 6 joins to "2146" because a string is on the left. 6 + "214"
joins too — + doesn't care which side the string is on. 214 + 6 has no
string at all, so it adds normally to 220. true + 1 also has no
string, so true coerces to the number 1 instead, giving 2.
The other operators never join
Subtract, multiply and divide only ever mean "make this a number":
"214" - 6 is 208: minus has no joining behaviour, so it coerces the
string to a number the same way Number() would. "abc" - 1 can't become
a number at all, so the result is NaN. null + 1 is 1 — null
coerces to 0 for arithmetic, and since neither side is a string, +
adds rather than joins.
Reading a chain of operators left to right
Order changes everything, because once a string appears, every + after
it joins too:
1 + 2 + "3" + 4 - 1 goes: 1 + 2 is 3 (no string yet), 3 + "3" joins
to "33", "33" + 4 joins to "334", then "334" - 1 finally needs a
number and gives 333. But "1" + 2 + 3 starts with the string already in
place: "1" + 2 is "12", then "12" + 3 is "123" — the same digits,
completely different answer, because of where the string sat.
First pair: 1 + 2
No strings. Add numbers: 3.
The safe habit: convert form input with Number() the moment you read it,
so no later + can ever meet a string by accident.
Quick practice
What is "5" + 2?
What is "5" - 2?
What is 1 + 2 + "3"?
What is true + true?
