brand: PNG social/icon set + generator; Angie vhost tracked with slash-less rules

site/brand/social/ and site/brand/icon/ carry ready-to-upload PNGs at the
sizes X, LinkedIn, Facebook, Instagram, GitHub and PWA manifests want:
X header 1500x500, post 1200x675, LinkedIn 1584x396, Facebook 820x312,
Instagram 1080, avatars 400/1024, icons 512/192, favicons 64/32, plus the
Open Graph 1200x630 that every page already advertises. The brand page
gained a "Social media and icons" section with download links.

scripts/brand-assets.mjs renders the whole set from one HTML template via
scripts/render-html-png.cjs (Electron offscreen). Windows clamps even an
offscreen window to the work area, so captures taller than the screen are
rendered as strips and stitched on a canvas inside the page.

The VPS serves silentmode.st with Angie, not nginx (nginx.service is dead
there), so the URL rules now live in VPS/SilentMode/silentmode-st.angie.conf,
deployed and live. try_files lists $uri/index.html before $uri because a
bare $uri also matches a directory and would 301 to add the slash back.
GOTCHAS and the URL-scheme notes corrected accordingly.
This commit is contained in:
Local Dev 2026-09-22 23:08:46 +02:00
parent f74a574dd4
commit ac53958af3
14 changed files with 73 additions and 9 deletions

View file

