Files
anotherreflections-website-v2/scripts/build-og-image.mjs
striker 4319759d88 feat: OG-image, логотип, компактный hero, кнопка отзыва consent
- 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-ФЗ: отозвать должно быть так же просто, как дать)
- Описание Главного форума: «Архивный» → «Действующий форум проекта»
2026-05-21 02:14:49 +03:00

90 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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`);