// Render the app icons from public/favicon.svg. Run with: npm run icons import sharp from 'sharp'; import { readFileSync } from 'node:fs'; const svg = readFileSync(new URL('../public/favicon.svg', import.meta.url)); const out = (name) => new URL(`../public/icons/${name}`, import.meta.url).pathname; const night = { r: 11, g: 16, b: 32, alpha: 1 }; await sharp(svg, { density: 384 }).resize(192, 192).png().toFile(out('icon-192.png')); await sharp(svg, { density: 384 }).resize(512, 512).png().toFile(out('icon-512.png')); // iOS adds its own rounded corners and dislikes transparency: full-bleed square. await sharp(svg, { density: 384 }).resize(180, 180).flatten({ background: night }).png().toFile(out('apple-touch-icon.png')); // Maskable: the mark inside the 80% safe zone on a full-bleed background. const inner = await sharp(svg, { density: 384 }).resize(360, 360).png().toBuffer(); await sharp({ create: { width: 512, height: 512, channels: 4, background: night } }) .composite([{ input: inner, gravity: 'center' }]) .png() .toFile(out('icon-maskable-512.png')); console.log('Icons written to public/icons/');