168 lines
8.1 KiB
Plaintext
168 lines
8.1 KiB
Plaintext
---
|
|
export interface Props {
|
|
title: string;
|
|
description?: string;
|
|
schema?: string;
|
|
image?: string;
|
|
date?: string;
|
|
slug?: string;
|
|
ogType?: string;
|
|
}
|
|
const {
|
|
title, description = '', schema = '',
|
|
image = '', date = '', slug = '',
|
|
ogType = 'article',
|
|
} = Astro.props;
|
|
|
|
const baseUrl = 'https://нейросети.рус';
|
|
const pageUrl = slug ? `${baseUrl}/${slug}/` : baseUrl;
|
|
const ogImage = image || `${baseUrl}/og-image.svg`;
|
|
|
|
const articleSchema = slug ? JSON.stringify({
|
|
"@context": "https://schema.org",
|
|
"@type": "Article",
|
|
"headline": title,
|
|
"description": description || title,
|
|
"datePublished": date || new Date().toISOString().split('T')[0],
|
|
"image": image || undefined,
|
|
"url": `${baseUrl}/${slug}/`,
|
|
"author": { "@type": "Person", "name": "Никита Тарасов" },
|
|
"publisher": { "@type": "Organization", "name": "нейросети.рус" }
|
|
}) : '';
|
|
|
|
const orgSchema = JSON.stringify({
|
|
"@context": "https://schema.org",
|
|
"@type": "Organization",
|
|
"name": "нейросети.рус",
|
|
"url": baseUrl,
|
|
"description": "Витрина реальных результатов локальных open-source нейросетей: текст, графика, аудио, видео",
|
|
"sameAs": [
|
|
"https://tarasov.top",
|
|
],
|
|
});
|
|
---
|
|
<!DOCTYPE html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="robots" content="noindex, nofollow">
|
|
<title>{title}</title>
|
|
<meta name="description" content={description}>
|
|
<link rel="canonical" href={pageUrl}>
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
|
|
<!-- Pagefind search (файлы генерируются при pagefind --site dist после сборки) -->
|
|
<link href="/pagefind/pagefind-ui.css" rel="stylesheet" is:inline>
|
|
<script src="/pagefind/pagefind-ui.js" is:inline></script>
|
|
|
|
<!-- OpenGraph -->
|
|
<meta property="og:type" content={ogType}>
|
|
<meta property="og:title" content={title}>
|
|
<meta property="og:description" content={description}>
|
|
<meta property="og:url" content={pageUrl}>
|
|
<meta property="og:image" content={ogImage}>
|
|
<meta property="og:site_name" content="нейросети.рус">
|
|
<meta property="og:locale" content="ru_RU">
|
|
|
|
<!-- Twitter -->
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content={title}>
|
|
<meta name="twitter:description" content={description}>
|
|
|
|
<!-- Schema.org JSON-LD -->
|
|
{articleSchema && <script type="application/ld+json" set:html={articleSchema}></script>}
|
|
<script type="application/ld+json" set:html={orgSchema}></script>
|
|
|
|
<!-- Yandex.Metrika counter -->
|
|
<script type="text/javascript" is:inline>
|
|
(function(m,e,t,r,i,k,a){
|
|
m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
m[i].l=1*new Date();
|
|
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
|
|
})(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id=112350856', 'ym');
|
|
|
|
ym(112350856, 'init', {ssr:true, clickmap:true, ecommerce:"dataLayer", referrer: document.referrer, url: location.href, accurateTrackBounce:true, trackLinks:true});
|
|
</script>
|
|
<noscript><div><img src="https://mc.yandex.ru/watch/112350856" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
|
<!-- /Yandex.Metrika counter -->
|
|
|
|
<!-- UnoCSS (virtual:uno.css — генерируется @unocss/astro) -->
|
|
<style is:global>
|
|
:root{
|
|
--bg:#0d0f1a;
|
|
--text:#e6e8f0;
|
|
--muted:#9aa0b5;
|
|
--accent:#6d5efc;
|
|
--accent2:#38d9a9;
|
|
--card:#161a2a;
|
|
--card2:#1e2235;
|
|
--border:#2a2f45;
|
|
--radius:12px;
|
|
}
|
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--bg);color:var(--text);line-height:1.7}
|
|
|
|
/* Типографика контента (markdown) — остаётся в CSS, т.к. генерится из .md */
|
|
article{margin:32px 0;padding:32px;background:var(--card);border-radius:var(--radius);border:1px solid var(--border)}
|
|
article h1{font-size:32px;margin-bottom:16px;line-height:1.2;letter-spacing:-.5px}
|
|
article h2{font-size:22px;margin:28px 0 12px;color:var(--text)}
|
|
article h3{font-size:18px;margin:20px 0 8px;color:var(--accent2)}
|
|
article p{margin:10px 0;color:#cdd2e0}
|
|
article ul,article ol{margin:10px 0;padding-left:24px}
|
|
article li{margin:6px 0;color:#cdd2e0}
|
|
article strong{color:var(--text)}
|
|
article a{color:var(--accent2);text-decoration:none;border-bottom:1px solid transparent;transition:border-color .2s}
|
|
article a:hover{border-bottom-color:var(--accent2)}
|
|
article table{width:100%;border-collapse:collapse;margin:16px 0;font-size:14px}
|
|
article th,article td{border:1px solid var(--border);padding:8px 12px;text-align:left}
|
|
article th{background:var(--card2);color:var(--text)}
|
|
article td{color:#cdd2e0}
|
|
code{background:var(--card2);padding:2px 6px;border-radius:4px;font-size:.9em;color:#e0b0ff}
|
|
pre{background:var(--card2);padding:16px;border-radius:8px;overflow-x:auto;margin:16px 0;border:1px solid var(--border)}
|
|
pre code{background:none;padding:0;color:#c9d4ff}
|
|
|
|
/* Бейджи: модификаторы типов (класс "badge t" — два отдельных класса, UnoCSS не матчит) */
|
|
.badge.t{background:var(--accent)}.badge.i{background:#f72585}.badge.a{background:#38d9a9}.badge.v{background:#ff9f1c}
|
|
|
|
/* Pagefind UI — переопределение на тёмную тему */
|
|
.search-bar{position:relative}
|
|
.search-bar input{padding:7px 12px;border:1px solid var(--border);border-radius:8px;background:var(--card2);color:var(--text);width:220px;font-size:14px}
|
|
.search-bar input:focus{outline:none;border-color:var(--accent)}
|
|
.pagefind-ui__results{position:absolute;background:var(--card);border:1px solid var(--border);border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.4);z-index:100;margin-top:6px;max-height:360px;overflow-y:auto;width:300px}
|
|
.pagefind-ui__result{padding:10px 12px;border-bottom:1px solid var(--border)}
|
|
.pagefind-ui__result:last-child{border:none}
|
|
.pagefind-ui__result a{color:var(--accent2);font-weight:600;text-decoration:none}
|
|
.pagefind-ui__result p{font-size:12px;color:var(--muted);margin:2px 0}
|
|
.pagefind-ui__drawer{display:none !important}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container max-w-960px mx-auto px-20px">
|
|
<header class="py-20px border-b border-border">
|
|
<nav class="flex items-center gap-16px flex-wrap">
|
|
<a href="/" class="brand text-18px font-800 text-text tracking--0.5px">
|
|
🤖 нейросети<span class="text-accent">.рус</span>
|
|
</a>
|
|
<a href="/examples/" class="text-muted no-underline font-600 text-14px transition-colors hover:text-accent2">Примеры</a>
|
|
<a href="/models/" class="text-muted no-underline font-600 text-14px transition-colors hover:text-accent2">Модели</a>
|
|
<a href="/compare/" class="text-muted no-underline font-600 text-14px transition-colors hover:text-accent2">Сравнения</a>
|
|
<a href="/news/" class="text-muted no-underline font-600 text-14px transition-colors hover:text-accent2">Новости</a>
|
|
<a href="/guide/" class="text-muted no-underline font-600 text-14px transition-colors hover:text-accent2">Гайды</a>
|
|
<a href="/ace-studio/" class="text-muted no-underline font-600 text-14px transition-colors hover:text-accent2">Ace Studio</a>
|
|
<span class="ml-auto"></span>
|
|
<div class="search-bar" id="search"></div>
|
|
</nav>
|
|
</header>
|
|
<slot />
|
|
<footer class="text-center py-40px text-muted text-13px border-t border-border mt-40px">
|
|
<p>© 2026 нейросети.рус — витрина реальных результатов локальных open-source моделей</p>
|
|
</footer>
|
|
</div>
|
|
<script is:inline>
|
|
new PagefindUI({ element: "#search", showSubResults: false, showImages: false });
|
|
</script>
|
|
</body>
|
|
</html>
|