/**
* Renders the site icon (docs/07 §11) with headless Chrome.
* bun scripts/pwa-icons.ts → apps/web/public/favicon.svg + apps/web/public/icons/*.png
* One design (아케이드 게임기 + 천사 고리 + 반짝이) is the source of every icon:
* "any" icons keep rounded corners; maskable/apple icons are full-bleed
* (the OS applies its own mask) with the art shrunk into the safe circle.
*/
import { chromium } from 'playwright-core';
import { mkdirSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
const PUBLIC = join(import.meta.dir, '../apps/web/public');
const OUT = join(PUBLIC, 'icons');
mkdirSync(OUT, { recursive: true });
const INK = '#1e1b4b';
const DEFS = ``;
const star = (x: number, y: number, r: number, fill: string) =>
``;
const ART = [
// 천사 고리: "게임천국"
``,
// 게임 패드
``,
``,
``,
``,
``,
``,
// 반짝이
star(53, 11, 4.6, '#fde047'),
star(10.5, 14, 3, '#fff'),
star(54, 53, 3, '#fff'),
star(11, 54, 2.2, '#fde047'),
].join('');
const rounded = `\n`;
const fullBleed = ``;
writeFileSync(join(PUBLIC, 'favicon.svg'), rounded);
console.log('✓ favicon.svg');
const ICONS: [file: string, size: number, svg: string][] = [
['icon-192.png', 192, rounded],
['icon-512.png', 512, rounded],
['icon-maskable-512.png', 512, fullBleed],
['apple-touch-icon.png', 180, fullBleed],
];
const browser = await chromium.launch({ executablePath: process.env.CHROME ?? '/usr/bin/google-chrome', headless: true });
const page = await browser.newPage();
for (const [file, size, svg] of ICONS) {
await page.setViewportSize({ width: size, height: size });
await page.setContent(`${svg}`);
await page.screenshot({ path: join(OUT, file), omitBackground: true });
console.log(`✓ ${file}`);
}
await browser.close();