That is because the length function returns a float and then the step function goes to zero if below the threshold (the hard coded number there) or 1 if above. at the end c is actually an integer, because you only added or substracted 1 and 0. last, when you pass a float to vec4( ) it will assign that value to all the values of the vec4, hence you end up with all values 0 or more or equal to 1. Does it make sense?
I often find it helpful to break shader code into smaller pieces, to see how it works. With the original code, you can see how the step() functions affect the color. It can be a good way to troubleshoot:
// run each separately in the shader to see what they do
float c = step(length(tile), 0.6);
// float c = step(length(tile - vec2(1.0)), 0.6);
// float c = step(length(tile), 0.6) - step(length(tc), 0.4);