feat(brand): актуальный фавикон по брендовому знаку
Старый favicon.svg (стилизованная «A» от скаффолдинга) заменён на оптимизированный для 16-32px вариант logo-mark: кривые-отражения + точка на тёмном фоне, тот же градиент #b794ff→#6c4ed4. - public/favicon.svg — новый 64×64 viewBox, утолщённые штрихи - public/favicon.ico — 32×32 (sharp → PNG-in-ICO) - public/apple-touch-icon.png — 180×180 для iOS - scripts/build-favicon.mjs + npm run build:favicon - BaseLayout: добавлены <link> на ico (fallback) и apple-touch-icon
This commit is contained in:
@@ -75,7 +75,9 @@ src/
|
|||||||
└── consts.ts (SITE_TITLE, WORLDS, ANALYTICS, CATEGORY_COLORS, plural())
|
└── consts.ts (SITE_TITLE, WORLDS, ANALYTICS, CATEGORY_COLORS, plural())
|
||||||
|
|
||||||
public/
|
public/
|
||||||
├── favicon.svg
|
├── favicon.svg (брендовый знак на тёмном фоне, оптимизирован под 16-32px)
|
||||||
|
├── favicon.ico (32×32 PNG-in-ICO, генерируется из favicon.svg)
|
||||||
|
├── apple-touch-icon.png (180×180 для iOS home screen)
|
||||||
├── logo.svg, logo-mark.svg
|
├── logo.svg, logo-mark.svg
|
||||||
├── og-image.png (1200×630 для расшаривания в TG/VK/Twitter)
|
├── og-image.png (1200×630 для расшаривания в TG/VK/Twitter)
|
||||||
├── og-image.svg (исходник)
|
├── og-image.svg (исходник)
|
||||||
@@ -86,7 +88,8 @@ public/
|
|||||||
|
|
||||||
scripts/
|
scripts/
|
||||||
├── migrate-wp.mjs (одноразовый: _wp-export.json → src/content/*.md)
|
├── migrate-wp.mjs (одноразовый: _wp-export.json → src/content/*.md)
|
||||||
└── build-og-image.mjs (sharp → public/og-image.png из SVG)
|
├── build-og-image.mjs (sharp → public/og-image.png из SVG)
|
||||||
|
└── build-favicon.mjs (sharp → public/favicon.ico + apple-touch-icon.png из favicon.svg; `npm run build:favicon`)
|
||||||
|
|
||||||
Dockerfile (multi-stage: node:22-alpine builds → nginx:1.29-alpine serves)
|
Dockerfile (multi-stage: node:22-alpine builds → nginx:1.29-alpine serves)
|
||||||
nginx.conf (gzip, кэш _astro/ 1y, MIME application/rss+xml для feed)
|
nginx.conf (gzip, кэш _astro/ 1y, MIME application/rss+xml для feed)
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"migrate": "node scripts/migrate-wp.mjs",
|
"migrate": "node scripts/migrate-wp.mjs",
|
||||||
"indexnow": "node scripts/indexnow.js"
|
"indexnow": "node scripts/indexnow.js",
|
||||||
|
"build:favicon": "node scripts/build-favicon.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/rss": "^4.0.12",
|
"@astrojs/rss": "^4.0.12",
|
||||||
|
|||||||
BIN
public/apple-touch-icon.png
Normal file
BIN
public/apple-touch-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 655 B After Width: | Height: | Size: 1.4 KiB |
@@ -1,9 +1,16 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
<defs>
|
||||||
<style>
|
<linearGradient id="fg" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse">
|
||||||
path { fill: #000; }
|
<stop offset="0" stop-color="#b794ff"/>
|
||||||
@media (prefers-color-scheme: dark) {
|
<stop offset="1" stop-color="#6c4ed4"/>
|
||||||
path { fill: #FFF; }
|
</linearGradient>
|
||||||
}
|
<radialGradient id="bg" cx="50%" cy="38%" r="65%">
|
||||||
</style>
|
<stop offset="0" stop-color="#1a1430"/>
|
||||||
|
<stop offset="1" stop-color="#07090f"/>
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="64" height="64" rx="12" fill="url(#bg)"/>
|
||||||
|
<path d="M14 40 Q32 16 50 40" stroke="url(#fg)" stroke-width="3.5" stroke-linecap="round" fill="none"/>
|
||||||
|
<path d="M14 28 Q32 52 50 28" stroke="url(#fg)" stroke-width="3" stroke-linecap="round" fill="none" opacity="0.7"/>
|
||||||
|
<circle cx="32" cy="34" r="3.2" fill="#d4b9ff"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 749 B After Width: | Height: | Size: 792 B |
28
scripts/build-favicon.mjs
Normal file
28
scripts/build-favicon.mjs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Генерирует public/favicon.ico (32x32 PNG-in-ICO, как у Astro по умолчанию)
|
||||||
|
// и public/apple-touch-icon.png (180x180) из public/favicon.svg.
|
||||||
|
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 svgPath = path.join(ROOT, 'public/favicon.svg');
|
||||||
|
const svg = fs.readFileSync(svgPath);
|
||||||
|
|
||||||
|
const targets = [
|
||||||
|
{ out: 'public/favicon.ico', size: 32 },
|
||||||
|
{ out: 'public/apple-touch-icon.png', size: 180 },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { out, size } of targets) {
|
||||||
|
const dst = path.join(ROOT, out);
|
||||||
|
await sharp(svg, { density: 384 })
|
||||||
|
.resize(size, size)
|
||||||
|
.png({ compressionLevel: 9 })
|
||||||
|
.toFile(dst);
|
||||||
|
const kb = (fs.statSync(dst).size / 1024).toFixed(1);
|
||||||
|
console.log(`wrote ${out} (${size}x${size}) — ${kb} KB`);
|
||||||
|
}
|
||||||
@@ -69,6 +69,8 @@ const jsonLd = [
|
|||||||
<meta name="theme-color" content="#07090f" />
|
<meta name="theme-color" content="#07090f" />
|
||||||
<link rel="canonical" href={canonical} />
|
<link rel="canonical" href={canonical} />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" sizes="32x32" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
|
|
||||||
<meta property="og:type" content={ogType} />
|
<meta property="og:type" content={ogType} />
|
||||||
<meta property="og:title" content={pageTitle} />
|
<meta property="og:title" content={pageTitle} />
|
||||||
|
|||||||
Reference in New Issue
Block a user