food-market/src/food-market.public/scripts/og.mjs
nns d1176e0fb1 rebrand: публичный сайт ALL MARKET (лого, OG, тексты)
- Логотипы logo.svg/logo-light.svg/favicon.svg → готовые файлы ALL MARKET.
- OG-картинки 1200×630 перегенерированы: реальный логотип ALL MARKET на светлом
  фоне (og.mjs теперь вставляет PNG-лого вместо «F»-плашки). Футер домена
  food-market.kz оставлен (домены — отдельная задача).
- BaseLayout (title/og/twitter/JSON-LD), Logo.astro (alt, h-8), все .astro-страницы,
  блог/KB/legal-контент: «Food Market» → «ALL MARKET».
- Юрлицо (плейсхолдер ТОО) и домены не менялись.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 17:34:51 +05:00

96 lines
5.4 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.

import satori from 'satori'
import { Resvg } from '@resvg/resvg-js'
import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const FONTS = path.join(__dirname, 'fonts')
const OUT = path.resolve(__dirname, '..', 'public', 'og')
const interReg = await fs.readFile(path.join(FONTS, 'Inter-Regular.ttf'))
const interBold = await fs.readFile(path.join(FONTS, 'Inter-Bold.ttf'))
// Логотип ALL MARKET (готовый файл бренда, color на прозрачном). viewBox 3:1.
const logoPng = await fs.readFile(path.join(__dirname, 'allmarket-logo-color.png'))
const logoUri = `data:image/png;base64,${logoPng.toString('base64')}`
const pages = [
{ file: 'home.png', title: 'Программа учёта и касса для розничных магазинов в Казахстане', sub: 'Касса с торговыми весами, импорт каталога, ОФД РК. Бесплатно 90 дней.' },
{ file: 'pos.png', title: 'Касса для Windows с поддержкой торговых весов', sub: 'Установка за 5 минут. Офлайн-режим. Стандартное оборудование.' },
{ file: 'pricing.png', title: 'Прозрачные тарифы ALL MARKET', sub: 'От 5 000 ₸/мес. Все возможности на любом тарифе. 90 дней триал.' },
{ file: 'import.png', title: 'Перенесите каталог за один клик', sub: 'Excel, CSV, REST API. До 100 000 товаров. Бесплатно.' },
{ file: 'about.png', title: 'О ALL MARKET', sub: 'Программа учёта розничной торговли, созданная в Казахстане.' },
{ file: 'for-grocery.png', title: 'ALL MARKET для продуктового магазина', sub: 'Весовой товар, скоропорт, штрихкоды, ABC-анализ.' },
{ file: 'for-pharmacy.png', title: 'ALL MARKET для аптеки', sub: 'Серии, сроки годности, рецептурный отпуск, контроль ЛП.' },
{ file: 'for-cafe.png', title: 'ALL MARKET для кафе и общепита', sub: 'Модификаторы блюд, столики, печать на кухню.' },
{ file: 'for-alcohol.png', title: 'ALL MARKET для алкомаркета', sub: 'Акцизные марки, контроль времени продаж, маркировка.' },
{ file: 'for-clothing.png', title: 'ALL MARKET для магазина одежды', sub: 'Размерные сетки, цветовые матрицы, остатки по размерам.' },
{ file: 'for-household.png', title: 'ALL MARKET для дома и быта', sub: 'Гарантийные сроки, серийные номера, характеристики.' },
]
const tmpl = ({ title, sub }) => ({
type: 'div',
props: {
style: {
width: '1200px', height: '630px', display: 'flex', flexDirection: 'column',
justifyContent: 'space-between', padding: '64px',
background: 'linear-gradient(135deg, #FFFFFF 0%, #ECFDF5 100%)',
fontFamily: 'Inter',
},
children: [
// Logo (готовый файл бренда на светлом фоне)
{
type: 'img',
props: { src: logoUri, width: 300, height: 99 },
},
// Title + subtitle
{
type: 'div',
props: {
style: { display: 'flex', flexDirection: 'column', gap: '20px', maxWidth: '1000px' },
children: [
{ type: 'div', props: { style: { color: '#0F172A', fontSize: title.length > 60 ? '54px' : '64px', fontWeight: 700, lineHeight: 1.15 }, children: title } },
{ type: 'div', props: { style: { color: '#475569', fontSize: '28px', fontWeight: 400, lineHeight: 1.3 }, children: sub } },
],
},
},
// Footer
{
type: 'div',
props: {
style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' },
children: [
{ type: 'div', props: { style: { color: '#0F172A', fontSize: '20px', fontWeight: 700 }, children: 'food-market.kz' } },
{
type: 'div',
props: {
style: {
background: '#00B207', color: '#FFFFFF',
padding: '14px 28px', borderRadius: '10px', fontSize: '20px', fontWeight: 700,
},
children: 'Начать бесплатно →',
},
},
],
},
},
],
},
})
await fs.mkdir(OUT, { recursive: true })
for (const p of pages) {
const svg = await satori(tmpl(p), {
width: 1200, height: 630,
fonts: [
{ name: 'Inter', data: interReg, weight: 400, style: 'normal' },
{ name: 'Inter', data: interBold, weight: 700, style: 'normal' },
],
})
const png = new Resvg(svg, { fitTo: { mode: 'width', value: 1200 } }).render().asPng()
await fs.writeFile(path.join(OUT, p.file), png)
console.log('og →', p.file)
}
console.log('done')