3ce9ab7bf1
Build and push image / build (push) Successful in 3m13s
Localized home pages (/es, /fr, /de, /it, /pt) with server-rendered intro, how-to-play and FAQ plus FAQPage/WebApplication JSON-LD and hreflang. Puzzle archive at /archive with answer pages (/puzzle/N) for past days only and replays (/play/N) that never touch stats or the daily streak. Challenge loop: shared results link back as /?challenge=<code> and the result screen shows a head-to-head verdict. Also adds robots.txt, sitemap.xml, the PWA manifest and icons, a compact share text with WhatsApp/X/copy channels, a next-puzzle countdown, the social-proof play counter and a spoiler-free /api/teaser for daily posting. Refs #1 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvQ1ErZNRUcWgCEkJ9uyrn
25 lines
1.0 KiB
JavaScript
25 lines
1.0 KiB
JavaScript
// Generates the PWA icons in public/ from public/favicon.svg using sharp
|
|
// (already available transitively via Next.js). Run: node scripts/generate-icons.mjs
|
|
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import path from "node:path";
|
|
import sharp from "sharp";
|
|
|
|
const root = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
const svg = readFileSync(path.join(root, "public", "favicon.svg"));
|
|
|
|
await sharp(svg).resize(192, 192).png().toFile(path.join(root, "public", "icon-192.png"));
|
|
await sharp(svg).resize(512, 512).png().toFile(path.join(root, "public", "icon-512.png"));
|
|
|
|
// Maskable variant: the artwork shrunk to ~72% on the brand background so the
|
|
// safe zone survives circular/squircle masks.
|
|
const inner = await sharp(svg).resize(368, 368).png().toBuffer();
|
|
await sharp({
|
|
create: { width: 512, height: 512, channels: 4, background: "#061b12" },
|
|
})
|
|
.composite([{ input: inner, gravity: "center" }])
|
|
.png()
|
|
.toFile(path.join(root, "public", "icon-maskable-512.png"));
|
|
|
|
console.log("icons written to public/");
|