Archilyzer · Source

archilyzer

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

commit f1fc799bdeb45dbdeef8c8e3958a3f78761e42a2
parent dc34b4e4305f5edd6bf64fe05a0ae77327929426
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sat, 26 Sep 2026 02:05:54 -0400

plans: brand S4 approved — Archilyzer Media: M2 Signal mark, "flush · caps matched" lockup (MEDIA at 1.035x, measured), YouTube assets CLI, an opt-in umtool report-to-video preset with vendored OFL fonts; not part of the site rollout

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

Diffstat:
Mplans/brand-and-themes.md | 147+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 91 insertions(+), 56 deletions(-)

diff --git a/plans/brand-and-themes.md b/plans/brand-and-themes.md @@ -1256,59 +1256,94 @@ also writes the rollout scripts to `scripts/`); the release record is and the homepage (`pnpm --filter yt-dlp-transcript-common exec tsx bin/archilyzer.ts build homepage`, then `… deploy homepage`). `pnpm ops` needs `WORKER_TOKEN` from `editor/.env`. -## Proposed — Archilyzer Media, the YouTube channel (awaiting the operator's picks) - -Asked 2026-09-25: branding for **Archilyzer Media**, the operator's YouTube channel for the -videos. It is a new row on the canvas, "Archilyzer Media · the YouTube channel" (canvas -version 10), with three boards: *Media · mark + lockup*, *Media · the channel* and *Media · in -the video*. The generators are `gen.py` and `gen_media.py` beside the staging dir -(`node_modules/.brand-canvas/`); `gen_media.py` takes the live `canvas.json` it read as its -argument. - -**Open choices** (recommendation first): -- **Mark.** - - **M2 · Signal:** the parent mark, graphite and dim, with the found line and play head lit in - Signal `#5fa8a0`. - - **M1 · Bone:** the parent mark unchanged. - - At 40 px in a subscription list, bone on graphite reads as a blank grey avatar. Signal is - Archilyzer's own accent, so the channel speaks as the project rather than as any one site, - and it does not fight YouTube's red. -- **Lockup.** - - **Imprint:** the `Archi|lyzer` wordmark over a `MEDIA` tag (Plex Mono 500, tracked - 0.24em, in the accent). - - **Inline:** `Archi|lyzer Media`, with "Media" in the suffix weight. - -**The channel assets.** YouTube's specs were checked 2026-09-25. - -| Asset | Size | Design | -|---|---|---| -| Profile picture | 800×800 PNG, rendered as a 98 px circle | `markSvg` maskable (scale 0.8 keeps the farthest corner at 69% of the circle's radius) | -| Banner | 2560×1440 PNG ≤ 6 MB. Every device shows only the centre 1546×423; desktop shows 2560×423, tablet 1855×423 | A field of dim transcript lines wrapping around a clear safe area, the lockup centred in it, and one lit found line in the desktop strip | -| Watermark (Studio) | 150×150 PNG | `markSvg` any | -| Thumbnail template | 1280×720 | The still on the left; the headline (Archivo 118%, 800) and a found line on the right; the mark top-left; the bottom-right kept clear for YouTube's duration badge | - -**In the video** (`umtool/report-to-video`). -- **Today:** - - The cards are drawn with ImageMagick + Pango (`render-cards.mjs`), and the clip header - with ffmpeg `drawtext` (`build-video.mjs`). - - Colours come from the manifest's `render.palette`; fonts come from `render.fontRegular` / - `render.fontBold`. - - "Fira Sans" is the hardcoded default in `span()`. - - Nothing is burned in. -- **Proposed:** - - A `brand` preset: ground `#151b20`, fg `#e7edf1`, muted `#8496a2`, accent Signal. - - The mark leads the existing `Channel · title · date @ time` header. It is burned in, so - reposts keep it. - - A title card and an end card that carry the lockup, the end card with slots for the - end-screen elements. -- **Fonts:** this needs Archivo and IBM Plex installed as system fonts; neither is on this - machine. `ttf-ibm-plex` is in Arch's extra repo. Archivo's variable TTF comes from Google - Fonts, into `~/.local/share/fonts`. Pango takes `@wdth=118` variations. - -**Slice S4, after S1** (it reuses `markSvg` and S1's PNG renderer): -- `common/bin/brand-icons.ts --youtube <dir>` writes the profile picture, banner and watermark. - The banner's text needs Archivo at exactly 118%: a static instance (fontTools `instancer`) - for satori, or installed fonts for `rsvg-convert`. -- The umtool preset. -- The operator claims the handle and uploads the assets. +## S4 — Archilyzer Media, the YouTube channel (approved 2026-09-26) + +On 2026-09-25 the operator asked for branding for **Archilyzer Media**, their YouTube channel for +the videos, and approved the design on 2026-09-26. It is on the canvas (version 14): +https://claude.ai/artifact/UsUxwgRkP5a3m4jZXucAvG, in the row "Archilyzer Media · the YouTube +channel". The generators are `node_modules/.brand-canvas/{gen,gen_media}.py` in the primary checkout. + +S4 ships after release 10's cut and is **not part of the site rollout**: it touches only a CLI in +`common/bin` and umtool. + +### Decisions (operator, 2026-09-26) + +- **Mark M2 · Signal.** The parent mark's geometry, lit in Signal: ground `#151b20`, dim `#3f4c56`, + lit `#5fa8a0`. The avatar uses the maskable variant (scale 0.8 on full-bleed ground). +- **Lockup "flush · caps matched".** The `Archi|lyzer` wordmark sits over `MEDIA`: + - Both are Archivo at wdth 118. The wordmark is 720 / 380 at -0.01em; MEDIA is 700, in Signal. + - MEDIA's size is **1.035×** the wordmark's, and it is letter-spaced to exactly the wordmark's + width. + - Measured with fontTools on `Archivo[wdth,wght]`: "Archilyzer" is 5.334 em and "MEDIA" is + 3.953 em. So MEDIA's capitals match the wordmark's cap height (0.686 em), with 0.30 em between + letters. + - The mark's height equals the text block's (wordmark cap top to MEDIA baseline), about 1.70× the + wordmark size, with a 0.46× gap. + - On the banner at 2560 px: wordmark 124 px, MEDIA 128 px, text width 661, mark 210. The block + is centred on the safe area. +- **Unchanged from the proposal:** the banner (a field of dim transcript lines wrapping around a + clear gutter round the safe area, the lockup centred in it, one lit found line with a play head in + the desktop strip right of the safe area); the Studio watermark (`any` variant); the burned-in mark + leading the clip header; the title card, end card and thumbnail layouts of the *in the video* + board. + +### What S4 delivers + +1. **`common/lib/brandMedia.ts` (pure).** + - `MEDIA_PALETTE`, `MEDIA_RATIO = 1.035`. + - `mediaLockupSvg({px, palette})`: a standalone SVG with **the text as outlined paths**, so + rendering the lockup needs no font (rsvg-convert, satori `<img>`, ImageMagick). + - The outlines come from a checked-in, generated `common/lib/brandMediaGlyphs.ts` (do-not-edit + header): glyph paths and advances at wdth 118 for `Archi` 720, `lyzer` 380 and `MEDIA` 700, + plus kerning pairs if the font has them. + - The generator is `common/bin/gen-media-glyphs.py` (fontTools instancer; the repo already has + Python tools). It downloads `Archivo[wdth,wght].ttf` from google/fonts; the font is not + committed. +2. **The YouTube channel assets:** `common/bin/brand-media.ts --out <dir>`. The default dir is + `~/reports/archilyzer-media/brand/`. It writes, each with its SVG source: + - `avatar-800.png`; + - `watermark-150.png`, with transparent corners; + - `banner-2560x1440.png`, ≤ 6 MB; + - `banner-safe-1546x423.png`, the part every device shows. + + It also writes `INDEX.html` (operator rule: handoffs are HTML), with a preview of each asset, + its size, and the YouTube Studio upload steps: Customization → Branding → Picture / Banner + image / Video watermark. +3. **The umtool report-to-video brand preset: opt-in, and nothing else moves.** + - **How it's enabled:** a manifest opts in (e.g. `render.brand: "archilyzer-media"`). The preset + sets `render.palette` (bg `#151b20`, fg `#e7edf1`, muted `#8496a2`, accent `#5fa8a0`, amber + `#e3b15c`) and the fonts: Archivo at wdth 118 for display, Plex Sans for body, Plex Mono for + the header and meta lines. + - **Title card:** the lockup top-left; the title in Archivo 118% 720; the found line (play head + + lit bar) under it; a Plex Mono meta line. + - **Clip header:** the mark leads the existing `Channel · title · date @ time` header, burned in. + - **End card:** new, and only with the preset. The lockup and `archilyzer.pages.dev` on the + left; the right half kept clear for YouTube's end-screen elements (nothing drawn there). The + duration is configurable, default 20 s. + - **Thumbnail step:** 1280×720 from a clip still plus a headline, per the board. The mark is + top-left, and the bottom-right is kept clear for the duration badge. + - **Fonts are vendored (OFL), not system-installed.** Archivo variable, IBM Plex Sans and IBM + Plex Mono go under `umtool/report-to-video/fonts/` with `OFL.txt` and a `fonts.conf`. + - The preset points `FONTCONFIG_FILE` at that conf for its `magick`/`rsvg-convert` children. + - Pango takes `@wght=…,wdth=118` variations (Pango 1.58 here). + - ffmpeg `drawtext` takes `fontfile=` paths, and needs static fonts only. + - Fallback: `fonts/install-user-fonts.sh` into `~/.local/share/fonts`, which needs no sudo. + - **Surface:** if umtool has a render/project settings surface, the preset is a choice there + (operator rule: umtool evolves with the video); otherwise it is manifest-only, and the report + says so. + - **Hard rule: byte-identical when not opted in.** The live umtool (:3050) spawns + report-to-video scripts from disk, so a manifest that does not opt in must render + **byte-identical** cards before and after. Prove it on an existing manifest's cards. + +### Gates + +- tsc. +- Unit tests: common, editor, `test:scripts`, mcp, and the report-to-video tests. +- **The lockup's geometry:** the MEDIA advance equals the wordmark advance within 0.5%, and the + block sits inside the banner's safe area. +- **The PNGs:** the IHDR sizes are right, and the banner is ≤ 6 MB. +- **The before/after card diff** for a manifest that does not opt in. +- **A rendered sample:** title card, a clip header frame, end card and thumbnail for a small + fixture manifest. Look at each one. +- umtool e2e if umtool's code is touched (`SONG_DIR=~/reports/quartering-uh-song/data pnpm + --filter umtool run e2e`, queued).