I consider shit code, assuming it works, to be hard to read and hard to build. If I have to read every line of a function/method to figure out what it does, it probably means the name of the function/method is inadequate at explaining it. If I have to build something that only works on a certain operating system, or has dependencies that only work on computers with specific local files, it's shitty code.
Premature optimization also makes for shitty code. One code snippet I remember used custom bitwise logic for multiplication. It was both a wasted effort (because of compiler optimizations), and made the code unnecessarily complex for newer junior devs on the team to understand.
Cleverness is fine imo, as long as the clever implementation is behind a good interface that can be swapped out easily if problems arise. I would prefer to start off with a well-abstracted dumb implementation and swap it for a clever one afterwards so that the commit history can be called upon for easy file reverts.