docs: draft ten logo concepts #23

Merged
jknapp merged 1 commits from docs/logo-concepts into main 2026-08-13 01:46:26 +00:00
11 changed files with 265 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
# Logo concepts
**Status:** exploration, nothing adopted
**Drafted:** 2026-08-12
Ten directions for the `shared-memory` mark. Eight are fresh concepts, two are
refinements of the mark currently shipping in `apps/web/public/logo.svg` and
`apps/web/app/icon.svg`.
Every concept is drafted as a real SVG in `docs/logo-concepts/`, authored the
same way the shipped mark is: a 64×64 viewBox, `currentColor` so it inherits the
surrounding text colour, round caps, and opacity rather than a second hue for
depth. That means any of them can be dropped straight into the app, and the tile
(favicon) variant is a mechanical derivation — wrap it in the rounded `#11151b`
rect and substitute the accent blues.
## How these were judged
A mark for this project has to survive three places: the browser tab at 16px,
the app header at 3264px, and a README at whatever size GitHub renders. Small
size is the brutal filter — it is where most of the concepts below die, and it
is where the *currently shipped* mark is weakest, which is the single most
useful finding here.
Each was rendered at 120px, 24px and 16px and looked at, not just reasoned
about. The failures noted below are observed, not predicted.
---
## The concepts
### 01 · Venn core
Two outlined circles; the lens where they overlap is filled solid. The overlap
*is* the shared memory.
The most literal, most immediately-readable statement of "shared" in the set —
nobody needs it explained. That is also the problem: Venn diagrams are visual
public domain, and this would not be ownable. At 16px the two outlines fuse into
a single blob with a bright centre, which is legible but says nothing.
### 02 · Handoff
Two brackets facing each other around a single node — one session passing a
memory to the next.
Calm and symmetric, and the metaphor is exactly right for what the MCP does
across sessions. It reads as `( • )`, which unfortunately is also how a hundred
focus / aperture / eye icons read. Holds together at 16px better than 01.
### 03 · Braid
Two threads woven through each other with real over/under crossings, neither
subordinate to the other.
The most distinctive mark here by a wide margin, and the only one that looks
*crafted* rather than assembled from primitives. It also has the cleanest
meaning: two agents, one durable strand, and the weave is what makes it hold.
**It fails as a favicon.** At 16px the crossings collapse and it becomes an
unreadable smudge. This is not fixable by thickening strokes — the weave needs
the crossings to be visible, and they need room. Use it as a hero graphic or a
wordmark companion, not as the app icon.
### 04 · Return arc
An open ring with a solid node inside it: write it down, leave, come back to it.
The gap in the ring is where the next session enters.
The best small-size performer of the fresh concepts — completely legible at
16px, and the interior node keeps it from being just a shape. The risk is
literal: at small sizes it reads as a **©**. Worth checking against that
association before committing.
### 05 · Anchor
One fixed point that three separate agents reference from wherever they are.
Clean, balanced, and conceptually accurate — the memory is the fixed thing and
the clients are transient. But a three-spoke hub at this weight lands very close
to the Mercedes-Benz mark, and adjacent to the peace symbol. Both would come up
in any trademark review. Included for completeness; hard to recommend.
### 06 · Spine
A vertical spine with entries branching off it, the active one reaching furthest
to a node. An index, a ledger.
The only rectilinear mark in the set, so it stands apart from the others
immediately. It is also the most honest about what the product actually is —
a queryable index, not an abstraction. The risk is that it reads as a bar chart,
which pushes the association toward analytics rather than memory.
### 07 · Knot
A single continuous thread with no start and no end.
Renders flawlessly at every size tested — genuinely the most legible mark here.
That is its only advantage. It is the infinity symbol, which means near-zero
ownability, and it says "endless", not "shared". Kept in the set as the
legibility baseline the others are measured against.
### 08 · Triad
Three nodes joined by edges, one lit brighter than the others: the smallest
possible shared graph, with one participant currently active.
The strongest *conceptual* fit after the braid — it shows plurality, connection,
and activity in one figure, and the lit node gives it somewhere to go for a
loading or live state. Degrades gracefully: at 16px the edges thin out but three
dots in a triangle still reads. The concern is category crowding — triangular
node graphs are the default visual language of network and blockchain branding.
### 09 · Current mark, rebalanced
The shipped mark with three targeted changes, all aimed at 16px:
| | Shipped | Rebalanced |
|---|---|---|
| Converging strokes end at | `x=35` (2.5px from the node) | `x=30` (4px clear) |
| Outer stroke opacity | `.45` / `.55` | `.7` |
| Node radius | `7.5` | `8.5` |
At 16px the shipped mark loses its outer strokes to rasterisation and the
remaining gap between stroke and node fills in, so it renders as an
indeterminate horizontal smear. The rebalanced version resolves as an arrow
meeting a node at the same size.
This is the lowest-risk option on the table: it is not a rebrand, it keeps
whatever recognition the current mark has already earned, and it fixes a real
defect. It is worth doing *regardless* of what happens with the eight concepts
above.
### 10 · Lockup
Not an alternative mark — the missing asset. The rebalanced mark set against the
wordmark in the project's monospace stack, on a shared baseline, with the hyphen
dropped to 45% so `shared` and `memory` read as two things joined.
For README headers, the docs site, and the OAuth consent screen, where a bare
64px glyph is too little and the full app header is too much.
---
## Recommendation
Three separate decisions, not one:
1. **Ship 09 now.** The small-size failure of the current mark is a real defect
and the fix is a five-line diff. It does not depend on choosing a new
direction.
2. **Adopt 10** for the README and docs headers, using whichever mark wins.
3. **If a genuine replacement is wanted**, the shortlist is **08 Triad** (best
concept-to-legibility ratio) and **04 Return arc** (best legibility, pending
the © check). **03 Braid** is the most beautiful and should be used
*somewhere* — as a hero graphic — but cannot be the icon.
Concepts 01, 05 and 07 are documented here so the reasoning against them is on
record, not because they are live candidates.
+9
View File
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Venn core">
<title>Venn core</title>
<!-- Two participants; the filled lens is the memory they hold in common. -->
<g fill="none" stroke="currentColor" stroke-width="5" opacity=".5">
<circle cx="24" cy="32" r="15"/>
<circle cx="40" cy="32" r="15"/>
</g>
<path d="M32 19.31A15 15 0 0 1 32 44.69 15 15 0 0 1 32 19.31Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 470 B

