Basefox · Illustration library · 26 Aug 2026
84 objects extracted from your seven sheets, keyed to single ink, and rendering in the app. The drawings are good; three things about the delivery needed handling before they could be used.
| Delivered | Needed | What I did |
|---|---|---|
| 7 contact sheets, 12 objects per sheet in labelled cells | Individual asset files | Cut all 84 cells, trimmed each to its ink |
| Accent disc and topo baked behind every object | Object only — the app draws the accent | Keyed both out, so the card's own colour applies |
| Flattened raster PNG | Vector PDF | Using the raster now; drop-in replaceable later |
All 84, extracted and keyed. No labels, no number badges, no accent discs, no topo — just single-ink line art on transparency.
Dropping the accent discs by saturation worked for the orange and sage ones. The
blue-grey disc measures #A4ADAF — saturation 11, which is lower than
some of the ink. Keying it by colour was never going to work. It separates on brightness
instead: luminance 171, against strokes that sit below 100. First pass left grey blobs
behind the backpack, cooler, and suitcase; the brightness rule cleared them.
I first padded each object to a square, per the drawing spec. The sofa's ink is
245 × 130 in a 284 × 284 canvas, and scaledToFit fits the canvas, not
the drawing — so in a 174 × 140 band the sofa rendered about 45pt tall with empty space
around it. Every object now keeps its own aspect with a 10% margin, and a wide object fills
the band. This is why the first render looked like tiny drawings floating in big cards.
Files are illus-sofa, illus-tent, illus-jacket —
named for what they are. categories.yaml and events.yaml point at
whichever object they want, which is what makes the objects composable: one drawing can serve
several cards, and swapping a category's cue is a one-line registry edit.
| Category | Object | Event | Object |
|---|---|---|---|
| Footwear | illus-sneaker | AAFES Labor Day Home Sale | illus-sofa |
| Running | illus-running-shoe | NEX Fall Apparel Event | illus-jacket |
| Apparel | illus-t-shirt | NEX Back to School | illus-school-supplies |
| Outdoor | illus-tent | The other 74 objects are stock. The sync counts them and no longer flags them as orphans, because a library being larger than the set in use is the point. | |
| Workwear | illus-work-boot | ||
| Accessories | illus-sunglasses | ||
| Travel | illus-airplane | ||
Browse tiles now use the same drawings the cards do, so a tile and a card visual are one mark.
The extracted objects are 200–340px on their long edge. A hero card wants roughly 520px at 3x, so these run about 1x–1.5x there. They read correctly at every density and look soft on the largest one — visible in the sofa's edges above if you look closely.
Re-exporting the same drawings as PDF from their vector masters is a genuine drop-in:
same names, same directory, and assets sync already prefers whatever is present.
Nothing in the app changes. The sheets say “Scalable SVG”, so the masters likely
exist.
The camp lantern had an orange flame drawn as part of the object rather than as background. The colour key removed it along with the discs, so that one object is now an empty lantern. It is not referenced by anything, and a vector re-export would fix it.
test_dry_run_reports_missing_without_writing and
test_coverage_reads_as_a_fraction both asserted “no asset files ship
yet”. That stopped being true, which is the good kind of failure. They now assert the
invariant rather than the state: a dry run writes nothing, coverage adds up, every referenced
illustration has a file, and only brand lockups remain outstanding.