Files
Spendlight/web/scripts/make-icons.mjs
Chris Olson c3cf0f3eb8 Milestones 0 and 1: foundation and money in (20261007.10)
Foundation: single arm64 container (Hono + SQLite via Drizzle, React + Vite),
local sign-in with long-lived sessions and passkeys, roles (read-only, full
access, admin), nightly and pre-upgrade backups, light and dark themes,
date-based version numbers, and the ideas lightbulb behind IDEAS_ENABLED.

Money in: accounts with balances, CSV import with bank detection, a column
mapping pop-up for unknown layouts, duplicate checks, transfer pairing and
undo; one-tap review with learned rules; activity with search, splits, tags,
notes and cash entries. Statement files are blocked from commits by a
pre-commit hook; tests use synthetic fixtures only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 19:52:07 -04:00

20 lines
1.1 KiB
JavaScript

// 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/');