paste-lines.js joined .codeline spans with '\n' text nodes that pre-wrap renders as extra line boxes, and renumber() counted per-line span heights (rounding) instead of real geometry, so gutter numbers drifted off their line starts on wrapped lines. Fix: join spans with '' (blocks need no newline text), and build one .gutline per visual row measured from the code body's real height, placing each number at the visual row whose top matches its .codeline's measured top. Wrap OFF path unchanged. Mobile font-size rule added so gutter row pitch matches code rows at 375x812.