Files
hanzo.ai/film/face.mjs

47 lines
2.1 KiB
JavaScript

// The faces every film renders in, in ONE place.
//
// A film is a standalone HTML document a headless browser opens from disk, so it
// cannot reach a stylesheet in node_modules and must not reach the network — a
// render that waits on a font request is a render that ships a frame in the
// fallback face. Each film therefore carries the two woff2 files beside its
// index.html.
//
// The bytes are NOT kept in the repo. `install()` copies them out of the
// published `@hanzo/font` at compose time, so the package is the single source
// of the family and a film cannot drift from the site it advertises.
//
// `font-display: block`, not swap: the renderer captures frames from the first
// paint, and a swap would put the fallback face in the opening seconds.
import { copyFileSync, mkdirSync } from "node:fs";
import { createRequire } from "node:module";
import { dirname, join } from "node:path";
// `@hanzo/font/css` IS the package's plain-CSS entry, so resolving it lands in
// dist beside the fonts. The package.json itself is not an export.
const require = createRequire(import.meta.url);
const dist = dirname(require.resolve("@hanzo/font/css"));
const FILES = [
["zen-sans/Zen-Variable.woff2", "zen.woff2"],
["zen-mono/ZenMono-Variable.woff2", "zen-mono.woff2"],
];
/** Put the faces in `<dir>/assets`. Call it wherever a film writes its frame. */
export const install = (dir) => {
const assets = join(dir, "assets");
mkdirSync(assets, { recursive: true });
for (const [from, to] of FILES) {
copyFileSync(join(dist, "fonts", from), join(assets, to));
}
};
/** The @font-face rules, relative to the document that `install()` served. */
export const FACE = `
@font-face { font-family: "Zen"; src: url("./assets/zen.woff2") format("woff2"); font-weight: 100 900; font-display: block; }
@font-face { font-family: "Zen Mono"; src: url("./assets/zen-mono.woff2") format("woff2"); font-weight: 100 900; font-display: block; }`;
/** The stacks, so no film spells a family name of its own. */
export const SANS = `"Zen", ui-sans-serif, system-ui, sans-serif`;
export const MONO = `"Zen Mono", ui-monospace, SFMono-Regular, Menlo, monospace`;