/** * Icon Generator for Oikos PWA * Generates icons from docs/logo.svg * Sizes: 192px and 512px, both "any" and "maskable" variants * Maskable icons: full-bleed background, logo content stays within 80% safe zone * * Usage: node scripts/generate-icons.js * Dependencies: sharp (devDependency) */ import sharp from 'sharp'; import { mkdirSync } from 'node:fs'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ICONS_DIR = join(__dirname, '..', 'public', 'icons'); mkdirSync(ICONS_DIR, { recursive: true }); /** Logo SVG (any): rounded corners, gradient background */ function createLogoSvg(size) { return ` `; } /** Maskable logo SVG: full-bleed background (no rx), logo within safe zone */ function createMaskableLogoSvg(size) { return ` `; } /** Apple Touch Icon (180x180): same as any-icon */ function createAppleTouchSvg() { return createLogoSvg(180); } /** Favicon (32x32): simplified - just gradient background with house */ function createFaviconSvg() { return createLogoSvg(32); } const icons = [ { name: 'icon-192.png', size: 192, svg: createLogoSvg(192) }, { name: 'icon-512.png', size: 512, svg: createLogoSvg(512) }, { name: 'icon-maskable-192.png', size: 192, svg: createMaskableLogoSvg(192) }, { name: 'icon-maskable-512.png', size: 512, svg: createMaskableLogoSvg(512) }, { name: 'apple-touch-icon.png', size: 180, svg: createAppleTouchSvg() }, { name: 'favicon-32.png', size: 32, svg: createFaviconSvg() }, ]; for (const icon of icons) { const outputPath = join(ICONS_DIR, icon.name); await sharp(Buffer.from(icon.svg)) .png() .toFile(outputPath); console.log(` ✓ ${icon.name} (${icon.size}x${icon.size})`); } console.log('\nIcons generated in public/icons/');