One favicon for one company, and the bar offers both controls

THE MARK. docs shipped the brand mark inset ~13% inside a black rounded tile,
with two shaded paths the brand mark does not have, while hanzo.ai serves it bare
and full-bleed. Two favicons for one company: on a light tab strip hanzo.ai
showed a clean H and docs showed a black tile, so the two did not read as the
same product. icon.svg is now byte-identical in geometry to hanzo.ai's, colour
rule included — black on light, white on dark, which a tile cannot do because its
background is opaque. The .ico and the two .png are regenerated from it, taking
the light fill because a raster cannot follow the strip and black-on-black is the
one outcome that shows nothing.

THE BAR CARRIED ONLY THE KEY. The column at the foot of the rail offers Sign in
then Get an API key; the top-bar copy — which is what shows on the front page and
on every phone, where the rail is collapsed or a drawer — offered the key alone.
So in exactly the states a first-time reader is in, the commitment was the only
thing on screen and there was no way to sign in beside it. Both now, sign in
first, short labels because that row is a fixed 56px.

AND "SURFACES" IS "INTERFACES". Not "Apps": this section already contains a page
called apps, and a heading sharing a name with one of its own rows reads as a
mistake. Interfaces says what they are — the places a person reaches Hanzo.
This commit is contained in:
2026-08-22 17:39:17 -07:00
parent ad3eae731e
commit 73302c7bcc
6 changed files with 39 additions and 31 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

+16 -24
View File
@@ -1,29 +1,21 @@
<!--
Favicon framing. The mark's geometry is untouched — it is the shared brand mark,
drawn identically by the header. Only the viewBox that frames it moved.
The brand mark, and the SAME one hanzo.ai serves at /favicon.svg — byte-for-byte
the same geometry, the same full-bleed viewBox, the same colour rule.
It was viewBox="0 0 67 67" while the mark occupies x 4..53.6 and y 4..54, so the
padding was 4 on the left and top but ~13 on the right and bottom. At 16px in a
tab that reads as a lopsided glyph pushed into one corner.
It used to be this mark inset ~13% inside a black rounded rectangle, with two
extra shaded paths the brand mark does not have. That is a second favicon for
one company: on a light tab strip hanzo.ai showed a clean H and docs showed a
black tile, so the two sites did not read as the same product.
The size 67 was already right and is kept: measured against the shipped icon.png
(256px, mark bbox 32..222 on both axes) the mark is 74% of the canvas, and
50 / 0.746 = 67. Only the ORIGIN moves. The mark centres on (28.8, 29), so
shifting the box to (-4.7, -4.5) puts 8.7 and 8.5 units of padding on all four
sides — the same 13% the PNG has.
rx matches the PNG's rounded corner, which this file was missing entirely: the
SVG and the PNG were two different shapes.
The fill follows the tab strip rather than being painted on: black on light,
white on dark. A boxed mark cannot do that — the box is opaque, so it carries
its own background into whatever the browser draws behind it.
-->
<svg viewBox="-4.7 -4.5 67 67" xmlns="http://www.w3.org/2000/svg">
<rect x="-4.7" y="-4.5" width="67" height="67" rx="10.5" fill="#000000"/>
<g>
<path d="M17 54V36.1H4V54H17Z" fill="#ffffff"/>
<path d="M4 36.1L17 37.6V36.1H4Z" fill="#DDDDDD" opacity="0.7"/>
<path d="M53.6 17.4H17.2L4 36.1H40.3L53.6 17.4Z" fill="#ffffff"/>
<path d="M17 4H4V17.4H17V4Z" fill="#ffffff"/>
<path d="M53.6 4H40.4V17.4H53.6V4Z" fill="#ffffff"/>
<path d="M53.6 17.4L40.4 15.7V17.4H53.6Z" fill="#DDDDDD" opacity="0.7"/>
<path d="M53.6 54V36.1H40.4V54H53.6Z" fill="#ffffff"/>
</g>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 67 67" role="img" aria-label="Hanzo">
<style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style>
<path d="M22.21 67V44.6369H0V67H22.21Z"/>
<path d="M66.7038 22.3184H22.2534L0.0878906 44.6367H44.4634L66.7038 22.3184Z"/>
<path d="M22.21 0H0V22.3184H22.21V0Z"/>
<path d="M66.7198 0H44.5098V22.3184H66.7198V0Z"/>
<path d="M66.7198 67V44.6369H44.5098V67H66.7198Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+22 -6
View File
@@ -176,12 +176,28 @@ export function NavAccount() {
</a>
)
// BOTH, and sign in first — the same order the column at the foot of the rail
// uses. Carrying only the key made this the one place the two controls
// disagreed: on the front page and on every phone, "API key" stood alone with
// no way to sign in beside it, so the commitment was the only thing offered.
//
// Short labels, because the bar is a fixed 56px row: the full phrase is what
// reflowed to three lines and spilled between 768 and 805px, which is why the
// long form lives in the column and this one does not.
return (
<a
href="https://console.hanzo.ai"
className="rounded-lg bg-fd-primary px-2.5 py-1.5 text-sm font-medium text-fd-primary-foreground whitespace-nowrap transition-colors hover:opacity-90"
>
API key
</a>
<div className="flex items-center gap-2">
<Link
href="/login"
className="rounded-lg px-2 py-1.5 text-sm text-fd-muted-foreground whitespace-nowrap transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground max-sm:hidden"
>
Sign in
</Link>
<a
href="https://console.hanzo.ai"
className="rounded-lg bg-fd-primary px-2.5 py-1.5 text-sm font-medium text-fd-primary-foreground whitespace-nowrap transition-colors hover:opacity-90"
>
API key
</a>
</div>
)
}
+1 -1
View File
@@ -24,7 +24,7 @@
"credits",
"pricing",
"errors",
"---Surfaces---",
"---Interfaces---",
"console",
"mission-control",
"studio",