90% this is happening because they are making a selection before the page has actually fully loaded.
When you confirm the basic testing steps below to establish ground-truth a quick fix can simply be to add a transition to the page that hides the add to cart until the relevant code is actually loaded.
A real fix is to optimize the theme to prioritize product form related javascript to load asap. It’s kinda nuts this isn’t the norm /shrug.
So whats going on here is the customers browser as the page is loading they literally can select “M” (medium) and see it is selected(and technically it is) and yet when they hit add to cart the XS(extra-small) is what’s actually added to the cart because it is the first item in the options and the currently selected one either in the theme, or what the javascript is set too when it loads just a bit before the AtC is hit.
This is most apparent when the variant parameter is missing or does not change i.e. product-name?variant=7654321
Other tests to run include disabling javascript to see what the behavior is when partially loaded, or fully loaded.
By partially loaded I mean making a selection and hitting the add to cart as soon as possible.
Or use developer tools to throttle the network connection to simulate a slow speed connection.
https://stackoverflow.com/questions/10328568/simulate-limited-bandwidth-from-within-chrome
And then for robustness doing the above with and without an adblocker running as this can be a factor too in javascript either not loading or being slow to load.
There’s also doing the above with a fresh install of the theme with {{ content_for_header }} commented out to remove app interference as a suspect. Note: some apps autoinstall files directly to a theme when it’s created making it harder to get a clean test /sigh.
FYI: There is no quantity shown on your cart page for items. If you do that on purpose and have a/b tested it as increasing conversions that is fascinating.