We use the Dawn theme for all our stores. It is open source and can be found on Github.
There are multiple ways to update the theme, some more efficient than others.
Manual update from theme store - do not do this!
You can wait for a new release to be available on the theme store, download the code and replace the index.json and settings_data.json. But the problem with this is you probably have other customizations:
1. Custom styling
2. Injected app code in theme.liquid, product page etc.
And more. Thus updating to a new release this way is not smart.
Cherry picking commits or compare branch
Since all the theme code is version controlled and all commits/updates to the code are available, you can "merge" the updates to the theme with your custom changes automatically and in most cases without manually fixing conflicts between your custom changes and the theme updates.
For example, "cherry picking" commits, which means getting the code changes others(or you) have made on another branch into the live theme can easily be done with Intellij's git GUI:
What I suggest is having one live theme connected to the main branch of your repository. And then a dev branch connected to an unpublished theme:
You can then try to merge the theme updates to the dev branch and do a test to see if something broke. If nothing is broken, then you can move the changes to the main branch by doing a compare of branches and retrieving all changes.
For most stores, adding new code continuously is probably a bit overkill, but it is a good idea to update for each release, so that your code base does not diverge too much from the latest theme version. You can subscribe to releases on Github.
Customization should, in most cases, only be done when the theme does not support functionality out of the box. A custom collapsible tab is not needed when the theme supports it.
When you add new functionality, you should try to add it in a way that reduces the risk of conflicts and makes it easier to change and understand the code in the future. Some tips to achieve this:
1. Add custom css to a separate css file and import it to theme.liquid
2. For each customization, add a comment explaining why the code was added, for example to support
3. A convention with prefixes by company name is pretty standard in the industry to avoid conflicts, for example famme-image-banner-with-X.liquid if you make a new type of image banner for some reason
4. Change the code via github / code editor so you can add useful commit messages
5. Do regular checks against the uncustomized theme, if there are unused customization code, remove it. For example Dawn just added a setting for space between sections which made a custom space section we made unnecessary, that sections is probably best to just remove to reduce clutter.