.nornir/assets/why-leaf.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 300" font-family="-apple-system,Segoe UI,Roboto,sans-serif" font-size="14">
<defs>
<marker id="wl" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">
<path d="M0,0 L7,3 L0,6 Z" fill="#555"/>
</marker>
</defs>
<text x="410" y="28" text-anchor="middle" font-size="16" font-weight="bold" fill="#1a1a1a">Why a leaf repo — break the release-cascade cycle</text>
<!-- katana-osm origin -->
<rect x="320" y="55" width="180" height="50" rx="10" fill="#f2f2f2" stroke="#888" stroke-width="1.5"/>
<text x="410" y="85" text-anchor="middle" font-size="13" fill="#555">katana-osm (origin)</text>
<!-- extracted -->
<rect x="300" y="140" width="220" height="60" rx="10" fill="#e7f0ff" stroke="#2b5fb3" stroke-width="2"/>
<text x="410" y="167" text-anchor="middle" font-weight="bold" fill="#1a3a6b">znippy-zoomies</text>
<text x="410" y="186" text-anchor="middle" font-size="12" fill="#33507a">the shared primitives, one leaf</text>
<line x1="410" y1="105" x2="410" y2="140" stroke="#555" stroke-width="1.5" marker-end="url(#wl)"/>
<text x="470" y="128" font-size="11" fill="#777">extract</text>
<!-- consumers -->
<rect x="120" y="235" width="180" height="50" rx="10" fill="#eef7ee" stroke="#2f8f46" stroke-width="1.5"/>
<text x="210" y="265" text-anchor="middle" font-size="13" fill="#245c30">skade (stree / gatling)</text>
<rect x="520" y="235" width="180" height="50" rx="10" fill="#fff6e6" stroke="#c8891f" stroke-width="1.5"/>
<text x="610" y="265" text-anchor="middle" font-size="13" fill="#7a5410">znippy (codecs / gatling)</text>
<line x1="360" y1="200" x2="210" y2="235" stroke="#555" stroke-width="1.5" marker-end="url(#wl)"/>
<line x1="460" y1="200" x2="610" y2="235" stroke="#555" stroke-width="1.5" marker-end="url(#wl)"/>
<text x="410" y="298" text-anchor="middle" font-size="12" fill="#666">both depend on it without either depending on the other — no cascade, no rayon</text>
</svg>