Build image / build-and-push (push) Successful in 8s
Correctness: - PlantFormModal: validate days-to-maturity with Number() so "1.5" is rejected rather than silently truncated to 1 (parseInt). Accurate "at least 1 <unit>" spacing message; spacing input min now matches validation. Drop the icon maxLength that could split a multi-codepoint emoji (server caps at 32 bytes). - PlantPicker: namespace row keys (recent- / all-) so a plant shown in both the Recent and All sections no longer collides on a duplicate React key. Dedupe (the review's dominant, multi-model theme) — also sets up #15's reuse: - lib/plants.ts: shared CategoryFilter type + filterPlants() helper. - components/plants/CategoryChips.tsx and PlantIcon.tsx: extracted the chip row and the color-mix icon tile, now used by both the /plants page and PlantPicker (and PlantCard for the tile). Skipped (cosmetic/cross-file, low agreement): conflictPlant→generic helper, PlantCard vs GardenCard button-class dup, form component length, and localStorage user-scoping (recent custom-plant ids don't resolve cross-user anyway). tsc --noEmit clean; 20/20 vitest; production build green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi