var is hoisted, that means it's accessible right in the beginning of the scope where it's defined even the declaration line could be in the end of the scope. If you access the var before it's declaration it's undefined because you still need to execute the declaration with possible initialization this variable to particular value.
So your second example works that way.
Read about hoisting here:
https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
But in your first example 2 <scripts> have 2 different scopes, so the var basically doesn't exists in the first script thus the error not defined.
Read about var and its scope here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
IMPORTANT
I strongly advocate against using var. Use const and let instead. Using var with hoisting leads to bugs which sometimes are very hard to debug and fix. If you need using only var in your production, just downgrade your code with esbuild for example to the appropriate older version of JS.
Interestingly enough, const and let are kinda hoisted also, but accessing them in the hoisted state leads to a runtime error (that's called a temporal dead zone), that's why they are more safe because you get an error immediately opposed to var hoisted silently and thus leaving you with a potential bug you don't know about.
About the temporal dead zone:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz
<body>
<script>
console.log(x);
const x = 10;
</script>
</body>
An interesting part: the 2 <script>s are executed in order of appearance but if you change the order by deffering it (executing after DOM is built) with type="module" then you get the variable defined. This is only way to defer an inline script since defer wouldn't work:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
<body>
<script type="module">
console.log(x);
</script>
<script>
var x = 10;
</script>
</body>