- public/logo-mark.svg (знак, 512×512) и public/logo.svg (знак+надпись,
640×160). Копии для пользователя — E:/Projects/anotherreflections-logo*.{svg,png}
- public/og-image.png 1200×630 — тематический баннер с лого, заголовком
градиентом и подписью. og:image + twitter:summary_large_image в meta,
расшаривание в Telegram/VK/WhatsApp/Twitter получит превью
- scripts/build-og-image.mjs — пересоздание баннера через sharp (devdep)
- .hero.hero-compact — внутренние страницы /miry/, /kontakty/, /privacy/,
/category/* перешли на компактный hero (меньше padding, без курсивного
tagline). На главной hero остался прежний — entry point
- На /privacy/ кнопка «Отозвать согласие» — ставит ar-consent=deny
одним кликом (152-ФЗ: отозвать должно быть так же просто, как дать)
- Описание Главного форума: «Архивный» → «Действующий форум проекта»
90 lines
3.6 KiB
JavaScript
90 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
||
// Один раз: генерирует public/og-image.png 1200x630 для расшаривания
|
||
// в Telegram/VK/WhatsApp/Twitter. Требует `npm i -D sharp` (один раз).
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import { fileURLToPath } from 'node:url';
|
||
import sharp from 'sharp';
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||
const ROOT = path.resolve(__dirname, '..');
|
||
|
||
const SVG = `
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630">
|
||
<defs>
|
||
<radialGradient id="bg" cx="50%" cy="30%" r="70%">
|
||
<stop offset="0" stop-color="#1a1430"/>
|
||
<stop offset="0.7" stop-color="#07090f"/>
|
||
<stop offset="1" stop-color="#000000"/>
|
||
</radialGradient>
|
||
<linearGradient id="mark" x1="0" y1="0" x2="100%" y2="100%">
|
||
<stop offset="0" stop-color="#b794ff"/>
|
||
<stop offset="1" stop-color="#6c4ed4"/>
|
||
</linearGradient>
|
||
<linearGradient id="title" x1="0" y1="0" x2="0" y2="100%">
|
||
<stop offset="0" stop-color="#ffffff"/>
|
||
<stop offset="1" stop-color="#b794ff"/>
|
||
</linearGradient>
|
||
<!-- Звёзды -->
|
||
<radialGradient id="star" cx="50%" cy="50%" r="50%">
|
||
<stop offset="0" stop-color="#ffffff" stop-opacity="0.9"/>
|
||
<stop offset="1" stop-color="#ffffff" stop-opacity="0"/>
|
||
</radialGradient>
|
||
</defs>
|
||
|
||
<rect width="1200" height="630" fill="url(#bg)"/>
|
||
|
||
<!-- Stars -->
|
||
<circle cx="180" cy="110" r="1.5" fill="url(#star)"/>
|
||
<circle cx="320" cy="180" r="1" fill="url(#star)"/>
|
||
<circle cx="480" cy="80" r="1.2" fill="url(#star)"/>
|
||
<circle cx="720" cy="140" r="1" fill="url(#star)"/>
|
||
<circle cx="900" cy="90" r="1.6" fill="url(#star)"/>
|
||
<circle cx="1080" cy="200" r="1.2" fill="url(#star)"/>
|
||
<circle cx="160" cy="460" r="1" fill="url(#star)"/>
|
||
<circle cx="380" cy="540" r="1.2" fill="url(#star)"/>
|
||
<circle cx="620" cy="500" r="1" fill="url(#star)"/>
|
||
<circle cx="860" cy="540" r="1.6" fill="url(#star)"/>
|
||
<circle cx="1040" cy="460" r="1.2" fill="url(#star)"/>
|
||
|
||
<!-- Mark в центре -->
|
||
<g transform="translate(600 195) scale(3.6)">
|
||
<g transform="translate(-32 -32)">
|
||
<circle cx="32" cy="32" r="29" stroke="url(#mark)" stroke-width="1.2" opacity="0.45" fill="none"/>
|
||
<path d="M16 40 Q32 18 48 40" stroke="url(#mark)" stroke-width="1.6" stroke-linecap="round" fill="none"/>
|
||
<path d="M16 28 Q32 50 48 28" stroke="url(#mark)" stroke-width="1.6" stroke-linecap="round" fill="none" opacity="0.6"/>
|
||
<circle cx="32" cy="34" r="2" fill="#b794ff"/>
|
||
</g>
|
||
</g>
|
||
|
||
<!-- Title -->
|
||
<text x="600" y="430" font-family="Cormorant Garamond, Lora, Georgia, serif" font-size="92" font-weight="600" text-anchor="middle" fill="url(#title)" letter-spacing="-0.01em">
|
||
Иные Отражения
|
||
</text>
|
||
|
||
<!-- Tagline -->
|
||
<text x="600" y="490" font-family="Cormorant Garamond, Lora, Georgia, serif" font-size="28" font-style="italic" text-anchor="middle" fill="#a89bc4">
|
||
Ролевой проект по современной фантастике
|
||
</text>
|
||
|
||
<!-- Eyebrow -->
|
||
<text x="600" y="560" font-family="Inter, sans-serif" font-size="18" text-anchor="middle" fill="#8a93a8" letter-spacing="0.4em">
|
||
С 2006 ГОДА
|
||
</text>
|
||
</svg>
|
||
`;
|
||
|
||
const outPng = path.join(ROOT, 'public/og-image.png');
|
||
const outSvg = path.join(ROOT, 'public/og-image.svg');
|
||
|
||
fs.writeFileSync(outSvg, SVG.trim() + '\n', 'utf8');
|
||
console.log(`wrote ${outSvg}`);
|
||
|
||
await sharp(Buffer.from(SVG))
|
||
.resize(1200, 630)
|
||
.png({ compressionLevel: 9 })
|
||
.toFile(outPng);
|
||
|
||
const stat = fs.statSync(outPng);
|
||
console.log(`wrote ${outPng} — ${(stat.size / 1024).toFixed(1)} KB`);
|