A classic theme can add theme.json without becoming a block theme, which is the migration path for an existing site.
theme/ # still a classic theme
index.php
single.php
functions.php
theme.json # ← the only addition
# what it gains: the editor settings, global styles, the
# generated custom properties.
# what it does not: templates/, parts/, the site editor.
# adding templates/index.html is what flips it.
The flip is abrupt: creating templates/index.html makes WordPress treat the theme as a block theme and stop consulting the PHP hierarchy, so there is no gradual middle. Template parts can be added to a classic theme separately with block_template_part(), which gives a partial migration and is the arrangement that actually works on a large site.