Left draws three marks it does not own. This file is the record of where they came from, what we checked, and what we are relying on to use them. If you are refreshing an asset, read this first and update it in the same commit.
Until 2026-07-28 the app drew a cloud for Claude and a hexagonal ring for GPT — shapes invented here on the reasoning that we had no licence to redraw a trademark. The captain rejected them, and was right to: a status item exists to be recognised without reading, and an interpretation of a logo is recognised as nothing. Worse, the cloud was not merely unofficial but actively misleading — it is nobody's Claude mark, and a user seeing it had no way to know which provider the number beside it belonged to.
The app now draws exactly what each vendor publishes, unaltered.
Claude and ChatGPT were retrieved on 2026-07-28, Grok on 2026-08-19,
over plain HTTPS reads of the vendors' own sites. No third-party icon
repository was used, and none may be: ProviderMarkProvenanceTests fails on
any origin that is not first-party.
| Claude | ChatGPT | Grok | |
|---|---|---|---|
| Vendor | Anthropic PBC | OpenAI OpCo, LLC | X.AI LLC |
| Source URL | https://claude.ai/favicon.svg |
https://chatgpt.com/cdn/assets/favicon-l4nq08hd.svg |
https://grok.com/images/favicon.svg |
| Corroborated against | https://assets-proxy.anthropic.com/claude-ai/v2/assets/v1/cd02a42d9-Vq_H3mgS.svg (the <link rel="icon"> claude.ai itself serves) |
the <link rel="icon" type="image/svg+xml"> on https://chatgpt.com/ |
the <link rel="icon" type="image/svg+xml"> on https://grok.com/ |
| Retrieved | 2026-07-28T12:06:07Z | 2026-07-28T12:06:07Z | 2026-08-19T22:39:59Z |
| Vendored as | Assets/provider-marks/claude-ai-favicon.svg |
Assets/provider-marks/chatgpt-com-favicon.svg |
Assets/provider-marks/grok-com-favicon.svg |
| Bytes | 2558 | 4258 | 9758 |
| sha256 | b150888bc7257af83e3b85d3c2be4294f88986026f8168f6c12fc1fde6697350 |
8f2de046d22cfecfe3917cf87ff1ce49a48d79956f6b18be3b37db29148a0aeb |
c3db0dfaf760b702b8490c6cbefe07fd8bfe00db43cae6a0acccf768f44d6179 |
viewBox |
0 0 248 248 |
0 0 180 180 |
0 0 512 512 |
| Declared fill | #D97757 |
#000 light / #fff dark, via the asset's own prefers-color-scheme block |
mark blades #FCFCFC on a #050505 plate |
Assets/provider-marks/PROVENANCE.json carries the same facts in machine-
readable form, including the sha256 of each d attribute, and is what the
tests read.
Three corroborations worth recording. Anthropic's published brand accent is
#d97757, which is the fill in the retrieved file — the asset is the real
mark, not a lookalike. claude.ai's favicon.svg and the <link rel=icon>
asset its own HTML references are byte-identical, so two independent first-party
paths agree on the same bytes. grok.com's HTML names
/images/favicon.svg as rel="icon" type="image/svg+xml", and that is the
file vendored here. xAI also publishes a brand-asset zip from
the brand guidelines; Cloudflare
blocked an unauthenticated fetch of the zip on this retrieval, so the live
first-party favicon is the source of record.
Retrieval used a read-only browser session (chrome-devtools-axi) for
chatgpt.com, whose edge refuses non-browser clients, and a plain curl for
claude.ai and grok.com. Nothing was authenticated and nothing was written.
Grok's favicon is a Figma plate, not a bare mark: a rounded square, two white
blades, and a masked hairline for the 512px icon. The compiled geometry is
those two unmasked #FCFCFC paths concatenated in document order — the
vendor's curves, without the plate. vendor-provider-marks.py records that
selection; it does not redraw the blades.
Assets/provider-marks/*.svg the retrieved bytes, unedited
-> scripts/vendor-provider-marks.py
-> Sources/LeftCore/ProviderMarkGeometry.swift the `d`, verbatim
-> Sources/LeftCore/SVGPath.swift parsed to a CGPath
-> Sources/LeftCore/ProviderMark.swift filled, never redrawn
Nothing in that chain is free to reinterpret a curve, and
ProviderMarkProvenanceTests holds every link:
- the vendored file still hashes to what was retrieved;
- the compiled
dstring equals the file'sdbyte for byte; - the mark actually drawn still matches a committed 32×32 fingerprint, so re-pointing the drawing code at something hand-made fails even if the constants are untouched;
- the retired symbols cannot return — the Claude mark must radiate into all four corners as a cloud cannot, and the GPT mark must cross ink three times from centre to edge as a single-band ring cannot.
To refresh an asset: replace the SVG with fresh first-party bytes, update
RETRIEVED_AT/SOURCES in scripts/vendor-provider-marks.py, rerun it, then
refresh the fingerprint by hand from the failing test. The manual fingerprint
step is deliberate — a changed fingerprint means the mark on screen changed, and
somebody should look at it before it ships.
Geometry is never adapted. Two rendering properties are:
- Size. Each mark is scaled to the requested height by its own ink bounds
rather than its
viewBox. The vendors pad their favicons differently for their own icon plates; matching those paddings would make one mark optically smaller than the others beside the same digits. Proportions are preserved — the published marks are square within one percent, andProviderMarkTestsasserts each rendered image matches its artwork's aspect ratio. - Colour, in the menu bar only. macOS status items must be template images:
the system inverts them for light menu bars and click highlight, and an image
that opts out of that is simply broken in half the menu bars it appears in.
So in the menu bar each mark is a monochrome silhouette of the official
geometry. In the overlay there is no such constraint, so each mark is drawn
in its vendor's own colour — Anthropic's
#D97757, the#fffthat chatgpt.com's favicon itself specifies for a dark background, and the#FCFCFCgrok.com fills the blades with on its dark plate. All three clear WCAG 1.4.11's 3:1 non-text requirement against our surface (#131513).PaletteTestsholds this, and a future asset whose colour failed would have to fall back to the template silhouette.
Negative space is preserved by construction: the paths are filled non-zero, exactly as browsers render them, so the knot's interlacing and the burst's gaps survive. The mark tests check both read at the menu bar's real 11 pt glyph height.
The Claude name and mark are trademarks of Anthropic PBC. The ChatGPT and OpenAI names and marks are trademarks of OpenAI OpCo, LLC. The Grok name and mark are trademarks of X.AI LLC. Left is an independent tool and is not affiliated with, endorsed by, or sponsored by any of those companies.
The marks are used nominatively: each identifies the provider whose allowance is displayed on the row it labels, which is the purpose a nominative use has to serve. Specifically:
- Each mark appears only beside that provider's own data. Neither is used as
Left's own icon, in its app icon, or anywhere it could read as the source of
the software. Left's identity is its own mark (
LeftMark.swift), which is what the app icon and the pre-first-reading status item carry. - No more of either brand is used than identifies the provider — the mark and the provider's name, nothing else. No wordmark lockup, no brand typeface, no vendor colour anywhere but the mark itself.
- The geometry is unmodified. The two adaptations above are rendering, not redesign, and both are documented here.
Constraints we are knowingly operating under, recorded so the next person does not have to rediscover them:
- The vendors' brand guidelines restrict recolouring their marks. The menu-bar template is a recolour — it is the platform's requirement for a status item, not a stylistic choice, and it is the narrowest form available (a monochrome silhouette of the unmodified geometry). The overlay avoids the issue entirely by using each vendor's own declared colour.
- A favicon is published for browsers to display, which is not the same as a grant of trademark licence. The claim here is nominative fair use, not licence. That is a defensible position for an independent client that displays a user's own account data, and it is the position Left is taking.
- If either vendor objects, the remedy is small and pre-planned: the marks are loaded through one type, so replacing them with the provider's plain name is a one-file change.
The ChatGPT mark stands for the provider, not the product. The allowance
behind it is the Codex CLI's, so the overlay row is labelled ChatGPT / Codex
rather than left to the mark alone, and the mark never appears without that
label or the compact GPT beside it. Nothing in the app presents Codex
allowance as a separate provider identity, and nothing presents it as ChatGPT
subscription usage.