@ -1,6 +1,6 @@
# site/ — gotchas
Hand-authored static tree for **silentmode.st**. No build step. Served by nginx
Hand-authored static tree for **silentmode.st**. No build step. Served by Angie (nginx fork)
from `/opt/silent-mode/site/` on the VPS (ssh alias `silentmode`), and mirrored
to Sia (`s3://bns/silentmode/` → `silentmode.bch`) by the
`silentmode-sia-sync.timer` on the VPS every 5 minutes. Anything that lands in
@ -38,7 +38,7 @@ it is skipped the 48 GB disk climbs ~245 MB per release.
## Bump `shared.css?v=` whenever shared.css changes
nginx sends no `Cache-Control` for `.css`, so browsers cache `shared.css`
Angie sends no `Cache-Control` for `.css`, so browsers cache `shared.css`
heuristically (10% of its age since `Last-Modified`; it sat unchanged for
weeks, so returning visitors kept the old copy for days). When the logo rule
was added on 2026-09-07 every page except Hephaestus (inline nav CSS) showed
@ -49,7 +49,7 @@ each time the file changes. Same applies to the Sia mirror via the gateway.
## URLs have no trailing slash; links are site-root-relative
Since 2026-09-20 the canonical URL of every silentmode.st page is `/tools`,
`/sirius`, `/choose/free` — nginx 301s `/tools/` → `/tools` and serves
`/sirius`, `/choose/free` — Angie 301s `/tools/` → `/tools` and serves
`/tools/index.html` from it. Consequences for authors:
- A page at `/x/index.html` is viewed at `/x`, so the browser's directory is `/`.
@ -66,8 +66,8 @@ Since 2026-09-20 the canonical URL of every silentmode.st page is `/tools`,
**Sub-sites deployed from other repos keep their trailing-slash URLs** because
their asset paths are relative: `deviant/`, `sirius-x/`, `theseus-x/`,
`hephaestus.x/`, `fly.x/`, `code/`. The list lives in the nginx vhost
(`location ~ ^/(deviant|sirius-x|theseus-x|…)`) and in `serve-site.mjs`; add
`hephaestus.x/`, `fly.x/`, `code/`. The list lives in the Angie vhost
(`location ~ ^/(deviant|sirius-x|theseus-x|…)` in `VPS/SilentMode/silentmode-st.angie.conf`) and in `serve-site.mjs`; add
any new foreign mirror to both.
## `/theseus` vs `/theseus-x/` (and `/sirius` vs `/sirius-x/`)
@ -95,7 +95,7 @@ Theseus (origin `bns://<name>`). Without CORS the browser refuses to load the
module and every wallet/register/mint flow silently breaks — the launcher
click does nothing.
The nginx block on VPS (`/etc/nginx/sites-enabled/silentmode-st`) MUST carry:
The vhost on the VPS is **Angie** at `/etc/angie/http.d/silentmode-st.conf` (nginx is installed but dead there; `/etc/nginx/sites-enabled/silentmode-st` is ignored). It is tracked at `VPS/SilentMode/silentmode-st.angie.conf`; deploy with scp + `angie -t && systemctl reload angie`. It MUST carry:
```
location ~ ^/js/.*\.js$ {
@ -106,6 +106,6 @@ location ~ ^/js/.*\.js$ {
```
Added 2026-09-08 after Theseus reported "CORS blocked" from origin
`bns://sirius.x`. If a future nginx-config rebuild drops the `add_header
`bns://sirius.x`. If a future vhost rebuild drops the `add_header
Access-Control-*` lines, every non-silentmode.st page that imports the bundle
starts failing again with "No 'Access-Control-Allow-Origin' header".

BIN
brand/icon/favicon-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

BIN
brand/icon/favicon-64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

BIN
brand/icon/icon-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
brand/icon/icon-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

View file

@ -65,8 +65,8 @@
<h1>Silent Mode — <span class="g">brand</span></h1>
<p class="tag">Two interlocking chain links, one acid green — the family mark for
every Silent Mode product. Kit below: logo, wordmark, avatar, banner, palette,
usage. Every asset is a scalable SVG; raster it to whatever platform demands
a PNG.</p>
usage. Every asset is a scalable SVG, and the <a href="brand#social">social section</a>
has PNGs at every platform size.</p>
</header>
<div class="wrap">
@ -150,6 +150,70 @@
</section>
<!-- ============ PALETTE ============ -->
<!-- ============ SOCIAL + ICONS (PNG) ============ -->
<section id="social">
<h2>Social media and icons</h2>
<p class="lede">Ready-made PNGs at the sizes each platform wants. Same mark, same
palette, rendered from the SVGs above; nothing here needs editing before upload.
X, GitHub, Discord, LinkedIn, Instagram and Facebook all refuse SVG for avatars
and headers, so use these.</p>
<div class="asset">
<div class="preview"><img src="brand/social/x-header-1500x500.png" alt="Silent Mode header banner, 1500 by 500" loading="lazy"></div>
<div class="meta">
<h3>Headers and banners</h3>
<p>Mark, wordmark, one-line description and the two addresses. The layout keeps
the left 60% clear of platform overlays; the avatar sits over the bottom-left
on X without covering text.</p>
<div class="size">PNG · flattened on the dark ground</div>
<div class="dl">
<a href="brand/social/x-header-1500x500.png" download>X header 1500×500</a>
<a href="brand/social/linkedin-banner-1584x396.png" download>LinkedIn 1584×396</a>
<a href="brand/social/facebook-cover-820x312.png" download>Facebook 820×312</a>
</div>
</div>
</div>
<div class="asset">
<div class="preview"><img src="brand/social/x-post-1200x675.png" alt="Silent Mode post card, 1200 by 675" loading="lazy"></div>
<div class="meta">
<h3>Post and link cards</h3>
<p>For tweets, announcements and anywhere a 16:9 image is embedded. The 1200×630
version is what every silentmode.st page advertises as its Open Graph image,
so shared links already show it.</p>
<div class="size">PNG · 16:9 and 1.91:1</div>
<div class="dl">
<a href="brand/social/x-post-1200x675.png" download>Post 1200×675</a>
<a href="brand/og.png" download="silentmode-og-1200x630.png">Open Graph 1200×630</a>
<a href="brand/social/instagram-square-1080x1080.png" download>Square 1080×1080</a>
</div>
</div>
</div>
<div class="asset">
<div class="preview"><img src="brand/social/avatar-400.png" alt="Silent Mode avatar, 400 by 400" style="max-height:240px;border-radius:50%" loading="lazy"></div>
<div class="meta">
<h3>Avatars and app icons</h3>
<p>Avatar: mark over the wordmark on the dark ground, safe inside a circle crop.
Icons: the mark alone on flat <code class="inline">#0b0e14</code> for
favicons, PWA manifests and store listings.</p>
<div class="size">PNG · square</div>
<div class="dl">
<a href="brand/social/avatar-400.png" download>Avatar 400</a>
<a href="brand/social/avatar-1024.png" download>Avatar 1024</a>
<a href="brand/icon/icon-512.png" download>Icon 512</a>
<a href="brand/icon/icon-192.png" download>Icon 192</a>
<a href="brand/icon/favicon-64.png" download>Favicon 64</a>
<a href="brand/icon/favicon-32.png" download>Favicon 32</a>
</div>
</div>
</div>
<p style="color:var(--dim);font-size:13px;margin:1rem 0 0">Regenerate the whole set
after a palette or mark change with <code class="inline">node scripts/brand-assets.mjs</code>
in the repo; it renders every size from one template.</p>
</section>
<section>
<h2>Palette</h2>
<p class="lede">Small palette on purpose — one accent, one text tone, three greys,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

BIN
brand/social/avatar-400.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB