I think that words like "clean code" or "beautiful code" does help juniors to learn best practices of software architecture.
- Junior asks to senior: what did you we use an ORM ?
- senior answers: because it's cleaner.
- junior: ???
I prefer when people are able to define a clear list of objectives:
- maintenable;
- performant, scalable;
- efficient;
- resilient;
- observable;
- testable (and tested);
- secured;
- readable for new devs that come on board.
Each criteria balance the others, and the more we add criteria the more it helps to make good choice when we hesitate. It is also meaningful for people outside of the dev team, we can reach an agreement with the customer so he knows what he pays for.
"maintenable" can be also defined, since a project is mostly in maintenance mode during its lifetime (which means the project is successful, which is good !). The ability to incorporate new features without breaking architecture or even without breaking a single method signature is a good starting point.
Being super careful with abstractions. Here someone wrote something like that: "abstraction often hides how what you want is simple". True, ORM I am looking at you. In most case data should be threaten as first class citizen, it also fosters good collaboration with the DBA.
Thinking beyond "the happy path" without falling in premature optimization is also a challenge. A nice one, once again to it avoids to go head first in implementing a good idea without considering drawbacks.
I also tend to imagine that the one that will work on my code had a very bad day so it must be pleasant to read what I wrote. Comments here and there, locale variable here and there even if they can be avoided, variable naming, etc...
Being selective about frameworks. They are good servant but bad leaders. "Be an engineer, not a frameworker" says an article.