I agree this looks like a font issue. Most fonts don’t have all characters, and different fonts offer different selections of characters. When a font lacks a character that your text uses, your system will render it with a different font that has the character.
This also explains why the code block in your post doesn’t show the problem. Code blocks normally use a monospaced font (meaning the characters are all the same width), which differs from how text is usually presented. So the code block is using a different font than the rest of the post, and that font lacks all of the circled numeral characters, so they’re all rendered in the fallback font. (Or maybe the code block font has all of the circled numerals, but I think that’s less likely.)
Circled 1 has an East Asian Width of narrow in the text context your using. U+2460
Circled 21 always has an East Asian Width of wide. U+3251
That’s why some fonts might display them differently, either intentionally adhering to the standard or simply not including those characters and letting them default to another font. And some fonts choose to make them equal in width.
What you’re seeing is a consequence of the font. The same happens in other applications.
In Word, Aptos, Calibri, and even the monospace font Source Sans Pro default to MS Gothic for ㉑. Aptos didn’t make an 11 – 20, and Source Sans Pro didn’t even bother to make 1 – 20 which all default to Cambria Math.
In Google Docs, the default for ㉑ happens to be larger than Arial’s 1 – 20 and smaller than Calibri’s 1 – 20. (I can’t identify that default font offhand.)
In my Obsidian, Inter falls back to Inter Variable for 1 – 9, Segoe UI Symbol for 10 – 20, and MS PGothic for 21. Obsidian sets several fall backs, but you can change them in Setting or through CSS.