Option 1: Find a visual error, open devtools, find the nearest most descriptive class or id (.primary? Oh no…), open IDE, global search in styles folder structure (most likely but not the only place to find CSS) for “.primary”. 40 files returned. After 15 minutes find a file that looks like it might be the right one. 10 minutes to understand the CSS (lots of advanced CSS in here…). Find the cause of the visual error, make the 1 line change. 30 minutes - job done.
Option 2: Find a visual error, open e.g. React Devtools, find the component name, open the IDE, find the component source file, find the HTML, change the utility style class, job done - 5 minutes.
These are not contrived examples. I had a one liner take 40 minutes to find in a codebase a couple of weeks ago. Not an exaggeration.
I really used to believe in separation of concerns but I don’t any more, because of all the time I’ve had to spend fighting with “option 1” codebases over the years. Pretty much any big codebase with normal CSS is going to be an “option 1” eventually unless it’s the work of a single good CSS developer (rare skill), or a team where someone who’s a good leader also cares about CSS enough to enforce a convention like BEM in perpetuity (even rarer skill).
Anyone building anything complex these days is using some component abstraction - whether it’s client side or not - to manage complexity. May as well make use of it for styles if it’s already there.
The reason that there’s a backlash against separation of concerns, the cascade, and (low) specificity is that each of these things is a complete disaster for maintainability in the long run.
One note in making an example of that Catalyst button. If you wrote out all the styles required to do the amount of work that button is doing it would also be extremely difficult to understand, and what’s more, it’d be in a completely different file to the single thing that gives it any meaning - the HTML.