You have two separate variables.
They have the same name, but they’re separate, as if they had different names.
When you use that name, you will search from the innermost scope outwards until a variable by that name is found, and if that search goes past the outermost scope then … you’ll get some error message for trying to read something that isn’t there.
So when the compiler is reading the code and creating an internal representation of it, it will start with the outermost scope, gather all variables into a list. Then scopes within that receive the same treatment, and uses of non-existing ones result in a search outwards and get rewritten, and then it keeps going inwards until it’s all done.
Again, compiler and compiling are very loose terms, really only means turning one thing into another. Your code has multiple intermediary representations, starting with text and then turned into other data structures. Some languages eventually create a representation in the form of a binary executable of a specific format that some operating system knows how to launch, others keep the representation in memory and then starts running it directly.