However, a lot (perhaps most) code is more about integrating disparate components (browsers, lots of different kinds of external APIs, databases, times, distributed task processors, etc.) rather than lots of complex logic and for that kind of code, unit tests are substantially less effective and more horrible to use whereas integration tests really shine.
I think ideally, you should keep the two kinds of code strongly segregated, with clean APIs between them, so you can easily use the appropriate kind of testing for either one.
I don't agree that a good code base necessarily has both types. A web app with relatively shallow logic and lots of integrations only really benefits from having integration tests. A library to convert human readable strings into dates likewise gains nothing from having integration tests.
Similarly, a messy spaghetti codebase with a disgusting mix of both types of code can only really benefit from integration testing until it's substantially refactored and the two types of code are segregated.
Why _strongly_ segregated?
Nothing stops you to write unit tests for the methods that should be covered by unit tests and integration tests for the functionality that needs to be covered by integration tests.
How would code segregation help?
That test will also often break as you refactor the various connecting APIs it surrounds.
Tests that break in the presence of changed API contracts (as opposed to bugs) are vastly less valuable than tests which only go red in the presence of a bug.
Unit tests cannot catch everything though, and for stuff like how multiple units are wired together, that's where integration tests come into play.
A good codebase has both types - even combined they won't catch everything, but they should capture almost all business logic issues.