I used to think about server and client boundaries as an architectural decision that needed to be made up front. In practice, I have found it easier to start from the data dependency and move outward.
Keep server state boring
Data that comes from a database, an API, or an authenticated session usually wants to stay close to the server. Fetch it where it is easiest to authorize, cache, and invalidate.
Keep interaction state local
A search box, open popover, selected tab, or drag state rarely deserves a global store. If the state exists to make one interaction feel good, keep it near the interaction.
The boundary should follow ownership, not fashion.
Move a boundary when the user experience requires it
There are plenty of legitimate reasons to move work to the client: instant feedback, rich interactions, streaming, or browser-only APIs. The key is knowing what you gained by crossing the boundary.
I try to make the smallest possible part interactive. That tends to keep server-rendered content simple while preserving a good experience where it matters.