This was generated by AI during triage. Body rewritten on contact: the family half shipped, and the colour half turned out to be 34 literals rather than the one this ticket described.
Found while sweeping #380.
Done — the family, in #431
roasty_particles.dart spelled fontFamily: 'Fraunces' instead of reading it from the ladder. Correct only until the pubspec renames the family, at which point it silently falls back to the platform font — the failure the families guard already existed to catch, arriving one step later.
It now reads AppFace.display.family and that face's weight, the split grinder_dial_view.dart already makes: face from the ladder, size from the drawing. font_families_test.dart carries the stronger rule — no file outside the ladder may spell a family at all, so this cannot come back by another hand.
Done — the palette, in #510
The original finding said the particle ink was a bare literal that belonged in the OffTokens register. That was true but badly scoped: it was one of 37 Color(0x…) literals across the three companion painters, none registered, none a token, none documented as an exception.
RoastyColors (lib/shared/theme/roasty_colors.dart) now holds them, the shape ArtColors set: an abstract final class of static const colours with no of(context) accessor. The ten named tokens are transcribed from the /* Roasty palette */ block of prototype/Mascot - Roasty.html; the five the drawings use unnamed (highlight, glow, three confetti) are pinned to their literals in prototype/roasty.jsx.
Not every colour Roasty draws with belongs there. roasty.jsx — the component the app screens render, in both moods — gives the module stars and rays and two of the four sparkles to --warn, the wrong badge to --berry, and the sleeping zs to --ink-mute. Pinning those to Cupping's values in a "mood-independent" holder would have been wrong by construction, and it was already a visible bug: in Dark Roast the zs were #6B5F54 on #1A130E. The Roasty widget now hands context.mood to its painter, and those marks read it.
Acceptance criteria
Left open
The painters stay on the no-magic-number exclusion list: it is per-file, and their coordinates still need it. The entry now says so, and the guard above is what keeps a colour from hiding under it. The faces' geometry gaps found on the way are #506.
Found while sweeping #380.
Done — the family, in #431
roasty_particles.dartspelledfontFamily: 'Fraunces'instead of reading it from the ladder. Correct only until the pubspec renames the family, at which point it silently falls back to the platform font — the failure the families guard already existed to catch, arriving one step later.It now reads
AppFace.display.familyand that face's weight, the splitgrinder_dial_view.dartalready makes: face from the ladder, size from the drawing.font_families_test.dartcarries the stronger rule — no file outside the ladder may spell a family at all, so this cannot come back by another hand.Done — the palette, in #510
The original finding said the particle ink was a bare literal that belonged in the
OffTokensregister. That was true but badly scoped: it was one of 37Color(0x…)literals across the three companion painters, none registered, none a token, none documented as an exception.RoastyColors(lib/shared/theme/roasty_colors.dart) now holds them, the shapeArtColorsset: anabstract final classofstatic constcolours with noof(context)accessor. The ten named tokens are transcribed from the/* Roasty palette */block ofprototype/Mascot - Roasty.html; the five the drawings use unnamed (highlight, glow, three confetti) are pinned to their literals inprototype/roasty.jsx.Not every colour Roasty draws with belongs there.
roasty.jsx— the component the app screens render, in both moods — gives the module stars and rays and two of the four sparkles to--warn, the wrong badge to--berry, and the sleepingzs to--ink-mute. Pinning those to Cupping's values in a "mood-independent" holder would have been wrong by construction, and it was already a visible bug: in Dark Roast thezs were#6B5F54on#1A130E. TheRoastywidget now handscontext.moodto its painter, and those marks read it.Acceptance criteria
AppFacerather than a string literal —font_families_test.dartroasty_colors_test.dartfails anyColor(0x…)underlib/features/companionunthemed_constants_guard_test.dartlists it;roasty_colors_test.dartreads the palette block and the component's literalsflutter analyze, metrics gate, tests clean — run locally on Roasty's palette gets a home, and its mood marks follow the mood #510Left open
The painters stay on the
no-magic-numberexclusion list: it is per-file, and their coordinates still need it. The entry now says so, and the guard above is what keeps a colour from hiding under it. The faces' geometry gaps found on the way are #506.