Timing issue with button press

Possibly the call to the animation is blocking and thus it only reads the button

if (digitalRead(BTN_PIN) == LOW)

once in a while.

if you want the system to be reactive, you need to come read the button often and can't have a blocking animation call

as a first try, call ws2812fx.service() only when animation is due (I don't know that library)

also set last_change with a negative value (-TIMER_MS at least) so that it's taken into account