Dev note · the card is rendered, not screenshotted
Draw the card off-screen and export a PNG (device pixel ratio ≥ 3) — never a screenshot of the completion surface, which would carry the status bar, the skip control and whatever beat happened to be on screen. Inputs are all in LessonSummary today: lessonScorePercent, scoredCount/scoreEligibleCount, partsCleared/partsScored, spokenCount, objective, said[].hanzi. The formatter is one function shared with the completion screens, so a number can never be phrased two ways: same rounding (truncate), same "n/m" wording, same null handling. The goal-completion variant swaps the words for the can-do sentence and the medallion, and carries 5/5 steps in place of the percent.