larpaso-website/scripts/icons-bauen.mjs
Lara 58fc72b283 Less petrol on phones; logo-only share preview
On screens below 700px the offer band turns light (sand) and the process
section uses sand instead of sage, so phones show about half as much
petrol; desktop is unchanged. The share preview now shows only the
larpaso pill, small enough to survive a centred square crop, under a new
file name so link previews refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:11:05 +02:00

60 lines
2.6 KiB
JavaScript

// Baut Favicon, App-Icons und das Vorschaubild für geteilte Links aus den
// Marken-SVGs in public/. Aufruf: node scripts/icons-bauen.mjs
// Quelle des Favicons: das "la" auf Petrol aus dem Prototyp lara-webdesign.html.
import sharp from 'sharp';
import { readFileSync, writeFileSync } from 'node:fs';
const pub = (f) => new URL(`../public/${f}`, import.meta.url);
const papier = { r: 252, g: 250, b: 246, alpha: 1 };
const favicon = readFileSync(pub('favicon.svg'));
const logo = readFileSync(pub('logo.svg'));
const png = (svg, size) =>
sharp(svg, { density: 72 * Math.ceil(size / 100) * 4 }).resize(size, size).png().toBuffer();
// Transparente Icons
for (const size of [48, 96, 192, 512]) {
writeFileSync(pub(`icon-${size}.png`), await png(favicon, size));
}
// Apple-Icon braucht deckenden Grund (iOS füllt Transparenz schwarz)
const appleInner = await png(favicon, 148);
await sharp({ create: { width: 180, height: 180, channels: 4, background: papier } })
.composite([{ input: appleInner, gravity: 'center' }])
.png()
.toFile(new URL('../public/apple-touch-icon.png', import.meta.url).pathname.replace(/^\/(\w:)/, '$1'));
// favicon.ico mit 16/32/48 als PNG-Einträge
const sizes = [16, 32, 48];
const bufs = await Promise.all(sizes.map((s) => png(favicon, s)));
const header = Buffer.alloc(6 + 16 * sizes.length);
header.writeUInt16LE(0, 0);
header.writeUInt16LE(1, 2);
header.writeUInt16LE(sizes.length, 4);
let offset = header.length;
sizes.forEach((s, i) => {
const e = 6 + 16 * i;
header.writeUInt8(s, e);
header.writeUInt8(s, e + 1);
header.writeUInt16LE(1, e + 4);
header.writeUInt16LE(32, e + 6);
header.writeUInt32LE(bufs[i].length, e + 8);
header.writeUInt32LE(offset, e + 12);
offset += bufs[i].length;
});
writeFileSync(pub('favicon.ico'), Buffer.concat([header, ...bufs]));
// Vorschaubild für WhatsApp, Signal, Facebook, LinkedIn & Co. (1200 x 630).
// Nur die Pille mit "larpaso" (ohne WEBDESIGN), mittig und so schmal, dass sie
// auch dann ganz zu sehen ist, wenn ein Dienst das Bild auf ein Quadrat aus
// der Mitte zuschneidet (630 x 630 -> Pille höchstens ~560 breit).
const pille = Buffer.from(logo.toString('utf8').replace('viewBox="0 0 944 240"', 'viewBox="0 0 502 240"').replace(/width="\d+"\s*height="\d+"/, ''));
const logoPng = await sharp(pille, { density: 400 }).resize({ width: 540 }).png().toBuffer();
await sharp({ create: { width: 1200, height: 630, channels: 4, background: papier } })
.composite([{ input: logoPng, gravity: 'center' }])
.flatten({ background: papier })
.jpeg({ quality: 88 })
.toFile(new URL('../public/og-larpaso.jpg', import.meta.url).pathname.replace(/^\/(\w:)/, '$1'));
console.log('Icons gebaut.');