diff --git a/public/icons/clock-icon-192.png b/public/icons/clock-icon-192.png new file mode 100644 index 0000000..b051c49 Binary files /dev/null and b/public/icons/clock-icon-192.png differ diff --git a/public/icons/clock-icon-512.png b/public/icons/clock-icon-512.png new file mode 100644 index 0000000..beac4b7 Binary files /dev/null and b/public/icons/clock-icon-512.png differ diff --git a/public/icons/clock-maskable-512.png b/public/icons/clock-maskable-512.png new file mode 100644 index 0000000..c04c1d7 Binary files /dev/null and b/public/icons/clock-maskable-512.png differ diff --git a/scripts/build-icons.mjs b/scripts/build-icons.mjs index a2a4af4..f4bbc9f 100644 --- a/scripts/build-icons.mjs +++ b/scripts/build-icons.mjs @@ -162,6 +162,126 @@ function chatMaskableSvg(size, fontPx) { `; } +// Non-maskable clock icon (192 and 512). Transparent background. +// Layout: orange clock ring with tick marks, cube mark as the centre +// hub, "CLOCK" wordmark underneath — same brand DNA as the dashboard +// and chat icons. +function clockSvg(size, fontPx) { + const cx = 256; + const cy = 190; + const r = 130; + + const cubeSize = 90; + const cubeX = cx - cubeSize / 2; + const cubeY = cy - cubeSize / 2; + + const wordY = 420; + + const ticks = []; + for (let i = 0; i < 12; i++) { + const angle = (i * Math.PI * 2) / 12; + const inner = r - 14; + const outer = r - 2; + const x1 = cx + inner * Math.sin(angle); + const y1 = cy - inner * Math.cos(angle); + const x2 = cx + outer * Math.sin(angle); + const y2 = cy - outer * Math.cos(angle); + ticks.push( + ``, + ); + } + + return ` + + + + + + + ${ticks.join("\n ")} + + + + + + + + + + + CLOCK + `; +} + +// Maskable variant — orange fills the whole canvas. Content lives +// inside the centre ~40% safe-zone (~205x205 inside a 512 canvas). +function clockMaskableSvg(size, fontPx) { + const scale = 205 / 512; + const offset = (512 - 205) / 2; + + const cx = offset + 102; + const cy = offset + 75; + const r = 55 * (scale / scale); // keep in the 205-wide safe zone + + const cubeSize = 38; + const cubeX = cx - cubeSize / 2; + const cubeY = cy - cubeSize / 2; + + const wordY = offset + 175; + + const ticks = []; + for (let i = 0; i < 12; i++) { + const angle = (i * Math.PI * 2) / 12; + const inner = r - 6; + const outer = r - 1; + const x1 = cx + inner * Math.sin(angle); + const y1 = cy - inner * Math.cos(angle); + const x2 = cx + outer * Math.sin(angle); + const y2 = cy - outer * Math.cos(angle); + ticks.push( + ``, + ); + } + + return ` + + + + + + + + + + ${ticks.join("\n ")} + + + + + + + + + + + CLOCK + `; +} + async function renderSvg(svg, outPath, size) { const buf = Buffer.from(svg); await sharp(buf, { density: 144 }) @@ -207,4 +327,14 @@ await renderAppleIcon( path.join(ROOT, "src/app/apple-icon.png"), ); +// MEGA Clock icon set (non-maskable 192/512, maskable 512) +await renderSvg(clockSvg(512, 80), path.join(ROOT, "public/icons/clock-icon-512.png"), 512); +await renderSvg(clockSvg(192, 30), path.join(ROOT, "public/icons/clock-icon-192.png"), 192); +await renderSvg(clockMaskableSvg(512, 38), path.join(ROOT, "public/icons/clock-maskable-512.png"), 512); + +await renderAppleIcon( + path.join(ROOT, "public/icons/clock-icon-512.png"), + path.join(ROOT, "src/app/clock/apple-icon.png"), +); + console.log("All icons rendered."); \ No newline at end of file diff --git a/src/app/clock/apple-icon.png b/src/app/clock/apple-icon.png new file mode 100644 index 0000000..d18491a Binary files /dev/null and b/src/app/clock/apple-icon.png differ