diff --git a/brand/README.md b/brand/README.md
new file mode 100644
index 000000000..2c1cd6935
--- /dev/null
+++ b/brand/README.md
@@ -0,0 +1,57 @@
+# Igneum brand assets
+
+## The rule (the project lead, 4 October 2026)
+
+One global logo for apps, profile pictures, favicons, everything. The mark sits in a black square. Never in a circle.
+Never on another colour. Minimum clear space = 20% of the square. The Mac app icon is the model: a full square, all
+black, the mark in the middle.
+
+- Square: `#0C0C0E` (the site's obsidian token, `--obsidian` in `site/index.html`).
+- Mark: `#F2541B` ember, the flame's centre cut in obsidian. Geometry = the two polygons in the site header
+ (`site/index.html`, 100 x 100 viewBox). Do not redraw it.
+- Mark height = 62% of the square (so 19% clear on top and bottom, 30% on each side).
+- No ring, no border, no rounded corners baked in, apart from the one rounded variant below.
+
+## Masters (`brand/master/`)
+
+| File | Use |
+|---|---|
+| `igneum-mark-square.svg` | The master. 1024 x 1024, full-bleed obsidian, mark centred. Every derivative comes from this. |
+| `igneum-mark-square-rounded.svg` | Apple's icon grid (824 x 824 shape on the 1024 canvas, continuous corner as a superellipse). Only for the DMG volume icon. Tahoe masks the plain square itself, so the app bundle ships the plain square. |
+
+## Generator
+
+`python3 brand/icons/make-icons.py` rebuilds every file below from the masters. It uses `rsvg-convert` when installed
+(`brew install librsvg`), otherwise Pillow draws the master's polygons at 4x to 16x supersampling (exact, the mark is two
+polygons). The Windows `.ico` and the favicons render each size from the vector, never by shrinking a bitmap.
+
+## File map
+
+| File | What | Where it is used |
+|---|---|---|
+| `brand/icons/igneum.icns` | plain square, 16 to 1024 | `Igneum Miner.app/Contents/Resources` (`packaging/mac/build-dmg.sh`, `CFBundleIconFile` = `igneum`) |
+| `brand/icons/igneum-volume.icns` | rounded variant | the DMG volume icon (`packaging/mac/dmg/settings.py`) |
+| `brand/icons/igneum.ico` | 16 24 32 48 64 128 256, BMP entries | every Windows exe through the `.rc` files (`packaging/windows/resources/*.rc`, `proto-cuda/nvrtc/*.rc`, `app/igneum-app/resources/igneum-app.rc`, `app/windows/host.rc`), Inno Setup (`Igneum-Miner.iss`) |
+| `brand/icons/igneum-256.png` | the square at 256 | reference |
+| `brand/icons/inno-*.bmp` | installer wizard art | Inno Setup |
+| `brand/icons/dmg-background*.png/.tiff` | DMG window background | `packaging/mac/dmg/settings.py` |
+| `site/favicon.ico` (16 32 48), `favicon-32.png`, `apple-touch-icon.png` (180, square: iOS rounds it), `icon-192.png`, `icon-512.png`, `maskable-512.png` (mark at 50%) | site favicons | every `site/*.html`, the header template in `site/build.mjs`, `site/site.webmanifest` |
+| `relay/favicon.ico`, `favicon-32.png`, `apple-touch-icon.png` | relay favicons | `relay/index.html`, `relay/ui.html` (static files at the relay root) |
+| `brand/profile/profile-400.png`, `profile-512.png`, `profile-1024.png` | profile pictures | X, Discord, Telegram, LinkedIn |
+| `brand/profile/github-org-512.png` | organisation avatar | github.com/igneum-network (uploaded by hand from the Igneum Chrome profile) |
+| `brand/profile/x-banner-1500x500.png` | X header | the mark centred on obsidian |
+| `brand/igneum-icon-512.png`, `igneum-icon-1024.png` | the square at 512 and 1024 | the same as the profile files; kept for links that already point here |
+
+Inline SVG favicons (the `data:` link in every page head) carry the same square and mark, so a page shows the right icon
+before the `.ico` loads.
+
+## Not regenerated
+
+- `site/og-small.png`, `og-square.png`, `og-coin.png`: the social card design, left as it was by instruction (4 October 2026).
+- `brand/igneum-coin-1024.png`: the old ringed coin. Retired as a source; nothing reads it now.
+- `brand/igneum-mark-transparent-1024.png`, the wordmark PNGs and `Unbounded.ttf`: unchanged.
+
+## Before and after
+
+`docs/brand/before/` holds the icons as they were (ringed coin everywhere except the GitHub avatar), `docs/brand/after-*.png`
+the new set.
diff --git a/brand/icons/dmg-background.png b/brand/icons/dmg-background.png
index 443767a6d..5a3e894fa 100644
Binary files a/brand/icons/dmg-background.png and b/brand/icons/dmg-background.png differ
diff --git a/brand/icons/dmg-background.tiff b/brand/icons/dmg-background.tiff
index 976672e82..7ae40c099 100644
Binary files a/brand/icons/dmg-background.tiff and b/brand/icons/dmg-background.tiff differ
diff --git a/brand/icons/dmg-background@2x.png b/brand/icons/dmg-background@2x.png
index 28cec5a74..a491c2970 100644
Binary files a/brand/icons/dmg-background@2x.png and b/brand/icons/dmg-background@2x.png differ
diff --git a/brand/icons/igneum-256.png b/brand/icons/igneum-256.png
index ada88e8a6..17d2b790c 100644
Binary files a/brand/icons/igneum-256.png and b/brand/icons/igneum-256.png differ
diff --git a/brand/icons/igneum-volume.icns b/brand/icons/igneum-volume.icns
new file mode 100644
index 000000000..6f3f9a442
Binary files /dev/null and b/brand/icons/igneum-volume.icns differ
diff --git a/brand/icons/igneum.icns b/brand/icons/igneum.icns
index 202b1f93a..d06c4da91 100644
Binary files a/brand/icons/igneum.icns and b/brand/icons/igneum.icns differ
diff --git a/brand/icons/igneum.ico b/brand/icons/igneum.ico
index b964d2f30..f333b2f90 100644
Binary files a/brand/icons/igneum.ico and b/brand/icons/igneum.ico differ
diff --git a/brand/icons/inno-banner-150x57.bmp b/brand/icons/inno-banner-150x57.bmp
index 6f94c4cca..8debab1f0 100644
Binary files a/brand/icons/inno-banner-150x57.bmp and b/brand/icons/inno-banner-150x57.bmp differ
diff --git a/brand/icons/inno-wizard-164x314.bmp b/brand/icons/inno-wizard-164x314.bmp
index 041acc6ed..f322fc81e 100644
Binary files a/brand/icons/inno-wizard-164x314.bmp and b/brand/icons/inno-wizard-164x314.bmp differ
diff --git a/brand/icons/inno-wizard-small-55x58.bmp b/brand/icons/inno-wizard-small-55x58.bmp
index 08c292bb1..35d20102c 100644
Binary files a/brand/icons/inno-wizard-small-55x58.bmp and b/brand/icons/inno-wizard-small-55x58.bmp differ
diff --git a/brand/icons/make-icons.py b/brand/icons/make-icons.py
index aebe9b036..cf6474514 100644
--- a/brand/icons/make-icons.py
+++ b/brand/icons/make-icons.py
@@ -1,31 +1,155 @@
#!/usr/bin/env python3
-"""Builds the Igneum Miner icon and installer art from brand/igneum-coin-1024.png (3 October 2026).
+"""Builds every Igneum icon from the master mark, brand/master/igneum-mark-square.svg (4 October 2026).
-Outputs, all in brand/icons/:
- igneum.icns Mac app and DMG volume icon (iconutil from the full 10-file iconset)
- igneum.ico Windows icon, 16 24 32 48 64 128 256 px, uncompressed BMP entries
- igneum-256.png the coin cut out on transparency (the source of both)
- inno-wizard-164x314.bmp Inno Setup WizardImageFile (left side of the welcome and finish pages)
- inno-wizard-small-55x58.bmp Inno Setup WizardSmallImageFile (top right of the other pages)
- inno-banner-150x57.bmp header banner (NSIS size; kept for the Windows README and any header-style page)
- dmg-background.png 660x400 DMG window background
- dmg-background@2x.png the same at 1320x800 for Retina; dmg-background.tiff holds both when tiffutil is present
-Needs Pillow and, on a Mac, iconutil and tiffutil (both ship with macOS).
+the project lead's rule (4 October 2026): one global logo for apps, profile pictures, favicons, everything. The mark sits in a black
+square (#0C0C0E, the site's obsidian token), centred, no circle, no ring, no border, never on another colour. The Mac app
+is the model. The rounded variant (brand/master/igneum-mark-square-rounded.svg, Apple's 824-on-1024 icon grid) is used
+only where the shape has to be baked into the file: the DMG volume icon. Tahoe masks the plain square itself.
+
+Outputs:
+ brand/icons/
+ igneum.icns the app bundle icon (plain square, 16 to 1024, iconutil)
+ igneum-volume.icns the DMG volume icon (rounded variant)
+ igneum.ico Windows icon, 16 24 32 48 64 128 256 px, uncompressed BMP entries, each rendered from the vector
+ igneum-256.png the square at 256 px
+ inno-wizard-164x314.bmp Inno Setup WizardImageFile
+ inno-wizard-small-55x58.bmp Inno Setup WizardSmallImageFile
+ inno-banner-150x57.bmp header banner (NSIS size)
+ dmg-background.png / @2x 660x400 DMG window background; dmg-background.tiff holds both when tiffutil is present
+ site/ favicon.ico (16 32 48), favicon-32.png, apple-touch-icon.png (180, square: iOS rounds it), icon-192.png,
+ icon-512.png, maskable-512.png (the mark at 50% of the square, inside the maskable safe zone)
+ relay/ favicon.ico, favicon-32.png, apple-touch-icon.png (the relay serves static files from its root)
+ brand/profile/ profile-400.png, profile-512.png, profile-1024.png (X, Discord, Telegram, LinkedIn), github-org-512.png,
+ x-banner-1500x500.png (the mark centred on obsidian)
+ brand/igneum-icon-512.png and igneum-icon-1024.png are refreshed from the master as well.
+
+Rendering: rsvg-convert when it is installed (brew install librsvg), else Pillow draws the master's rect and polygons
+itself at 4x to 16x supersampling (the mark is two polygons, so this is exact). cairosvg is not used: the conda build on
+this Mac has no libcairo. Needs Pillow and, on a Mac, iconutil and tiffutil (both ship with macOS).
python3 brand/icons/make-icons.py
"""
-import os, subprocess, sys, shutil, tempfile
+import os, re, subprocess, sys, shutil, tempfile
+import xml.etree.ElementTree as ET
from PIL import Image, ImageDraw, ImageFont
HERE = os.path.dirname(os.path.abspath(__file__))
BRAND = os.path.dirname(HERE)
-COIN = os.path.join(BRAND, 'igneum-coin-1024.png')
+ROOT = os.path.dirname(BRAND)
+MASTER = os.path.join(BRAND, 'master', 'igneum-mark-square.svg')
+MASTER_ROUNDED = os.path.join(BRAND, 'master', 'igneum-mark-square-rounded.svg')
+SITE = os.path.join(ROOT, 'site')
+RELAY = os.path.join(ROOT, 'relay')
+PROFILE = os.path.join(BRAND, 'profile')
FONT = os.path.join(BRAND, 'Unbounded.ttf')
OBSIDIAN = (12, 12, 14)
EMBER = (242, 84, 27)
MOLTEN = (255, 179, 92)
BONE = (244, 241, 236)
-RADIUS = 480.0 # the ember ring's outer edge, measured on the 1024 px coin
-CENTRE = (511.5, 511.5)
+ARTBOARD = 1024
+SVG = '{http://www.w3.org/2000/svg}'
+
+# ---- the vector -------------------------------------------------------------------------------------------------
+
+def hex_rgb(s):
+ s = s.strip().lstrip('#')
+ return tuple(int(s[i:i + 2], 16) for i in (0, 2, 4))
+
+def parse_transform(t):
+ """translate(tx ty) scale(s) -> (tx, ty, s); only the two forms the masters use."""
+ tx = ty = 0.0
+ s = 1.0
+ for name, args in re.findall(r'(\w+)\(([^)]*)\)', t or ''):
+ v = [float(x) for x in re.split(r'[\s,]+', args.strip()) if x]
+ if name == 'translate':
+ tx, ty = v[0], (v[1] if len(v) > 1 else 0.0)
+ elif name == 'scale':
+ s = v[0]
+ return tx, ty, s
+
+def load_master(path):
+ """The master as a list of shapes: ('rect', fill) or ('poly', [(x, y), ...], fill), in document order, on the 1024 artboard."""
+ root = ET.parse(path).getroot()
+ shapes = []
+ def walk(el, tx, ty, s):
+ tag = el.tag.replace(SVG, '')
+ if tag == 'g':
+ gx, gy, gs = parse_transform(el.get('transform'))
+ for c in el:
+ walk(c, tx + gx * s, ty + gy * s, s * gs)
+ elif tag == 'rect':
+ shapes.append(('rect', hex_rgb(el.get('fill'))))
+ elif tag == 'polygon':
+ pts = [float(v) for v in re.split(r'[\s,]+', el.get('points').strip()) if v]
+ poly = [(tx + pts[i] * s, ty + pts[i + 1] * s) for i in range(0, len(pts), 2)]
+ shapes.append(('poly', poly, hex_rgb(el.get('fill'))))
+ else:
+ for c in el:
+ walk(c, tx, ty, s)
+ walk(root, 0.0, 0.0, 1.0)
+ return shapes
+
+def render_pillow(shapes, size, mark_scale=1.0):
+ """The shapes at `size` px, supersampled, on transparency. mark_scale shrinks the polygons about the centre
+ (the maskable icon wants the mark at 50% of the square instead of 62%)."""
+ ss = max(2, min(16, 4096 // size))
+ big = size * ss
+ k = big / ARTBOARD
+ im = Image.new('RGBA', (big, big), (0, 0, 0, 0))
+ d = ImageDraw.Draw(im)
+ c = ARTBOARD / 2
+ for sh in shapes:
+ if sh[0] == 'rect':
+ d.rectangle((0, 0, big, big), fill=sh[1] + (255,))
+ else:
+ pts = [((c + (x - c) * mark_scale) * k, (c + (y - c) * mark_scale) * k) for x, y in sh[1]]
+ d.polygon(pts, fill=sh[2] + (255,))
+ return im.resize((size, size), Image.LANCZOS)
+
+def render_rsvg(path, size):
+ out = subprocess.run(['rsvg-convert', '-w', str(size), '-h', str(size), path], capture_output=True, check=True).stdout
+ import io
+ return Image.open(io.BytesIO(out)).convert('RGBA')
+
+_cache = {}
+def render(size, rounded=False, mark_scale=1.0):
+ key = (size, rounded, mark_scale)
+ if key not in _cache:
+ path = MASTER_ROUNDED if rounded else MASTER
+ if mark_scale == 1.0 and shutil.which('rsvg-convert'):
+ im = render_rsvg(path, size)
+ else:
+ im = render_pillow(load_master(path), size, mark_scale)
+ _cache[key] = im
+ return _cache[key].copy()
+
+# ---- outputs ----------------------------------------------------------------------------------------------------
+
+def save_png(im, path):
+ os.makedirs(os.path.dirname(path), exist_ok=True)
+ im.save(path, optimize=True)
+ return path
+
+def make_icns(name, rounded):
+ tmp = tempfile.mkdtemp()
+ iconset = os.path.join(tmp, 'igneum.iconset')
+ os.mkdir(iconset)
+ for s in (16, 32, 128, 256, 512):
+ render(s, rounded).save(os.path.join(iconset, f'icon_{s}x{s}.png'))
+ render(s * 2, rounded).save(os.path.join(iconset, f'icon_{s}x{s}@2x.png'))
+ out = os.path.join(HERE, name)
+ subprocess.run(['iconutil', '-c', 'icns', iconset, '-o', out], check=True)
+ shutil.rmtree(tmp)
+ return out
+
+def make_ico(path, sizes):
+ frames = [render(s).convert('RGBA') for s in sizes]
+ os.makedirs(os.path.dirname(path), exist_ok=True)
+ base, rest = frames[-1], frames[:-1]
+ try:
+ base.save(path, format='ICO', sizes=[(s, s) for s in sizes], append_images=rest, bitmap_format='bmp')
+ except TypeError:
+ base.save(path, format='ICO', sizes=[(s, s) for s in sizes], append_images=rest)
+ return path
def font(size, weight='SemiBold'):
f = ImageFont.truetype(FONT, size)
@@ -35,42 +159,6 @@ def font(size, weight='SemiBold'):
pass
return f
-def coin_rgba():
- """The coin on transparency: a 4x supersampled circular mask at the ring's outer edge."""
- im = Image.open(COIN).convert('RGBA')
- big = Image.new('L', (4096, 4096), 0)
- d = ImageDraw.Draw(big)
- cx, cy, r = CENTRE[0] * 4 + 2, CENTRE[1] * 4 + 2, (RADIUS - 0.5) * 4
- d.ellipse((cx - r, cy - r, cx + r, cy + r), fill=255)
- mask = big.resize((1024, 1024), Image.LANCZOS)
- im.putalpha(mask)
- return im
-
-def fit(im, size):
- return im.resize((size, size), Image.LANCZOS)
-
-def make_icns(coin):
- tmp = tempfile.mkdtemp()
- iconset = os.path.join(tmp, 'igneum.iconset')
- os.mkdir(iconset)
- for s in (16, 32, 128, 256, 512):
- fit(coin, s).save(os.path.join(iconset, f'icon_{s}x{s}.png'))
- fit(coin, s * 2).save(os.path.join(iconset, f'icon_{s}x{s}@2x.png'))
- out = os.path.join(HERE, 'igneum.icns')
- subprocess.run(['iconutil', '-c', 'icns', iconset, '-o', out], check=True)
- shutil.rmtree(tmp)
- return out
-
-def make_ico(coin):
- out = os.path.join(HERE, 'igneum.ico')
- sizes = [(s, s) for s in (16, 24, 32, 48, 64, 128, 256)]
- base = fit(coin, 256)
- try:
- base.save(out, format='ICO', sizes=sizes, bitmap_format='bmp')
- except TypeError:
- base.save(out, format='ICO', sizes=sizes)
- return out
-
def wordmark(text, size, colour=BONE, weight='SemiBold'):
f = font(size, weight)
l, t, r, b = f.getbbox(text)
@@ -84,20 +172,18 @@ def paste_centre(dst, src, cx, cy):
def bmp(im, path):
im.convert('RGB').save(path, format='BMP')
-def make_inno(coin):
- # 164x314: the coin above a two-line wordmark
+def make_inno():
+ # The installer pages are obsidian already, so the square tile merges with the page: the mark reads centred, no edge.
big = Image.new('RGBA', (164, 314), OBSIDIAN + (255,))
- paste_centre(big, fit(coin, 112), 82, 110)
+ paste_centre(big, render(124), 82, 110)
paste_centre(big, wordmark('IGNEUM', 19, BONE, 'Bold'), 82, 205)
paste_centre(big, wordmark('MINER', 13, MOLTEN, 'Medium'), 82, 232)
bmp(big, os.path.join(HERE, 'inno-wizard-164x314.bmp'))
- # 55x58: the coin alone
small = Image.new('RGBA', (55, 58), OBSIDIAN + (255,))
- paste_centre(small, fit(coin, 50), 27.5, 29)
+ paste_centre(small, render(55), 27.5, 29)
bmp(small, os.path.join(HERE, 'inno-wizard-small-55x58.bmp'))
- # 150x57: coin left, wordmark right
banner = Image.new('RGBA', (150, 57), OBSIDIAN + (255,))
- paste_centre(banner, fit(coin, 44), 28, 28.5)
+ paste_centre(banner, render(50), 28, 28.5)
w1 = wordmark('IGNEUM', 15, BONE, 'Bold')
w2 = wordmark('MINER', 10, MOLTEN, 'Medium')
banner.alpha_composite(w1, (56, 14))
@@ -110,7 +196,7 @@ def arrow(draw, x0, x1, y, colour, width):
draw.polygon([(x1, y), (x1 - h * 1.6, y - h), (x1 - h * 1.6, y + h)], fill=colour)
# Finder icon slots on the DMG (1x pixels, icon size 96): the app at APP_SLOT, the Applications link at APPS_SLOT,
-# README.txt and the Stop command in the row below. build-dmg.sh uses the same numbers.
+# README.txt and the Stop command in the row below. packaging/mac/dmg/settings.py uses the same numbers.
ICON = 96
APP_SLOT = (165, 130)
APPS_SLOT = (495, 130)
@@ -132,9 +218,9 @@ def dashed_box(im, cx, cy, r, colour, width=3, dash=16, gap=10, radius=18):
layer.putalpha(alpha)
im.alpha_composite(layer)
-def make_dmg_background(coin):
- """660x400 at 1x; drawn at 2x and downsampled. The coin is painted under the app slot, so the slot reads as the
- product even before Finder draws the app icon on top of it."""
+def make_dmg_background():
+ """660x400 at 1x; drawn at 2x and downsampled. The rounded icon is painted under the app slot, so the slot reads as
+ the product even before Finder draws the app icon on top of it."""
S = 2
W, H = 660 * S, 400 * S
im = Image.new('RGBA', (W, H), OBSIDIAN + (255,))
@@ -146,7 +232,7 @@ def make_dmg_background(coin):
for i, a in ((76 * S, 10), (66 * S, 12), (58 * S, 14)):
gd.ellipse((ax - i, ay - i, ax + i, ay + i), fill=EMBER + (a,))
im.alpha_composite(glow)
- paste_centre(im, fit(coin, ICON * S), ax, ay)
+ paste_centre(im, render(ICON * S, rounded=True), ax, ay)
dashed_box(im, bx, by, (ICON // 2 + 14) * S, MOLTEN + (190,), width=2 * S, dash=9 * S, gap=6 * S, radius=9 * S)
arrow(d, (APP_SLOT[0] + 78) * S, (APPS_SLOT[0] - 78) * S, ay, EMBER + (255,), 4 * S)
paste_centre(im, wordmark('Drag Igneum Miner to Applications', 16 * S, BONE, 'Medium'), 330 * S, 236 * S)
@@ -160,20 +246,51 @@ def make_dmg_background(coin):
subprocess.run(['tiffutil', '-cathidpicheck', os.path.join(HERE, 'dmg-background.png'),
os.path.join(HERE, 'dmg-background@2x.png'), '-out', tiff], check=True)
+def make_site(folder, full=True):
+ out = []
+ out.append(make_ico(os.path.join(folder, 'favicon.ico'), (16, 32, 48)))
+ out.append(save_png(render(32).convert('RGB'), os.path.join(folder, 'favicon-32.png')))
+ out.append(save_png(render(180).convert('RGB'), os.path.join(folder, 'apple-touch-icon.png')))
+ if full:
+ out.append(save_png(render(192).convert('RGB'), os.path.join(folder, 'icon-192.png')))
+ out.append(save_png(render(512).convert('RGB'), os.path.join(folder, 'icon-512.png')))
+ out.append(save_png(render(512, mark_scale=50 / 62).convert('RGB'), os.path.join(folder, 'maskable-512.png')))
+ return out
+
+def make_profile():
+ out = []
+ for s in (400, 512, 1024):
+ out.append(save_png(render(s).convert('RGB'), os.path.join(PROFILE, f'profile-{s}.png')))
+ out.append(save_png(render(512).convert('RGB'), os.path.join(PROFILE, 'github-org-512.png')))
+ banner = Image.new('RGB', (1500, 500), OBSIDIAN)
+ tile = render(500).convert('RGB')
+ banner.paste(tile, (500, 0))
+ out.append(save_png(banner, os.path.join(PROFILE, 'x-banner-1500x500.png')))
+ out.append(save_png(render(512).convert('RGB'), os.path.join(BRAND, 'igneum-icon-512.png')))
+ out.append(save_png(render(1024).convert('RGB'), os.path.join(BRAND, 'igneum-icon-1024.png')))
+ return out
+
def main():
- coin = coin_rgba()
- fit(coin, 256).save(os.path.join(HERE, 'igneum-256.png'))
+ made = []
+ made.append(save_png(render(256), os.path.join(HERE, 'igneum-256.png')))
if sys.platform == 'darwin' and shutil.which('iconutil'):
- print('icns:', make_icns(coin))
+ made.append(make_icns('igneum.icns', rounded=False))
+ made.append(make_icns('igneum-volume.icns', rounded=True))
else:
print('icns skipped: iconutil is a macOS tool')
- print('ico:', make_ico(coin))
- make_inno(coin)
- make_dmg_background(coin)
+ made.append(make_ico(os.path.join(HERE, 'igneum.ico'), (16, 24, 32, 48, 64, 128, 256)))
+ make_inno()
+ make_dmg_background()
+ made += make_site(SITE)
+ made += make_site(RELAY, full=False)
+ made += make_profile()
for f in sorted(os.listdir(HERE)):
p = os.path.join(HERE, f)
if os.path.isfile(p) and not f.endswith('.py'):
- print(f'{os.path.getsize(p):>8} {f}')
+ made.append(p)
+ print('renderer:', 'rsvg-convert' if shutil.which('rsvg-convert') else 'Pillow (polygons from the master SVG)')
+ for p in sorted(set(made)):
+ print(f'{os.path.getsize(p):>8} {os.path.relpath(p, ROOT)}')
if __name__ == '__main__':
main()
diff --git a/brand/igneum-icon-1024.png b/brand/igneum-icon-1024.png
index 6ab4be74f..5123c561c 100644
Binary files a/brand/igneum-icon-1024.png and b/brand/igneum-icon-1024.png differ
diff --git a/brand/igneum-icon-512.png b/brand/igneum-icon-512.png
index 4b0ca17ca..d6cd427e2 100644
Binary files a/brand/igneum-icon-512.png and b/brand/igneum-icon-512.png differ
diff --git a/brand/master/igneum-mark-square-rounded.svg b/brand/master/igneum-mark-square-rounded.svg
new file mode 100644
index 000000000..cc2e730f9
--- /dev/null
+++ b/brand/master/igneum-mark-square-rounded.svg
@@ -0,0 +1,11 @@
+
diff --git a/brand/master/igneum-mark-square.svg b/brand/master/igneum-mark-square.svg
new file mode 100644
index 000000000..d508e75c6
--- /dev/null
+++ b/brand/master/igneum-mark-square.svg
@@ -0,0 +1,11 @@
+
diff --git a/brand/profile/github-org-512.png b/brand/profile/github-org-512.png
new file mode 100644
index 000000000..d6cd427e2
Binary files /dev/null and b/brand/profile/github-org-512.png differ
diff --git a/brand/profile/profile-1024.png b/brand/profile/profile-1024.png
new file mode 100644
index 000000000..5123c561c
Binary files /dev/null and b/brand/profile/profile-1024.png differ
diff --git a/brand/profile/profile-400.png b/brand/profile/profile-400.png
new file mode 100644
index 000000000..7ffc43718
Binary files /dev/null and b/brand/profile/profile-400.png differ
diff --git a/brand/profile/profile-512.png b/brand/profile/profile-512.png
new file mode 100644
index 000000000..d6cd427e2
Binary files /dev/null and b/brand/profile/profile-512.png differ
diff --git a/brand/profile/x-banner-1500x500.png b/brand/profile/x-banner-1500x500.png
new file mode 100644
index 000000000..d749e4c4b
Binary files /dev/null and b/brand/profile/x-banner-1500x500.png differ
diff --git a/docs/brand/after-contact-sheet.png b/docs/brand/after-contact-sheet.png
new file mode 100644
index 000000000..8ad7c3add
Binary files /dev/null and b/docs/brand/after-contact-sheet.png differ
diff --git a/docs/brand/after-icns-and-favicon16.png b/docs/brand/after-icns-and-favicon16.png
new file mode 100644
index 000000000..934c65eb9
Binary files /dev/null and b/docs/brand/after-icns-and-favicon16.png differ
diff --git a/docs/brand/before/brand-igneum-coin-1024.png b/docs/brand/before/brand-igneum-coin-1024.png
new file mode 100644
index 000000000..ad4237650
Binary files /dev/null and b/docs/brand/before/brand-igneum-coin-1024.png differ
diff --git a/docs/brand/before/brand-igneum-icon-1024.png b/docs/brand/before/brand-igneum-icon-1024.png
new file mode 100644
index 000000000..6ab4be74f
Binary files /dev/null and b/docs/brand/before/brand-igneum-icon-1024.png differ
diff --git a/docs/brand/before/brand-igneum-icon-512.png b/docs/brand/before/brand-igneum-icon-512.png
new file mode 100644
index 000000000..4b0ca17ca
Binary files /dev/null and b/docs/brand/before/brand-igneum-icon-512.png differ
diff --git a/docs/brand/before/brand-mark-transparent-1024.png b/docs/brand/before/brand-mark-transparent-1024.png
new file mode 100644
index 000000000..29f691f5e
Binary files /dev/null and b/docs/brand/before/brand-mark-transparent-1024.png differ
diff --git a/docs/brand/before/contact-sheet-before.png b/docs/brand/before/contact-sheet-before.png
new file mode 100644
index 000000000..26282fa5d
Binary files /dev/null and b/docs/brand/before/contact-sheet-before.png differ
diff --git a/docs/brand/before/dmg-file-icon-finder-256.png b/docs/brand/before/dmg-file-icon-finder-256.png
new file mode 100644
index 000000000..9341b3462
Binary files /dev/null and b/docs/brand/before/dmg-file-icon-finder-256.png differ
diff --git a/docs/brand/before/dmg-volume-icon-256.png b/docs/brand/before/dmg-volume-icon-256.png
new file mode 100644
index 000000000..6976d2614
Binary files /dev/null and b/docs/brand/before/dmg-volume-icon-256.png differ
diff --git a/docs/brand/before/dmg-volume-icon-finder-256.png b/docs/brand/before/dmg-volume-icon-finder-256.png
new file mode 100644
index 000000000..a5bc285f6
Binary files /dev/null and b/docs/brand/before/dmg-volume-icon-finder-256.png differ
diff --git a/docs/brand/before/finder-before.png b/docs/brand/before/finder-before.png
new file mode 100644
index 000000000..b64e6c2cd
Binary files /dev/null and b/docs/brand/before/finder-before.png differ
diff --git a/docs/brand/before/icons-dmg-background.png b/docs/brand/before/icons-dmg-background.png
new file mode 100644
index 000000000..5b836c608
Binary files /dev/null and b/docs/brand/before/icons-dmg-background.png differ
diff --git a/docs/brand/before/icons-igneum-256.png b/docs/brand/before/icons-igneum-256.png
new file mode 100644
index 000000000..ada88e8a6
Binary files /dev/null and b/docs/brand/before/icons-igneum-256.png differ
diff --git a/docs/brand/before/icons-igneum-ico-256.png b/docs/brand/before/icons-igneum-ico-256.png
new file mode 100644
index 000000000..ada88e8a6
Binary files /dev/null and b/docs/brand/before/icons-igneum-ico-256.png differ
diff --git a/docs/brand/before/mac-app-icon-256.png b/docs/brand/before/mac-app-icon-256.png
new file mode 100644
index 000000000..6976d2614
Binary files /dev/null and b/docs/brand/before/mac-app-icon-256.png differ
diff --git a/docs/brand/before/mac-app-icon-finder-256.png b/docs/brand/before/mac-app-icon-finder-256.png
new file mode 100644
index 000000000..154f01901
Binary files /dev/null and b/docs/brand/before/mac-app-icon-finder-256.png differ
diff --git a/docs/brand/before/site-apple-touch-icon.png b/docs/brand/before/site-apple-touch-icon.png
new file mode 100644
index 000000000..b1323f2d5
Binary files /dev/null and b/docs/brand/before/site-apple-touch-icon.png differ
diff --git a/docs/brand/before/site-favicon-32-upscaled.png b/docs/brand/before/site-favicon-32-upscaled.png
new file mode 100644
index 000000000..6f72b7b01
Binary files /dev/null and b/docs/brand/before/site-favicon-32-upscaled.png differ
diff --git a/docs/brand/before/site-icon-192.png b/docs/brand/before/site-icon-192.png
new file mode 100644
index 000000000..0959cc485
Binary files /dev/null and b/docs/brand/before/site-icon-192.png differ
diff --git a/docs/brand/before/site-icon-512.png b/docs/brand/before/site-icon-512.png
new file mode 100644
index 000000000..24cd5aab6
Binary files /dev/null and b/docs/brand/before/site-icon-512.png differ
diff --git a/docs/brand/before/site-og-coin.png b/docs/brand/before/site-og-coin.png
new file mode 100644
index 000000000..ff8d98a6e
Binary files /dev/null and b/docs/brand/before/site-og-coin.png differ
diff --git a/docs/brand/before/site-og-small.png b/docs/brand/before/site-og-small.png
new file mode 100644
index 000000000..2be8c1c05
Binary files /dev/null and b/docs/brand/before/site-og-small.png differ
diff --git a/docs/brand/before/site-og-square.png b/docs/brand/before/site-og-square.png
new file mode 100644
index 000000000..ad4237650
Binary files /dev/null and b/docs/brand/before/site-og-square.png differ
diff --git a/packaging/mac/README.md b/packaging/mac/README.md
index 7a13850a6..06efbfbd6 100644
--- a/packaging/mac/README.md
+++ b/packaging/mac/README.md
@@ -15,7 +15,7 @@ Output: `packaging/mac/dist/Igneum-Miner-0.3.0.dmg` (about 20 MB, lzfse). The sc
same target), takes `igneumd` and `igneum-miner` from `vendor/igneum-node/target-integration/release` (the devnet-v4
integration build; `NODE=`, `MINER=`, `WORKER=`, `ENGINE=` override), strips and ad-hoc signs the copies, checks each
one runs, writes `igneum-app.json` (below) and lays the image out with `dmgbuild` (`pip3 install dmgbuild`; without it a
-plain hdiutil image). The icon is `brand/icons/igneum.icns`, the DMG art `brand/icons/dmg-background.tiff`
+plain hdiutil image). The app icon is `brand/icons/igneum.icns` (the master mark, a plain black square), the volume icon `brand/icons/igneum-volume.icns` (its rounded variant), the DMG art `brand/icons/dmg-background.tiff`
(`python3 brand/icons/make-icons.py`). `build/` and `dist/` are ignored by git.
## The bundle
diff --git a/packaging/mac/build-dmg.sh b/packaging/mac/build-dmg.sh
index a02efd07e..bf10816a8 100755
--- a/packaging/mac/build-dmg.sh
+++ b/packaging/mac/build-dmg.sh
@@ -1,6 +1,6 @@
#!/bin/bash
# Builds packaging/mac/dist/Igneum-Miner-.dmg: "Igneum Miner.app" + README.txt + "Stop Igneum Miner.command" +
-# a link to /Applications, on a branded image (volume "Igneum Miner", coin volume icon, background with the drag arrow,
+# a link to /Applications, on a branded image (volume "Igneum Miner", the rounded mark as the volume icon, background with the drag arrow,
# icons placed). 3 October 2026; 0.2.0 for devnet v4 on 4 October 2026; 0.3.0 the same day: the app (no Terminal).
#
# The bundle, 0.3.0:
@@ -11,13 +11,13 @@
# with -target arm64-apple-macos11 so it loads on any Apple silicon macOS)
# Contents/Resources/igneum-app.json the update manifest URL (token from ~/.config/igneum/dl-token, not in the repo),
# the log intake, the live page (packaged-config.sh)
-# Contents/Resources/igneum.icns
+# Contents/Resources/igneum.icns the master mark, a plain black square (brand/master/igneum-mark-square.svg; Tahoe masks it)
# Copies of the binaries are stripped and re-signed ad hoc (strip invalidates the linker signature and arm64 macOS
# refuses an unsigned binary); the originals are not touched.
#
# packaging/mac/build-dmg.sh build
# NODE= MINER= WORKER= ENGINE= use other binaries; REBUILD_WORKER=0 ships proto-metal/igneum-bench-hotswap
-# Needs: brand/icons/igneum.icns and dmg-background.tiff (python3 brand/icons/make-icons.py), swiftc, cargo (rustup), and
+# Needs: brand/icons/igneum.icns, igneum-volume.icns and dmg-background.tiff (python3 brand/icons/make-icons.py), swiftc, cargo (rustup), and
# dmgbuild (pip3 install dmgbuild) for the icon layout. Without dmgbuild a plain hdiutil image is built and said so.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
@@ -50,7 +50,7 @@ fi
for f in "$NODE" "$MINER"; do
file "$f" | grep -q 'arm64' || { echo "$f is not an arm64 binary"; exit 1; }
done
-[ -f "$ICONS/igneum.icns" ] || { echo "no $ICONS/igneum.icns; run: python3 brand/icons/make-icons.py"; exit 1; }
+for f in igneum.icns igneum-volume.icns; do [ -f "$ICONS/$f" ] || { echo "no $ICONS/$f; run: python3 brand/icons/make-icons.py"; exit 1; }; done
command -v swiftc >/dev/null 2>&1 || { echo "swiftc is needed for the window (xcode-select --install)"; exit 1; }
rm -rf "$BUILD"
@@ -126,7 +126,7 @@ if command -v dmgbuild >/dev/null 2>&1; then
else
echo "note: dmgbuild is not installed (pip3 install dmgbuild); building a plain image without icon positions or background"
ln -s /Applications "$STAGE/Applications"
- cp "$ICONS/igneum.icns" "$STAGE/.VolumeIcon.icns"
+ cp "$ICONS/igneum-volume.icns" "$STAGE/.VolumeIcon.icns"
hdiutil create -volname "Igneum Miner" -srcfolder "$STAGE" -ov -format ULFO -fs HFS+ "$DMG" >/dev/null
fi
hdiutil verify "$DMG" >/dev/null
diff --git a/packaging/mac/dmg/settings.py b/packaging/mac/dmg/settings.py
index 1594bacf8..1a6356e03 100644
--- a/packaging/mac/dmg/settings.py
+++ b/packaging/mac/dmg/settings.py
@@ -12,7 +12,8 @@ filesystem = 'HFS+'
size = None
files = [app, os.path.join(stage, 'README.txt'), os.path.join(stage, 'Stop Igneum Miner.command')]
symlinks = {'Applications': '/Applications'}
-icon = os.path.join(icons, 'igneum.icns') # the volume icon (.VolumeIcon.icns, hidden, custom-icon flag set)
+icon = os.path.join(icons, 'igneum-volume.icns') # the volume icon (.VolumeIcon.icns, hidden, custom-icon flag set): the rounded
+ # variant of the master mark; the app bundle itself carries the plain square igneum.icns
background = os.path.join(icons, 'dmg-background.tiff') if os.path.exists(os.path.join(icons, 'dmg-background.tiff')) else os.path.join(icons, 'dmg-background.png')
show_status_bar = False
show_tab_view = False
diff --git a/relay/apple-touch-icon.png b/relay/apple-touch-icon.png
new file mode 100644
index 000000000..2cdf07095
Binary files /dev/null and b/relay/apple-touch-icon.png differ
diff --git a/relay/favicon-32.png b/relay/favicon-32.png
new file mode 100644
index 000000000..a9e0f8afc
Binary files /dev/null and b/relay/favicon-32.png differ
diff --git a/relay/favicon.ico b/relay/favicon.ico
new file mode 100644
index 000000000..55b1028cb
Binary files /dev/null and b/relay/favicon.ico differ
diff --git a/relay/index.html b/relay/index.html
index c9876c45a..fe4b515f0 100644
--- a/relay/index.html
+++ b/relay/index.html
@@ -1 +1 @@
-Igneum relayigneum relay
+Igneum relayigneum relay
diff --git a/relay/ui.html b/relay/ui.html
index 8d231affd..c2957c2b5 100644
--- a/relay/ui.html
+++ b/relay/ui.html
@@ -6,7 +6,10 @@
Igneum relay
-
+
+
+
+
@@ -115,7 +118,7 @@ pre.code{color:var(--bone)}