+9
View File
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Handoff">
<title>Handoff</title>
<!-- Two sessions facing each other, passing one memory between them. -->
<g fill="none" stroke="currentColor" stroke-width="6.5" stroke-linecap="round" opacity=".65">
<path d="M26 16Q10 32 26 48"/>
<path d="M38 16Q54 32 38 48"/>
</g>
<circle cx="32" cy="32" r="7" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 451 B

+16
View File
@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Braid">
<title>Braid</title>
<!--
Two independent threads woven into one strand - neither is subordinate,
and the weave is what holds. Crossings computed at (20,32) and (44,32);
the mask punches the first one so strand A reads as passing over it.
-->
<mask id="sm-braid-gap">
<rect width="64" height="64" fill="#fff"/>
<circle cx="20" cy="32" r="6.25" fill="#000"/>
</mask>
<g fill="none" stroke="currentColor" stroke-width="6.5" stroke-linecap="round">
<path d="M8 20C20 20 20 44 32 44 44 44 44 20 56 20" opacity=".75"/>
<path d="M8 44C20 44 20 20 32 20 44 20 44 44 56 44" mask="url(#sm-braid-gap)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 762 B

+7
View File
@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Return arc">
<title>Return arc</title>
<!-- Write, leave, come back to it. The gap is where the next session enters. -->
<path d="M42.3 46.7A18 18 0 1 1 42.3 17.3" fill="none" stroke="currentColor"
stroke-width="6.5" stroke-linecap="round" opacity=".7"/>
<circle cx="30" cy="32" r="7.5" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 438 B

+10
View File
@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Anchor">
<title>Anchor</title>
<!-- One fixed point that separate agents reference from wherever they are. -->
<g fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="round" opacity=".6">
<path d="M32 8V20"/>
<path d="M11.2 44L21.6 38"/>
<path d="M52.8 44L42.4 38"/>
</g>
<circle cx="32" cy="32" r="8.5" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 475 B

+11
View File
@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Spine">
<title>Spine</title>
<!-- An index: many entries on one shared spine, the active one reaching furthest. -->
<g fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="round">
<path d="M16 13V51"/>
<path d="M16 21H34" opacity=".5"/>
<path d="M16 32H42"/>
<path d="M16 43H34" opacity=".5"/>
</g>
<circle cx="52" cy="32" r="5" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 504 B

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Knot">
<title>Knot</title>
<!-- One continuous thread with no start and no end; it persists past any session. -->
<path d="M32 32C38 20 50 20 50 32 50 44 38 44 32 32 26 20 14 20 14 32 14 44 26 44 32 32Z"
fill="none" stroke="currentColor" stroke-width="6.5" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 410 B

+11
View File
@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Triad">
<title>Triad</title>
<!-- The smallest possible shared graph: three peers, one currently speaking. -->
<path d="M32 16L17 44H47Z" fill="none" stroke="currentColor" stroke-width="5"
stroke-linejoin="round" opacity=".4"/>
<g fill="currentColor">
<circle cx="32" cy="16" r="7"/>
<circle cx="17" cy="44" r="7" opacity=".55"/>
<circle cx="47" cy="44" r="7" opacity=".55"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 524 B

+14
View File
@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Current mark, rebalanced">
<title>Current mark, rebalanced</title>
<!--
The shipped mark with three changes aimed at 16px: strokes stop earlier so
the gap to the node survives rasterisation, outer opacity raised .45 -> .7
so the neighbours don't drop out, node enlarged 7.5 -> 8.5.
-->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="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="46" cy="32" r="8.5" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 694 B

+13
View File
@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 292 64" width="292" height="64" role="img" aria-label="shared-memory">
<title>shared-memory lockup</title>
<!-- Horizontal lockup: rebalanced mark + monospace wordmark on a shared baseline. -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="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="46" cy="32" r="8.5" fill="currentColor"/>
<text x="72" y="41" fill="currentColor"
font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
font-size="26" letter-spacing="-0.8">shared<tspan opacity=".45">-</tspan>memory</text>
</svg>

After

Width:  |  Height:  |  Size: 751 B