import InfoBox from '../components/InfoBox.astro'

The review's sixth pick was `screenshot.ts`, 626 lines with no tests of its own, drawing [the daily and duel share images](/posts/the-image-that-repaints-itself) and the board underneath both of them, board geometry and snake colors sitting in the same file as panel layout and podium rank lines. The plan going in looked clean: pull the board-drawing primitives into their own module, then a thin composer each for the daily image and the duel image, three pieces for what was clearly three concerns.

Actually drawing that boundary turned up a fourth concern the plan hadn't named: a chunk of the file that both composers needed equally, and that wasn't board geometry or specific to either mode. Shoving it into `board.ts` would have mixed drawing primitives with infrastructure that has nothing to do with geometry, and duplicating it into both composers would have recreated the exact kind of drift the split was supposed to end.

<InfoBox title="What had nowhere to go">
  Canvas context setup sized for PNG export, background and divider drawing, text
  truncation, the shared fonts, and the snake color palette both composers read
  from when they draw a player or opponent snake. None of it is board geometry;
  none of it belongs to only daily or only duel.
</InfoBox>

The boundary that actually shipped added a fourth module for exactly that shared infrastructure, settled through a plain conversation rather than another multi-candidate design round, since by the time the question was concrete there was really only one place each piece of code could go. `screenshot.ts` came apart into board-drawing primitives, a new module holding that shared share-image plumbing, and one composer each for daily and duel.

The old file was deleted outright rather than left behind as a re-export, [the same call the engine split had already made a day earlier](/posts/verbatim-not-cleaned-up). The 433 lines of tests that used to cover the whole file split one-to-one with the four new modules, and both recap components repointed straight to their new imports with nothing standing in between.