I think of std_logic_vector the same way I would think of digits in a number... the rightmost digit is digit zero. It most likely isn't the best way set things up for this example, but it avoids the need to swap the bit ordering in the ASCII characters.
Oh, for the button synchronization... signals take time to get across the chip (speed of light, capacitance and so on), so different parts of the design can see different values for the same signal as it change unless. As you can't control when the user might press the button you have to sample the value of the input signal on the clock edge, holding that in a register. That registered value is then used drive the rest of your logic.
There is a slight complication - If the signal from the button changes state *exactly* on the clock edge, the flipflop might not be able to correctly register as a 1 or a 0, but could be in some weird "metastable" state that takes a short while to become either a 1 or a 0. To stop this causing bugs in the operation of the logic deeper in the deign, the output of that fliplfop is then sampled a second time to get a "known good, either 1 or 0" signal, that can get to where it needs to within a clock cycle.
Hence the design pattern... btn gets sampled into btn_metastable (which is a bit dodgy if you use it), and then btn_metastable gets sampled into btn_synchronized, which is then used by the rest of the logic.