One way I've seen this enforced is this: Have your "best" devs, the people who put out 2x the amount of solid, testable, well documented code as anyone else, you know those that carry the sprint, spend half their time reviewing. Your overall sprint velocity may go down a bit, but your code quality will go up.
There's a magic to slowing things down, too - require reviews on every change, require tests to run and pass, run UI tests on each PR. Let people discuss good and bad code they see. Turn every little thing people mention, (like "man, this view is difficult to reason about", "the entire xyz class is a mess", "does anyone know why we do X here?") into a Refactor issue, discuss it, plan it, do it. You can do this during a big feature sprint, you dont need to wait until your product is done (then its too late).
Refactor, let people say "yes this issue isnt high prio, but its important to me". Embrace when people want to make code better.
There's a magic to slowing things down, too - require reviews on every change, require tests to run and pass, run UI tests on each PR. Let people discuss good and bad code they see. Turn every little thing people mention, (like "man, this view is difficult to reason about", "the entire xyz class is a mess", "does anyone know why we do X here?") into a Refactor issue, discuss it, plan it, do it. You can do this during a big feature sprint, you dont need to wait until your product is done (then its too late).
Refactor, let people say "yes this issue isnt high prio, but its important to me". Embrace when people want to make code better.