Files
site-servaki-online/reference/original.html
T

1677 lines
115 KiB
HTML
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.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>servaki.online — IT-поддержка для бизнеса на Юге России | Ваш IT-отдел на орбите</title>
<!-- SEO -->
<meta name="description" content="servaki.online — удалённая IT-поддержка для малого бизнеса на Юге России: обслуживание компьютеров, сетей и серверов. Реакция от 15 минут, мониторинг 24/7, тарифы от 3000 ₽. Работаем с HoReCa, агросектором и строительством — мы рядом, даже если между нами горы." />
<meta name="keywords" content="servaki.online, IT-поддержка, аутсорсинг ИТ, удалённая поддержка, IT-отдел на орбите, обслуживание компьютеров, настройка сетей, VPN, WireGuard, ZeroTier, Keenetic, видеонаблюдение, серверы, Proxmox, Docker, 1С, Telegram-боты, HoReCa, агросектор, строительство, Юг России, Ставропольский край, КМВ, Кавказ, мониторинг 24/7, SLA" />
<meta name="author" content="servaki.online" />
<meta name="robots" content="index, follow, max-image-preview:large" />
<meta name="theme-color" content="#070b18" />
<link rel="canonical" href="https://servaki.online/" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="servaki.online" />
<meta property="og:locale" content="ru_RU" />
<meta property="og:title" content="servaki.online — Ваш IT-отдел на орбите" />
<meta property="og:description" content="Удалённая IT-поддержка для бизнеса на Юге России. Реакция от 15 минут, мониторинг 24/7, тарифы от 3000 ₽. HoReCa, агросектор, строительство." />
<meta property="og:url" content="https://servaki.online/" />
<meta property="og:image" content="https://servaki.online/og-cover.png" />
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="servaki.online — Ваш IT-отдел на орбите" />
<meta name="twitter:description" content="Удалённая IT-поддержка для бизнеса на Юге России. Реакция от 15 минут, мониторинг 24/7, тарифы от 3000 ₽." />
<meta name="twitter:image" content="https://servaki.online/og-cover.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
<!-- JSON-LD: structured data for search engines and AI -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://servaki.online/#organization",
"name": "servaki.online",
"alternateName": "Ваш IT-отдел на орбите",
"url": "https://servaki.online/",
"slogan": "Ваш IT-отдел на орбите",
"description": "Удалённая IT-поддержка для малого и среднего бизнеса на Юге России: обслуживание компьютеров, сетей и серверов, видеонаблюдение, мониторинг 24/7.",
"areaServed": [
{ "@type": "AdministrativeArea", "name": "Юг России" },
{ "@type": "AdministrativeArea", "name": "Ставропольский край" },
{ "@type": "AdministrativeArea", "name": "Кавказские Минеральные Воды" }
],
"knowsAbout": ["IT-поддержка", "Компьютерные сети", "VPN", "Серверы", "Видеонаблюдение", "Автоматизация бизнеса"],
"contactPoint": [
{
"@type": "ContactPoint",
"telephone": "+79620151414",
"contactType": "customer support",
"availableLanguage": ["Russian"],
"areaServed": "RU",
"url": "https://t.me/servaki_online"
}
],
"telephone": "+79620151414",
"sameAs": ["https://t.me/servaki_online"]
},
{
"@type": "WebSite",
"@id": "https://servaki.online/#website",
"url": "https://servaki.online/",
"name": "servaki.online",
"inLanguage": "ru-RU",
"publisher": { "@id": "https://servaki.online/#organization" }
},
{
"@type": "Service",
"@id": "https://servaki.online/#service",
"serviceType": "Удалённая IT-поддержка бизнеса",
"name": "IT-поддержка для бизнеса на Юге России",
"provider": { "@id": "https://servaki.online/#organization" },
"areaServed": "Юг России",
"audience": { "@type": "BusinessAudience", "name": "HoReCa, агросектор, строительство, малый и средний бизнес" },
"description": "Удалённое обслуживание компьютеров, сетей и серверов, видеонаблюдение, мониторинг и автоматизация. Реакция от 15 минут, мониторинг 24/7.",
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Услуги servaki.online",
"itemListElement": [
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Удалённый рабочий стол — диагностика ПК, ПО, драйверы, принтеры" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Сети и VPN — объединение офисов и складов (WireGuard, ZeroTier, Keenetic)" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Мониторинг и безопасность — контроль серверов, бэкапы, антивирус" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Видеонаблюдение — IP-камеры, регистраторы, проектирование трасс" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Серверы и хостинг — Proxmox, Docker, почта, чаты, CRM, 1С" } },
{ "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Автоматизация — Telegram-боты, интеграции с кассами" } }
]
}
},
{
"@type": "Product",
"@id": "https://servaki.online/#plans",
"name": "Тарифы IT-поддержки servaki.online",
"brand": { "@id": "https://servaki.online/#organization" },
"description": "Подписки на удалённую IT-поддержку с фиксированной ценой: Старт, Бизнес, Премиум.",
"offers": [
{
"@type": "Offer",
"name": "Старт",
"description": "1–3 рабочих места, отклик до 2 часов, без выездов.",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "3000",
"priceCurrency": "RUB",
"unitText": "месяц",
"billingIncrement": 1
},
"availability": "https://schema.org/InStock",
"url": "https://servaki.online/#pricing"
},
{
"@type": "Offer",
"name": "Бизнес",
"description": "До 10 рабочих мест, отклик 30 минут, 1 выезд в месяц.",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "7000",
"priceCurrency": "RUB",
"unitText": "месяц",
"billingIncrement": 1
},
"availability": "https://schema.org/InStock",
"url": "https://servaki.online/#pricing"
},
{
"@type": "Offer",
"name": "Премиум",
"description": "Без ограничений по местам, отклик 15 минут, 4 выезда в месяц, выделенный специалист, видеонаблюдение, бэкапы, мониторинг 24/7 и приоритет.",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"price": "15000",
"priceCurrency": "RUB",
"unitText": "месяц",
"billingIncrement": 1
},
"availability": "https://schema.org/InStock",
"url": "https://servaki.online/#pricing"
}
]
},
{
"@type": "BreadcrumbList",
"@id": "https://servaki.online/#breadcrumbs",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Главная", "item": "https://servaki.online/" },
{ "@type": "ListItem", "position": 2, "name": "О нас", "item": "https://servaki.online/#about" },
{ "@type": "ListItem", "position": 3, "name": "Услуги", "item": "https://servaki.online/#services" },
{ "@type": "ListItem", "position": 4, "name": "Отрасли", "item": "https://servaki.online/#industries" },
{ "@type": "ListItem", "position": 5, "name": "Тарифы", "item": "https://servaki.online/#pricing" },
{ "@type": "ListItem", "position": 6, "name": "Галерея", "item": "https://servaki.online/#gallery" },
{ "@type": "ListItem", "position": 7, "name": "Связаться", "item": "https://servaki.online/#contacts" }
]
}
]
}
</script>
<style>
:root{
--space-900:#05070f;
--space-800:#080c1a;
--space-700:#0c1326;
--panel:#0f1730;
--panel-2:#121b38;
--line:rgba(255,255,255,.10);
--line-2:rgba(255,255,255,.16);
--text:#eef2ff;
--muted:#9fb0d6;
--muted-2:#7f92bd;
--cyan:#22d3ee;
--blue:#3b82f6;
--violet:#8b5cf6;
--mint:#5eead4;
--radius:18px;
--radius-lg:24px;
--max:1200px;
--ease:cubic-bezier(.16,.84,.44,1);
--shadow:0 20px 50px rgba(0,0,0,.45);
--glow-cyan:0 0 0 1px rgba(34,211,238,.30), 0 12px 40px rgba(34,211,238,.18);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%}
body{
margin:0;
font-family:"Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
color:var(--text);
background:var(--space-900);
line-height:1.6; font-size:16px; overflow-x:hidden;
position:relative;
}
/* global cosmic backdrop */
body::before{
content:""; position:fixed; inset:0; z-index:-2; pointer-events:none;
background:
radial-gradient(1000px 700px at 82% -6%, rgba(139,92,246,.24), transparent 58%),
radial-gradient(1100px 800px at 8% 4%, rgba(59,130,246,.22), transparent 55%),
radial-gradient(900px 700px at 50% 108%, rgba(34,211,238,.14), transparent 60%),
linear-gradient(180deg, var(--space-900), var(--space-800) 45%, var(--space-900));
}
#stars{position:fixed; inset:0; z-index:-1; pointer-events:none; opacity:.7}
h1,h2,h3,h4,.brand-name,.stat .num,.price .amount{font-family:"Space Grotesk","Inter",system-ui,sans-serif; letter-spacing:-.02em; line-height:1.12; font-weight:700}
a{color:inherit; text-decoration:none}
img{max-width:100%; display:block}
svg{max-width:100%; height:auto}
.container{max-width:var(--max); margin:0 auto; padding:0 24px}
@media (max-width:560px){ .container{padding:0 18px} }
.grad-text{background:linear-gradient(100deg,#7cf3e0,#63a4ff 48%,#b79bff); -webkit-background-clip:text; background-clip:text; color:transparent}
/* ============ NAV ============ */
.nav{position:sticky; top:0; z-index:100; transition:background .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
background:rgba(6,9,18,.55); backdrop-filter:saturate(160%) blur(14px); -webkit-backdrop-filter:saturate(160%) blur(14px);
border-bottom:1px solid transparent;}
.nav.scrolled{background:rgba(6,9,18,.82); border-bottom-color:var(--line); box-shadow:0 8px 30px rgba(0,0,0,.4)}
.nav-inner{display:flex; align-items:center; justify-content:space-between; gap:18px; padding:13px 0}
.brand{display:flex; align-items:center; gap:12px}
.logo{width:40px; height:40px; border-radius:12px; flex:none; position:relative; display:grid; place-items:center;
background:radial-gradient(circle at 30% 30%, #22d3ee, #3b82f6 55%, #8b5cf6); box-shadow:0 8px 24px rgba(59,130,246,.5)}
.logo .ring{position:absolute; inset:-5px; border-radius:50%; border:1.5px solid rgba(124,243,224,.55); border-top-color:transparent; border-right-color:transparent; animation:spin 6s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.logo b{color:#04122e; font-family:"Space Grotesk"; font-weight:700; font-size:15px; position:relative; z-index:2}
.brand-name{font-size:16px; color:#fff}
.brand-name small{display:block; font-family:"Inter"; font-weight:500; font-size:11px; letter-spacing:.05em; color:var(--muted); text-transform:none}
.menu{display:flex; align-items:center; gap:3px}
.menu a{color:var(--muted); font-weight:500; font-size:14.5px; padding:9px 13px; border-radius:11px; position:relative; transition:color .2s, background .2s}
.menu a:hover{color:#fff; background:rgba(255,255,255,.06)}
.menu a.active{color:#fff}
.menu a.active::after{content:""; position:absolute; left:13px; right:13px; bottom:3px; height:2px; border-radius:2px; background:linear-gradient(90deg,var(--cyan),var(--violet))}
.cta{background:linear-gradient(135deg,var(--cyan),var(--blue)); color:#04122e !important; font-weight:700; padding:10px 17px !important; border-radius:12px !important;
box-shadow:0 10px 26px rgba(34,211,238,.30); white-space:nowrap; transition:transform .2s var(--ease), box-shadow .2s}
.cta:hover{transform:translateY(-2px); box-shadow:0 16px 34px rgba(34,211,238,.45); background:linear-gradient(135deg,var(--cyan),var(--blue)) !important; color:#04122e !important}
.cta::after{display:none !important}
.nav-toggle{display:none; background:rgba(255,255,255,.05); border:1px solid var(--line); border-radius:10px; width:42px; height:42px; cursor:pointer; align-items:center; justify-content:center}
.nav-toggle span,.nav-toggle span::before,.nav-toggle span::after{display:block; width:18px; height:2px; background:#fff; position:relative; content:""}
.nav-toggle span::before,.nav-toggle span::after{position:absolute; left:0; content:""}
.nav-toggle span::before{top:-6px} .nav-toggle span::after{top:6px}
@media (max-width:960px){
.nav-toggle{display:inline-flex}
.menu{position:absolute; top:100%; left:0; right:0; flex-direction:column; align-items:stretch; gap:2px;
background:var(--space-800); border-bottom:1px solid var(--line); padding:12px 18px 18px; box-shadow:var(--shadow);
transform:translateY(-8px); opacity:0; pointer-events:none; transition:opacity .25s var(--ease), transform .25s var(--ease)}
.menu.open{opacity:1; transform:translateY(0); pointer-events:auto}
.menu a{padding:12px 14px; font-size:16px}
.menu a.active::after{display:none}
.cta{text-align:center; margin-top:6px}
}
/* ============ HERO ============ */
.hero{position:relative; overflow:hidden}
.hero-inner{display:grid; grid-template-columns:1.1fr .9fr; gap:44px; align-items:center; padding:76px 0 84px}
@media (max-width:980px){ .hero-inner{grid-template-columns:1fr; gap:36px; padding:52px 0 60px} }
.kicker{display:inline-flex; align-items:center; gap:9px; font-family:"Space Grotesk"; font-size:12.5px; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
color:#9be7ff; border:1px solid rgba(34,211,238,.30); background:rgba(34,211,238,.10); padding:7px 14px; border-radius:999px; margin-bottom:22px}
.kicker .dot{width:7px; height:7px; border-radius:50%; background:var(--cyan); box-shadow:0 0 0 4px rgba(34,211,238,.22); animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{0%,100%{opacity:1} 50%{opacity:.4}}
.h1{font-size:clamp(32px,5.4vw,58px); margin:0 0 20px; color:#fff}
.lead{font-size:clamp(16px,1.8vw,19px); color:var(--muted); max-width:600px; margin:0 0 12px}
.lead b{color:#fff; font-weight:600}
.lead-2{font-size:15.5px; color:var(--muted-2); max-width:560px; margin:0 0 26px; font-style:italic}
.hero-actions{display:flex; gap:14px; flex-wrap:wrap}
.btn-primary{display:inline-flex; align-items:center; gap:9px; font-family:"Space Grotesk"; font-weight:700; font-size:15.5px;
background:linear-gradient(135deg,var(--cyan),var(--blue)); color:#04122e; padding:15px 26px; border-radius:14px;
box-shadow:0 16px 34px rgba(34,211,238,.30); transition:transform .2s var(--ease), box-shadow .2s}
.btn-primary:hover{transform:translateY(-2px); box-shadow:0 22px 44px rgba(34,211,238,.45)}
.btn-ghost{display:inline-flex; align-items:center; gap:9px; font-weight:600; color:#eaf1ff; padding:15px 24px; border-radius:14px;
border:1px solid var(--line-2); background:rgba(255,255,255,.04); transition:background .2s, transform .2s}
.btn-ghost:hover{background:rgba(255,255,255,.10); transform:translateY(-2px)}
/* hero metrics strip */
.metrics{display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-top:38px; max-width:560px}
@media (max-width:480px){ .metrics{grid-template-columns:1fr; max-width:340px} }
.metric{border:1px solid var(--line); background:rgba(255,255,255,.03); border-radius:16px; padding:16px 14px}
.metric .num{font-family:"Space Grotesk"; font-weight:700; font-size:30px; color:#fff; line-height:1}
.metric .num .suf{color:var(--cyan)}
.metric .lbl{font-size:12.5px; color:var(--muted); margin-top:7px; line-height:1.35}
/* orbit visual */
.orbit-wrap{position:relative; display:grid; place-items:center; min-height:380px}
.orbit-core{width:120px; height:120px; border-radius:50%; background:radial-gradient(circle at 35% 30%, #7cf3e0, #3b82f6 55%, #8b5cf6);
box-shadow:0 0 60px rgba(59,130,246,.55), inset 0 0 30px rgba(255,255,255,.25); display:grid; place-items:center; position:relative; z-index:3}
.orbit-core span{font-family:"Space Grotesk"; font-weight:700; font-size:15px; color:#04122e; letter-spacing:.02em}
.orbit-ring{position:absolute; border:1px solid rgba(255,255,255,.14); border-radius:50%; top:50%; left:50%; transform:translate(-50%,-50%)}
.orbit-ring.r1{width:220px; height:220px} .orbit-ring.r2{width:320px; height:320px} .orbit-ring.r3{width:420px; height:420px}
.sat{position:absolute; top:50%; left:50%; width:0; height:0; transform-origin:0 0}
.sat .chip{position:absolute; transform:translate(-50%,-50%); display:flex; align-items:center; gap:7px;
background:rgba(15,23,48,.9); border:1px solid var(--line-2); border-radius:11px; padding:8px 11px; font-size:12.5px; color:#dbe6ff; font-weight:600; white-space:nowrap; box-shadow:var(--shadow)}
.sat .chip .ci{color:var(--cyan); display:grid; place-items:center}
@keyframes orbit1{from{transform:rotate(0deg)} to{transform:rotate(360deg)}}
@keyframes orbit1c{from{transform:rotate(0deg)} to{transform:rotate(-360deg)}}
.a1{animation:orbit1 26s linear infinite} .a2{animation:orbit1c 34s linear infinite} .a3{animation:orbit1 44s linear infinite}
.sat .chip{animation:counter 26s linear infinite}
.a2 .chip{animation:counterc 34s linear infinite} .a3 .chip{animation:counter 44s linear infinite}
@keyframes counter{from{transform:translate(-50%,-50%) rotate(0)} to{transform:translate(-50%,-50%) rotate(-360deg)}}
@keyframes counterc{from{transform:translate(-50%,-50%) rotate(0)} to{transform:translate(-50%,-50%) rotate(360deg)}}
@media (max-width:980px){ .orbit-wrap{min-height:340px; transform:scale(.92)} }
@media (max-width:420px){ .orbit-wrap{transform:scale(.72)} }
/* ============ SECTIONS ============ */
section{padding:82px 0; position:relative}
@media (max-width:640px){ section{padding:58px 0} }
.sec-head{max-width:760px; margin:0 0 44px}
.sec-head.center{margin:0 auto 44px; text-align:center}
.eyebrow{display:inline-flex; align-items:center; gap:8px; font-family:"Space Grotesk"; font-weight:600; font-size:12.5px;
letter-spacing:.07em; text-transform:uppercase; color:var(--cyan); background:rgba(34,211,238,.10); border:1px solid rgba(34,211,238,.22); padding:6px 13px; border-radius:999px; margin-bottom:16px}
.sec-title{font-size:clamp(26px,3.6vw,40px); margin:0 0 14px; color:#fff}
.sec-sub{font-size:16.5px; color:var(--muted); margin:0}
.sec-sub b{color:#fff; font-weight:600}
.grid-3{display:grid; grid-template-columns:repeat(3,1fr); gap:20px}
@media (max-width:900px){ .grid-3{grid-template-columns:1fr} }
.grid-2{display:grid; grid-template-columns:1fr 1fr; gap:20px}
@media (max-width:820px){ .grid-2{grid-template-columns:1fr} }
.grid-svc{display:grid; grid-template-columns:repeat(3,1fr); gap:20px}
@media (max-width:900px){ .grid-svc{grid-template-columns:repeat(2,1fr)} }
@media (max-width:600px){ .grid-svc{grid-template-columns:1fr} }
.card{background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.02)); border:1px solid var(--line); border-radius:var(--radius); padding:26px;
transition:transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease); position:relative; overflow:hidden}
.card:hover{transform:translateY(-6px); border-color:rgba(34,211,238,.35); box-shadow:var(--glow-cyan)}
.card .card-ic{width:50px; height:50px; border-radius:14px; display:grid; place-items:center; margin-bottom:16px;
background:linear-gradient(135deg, rgba(34,211,238,.16), rgba(139,92,246,.16)); color:var(--cyan)}
.card h3{font-size:19px; margin:0 0 9px; color:#fff}
.card p{margin:0; font-size:14.5px; color:var(--muted)}
.card .stack{display:flex; flex-wrap:wrap; gap:7px; margin-top:14px}
.card .stack span{font-size:11.5px; font-weight:600; color:#bfe9ff; background:rgba(34,211,238,.10); border:1px solid rgba(34,211,238,.20); padding:4px 10px; border-radius:999px}
.num-badge{position:absolute; top:20px; right:22px; font-family:"Space Grotesk"; font-weight:700; font-size:34px; color:rgba(255,255,255,.08)}
/* about / why */
.about-lead{display:grid; grid-template-columns:1fr; gap:0; max-width:820px; margin:0 auto 36px; text-align:center}
/* industries */
.ind{background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.02)); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden;
transition:transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease)}
.ind:hover{transform:translateY(-6px); border-color:rgba(139,92,246,.4); box-shadow:0 0 0 1px rgba(139,92,246,.3), 0 16px 44px rgba(139,92,246,.18)}
.ind .top{height:172px; position:relative; display:grid; place-items:center; overflow:hidden}
.ind .top .ic{width:54px; height:54px; border-radius:15px; display:grid; place-items:center; color:#fff; z-index:2;
background:rgba(4,8,20,.42); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); border:1px solid rgba(255,255,255,.20); box-shadow:0 8px 24px rgba(0,0,0,.35)}
.ind-img{position:absolute; inset:0; z-index:0; width:100%; height:100%; object-fit:cover; transition:transform .5s var(--ease)}
.ind:hover .ind-img{transform:scale(1.06)}
.ind .top::after{content:""; position:absolute; inset:0; z-index:1; background:linear-gradient(180deg, rgba(4,8,20,.12), rgba(4,8,20,.60))}
.ind .body{padding:22px 24px 26px}
.ind h3{font-size:19px; color:#fff; margin:0 0 8px}
.ind p{margin:0; font-size:14.5px; color:var(--muted)}
.ind-1 .top{background:linear-gradient(135deg,#f59e0b,#ef4444)}
.ind-2 .top{background:linear-gradient(135deg,#22c55e,#0ea5e9)}
.ind-3 .top{background:linear-gradient(135deg,#8b5cf6,#3b82f6)}
/* process timeline */
.process{display:grid; grid-template-columns:repeat(4,1fr); gap:18px; position:relative}
@media (max-width:820px){ .process{grid-template-columns:1fr 1fr} }
@media (max-width:460px){ .process{grid-template-columns:1fr} }
.step{background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.02)); border:1px solid var(--line); border-radius:16px; padding:24px 20px; position:relative}
.step .n{width:40px; height:40px; border-radius:12px; display:grid; place-items:center; font-family:"Space Grotesk"; font-weight:700; font-size:17px;
background:linear-gradient(135deg,var(--cyan),var(--violet)); color:#04122e; margin-bottom:14px}
.step h3{font-size:16.5px; color:#fff; margin:0 0 6px}
.step p{margin:0; font-size:13.5px; color:var(--muted)}
/* pricing */
.plans{display:grid; grid-template-columns:repeat(3,1fr); gap:20px; align-items:stretch}
@media (max-width:900px){ .plans{grid-template-columns:1fr; max-width:440px; margin:0 auto} }
.plan{background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.02)); border:1px solid var(--line); border-radius:var(--radius-lg); padding:30px 26px; display:flex; flex-direction:column;
transition:transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease)}
.plan:hover{transform:translateY(-6px)}
.plan .pname{font-family:"Space Grotesk"; font-weight:700; font-size:15px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted)}
.plan .price{display:flex; align-items:baseline; gap:6px; margin:14px 0 4px}
.plan .amount{font-size:42px; color:#fff}
.plan .per{font-size:14px; color:var(--muted)}
.plan .ptag{font-size:13px; color:var(--muted-2); margin-bottom:20px}
.plan ul{list-style:none; margin:0 0 24px; padding:0; display:flex; flex-direction:column; gap:12px; flex:1}
.plan li{display:flex; gap:11px; font-size:14px; color:#cdd9f5; line-height:1.4}
.plan li .ck{flex:none; width:20px; height:20px; border-radius:6px; background:rgba(94,234,212,.16); color:var(--mint); display:grid; place-items:center; margin-top:2px}
.plan .btn{display:block; text-align:center; font-family:"Space Grotesk"; font-weight:700; padding:13px; border-radius:12px; border:1px solid var(--line-2); color:#fff; transition:background .2s, transform .2s}
.plan .btn:hover{background:rgba(255,255,255,.08); transform:translateY(-2px)}
.plan.featured{border-color:transparent; background:linear-gradient(180deg, rgba(34,211,238,.14), rgba(139,92,246,.10)); box-shadow:0 0 0 1px rgba(34,211,238,.4), 0 24px 60px rgba(34,211,238,.18); position:relative}
.plan.featured::before{content:"Популярный"; position:absolute; top:-12px; left:50%; transform:translateX(-50%); font-family:"Space Grotesk"; font-weight:700; font-size:11.5px; letter-spacing:.06em; text-transform:uppercase;
background:linear-gradient(135deg,var(--cyan),var(--violet)); color:#04122e; padding:5px 14px; border-radius:999px}
.plan.featured .btn{background:linear-gradient(135deg,var(--cyan),var(--blue)); color:#04122e; border-color:transparent; box-shadow:0 12px 28px rgba(34,211,238,.3)}
.plan.featured .btn:hover{transform:translateY(-2px); filter:brightness(1.05)}
/* SLA strip */
.sla{display:grid; grid-template-columns:repeat(4,1fr); gap:16px; margin-top:36px}
@media (max-width:760px){ .sla{grid-template-columns:1fr 1fr} }
.sla-item{text-align:center; border:1px solid var(--line); background:rgba(255,255,255,.03); border-radius:16px; padding:22px 14px}
.sla-item .v{font-family:"Space Grotesk"; font-weight:700; font-size:28px; color:#fff}
.sla-item .v .grad-text{font-weight:700}
.sla-item .k{font-size:13px; color:var(--muted); margin-top:6px}
/* gallery */
.gallery{display:grid; grid-template-columns:repeat(4,1fr); gap:16px}
@media (max-width:900px){ .gallery{grid-template-columns:repeat(2,1fr)} }
@media (max-width:460px){ .gallery{grid-template-columns:1fr} }
.ph{position:relative; border-radius:16px; overflow:hidden; border:1px solid var(--line); aspect-ratio:4/3; display:grid; place-items:end; padding:16px}
.ph::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg, transparent 40%, rgba(0,0,0,.55))}
.ph .cap{position:relative; z-index:2; font-family:"Space Grotesk"; font-weight:600; font-size:14px; color:#fff; display:flex; align-items:center; gap:8px}
.ph .cap .ic{opacity:.9}
.ph-1{background:linear-gradient(160deg,#1e3a8a,#0ea5e9 60%,#22d3ee)}
.ph-2{background:linear-gradient(160deg,#065f46,#22c55e 60%,#a3e635)}
.ph-3{background:linear-gradient(160deg,#7c2d12,#f59e0b 60%,#fbbf24)}
.ph-4{background:linear-gradient(160deg,#312e81,#6d28d9 55%,#22d3ee)}
.ph.has-photo{background:#0a1020}
.ph-img{position:absolute; inset:0; z-index:0; width:100%; height:100%; max-width:100%; object-fit:cover;
transition:transform .5s var(--ease); filter:saturate(1.05) contrast(1.02)}
.ph.has-photo:hover .ph-img{transform:scale(1.05)}
.ph .stars-mini{position:absolute; inset:0; opacity:.5;
background-image:radial-gradient(1.5px 1.5px at 20% 30%,#fff,transparent),radial-gradient(1.5px 1.5px at 70% 60%,#fff,transparent),radial-gradient(1px 1px at 45% 80%,#fff,transparent),radial-gradient(1px 1px at 85% 25%,#fff,transparent)}
/* contacts + form */
.contact-card{background:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.02)); border:1px solid var(--line); border-radius:var(--radius); padding:30px}
.contact-row{display:flex; align-items:flex-start; gap:15px; padding:16px 0; border-bottom:1px solid var(--line)}
.contact-row:last-child{border-bottom:0; padding-bottom:0}
.contact-row .ic{width:46px; height:46px; border-radius:12px; flex:none; display:grid; place-items:center;
background:linear-gradient(135deg, rgba(34,211,238,.14), rgba(139,92,246,.14)); color:var(--cyan)}
.contact-row .lbl{font-size:12px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--muted-2); margin-bottom:3px}
.contact-row .val{font-size:16px; font-weight:600; color:#fff}
.contact-row .val a{transition:color .2s} .contact-row .val a:hover{color:var(--cyan)}
.contact-row .val small{display:block; font-weight:500; color:var(--muted); font-size:13px; margin-top:2px}
.form-card{background:linear-gradient(165deg, var(--panel), var(--space-800)); border:1px solid var(--line); border-radius:var(--radius); padding:30px}
.form-card h3{color:#fff; font-size:21px; margin:0 0 6px}
.form-card .fsub{font-size:13.5px; color:var(--muted); margin:0 0 20px}
.field{margin-bottom:16px}
.field label{display:block; font-size:13px; font-weight:600; color:#c6d4f5; margin-bottom:7px}
.field input,.field textarea{width:100%; padding:13px 15px; border-radius:12px; border:1px solid var(--line-2); background:rgba(255,255,255,.05); color:#fff; font-family:inherit; font-size:15px; outline:none;
transition:border-color .2s var(--ease), background .2s, box-shadow .2s}
.field input::placeholder,.field textarea::placeholder{color:var(--muted-2)}
.field input:focus,.field textarea:focus{border-color:var(--cyan); background:rgba(255,255,255,.09); box-shadow:0 0 0 3px rgba(34,211,238,.20)}
.field textarea{min-height:110px; resize:vertical}
.field.invalid input,.field.invalid textarea{border-color:#f87171; box-shadow:0 0 0 3px rgba(248,113,113,.18)}
.field .err{font-size:12px; color:#fca5a5; margin-top:6px; display:none}
.field.invalid .err{display:block}
.btn-submit{width:100%; border:0; cursor:pointer; font-family:"Space Grotesk"; font-weight:700; font-size:15.5px;
background:linear-gradient(135deg,var(--cyan),var(--blue)); color:#04122e; padding:15px; border-radius:13px; box-shadow:0 14px 30px rgba(34,211,238,.30); transition:transform .2s var(--ease), box-shadow .2s}
.btn-submit:hover{transform:translateY(-2px); box-shadow:0 20px 40px rgba(34,211,238,.42)}
.form-result{margin-top:14px; font-size:14px; color:var(--mint); text-align:center; min-height:20px}
.form-note{font-size:11.5px; color:var(--muted-2); margin-top:12px; text-align:center}
/* footer */
.footer{border-top:1px solid var(--line); padding:56px 0 34px; background:rgba(5,7,15,.6)}
.foot-grid{display:grid; grid-template-columns:1.5fr 1fr 1fr; gap:32px; margin-bottom:36px}
@media (max-width:760px){ .foot-grid{grid-template-columns:1fr; gap:26px} }
.footer h4{color:#fff; font-size:14px; letter-spacing:.04em; text-transform:uppercase; margin:0 0 16px; font-weight:600}
.footer a{color:var(--muted); transition:color .2s} .footer a:hover{color:#fff}
.foot-links{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:10px; font-size:14.5px}
.foot-about{font-size:14px; line-height:1.6; margin:16px 0 0; max-width:360px; color:var(--muted)}
.foot-bottom{border-top:1px solid var(--line); padding-top:22px; display:flex; justify-content:space-between; gap:14px; flex-wrap:wrap; font-size:13px; color:var(--muted-2)}
/* reveal */
.reveal{opacity:0; transform:translateY(26px); transition:opacity .7s var(--ease), transform .7s var(--ease)}
.reveal.in{opacity:1; transform:none}
.reveal.d1{transition-delay:.08s} .reveal.d2{transition-delay:.16s} .reveal.d3{transition-delay:.24s} .reveal.d4{transition-delay:.32s}
@media (prefers-reduced-motion:reduce){
html{scroll-behavior:auto}
.reveal{opacity:1; transform:none; transition:none}
.kicker .dot,.a1,.a2,.a3,.sat .chip,.a2 .chip,.a3 .chip,.logo .ring{animation:none}
}
.skip{position:absolute; left:-9999px; top:0; background:#fff; color:#04122e; padding:10px 16px; border-radius:0 0 10px 0; z-index:200; font-weight:700}
.skip:focus{left:0}
/* ============ CYBERCORE HERO ============ */
.hero.cyber{
--neon-cyan:#22e0ff; --neon-mag:#ff2bd6; --neon-grn:#39ff9e; --neon-blue:#4d7cff;
position:relative; isolation:isolate;
border-bottom:1px solid rgba(34,224,255,.18);
background:
radial-gradient(900px 520px at 78% -8%, rgba(255,43,214,.16), transparent 60%),
radial-gradient(1000px 640px at 6% 2%, rgba(34,224,255,.16), transparent 58%),
linear-gradient(180deg, #030512, #050a1c 60%, #030512);
}
/* perspective neon grid floor */
.cyber-grid{position:absolute; inset:0; z-index:-1; overflow:hidden; pointer-events:none;
mask-image:linear-gradient(180deg, transparent 0%, #000 40%, #000 100%);
-webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 40%, #000 100%)}
.cyber-grid::before{content:""; position:absolute; left:-30%; right:-30%; bottom:-10%; height:78%;
background-image:
linear-gradient(rgba(34,224,255,.28) 1px, transparent 1px),
linear-gradient(90deg, rgba(34,224,255,.20) 1px, transparent 1px);
background-size:48px 48px;
transform:perspective(520px) rotateX(64deg);
transform-origin:bottom center;
animation:gridflow 7s linear infinite;
}
@keyframes gridflow{from{background-position:0 0} to{background-position:0 48px}}
/* faint vertical data-rain columns */
.cyber-grid::after{content:""; position:absolute; inset:0;
background:repeating-linear-gradient(90deg, transparent 0 78px, rgba(77,124,255,.05) 78px 80px);}
/* scanlines + subtle flicker overlay */
.scanlines{position:absolute; inset:0; z-index:1; pointer-events:none; opacity:.5;
background:repeating-linear-gradient(180deg, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.16) 2px 3px);
mix-blend-mode:overlay; animation:flick 5s steps(60) infinite}
@keyframes flick{0%,97%,100%{opacity:.5} 98%{opacity:.34} 99%{opacity:.58}}
/* frame corner brackets */
.cyber .frame-corner{position:absolute; width:34px; height:34px; z-index:2; pointer-events:none; border:2px solid var(--neon-cyan); box-shadow:0 0 12px rgba(34,224,255,.5)}
.cyber .fc-tl{top:16px; left:16px; border-right:0; border-bottom:0}
.cyber .fc-tr{top:16px; right:16px; border-left:0; border-bottom:0; border-color:var(--neon-mag); box-shadow:0 0 12px rgba(255,43,214,.5)}
.cyber .fc-bl{bottom:16px; left:16px; border-right:0; border-top:0; border-color:var(--neon-mag); box-shadow:0 0 12px rgba(255,43,214,.5)}
.cyber .fc-br{bottom:16px; right:16px; border-left:0; border-top:0}
.cyber .hero-inner{position:relative; z-index:3}
/* wireframe dotted globe */
.hero-globe{position:absolute; z-index:1; top:52%; right:1%; transform:translateY(-50%);
width:min(560px,46%); aspect-ratio:1; pointer-events:none;
filter:drop-shadow(0 0 26px rgba(34,224,255,.22));}
@media (max-width:980px){ .hero-globe{opacity:.24; width:min(380px,74%); right:-12%; top:24%; transform:none} }
/* system tag / HUD label */
.sys-tag{display:inline-flex; align-items:center; gap:8px; font-family:"Space Grotesk",monospace; font-size:11.5px; letter-spacing:.18em; text-transform:uppercase;
color:var(--neon-grn); margin-bottom:14px}
.sys-tag::before{content:""; width:8px; height:8px; background:var(--neon-grn); border-radius:1px; box-shadow:0 0 10px var(--neon-grn); animation:blink 1.4s steps(1) infinite}
@keyframes blink{50%{opacity:.25}}
.cyber .kicker{border-color:rgba(34,224,255,.35); background:rgba(34,224,255,.08); color:#9bf0ff; box-shadow:inset 0 0 18px rgba(34,224,255,.12)}
.cyber .kicker .dot{background:var(--neon-cyan); box-shadow:0 0 0 4px rgba(34,224,255,.20)}
/* glitch heading */
.glitch{position:relative; color:#eafcff; text-shadow:0 0 14px rgba(34,224,255,.30)}
.glitch .grad-text{background:linear-gradient(100deg,#39ff9e,#22e0ff 45%,#ff2bd6); -webkit-background-clip:text; background-clip:text; color:transparent}
.glitch::before,.glitch::after{content:attr(data-text); position:absolute; left:0; top:0; width:100%; overflow:hidden; pointer-events:none; opacity:.9}
.glitch::before{color:var(--neon-cyan); text-shadow:-2px 0 var(--neon-cyan); clip-path:inset(0 0 55% 0); animation:glitchTop 3.4s steps(2,end) infinite}
.glitch::after{color:var(--neon-mag); text-shadow:2px 0 var(--neon-mag); clip-path:inset(55% 0 0 0); animation:glitchBot 3.9s steps(2,end) infinite}
@keyframes glitchTop{0%,92%,100%{transform:translate(0,0)}93%{transform:translate(-3px,-1px)}95%{transform:translate(2px,1px)}97%{transform:translate(-2px,0)}}
@keyframes glitchBot{0%,90%,100%{transform:translate(0,0)}91%{transform:translate(3px,1px)}94%{transform:translate(-2px,-1px)}96%{transform:translate(2px,0)}}
/* neon buttons in cyber hero */
.cyber .btn-primary{background:linear-gradient(135deg,var(--neon-cyan),var(--neon-blue)); color:#04122e; box-shadow:0 0 22px rgba(34,224,255,.45), 0 14px 30px rgba(34,224,255,.25)}
.cyber .btn-ghost{border-color:rgba(255,43,214,.5); color:#ffd6f4; background:rgba(255,43,214,.06); box-shadow:inset 0 0 18px rgba(255,43,214,.10)}
.cyber .btn-ghost:hover{background:rgba(255,43,214,.14)}
/* HUD metrics */
.cyber .metric{position:relative; border:1px solid rgba(34,224,255,.28); background:linear-gradient(180deg, rgba(34,224,255,.06), rgba(3,8,24,.4)); box-shadow:inset 0 0 20px rgba(34,224,255,.08)}
.cyber .metric::before{content:""; position:absolute; top:8px; right:8px; width:6px; height:6px; border-radius:50%; background:var(--neon-grn); box-shadow:0 0 8px var(--neon-grn)}
.cyber .metric .num{color:#eafcff; text-shadow:0 0 10px rgba(34,224,255,.35)}
.cyber .metric .num .suf{color:var(--neon-cyan)}
.cyber .metric .lbl{color:#8fb6d9; font-family:"Space Grotesk",monospace; letter-spacing:.04em}
/* cyber terminal / HUD panel */
.terminal{position:relative; border:1px solid rgba(34,224,255,.35); border-radius:14px; overflow:hidden;
background:linear-gradient(180deg, rgba(5,12,28,.92), rgba(3,7,20,.92)); box-shadow:0 0 0 1px rgba(34,224,255,.12), 0 24px 60px rgba(0,0,0,.55), inset 0 0 40px rgba(34,224,255,.06);
font-family:"Space Grotesk", ui-monospace, monospace}
.terminal::after{content:""; position:absolute; inset:0; pointer-events:none;
background:repeating-linear-gradient(180deg, transparent 0 3px, rgba(0,0,0,.14) 3px 4px); opacity:.5}
.term-bar{display:flex; align-items:center; gap:8px; padding:11px 14px; border-bottom:1px solid rgba(34,224,255,.22); background:rgba(34,224,255,.05)}
.term-bar .d{width:11px; height:11px; border-radius:50%}
.term-bar .d.r{background:#ff5f57; box-shadow:0 0 8px #ff5f57} .term-bar .d.y{background:#ffbd2e} .term-bar .d.g{background:#39ff9e; box-shadow:0 0 8px #39ff9e}
.term-bar .tt{margin-left:8px; font-size:12px; color:#7fb0d8; letter-spacing:.06em}
.term-bar{cursor:grab; touch-action:none; user-select:none; -webkit-user-select:none}
.term-hint{margin-left:auto; font-size:10px; letter-spacing:.12em; color:#5f83b0; opacity:.7; white-space:nowrap}
.terminal.dragging{cursor:grabbing; transition:none !important; z-index:20; will-change:transform}
.terminal.dragging .term-bar{cursor:grabbing}
.term-body{padding:18px 18px 16px; font-size:13.5px; line-height:1.85; color:#bfe4ff; position:relative; z-index:2}
.term-body .prm{color:var(--neon-grn)} .term-body .cmd{color:#eafcff}
.term-body .ok{color:var(--neon-grn)} .term-body .mag{color:var(--neon-mag)} .term-body .cy{color:var(--neon-cyan)}
.term-body .row{display:flex; justify-content:space-between; gap:12px}
.term-body .bar{height:6px; border-radius:3px; background:rgba(255,255,255,.08); overflow:hidden; margin:2px 0 8px}
.term-body .bar i{display:block; height:100%; background:linear-gradient(90deg,var(--neon-cyan),var(--neon-grn)); box-shadow:0 0 10px rgba(34,224,255,.6)}
.term-cursor{display:inline-block; width:9px; height:15px; background:var(--neon-cyan); box-shadow:0 0 8px var(--neon-cyan); vertical-align:-2px; animation:cur 1s steps(1) infinite}
@keyframes cur{50%{opacity:0}}
.term-tag{position:absolute; top:-11px; right:16px; z-index:4; font-size:10.5px; letter-spacing:.16em; text-transform:uppercase; color:#030512; background:var(--neon-cyan); padding:3px 10px; border-radius:4px; box-shadow:0 0 14px rgba(34,224,255,.6); font-family:"Space Grotesk",monospace}
@media (max-width:980px){ .terminal{max-width:520px} }
@media (prefers-reduced-motion:reduce){
.cyber-grid::before,.scanlines,.sys-tag::before,.glitch::before,.glitch::after,.term-cursor,.terminal::after{animation:none}
.glitch::before,.glitch::after{display:none}
}
/* ============ GLASSMORPHISM BUTTONS ============ */
.btn-primary,.btn-ghost,.cta,.btn-submit,.plan .btn,
.cyber .btn-primary,.cyber .btn-ghost{
position:relative;
background:linear-gradient(180deg, rgba(255,255,255,.20), transparent 55%), rgba(255,255,255,.07) !important;
-webkit-backdrop-filter:blur(14px) saturate(160%);
backdrop-filter:blur(14px) saturate(160%);
border:1px solid rgba(255,255,255,.18) !important;
color:#eafcff !important;
text-shadow:0 1px 8px rgba(0,0,0,.35);
box-shadow:inset 0 1px 0 rgba(255,255,255,.32), inset 0 -10px 22px rgba(0,0,0,.16), 0 10px 26px rgba(0,0,0,.35) !important;
transition:transform .2s var(--ease), box-shadow .3s var(--ease), background .3s var(--ease), border-color .3s var(--ease);
}
/* accent CTAs — cyan-tinted glass + cyan neon glow on hover */
.btn-primary,.cta,.btn-submit,.plan.featured .btn{
background:linear-gradient(180deg, rgba(255,255,255,.24), transparent 55%), rgba(34,224,255,.13) !important;
border-color:rgba(34,224,255,.34) !important;
color:#eafeff !important;
}
.btn-primary:hover,.cta:hover,.btn-submit:hover,.plan.featured .btn:hover{
transform:translateY(-2px);
background:linear-gradient(180deg, rgba(255,255,255,.30), transparent 55%), rgba(34,224,255,.20) !important;
border-color:rgba(34,224,255,.60) !important;
box-shadow:inset 0 1px 0 rgba(255,255,255,.40), 0 0 24px rgba(34,224,255,.48), 0 14px 34px rgba(34,224,255,.24) !important;
}
/* secondary/ghost glass — magenta neon glow on hover */
.btn-ghost:hover,.plan .btn:hover,.cyber .btn-ghost:hover{
transform:translateY(-2px);
background:linear-gradient(180deg, rgba(255,255,255,.26), transparent 55%), rgba(255,255,255,.12) !important;
border-color:rgba(255,43,214,.55) !important;
box-shadow:inset 0 1px 0 rgba(255,255,255,.34), 0 0 22px rgba(255,43,214,.40), 0 14px 32px rgba(0,0,0,.42) !important;
}
@media (prefers-reduced-motion:reduce){
.btn-primary:hover,.btn-ghost:hover,.cta:hover,.btn-submit:hover,.plan .btn:hover{transform:none}
}
/* ============ GALLERY ITEMS CLICKABLE ============ */
.gitem{cursor:zoom-in}
.gitem:focus-visible{outline:2px solid var(--cyan); outline-offset:3px}
/* ============ TERMINAL WINDOW CONTROLS ============ */
.term-bar .d{cursor:pointer; transition:transform .15s var(--ease), box-shadow .15s var(--ease), filter .15s var(--ease); position:relative}
.term-bar .d:hover{transform:scale(1.28); filter:brightness(1.25)}
.term-bar .d.r:hover{box-shadow:0 0 10px #ff5f57}
.term-bar .d.y:hover{box-shadow:0 0 10px #ffbd2e}
.term-bar .d.g:hover{box-shadow:0 0 10px #39ff9e}
.term-bar .d:focus-visible{outline:2px solid #fff; outline-offset:2px}
/* minimize: скрыть тело, оставить шапку */
.terminal .term-body{overflow:hidden; max-height:420px; transition:max-height .38s var(--ease), opacity .28s var(--ease), padding .38s var(--ease)}
.terminal.min .term-body{max-height:0; opacity:0; padding-top:0; padding-bottom:0}
.terminal.min .term-hint{opacity:0}
.terminal.min{cursor:pointer}
/* close: скрыть окно с fade */
.terminal.closed{opacity:0; visibility:hidden; transform:scale(.94); pointer-events:none; transition:opacity .3s var(--ease), transform .3s var(--ease), visibility .3s}
/* restore chip */
.term-restore{position:absolute; right:24px; bottom:24px; z-index:16; display:inline-flex; align-items:center; gap:7px;
font-family:"Space Grotesk",monospace; font-size:12.5px; letter-spacing:.06em; color:#bfe4ff; cursor:pointer;
background:rgba(34,224,255,.10); -webkit-backdrop-filter:blur(12px) saturate(160%); backdrop-filter:blur(12px) saturate(160%);
border:1px solid rgba(34,224,255,.34); border-radius:11px; padding:9px 14px;
box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 0 18px rgba(34,224,255,.22), 0 8px 20px rgba(0,0,0,.4);
transition:transform .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease)}
.term-restore:hover{transform:translateY(-2px); background:rgba(34,224,255,.18); box-shadow:inset 0 1px 0 rgba(255,255,255,.34), 0 0 26px rgba(34,224,255,.4), 0 12px 26px rgba(0,0,0,.45)}
.term-restore[hidden]{display:none}
@media (max-width:980px){ .term-restore{right:18px; bottom:14px} }
/* ============ GLASS PRICING (transparent subscriptions) ============ */
.pricing-promo{display:flex; align-items:center; gap:12px; justify-content:center; text-align:center;
max-width:640px; margin:0 auto 26px; padding:12px 18px; border-radius:14px;
background:rgba(255,255,255,.05); -webkit-backdrop-filter:blur(12px) saturate(150%); backdrop-filter:blur(12px) saturate(150%);
border:1px solid rgba(255,255,255,.14); box-shadow:inset 0 1px 0 rgba(255,255,255,.20)}
.pricing-promo .pp-badge{flex:none; width:32px; height:32px; border-radius:9px; display:grid; place-items:center; color:var(--cyan);
background:rgba(34,224,255,.12); border:1px solid rgba(34,224,255,.28)}
.pricing-promo .pp-text{font-size:14px; color:var(--muted)}
.pricing-promo .pp-text b{color:#fff; font-weight:600}
@media (max-width:520px){ .pricing-promo{flex-direction:column; gap:8px} }
/* стеклянные карточки тарифов */
.plan{
background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.03)) !important;
-webkit-backdrop-filter:blur(16px) saturate(150%); backdrop-filter:blur(16px) saturate(150%);
border:1px solid rgba(255,255,255,.16) !important;
box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 18px 44px rgba(0,0,0,.35) !important;
}
.plan.featured{
background:linear-gradient(180deg, rgba(34,224,255,.16), rgba(139,92,246,.10)) !important;
border-color:rgba(34,224,255,.42) !important;
box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 0 0 1px rgba(34,224,255,.32), 0 24px 60px rgba(34,224,255,.18) !important;
}
.plan-3m{margin:-12px 0 16px; font-size:11.5px; color:var(--muted-2); letter-spacing:.01em}
/* ============ LIGHTBOX ============ */
.lightbox{position:fixed; inset:0; z-index:1000; display:flex; align-items:center; justify-content:center; padding:4vh 4vw;
background:rgba(4,8,20,.82); -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
opacity:0; visibility:hidden; transition:opacity .3s var(--ease), visibility .3s}
.lightbox.open{opacity:1; visibility:visible}
.lb-figure{margin:0; max-width:90vw; max-height:90vh; display:flex; flex-direction:column; align-items:center; gap:12px;
transform:scale(.94); transition:transform .32s var(--ease)}
.lightbox.open .lb-figure{transform:scale(1)}
.lb-img{max-width:90vw; max-height:80vh; width:auto; height:auto; object-fit:contain; border-radius:16px;
border:1px solid rgba(34,224,255,.30); box-shadow:0 0 0 1px rgba(34,224,255,.12), 0 30px 80px rgba(0,0,0,.6), 0 0 40px rgba(34,224,255,.18)}
.lb-cap{font-family:"Space Grotesk",monospace; font-size:14px; color:#dbe6ff; text-align:center}
.lb-cap .lb-count{color:var(--cyan); margin-left:8px; font-size:13px}
.lb-close,.lb-nav{position:absolute; z-index:2; cursor:pointer; color:#eaf1ff; font-family:"Space Grotesk",sans-serif;
background:rgba(255,255,255,.07); -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
border:1px solid rgba(255,255,255,.18); box-shadow:inset 0 1px 0 rgba(255,255,255,.24), 0 8px 22px rgba(0,0,0,.4);
transition:transform .2s var(--ease), background .2s var(--ease), border-color .2s var(--ease)}
.lb-close{top:18px; right:20px; width:46px; height:46px; border-radius:12px; font-size:20px; line-height:1}
.lb-nav{top:50%; transform:translateY(-50%); width:52px; height:52px; border-radius:50%; font-size:28px; line-height:1}
.lb-prev{left:18px} .lb-next{right:18px}
.lb-close:hover{background:rgba(255,43,214,.18); border-color:rgba(255,43,214,.5); transform:scale(1.06)}
.lb-nav:hover{background:rgba(34,224,255,.18); border-color:rgba(34,224,255,.5)}
.lb-prev:hover{transform:translateY(-50%) translateX(-2px)} .lb-next:hover{transform:translateY(-50%) translateX(2px)}
@media (max-width:560px){ .lb-nav{width:44px; height:44px; font-size:24px} .lb-prev{left:8px} .lb-next{right:8px} .lb-close{top:10px; right:10px} }
@media (prefers-reduced-motion:reduce){
.lightbox,.lb-figure{transition:none}
.terminal .term-body,.terminal.closed{transition:none}
}
/* ============ MOBILE / TABLET ADAPTATION ============ */
/* защита от горизонтального скролла */
html,body{max-width:100%}
img,svg,canvas{max-width:100%}
/* увеличенная тач-зона у traffic-кнопок терминала (визуал 11px, хит ≥40px) */
.term-bar .d{width:12px; height:12px}
.term-bar .d::before{content:""; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:30px; height:40px}
/* планшет */
@media (max-width:900px){
section{padding:64px 0}
.sec-head{margin-bottom:34px}
}
/* смартфон */
@media (max-width:640px){
body{font-size:15.5px}
section{padding:52px 0}
.container{padding:0 16px}
.sec-head{margin-bottom:28px}
.sec-sub{font-size:15px}
/* hero */
.hero-inner{padding:44px 0 52px; gap:26px}
.kicker{font-size:11px; padding:6px 11px}
.sys-tag{font-size:9.5px; letter-spacing:.08em; white-space:normal; line-height:1.5; word-break:break-word}
.h1{font-size:clamp(27px,8.4vw,40px); line-height:1.12; word-break:break-word}
.lead{font-size:15.5px}
.hero-actions{gap:10px}
.hero-actions .btn-primary,.hero-actions .btn-ghost{flex:1 1 100%; justify-content:center}
.metrics{grid-template-columns:1fr 1fr; gap:10px}
.metric .num{font-size:24px}
/* глобус — тихий ambient-фон, не даёт скролла */
.hero-globe{opacity:.18; width:min(320px,80%); right:-16%; top:auto; bottom:6%; transform:none}
/* терминал — компактнее, в пределах экрана */
.terminal{max-width:92vw; width:min(360px,92vw); margin:0 auto; font-size:12.5px}
.term-body{font-size:12.5px; padding:14px}
.term-hint{display:none}
.term-restore{right:14px; bottom:10px; font-size:12px; padding:10px 13px}
/* тарифы — стопкой, кнопки на всю ширину */
.plans{grid-template-columns:1fr; max-width:100%}
.plan{padding:26px 22px}
.plan .amount{font-size:38px}
.plan .btn{width:100%}
.pricing-promo{padding:12px 14px}
/* отрасли — фото ниже, но не гигантские */
.ind .top{height:150px}
/* контакты — крупные тап-ссылки */
.contact-row{padding:14px 0}
.contact-row .val{font-size:16.5px}
.contact-row .val a{display:inline-block; padding:2px 0}
.grid-2{gap:16px}
.form-card,.contact-card{padding:24px 20px}
/* лайтбокс — крупнее картинка */
.lb-img{max-height:74vh}
.lb-figure{gap:10px}
}
/* очень узкие экраны 320–380 */
@media (max-width:380px){
.h1{font-size:clamp(24px,9vw,34px)}
.metrics{grid-template-columns:1fr}
.plan .amount{font-size:34px}
.lb-nav{width:42px; height:42px}
}
</style>
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(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=110477494', 'ym');
ym(110477494, 'init', {ssr:true, webvisor: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/110477494" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
</head>
<body id="top">
<a class="skip" href="#main">Перейти к содержанию</a>
<canvas id="stars" aria-hidden="true"></canvas>
<!-- ============ HEADER / NAV ============ -->
<header class="nav" id="nav">
<div class="container nav-inner">
<a class="brand" href="#top" aria-label="servaki.online — на главную">
<span class="logo" aria-hidden="true"><span class="ring"></span><b>S</b></span>
<span class="brand-name">servaki.online<small>Ваш IT-отдел на орбите</small></span>
</a>
<nav class="menu" id="menu" aria-label="Основная навигация">
<a href="#about">О нас</a>
<a href="#services">Услуги</a>
<a href="#industries">Отрасли</a>
<a href="#pricing">Тарифы</a>
<a href="#gallery">Галерея</a>
<a href="#contacts" class="cta">Связаться</a>
</nav>
<button class="nav-toggle" id="navToggle" aria-label="Открыть меню" aria-expanded="false" aria-controls="menu"><span aria-hidden="true"></span></button>
</div>
</header>
<main id="main">
<!-- ============ HERO (CYBERCORE) ============ -->
<section class="hero cyber" aria-labelledby="hero-h1">
<div class="cyber-grid" aria-hidden="true"></div>
<canvas id="globe" class="hero-globe" aria-hidden="true"></canvas>
<div class="scanlines" aria-hidden="true"></div>
<span class="frame-corner fc-tl" aria-hidden="true"></span>
<span class="frame-corner fc-tr" aria-hidden="true"></span>
<span class="frame-corner fc-bl" aria-hidden="true"></span>
<span class="frame-corner fc-br" aria-hidden="true"></span>
<div class="container">
<div class="hero-inner">
<div>
<span class="sys-tag reveal" aria-hidden="true">// SYSTEM ONLINE · REGION: ЮГ_РОССИИ · UPLINK: SECURE</span>
<span class="kicker reveal d1"><span class="dot" aria-hidden="true"></span> IT-поддержка для бизнеса на Юге России</span>
<h1 class="h1 glitch reveal d1" id="hero-h1" data-text="Ваш IT-отдел на орбите">Ваш <span class="grad-text">IT-отдел</span> на орбите</h1>
<p class="lead reveal d2">
Удалённое обслуживание компьютеров, сетей и серверов для малого и среднего бизнеса.
Решаем задачи <b>без выездов</b> — быстро, из любой точки, с фиксированной ценой подписки.
</p>
<p class="lead-2 reveal d2">&gt;_ «Мы рядом, даже если между нами горы».</p>
<div class="hero-actions reveal d3">
<a class="btn-primary" href="#contacts">
Оставить заявку
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</a>
<a class="btn-ghost" href="#pricing">Смотреть тарифы</a>
</div>
<div class="metrics reveal d4" role="list">
<div class="metric" role="listitem"><div class="num" data-count="50" data-suf="+">0</div><div class="lbl">компаний на поддержке</div></div>
<div class="metric" role="listitem"><div class="num" data-count="15" data-suf=" мин">0</div><div class="lbl">среднее время реакции</div></div>
<div class="metric" role="listitem"><div class="num" data-static="24/7">24/7</div><div class="lbl">мониторинг систем</div></div>
</div>
</div>
<div class="terminal reveal d2" role="img" aria-label="Терминал статуса servaki.online: ядро активно, аптайм 99.5 процента, VPN-меш онлайн, резервные копии в норме, реакция 15 минут.">
<span class="term-tag" aria-hidden="true">LIVE</span>
<div class="term-bar" title="Потяни, чтобы перемещать окно">
<span class="d r" data-act="close" role="button" tabindex="0" title="Закрыть окно" aria-label="Закрыть окно консоли"></span><span class="d y" data-act="min" role="button" tabindex="0" title="Свернуть" aria-label="Свернуть окно консоли"></span><span class="d g" data-act="max" role="button" tabindex="0" title="Развернуть" aria-label="Развернуть окно консоли"></span>
<span class="tt" aria-hidden="true">servaki@orbital:~</span>
<span class="term-hint" aria-hidden="true">⠿ потяни</span>
</div>
<div class="term-body" aria-hidden="true">
<div><span class="prm">$</span> <span class="cmd">systemctl status servaki.core</span></div>
<div><span class="ok">●</span> servaki.core — <span class="ok">active (running)</span></div>
<div class="row"><span class="cy">uptime</span><span>99.5%</span></div>
<div class="bar"><i style="width:99.5%"></i></div>
<div><span class="prm">$</span> <span class="cmd">net status --mesh</span></div>
<div class="row"><span>WireGuard mesh</span><span class="ok">[ ONLINE ]</span></div>
<div class="row"><span>Backups /nightly</span><span class="ok">[ OK ]</span></div>
<div class="row"><span>Threat monitor</span><span class="mag">[ 24/7 ]</span></div>
<div><span class="prm">$</span> <span class="cmd">ping ops --sla</span> <span id="termType"></span><span class="term-cursor"></span></div>
</div>
</div>
</div>
</div>
<button class="term-restore" id="termRestore" type="button" aria-label="Показать окно консоли" hidden>▣ console</button>
</section>
<!-- ============ ABOUT / WHY US ============ -->
<section id="about" aria-labelledby="about-h">
<div class="container">
<header class="sec-head center">
<span class="eyebrow reveal">О нас</span>
<h2 class="sec-title reveal d1" id="about-h">Почему выбирают servaki.online</h2>
<p class="sec-sub reveal d2">
Мы — удалённый IT-отдел для бизнеса Юга России. Держим инфраструктуру под контролем там,
где выезд специалиста дорог и долог: <b>фермы, базы, объекты в горах, курорты и стройплощадки</b>.
</p>
</header>
<div class="grid-3">
<article class="card reveal">
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.8"/><path d="M12 7v5l3 2" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3>Реакция от 15 минут</h3>
<p>Решаем большинство задач удалённо, без выездов через перевалы. Помощь приходит по подключению, а не по дороге.</p>
</article>
<article class="card reveal d1">
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M3 12h4l3-8 4 16 3-8h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3>Работаем с удалёнными точками</h3>
<p>Фермы, весовые, склады, базы и объекты в горах — объединяем их в единую защищённую сеть и держим на связи.</p>
</article>
<article class="card reveal d2">
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="4" y="5" width="16" height="14" rx="2" stroke="currentColor" stroke-width="1.8"/><path d="M4 10h16" stroke="currentColor" stroke-width="1.8"/><path d="M8 15h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></div>
<h3>Доступные подписки</h3>
<p>Фиксированная цена в месяц вместо непредсказуемых счетов за разовые вызовы. Бюджет на IT понятен заранее.</p>
</article>
</div>
</div>
</section>
<!-- ============ SERVICES ============ -->
<section id="services" aria-labelledby="services-h">
<div class="container">
<header class="sec-head">
<span class="eyebrow reveal">Услуги</span>
<h2 class="sec-title reveal d1" id="services-h">Что мы делаем</h2>
<p class="sec-sub reveal d2">Полный цикл поддержки инфраструктуры — от рабочего места сотрудника до сервера и видеонаблюдения.</p>
</header>
<div class="grid-svc">
<article class="card reveal">
<span class="num-badge" aria-hidden="true">01</span>
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="3" y="4" width="18" height="12" rx="2" stroke="currentColor" stroke-width="1.8"/><path d="M8 20h8M12 16v4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></div>
<h3>Удалённый рабочий стол</h3>
<p>Диагностика и настройка ПК, программного обеспечения, драйверов и принтеров без выезда специалиста.</p>
</article>
<article class="card reveal d1">
<span class="num-badge" aria-hidden="true">02</span>
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><circle cx="6" cy="6" r="2.5" stroke="currentColor" stroke-width="1.8"/><circle cx="18" cy="18" r="2.5" stroke="currentColor" stroke-width="1.8"/><circle cx="18" cy="6" r="2.5" stroke="currentColor" stroke-width="1.8"/><path d="M8 6h7M6 8v8a2 2 0 0 0 2 2h7" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></div>
<h3>Сети и VPN</h3>
<p>Объединяем офисы, склады и удалённые точки в единую защищённую сеть.</p>
<div class="stack"><span>WireGuard</span><span>ZeroTier</span><span>Keenetic</span></div>
</article>
<article class="card reveal d2">
<span class="num-badge" aria-hidden="true">03</span>
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M12 3 4 6v6c0 5 3.4 8.3 8 10 4.6-1.7 8-5 8-10V6l-8-3Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="m9 12 2 2 4-4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3>Мониторинг и безопасность</h3>
<p>Круглосуточный контроль серверов, регулярные резервные копии и антивирусная защита.</p>
</article>
<article class="card reveal">
<span class="num-badge" aria-hidden="true">04</span>
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M3 7a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z" stroke="currentColor" stroke-width="1.8"/><path d="m16 10 5-3v10l-5-3" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></div>
<h3>Видеонаблюдение</h3>
<p>IP-камеры, регистраторы, проектирование трасс и удалённый доступ к архиву.</p>
</article>
<article class="card reveal d1">
<span class="num-badge" aria-hidden="true">05</span>
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="4" y="4" width="16" height="6" rx="1.5" stroke="currentColor" stroke-width="1.8"/><rect x="4" y="14" width="16" height="6" rx="1.5" stroke="currentColor" stroke-width="1.8"/><circle cx="8" cy="7" r="1" fill="currentColor"/><circle cx="8" cy="17" r="1" fill="currentColor"/></svg></div>
<h3>Серверы и хостинг</h3>
<p>Разворачиваем и обслуживаем сервисы для бизнеса: почта, чаты, CRM и 1С.</p>
<div class="stack"><span>Proxmox</span><span>Docker</span><span>CRM · 1С</span></div>
</article>
<article class="card reveal d2">
<span class="num-badge" aria-hidden="true">06</span>
<div class="card-ic" aria-hidden="true"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M12 3v4M12 17v4M5 12H1M23 12h-4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><rect x="7" y="7" width="10" height="10" rx="2.5" stroke="currentColor" stroke-width="1.8"/></svg></div>
<h3>Автоматизация</h3>
<p>Telegram-боты и интеграции с кассами: уведомления, отчёты и рутинные операции без ручного труда.</p>
</article>
</div>
</div>
</section>
<!-- ============ INDUSTRIES ============ -->
<section id="industries" aria-labelledby="industries-h">
<div class="container">
<header class="sec-head">
<span class="eyebrow reveal">Отрасли</span>
<h2 class="sec-title reveal d1" id="industries-h">Кому мы помогаем</h2>
<p class="sec-sub reveal d2">Понимаем специфику бизнеса Юга России и подбираем решения под задачи каждой отрасли.</p>
</header>
<div class="grid-3">
<article class="ind ind-1 reveal">
<div class="top"><img class="ind-img" src="/img/restaurant.png" alt="HoReCa — IT для ресторанов и кафе: кассы, Wi-Fi, сеть" loading="lazy" decoding="async" width="800" height="500" /><div class="ic" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none"><path d="M4 8h16l-1 12H5L4 8Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M8 8V6a4 4 0 0 1 8 0v2" stroke="currentColor" stroke-width="1.8"/></svg></div></div>
<div class="body">
<h3>HoReCa</h3>
<p>Кассы и POS-терминалы, стабильный Wi-Fi для гостей, интеграция с Яндекс.Еда и Delivery Club.</p>
</div>
</article>
<article class="ind ind-2 reveal d1">
<div class="top"><img class="ind-img" src="/img/farms.png" alt="Агросектор — IT для сельского хозяйства: сети, весовые, датчики" loading="lazy" decoding="async" width="800" height="500" /><div class="ic" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none"><path d="M3 20c4-1 6-4 6-8 0-3-2-6-2-6s5 1 7 4 2 8 2 8" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 20c0-4 3-8 8-9" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></div></div>
<div class="body">
<h3>Агросектор</h3>
<p>Сети удалённых точек, весовые, видеонаблюдение и датчики на фермах, полях и складах.</p>
</div>
</article>
<article class="ind ind-3 reveal d2">
<div class="top"><img class="ind-img" src="/img/construction.png" alt="Строительство — IT для стройплощадок: временные сети, камеры, учёт" loading="lazy" decoding="async" width="800" height="500" /><div class="ic" aria-hidden="true"><svg width="28" height="28" viewBox="0 0 24 24" fill="none"><path d="M3 21h18M6 21V10l6-4 6 4v11" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M10 21v-5h4v5" stroke="currentColor" stroke-width="1.8"/></svg></div></div>
<div class="body">
<h3>Строительство</h3>
<p>Временные сети и роутеры на объектах, камеры для контроля и учёт материалов.</p>
</div>
</article>
</div>
</div>
</section>
<!-- ============ PROCESS ============ -->
<section id="process" aria-labelledby="process-h">
<div class="container">
<header class="sec-head center">
<span class="eyebrow reveal">Как это работает</span>
<h2 class="sec-title reveal d1" id="process-h">Четыре шага до решения</h2>
<p class="sec-sub reveal d2">Простой и прозрачный процесс — от вашего сообщения до постоянного мониторинга.</p>
</header>
<ol class="process" style="list-style:none; margin:0; padding:0">
<li class="step reveal">
<div class="n">1</div>
<h3>Заявка</h3>
<p>Пишете в Telegram, WhatsApp или звоните — фиксируем задачу.</p>
</li>
<li class="step reveal d1">
<div class="n">2</div>
<h3>Удалённое подключение</h3>
<p>Безопасно подключаемся к вашему устройству или инфраструктуре.</p>
</li>
<li class="step reveal d2">
<div class="n">3</div>
<h3>Диагностика и решение</h3>
<p>Находим причину и устраняем проблему, не дожидаясь выезда.</p>
</li>
<li class="step reveal d3">
<div class="n">4</div>
<h3>Отчёт и мониторинг</h3>
<p>Присылаем отчёт и продолжаем следить за системами 24/7.</p>
</li>
</ol>
</div>
</section>
<!-- ============ PRICING ============ -->
<section id="pricing" aria-labelledby="pricing-h">
<div class="container">
<header class="sec-head center">
<span class="eyebrow reveal">Тарифы</span>
<h2 class="sec-title reveal d1" id="pricing-h">Прозрачные подписки</h2>
<p class="sec-sub reveal d2">Фиксированная цена в месяц. Прозрачные цены — без скрытых платежей и сюрпризов в счёте.</p>
</header>
<div class="pricing-promo reveal d2" role="note">
<span class="pp-badge" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.8"/><path d="M12 8h.01M11 12h1v4h1" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
<span class="pp-text">Стоимость указана при подписке <b>от 3 месяцев</b> — это минимальный период обслуживания.</span>
</div>
<div class="plans">
<article class="plan reveal">
<div class="pname">Старт</div>
<div class="price"><span class="amount">3000</span><span class="per">₽ / мес</span></div>
<div class="ptag">Для небольшой команды</div>
<div class="plan-3m">Цена при подписке от 3 месяцев</div>
<ul>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>1–3 рабочих места</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Отклик до 2 часов</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Удалённая поддержка</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Без выездов</li>
</ul>
<a class="btn" href="#contacts">Выбрать «Старт»</a>
</article>
<article class="plan featured reveal d1">
<div class="pname">Бизнес</div>
<div class="price"><span class="amount">7000</span><span class="per">₽ / мес</span></div>
<div class="ptag">Оптимально для растущего бизнеса</div>
<div class="plan-3m">Цена при подписке от 3 месяцев</div>
<ul>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>До 10 рабочих мест</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Отклик 30 минут</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>1 выезд в месяц</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Всё из тарифа «Старт»</li>
</ul>
<a class="btn" href="#contacts">Выбрать «Бизнес»</a>
</article>
<article class="plan reveal d2">
<div class="pname">Премиум</div>
<div class="price"><span class="amount">15000</span><span class="per">₽ / мес</span></div>
<div class="ptag">Максимальный контроль и приоритет</div>
<div class="plan-3m">Цена при подписке от 3 месяцев</div>
<ul>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Без ограничений по местам</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Отклик 15 минут, 4 выезда/мес</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Выделенный специалист</li>
<li><span class="ck" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="m5 12 5 5 9-11" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg></span>Видеонаблюдение, бэкапы, 24/7, приоритет</li>
</ul>
<a class="btn" href="#contacts">Выбрать «Премиум»</a>
</article>
</div>
<!-- SLA -->
<div class="sla" aria-label="Гарантии уровня сервиса">
<div class="sla-item reveal"><div class="v"><span class="grad-text">15 мин</span></div><div class="k">первый отклик</div></div>
<div class="sla-item reveal d1"><div class="v"><span class="grad-text">99.5%</span></div><div class="k">аптайм систем</div></div>
<div class="sla-item reveal d2"><div class="v"><span class="grad-text">4 часа</span></div><div class="k">на критичные сбои</div></div>
<div class="sla-item reveal d3"><div class="v"><span class="grad-text">∞</span></div><div class="k">без лимита обращений</div></div>
</div>
</div>
</section>
<!-- ============ GALLERY ============ -->
<section id="gallery" aria-labelledby="gallery-h">
<div class="container">
<header class="sec-head center">
<span class="eyebrow reveal">Галерея</span>
<h2 class="sec-title reveal d1" id="gallery-h">Наша орбита — Юг России</h2>
<p class="sec-sub reveal d2">Работаем там, где живёт и растёт бизнес региона: горы, поля, курорты и серверные.</p>
</header>
<div class="gallery">
<figure class="ph has-photo gitem reveal" role="button" tabindex="0" aria-label="Открыть фото: Горы Кавказа">
<img class="ph-img" src="/img/mountains.png" alt="Горы Кавказа и КМВ — регион работы Servaki на Юге России" loading="lazy" decoding="async" width="800" height="600" />
<figcaption class="cap"><span class="ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="m3 20 6-11 4 6 3-4 5 9H3Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></span>Горы Кавказа</figcaption>
</figure>
<figure class="ph has-photo gitem reveal d1" role="button" tabindex="0" aria-label="Открыть фото: Поля и фермы">
<img class="ph-img" src="/img/farms.png" alt="Фермы и агрообъекты — IT-поддержка агросектора Юга России" loading="lazy" decoding="async" width="800" height="600" />
<figcaption class="cap"><span class="ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M4 20c3-1 5-3 5-7M12 20V8M20 20c-3-1-5-3-5-7" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>Поля и фермы</figcaption>
</figure>
<figure class="ph has-photo gitem reveal d2" role="button" tabindex="0" aria-label="Открыть фото: Курорты КМВ">
<img class="ph-img" src="/img/resorts.png" alt="Курорты Кавказских Минеральных Вод — обслуживание HoReCa и туризма" loading="lazy" decoding="async" width="800" height="600" />
<figcaption class="cap"><span class="ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="8" r="4" stroke="currentColor" stroke-width="1.8"/><path d="M4 20c1-4 4-6 8-6s7 2 8 6" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>Курорты КМВ</figcaption>
</figure>
<figure class="ph has-photo gitem reveal d3" role="button" tabindex="0" aria-label="Открыть фото: HoReCa">
<img class="ph-img" src="/img/restaurant.png" alt="Интерьер ресторана — IT для HoReCa: кассы, Wi-Fi, сеть" loading="lazy" decoding="async" width="800" height="600" />
<figcaption class="cap"><span class="ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M6 3v7a2 2 0 0 0 4 0V3M8 3v18M18 3c-1.5 0-3 2-3 5s1 4 3 4v9" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></span>HoReCa</figcaption>
</figure>
<figure class="ph has-photo gitem reveal" role="button" tabindex="0" aria-label="Открыть фото: Серверная">
<img class="ph-img" src="/img/servers.png" alt="Серверная и сетевое оборудование — мониторинг и обслуживание 24/7" loading="lazy" decoding="async" width="800" height="600" />
<figcaption class="cap"><span class="ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><rect x="4" y="4" width="16" height="6" rx="1.5" stroke="currentColor" stroke-width="1.8"/><rect x="4" y="14" width="16" height="6" rx="1.5" stroke="currentColor" stroke-width="1.8"/></svg></span>Серверная</figcaption>
</figure>
<figure class="ph has-photo gitem reveal d1" role="button" tabindex="0" aria-label="Открыть фото: Наш офис">
<img class="ph-img" src="/img/office.png" alt="Офис Servaki — рабочее место IT-поддержки бизнеса на Юге России" loading="lazy" decoding="async" width="800" height="600" />
<figcaption class="cap"><span class="ic" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none"><rect x="4" y="4" width="16" height="6" rx="1.5" stroke="currentColor" stroke-width="1.8"/><rect x="4" y="14" width="16" height="6" rx="1.5" stroke="currentColor" stroke-width="1.8"/></svg></span>Наш офис</figcaption>
</figure>
</div>
</div>
</section>
<!-- ============ CONTACTS ============ -->
<section id="contacts" aria-labelledby="contacts-h">
<div class="container">
<header class="sec-head">
<span class="eyebrow reveal">Связаться</span>
<h2 class="sec-title reveal d1" id="contacts-h">Выведем ваш IT на орбиту</h2>
<p class="sec-sub reveal d2">Напишите в мессенджер или оставьте заявку — ответим и предложим план поддержки.</p>
</header>
<div class="grid-2" style="align-items:start">
<div class="contact-card reveal" itemscope itemtype="https://schema.org/Organization">
<meta itemprop="name" content="servaki.online" />
<div class="contact-row">
<span class="ic" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M21 5 3 11l6 2 2 6 3-5 5 3 2-12Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></span>
<div>
<div class="lbl">Telegram</div>
<div class="val"><a href="https://t.me/servaki_online">@servaki_online</a></div>
</div>
</div>
<div class="contact-row">
<span class="ic" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M4 20l1.5-4A8 8 0 1 1 12 20a8 8 0 0 1-4-1L4 20Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></span>
<div>
<div class="lbl">WhatsApp</div>
<div class="val"><a href="https://wa.me/79620151414">+7 962 015-14-14</a><small>Написать в WhatsApp</small></div>
</div>
</div>
<div class="contact-row">
<span class="ic" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M4 5c0 8.3 6.7 15 15 15a2 2 0 0 0 2-2v-2.6a1 1 0 0 0-.8-1l-3.4-.7a1 1 0 0 0-1 .3l-1 1.2a12 12 0 0 1-5.3-5.3l1.2-1a1 1 0 0 0 .3-1L9.6 4.8a1 1 0 0 0-1-.8H6a2 2 0 0 0-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></span>
<div>
<div class="lbl">Телефон</div>
<div class="val" itemprop="telephone"><a href="tel:+79620151414">+7 962 015-14-14</a><small>Telegram · WhatsApp · MAX</small></div>
</div>
</div>
<div class="contact-row">
<span class="ic" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="10" r="3" stroke="currentColor" stroke-width="1.8"/><path d="M12 21c5-5 7-8 7-11a7 7 0 1 0-14 0c0 3 2 6 7 11Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></span>
<div>
<div class="lbl">Регион работы</div>
<div class="val">Юг России · Ставропольский край · КМВ</div>
</div>
</div>
</div>
<div class="form-card reveal d1">
<h3>Оставить заявку</h3>
<p class="fsub">Опишите задачу — предложим подходящий тариф и план подключения.</p>
<form id="leadForm" novalidate>
<div class="field" id="f-name">
<label for="name">Имя</label>
<input id="name" name="name" type="text" placeholder="Как к вам обращаться" autocomplete="name" required />
<div class="err">Пожалуйста, укажите имя.</div>
</div>
<div class="field" id="f-contact">
<label for="contact">Telegram, WhatsApp или телефон</label>
<input id="contact" name="contact" type="text" placeholder="@username / +7 ... / e-mail" required />
<div class="err">Укажите контакт для связи.</div>
</div>
<div class="field" id="f-msg">
<label for="msg">Коротко о задаче</label>
<textarea id="msg" name="msg" placeholder="Что нужно: поддержка ПК, сеть между точками, серверы, видеонаблюдение?"></textarea>
</div>
<button class="btn-submit" type="submit">Отправить заявку</button>
<div class="form-result" id="formResult" role="status" aria-live="polite"></div>
<p class="form-note">Демонстрационная форма без отправки на сервер. Для реальных заявок подключается Telegram-бот / CRM.</p>
</form>
</div>
</div>
</div>
</section>
<!-- ============ FOOTER ============ -->
<footer class="footer" aria-label="Подвал сайта">
<div class="container">
<div class="foot-grid">
<div>
<a class="brand" href="#top" aria-label="servaki.online">
<span class="logo" aria-hidden="true"><span class="ring"></span><b>S</b></span>
<span class="brand-name">servaki.online<small>Ваш IT-отдел на орбите</small></span>
</a>
<p class="foot-about">Удалённая IT-поддержка для бизнеса на Юге России. Компьютеры, сети, серверы, видеонаблюдение и мониторинг 24/7 — мы рядом, даже если между нами горы.</p>
</div>
<div>
<h4>Разделы</h4>
<ul class="foot-links">
<li><a href="#about">О нас</a></li>
<li><a href="#services">Услуги</a></li>
<li><a href="#industries">Отрасли</a></li>
<li><a href="#pricing">Тарифы</a></li>
<li><a href="#gallery">Галерея</a></li>
</ul>
</div>
<div>
<h4>Контакты</h4>
<ul class="foot-links">
<li><a href="tel:+79620151414">+7 962 015-14-14</a></li>
<li><a href="https://t.me/servaki_online">Telegram @servaki_online</a></li>
<li><a href="https://wa.me/79620151414">WhatsApp</a></li>
<li>Юг России · КМВ</li>
</ul>
</div>
</div>
<div class="foot-bottom">
<div>© <span id="year"></span> servaki.online. Ваш IT-отдел на орбите.</div>
<div><a href="#top">Наверх ↑</a></div>
</div>
</div>
</footer>
</main>
<!-- ============ LIGHTBOX ============ -->
<div class="lightbox" id="lightbox" role="dialog" aria-modal="true" aria-label="Просмотр фотографии" aria-hidden="true">
<button class="lb-close" id="lbClose" type="button" aria-label="Закрыть просмотр (Esc)">✕</button>
<button class="lb-nav lb-prev" id="lbPrev" type="button" aria-label="Предыдущее фото">‹</button>
<button class="lb-nav lb-next" id="lbNext" type="button" aria-label="Следующее фото">›</button>
<figure class="lb-figure" id="lbFigure">
<img class="lb-img" id="lbImg" src="" alt="" />
<figcaption class="lb-cap"><span id="lbCap"></span> <span class="lb-count" id="lbCount"></span></figcaption>
</figure>
</div>
<script>
(function(){
"use strict";
var reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
var yEl = document.getElementById("year"); if(yEl){ yEl.textContent = new Date().getFullYear(); }
// FAILSAFE: показать контент даже если какой-то эффект упадёт (иначе .reveal=opacity:0 => белый экран)
setTimeout(function(){ try{ var rv=document.querySelectorAll(".reveal"); for(var k=0;k<rv.length;k++){ rv[k].classList.add("in"); } }catch(e){} }, 400);
// cyber terminal typing effect
(function typeLine(){
var el = document.getElementById("termType");
if(!el) return;
var txt = "reply 15ms · SLA OK";
if(reduce){ el.textContent = txt; return; }
var i = 0;
(function tick(){
el.textContent = txt.slice(0, i);
if(i++ <= txt.length) setTimeout(tick, 70);
})();
})();
// wireframe dotted globe (no external libs)
(function globe(){
try{
var c = document.getElementById("globe");
if(!c || !c.getContext) return;
var ctx = c.getContext("2d"), dpr = Math.min(window.devicePixelRatio||1, 2);
var R, Rbase, cx, cy, raf;
var TILT = 20*Math.PI/180, cosT = Math.cos(TILT), sinT = Math.sin(TILT); // наклон оси, как у планеты
var CY = [34,224,255], MG = [255,43,214]; // неон cyan / magenta
function col(rgb, a){ return "rgba("+rgb[0]+","+rgb[1]+","+rgb[2]+","+a+")"; }
function mix(a, b, t){ return [Math.round(a[0]+(b[0]-a[0])*t), Math.round(a[1]+(b[1]-a[1])*t), Math.round(a[2]+(b[2]-a[2])*t)]; }
// на узких экранах — реже сетка/дуги (производительность на смартфоне)
var small = (window.innerWidth || 1024) < 700;
var latInc = small ? 20 : 15, lonInc = small ? 24 : 18;
// ---- каркас: параллели и меридианы (сетка узлов) ----
var latVals = [], lonVals = [];
for(var la=-75; la<=75; la+=latInc) latVals.push(la);
for(var lo=0; lo<360; lo+=lonInc) lonVals.push(lo);
var grid = []; // grid[i][j] = базовая 3D-точка
for(var i=0;i<latVals.length;i++){
grid[i] = [];
var phi = latVals[i]*Math.PI/180;
for(var j=0;j<lonVals.length;j++){
var th = lonVals[j]*Math.PI/180;
grid[i][j] = {
x:Math.cos(phi)*Math.cos(th), y:Math.sin(phi), z:Math.cos(phi)*Math.sin(th),
accent:(latVals[i]%30===0 && lonVals[j]%36===0),
ph:Math.random()*6.283
};
}
}
// ---- дуги-связи (mesh): slerp по большой окружности + подъём над поверхностью ----
function sph(latd, lond){ var p=latd*Math.PI/180, t=lond*Math.PI/180; return {x:Math.cos(p)*Math.cos(t), y:Math.sin(p), z:Math.cos(p)*Math.sin(t)}; }
function slerp(a,b,t){
var d=a.x*b.x+a.y*b.y+a.z*b.z; d=Math.max(-1,Math.min(1,d));
var om=Math.acos(d), so=Math.sin(om);
if(so<1e-4) return {x:a.x,y:a.y,z:a.z};
var w1=Math.sin((1-t)*om)/so, w2=Math.sin(t*om)/so;
return {x:a.x*w1+b.x*w2, y:a.y*w1+b.y*w2, z:a.z*w1+b.z*w2};
}
var arcs = [], NARC = small ? 10 : 20, NSAMP = small ? 12 : 16;
for(var k=0;k<NARC;k++){
var a = sph(Math.random()*160-80, Math.random()*360);
var b = sph(Math.random()*160-80, Math.random()*360);
var lift = 0.18 + Math.random()*0.16;
var s = [];
for(var t=0;t<NSAMP;t++){
var tt=t/(NSAMP-1), v=slerp(a,b,tt);
var len=Math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z)||1;
var r=1 + lift*Math.sin(Math.PI*tt);
s.push({x:v.x/len*r, y:v.y/len*r, z:v.z/len*r});
}
arcs.push({s:s, speed:0.18+Math.random()*0.5, phase:Math.random(), puls:Math.random()*6.283});
}
function resize(){
var w = c.clientWidth || 400, h = c.clientHeight || 400;
c.width = Math.floor(w*dpr); c.height = Math.floor(h*dpr);
Rbase = Math.min(c.width, c.height)*0.40; cx = c.width/2; cy = c.height/2; R = Rbase;
}
var ang = 0.4, cosA=1, sinA=0;
function proj(p){
var x1 = p.x*cosA + p.z*sinA; // вращение вокруг оси Y
var z1 = -p.x*sinA + p.z*cosA;
var y1 = p.y;
var y2 = y1*cosT - z1*sinT; // наклон оси
var z2 = y1*sinT + z1*cosT;
return {sx:cx + x1*R, sy:cy - y2*R, d:(z2+1)/2};
}
function render(now){
var tsec = now*0.001;
R = Rbase*(1 + 0.018*Math.sin(now*0.0006)); // лёгкое «дыхание»
cosA = Math.cos(ang); sinA = Math.sin(ang);
ctx.clearRect(0,0,c.width,c.height);
// 1) атмосфера — радиальный halo
var atm = ctx.createRadialGradient(cx,cy,R*0.62, cx,cy,R*1.42);
atm.addColorStop(0,"rgba(34,224,255,0)");
atm.addColorStop(0.72,"rgba(34,224,255,.10)");
atm.addColorStop(0.9,"rgba(77,124,255,.14)");
atm.addColorStop(1,"rgba(139,92,246,0)");
ctx.fillStyle = atm; ctx.beginPath(); ctx.arc(cx,cy,R*1.42,0,6.283); ctx.fill();
// тонкий ободок
ctx.beginPath(); ctx.arc(cx,cy,R,0,6.283);
ctx.strokeStyle = "rgba(34,224,255,.22)"; ctx.lineWidth = 1.2*dpr; ctx.stroke();
// спроецировать сетку один раз за кадр
var P = [];
for(var i=0;i<grid.length;i++){ P[i]=[]; for(var j=0;j<grid[i].length;j++){ P[i][j]=proj(grid[i][j]); } }
ctx.globalCompositeOperation = "lighter";
ctx.lineWidth = 1*dpr;
// 2) каркас — параллели (кольца)
for(var i2=0;i2<P.length;i2++){
var ring=P[i2], n=ring.length;
for(var j2=0;j2<n;j2++){
var a1=ring[j2], b1=ring[(j2+1)%n];
var d=(a1.d+b1.d)/2; if(d<0.04) continue;
ctx.strokeStyle = col(CY, 0.05 + d*0.32);
ctx.beginPath(); ctx.moveTo(a1.sx,a1.sy); ctx.lineTo(b1.sx,b1.sy); ctx.stroke();
}
}
// каркас — меридианы
for(var j3=0;j3<lonVals.length;j3++){
for(var i3=0;i3<P.length-1;i3++){
var a2=P[i3][j3], b2=P[i3+1][j3];
var d2=(a2.d+b2.d)/2; if(d2<0.04) continue;
ctx.strokeStyle = col(CY, 0.04 + d2*0.28);
ctx.beginPath(); ctx.moveTo(a2.sx,a2.sy); ctx.lineTo(b2.sx,b2.sy); ctx.stroke();
}
}
// 3) дуги-связи с бегущим потоком
for(var k2=0;k2<arcs.length;k2++){
var arc=arcs[k2], s=arc.s, m=s.length, pr=[];
for(var q=0;q<m;q++) pr[q]=proj(s[q]);
var pulse = 0.55 + 0.45*Math.sin(tsec*1.6 + arc.puls);
for(var q2=0;q2<m-1;q2++){
var pa=pr[q2], pb=pr[q2+1];
var dd=(pa.d+pb.d)/2; if(dd<0.05) continue;
var tcol=q2/(m-2);
ctx.strokeStyle = col(mix(CY,MG,tcol), (0.06 + dd*0.42)*pulse);
ctx.lineWidth = (0.8 + dd*1.0)*dpr;
ctx.beginPath(); ctx.moveTo(pa.sx,pa.sy); ctx.lineTo(pb.sx,pb.sy); ctx.stroke();
}
// бегущий光 по дуге
var fp = (tsec*arc.speed + arc.phase) % 1;
var fi = fp*(m-1), i0=Math.floor(fi), fr=fi-i0;
if(i0>=0 && i0<m-1){
var fpt={sx:pr[i0].sx+(pr[i0+1].sx-pr[i0].sx)*fr, sy:pr[i0].sy+(pr[i0+1].sy-pr[i0].sy)*fr, d:pr[i0].d+(pr[i0+1].d-pr[i0].d)*fr};
if(fpt.d>0.12){
var fc=mix(CY,MG,fp);
ctx.fillStyle=col(fc,0.9*fpt.d);
ctx.beginPath(); ctx.arc(fpt.sx,fpt.sy,2.2*dpr,0,6.283); ctx.fill();
ctx.fillStyle=col(fc,0.18*fpt.d);
ctx.beginPath(); ctx.arc(fpt.sx,fpt.sy,6*dpr,0,6.283); ctx.fill();
}
}
ctx.lineWidth = 1*dpr;
}
// 4) узлы сетки — с глубиной и пульсацией
for(var i4=0;i4<P.length;i4++){
for(var j4=0;j4<P[i4].length;j4++){
var pp=P[i4][j4], g=grid[i4][j4], d3=pp.d;
var pulseN = g.accent ? (0.6 + 0.4*Math.sin(tsec*2.2 + g.ph)) : 1;
var base = g.accent ? 1.4 : 0.6;
var size = (base + d3*1.8)*dpr*pulseN;
var op = (g.accent ? 0.25 : 0.10) + d3*0.8;
ctx.fillStyle = g.accent ? col(MG, op) : col(CY, op);
ctx.beginPath(); ctx.arc(pp.sx,pp.sy,size,0,6.283); ctx.fill();
if(g.accent && d3>0.45){ // halo у ярких узлов
ctx.fillStyle = col(MG, 0.14*d3*pulseN);
ctx.beginPath(); ctx.arc(pp.sx,pp.sy,size*3.2,0,6.283); ctx.fill();
} else if(d3>0.8){
ctx.fillStyle = col([77,124,255], 0.12);
ctx.beginPath(); ctx.arc(pp.sx,pp.sy,size*2.4,0,6.283); ctx.fill();
}
}
}
ctx.globalCompositeOperation = "source-over";
}
function loop(now){ render(now||0); ang += 0.0022; raf = requestAnimationFrame(loop); }
resize(); if(reduce){ render(1200); } else { loop(0); }
var gt; window.addEventListener("resize", function(){ clearTimeout(gt); gt = setTimeout(function(){ resize(); if(reduce) render(1200); }, 200); });
}catch(ge){ /* globe fail — не ломаем страницу */ }
})();
// draggable terminal window (OS-style, pointer + touch)
(function dragTerminal(){
try{
var term = document.querySelector(".terminal");
if(!term) return;
var bar = term.querySelector(".term-bar");
if(!bar) return;
var tx = 0, ty = 0, px0 = 0, py0 = 0, dragging = false;
function apply(){ term.style.transform = "translate(" + tx + "px," + ty + "px)"; }
function clampToViewport(){
var r = term.getBoundingClientRect();
var m = 8;
var baseLeft = r.left - tx, baseTop = r.top - ty; // положение без текущего сдвига
var minX = m - baseLeft, maxX = window.innerWidth - m - (baseLeft + r.width);
var minY = m - baseTop, maxY = window.innerHeight - m - (baseTop + r.height);
if(maxX < minX){ maxX = minX; } if(maxY < minY){ maxY = minY; }
if(tx < minX) tx = minX; else if(tx > maxX) tx = maxX;
if(ty < minY) ty = minY; else if(ty > maxY) ty = maxY;
}
function start(x, y){ dragging = true; px0 = x; py0 = y; term.classList.add("dragging"); }
function move(x, y){ if(!dragging) return; tx += x - px0; ty += y - py0; px0 = x; py0 = y; clampToViewport(); apply(); }
function end(){ if(!dragging) return; dragging = false; term.classList.remove("dragging"); }
if(window.PointerEvent){
bar.addEventListener("pointerdown", function(e){
if(e.button && e.button !== 0) return;
start(e.clientX, e.clientY);
try{ bar.setPointerCapture(e.pointerId); }catch(_){}
e.preventDefault();
});
bar.addEventListener("pointermove", function(e){ if(dragging){ move(e.clientX, e.clientY); e.preventDefault(); } });
bar.addEventListener("pointerup", end);
bar.addEventListener("pointercancel", end);
// подстраховка, если capture недоступен
document.addEventListener("pointermove", function(e){ if(dragging) move(e.clientX, e.clientY); });
document.addEventListener("pointerup", end);
} else {
bar.addEventListener("mousedown", function(e){ start(e.clientX, e.clientY); e.preventDefault(); });
document.addEventListener("mousemove", function(e){ if(dragging){ move(e.clientX, e.clientY); } });
document.addEventListener("mouseup", end);
bar.addEventListener("touchstart", function(e){ var t = e.touches[0]; start(t.clientX, t.clientY); }, {passive:true});
document.addEventListener("touchmove", function(e){ if(dragging){ var t = e.touches[0]; move(t.clientX, t.clientY); e.preventDefault(); } }, {passive:false});
document.addEventListener("touchend", end);
document.addEventListener("touchcancel", end);
}
window.addEventListener("resize", function(){ if(tx || ty){ clampToViewport(); apply(); } });
}catch(de){ /* drag fail — не ломаем страницу */ }
})();
// terminal window controls: close / minimize / restore
(function terminalControls(){
try{
var term = document.querySelector(".terminal");
if(!term) return;
var bar = term.querySelector(".term-bar");
var restore = document.getElementById("termRestore");
var dots = term.querySelectorAll(".term-bar .d");
function setClosed(v){ term.classList.toggle("closed", v); if(restore){ restore.hidden = !v; } }
function act(name){
if(name === "close"){ setClosed(true); }
else if(name === "min"){ term.classList.toggle("min"); }
else if(name === "max"){ term.classList.remove("min"); setClosed(false); }
}
for(var i=0;i<dots.length;i++){
(function(d){
var name = d.getAttribute("data-act");
// клик по точке не должен запускать перетаскивание
d.addEventListener("pointerdown", function(e){ e.stopPropagation(); });
d.addEventListener("mousedown", function(e){ e.stopPropagation(); });
d.addEventListener("touchstart", function(e){ e.stopPropagation(); }, {passive:true});
d.addEventListener("click", function(e){ e.stopPropagation(); act(name); });
d.addEventListener("keydown", function(e){ if(e.key === "Enter" || e.key === " "){ e.preventDefault(); act(name); } });
})(d);
}
// клик по свёрнутой шапке — развернуть
if(bar){ bar.addEventListener("click", function(e){ if(term.classList.contains("min")){ term.classList.remove("min"); } }); }
if(restore){ restore.addEventListener("click", function(){ setClosed(false); term.classList.remove("min"); }); }
}catch(tc){ /* controls fail — не ломаем страницу */ }
})();
// lightbox для галереи (увеличение фото)
(function lightbox(){
try{
var lb = document.getElementById("lightbox");
if(!lb) return;
var items = Array.prototype.slice.call(document.querySelectorAll(".gallery .gitem"));
if(!items.length) return;
var imgEl = document.getElementById("lbImg");
var capEl = document.getElementById("lbCap");
var countEl = document.getElementById("lbCount");
var closeBtn = document.getElementById("lbClose");
var prevBtn = document.getElementById("lbPrev");
var nextBtn = document.getElementById("lbNext");
var data = items.map(function(fig){
var im = fig.querySelector("img");
var cap = fig.querySelector(".cap");
return { src: im ? im.getAttribute("src") : "", alt: im ? im.getAttribute("alt") : "", cap: cap ? (cap.textContent||"").trim() : "" };
});
var idx = 0, lastFocus = null;
function show(i){
idx = (i + data.length) % data.length;
var d = data[idx];
imgEl.setAttribute("src", d.src);
imgEl.setAttribute("alt", d.alt);
if(capEl) capEl.textContent = d.cap;
if(countEl) countEl.textContent = (idx+1) + " / " + data.length;
}
function open(i){
lastFocus = document.activeElement;
show(i);
lb.classList.add("open");
lb.setAttribute("aria-hidden", "false");
document.body.style.overflow = "hidden";
if(closeBtn) closeBtn.focus();
}
function close(){
lb.classList.remove("open");
lb.setAttribute("aria-hidden", "true");
document.body.style.overflow = "";
if(lastFocus && lastFocus.focus) lastFocus.focus();
}
items.forEach(function(fig, i){
fig.addEventListener("click", function(){ open(i); });
fig.addEventListener("keydown", function(e){ if(e.key === "Enter" || e.key === " "){ e.preventDefault(); open(i); } });
});
if(closeBtn) closeBtn.addEventListener("click", close);
if(prevBtn) prevBtn.addEventListener("click", function(e){ e.stopPropagation(); show(idx-1); });
if(nextBtn) nextBtn.addEventListener("click", function(e){ e.stopPropagation(); show(idx+1); });
lb.addEventListener("click", function(e){ if(e.target === lb){ close(); } });
document.addEventListener("keydown", function(e){
if(!lb.classList.contains("open")) return;
if(e.key === "Escape") close();
else if(e.key === "ArrowLeft") show(idx-1);
else if(e.key === "ArrowRight") show(idx+1);
});
// свайп на тач для листания
var sx0 = 0, sy0 = 0, sw = false;
lb.addEventListener("touchstart", function(e){ var t = e.touches[0]; sx0 = t.clientX; sy0 = t.clientY; sw = true; }, {passive:true});
lb.addEventListener("touchend", function(e){
if(!sw) return; sw = false;
var t = e.changedTouches[0], dx = t.clientX - sx0, dy = t.clientY - sy0;
if(Math.abs(dx) > 45 && Math.abs(dx) > Math.abs(dy)){ show(dx < 0 ? idx+1 : idx-1); }
}, {passive:true});
}catch(lbe){ /* lightbox fail — не ломаем страницу */ }
})();
// starfield canvas
(function starfield(){
var c = document.getElementById("stars");
if(!c) return;
var ctx = c.getContext("2d"), stars = [], w, h, dpr = Math.min(window.devicePixelRatio||1, 2);
function resize(){
w = c.width = Math.floor(innerWidth*dpr); h = c.height = Math.floor(innerHeight*dpr);
c.style.width = innerWidth+"px"; c.style.height = innerHeight+"px";
var count = Math.min(140, Math.floor(innerWidth*innerHeight/14000));
stars = [];
for(var i=0;i<count;i++){
stars.push({x:Math.random()*w, y:Math.random()*h, r:(Math.random()*1.3+.3)*dpr, a:Math.random(), s:Math.random()*.02+.004});
}
}
function draw(){
ctx.clearRect(0,0,w,h);
for(var i=0;i<stars.length;i++){
var st = stars[i];
st.a += st.s; var tw = .5 + .5*Math.sin(st.a);
ctx.globalAlpha = .25 + tw*.6;
ctx.fillStyle = i%7===0 ? "#7cf3e0" : (i%5===0 ? "#9bc2ff" : "#ffffff");
ctx.beginPath(); ctx.arc(st.x, st.y, st.r, 0, 6.283); ctx.fill();
}
if(!reduce) requestAnimationFrame(draw);
}
resize(); draw();
var rt; window.addEventListener("resize", function(){ clearTimeout(rt); rt = setTimeout(resize, 200); });
})();
// sticky nav
var nav = document.getElementById("nav");
var onScroll = function(){ nav.classList.toggle("scrolled", window.scrollY > 8); };
onScroll(); window.addEventListener("scroll", onScroll, {passive:true});
// mobile menu
var toggle = document.getElementById("navToggle"), menu = document.getElementById("menu");
toggle.addEventListener("click", function(){
var open = menu.classList.toggle("open");
toggle.setAttribute("aria-expanded", open ? "true" : "false");
});
menu.addEventListener("click", function(e){
if(e.target.tagName === "A"){ menu.classList.remove("open"); toggle.setAttribute("aria-expanded","false"); }
});
// reveal
var reveals = document.querySelectorAll(".reveal");
if(reduce || !("IntersectionObserver" in window)){
reveals.forEach(function(el){ el.classList.add("in"); });
} else {
var ro = new IntersectionObserver(function(entries){
entries.forEach(function(en){ if(en.isIntersecting){ en.target.classList.add("in"); ro.unobserve(en.target); } });
}, {threshold:.12, rootMargin:"0px 0px -8% 0px"});
reveals.forEach(function(el){ ro.observe(el); });
}
// counters
function animateCount(el){
var target = parseInt(el.getAttribute("data-count"), 10);
var suf = el.getAttribute("data-suf") || "";
var dur = 1300, start = null;
function step(ts){
if(!start) start = ts;
var p = Math.min((ts-start)/dur, 1), eased = 1 - Math.pow(1-p, 3), val = Math.round(target*eased);
el.innerHTML = val + (suf ? '<span class="suf">'+suf+'</span>' : '');
if(p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
var counters = document.querySelectorAll("[data-count]");
if(reduce || !("IntersectionObserver" in window)){
counters.forEach(function(el){ el.innerHTML = el.getAttribute("data-count") + (el.getAttribute("data-suf") ? '<span class="suf">'+el.getAttribute("data-suf")+'</span>' : ''); });
} else {
var co = new IntersectionObserver(function(entries){
entries.forEach(function(en){ if(en.isIntersecting){ animateCount(en.target); co.unobserve(en.target); } });
}, {threshold:.5});
counters.forEach(function(el){ co.observe(el); });
}
// scrollspy
var links = Array.prototype.slice.call(menu.querySelectorAll("a[href^='#']"));
var sections = links.map(function(a){ return document.getElementById(a.getAttribute("href").slice(1)); });
if("IntersectionObserver" in window){
var spy = new IntersectionObserver(function(entries){
entries.forEach(function(en){
if(en.isIntersecting){
links.forEach(function(a){ a.classList.toggle("active", a.getAttribute("href") === "#"+en.target.id); });
}
});
}, {rootMargin:"-45% 0px -50% 0px"});
sections.forEach(function(s){ if(s) spy.observe(s); });
}
// form validation
var form = document.getElementById("leadForm"), out = document.getElementById("formResult");
function setInvalid(id, bad){ document.getElementById(id).classList.toggle("invalid", bad); }
form.addEventListener("submit", function(e){
e.preventDefault();
var name = form.name.value.trim(), contact = form.contact.value.trim();
var ok = true;
setInvalid("f-name", !name); if(!name) ok = false;
setInvalid("f-contact", contact.length < 3); if(contact.length < 3) ok = false;
if(!ok){ out.style.color = "#fca5a5"; out.textContent = "Проверьте выделенные поля."; return; }
out.style.color = "#5eead4";
out.textContent = "Спасибо, " + name + "! Заявка принята (демо). Свяжемся по указанному контакту.";
form.reset(); setInvalid("f-name", false); setInvalid("f-contact", false);
});
["name","contact"].forEach(function(n){
form[n].addEventListener("input", function(){ document.getElementById("f-"+n).classList.remove("invalid"); });
});
})();
</script>
</body>
</html>