Archilyzer · Source

archilyzer

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

commit 02545df562a0da24327e90ad33a6f26e7110055e
parent 7982d433a32c69a43548d4a9ac8f6d0a98c45200
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Fri, 25 Sep 2026 21:27:03 -0400

export: the icons and favicon are rendered per build from the mark, lit with the site's accent (brand S1)

app/icons/[file]/route.ts and app/favicon.ico/route.ts are force-static GET
handlers (generateStaticParams over ICON_FILES, dynamicParams false), which
static export writes byte-for-byte to out/icons/<file> and out/favicon.ico.
lib/brand.ts iconPalette(): the parent mark on the hub, else the child ground
lit with resolveAccent(site.accent).dark. The committed public/icons/* and
app/favicon.ico are gone. The layout links ICON_METADATA (icon.svg first,
icon-32, 192, 512, apple). The manifest's theme_color is the dark base's
ground and its background_color the icon's ground, replacing the hex-only
parseAccent fallback (a named accent read as #2563eb), and it lists icon.svg
with sizes "any".

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

Diffstat:
Dexport/app/favicon.ico | 0
Aexport/app/favicon.ico/route.ts | 11+++++++++++
Aexport/app/icons/[file]/route.ts | 27+++++++++++++++++++++++++++
Mexport/app/layout.tsx | 11++++-------
Aexport/app/lib/brand.ts | 15+++++++++++++++
Mexport/app/manifest.ts | 30+++++++++++++++++-------------
Dexport/public/icons/apple-touch-icon.png | 0
Dexport/public/icons/icon-192.png | 0
Dexport/public/icons/icon-512.png | 0
Dexport/public/icons/icon.svg | 6------
Dexport/public/icons/maskable-512.png | 0
Dexport/public/icons/maskable.svg | 6------
12 files changed, 74 insertions(+), 32 deletions(-)

diff --git a/export/app/favicon.ico b/export/app/favicon.ico Binary files differ. diff --git a/export/app/favicon.ico/route.ts b/export/app/favicon.ico/route.ts @@ -0,0 +1,11 @@ +import { iconResponse, renderFaviconIco } from "yt-dlp-transcript-common/lib/brandIcons"; +import { iconPalette } from "../lib/brand"; + +// /favicon.ico: the mark at 16/32/48 in one PNG-payload ICO, for the browsers +// and crawlers that ask for it by name whatever <head> says. Static; written to +// out/favicon.ico at build. +export const dynamic = "force-static"; + +export async function GET() { + return iconResponse(await renderFaviconIco(iconPalette()), "image/x-icon"); +} diff --git a/export/app/icons/[file]/route.ts b/export/app/icons/[file]/route.ts @@ -0,0 +1,27 @@ +import { + ICON_FILES, + iconResponse, + renderIconFile, +} from "yt-dlp-transcript-common/lib/brandIcons"; +import { iconPalette } from "../../lib/brand"; + +// /icons/<file>: the site's icon set, rendered from the one mark at build time +// (common/lib/brandIcons.ts). Static: under `output: "export"` each listed file +// is written to out/icons/<file> byte-for-byte, and nothing else resolves. +// Never reads the request. +export const dynamic = "force-static"; +export const dynamicParams = false; + +export function generateStaticParams() { + return ICON_FILES.map((f) => ({ file: f.file })); +} + +export async function GET( + _req: Request, + { params }: { params: Promise<{ file: string }> }, +) { + const { file } = await params; + const out = await renderIconFile(file, iconPalette()); + if (!out) return new Response("Not found", { status: 404 }); + return iconResponse(out.body, out.contentType); +} diff --git a/export/app/layout.tsx b/export/app/layout.tsx @@ -4,6 +4,7 @@ import { ThemeScript } from "yt-dlp-transcript-common/components/ThemeScript"; import { ThemeProvider } from "yt-dlp-transcript-common/components/ThemeProvider"; import { QueryProvider } from "yt-dlp-transcript-common/components/QueryProvider"; import { parseAccent, siteAccentVars } from "yt-dlp-transcript-common/lib/accent"; +import { ICON_METADATA } from "yt-dlp-transcript-common/lib/brandIcons"; import { currentSite } from "./lib/site"; import { instanceMode, shipsPwa } from "./lib/mode"; import Header from "./components/Header"; @@ -42,13 +43,9 @@ export function generateMetadata(): Metadata { // (and registers the SW below). A dumb instance omits both — it stays // federatable JSON, but not independently installable. ...(shipsPwa() ? { manifest: "/manifest.webmanifest" } : {}), - icons: { - icon: [ - { url: "/icons/icon-192.png", sizes: "192x192", type: "image/png" }, - { url: "/icons/icon-512.png", sizes: "512x512", type: "image/png" }, - ], - apple: [{ url: "/icons/apple-touch-icon.png", sizes: "180x180" }], - }, + // Rendered per build by app/icons/[file]/route.ts: the site's accent, or + // the parent mark on the hub. + icons: ICON_METADATA, appleWebApp: { capable: true, statusBarStyle: "black-translucent", diff --git a/export/app/lib/brand.ts b/export/app/lib/brand.ts @@ -0,0 +1,15 @@ +import { ICON_PALETTES, type IconPalette } from "yt-dlp-transcript-common/lib/brand"; +import { siteIconPalette } from "yt-dlp-transcript-common/lib/brandIcons"; +import { currentSite } from "./site"; +import { instanceMode } from "./mode"; + +// The palette this build's icons and header mark are drawn in. The hub is the +// family's own tool, so it wears the parent mark — achromatic, like the +// homepage and the editor. Every archive site is lit with its own accent's +// on-dark value (the favicon keeps the SITE default; the header mark follows +// the reader's pick through --brand-mark). Server-only, like currentSite(). +export function iconPalette(): IconPalette { + return instanceMode() === "hub" + ? ICON_PALETTES.archilyzer + : siteIconPalette(currentSite().accent); +} diff --git a/export/app/manifest.ts b/export/app/manifest.ts @@ -1,22 +1,17 @@ import type { MetadataRoute } from "next"; -import { parseAccent } from "yt-dlp-transcript-common/lib/accent"; +import { BASE_GROUNDS } from "yt-dlp-transcript-common/lib/brand"; import { currentSite } from "./lib/site"; +import { iconPalette } from "./lib/brand"; // Web App Manifest → statically emitted as /manifest.webmanifest at build time -// (output: "export"). Per-site: name/description from currentSite(), theme_color -// from the site's brand accent (falls back to the base brand blue). Makes each -// deployed export site installable as a standalone PWA. Icons are the shared -// mark under public/icons (a per-site accent-tinted icon is a later -// refinement — theme_color already differentiates the browser chrome). +// (output: "export"). Per-site: name/description from currentSite(). Makes each +// deployed export site installable as a standalone PWA. The icons are this +// build's own — the site's accent, or the parent mark on the hub — rendered by +// app/icons/[file]/route.ts. export const dynamic = "force-static"; -// Base brand blue (tokens.css --brand), used when a site sets no accent — the -// export default family is base. -const FALLBACK_THEME_COLOR = "#2563eb"; - export default function manifest(): MetadataRoute.Manifest { const site = currentSite(); - const themeColor = parseAccent(site.accent) ?? FALLBACK_THEME_COLOR; return { name: site.siteTitle, short_name: site.headerTitle || site.siteTitle, @@ -26,10 +21,19 @@ export default function manifest(): MetadataRoute.Manifest { display: "standalone", // No `orientation` lock: the archive is mostly video, and landscape is the // right shape for the player view. - background_color: "#0a0a0a", - theme_color: themeColor, + // The splash is the icon's own ground, so the mark sits on its tile's + // colour; the installed app's chrome is the dark base's ground. Neither is + // the accent: a reader may pick another, and the manifest cannot follow. + background_color: iconPalette().ground, + theme_color: BASE_GROUNDS.dark, icons: [ { + src: "/icons/icon.svg", + sizes: "any", + type: "image/svg+xml", + purpose: "any", + }, + { src: "/icons/icon-192.png", sizes: "192x192", type: "image/png", diff --git a/export/public/icons/apple-touch-icon.png b/export/public/icons/apple-touch-icon.png Binary files differ. diff --git a/export/public/icons/icon-192.png b/export/public/icons/icon-192.png Binary files differ. diff --git a/export/public/icons/icon-512.png b/export/public/icons/icon-512.png Binary files differ. diff --git a/export/public/icons/icon.svg b/export/public/icons/icon.svg @@ -1,6 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="Archive"> - <rect width="512" height="512" rx="112" fill="#0c0a08"/> - <polygon points="256,92 420,256 256,420 92,256" fill="#e3b15c"/> - <polygon points="256,150 362,256 256,362 150,256" fill="#0c0a08"/> - <polygon points="256,196 316,256 256,316 196,256" fill="#e3b15c"/> -</svg> diff --git a/export/public/icons/maskable-512.png b/export/public/icons/maskable-512.png Binary files differ. diff --git a/export/public/icons/maskable.svg b/export/public/icons/maskable.svg @@ -1,6 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="Archive"> - <rect width="512" height="512" fill="#0c0a08"/> - <polygon points="256,140 372,256 256,372 140,256" fill="#e3b15c"/> - <polygon points="256,182 330,256 256,330 182,256" fill="#0c0a08"/> - <polygon points="256,214 298,256 256,298 214,256" fill="#e3b15c"/> -</svg>