For transactions with no brand match, show the spending category emoji
(Twitter Twemoji SVG via jsDelivr) instead of a bare initial:
Groceries 🛒 Food 🍔 Fuel ⛽ Health 💊 Subscriptions 💻
Shopping 🛍 Utilities 💡 Cash 🏧 Debt 💳 Wallets 📱 Fees 🏦
Income/transfer rows use flow-type icons (💰 income, 🔁 self-transfer).
Resolution chain: Brandfetch brand logo -> category Twemoji -> coloured
initial. Brand logo onerror also falls back to the category emoji.
Call sites pass {category} (merchants/breakdown) or {flowType} (ledger).
- web/logos.js: high-precision alias map (description regex -> brand domain)
feeding the Brandfetch logo CDN; only attaches a logo when a merchant
confidently maps to a known brand, else a coloured-initial fallback.
- Logos rendered in: top-merchants list, category breakdown rows, ledger.
- scripts/resolve-logos.mjs: offline resolver (alias + Brandfetch search) that
measures coverage and writes merchant-logos.json. Current: 33 brands cover
~35% of expense txns (Uber, MercadoPago, Apple, Rappi, Santa Isabel, Copec,
etc.); the long tail is local businesses with no brand -> fallback.
- Client ID is public (CDN); no secret key in the repo.
Remove cleanDesc() stripping in breakdown accordion, top merchants,
tooltip rows, and Ledger table — descriptions now show verbatim as they
appear in the source PDF so any transaction can be cross-referenced.