feat: adopt the rebalanced mark and add a wordmark lockup

The shipped mark failed the one size it most needed to survive. At 16px
in a browser tab its outer strokes rasterised away entirely and the
2.5px gap between stroke and node filled in, so the favicon rendered as
an indeterminate horizontal smear rather than as anything. Three changes
fix it, all driven by that case and verified by rendering rather than by
reasoning: strokes stop at x=30 so the gap survives, outer opacity goes
.45/.55 -> .7 so the neighbours stay visible, and the node grows to
r=8.5 so it still reads as a disc.

This is not a rebrand. The mark is the same three-signals-converging
figure and keeps whatever recognition it has earned; only its
proportions changed. icon.svg and logo.svg had drifted slightly apart
(different node radii and stroke ends) and are now geometrically
identical, differing only in palette.

Adds the lockup, which had no asset at all, in two variants because one
cannot serve both jobs: public/lockup.svg uses currentColor for in-app
use, and docs/assets/lockup.svg fixes the colour to #0092fd for the
README. An <img src> reference resolves currentColor to black, so the
currentColor variant would be invisible against a dark README. The
wordmark carries textLength, without which it overruns the viewBox on
wider monospace fonts.

Concepts and the reasoning behind the ones not chosen are on the
docs/logo-concepts branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 14:09:56 -07:00
co-authored by Claude Opus 5
parent 80341c558d
commit 5d06095883
5 changed files with 72 additions and 11 deletions
+13 -5
View File
@@ -3,12 +3,20 @@
<!--
Transparent, currentColor variant of the mark for in-app use - inherits
the surrounding text color so it works on any surface. The tile version
used as the favicon lives at app/icon.svg.
used as the favicon lives at app/icon.svg, and the horizontal lockup at
public/lockup.svg.
Three retrieval signals converging on a single memory. Proportions are
set by the 16px case, which is the one that breaks: the strokes stop at
x=30 so the gap to the node survives rasterisation, the outer pair sits
at .7 rather than .45 so it doesn't drop out, and the node is r=8.5.
The earlier proportions rendered as an indeterminate smear in a browser
tab.
-->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="7">
<path d="M13 15C25 15 27 32 37 32" opacity=".45"/>
<path d="M13 32H37"/>
<path d="M13 49C25 49 27 32 37 32" opacity=".7"/>
<path d="M12 16C24 16 25 32 30 32" opacity=".7"/>
<path d="M12 32H30"/>
<path d="M12 48C24 48 25 32 30 32" opacity=".7"/>
</g>
<circle cx="43" cy="32" r="8" fill="currentColor"/>
<circle cx="46" cy="32" r="8.5" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 1.1 KiB