Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit e4b6c190b4b2c03c97d3cda97cbdfb952b775a9c
parent fa6d4dce4828ac8be7c972fd26f18addb92377c6
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sat, 26 Sep 2026 03:21:56 -0400

common: brand-media's Studio steps say Customization → Profile (formerly Branding) → Change, as YouTube's help does today; the glyph file records the fontTools it was generated with, and its parity test skips, visibly, under another (S4 review)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mcommon/bin/brand-media.test.ts | 3++-
Mcommon/bin/brand-media.ts | 8++++----
Mcommon/bin/gen-media-glyphs.py | 5++++-
Mcommon/lib/brandMedia.test.ts | 16++++++++++++++--
Mcommon/lib/brandMediaGlyphs.ts | 4+++-
5 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/common/bin/brand-media.test.ts b/common/bin/brand-media.test.ts @@ -60,7 +60,8 @@ test("writeMediaAssets: every PNG at its IHDR size, the banner under 6 MB, sourc assert.ok(banner.byteLength <= BANNER_MAX_BYTES, `${banner.byteLength} B`); const html = await readFile(path.join(dir, "INDEX.html"), "utf8"); for (const r of rows) assert.ok(html.includes(`src="${r.png}"`), r.png); - for (const step of ["Customization", "Branding", "Picture", "Banner image", "Video watermark"]) { + // Studio's current page: Customization -> Profile (Branding was folded into it). + for (const step of ["Customization", "<b>Profile</b>", "Picture", "Banner image", "Video watermark", "<b>Change</b>"]) { assert.ok(html.includes(step), step); } } finally { diff --git a/common/bin/brand-media.ts b/common/bin/brand-media.ts @@ -171,10 +171,10 @@ ol li { margin: 6px 0; } <h2>Upload in YouTube Studio</h2> <ol> -<li>Open <a href="https://studio.youtube.com">YouTube Studio</a> signed in as the channel, then <b>Customization</b> → <b>Branding</b>.</li> -<li><b>Picture</b> → Upload → <code>avatar-800.png</code>. Keep the crop at the whole square; YouTube shows it as a circle.</li> -<li><b>Banner image</b> → Upload → <code>banner-2560x1440.png</code> (${kb(bannerBytes)}; YouTube takes up to 6 MB). Leave the crop at the default: the device preview should show the lockup centred, as in the safe-area picture below.</li> -<li><b>Video watermark</b> → Upload → <code>watermark-150.png</code>. Display time: <i>Entire video</i>.</li> +<li>Open <a href="https://studio.youtube.com">YouTube Studio</a> signed in as the channel, then <b>Customization</b> → <b>Profile</b> (formerly <i>Branding</i>). The picture, the banner and the watermark are all on that page (<a href="https://support.google.com/youtube/answer/10456525">YouTube Help: Manage your channel branding</a>).</li> +<li><b>Picture</b> → <b>Change</b> (<b>Upload</b> if the channel has none yet) → <code>avatar-800.png</code>. Keep the crop at the whole square; YouTube shows it as a circle.</li> +<li><b>Banner image</b> → <b>Change</b> (or <b>Upload</b>) → <code>banner-2560x1440.png</code> (${kb(bannerBytes)}; YouTube takes up to 6 MB). Leave the crop at the default: the device preview should show the lockup centred, as in the safe-area picture below.</li> +<li><b>Video watermark</b> → <b>Change</b> (or <b>Upload</b>) → <code>watermark-150.png</code>. Display time: <i>Entire video</i>.</li> <li><b>Publish</b> (top right). Changes can take a few minutes to show on the channel page.</li> </ol> diff --git a/common/bin/gen-media-glyphs.py b/common/bin/gen-media-glyphs.py @@ -32,6 +32,7 @@ import sys import tempfile import urllib.request +import fontTools from fontTools.pens.svgPathPen import SVGPathPen from fontTools.pens.transformPen import TransformPen from fontTools.ttLib import TTFont @@ -158,7 +159,8 @@ def render_ts(font_path): out = [ "// GENERATED by common/bin/gen-media-glyphs.py -- DO NOT EDIT. Re-run it instead:", "// python3 common/bin/gen-media-glyphs.py", - "// brandMedia.test.ts diffs this file against a fresh run.", + "// brandMedia.test.ts diffs this file against a fresh run -- under the fontTools version", + "// recorded below; another version may round the instancer differently, so the test skips.", "//", "// The Archilyzer Media lockup's letters as outlines: Archivo[wdth,wght].ttf pinned to", f"// wdth {WDTH}, one instance per run. Font units, y down, baseline at 0; `kerning[i]` is", @@ -186,6 +188,7 @@ def render_ts(font_path): ' font: "Archivo[wdth,wght].ttf",', f' sha256: "{sha}",', f" wdth: {WDTH},", + f' fontTools: "{fontTools.version}",', "} as const;", "", f"export const MEDIA_UNITS_PER_EM = {upem.pop()};", diff --git a/common/lib/brandMedia.test.ts b/common/lib/brandMedia.test.ts @@ -144,13 +144,25 @@ test("SVGs: well-formed roots, colours validated, the safe crop is a viewBox", ( }); // The glyph file is generated; a hand edit or a font swap without a re-run is a -// failure. Needs python3 + fontTools, which a test machine may not have. +// failure. Needs python3 + fontTools, which a test machine may not have -- and +// the SAME fontTools the file records: another version can round the +// instancer's outlines differently, which is not a stale file. Both skips say +// why in the test output. test("brandMediaGlyphs.ts is exactly what gen-media-glyphs.py writes", (t) => { - const probe = spawnSync("python3", ["-c", "import fontTools.varLib.instancer"], { stdio: "ignore" }); + const probe = spawnSync( + "python3", + ["-c", "import fontTools, fontTools.varLib.instancer; print(fontTools.version)"], + { encoding: "utf8" }, + ); if (probe.status !== 0) { t.skip("python3 with fontTools is not available"); return; } + const installed = probe.stdout.trim(); + if (installed !== MEDIA_GLYPH_SOURCE.fontTools) { + t.skip(`fontTools ${installed} is installed; brandMediaGlyphs.ts was generated with ${MEDIA_GLYPH_SOURCE.fontTools}`); + return; + } const fresh = execFileSync("python3", [path.join(REPO, "common/bin/gen-media-glyphs.py"), "--stdout"], { encoding: "utf8", maxBuffer: 1 << 24, diff --git a/common/lib/brandMediaGlyphs.ts b/common/lib/brandMediaGlyphs.ts @@ -1,6 +1,7 @@ // GENERATED by common/bin/gen-media-glyphs.py -- DO NOT EDIT. Re-run it instead: // python3 common/bin/gen-media-glyphs.py -// brandMedia.test.ts diffs this file against a fresh run. +// brandMedia.test.ts diffs this file against a fresh run -- under the fontTools version +// recorded below; another version may round the instancer differently, so the test skips. // // The Archilyzer Media lockup's letters as outlines: Archivo[wdth,wght].ttf pinned to // wdth 118, one instance per run. Font units, y down, baseline at 0; `kerning[i]` is @@ -28,6 +29,7 @@ export const MEDIA_GLYPH_SOURCE = { font: "Archivo[wdth,wght].ttf", sha256: "0e094a7d3c7c4c25cf1310c4b30014f1dae9332220b1c2c88f4fa996f0b05053", wdth: 118, + fontTools: "4.65.0", } as const; export const MEDIA_UNITS_PER_EM = 1000;