// Regenerates favicons, the small touch icons and placeholder screenshots.
// Run: bun run assets (placeholders never overwrite a file that already exists)
import sharp from 'sharp';
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
import { screens } from '../src/lib/screens.ts';
const root = new URL('..', import.meta.url).pathname;
const NIB =
'M330 340 C330 296 362 266 406 266 H618 C662 266 694 296 694 340 C694 448 646 528 598 600 C560 656 530 724 512 806 C494 724 464 656 426 600 C378 528 330 448 330 340 Z';
// Favicon: the app's nib on a flat tile (the full icon's filters are too heavy for 16px).
const favicon = ``;
writeFileSync(`${root}public/favicon.svg`, favicon);
for (const [file, size] of [['favicon-32.png', 32], ['apple-touch-icon.png', 180], ['icon-192.png', 192], ['icon-512.png', 512]] as const) {
await sharp(Buffer.from(favicon), { density: 384 }).resize(size, size).png().toFile(`${root}public/${file}`);
}
// Placeholder screenshots: 16:10 wireframes that say what to capture.
const esc = (s: string) => s.replace(/&/g, '&').replace(/ max) { out.push(line); line = w; } else line = (line + ' ' + w).trim();
}
return line ? [...out, line] : out;
}
function placeholder(name: string, capture: string, theme: 'dark' | 'light') {
const c = theme === 'dark'
? { ground: '#0e0e0f', island: '#161617', bar: 'rgba(255,255,255,.07)', ink: '#ececed', mute: '#a1a1a6', accent: '#e4ada5' }
: { ground: '#e7e7e9', island: '#fbfbfb', bar: 'rgba(0,0,0,.07)', ink: '#1c1c1e', mute: '#5c5c61', accent: '#b8695f' };
const lines = wrap(capture, 62).slice(0, 5);
const side = [0, 1, 2, 3, 4, 5, 6].map((i) => ``).join('');
const text = [0, 1, 2, 3].map((i) => ``).join('');
return ``;
}
mkdirSync(`${root}src/assets/screens`, { recursive: true });
for (const [name, spec] of Object.entries(screens)) {
for (const theme of ['dark', 'light'] as const) {
const path = `${root}src/assets/screens/${name}-${theme}.svg`;
// Real captures (see scripts/capture) win; don't recreate a placeholder they shadow.
const real = ['png', 'webp', 'jpg'].some((e) => existsSync(path.replace(/\.svg$/, `.${e}`)));
if (!real && !existsSync(path)) writeFileSync(path, placeholder(name, spec.capture, theme));
}
}
console.log('assets done');