|
| 1 | +import sharp from 'sharp'; |
| 2 | +import { join, dirname } from 'path'; |
| 3 | +import { fileURLToPath } from 'url'; |
| 4 | + |
| 5 | +const __dirname = dirname(fileURLToPath(import.meta.url)); |
| 6 | +const outputPath = join(__dirname, '..', 'site', 'og-image.png'); |
| 7 | + |
| 8 | +const width = 1200; |
| 9 | +const height = 630; |
| 10 | + |
| 11 | +// Colors from the site's design system |
| 12 | +const bgColor = '#0A0A0B'; |
| 13 | +const textPrimary = '#F5F5F5'; |
| 14 | +const accent = '#F59E0B'; |
| 15 | +const textSecondary = '#A0A0A0'; |
| 16 | +const textTertiary = '#666666'; |
| 17 | + |
| 18 | +const svg = ` |
| 19 | +<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg"> |
| 20 | + <defs> |
| 21 | + <style> |
| 22 | + @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap'); |
| 23 | + </style> |
| 24 | + </defs> |
| 25 | +
|
| 26 | + <!-- Background --> |
| 27 | + <rect width="${width}" height="${height}" fill="${bgColor}"/> |
| 28 | +
|
| 29 | + <!-- Subtle grid pattern --> |
| 30 | + <pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse"> |
| 31 | + <rect width="40" height="40" fill="none"/> |
| 32 | + <rect width="1" height="1" x="0" y="0" fill="rgba(255,255,255,0.03)"/> |
| 33 | + </pattern> |
| 34 | + <rect width="${width}" height="${height}" fill="url(#grid)"/> |
| 35 | +
|
| 36 | + <!-- Top accent line --> |
| 37 | + <rect x="0" y="0" width="${width}" height="4" fill="${accent}"/> |
| 38 | +
|
| 39 | + <!-- Bottom accent line --> |
| 40 | + <rect x="0" y="${height - 4}" width="${width}" height="4" fill="${accent}"/> |
| 41 | +
|
| 42 | + <!-- Wordmark: "markup" in white + "R" in amber --> |
| 43 | + <text x="600" y="240" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif" font-size="96" font-weight="900" letter-spacing="-4"> |
| 44 | + <tspan fill="${textPrimary}">markup</tspan><tspan fill="${accent}">R</tspan> |
| 45 | + </text> |
| 46 | +
|
| 47 | + <!-- Tagline --> |
| 48 | + <text x="600" y="320" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif" font-size="32" font-weight="700" fill="${textPrimary}" letter-spacing="-1"> |
| 49 | + You see it. You say it. Your AI fixes it. |
| 50 | + </text> |
| 51 | +
|
| 52 | + <!-- Subtitle --> |
| 53 | + <text x="600" y="380" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif" font-size="22" font-weight="400" fill="${textSecondary}"> |
| 54 | + AI-ready developer feedback capture -- open source |
| 55 | + </text> |
| 56 | +
|
| 57 | + <!-- Decorative neo-brutalist border elements --> |
| 58 | + <!-- Left bracket --> |
| 59 | + <rect x="80" y="180" width="4" height="220" fill="${accent}" opacity="0.6"/> |
| 60 | + <rect x="80" y="180" width="24" height="4" fill="${accent}" opacity="0.6"/> |
| 61 | + <rect x="80" y="396" width="24" height="4" fill="${accent}" opacity="0.6"/> |
| 62 | +
|
| 63 | + <!-- Right bracket --> |
| 64 | + <rect x="${width - 84}" y="180" width="4" height="220" fill="${accent}" opacity="0.6"/> |
| 65 | + <rect x="${width - 104}" y="180" width="24" height="4" fill="${accent}" opacity="0.6"/> |
| 66 | + <rect x="${width - 104}" y="396" width="24" height="4" fill="${accent}" opacity="0.6"/> |
| 67 | +
|
| 68 | + <!-- Bottom info bar --> |
| 69 | + <rect x="0" y="${height - 80}" width="${width}" height="76" fill="rgba(255,255,255,0.03)"/> |
| 70 | + <line x1="0" y1="${height - 80}" x2="${width}" y2="${height - 80}" stroke="rgba(255,255,255,0.08)" stroke-width="1"/> |
| 71 | +
|
| 72 | + <!-- GitHub icon hint --> |
| 73 | + <text x="200" y="${height - 34}" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif" font-size="16" font-weight="600" fill="${textTertiary}"> |
| 74 | + github.com/eddiesanjuan/markupr |
| 75 | + </text> |
| 76 | +
|
| 77 | + <!-- Version badge --> |
| 78 | + <rect x="880" y="${height - 60}" width="80" height="28" rx="4" fill="rgba(245,158,11,0.15)" stroke="${accent}" stroke-width="2"/> |
| 79 | + <text x="920" y="${height - 40}" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif" font-size="14" font-weight="700" fill="${accent}"> |
| 80 | + v2.4.0 |
| 81 | + </text> |
| 82 | +
|
| 83 | + <!-- MIT badge --> |
| 84 | + <rect x="980" y="${height - 60}" width="60" height="28" rx="4" fill="rgba(255,255,255,0.05)" stroke="rgba(255,255,255,0.16)" stroke-width="2"/> |
| 85 | + <text x="1010" y="${height - 40}" text-anchor="middle" font-family="-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif" font-size="14" font-weight="600" fill="${textTertiary}"> |
| 86 | + MIT |
| 87 | + </text> |
| 88 | +</svg>`; |
| 89 | + |
| 90 | +async function generate() { |
| 91 | + try { |
| 92 | + await sharp(Buffer.from(svg)) |
| 93 | + .png() |
| 94 | + .toFile(outputPath); |
| 95 | + |
| 96 | + const metadata = await sharp(outputPath).metadata(); |
| 97 | + console.log(`OG image generated: ${outputPath}`); |
| 98 | + console.log(`Dimensions: ${metadata.width}x${metadata.height}`); |
| 99 | + console.log(`Format: ${metadata.format}`); |
| 100 | + console.log(`Size: ${(metadata.size || 0) / 1024} KB`); |
| 101 | + } catch (err) { |
| 102 | + console.error('Failed to generate OG image:', err); |
| 103 | + process.exit(1); |
| 104 | + } |
| 105 | +} |
| 106 | + |
| 107 | +generate(); |
0 commit comments