Files
zeekay ad3b4a9e7b fix(brand): every brand wears its own mark, drawn by its own package
Zoo, Pars and Hanzo were rendering a rounded rectangle. Their real artwork
existed the whole time — the CMYK circles, the Persian star, the block H —
just not here. Each now comes from that brand's own logo package at build
time, the way Lux already did, so nobody is holding a second copy of anyone
else's letterforms.

A mark drawn in currentColor has no colour of its own, and an SVG loaded as
an image is its own document with nothing to inherit from, so the Hanzo mark
carries its own light and dark ink. The colour marks keep theirs in both.

The NEXT_PUBLIC_BRAND_* vars went with it. Nothing had read them since the
brand started resolving from the request host, but .env.hanzo still named
safe-client.safe.global as the gateway and black as the primary colour, both
of which the brand package contradicts, and select-brand.sh would have
copied either into a build. .env.safe could no longer produce the upstream
build it promised. Both files were dead through and every line, so they are
gone rather than emptied, along with the two build scripts that read them.
One build remains; the host decides the brand.
2026-08-13 17:00:30 -07:00

1.5 KiB

@safe-global/brand

White-label brand tokens for the Safe wallet monorepo.

Why

The Safe wallet codebase is the upstream OSS reference. Lux Safe, Zoo Safe, Pars Safe and Hanzo Vault all ship from the same source. To keep them in lock- step we keep brand strings (product name, URLs, support contacts, asset paths, primary color) out of the source — they live here, in one file, behind one type.

Shape

import { brand } from '@safe-global/brand'

brand.name // "Lux Safe"  (or "Zoo Safe", "Pars Safe", "Hanzo Vault")
brand.domain // "safe.lux.network"
brand.email // "[email protected]"
brand.helpUrl // "https://docs.lux.network/safe"
brand.logoUrl // "/brand/lux/logo.svg"
brand.primaryColor // "#000000"

See src/index.ts for the full Brand interface.

Where the values come from

The request host, at runtime — the same way getWhiteLabelBrand works across the rest of the Lux/Hanzo stack. safe.lux.network is Lux, safe.zoo.network is Zoo, safe.pars.network is Pars, vault.hanzo.ai is Hanzo Vault. A host that matches nothing gets Lux.

Nothing is baked in at build time, so one image serves every brand. Adding a brand means adding an entry to the registry in src/index.ts and an asset directory under apps/web/public/brand/<slug>/ — there is no env var to set and no per-brand build to run.

Rule

There is exactly one way to render the product name. It is brand.name. There is no 'Safe' string literal in source files. If you find one, replace it.