From dc2e33b3f9c533461590a0ed4c205fe3350cb546 Mon Sep 17 00:00:00 2001 From: 0thernet Date: Wed, 30 Sep 2026 15:42:44 -0400 Subject: [PATCH] fix: align favicons with the current header mark --- site/BRAND_ASSETS.md | 21 +++++++++------------ site/apple-touch-icon.png | Bin 7194 -> 6842 bytes site/favicon-48.png | Bin 2054 -> 1847 bytes site/favicon.svg | 2 +- site/generate-icons.ts | 30 ++++++++++++++++++++++++------ 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/site/BRAND_ASSETS.md b/site/BRAND_ASSETS.md index db57c9ac..95b5dc10 100644 --- a/site/BRAND_ASSETS.md +++ b/site/BRAND_ASSETS.md @@ -1,15 +1,12 @@ -# ALGAL header identity +# ALGAL website identity -The header preserves the three overlapping circles from `favicon.svg` at its -current 28px size. `algal-mark.svg` removes only the opaque rounded background -rectangle; its view box, circle coordinates, strokes, and group are unchanged. -The name and transparent mark share the released Design Kit metallic foil recipe. -The extracted original artwork remains visible when masks or forced colors -disable the decorative paint. The favicon itself is unchanged. +The favicon silhouette comes from the actual header mark, `algal-mark.svg`. Browser variants render it in pure white on transparency. Apple touch variants use the same white mark on black. The visible bounds are centered horizontally and vertically and fill the square on their longest axis, preserving the aspect ratio with no added padding. -- Original `favicon.svg` SHA-256: `340aad988f525145b7caf7545abf311fa5f52cf46c399f172bc948de437d4a88`. -- Transparent `algal-mark.svg` SHA-256: `c962e23d88fea8c8e4aa10ebadbad97af09d54d65b3ed3d63080eef94396a07b`. +Run `bun run generate:icons` to regenerate the SVG and PNG variants from `algal-mark.svg`. -The stylesheet and browser controller are build-only dependencies; the CLI keeps -its zero required runtime dependency contract. No product copy or page layout -is generated by Design Kit. +| File | Size | SHA-256 | +| --- | --- | --- | +| algal-mark.svg | SVG | `c962e23d88fea8c8e4aa10ebadbad97af09d54d65b3ed3d63080eef94396a07b` | +| favicon.svg | SVG | `75802f85fecb6d76c8507c8374b81875101b6dec4733154f4dadc34c3394b63e` | +| favicon-48.png | 48×48 | `19cf28dfd722aa94260e9d61e9f742336a62d68cfccd5013684368655a5721d0` | +| apple-touch-icon.png | 180×180 | `6b92c290b40a46c2dc8a570fd8d3f710f613ef59d1be85c79daa20148782e533` | diff --git a/site/apple-touch-icon.png b/site/apple-touch-icon.png index c05547d7244ec59f3b38679b9e1c25454b71e04f..b46d01b04f39620f7570c75e1ec7a25314de7ba0 100644 GIT binary patch literal 6842 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 literal 7194 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 diff --git a/site/favicon-48.png b/site/favicon-48.png index 76ced384febbefcbd593472018eee95bb1391c2f..22bd6f9ac140b1f39cc86da9bee5904ee097cfe5 100644 GIT binary patch delta 1833 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 + diff --git a/site/generate-icons.ts b/site/generate-icons.ts index b4bb23bf..81097e2e 100644 --- a/site/generate-icons.ts +++ b/site/generate-icons.ts @@ -1,15 +1,33 @@ -// Renders the SVG favicon into the PNG sizes that browsers, link unfurlers, -// and iOS home screens request. Run `bun run generate:icons` after editing -// site/favicon.svg and commit the PNGs beside it. +// Browser icons follow the current transparent header mark. Run +// `bun run generate:icons` and commit the SVG and PNG derivatives together. import { readFile, writeFile } from "node:fs/promises"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { Resvg } from "@resvg/resvg-js"; const siteDirectory = dirname(fileURLToPath(import.meta.url)); -const svg = await readFile(join(siteDirectory, "favicon.svg"), "utf8"); - +const source = await readFile(join(siteDirectory, "algal-mark.svg"), "utf8"); +const white = source.replace(/stroke="[^"]*"/gu, 'stroke="#ffffff"'); +const sample = new Resvg(white, { fitTo: { mode: "width", value: 2048 } }).render(); +const pixels = sample.pixels; +let left = sample.width, top = sample.height, right = -1, bottom = -1; +for (let y = 0; y < sample.height; y++) for (let x = 0; x < sample.width; x++) { + if (pixels[(y * sample.width + x) * 4 + 3]! > 0) { + left = Math.min(left, x); right = Math.max(right, x); + top = Math.min(top, y); bottom = Math.max(bottom, y); + } +} +if (right < left) throw new Error("The header mark is empty"); +const scale = sample.width / 32; +const side = Math.max(right - left + 1, bottom - top + 1) / scale; +const cx = (left + right + 1) / 2 / scale, cy = (top + bottom + 1) / 2 / scale; +const box = [cx - side / 2, cy - side / 2, side, side].join(" "); +const svg = white.replace('viewBox="0 0 32 32"', `viewBox="${box}"`); +await writeFile(join(siteDirectory, "favicon.svg"), svg); for (const [file, size] of [["favicon-48.png", 48], ["apple-touch-icon.png", 180]] as const) { - const png = new Resvg(svg, { fitTo: { mode: "width", value: size } }).render().asPng(); + const png = new Resvg(svg, { + fitTo: { mode: "width", value: size }, + ...(file === "apple-touch-icon.png" ? { background: "#000000" } : {}), + }).render().asPng(); await writeFile(join(siteDirectory, file), png); }