a440160249
- SALES_STRATEGY.md: $1K/day plan (37 orders @ $27.50 AOV, 1,700 visits) - TRIPWIRE_FUNNEL.md: 7-email Mautic sequence + lead scoring - MONETIZATION.md: 9 monetization options for Nūr PWA (no ads, no registration) - EXECUTABLE_PLAN.md: MCP-executable automation plan - DAILY_OPS.md: daily KPI checklist (visits, orders, sends, recoveries) - scripts/: automation.py, mautic_setup.py, gumroad_setup.py, scout_scrape.py, analytics.py, crontab - quality_leads.json/.csv: 12 enriched Islamic-tech leads for Mautic import - content_queue.json: 10 SEO blog posts for Ghost - PWA: icons, sw.js, e2e + vitest coverage, generator scripts
84 lines
2.4 KiB
JavaScript
84 lines
2.4 KiB
JavaScript
const fs = require('fs');
|
|
const { createCanvas } = require('canvas');
|
|
|
|
// Simple icon generator using canvas
|
|
function createIcon(size) {
|
|
const canvas = createCanvas(size, size);
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Background gradient
|
|
const gradient = ctx.createLinearGradient(0, 0, size, size);
|
|
gradient.addColorStop(0, '#0f766e');
|
|
gradient.addColorStop(1, '#0d9488');
|
|
ctx.fillStyle = gradient;
|
|
ctx.fillRect(0, 0, size, size);
|
|
|
|
// Rounded corners
|
|
ctx.globalCompositeOperation = 'destination-in';
|
|
ctx.beginPath();
|
|
const radius = size * 0.2;
|
|
ctx.roundRect(0, 0, size, size, radius);
|
|
ctx.fill();
|
|
|
|
// Draw mosque silhouette
|
|
ctx.globalCompositeOperation = 'source-over';
|
|
ctx.fillStyle = 'white';
|
|
|
|
const cx = size / 2;
|
|
const scale = size / 512;
|
|
|
|
// Main dome
|
|
ctx.beginPath();
|
|
ctx.arc(cx, size * 0.45, size * 0.18, Math.PI, 0);
|
|
ctx.lineTo(cx + size * 0.18, size * 0.65);
|
|
ctx.lineTo(cx - size * 0.18, size * 0.65);
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
|
|
// Minaret left
|
|
ctx.fillRect(cx - size * 0.35, size * 0.35, size * 0.06, size * 0.35);
|
|
ctx.beginPath();
|
|
ctx.moveTo(cx - size * 0.38, size * 0.35);
|
|
ctx.lineTo(cx - size * 0.32, size * 0.28);
|
|
ctx.lineTo(cx - size * 0.26, size * 0.35);
|
|
ctx.fill();
|
|
|
|
// Minaret right
|
|
ctx.fillRect(cx + size * 0.29, size * 0.35, size * 0.06, size * 0.35);
|
|
ctx.beginPath();
|
|
ctx.moveTo(cx + size * 0.26, size * 0.35);
|
|
ctx.lineTo(cx + size * 0.32, size * 0.28);
|
|
ctx.lineTo(cx + size * 0.38, size * 0.35);
|
|
ctx.fill();
|
|
|
|
// Crescent moon
|
|
ctx.fillStyle = '#fef3c7';
|
|
ctx.beginPath();
|
|
ctx.arc(cx, size * 0.22, size * 0.06, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
ctx.globalCompositeOperation = 'destination-out';
|
|
ctx.beginPath();
|
|
ctx.arc(cx + size * 0.02, size * 0.22, size * 0.055, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
ctx.globalCompositeOperation = 'source-over';
|
|
|
|
return canvas.toBuffer('image/png');
|
|
}
|
|
|
|
const sizes = [192, 512];
|
|
sizes.forEach(size => {
|
|
const png = createIcon(size);
|
|
fs.writeFileSync(`public/icon-${size}.png`, png);
|
|
console.log(`Generated icon-${size}.png`);
|
|
});
|
|
|
|
// Also create a favicon.ico equivalent (32x32 PNG for modern browsers)
|
|
const favicon32 = createIcon(32);
|
|
fs.writeFileSync('public/favicon-32.png', favicon32);
|
|
console.log('Generated favicon-32.png');
|
|
|
|
// Apple touch icon
|
|
const appleTouch = createIcon(180);
|
|
fs.writeFileSync('public/apple-touch-icon.png', appleTouch);
|
|
console.log('Generated apple-touch-icon.png');
|