Tailwind, in base.css removes default font-weight for hn.
So, when I’m trying to define default font-weight for my h2, the style generated by base.css is read first.
This would be a CSS selector specificity issue then. Wrap your frontend styles (that should override) with extra selectors (html or html body) then. Those would are also automatically changed to .editor-styles-wrapper, if you use these frontend styles as editor styles.
html {
(my tailwind styles)
}
html h1 would be more specific than just h1, hence override it.
To be honest, I had to even use !important in frontend styles to override some of the Gutenberg-injected styles because those are either inline or !important.
The theme.json is primarily used for the editor (backend/admin).
Often you will have to declare your own frontend styles.
So you still use the theme.json as much as possible,
and then use normal CSS frontend styles (which you can also add as editor styles to override in the backend) to fix what is wrong by the theme.json-generated styles.
I also use a editor.css for overriding editor-specific styles.
Edit: This is how I currently enqueue editor-only/-specific styles and scripts in Sage 10:
add_action('admin_enqueue_scripts', function ($hook) {
if ('post.php' !== $hook) {
return;
}
bundle('editor')->enqueue();
});
When $hook equals post.php, it is the editor page.