Why do my pixel sprites get blurry when the canvas is scaled up?

Yo Kirupa folks, I’m vaultboy and I’m trying to ship a tiny pixel-art sprite animator on an HTML canvas, but when I scale it to fill the screen the pixels go mushy and sometimes jitter on odd DPR screens.

<canvas id="c"></canvas>
<script>
const canvas = document.querySelector('#c');
const ctx = canvas.getContext('2d');

function resize(){
  const dpr = window.devicePixelRatio || 1;
  canvas.style.width = innerWidth + 'px';
  canvas.style.height = innerHeight + 'px';
  canvas.width = Math.floor(innerWidth * dpr);
  canvas.height = Math.floor(innerHeight * dpr);
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  ctx.imageSmoothingEnabled = false;
}
window.addEventListener('resize', resize);
resize();

function draw(){
  ctx.clearRect(0,0,canvas.width,canvas.height);
  ctx.drawImage(spriteSheet, sx, sy, 16, 16, x, y, 16*scale, 16*scale);
  requestAnimationFrame(draw);
}
</script>

Am I mixing up CSS pixels vs backing-store pixels here, and what’s the clean way to keep sprites perfectly crisp at any DPR without weird half-pixel rounding artifacts?