diff options
| -rw-r--r-- | assets/brand/README.md | 35 | ||||
| -rw-r--r-- | assets/brand/meshbay-M-transparent.png | bin | 0 -> 56523 bytes | |||
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/api/webapp.py | 2 | ||||
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 9 | ||||
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/meshbay-m.png | bin | 0 -> 10066 bytes | |||
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/style.css | 36 |
6 files changed, 78 insertions, 4 deletions
diff --git a/assets/brand/README.md b/assets/brand/README.md new file mode 100644 index 0000000..b673589 --- /dev/null +++ b/assets/brand/README.md @@ -0,0 +1,35 @@ +# Brand assets + +## `meshbay-M-transparent.png` + +The stylised M, 214 × 190, RGBA with a transparent background. **This is the +source.** It lived in `QE/` until 2026-08-19, which is gitignored — the artwork +would not have survived a clone. + +## Deriving the nav wordmark + +`packages/meshbay-hub/src/meshbay_hub/static/meshbay-m.png` is generated from +it, not drawn separately: + +```bash +convert assets/brand/meshbay-M-transparent.png \ + -trim +repage -resize x72 -strip \ + packages/meshbay-hub/src/meshbay_hub/static/meshbay-m.png +``` + +- `-trim +repage` removes the transparent margin, so the CSS controls the + spacing rather than the file's padding doing it invisibly. +- `-resize x72` is 72 px tall for a picture displayed at 30 px — enough for a + 2× screen, and 56 KB becomes 10 KB. + +The derived file is listed in `_ASSETS` in `meshbay_hub/api/webapp.py`. It has +to be: that list is what the `/a/<hash>/` fingerprint is computed from, so a +file missing from it is a file whose change never moves the URL, and a browser +holding the old one never asks again. Regenerate the picture, and the wordmark +changes for everyone; forget the list, and it changes for nobody. + +The M is a picture standing in for the letter M; `eshBay` beside it is text. +Their sizes are set independently in `style.css` — `.nav-brand { font-size }` +and `.nav-brand-m { height }`, the second in **pixels on purpose**. Written in +`em` it was a fraction of the lettering, so resizing the words resized the +picture by the same stroke and the balance between them could never be changed. diff --git a/assets/brand/meshbay-M-transparent.png b/assets/brand/meshbay-M-transparent.png Binary files differnew file mode 100644 index 0000000..6fea08c --- /dev/null +++ b/assets/brand/meshbay-M-transparent.png diff --git a/packages/meshbay-hub/src/meshbay_hub/api/webapp.py b/packages/meshbay-hub/src/meshbay_hub/api/webapp.py index 7028071..19d22d4 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/webapp.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/webapp.py @@ -28,7 +28,7 @@ router = APIRouter(tags=["webapp"]) # which is the failure this list exists to prevent, and it is silent. _ASSETS = ("style.css", "keyderive.js", "crypto.js", "transport.js", "app.js", "i18n.js", "downloads.js", "transfers.js", "zipstream.js", - "platform.js") + "platform.js", "meshbay-m.png") def _asset_version() -> str: diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index 0843d1d..2e3c422 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -400,6 +400,11 @@ const ICON_PATHS = { close: ['M6 6l12 12M18 6L6 18'], }; +// The M of the wordmark is a picture; the rest is text. Resolved from this +// module's own URL so the hub's fingerprinted path and the application's +// app:// scheme both come out right without either being named here. +const BRAND_M = new URL('./meshbay-m.png', import.meta.url).href; + function Icon({ name, cls = '' }) { const paths = ICON_PATHS[name]; if (!paths) return null; @@ -579,7 +584,9 @@ function Nav({ user, theme, onThemeChange, onLogout, onMenuToggle, unreadCount, <button class="nav-hamburger" onClick=${onMenuToggle} aria-label="${t('nav.toggle_menu')}"><${Icon} name="menu" /></button> `} - <a class="nav-brand" href="#/">MeshBay</a> + <a class="nav-brand" href="#/"> + <img class="nav-brand-m" src=${BRAND_M} alt="M" />eshBay + </a> </div> <div class="nav-right"> ${user && html`<${TransferWidget} />`} diff --git a/packages/meshbay-hub/src/meshbay_hub/static/meshbay-m.png b/packages/meshbay-hub/src/meshbay_hub/static/meshbay-m.png Binary files differnew file mode 100644 index 0000000..a682f33 --- /dev/null +++ b/packages/meshbay-hub/src/meshbay_hub/static/meshbay-m.png diff --git a/packages/meshbay-hub/src/meshbay_hub/static/style.css b/packages/meshbay-hub/src/meshbay_hub/static/style.css index 12fc15f..238f33a 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/style.css +++ b/packages/meshbay-hub/src/meshbay_hub/static/style.css @@ -19,7 +19,9 @@ --success: #22c55e; --nav-bg: #0f172a; --nav-text: #e2e8f0; - --nav-brand: #38bdf8; + /* One step down from sky-400 towards sky-500: the wordmark sat brighter than + the picture beside it, which made the two read as different materials. */ + --nav-brand: #23b1f0; --sidebar-bg: #f1f5f9; --sidebar-hover: #e2e8f0; --shadow: 0 1px 3px rgba(0, 0, 0, 0.08); @@ -92,11 +94,41 @@ a:hover { text-decoration: underline; } .nav-brand { color: var(--nav-brand); font-weight: 700; - font-size: 1.15em; + /* 22px measured in the application. 1.15em was lettering sized for plain + text and read as a caption beside the picture; 1.45em overshot. */ + font-size: 1.375em; text-decoration: none; } .nav-brand:hover { text-decoration: none; } +/* The M is a picture standing in for a letter, so it is sized in `em` and + follows the wordmark rather than being pinned to a pixel height. + + Sized by measuring the running application, twice. At 1.35em of the old + font size it rendered 25px against a 29px line box — *smaller* than the + letters beside it, so the wordmark read as unchanged. At 1.9em it was 35px + against 29px, which overshot the other way. The pair is now set together: + the picture leads, the lettering follows a little behind it. */ +.nav-brand { + display: inline-flex; + align-items: center; +} +.nav-brand-m { + /* **In pixels, not `em` — and that is the point.** Written in `em` this was + a fraction of the lettering's size, so every adjustment to the text moved + the picture too and the pair could never be settled: making the words + bigger made the M bigger by the same stroke, and the ratio never changed. + Two independent things need two independent numbers. + + 30px against 22px of lettering. */ + height: 30px; + width: auto; + /* Positive, deliberately. The glyph this replaces carried its own side + bearing and an image has none, so without this the picture sits flush + against the "e". */ + margin-right: 4px; +} + .nav-hamburger { display: none; background: none; |