How is the storage layout when inheriting contracts?

There is a passing mention on the docs, in the section about modifying your contracts and not changing the storage layout that says:

"You also cannot add new variables to base contracts, if the child has any variables of its own"

Does that mean that the first storage slot is assigned to the first variable of the first base contract, when the first contract has been assigned slots for all its variables, then the second, all the way to the last base contract, AND THEN, is your contract's turn. Is that correct?

Then, does that means that adding a new base contract would overwrite all the variables of the variables of your contract?

So, as long as your contract doesn't have any variables of its own, should that be safe? Could i extend my deployed ERC20 contract, and add the pausable contract?

Yes, those are correct. Here's an example of extending a contract, similar to your last suggestion: New storage layout is incompatible: ContextUpgradeable.sol:36: Inserted `__gap` - #3 by frangio

Great! Thanks for the response.

If i can make the suggestion, add that information to the documentation, so new users doesn't limit their future upgradeability prospects early in.

Maybe an addition to the Writing Upgradeable Contracts metioning how you can avoid limiting the future upgradeability of your contract, by adding gaps (unused variables) to any inherited contract, as oz contracts do, and by not having any storage variable in the main contract.

Also, the solution of your linked post of moving the variables of the original contract to an inherited one so they aren't pushed further down the storage slots is a nice workarround, that should certainly be included in the docs.