Add clade silhouettes, compact navigation tabs, and drop the hover underline
Follows #2, which added the English names. This adds the silhouettes that were only a backlog note there, and two interface fixes.
Silhouettes
Every group now carries a PhyloPic outline beside its name, so Porifera reads as a vase sponge and Choanoflagellata shows its collar and flagellum. refresh_icons.py resolves each taxon's NCBI id to a PhyloPic node and stores the SVG unmodified under data/icons/, with the map and credits in data/icons.json. Gradio serves them as static files, so each is cached once by the browser rather than riding along in every re-render.
Licensing is settled at build time rather than argued about later. Both the representative-image lookup and the clade fallback exclude NonCommercial and ShareAlike: NC is unsettled for a Space run by a company, and SA would reach into this repository the moment an icon were adapted. What ships is CC0, Public Domain Mark and CC BY, every CC BY artist is credited in a new "Silhouette credits" panel, and the build fails if anything else slips through.
Three things only showed up by looking at the rendered chart:
- Taking any image from the clade gave Fungi a chytrid zoospore. The node's own representative image is the right default.
- Silhouettes run from 0.20 to 9.48 in aspect ratio, so a single square box turned most of them into slivers. Preferring square images instead made Metazoa a spiky blob and four protist groups identical, so the fix is to stop forcing a square: each icon gets its own box, equal area, its own proportions.
- Groups under the size threshold borrowed an ancestor's outline, which made Ichthyosporea, Filasterea, Choanoflagellata and Rotosphaerida look identical on the opening screen. The first five columns now get their own icons whatever their size, and a borrowed outline that would repeat within a column is dropped instead of drawn.
Navigation
The Genome Atlas / Database tabs were two 62-point bars spanning the page. They are now ordinary tabs on the left with an underline on the active one.
Hover
The label underline is gone; hover reads on the label colour and the bar outline alone.
Tests
Thirteen pass. New coverage for the licence filter, icon presence, ancestor inheritance, and that borrowed icons never repeat within a column. One guards the viewBox: while writing the icon sizing I named a local width inside the node loop, which shadowed the SVG's own width and shrank the viewBox to 23x23. The chart rendered completely blank and every existing test still passed, because all the elements were present in the markup.
🤖 Generated with Claude Code