Files

1677 lines
136 KiB
HTML
Raw Permalink 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>IT-поддержка бизнеса на КМВ и Юге России — servaki.online</title>
<!-- SEO -->
<meta name="description" content="IT-поддержка бизнеса на КМВ и Юге России: рабочие места, сети и VPN, серверы, видеонаблюдение и удалённые объекты. Услуги, тарифы и порядок обращения." />
<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="IT-поддержка бизнеса на КМВ и Юге России — servaki.online" />
<meta property="og:description" content="Поддержка рабочих мест, сетей, серверов и удалённых объектов для бизнеса на Юге России." />
<meta property="og:url" content="https://servaki.online/" />
<meta property="og:image" content="https://servaki.online/assets/editorial/remote-sites-1536.webp" />
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="IT-поддержка бизнеса на КМВ и Юге России — servaki.online" />
<meta name="twitter:description" content="Рабочие места, сети и VPN, серверы, видеонаблюдение и удалённые объекты. Услуги и тарифы servaki.online." />
<meta name="twitter:image" content="https://servaki.online/assets/editorial/remote-sites-1536.webp" />
<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": "9000",
"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": "21000",
"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": "45000",
"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 -->
<link rel="stylesheet" href="/assets/editorial/motion.css"><script src="/assets/editorial/motion.js" defer></script><style>.card{display:flex;flex-direction:column}.card-landing{display:block;margin-top:22px;border-radius:12px;overflow:hidden;border:1px solid rgba(255,255,255,.12);position:relative;z-index:2}.card-landing img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;transition:transform .25s}.card-landing span{display:block;min-height:67px;padding:14px 15px;background:#0c1326;color:#67e8f9;font-size:13px;font-weight:600;line-height:1.5}.card-landing:hover img{transform:scale(1.025)}.card-landing:focus-visible{outline:3px solid #22d3ee;outline-offset:4px}.ind .card-landing{margin:0 24px 24px}.ind .body{padding-top:26px}.card .card-landing{margin-top:auto}.card h3+p{margin-bottom:22px}.card .stack{margin-bottom:22px}body .reveal{opacity:1;transform:none}.editorial-entry{color:#67e8f9!important}@media(prefers-reduced-motion:reduce){.card-landing img{transition:none}}</style></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>При сбое связи, компьютера или сервиса принимаем заявку, оцениваем влияние на работу и начинаем диагностику. Отклик от 15 минут зависит от тарифа; срок устранения определяем после выяснения причины.</p>
<a class="card-landing" href="/approach/rapid-response/" aria-label="Подробнее: Реакция от 15 минут"><div class="motion-visual"><img src="/assets/editorial/rapid-response-960.webp" srcset="/assets/editorial/rapid-response-480.webp 480w, /assets/editorial/rapid-response-960.webp 960w, /assets/editorial/rapid-response-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Рабочее место IT-поддержки и световая шкала времени в тёмно-синей палитре" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M245 380 C280 336 291 286 319 243 C409 236 466 207 547 161"/><circle class="motion-packet" r="6"><animateMotion path="M245 380 C280 336 291 286 319 243 C409 236 466 207 547 161" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M245 380 C280 336 291 286 319 243 C409 236 466 207 547 161" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="245" cy="380" r="7"/><circle class="motion-light" cx="319" cy="243" r="7"/><circle class="motion-light" cx="547" cy="161" r="7"/></svg></div><span>Подробнее: Реакция от 15 минут <b aria-hidden="true">↗</b></span></a></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>
<a class="card-landing" href="/approach/remote-sites/" aria-label="Подробнее: Работаем с удалёнными точками"><div class="motion-visual"><img src="/assets/editorial/remote-sites-960.webp" srcset="/assets/editorial/remote-sites-480.webp 480w, /assets/editorial/remote-sites-960.webp 960w, /assets/editorial/remote-sites-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Ферма, склад и горная база связаны голубыми линиями сети в кавказской долине" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M172 252 C270 128 344 152 480 386 C610 185 719 162 809 271"/><circle class="motion-packet" r="6"><animateMotion path="M172 252 C270 128 344 152 480 386 C610 185 719 162 809 271" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M172 252 C270 128 344 152 480 386 C610 185 719 162 809 271" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="172" cy="252" r="7"/><circle class="motion-light" cx="480" cy="386" r="7"/><circle class="motion-light" cx="809" cy="271" r="7"/></svg></div><span>Подробнее: Работаем с удалёнными точками <b aria-hidden="true">↗</b></span></a></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>Обслуживание рабочих мест и инфраструктуры по понятному ежемесячному плану: состав работ, ответственные и время отклика согласованы заранее. Помогаем не копить сбои до остановки работы.</p>
<a class="card-landing" href="/approach/it-subscription/" aria-label="Подробнее: Доступные подписки"><div class="motion-visual"><img src="/assets/editorial/it-subscription-960.webp" srcset="/assets/editorial/it-subscription-480.webp 480w, /assets/editorial/it-subscription-960.webp 960w, /assets/editorial/it-subscription-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Компьютер, сервер и роутер на упорядоченных модульных платформах" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M218 371 C344 400 362 287 479 265 C601 208 661 309 800 303"/><circle class="motion-packet" r="6"><animateMotion path="M218 371 C344 400 362 287 479 265 C601 208 661 309 800 303" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M218 371 C344 400 362 287 479 265 C601 208 661 309 800 303" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="218" cy="371" r="7"/><circle class="motion-light" cx="479" cy="265" r="7"/><circle class="motion-light" cx="800" cy="303" r="7"/></svg></div><span>Подробнее: Доступные подписки <b aria-hidden="true">↗</b></span></a></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>
<a class="card-landing" href="/services/remote-desktop/" aria-label="Подробнее: Удалённый рабочий стол"><div class="motion-visual"><img src="/assets/editorial/remote-desktop-960.webp" srcset="/assets/editorial/remote-desktop-480.webp 480w, /assets/editorial/remote-desktop-960.webp 960w, /assets/editorial/remote-desktop-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Офисный компьютер и компактный принтер с защищённым каналом удалённой помощи" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M247 286 C344 127 543 150 772 204"/><circle class="motion-packet" r="6"><animateMotion path="M247 286 C344 127 543 150 772 204" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M247 286 C344 127 543 150 772 204" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="247" cy="286" r="7"/><circle class="motion-light" cx="772" cy="204" r="7"/></svg></div><span>Подробнее: Удалённый рабочий стол <b aria-hidden="true">↗</b></span></a></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>
<a class="card-landing" href="/services/networks-vpn/" aria-label="Подробнее: Сети и VPN"><div class="motion-visual"><img src="/assets/editorial/networks-vpn-960.webp" srcset="/assets/editorial/networks-vpn-480.webp 480w, /assets/editorial/networks-vpn-960.webp 960w, /assets/editorial/networks-vpn-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Маршрутизатор и сетевой коммутатор соединяют несколько офисных миниатюр световыми линиями" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M146 375 C284 492 389 498 480 413 C589 503 709 491 810 366"/><circle class="motion-packet" r="6"><animateMotion path="M146 375 C284 492 389 498 480 413 C589 503 709 491 810 366" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M146 375 C284 492 389 498 480 413 C589 503 709 491 810 366" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><path class="motion-path" d="M480 413 C468 269 500 211 477 154"/><circle class="motion-packet" r="6"><animateMotion path="M480 413 C468 269 500 211 477 154" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M480 413 C468 269 500 211 477 154" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="146" cy="375" r="7"/><circle class="motion-light" cx="480" cy="413" r="7"/><circle class="motion-light" cx="810" cy="366" r="7"/><circle class="motion-light" cx="477" cy="154" r="7"/></svg></div><span>Подробнее: Сети и VPN <b aria-hidden="true">↗</b></span></a></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>
<a class="card-landing" href="/services/monitoring-security/" aria-label="Подробнее: Мониторинг и безопасность"><div class="motion-visual"><img src="/assets/editorial/monitoring-security-960.webp" srcset="/assets/editorial/monitoring-security-480.webp 480w, /assets/editorial/monitoring-security-960.webp 960w, /assets/editorial/monitoring-security-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Панель наблюдения за серверами, сигналы доступности и защищённое резервное хранилище" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M353 412 C481 492 567 444 673 450 C733 407 767 346 770 275"/><circle class="motion-packet" r="6"><animateMotion path="M353 412 C481 492 567 444 673 450 C733 407 767 346 770 275" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M353 412 C481 492 567 444 673 450 C733 407 767 346 770 275" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="353" cy="412" r="7"/><circle class="motion-light" cx="673" cy="450" r="7"/><circle class="motion-light" cx="770" cy="275" r="7"/></svg></div><span>Подробнее: Мониторинг и безопасность <b aria-hidden="true">↗</b></span></a></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>Подбираем камеры, запись и удалённый просмотр под задачи объекта. Учитываем зоны обзора, питание, хранение архива и права доступа, чтобы система помогала в работе.</p>
<a class="card-landing" href="/services/video-surveillance/" aria-label="Подробнее: Видеонаблюдение"><div class="motion-visual"><img src="/assets/editorial/video-surveillance-960.webp" srcset="/assets/editorial/video-surveillance-480.webp 480w, /assets/editorial/video-surveillance-960.webp 960w, /assets/editorial/video-surveillance-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="IP-камера над складской площадкой и видеорегистратор в тёмной технологической композиции" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M164 169 C287 176 416 287 416 428 C335 463 241 478 183 541"/><circle class="motion-packet" r="6"><animateMotion path="M164 169 C287 176 416 287 416 428 C335 463 241 478 183 541" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M164 169 C287 176 416 287 416 428 C335 463 241 478 183 541" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="164" cy="169" r="7"/><circle class="motion-light" cx="416" cy="428" r="7"/><circle class="motion-light" cx="183" cy="541" r="7"/></svg></div><span>Подробнее: Видеонаблюдение <b aria-hidden="true">↗</b></span></a></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>Размещаем и сопровождаем серверы для рабочих приложений, чатов и внутренних сервисов. Контролируем доступы, обновления и резервные копии, согласуем перенос до начала работ.</p>
<div class="stack"><span>Proxmox</span><span>Docker</span><span>CRM · 1С</span></div>
<a class="card-landing" href="/services/servers-hosting/" aria-label="Подробнее: Серверы и хостинг"><div class="motion-visual"><img src="/assets/editorial/servers-hosting-960.webp" srcset="/assets/editorial/servers-hosting-480.webp 480w, /assets/editorial/servers-hosting-960.webp 960w, /assets/editorial/servers-hosting-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Компактная серверная стойка с синим и бирюзовым светом и орбитальной линией резервирования" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M455 418 C317 348 340 190 502 171 C705 139 824 307 737 405 C662 493 549 483 455 418"/><circle class="motion-packet" r="6"><animateMotion path="M455 418 C317 348 340 190 502 171 C705 139 824 307 737 405 C662 493 549 483 455 418" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M455 418 C317 348 340 190 502 171 C705 139 824 307 737 405 C662 493 549 483 455 418" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="455" cy="418" r="7"/><circle class="motion-light" cx="502" cy="171" r="7"/><circle class="motion-light" cx="737" cy="405" r="7"/></svg></div><span>Подробнее: Серверы и хостинг <b aria-hidden="true">↗</b></span></a></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>Соединяем датчики, учётные системы и уведомления в понятный рабочий процесс. Боты сообщают о событиях и собирают данные; управляющие команды доступны согласованным сотрудникам.</p>
<a class="card-landing" href="/services/automation/" aria-label="Подробнее: Автоматизация"><div class="motion-visual"><img src="/assets/editorial/automation-960.webp" srcset="/assets/editorial/automation-480.webp 480w, /assets/editorial/automation-960.webp 960w, /assets/editorial/automation-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Промышленный контроллер, датчик и телефон соединены световыми потоками событий" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M387 333 C501 177 633 180 703 317 C751 375 787 366 820 311"/><circle class="motion-packet" r="6"><animateMotion path="M387 333 C501 177 633 180 703 317 C751 375 787 366 820 311" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M387 333 C501 177 633 180 703 317 C751 375 787 366 820 311" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="387" cy="333" r="7"/><circle class="motion-light" cx="703" cy="317" r="7"/><circle class="motion-light" cx="820" cy="311" r="7"/></svg></div><span>Подробнее: Автоматизация <b aria-hidden="true">↗</b></span></a></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="body">
<h3>HoReCa</h3>
<p>Для гостиниц и кафе проектируем разделение гостевого Wi-Fi и рабочих систем, помогаем с кассами и служебными сервисами. Доступ к данным гостей определяется правилами заведения.</p>
</div>
<a class="card-landing" href="/industries/horeca/" aria-label="Подробнее: HoReCa"><div class="motion-visual"><img src="/assets/editorial/horeca-960.webp" srcset="/assets/editorial/horeca-480.webp 480w, /assets/editorial/horeca-960.webp 960w, /assets/editorial/horeca-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Уютный ресторан при горном отеле со стойкой администратора и деликатными линиями Wi-Fi" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M622 138 C502 109 409 160 351 284 C398 372 512 403 622 373"/><circle class="motion-packet" r="6"><animateMotion path="M622 138 C502 109 409 160 351 284 C398 372 512 403 622 373" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M622 138 C502 109 409 160 351 284 C398 372 512 403 622 373" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="622" cy="138" r="7"/><circle class="motion-light" cx="351" cy="284" r="7"/><circle class="motion-light" cx="622" cy="373" r="7"/></svg></div><span>Подробнее: HoReCa <b aria-hidden="true">↗</b></span></a></article>
<article class="ind ind-2 reveal d1">
<div class="body">
<h3>Агросектор</h3>
<p>На фермах и складах связываем датчики, весовые, камеры и удалённые площадки. Проверяем связь и питание, чтобы ответственные получали нужные показатели и понимали причину сбоя.</p>
</div>
<a class="card-landing" href="/industries/agriculture/" aria-label="Подробнее: Агросектор"><div class="motion-visual"><img src="/assets/editorial/agriculture-960.webp" srcset="/assets/editorial/agriculture-480.webp 480w, /assets/editorial/agriculture-960.webp 960w, /assets/editorial/agriculture-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Ферма у гор, весовая площадка и зерновое хранилище с деликатной визуализацией сети датчиков" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M174 309 C338 177 492 172 609 288 C716 314 790 382 835 450"/><circle class="motion-packet" r="6"><animateMotion path="M174 309 C338 177 492 172 609 288 C716 314 790 382 835 450" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M174 309 C338 177 492 172 609 288 C716 314 790 382 835 450" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="174" cy="309" r="7"/><circle class="motion-light" cx="609" cy="288" r="7"/><circle class="motion-light" cx="835" cy="450" r="7"/></svg></div><span>Подробнее: Агросектор <b aria-hidden="true">↗</b></span></a></article>
<article class="ind ind-3 reveal d2">
<div class="body">
<h3>Строительство</h3>
<p>Организуем временные сети, рабочие места и камеры на стройплощадке. Учитываем перенос оборудования по этапам работ, питание, схему доступа и передачу настроек.</p>
</div>
<a class="card-landing" href="/industries/construction/" aria-label="Подробнее: Строительство"><div class="motion-visual"><img src="/assets/editorial/construction-960.webp" srcset="/assets/editorial/construction-480.webp 480w, /assets/editorial/construction-960.webp 960w, /assets/editorial/construction-1536.webp 1536w" sizes="(max-width: 600px) 100vw, 380px" width="1536" height="1024" alt="Строительная площадка с краном, модульным офисом и камерой на фоне гор в ночной палитре" loading="lazy" decoding="async"><svg class="motion-overlay" viewBox="0 0 960 640" preserveAspectRatio="xMidYMid slice" aria-hidden="true" focusable="false"><path class="motion-path" d="M165 232 C282 116 446 119 563 243 C698 294 768 332 828 421"/><circle class="motion-packet" r="6"><animateMotion path="M165 232 C282 116 446 119 563 243 C698 294 768 332 828 421" dur="4.8s" repeatCount="indefinite"/></circle><circle class="motion-packet motion-packet-late" r="4"><animateMotion path="M165 232 C282 116 446 119 563 243 C698 294 768 332 828 421" dur="4.8s" begin="2.4s" repeatCount="indefinite"/></circle><circle class="motion-light" cx="165" cy="232" r="7"/><circle class="motion-light" cx="563" cy="243" r="7"/><circle class="motion-light" cx="828" cy="421" r="7"/></svg></div><span>Подробнее: Строительство <b aria-hidden="true">↗</b></span></a></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">Простой и прозрачный процесс — от вашего сообщения до постоянного мониторинга. <a class="editorial-entry" href="/approach/rapid-response/">Как устроена поддержка →</a></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><a class="editorial-entry" href="/approach/it-subscription/">Что входит в обслуживание и как выбрать тариф →</a></p>
<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">9 000</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">21 000</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">45 000</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="/approach/">Наш подход</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>