Анализ сайта narad-dopusk.ru
Основное Готовность: 100%
Домен
narad-dopusk.ru
Состояние доменного имени
?
Проверяем корректность доменного имени и наличие технических проблем на уровне домена.
Домен второго уровня идеален для продвижения.
Отличный запоминающийся домен.
Регистратор домена - RU-CENTER-RU
Дата регистрации домена 30.07.2026 (более 2 недель назад)
Ответ сервера
200 Успешный ответ
HTTP-код ответа и цепочка редиректов
?
Код 200 — страница доступна. Коды 3xx — редиректы (цепочки замедляют загрузку и размывают ссылочный вес). Коды 4xx/5xx — ошибки, поисковик не сможет проиндексировать страницу.
Сервер настроен корректно.
Цепочка редиректов:
http://narad-dopusk.ru
308 PermanentRedirect
https://narad-dopusk.ru/
200 OK
Безопасность
Сайт безопасен
Использование HTTPS и SSL-сертификат
?
HTTPS — обязательный стандарт. Google и Яндекс отдают предпочтение защищённым сайтам. Отсутствие SSL или просроченный сертификат ведут к предупреждениям в браузере и снижению позиций.
На сайте работает защищенный протокол ssl и сайт открывается по https.
Ssl-сертификат действителен до 31.10.2026 20:42:10.
Сервер поддерживает HTTP/3 (QUIC) — новейший протокол.
Включён HSTS (Strict-Transport-Security) — защита от подмены на http.
HTTP автоматически перенаправляется на HTTPS.
Поздравляем! Сайт не содержится в реестре РКН.
Кодировка
UTF-8
Кодировка символов страницы
?
Стандарт — UTF-8. Неправильная кодировка вызывает нечитаемые символы и мешает поисковику корректно распознать текст страницы.
Указана кодировка на странице UTF-8.
Язык
ru
Атрибут lang в HTML-теге
?
Атрибут lang (<html lang="ru">) сообщает поисковикам и браузерам, на каком языке написана страница. Помогает при ранжировании в региональном поиске.
Указан язык документа ru.
Скорость загрузки
~0,42сек
Время отклика сервера (TTFB)
?
Time To First Byte — время до получения первого байта от сервера. Норма до 200 мс. Медленный отклик ухудшает пользовательский опыт и ранжирование: Яндекс и Google учитывают скорость страниц.
Скорость загрузки сайта 0,42сек оптимальна.
Объем документа
112Кб
Размер HTML-кода страницы
?
Слишком большой HTML замедляет парсинг браузером и сканирование поисковым роботом. Рекомендуется не более 200 Кб.
Объем html-документа 112Кб оптимален.
Структура html-документа корректна.
Ресурсы
Ресурсы: 1
Внешние ресурсы страницы (CSS, JS, изображения)
?
Количество и тип подключённых ресурсов влияют на скорость загрузки. Большое число запросов увеличивает время рендеринга страницы.
Кол-во файлов ресурсов 1 достаточно.
Показать полный список ресурсов
| Тип | Название | Значение |
|---|---|---|
| stylesheet | https://fonts.googleapis.com/css2?family=Bebas+Neue&family=IBM+Plex+Sans:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap |
Серверные заголовки
Кол-во: 12
HTTP-заголовки ответа сервера
?
Заголовки сервера передают браузеру и поисковику служебную информацию: кеширование, безопасность (CSP, HSTS), сжатие (gzip). Правильная настройка ускоряет загрузку и повышает защищённость.
Найдены серверные заголовки 12шт. Подробнее про серверные заголовки.
Показать полный список серверных заголовков
| Ключ | Значение |
|---|---|
| Accept-Ranges | bytes |
| Alt-Svc | h3=":443"; ma=2592000 |
| Cache-Control | public, max-age=86400 |
| Content-Security-Policy | default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'self' |
| Date | Wed, 19 Aug 2026 11:36:49 GMT |
| ETag | "6a6c57c6-21ea4" |
| permissions-policy | geolocation=(), microphone=(), camera=() |
| Referrer-Policy | strict-origin-when-cross-origin |
| Strict-Transport-Security | max-age=31536000; includeSubDomains; preload |
| Via | 1.1 Caddy |
| X-Content-Type-Options | nosniff |
| X-Frame-Options | SAMEORIGIN |
CMS
Не определена
Система управления сайтом (движок)
?
CMS — это движок, на котором работает сайт (WordPress, 1C-Bitrix, Tilda и др.). Знание CMS помогает понять возможности SEO-оптимизации и подобрать подходящие инструменты. «Не определена» — вероятно, самописный сайт или нестандартная сборка.
CMS не определена. Вероятно, сайт самописный либо движок надёжно скрыт. Это не ошибка.
Веб-сервер
Не определён
Программное обеспечение сервера
?
Веб-сервер — это ПО, которое отдаёт страницы посетителям (nginx, Apache, IIS, LiteSpeed и др.). Определяется по серверным заголовкам ответа (Server, X-Powered-By и т.п.). «Не определён» — сервер намеренно скрывает эти заголовки, это нормальная практика безопасности.
Веб-сервер не определён — заголовок Server скрыт. Это не ошибка: часто так настраивают из соображений безопасности.
Мета-теги Готовность: 23%
Title
Наряд-Допуск v2.21 — Электронные наряды-допуски, медосмотры, ИОТ, ОПР, ПАБ, IoT на ОПО
Заголовок страницы в браузере и поисковой выдаче
?
Title — главный SEO-заголовок страницы. Влияет на CTR в поиске и ранжирование. Оптимальная длина: 50–70 символов. Ключевые слова — ближе к началу.
Необходимо уменьшить число символов в title (текущее значение: 86, оптимально: от 40 до 45)
Дублей словоформ в title не найдено.
Description
Электронные наряды-допуски на ОПО + 12 модулей v2.21: медосмотры, ИОТ, стажировки, СИЗ и поверки, ОПР, ПАБ, скоринг подрядчиков, микротравмы, IoT-телеметрия, расследования НС. 4 микросервиса, Ed25519 + AES-GCM + Argon2id.
Описание страницы в поисковой выдаче (сниппет)
?
Meta Description — текст под заголовком в выдаче. Напрямую на позиции не влияет, но влияет на CTR. Оптимальная длина: 120–160 символов.
Необходимо уменьшить число символов в description (текущее значение: 221, оптимально: от 120 до 130)
Keywords
Список ключевых слов страницы (устаревший тег)
?
Meta Keywords не учитывается Яндексом и Google для ранжирования с 2009–2012 годов. Заполнение не обязательно, но не вредит. Конкурент может использовать содержимое для анализа.
Установите мета-тег keywords!
Канонический Url
https://narad-dopusk.ru/
Указывает поисковику основную версию страницы
?
Canonical (rel=canonical) предотвращает проблему дублей страниц. Должен точно совпадать с URL проверяемой страницы. Неправильный canonical может передать ссылочный вес на другую страницу.
Канонический Url прописан корректно.
Robots
index, follow
Директивы для поисковых роботов на уровне страницы
?
Meta Robots управляет индексацией конкретной страницы: index/noindex — индексировать ли, follow/nofollow — следовать ли по ссылкам. Noindex полностью исключает страницу из поиска.
Meta-тег robots со значениями index, follow не накладывает ограничений на индексирование и показ контента.
Адаптивность
width=device-width, initial-scale=1.0
Настройка масштабирования на мобильных устройствах
?
Тег viewport (<meta name="viewport">) сообщает браузеру, как масштабировать страницу на мобильных. Стандарт: width=device-width, initial-scale=1. Отсутствие — признак отсутствия мобильной версии.
Meta-тег viewport со значением-константой width=device-width задаёт ширину страницы в соответствии с размером экрана.
Meta-тег viewport со значением initial-scale=1.0 определяет масштаб 1:1, т.е. «не масштабировать».
Разметка OpenGraph
Кол-во: 6
Мета-теги для красивых превью в соцсетях
?
OpenGraph (og:title, og:description, og:image) управляет тем, как страница выглядит при репосте в социальных сетях и мессенджерах. Отсутствие OG-тегов — невзрачный превью при шеринге.
Разметка OpenGraph задана. Страница оптимизирована под социальные сети.
Показать полный список og мета-тегов
| Тип | Значение |
|---|---|
| og:type | website |
| og:title | Наряд-Допуск v2.21 — наряды-допуски + 12 модулей на ОПО |
| og:description | Электронные наряды-допуски на ОПО + 12 модулей v2.21: медосмотры, ИОТ, стажировки, СИЗ, ОПР, ПАБ, скоринг, микротравмы, IoT, расследования НС. 4 микросервиса, Ed25519 + AES-GCM + Argon2id. |
| og:site_name | Наряд-Допуск |
| og:locale | ru_RU |
| og:image | /favicon.svg |
Все мета-теги
Кол-во: 12
Полный список мета-тегов страницы
?
Таблица всех meta-тегов, включая нестандартные. Позволяет найти опечатки, дубли и лишние теги.
Найдены мета-теги 12шт. Мета-теги не видимы для человека и предназначены для обмена информацией между веб-страницей и поисковыми системами, браузерами и другими веб-службами. С ними роботы 🤖 и устройства ведут себя более ожидаемо.
Показать полный список мета-тегов
| Тип | Название | Значение |
|---|---|---|
| name | viewport | width=device-width, initial-scale=1.0 |
| name | description | Электронные наряды-допуски на ОПО + 12 модулей v2.21: медосмотры, ИОТ, стажировки, СИЗ и поверки, ОПР, ПАБ, скоринг подрядчиков, микротравмы, IoT-телеметрия, расследования НС. 4 микросервиса, Ed25519 + AES-GCM + Argon2id. |
| name | twitter:card | summary_large_image |
| name | twitter:title | Наряд-Допуск — электронные наряды-допуски на ОПО |
| name | twitter:description | v2.21: 10+ типов нарядов + 12 модулей (медосмотры, ОПР, ПАБ, IoT, НС), 4 микросервиса, Ed25519. |
| name | robots | index, follow |
| property | og:type | website |
| property | og:title | Наряд-Допуск v2.21 — наряды-допуски + 12 модулей на ОПО |
| property | og:description | Электронные наряды-допуски на ОПО + 12 модулей v2.21: медосмотры, ИОТ, стажировки, СИЗ, ОПР, ПАБ, скоринг, микротравмы, IoT, расследования НС. 4 микросервиса, Ed25519 + AES-GCM + Argon2id. |
| property | og:site_name | Наряд-Допуск |
| property | og:locale | ru_RU |
| property | og:image | /favicon.svg |
Оптимизация Готовность: 92%
Структура
Ошибок нет
Семантические HTML-элементы страницы
?
Проверяет наличие основных структурных элементов: nav, header, footer, main. Корректная семантическая структура помогает поисковику понять архитектуру страницы.
Структура документа корректна (теги <html> и <body> присутствуют в единственном экземпляре).
Контент
Ошибок нет
Объём и качество текстового содержимого
?
Анализирует объём полезного текста на странице. Слишком мало — страница может считаться малополезной. Слишком много — ухудшается читаемость и восприятие.
Слова из title 9 встречаются в тексте достаточно.
Абзацев с текстом 18 достаточно.
Среднее число слов в абзаце 32 достаточно.
Кол-во знаков контента 15786 на странице оптимально.
Кол-во слов 2305 на странице оптимально.
Заголовки
Ошибок нет
Иерархия заголовков H1–H6
?
H1 должен быть один и содержать ключевой запрос. H2–H6 описывают подразделы. Пропуск уровней (H1 → H3) и несколько H1 — типичные ошибки, снижающие понятность страницы для поисковика.
На странице присутствуют заголовки <h1> 1. Это прекрасно.
На странице присутствуют заголовки <h2> 10. Это хорошо.
На странице присутствуют заголовки <h3> 2.
Тошнота
5,20
Насколько одно слово доминирует в тексте
?
Классическая тошнота = √(частота самого повторяющегося слова). Норма до 7–8: текст воспринимается естественно. Выше — поисковик может счесть страницу переспамленной.
Тошнота превышает норму 5. Измените текст страницы!
Академич. тошнота
8,50%
Насколько текст перенасыщен ключевыми словами
?
Академическая тошнота = (частота слова / общее количество слов) × 100%. Показывает долю конкретного слова в тексте. Норма 5–15%.
Академическая тошнота страницы в пределах нормы.
Семантическое ядро
20
Наиболее часто встречающиеся слова на странице
?
Топ слов по частоте использования. Показывает, какие слова доминируют в тексте с точки зрения поисковика.
Контент страницы содержит осмысленный текст и слова.
Показать список слов
| Слово | Кол-во | Частота |
|---|---|---|
| приказ | 27 | 1,17% |
| нарядов | 13 | 0,56% |
| система | 12 | 0,52% |
| инструктажи | 7 | 0,30% |
| минтруда | 7 | 0,30% |
| пользователей | 7 | 0,30% |
| модули | 6 | 0,26% |
| фз-116 | 6 | 0,26% |
| работы | 6 | 0,26% |
| проверка | 6 | 0,26% |
| наряд-допуск | 5 | 0,22% |
| времени | 5 | 0,22% |
| служба | 5 | 0,22% |
| подпись | 5 | 0,22% |
| приложение | 5 | 0,22% |
| наряды | 5 | 0,22% |
| реестр | 5 | 0,22% |
| журнал | 5 | 0,22% |
| заказчика | 5 | 0,22% |
| инструктаж | 5 | 0,22% |
Индексация Готовность: 80%
Индексирование
Ошибок нет
Разрешено ли индексирование страницы
?
Проверяет, не закрыта ли страница от индексации через robots.txt, meta robots или X-Robots-Tag. Страница, закрытая от индексации, не появится в поисковой выдаче.
Анкоров на странице 28 оптимально. Поисковые роботы обязательно проиндексируют сайт.
Robots.txt
Найден корректный robots.txt
Файл управления сканированием сайта роботами
?
Robots.txt указывает поисковым роботам, какие страницы сканировать, а какие — нет. Ошибки в файле могут случайно закрыть важные разделы от индексации.
Robots.txt настроен корректно. Размер файла: 115456 байт. Загружен за: 0сек.
Проверяемая страница не запрещена в robots.txt.
Robots.txt доступен по постоянному адресу
Цепочка редиректов для файла robots.txt:
http://narad-dopusk.ru/robots.txt
308 PermanentRedirect
https://narad-dopusk.ru/robots.txt
200 OK
Показать содержимое robots.txt
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Наряд-Допуск v2.21 — Электронные наряды-допуски, медосмотры, ИОТ, ОПР, ПАБ, IoT на ОПО</title>
<meta name="description" content="Электронные наряды-допуски на ОПО + 12 модулей v2.21: медосмотры, ИОТ, стажировки, СИЗ и поверки, ОПР, ПАБ, скоринг подрядчиков, микротравмы, IoT-телеметрия, расследования НС. 4 микросервиса, Ed25519 + AES-GCM + Argon2id.">
<!-- LAND-SEO-02 (Sprint D): Open Graph / Twitter Card для расшаривания в Telegram/WhatsApp -->
<meta property="og:type" content="website">
<meta property="og:title" content="Наряд-Допуск v2.21 — наряды-допуски + 12 модулей на ОПО">
<meta property="og:description" content="Электронные наряды-допуски на ОПО + 12 модулей v2.21: медосмотры, ИОТ, стажировки, СИЗ, ОПР, ПАБ, скоринг, микротравмы, IoT, расследования НС. 4 микросервиса, Ed25519 + AES-GCM + Argon2id.">
<meta property="og:site_name" content="Наряд-Допуск">
<meta property="og:locale" content="ru_RU">
<meta property="og:image" content="/favicon.svg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Наряд-Допуск — электронные наряды-допуски на ОПО">
<meta name="twitter:description" content="v2.21: 10+ типов нарядов + 12 модулей (медосмотры, ОПР, ПАБ, IoT, НС), 4 микросервиса, Ed25519.">
<!-- LAND-SEO-05: canonical URL -->
<link rel="canonical" href="https://narad-dopusk.ru/">
<!-- LAND-SEO-04: robots -->
<meta name="robots" content="index, follow">
<!-- ── КОНТАКТНЫЕ ДАННЫЕ (изменяемые переменные) ─────────────────────────── -->
<script>
const CONTACT_PHONE = '+7 (912)420-23-89'; // ← телефон для заказа звонка
const CONTACT_EMAIL = 'Bobretsov.AA@gmail.com'; // ← email для заявок
const CONTACT_TELEGRAM = '@BobretsovAA'; // ← Telegram
</script>
<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=Bebas+Neue&family=IBM+Plex+Sans:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- Favicon · design-system/assets/favicon.svg (Logo A · Solid Shield, dark rounded tile) -->
<link rel="icon" type="image/svg+xml" href="assets/favicon.svg">
<style>
/* ── Токены ──────────────────────────────────────────────────────────────── */
:root {
--bg: #0C0E14;
--bg-s: #141720;
--bg-card: #1A1E2C;
--bg-hover: #222736;
--border: #2A2F42;
--border-l: #363D56;
--text: #E8ECF4;
--text-s: #8892AD;
--text-m: #535D78;
--amber: #F7A621;
--amber-d: rgba(247,166,33,0.12);
--amber-h: #FFB840;
--red: #EF4444;
--green: #22C55E;
--blue: #3B82F6;
/* v2.9 «Спектр»: со-акцент азур — info/ссылки/второстепенные бейджи.
Значение синхронизировано с tokens/colors.css дизайн-системы
(spectrum: --accent-2: #34D6E0), не со старым --blue лендинга. */
--accent-2: #34D6E0;
--accent-2-dim: rgba(52, 214, 224, 0.13);
--radius: 10px;
--radius-lg: 16px;
--ff-head: 'Bebas Neue', sans-serif;
--ff-body: 'IBM Plex Sans', sans-serif;
--ff-mono: 'IBM Plex Mono', monospace;
--shadow: 0 4px 32px rgba(0,0,0,.5);
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body { font-family: var(--ff-body); background: var(--bg); color: var(--text); line-height: 1.65; -webkit-font-smoothing: antialiased; }
img { display: block; max-width: 100%; }
a { color: var(--amber); text-decoration: none; }
/* ── Утилиты ─────────────────────────────────────────────────────────────── */
.container { max-width: 1160px; margin: 0 auto; padding: 0 24px; }
.section { padding: 96px 0; }
/* Якорные переходы: sticky-шапка 60px перекрывала заголовок целевой секции. */
section[id], .stats-band { scroll-margin-top: 76px; }
.section-alt { background: var(--bg-s); }
.tag { display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
background: var(--amber-d); color: var(--amber); border: 1px solid rgba(247,166,33,.25);
border-radius: 99px; padding: 4px 14px; margin-bottom: 20px; }
/* v2.9 «Спектр»: вариант тега на азур-акценте — для секций, описывающих
возможности/процесс (информационный контекст), а не призыв к действию. */
.tag-info { background: var(--accent-2-dim); color: var(--accent-2); border: 1px solid color-mix(in srgb, var(--accent-2) 35%, transparent); }
/* text-wrap: balance — перенос решает браузер: помещается в строку —
строка одна, не помещается — строки делятся поровну. Раньше место
разрыва было забито <br> в разметке. */
h2.section-title { font-family: var(--ff-head); font-size: clamp(2rem,4vw,3rem); letter-spacing: .05em;
margin-bottom: 14px; text-wrap: balance; }
/* Без max-width: подзаголовки секций идут во всю ширину контейнера
(раньше обрывались по 620px, оставляя половину строки пустой). */
.section-sub { font-size: 16px; color: var(--text-s); line-height: 1.7; }
/* ── Кнопки ──────────────────────────────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; gap: 8px; padding: 13px 28px;
border-radius: var(--radius); font-family: var(--ff-body); font-size: 15px;
font-weight: 600; cursor: pointer; border: 1px solid transparent; transition: all .15s; white-space: nowrap; }
.btn-primary { background: var(--amber); color: #0C0E14; border-color: var(--amber); }
.btn-primary:hover { background: var(--amber-h); }
.btn-outline { background: transparent; color: var(--text); border-color: var(--border-l); }
.btn-outline:hover { border-color: var(--amber); color: var(--amber); }
.btn-lg { padding: 16px 36px; font-size: 16px; }
.btn-sm { padding: 9px 20px; font-size: 13px; }
/* ── NAV ─────────────────────────────────────────────────────────────────── */
nav {
position: sticky; top: 0; z-index: 100;
background: rgba(12,14,20,.97);
border-bottom: 1px solid var(--border);
}
/* Бюджет ширины строки: контейнер 1160 − 48 padding = 1112px.
Логотип ~180 + 7 пунктов меню ~600 + CTA ~135 + зазоры 24 ≈ 940.
Телефон (+150) в этот бюджет не влезает — он скрыт до 1240px (см. ниже),
а на широких экранах помещается за счёт ужатых gap/кеглей. */
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 60px; }
.nav-logo { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.nav-logo svg { flex-shrink: 0; }
.nav-logo-text { font-family: var(--ff-head); font-size: 18px; letter-spacing: .06em; white-space: nowrap; }
/* Пункты меню не переносятся: строка навигации фиксированной высоты 60px,
перенос ломал её на две строки (см. burger-брейкпоинт 1060px ниже). */
.nav-links { display: flex; align-items: center; gap: 16px; flex-wrap: nowrap; }
.nav-links a { color: var(--text-s); font-size: 13px; transition: color .15s; white-space: nowrap; }
.nav-links a:hover { color: var(--text); }
.nav-cta { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.nav-phone { font-size: 12.5px; color: var(--text-s); display: flex; align-items: center; gap: 6px; white-space: nowrap; }
/* ── HERO ────────────────────────────────────────────────────────────────── */
.hero { position: relative; overflow: hidden; padding: 120px 0 100px; }
/* z-index обязателен: без него абсолютный .hero-bg рисуется ПОВЕРХ
не-позиционированного контента секции (сетка точек ложилась на текст). */
.hero-bg { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.hero > .container { position: relative; z-index: 1; }
.hero-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.hero-tag { margin-bottom: 24px; }
.hero h1 { font-family: var(--ff-head); font-size: clamp(2.8rem, 5vw, 4.2rem);
letter-spacing: .04em; line-height: 1.05; margin-bottom: 24px; }
.hero h1 span { color: var(--amber); }
.hero-sub { font-size: 17px; color: var(--text-s); max-width: 500px; margin-bottom: 36px; line-height: 1.7; }
.hero-btns { display: flex; gap: 14px; flex-wrap: wrap; }
/* Focal before/after — один акцент вместо трёх равных стат */
.hero-metric { display: flex; align-items: center; gap: 18px; background: var(--bg-card);
border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 16px 22px; margin: 0 0 26px; max-width: 480px; }
.hero-metric .was { font-family: var(--ff-head); font-size: 1.6rem; color: var(--text-m);
text-decoration: line-through; text-decoration-color: var(--red);
line-height: 1; white-space: nowrap; }
.hero-metric .now { font-family: var(--ff-head); font-size: 2.4rem; color: var(--amber);
line-height: 1; white-space: nowrap; }
.hero-metric .cut { font-family: var(--ff-head); font-size: 1.5rem; color: var(--amber);
line-height: 1; white-space: nowrap; }
.hero-metric .ml { font-size: 10px; color: var(--text-m); margin-top: 3px; }
.hero-metric .arrow { color: var(--amber); font-size: 22px; }
/* Compliance bar — телеграф нормативки сразу.
Выведен из левой колонки hero под сетку: во всю ширину контейнера и строго
в одну линию (раньше был зажат в 480px и разъезжался на три строки). */
.hero-compliance { border-top: 1px solid var(--border); padding-top: 16px; margin-top: 48px; }
.hero-compliance .lbl { font-size: 10px; color: var(--text-m); letter-spacing: .06em;
margin-bottom: 10px; text-transform: uppercase; }
/* nowrap + горизонтальный скролл: на узких экранах лента не переносится,
а прокручивается. Полоса прокрутки скрыта, чтобы не резать чипы. */
.hero-compliance .chips { display: flex; flex-wrap: nowrap; gap: 8px;
overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
padding-bottom: 2px; }
.hero-compliance .chips::-webkit-scrollbar { display: none; }
.hero-compliance .chips span { flex: 0 0 auto; white-space: nowrap;
font-size: 11px; color: var(--text-s); background: var(--bg-hover);
border: 1px solid var(--border); border-radius: 6px; padding: 6px 12px;
display: inline-flex; align-items: center; gap: 5px; }
/* Скриншот-карточка справа */
.hero-visual { position: relative; }
.hero-screen {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--radius-lg); overflow: hidden;
box-shadow: var(--shadow);
}
.screen-bar { background: var(--bg-s); border-bottom: 1px solid var(--border);
padding: 10px 16px; display: flex; align-items: center; gap: 8px; }
.dot { width: 10px; height: 10px; border-radius: 50%; }
.screen-url { font-family: var(--ff-mono); font-size: 11px; color: var(--text-m);
background: var(--bg); border-radius: 4px; padding: 3px 10px; margin-left: 8px; }
.screen-body { padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.screen-permit { position: relative; background: var(--bg-s); border: 1px solid var(--border); border-radius: var(--radius);
padding: 14px 16px; }
.permit-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.permit-num { font-family: var(--ff-mono); font-size: 12px; color: var(--amber); font-weight: 500; }
.permit-status { font-size: 11px; padding: 2px 10px; border-radius: 99px; font-weight: 600; }
.s-admitted { background: rgba(34,197,94,.15); color: #22C55E; }
.s-progress { background: rgba(59,130,246,.15); color: #3B82F6; }
.s-closed { background: rgba(83,93,120,.2); color: var(--text-s); }
.s-pending { background: rgba(247,166,33,.15); color: var(--amber); }
.permit-type { font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.permit-meta { font-size: 11px; color: var(--text-m); }
.progress-bar { height: 3px; background: var(--border); border-radius: 2px; margin-top: 10px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--amber); border-radius: 2px; }
/* ЭП-штамп на карточке наряда — телеграф о юридически-значимой ЭП */
/* Штамп вынесен на правый край карточки по вертикальному центру.
Было top:-10px/right:8px — он налезал на бейдж .permit-status в шапке
карточки; над карточкой места тоже нет (там подпись секции). */
.ep-stamp { position: absolute; top: 50%; right: -14px; font-family: var(--ff-body);
font-size: 11px; font-weight: 700; color: var(--green);
border: 2px solid var(--green); border-radius: 6px; padding: 4px 8px;
background: rgba(34,197,94,.08); transform: translateY(-50%) rotate(-8deg);
letter-spacing: .03em; box-shadow: 0 2px 8px rgba(0,0,0,.3); z-index: 2; }
/* ── FEATURES GRID ───────────────────────────────────────────────────────── */
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 56px; }
.feat-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 28px; transition: all .2s; }
.feat-card:hover { transform: translateY(-2px); border-color: var(--amber); }
.feat-icon { width: 44px; height: 44px; border-radius: var(--radius); background: var(--amber-d);
display: flex; align-items: center; justify-content: center; margin-bottom: 18px; font-size: 20px; }
/* v2.21: TZ-бейдж для карточек новых модулей */
.tz-tag { display: inline-block; font-family: var(--ff-mono); font-size: 10px; font-weight: 500;
color: var(--accent-2); background: var(--accent-2-dim);
border: 1px solid color-mix(in srgb, var(--accent-2) 35%, transparent);
border-radius: 4px; padding: 1px 6px; margin-left: 6px; vertical-align: middle;
letter-spacing: .03em; }
/* ── STATS BAND (v2.21) ──────────────────────────────────────────────────── */
.stats-band { background: var(--bg-card); border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border); padding: 40px 0; }
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.stat-item { text-align: center; padding: 8px 12px; }
.stat-item + .stat-item { border-left: 1px solid var(--border); }
.stat-num { font-family: var(--ff-head); font-size: 2.6rem; color: var(--amber);
letter-spacing: .02em; line-height: 1.05; margin-bottom: 10px; }
.stat-num small { display: block; font-size: .5em; line-height: 1.2; color: var(--amber); }
.stat-lbl { font-size: 13px; color: var(--text-s); line-height: 1.5; }
.stat-lbl small { display: block; color: var(--text-m); font-size: 11px; margin-top: 3px; }
/* ── ARCHITECTURE (v2.21) ────────────────────────────────────────────────── */
.arch-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 56px; }
.arch-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 24px; transition: all .2s; }
.arch-card:hover { transform: translateY(-2px); border-color: var(--amber); }
.arch-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px;
padding-bottom: 14px; border-bottom: 1px solid var(--border); }
.arch-icon { width: 44px; height: 44px; border-radius: var(--radius); background: var(--amber-d);
display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.arch-name { font-family: var(--ff-head); font-size: 1.2rem; letter-spacing: .06em; color: var(--amber); line-height: 1; }
.arch-tagline { font-size: 11px; color: var(--text-s); margin-top: 3px; }
.arch-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.arch-list li { font-size: 13px; color: var(--text-s); padding-left: 16px; position: relative; line-height: 1.5; }
.arch-list li::before { content: '▸'; position: absolute; left: 0; top: 0; color: var(--amber); font-size: 11px; }
.arch-note { margin-top: 32px; background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--radius); padding: 20px 24px; font-size: 13px; color: var(--text-s);
line-height: 1.7; }
.arch-note code { font-family: var(--ff-mono); font-size: 12px; color: var(--amber);
background: var(--amber-d); padding: 1px 6px; border-radius: 4px; }
/* ── COMPLIANCE (v2.21) ──────────────────────────────────────────────────── */
.compliance-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 48px; }
.comp-block { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 24px; transition: all .2s; }
.comp-block:hover { transform: translateY(-2px); border-color: var(--amber); }
.comp-block-title { font-size: 14px; font-weight: 600; margin-bottom: 14px; color: var(--text); }
.comp-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.comp-chip { font-size: 12px; color: var(--text-s); background: var(--bg-hover);
border: 1px solid var(--border); border-radius: 6px; padding: 5px 11px; }
/* v2.9 «Спектр»: азур-вариант иконки — для карточек об информации/связи/
мониторинге (не о прямом действии), чтобы сетка фич не читалась монотонно. */
.feat-icon-info { background: var(--accent-2-dim); }
.feat-title { font-size: 15px; font-weight: 600; margin-bottom: 8px; }
.feat-desc { font-size: 13px; color: var(--text-s); line-height: 1.6; }
/* ── TYPES GRID ──────────────────────────────────────────────────────────── */
.types-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-top: 48px; }
.type-card { background: var(--bg-card); border-radius: var(--radius); padding: 16px 14px;
border: 1px solid var(--border); text-align: center; transition: all .2s; }
.type-card:hover { transform: translateY(-3px); border-color: var(--border-l); }
.type-icon { font-size: 28px; margin-bottom: 10px; }
.type-name { font-size: 12px; color: var(--text-s); line-height: 1.4; }
/* ── WORKFLOW ─────────────────────────────────────────────────────────────── */
.workflow-steps { display: flex; align-items: flex-start; gap: 0; margin-top: 56px; flex-wrap: wrap; }
.wf-step { flex: 1; min-width: 90px; display: flex; flex-direction: column; align-items: center; position: relative; }
.wf-step::after { content: '→'; position: absolute; right: -12px; top: 14px; color: var(--amber); font-size: 18px; }
.wf-step:last-child::after { display: none; }
.wf-dot { width: 40px; height: 40px; border-radius: 50%; border: 2px solid; display: flex; align-items: center;
justify-content: center; font-size: 13px; font-weight: 700; margin-bottom: 10px; flex-shrink: 0; }
.wf-label { font-size: 11px; color: var(--text-s); text-align: center; line-height: 1.4; }
.wf-ep { font-size: 9px; color: var(--amber); font-weight: 700; letter-spacing: .05em; margin-top: 4px; }
/* ── PRICING ─────────────────────────────────────────────────────────────── */
.pricing-controls { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 32px; margin-top: 48px; margin-bottom: 32px; }
.pricing-controls h3 { font-family: var(--ff-head); font-size: 1.4rem; letter-spacing: .04em; margin-bottom: 24px; }
.slider-row { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; }
.slider-label { font-size: 14px; color: var(--text-s); min-width: 200px; }
.slider-val { font-size: 15px; font-weight: 600; min-width: 52px; text-align: right; color: var(--amber); }
input[type=range] {
flex: 1; appearance: none; height: 4px; background: var(--border); border-radius: 2px; outline: none; cursor: pointer;
}
input[type=range]::-webkit-slider-thumb {
appearance: none; width: 18px; height: 18px; border-radius: 50%;
background: var(--amber); cursor: pointer; box-shadow: 0 0 0 3px rgba(247,166,33,.2);
}
input[type=range]::-moz-range-thumb {
width: 18px; height: 18px; border-radius: 50%; background: var(--amber); cursor: pointer; border: none;
}
.pricing-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-bottom: 32px; }
.price-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 28px; display: flex; flex-direction: column; }
.price-card.featured { border-color: var(--amber); box-shadow: 0 0 0 1px rgba(247,166,33,.3); }
.price-badge { display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
background: var(--amber); color: #0C0E14; border-radius: 99px; padding: 3px 12px;
margin-bottom: 14px; align-self: flex-start; }
.price-name { font-size: 14px; color: var(--text-s); margin-bottom: 8px; }
.price-amount { font-family: var(--ff-head); font-size: 2.6rem; letter-spacing: .02em; margin-bottom: 2px; }
.price-period { font-size: 13px; color: var(--text-m); margin-bottom: 20px; }
.price-discount { font-size: 13px; color: var(--green); font-weight: 600; }
.price-feats { list-style: none; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.price-feats li { font-size: 13px; color: var(--text-s); display: flex; gap: 8px; align-items: flex-start; }
.price-feats li::before { content: '✓'; color: var(--green); font-weight: 700; flex-shrink: 0; }
.price-feats li.no::before { content: '×'; color: var(--text-m); }
.price-feats li.no { color: var(--text-m); }
.price-cta { margin-top: 24px; }
/* v2.21: выбор модульных пакетов в калькуляторе */
.mod-head { display:flex; align-items:baseline; justify-content:space-between; gap:12px;
margin:22px 0 12px; padding-top:18px; border-top:1px solid var(--border); }
.mod-head .mh-title { font-size:13px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--text-s); }
.mod-head .mh-hint { font-size:12px; color:var(--text-m); }
.mod-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.mod-toggle { display:flex; align-items:flex-start; gap:11px; text-align:left; cursor:pointer;
background:var(--bg-s); border:1px solid var(--border); border-radius:var(--radius);
padding:12px 14px; transition:border-color .15s, background .15s; }
.mod-toggle:hover { border-color:var(--amber); }
.mod-toggle.on { border-color:var(--amber); background:var(--amber-d); }
.mod-toggle.core { cursor:default; border-color:rgba(247,166,33,.4); background:var(--amber-d); opacity:.9; }
.mod-check { flex-shrink:0; width:18px; height:18px; margin-top:1px; border-radius:5px;
border:1.5px solid var(--text-m); display:flex; align-items:center; justify-content:center;
font-size:12px; font-weight:700; color:var(--bg); background:transparent; }
.mod-toggle.on .mod-check, .mod-toggle.core .mod-check { background:var(--amber); border-color:var(--amber); }
/* Разметка тумблеров генерируется из span-ов (renderModulePacks), поэтому
display:block обязателен — иначе название и описание слипались в строку. */
.mod-body { flex:1; min-width:0; display:block; }
.mod-name { display:block; font-size:13px; font-weight:600; color:var(--text); }
.mod-desc { display:block; font-size:11.5px; color:var(--text-m); margin-top:2px; line-height:1.45; }
.mod-price { font-size:12.5px; font-weight:700; color:var(--amber); white-space:nowrap; margin-top:2px; }
.mod-price.free { color:var(--green); }
.rate-line { display:flex; flex-wrap:wrap; align-items:baseline; gap:8px; margin-top:16px;
font-size:13px; color:var(--text-s); }
.rate-line b { font-family:var(--ff-head); font-size:1.15rem; color:var(--amber); letter-spacing:.02em; }
@media (max-width:640px){ .mod-grid{ grid-template-columns:1fr; } }
.pricing-metrics { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; margin-bottom: 24px; }
.pm-card { background: var(--bg-s); border-radius: var(--radius); padding: 16px; }
.pm-val { font-family: var(--ff-head); font-size: 1.6rem; color: var(--amber); letter-spacing: .02em; }
.pm-lbl { font-size: 11px; color: var(--text-m); margin-top: 4px; line-height: 1.4; }
.roi-block { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 28px; display: grid; grid-template-columns: 1fr 1fr; gap: 32px; }
.roi-row { display: flex; justify-content: space-between; padding: 8px 0;
border-bottom: 1px solid var(--border); font-size: 14px; }
.roi-row:last-child { border-bottom: none; font-weight: 700; font-size: 15px; }
.roi-green { color: var(--green); }
.roi-red { color: var(--red); }
.comp-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.comp-table th { text-align: left; color: var(--text-m); font-weight: 500;
padding: 6px 8px; border-bottom: 1px solid var(--border); font-size: 12px; }
.comp-table td { padding: 9px 8px; border-bottom: 1px solid rgba(42,47,66,.6); color: var(--text); }
.comp-table tr.our td { background: var(--amber-d); }
.comp-table .num { text-align: right; }
.comp-table .c-green { color: var(--green); }
.comp-table .c-amber { color: var(--amber); }
.comp-table .c-red { color: var(--red); }
/* Пояснение под обеими колонками ROI-блока: grid-column на всю ширину —
раньше текст был вложен в левую колонку и занимал половину строки. */
.roi-note { grid-column: 1 / -1; font-size: 12px; color: var(--text-m);
line-height: 1.6; margin-top: 4px; }
/* ── CTA BANNER ──────────────────────────────────────────────────────────── */
.cta-banner { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg);
padding: 56px; text-align: center; margin: 0 auto; max-width: 720px; }
.cta-banner h2 { font-family: var(--ff-head); font-size: clamp(2rem,4vw,2.8rem);
letter-spacing: .04em; margin-bottom: 16px; }
.cta-banner p { font-size: 16px; color: var(--text-s); margin-bottom: 32px; }
.cta-btns { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
/* ── FORM MODAL ──────────────────────────────────────────────────────────── */
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,.82);
z-index: 1000; display: none; align-items: center; justify-content: center;
padding: 24px 16px; }
.overlay.open { display: flex; }
.modal { background: var(--bg-card); border: 1px solid var(--border-l); border-radius: var(--radius-lg);
padding: 40px; width: 100%; max-width: 500px; position: relative;
overflow-y: auto; max-height: 90vh;
box-shadow: 0 24px 80px rgba(0,0,0,.8); }
@keyframes modalIn {
from { opacity: 0; transform: translateY(16px); }
to { opacity: 1; transform: translateY(0); }
}
.modal-close { position: absolute; top: 16px; right: 16px; background: none; border: none; cursor: pointer;
color: var(--text-s); font-size: 22px; line-height: 1; transition: color .15s; }
.modal-close:hover { color: var(--text); }
.modal h3 { font-family: var(--ff-head); font-size: 1.8rem; letter-spacing: .04em; margin-bottom: 8px; }
.modal p { font-size: 14px; color: var(--text-s); margin-bottom: 24px; }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 12px; color: var(--text-s); margin-bottom: 6px; font-weight: 500; }
.form-group input, .form-group select, .form-group textarea {
width: 100%; background: var(--bg-s); border: 1px solid var(--border-l);
border-radius: var(--radius); color: var(--text); font-family: var(--ff-body);
font-size: 14px; padding: 11px 14px; outline: none; transition: border-color .15s;
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus { border-color: var(--amber); }
.form-group textarea { resize: vertical; min-height: 80px; }
select option { background: var(--bg-card); }
.form-contact { background: var(--bg-s); border-radius: var(--radius); padding: 14px 16px;
font-size: 13px; color: var(--text-s); margin-bottom: 16px; line-height: 1.7; }
.form-contact a { color: var(--amber); }
.form-success { text-align: center; padding: 24px 0; }
.form-success .check { font-size: 48px; margin-bottom: 16px; }
.form-success h4 { font-family: var(--ff-head); font-size: 1.5rem; margin-bottom: 8px; }
.form-success p { font-size: 14px; color: var(--text-s); }
/* ── NORMS ───────────────────────────────────────────────────────────────── */
.norms { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 40px; }
.norm-tag { font-size: 12px; color: var(--text-m); background: var(--bg-hover);
border: 1px solid var(--border); border-radius: 6px; padding: 5px 12px; }
/* ── FOOTER ──────────────────────────────────────────────────────────────── */
footer { background: var(--bg-s); border-top: 1px solid var(--border); padding: 40px 0; }
.footer-inner { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 24px; }
.footer-logo { display: flex; align-items: center; gap: 10px; }
.footer-copy { font-size: 13px; color: var(--text-m); }
/* Без wrap/nowrap ссылки сжимались и рвались посередине слова
(«Модули v2.21», e-mail) — теперь переносится список целыми пунктами. */
.footer-links { display: flex; flex-wrap: wrap; gap: 14px 24px; }
.footer-links a { font-size: 13px; color: var(--text-s); transition: color .15s; white-space: nowrap; }
.footer-links a:hover { color: var(--amber); }
/* ── Responsive ──────────────────────────────────────────────────────────── */
/* ── BURGER ──────────────────────────────────────────────────────────────── */
.burger {
display: none;
flex-direction: column; justify-content: center; align-items: center;
width: 40px; height: 40px; gap: 5px; cursor: pointer;
background: none; border: none; padding: 4px; border-radius: var(--radius);
transition: background .15s;
}
.burger:hover { background: var(--bg-hover); }
.burger span { display: block; width: 22px; height: 2px; background: var(--text); border-radius: 2px; transition: all .25s; }
.burger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.burger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
/* Мобильное меню-дровер */
.mobile-menu {
display: none;
position: fixed; top: 60px; left: 0; right: 0;
background: rgba(12,14,20,.99);
border-bottom: 1px solid var(--border);
z-index: 99; padding: 16px 24px 24px;
flex-direction: column; gap: 4px;
transform: translateY(-10px); opacity: 0;
transition: transform .2s, opacity .2s;
}
.mobile-menu.open { transform: translateY(0); opacity: 1; }
.mobile-menu a {
display: block; padding: 13px 0; font-size: 18px;
color: var(--text-s); border-bottom: 1px solid var(--border);
font-weight: 500; transition: color .15s;
}
.mobile-menu a:last-of-type { border-bottom: none; }
.mobile-menu a:hover { color: var(--amber); }
.mobile-menu .mobile-cta {
display: flex; flex-direction: column; gap: 10px; margin-top: 16px;
}
.mobile-menu .mobile-phone {
font-size: 15px; color: var(--text-s); text-align: center;
padding: 10px 0; border: 1px solid var(--border); border-radius: var(--radius);
}
/* ── УЗКИЙ ДЕСКТОП ────────────────────────────────────────────────────────── */
/* Телефон в шапке уходит первым — он шире любого пункта меню.
Он продублирован в бургер-меню, sticky-CTA, секции контактов и подвале. */
@media (max-width: 1240px) {
.nav-phone { display: none; }
}
/* Ниже 1060px семь пунктов + логотип + CTA перестают помещаться в 60px-строку
и переносятся на вторую строку — переключаемся на бургер. */
@media (max-width: 1060px) {
.nav-links { display: none; }
.burger { display: flex; }
.mobile-menu { display: flex; }
}
/* ── ТАБЛЕТ 900px ─────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
.hero-grid { grid-template-columns: 1fr; }
.hero-visual { display: none; }
.features-grid { grid-template-columns: 1fr 1fr; }
.arch-grid { grid-template-columns: 1fr 1fr; }
.stats-grid { grid-template-columns: 1fr 1fr; gap: 18px; }
.compliance-grid { grid-template-columns: 1fr 1fr; }
.types-grid { grid-template-columns: repeat(3,1fr); }
.pricing-cards { grid-template-columns: 1fr; }
.pricing-metrics { grid-template-columns: repeat(2,1fr); }
.roi-block { grid-template-columns: 1fr; }
/* stats-band в 2 колонки: вертикальный сепаратор только между колонками,
горизонтальный — начиная со второго ряда (3-я и 4-я карточки). */
.stat-item + .stat-item { border-left: none; }
.stat-item:nth-child(odd) { border-right: 1px solid var(--border); }
.stat-item:nth-child(n+3) { border-top: 1px solid var(--border); padding-top: 18px; }
}
/* ── МОБАЙЛ 600px ────────────────────────────────────────────────────────── */
@media (max-width: 600px) {
/* Типографика. Селектор h2.section-title — иначе базовое правило
(специфичность выше) перебивает мобильный размер. */
h2.section-title { font-size: clamp(1.7rem, 7vw, 2.2rem); }
.section-sub { font-size: 14px; }
/* Отступы */
.section { padding: 56px 0; }
.container { padding: 0 16px; }
/* HERO */
.hero { padding: 80px 0 64px; }
.hero h1 { font-size: clamp(2.2rem, 10vw, 3rem); margin-bottom: 16px; }
.hero-sub { font-size: 14px; margin-bottom: 24px; }
.hero-btns { flex-direction: column; }
.hero-btns .btn { width: 100%; justify-content: center; }
/* HERO metric + compliance */
.hero-metric { gap: 12px; padding: 14px 16px; }
.hero-metric .was { font-size: 1.3rem; }
.hero-metric .now { font-size: 1.9rem; }
.hero-metric .cut { font-size: 1.2rem; }
.hero-compliance { margin-top: 22px; }
.hero-compliance .chips span { font-size: 10px; padding: 4px 9px; }
/* Features */
.features-grid { grid-template-columns: 1fr; gap: 14px; margin-top: 36px; }
.feat-card { padding: 20px; }
/* v2.21: Modules / Architecture / Stats / Compliance — на мобайле в 1 колонку */
.arch-grid { grid-template-columns: 1fr; gap: 14px; margin-top: 36px; }
.arch-card { padding: 20px; }
.stats-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
.stat-num { font-size: 2rem; }
.compliance-grid { grid-template-columns: 1fr; gap: 14px; }
.comp-block { padding: 20px; }
/* Types */
.types-grid { grid-template-columns: repeat(2,1fr); gap: 10px; margin-top: 32px; }
.type-icon { font-size: 24px; margin-bottom: 8px; }
.type-card { padding: 12px 10px; }
/* Workflow */
.workflow-steps { flex-direction: column; gap: 0; align-items: stretch; }
.wf-step { flex-direction: row; align-items: center; gap: 16px; padding: 12px 0;
border-bottom: 1px solid var(--border); min-width: unset; }
.wf-step:last-child { border-bottom: none; }
.wf-step::after { display: none; }
.wf-dot { flex-shrink: 0; }
.wf-label { text-align: left; font-size: 13px; }
.wf-ep { margin-top: 2px; }
/* Pricing controls */
.pricing-controls { padding: 20px 16px; }
.slider-row { flex-wrap: wrap; gap: 8px; }
.slider-label { min-width: unset; width: 100%; font-size: 13px; }
.slider-val { min-width: 36px; }
/* Pricing metrics */
.pricing-metrics { grid-template-columns: 1fr 1fr; gap: 10px; }
.pm-val { font-size: 1.3rem; }
.pm-lbl { font-size: 10px; }
/* Pricing cards */
.pricing-cards { gap: 14px; }
.price-card { padding: 20px; }
.price-amount { font-size: 2rem; }
/* ROI block */
.roi-block { padding: 20px; gap: 24px; }
.roi-row { font-size: 13px; }
.comp-table { font-size: 12px; }
.comp-table td, .comp-table th { padding: 7px 6px; }
/* Norms */
.norms { gap: 6px; margin-top: 28px; }
.norm-tag { font-size: 11px; }
/* CTA Banner */
.cta-banner { padding: 36px 20px; }
.cta-banner h2 { font-size: 1.8rem; }
.cta-banner p { font-size: 14px; }
.cta-btns { flex-direction: column; }
.cta-btns .btn { width: 100%; justify-content: center; }
/* Footer */
.footer-inner { flex-direction: column; align-items: flex-start; gap: 16px; }
.footer-links { flex-wrap: wrap; gap: 16px; }
/* Modal */
.overlay { padding: 12px 8px; }
.modal { padding: 24px 18px; max-width: 100%; }
.modal h3 { font-size: 1.5rem; }
/* Nav CTA — скрываем телефон, оставляем только кнопку */
.btn-sm { padding: 8px 16px; font-size: 13px; }
}
/* ── ОЧЕНЬ МАЛЕНЬКИЕ ЭКРАНЫ 375px ──────────────────────────────────────────── */
@media (max-width: 375px) {
.hero h1 { font-size: 2rem; }
.types-grid { grid-template-columns: 1fr 1fr; }
.pricing-metrics { grid-template-columns: 1fr 1fr; }
.nav-logo-text { font-size: 16px; }
}
/* Sticky мобильный CTA внизу экрана */
.mobile-sticky-cta {
display: none;
position: fixed; bottom: 0; left: 0; right: 0;
background: var(--bg-card);
border-top: 1px solid var(--border);
padding: 12px 16px;
z-index: 90;
flex-direction: column; gap: 8px;
box-shadow: 0 -8px 32px rgba(0,0,0,.4);
}
.mobile-sticky-cta .btn { width: 100%; justify-content: center; }
.mobile-sticky-cta .sticky-phone {
font-size: 13px; color: var(--text-s); text-align: center;
}
@media (max-width: 600px) {
.mobile-sticky-cta { display: flex; }
/* Отступ снизу чтобы контент не перекрывался */
footer { padding-bottom: 120px; }
}
/* ── КНОПКА «НАВЕРХ» ─────────────────────────────────────────────────────── */
.to-top {
position: fixed; right: 24px; bottom: 24px; z-index: 95;
width: 46px; height: 46px; border-radius: 50%;
display: flex; align-items: center; justify-content: center;
background: var(--bg-card); color: var(--amber);
border: 1px solid var(--border-l); cursor: pointer;
box-shadow: var(--shadow);
opacity: 0; visibility: hidden; transform: translateY(12px);
transition: opacity .2s, transform .2s, visibility .2s, background .15s, border-color .15s;
}
.to-top.show { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { background: var(--bg-hover); border-color: var(--amber); }
.to-top:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.to-top svg { width: 20px; height: 20px; }
/* На мобайле поднимаем над sticky-CTA, чтобы кнопки не накладывались. */
@media (max-width: 600px) {
.to-top { right: 16px; bottom: 118px; width: 42px; height: 42px; }
}
/* Пользователи с prefers-reduced-motion не должны получать плавную прокрутку. */
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
* { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
</style>
</head>
<body>
<!-- ══ NAVIGATION ═══════════════════════════════════════════════════════════ -->
<nav>
<div class="container">
<div class="nav-inner">
<a href="#" class="nav-logo">
<svg width="28" height="28" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="Наряд-Допуск">
<!-- Logo A · Solid Shield — design-system/assets/logo.svg (amber-filled warning triangle with knocked-out exclamation on #1A1E2C shield) -->
<path d="M100 14 L170 40 L170 106 Q170 156 100 184 Q30 156 30 106 L30 40 Z" fill="#1A1E2C" stroke="#F7A621" stroke-width="9" stroke-linejoin="round"/>
<path d="M100 60 L141 128 Q144 134 137 134 L63 134 Q56 134 59 128 Z" fill="#F7A621"/>
<rect x="94" y="82" width="12" height="26" rx="4" fill="#1A1E2C"/>
<circle cx="100" cy="120" r="6" fill="#1A1E2C"/>
</svg>
<span class="nav-logo-text">НАРЯД-ДОПУСК</span>
</a>
<div class="nav-links">
<a href="#features">Возможности</a>
<a href="#modules">Модули v2.21</a>
<a href="#architecture">Архитектура</a>
<a href="#types">Типы нарядов</a>
<a href="#training">Инструктажи</a>
<a href="#pricing">Тарифы</a>
<a href="#contact">Контакты</a>
</div>
<div class="nav-cta">
<a class="nav-phone" id="nav-phone-link" href="#"></a>
<button class="btn btn-primary btn-sm" onclick="openModal()">Заказать демо</button>
<!-- Бургер (только мобайл) -->
<button class="burger" id="burger-btn" aria-label="Открыть меню" aria-expanded="false" onclick="toggleMenu()">
<span></span><span></span><span></span>
</button>
</div>
</div>
</div>
<!-- Мобильное меню-дровер -->
<div class="mobile-menu" id="mobile-menu" aria-hidden="true">
<a href="#features" onclick="closeMenu()">Возможности</a>
<a href="#modules" onclick="closeMenu()">Модули v2.21</a>
<a href="#architecture" onclick="closeMenu()">Архитектура</a>
<a href="#types" onclick="closeMenu()">Типы нарядов</a>
<a href="#training" onclick="closeMenu()">Инструктажи</a>
<a href="#pricing" onclick="closeMenu()">Тарифы</a>
<a href="#contact" onclick="closeMenu()">Контакты</a>
<div class="mobile-cta">
<button class="btn btn-primary" style="width:100%;justify-content:center" onclick="closeMenu();openModal()">Заказать демо →</button>
<a class="mobile-phone" id="mobile-menu-phone" href="#">📞 Позвонить</a>
</div>
</div>
</nav>
<!-- ══ HERO ══════════════════════════════════════════════════════════════════ -->
<section class="hero">
<!-- Фоновые декоративные элементы -->
<div class="hero-bg">
<svg width="100%" height="100%" viewBox="0 0 1200 700" preserveAspectRatio="xMidYMid slice" fill="none">
<!-- сетка точек -->
<pattern id="grid" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="1" fill="#2A2F42"/>
</pattern>
<rect width="1200" height="700" fill="url(#grid)" opacity=".6"/>
<!-- свечение слева -->
<ellipse cx="200" cy="350" rx="300" ry="250" fill="#F7A621" fill-opacity=".04"/>
<!-- вышка -->
<g opacity=".10" stroke="#F7A621" stroke-width="2" fill="none">
<line x1="900" y1="680" x2="960" y2="200" />
<line x1="1020" y1="680" x2="960" y2="200" />
<line x1="870" y1="580" x2="1050" y2="580"/>
<line x1="885" y1="480" x2="1035" y2="480"/>
<line x1="900" y1="380" x2="1020" y2="380"/>
<line x1="915" y1="300" x2="1005" y2="300"/>
</g>
<!-- Декоративный трубопровод убран: он проходил ровно по нижней кромке
hero и прочерчивал полосу через ленту нормативки. -->
<!-- факел -->
<rect x="1100" y="380" width="8" height="300" fill="#363D56" opacity=".3"/>
<ellipse cx="1104" cy="370" rx="14" ry="20" fill="#EF4444" opacity=".35"/>
<ellipse cx="1104" cy="360" rx="8" ry="14" fill="#F7A621" opacity=".4"/>
</svg>
</div>
<div class="container">
<div class="hero-grid">
<div>
<div class="tag hero-tag">v2.21 · Промышленная безопасность · ФЗ-116 · ОПО</div>
<h1>Бумажный наряд<br>убивает <span>время.</span><br>И иногда — людей.</h1>
<p class="hero-sub">
Оцифровали весь путь наряда — от черновика до закрытия с ЭП — и сжали его с трёх дней до нескольких часов. В v2.21 добавили 12 модулей в едином контуре: <strong style="color:var(--text)">медосмотры, ИОТ, стажировки, СИЗ, ПАБ, ОПР, скоринг, микротравмы, IoT, расследования НС</strong>.
</p>
<div class="hero-metric">
<div style="text-align:center">
<div class="was">3 дня</div>
<div class="ml">бумага</div>
</div>
<span class="arrow">→</span>
<div style="text-align:center">
<div class="now">2 часа</div>
<div class="ml">цифра + ЭП</div>
</div>
<div style="flex:1;text-align:right">
<div class="cut">−85%</div>
<div class="ml">времени согл.</div>
</div>
</div>
<div class="hero-btns">
<button class="btn btn-primary btn-lg" onclick="openModal()">Получить демо-доступ</button>
<a href="#pricing" class="btn btn-outline btn-lg">Рассчитать стоимость</a>
</div>
</div>
<!-- Мини-дашборд справа -->
<div class="hero-visual">
<div class="hero-screen">
<div class="screen-bar">
<div class="dot" style="background:#EF4444"></div>
<div class="dot" style="background:#F59E0B"></div>
<div class="dot" style="background:#22C55E"></div>
<div class="screen-url">наряд-допуск.рф / дашборд</div>
</div>
<div class="screen-body">
<div style="font-size:11px;color:var(--text-m);margin-bottom:4px;font-weight:600;letter-spacing:.06em;text-transform:uppercase">Активные наряды-допуски</div>
<div class="screen-permit">
<div class="ep-stamp">ЭП ✓</div>
<div class="permit-header">
<span class="permit-num">НД-2026-0042</span>
<span class="permit-status s-progress">В работе</span>
</div>
<div class="permit-type">🔥 Огневые работы — Газосборный коллектор ГК-3</div>
<div class="permit-meta">СибГС → ГПН · Исполнитель: Быков Б.Б.</div>
<div class="progress-bar"><div class="progress-fill" style="width:65%"></div></div>
</div>
<div class="screen-permit">
<div class="permit-header">
<span class="permit-num">ВР-2026-0018</span>
<span class="permit-status s-admitted">Допущен</span>
</div>
<div class="permit-type">🏗️ Работы на высоте — Кронблок БУ-3000 +36м</div>
<div class="permit-meta">ПГС → ЛУКОЙЛ · Руководитель: Павлов П.П.</div>
<div class="progress-bar"><div class="progress-fill" style="width:45%"></div></div>
</div>
<div class="screen-permit">
<div class="permit-header">
<span class="permit-num">ЗР-2026-0007</span>
<span class="permit-status s-pending">Согласование</span>
</div>
<div class="permit-type">⛏️ Земляные работы — Котлован под фундамент НА-02</div>
<div class="permit-meta">СибГС → ГПН · Ожидает: пожарная служба</div>
<div class="progress-bar"><div class="progress-fill" style="width:30%"></div></div>
</div>
<div class="screen-permit">
<div class="permit-header">
<span class="permit-num">ГО-2026-0031</span>
<span class="permit-status s-closed">Закрыт</span>
</div>
<div class="permit-type">☁️ Газоопасные — Задвижка №14, P=6 МПа</div>
<div class="permit-meta">МНК → НТЭК · Закрыт 13.06.2026</div>
<div class="progress-bar"><div class="progress-fill" style="width:100%;background:var(--text-m)"></div></div>
</div>
</div>
</div>
</div>
</div>
<!-- Нормативка — под сеткой hero, во всю ширину контейнера и в одну линию -->
<div class="hero-compliance">
<div class="lbl">Соответствует нормативке · 15+ документов</div>
<div class="chips">
<span>📋 ФЗ-116</span>
<span>🚒 МЧС №1800</span>
<span>⚙️ РТН №485</span>
<span>🎓 ПП РФ №2464</span>
<span>🩺 Приказ №29н</span>
<span>⚖️ ст. 218/220/226/227-231 ТК РФ</span>
<span>🔐 Ed25519 + AES-GCM</span>
<span>✍️ ФЗ-63 (ЭП)</span>
</div>
</div>
</div>
</section>
<!-- ══ STATS BAND (v2.21) ════════════════════════════════════════════════════ -->
<section class="stats-band">
<div class="container">
<div class="stats-grid">
<div class="stat-item">
<div class="stat-num">4</div>
<div class="stat-lbl">микросервиса<small>CORE · TRAINING · ASSETS · AUDITS</small></div>
</div>
<div class="stat-item">
<div class="stat-num">10+</div>
<div class="stat-lbl">типов нарядов-допусков<small>огневые · газоопасные · высотные · …</small></div>
</div>
<div class="stat-item">
<div class="stat-num">15+</div>
<div class="stat-lbl">нормативных документов<small>ФЗ · приказы · ГОСТ · ПБ</small></div>
</div>
<div class="stat-item">
<div class="stat-num" style="font-size:1.5rem;line-height:1.15">Ed25519<small style="margin-top:6px">AES-GCM · Argon2id</small></div>
<div class="stat-lbl">криптография<small>подпись · шифрование · пароли</small></div>
</div>
</div>
</div>
</section>
<!-- ══ FEATURES ═══════════════════════════════════════════════════════════════ -->
<section class="section section-alt" id="features">
<div class="container">
<div class="tag tag-info">Возможности</div>
<h2 class="section-title">Не просто форма. Живой процесс.</h2>
<p class="section-sub">Система не хранит документы — она управляет процессом. Каждый участник знает что делать, когда делать и кто задержался.</p>
<div class="features-grid">
<div class="feat-card">
<div class="feat-icon">📱</div>
<div class="feat-title">Телефон вместо принтера</div>
<div class="feat-desc">Инициатор создаёт наряд на месте. Руководитель подписывает не выходя из машины. Телефон на «яблоке» или на «андроиде» — одно приложение, никаких компромиссов по функциям.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🔐</div>
<div class="feat-title">Подпись, которую не подделать</div>
<div class="feat-desc">Алгоритм ГОСТ Р 34.10 / ECDSA P-256. Каждое действие — отдельная криптографическая подпись с хэшем содержимого и меткой времени. QR-код на наряде — публичная проверка подлинности без пароля.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">⚡</div>
<div class="feat-title">Маршрутизация без участия человека</div>
<div class="feat-desc">Система сама знает, кто следующий. Пожарная служба, ОТ, смежные подразделения — уведомление приходит нужному человеку в нужный момент. Вы не следите за процессом. Он работает.</div>
</div>
<div class="feat-card">
<div class="feat-icon">👥</div>
<div class="feat-title">Подрядчики — отдельно</div>
<div class="feat-desc">Бригада от субподрядчика видит только свои объекты. Никто лишний не создаёт наряды туда, куда не надо. Заказчик согласует, подрядчик исполняет — роли не путаются.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">📊</div>
<div class="feat-title">Метрики. Живые.</div>
<div class="feat-desc">Встроенные метрики в формате Prometheus. Экран мониторинга показывает узкие места прямо сейчас: кто тормозит согласование, сколько нарядов просрочено, где очередь. Grafana подключается за минуту.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">🔔</div>
<div class="feat-title">Пишет туда, где вы есть</div>
<div class="feat-desc">Эл. почта, Telegram, корпоративный мессенджер, уведомление на телефон. Не надо заходить в систему чтобы узнать новости — система сама найдёт. Просрочка тоже не пройдёт незамеченной.</div>
</div>
<div class="feat-card">
<div class="feat-icon">☸️</div>
<div class="feat-title">Ваша инфраструктура</div>
<div class="feat-desc">Готовый пакет развёртывания с 12 настроенными шаблонами — разворачивается на ваших серверах, в частном облаке, в закрытом контуре без интернета. Никакой зависимости от нашего сервера.</div>
</div>
<div class="feat-card">
<div class="feat-icon">📤</div>
<div class="feat-title">Бумага когда надо</div>
<div class="feat-desc">Печатные формы по актуальным бланкам. Реестр нарядов таблицей — одной кнопкой, для отчётов, аудиторов, Ростехнадзора. Всё уже заполнено. Вам остаётся только распечатать.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🏛️</div>
<div class="feat-title">Формы из НТД, не придуманные</div>
<div class="feat-desc">Приказ МЧС №1800, РТН №485, ПОТ РМ-016, Приказ Минтруда №782н. Формы взяты из нормативки напрямую — никаких «похожих на оригинал» самоделок.</div>
</div>
</div>
</div>
</section>
<!-- ══ MODULES (v2.18 → v2.21) ══════════════════════════════════════════════ -->
<section class="section" id="modules">
<div class="container">
<div class="tag">Модули</div>
<h2 class="section-title">12 модулей поверх нарядов. Один контур — все процессы.</h2>
<p class="section-sub">Кроме самих нарядов система закрывает всё, что вокруг них: медосмотры и инструктажи, выдачу спецодежды и поверку приборов, оценку рисков, проверки на объектах, разбор происшествий. Подключайте только то, что нужно вашему предприятию, — люди, доступы и подписи остаются общими, поэтому одни и те же данные не придётся заводить дважды.</p>
<div class="features-grid">
<div class="feat-card">
<div class="feat-icon">🩺</div>
<div class="feat-title">Медосмотры <span class="tz-tag">TZ-01</span></div>
<div class="feat-desc">Предсменные и периодические осмотры по Приказу Минздрава №29н. Контроль допуска по медзаключению, реестр противопоказаний, интеграция с медицинскими кабинетами.</div>
</div>
<div class="feat-card">
<div class="feat-icon">📄</div>
<div class="feat-title">ИОТ-документы <span class="tz-tag">TZ-01</span></div>
<div class="feat-desc">Инструкции по охране труда с QR-ознакомлением. Версионирование, лист ознакомления с криптоподписью, авто-блокировка допуска при истечении срока действия версии.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🎓</div>
<div class="feat-title">Стажировки <span class="tz-tag">TZ-01</span></div>
<div class="feat-desc">Контроль смен наставником по ПП РФ №2464. Журнал стажировки, отметки наставника, допуск к самостоятельной работе после минимального количества смен.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">🩹</div>
<div class="feat-title">Микротравмы <span class="tz-tag">TZ-02</span></div>
<div class="feat-desc">Учёт микротравм по ст. 226 ТК РФ с 01.03.2022. Реестр происшествий без потери рабочего времени, аналитика, эскалация в расследование НС при утяжелении.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">⚠️</div>
<div class="feat-title">Конфликты зон <span class="tz-tag">TZ-02</span></div>
<div class="feat-desc">Авто-детекция пересечения нарядов по зонам проведения работ по Приказу МЧС №1800. Предупреждение при создании, блокировка допуска при подтверждённом конфликте.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🦺</div>
<div class="feat-title">СИЗ + оборудование <span class="tz-tag">TZ-03</span></div>
<div class="feat-desc">Личные карточки учёта СИЗ, поверки оборудования по ФЗ-102. Напоминания о сроках поверки, блокировка наряда при просроченной поверке газоанализатора.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">📐</div>
<div class="feat-title">ОПР <span class="tz-tag">TZ-04</span></div>
<div class="feat-desc">Оценка профессиональных рисков, матрица 5×5, реестр рабочих мест по ст. 218 ТК РФ. Связка рисков с нарядами, контроль мероприятий по снижению, аудит-след.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🔍</div>
<div class="feat-title">ПАБ <span class="tz-tag">TZ-04</span></div>
<div class="feat-desc">Проверки аудита безопасности с mobile-обходом. Чек-листы, фотофиксация нарушений, предписания с дедлайнами, эскалация в наряды при критических замечаниях.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">⭐</div>
<div class="feat-title">Скоринг подрядчиков <span class="tz-tag">TZ-04</span></div>
<div class="feat-desc">Автоматический рейтинг на основе нарушений, просрочек и качества работ. Gating: подрядчик с низким скорингом не допускается к новым нарядам заказчика.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🚨</div>
<div class="feat-title">Расследования НС <span class="tz-tag">TZ-05</span></div>
<div class="feat-desc">Расследование несчастных случаев по ст. 227-231 ТК РФ. Формирование комиссии, материалы, протоколы, CAPA-мероприятия с контролем исполнения и сроками.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">📡</div>
<div class="feat-title">IoT-телеметрия <span class="tz-tag">TZ-05</span></div>
<div class="feat-desc">Подключение газоанализаторов и датчиков. Auto-suspend наряда при превышении ПДК, emergency_stop при критических значениях, лог событий в наряд.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🔌</div>
<div class="feat-title">Внешние интеграции <span class="tz-tag">TZ-05</span></div>
<div class="feat-desc">1С:ЗУП (кадры), ЕИСОТ (обучение), СЭД (документооборот), СОУТ (спецоценка). REST + webhook, маппинг справочников, аудит-лог каждой синхронизации.</div>
</div>
</div>
</div>
</section>
<!-- ══ ARCHITECTURE (v2.21) ══════════════════════════════════════════════════ -->
<section class="section section-alt" id="architecture">
<div class="container">
<div class="tag tag-info">Архитектура</div>
<h2 class="section-title">4 микросервиса. Монолит или split — на выбор.</h2>
<p class="section-sub">Платформа v2.21 разделена на 4 доменных микросервиса. На небольших объёмах они разворачиваются как монолит (один контейнер, одна БД). При росте — разделяются без переписывания кода, через конфигурацию оркестрации.</p>
<div class="arch-grid">
<div class="arch-card">
<div class="arch-head">
<div class="arch-icon">🛡️</div>
<div>
<div class="arch-name">CORE</div>
<div class="arch-tagline">Ядро системы</div>
</div>
</div>
<ul class="arch-list">
<li>Наряды-допуски (10 типов)</li>
<li>Пользователи и роли</li>
<li>Криптоподписи (Ed25519)</li>
<li>Маршрутизация согласований</li>
</ul>
</div>
<div class="arch-card">
<div class="arch-head">
<div class="arch-icon">🎓</div>
<div>
<div class="arch-name">TRAINING</div>
<div class="arch-tagline">Обучение и персонал</div>
</div>
</div>
<ul class="arch-list">
<li>Инструктажи (вводный, целевой…)</li>
<li>Проверка знаний (билеты, тесты)</li>
<li>Медосмотры (Приказ №29н)</li>
<li>ИОТ-документы, стажировки</li>
</ul>
</div>
<div class="arch-card">
<div class="arch-head">
<div class="arch-icon">🔧</div>
<div>
<div class="arch-name">ASSETS</div>
<div class="arch-tagline">Активы и оборудование</div>
</div>
</div>
<ul class="arch-list">
<li>СИЗ: личные карточки</li>
<li>Оборудование и инструмент</li>
<li>Поверки (ФЗ-102)</li>
<li>Графики замен и ТО</li>
</ul>
</div>
<div class="arch-card">
<div class="arch-head">
<div class="arch-icon">📋</div>
<div>
<div class="arch-name">AUDITS</div>
<div class="arch-tagline">Аудит и риск-менеджмент</div>
</div>
</div>
<ul class="arch-list">
<li>ОПР (ст. 218 ТК РФ)</li>
<li>ПАБ: предписания, обходы</li>
<li>Скоринг подрядчиков</li>
<li>Расследования НС (ст. 227-231)</li>
</ul>
</div>
</div>
<div class="arch-note">
<strong style="color:var(--amber)">Система растёт вместе с вами.</strong>
Начать можно с малого — одна площадка, небольшая команда. Когда объектов и людей станет больше, наращивать мощность будем мы, без остановки работы и без перехода на «другую версию»: система у вас останется той же самой, просто станет выдерживать бо́льшую нагрузку. Датчики на объектах и обмен данными с вашими кадровыми и учётными программами подключаются отдельно — по мере необходимости, а не всё сразу.
</div>
</div>
</section>
<!-- ══ TYPES ════════════════════════════════════════════════════════════════ -->
<section class="section" id="types">
<div class="container">
<div class="tag tag-info">10 типов нарядов</div>
<h2 class="section-title">Один тип работ — один наряд. Не больше.</h2>
<p class="section-sub">Огневые, земляные, высотные, электро — у каждого своя форма, свой воркфлоу, своя нормативка. Не надо адаптировать один бланк под все случаи жизни.</p>
<div class="types-grid">
<div class="type-card" style="border-color:#EF444433"><div class="type-icon">🔥</div><div class="type-name" style="color:#EF4444;font-weight:600;font-size:13px">Огневые</div><div class="type-name">Приложение №3<br>Приказ МЧС №1800</div></div>
<div class="type-card" style="border-color:#8B5CF633"><div class="type-icon">☁️</div><div class="type-name" style="color:#8B5CF6;font-weight:600;font-size:13px">Газоопасные</div><div class="type-name">ПБ 09-560-03</div></div>
<div class="type-card" style="border-color:#F59E0B33"><div class="type-icon">⚠️</div><div class="type-name" style="color:#F59E0B;font-weight:600;font-size:13px">Повышенной опасности</div><div class="type-name">ГОСТ Р 12.3.048</div></div>
<div class="type-card" style="border-color:#92400E33"><div class="type-icon">⛏️</div><div class="type-name" style="color:#b45309;font-weight:600;font-size:13px">Земляные</div><div class="type-name">Приказ РТН №485</div></div>
<div class="type-card" style="border-color:#0369A133"><div class="type-icon">🔧</div><div class="type-name" style="color:#0369A1;font-weight:600;font-size:13px">Ремонтные</div><div class="type-name">Приказ РТН №485</div></div>
<div class="type-card" style="border-color:#D9770633"><div class="type-icon">⚡</div><div class="type-name" style="color:#D97706;font-weight:600;font-size:13px">Электробезопасность</div><div class="type-name">ПОТ РМ-016-2001</div></div>
<div class="type-card" style="border-color:#7C3AED33"><div class="type-icon">🏗️</div><div class="type-name" style="color:#7C3AED;font-weight:600;font-size:13px">Работы на высоте</div><div class="type-name">Приказ Минтруда №782н</div></div>
<div class="type-card" style="border-color:#BE185D33"><div class="type-icon">🔩</div><div class="type-name" style="color:#BE185D;font-weight:600;font-size:13px">Сварочные</div><div class="type-name">Приказ МЧС №1800</div></div>
<div class="type-card" style="border-color:#04785733"><div class="type-icon">🎨</div><div class="type-name" style="color:#047857;font-weight:600;font-size:13px">Окрасочные</div><div class="type-name">ПОТ Р М-017-2001</div></div>
<div class="type-card" style="border-color:#1D4ED833"><div class="type-icon">🚀</div><div class="type-name" style="color:#1D4ED8;font-weight:600;font-size:13px">Пусконаладочные</div><div class="type-name">ПБ 08-622-03</div></div>
</div>
<div class="norms">
<span class="norm-tag">ФЗ-116 «О промышленной безопасности»</span>
<span class="norm-tag">Приказ МЧС России №1800 от 24.10.2022</span>
<span class="norm-tag">Приказ Ростехнадзора №485 от 20.11.2017</span>
<span class="norm-tag">ПОТ РМ-016-2001 (ПТЭП)</span>
<span class="norm-tag">Приказ Минтруда №782н от 16.11.2020</span>
<span class="norm-tag">ГОСТ Р 34.10-2012 (Электронная подпись)</span>
</div>
</div>
</section>
<!-- ══ WORKFLOW ═══════════════════════════════════════════════════════════════ -->
<section class="section section-alt" id="workflow">
<div class="container">
<div class="tag tag-info">Воркфлоу</div>
<h2 class="section-title">8 шагов. Каждый — с подписью.</h2>
<p class="section-sub">Никто не пропустит свой этап — система не даёт двигаться дальше, пока предыдущий не закрыт нужными людьми. Кворум, не доверие.</p>
<div class="workflow-steps">
<div class="wf-step">
<div class="wf-dot" style="border-color:var(--border-l);color:var(--text-s)">1</div>
<div class="wf-label">Черновик<br><small>инициатор</small></div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:#3B82F6;color:#3B82F6">2</div>
<div class="wf-label">На согласование<br><small>инициатор</small></div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:#3B82F6;color:#3B82F6">3</div>
<div class="wf-label">Рук. подписал<br><small>рук. работ</small></div>
<div class="wf-ep">ЭП п.10</div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:#8B5CF6;color:#8B5CF6">4</div>
<div class="wf-label">Службы<br>согласовали<br><small>ПБ + ОТ + смежные</small></div>
<div class="wf-ep">ЭП п.11 ×3</div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:var(--amber);color:var(--amber)">5</div>
<div class="wf-label">Подготовка<br>подтв.<br><small>отв. подготовки + отв. проведения</small></div>
<div class="wf-ep">ЭП п.12 ×2</div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:var(--green);color:var(--green)">6</div>
<div class="wf-label">Допущен<br><small>рук. работ</small></div>
<div class="wf-ep">ЭП п.17</div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:var(--green);color:var(--green)">7</div>
<div class="wf-label">В работе<br><small>инициатор</small></div>
</div>
<div class="wf-step">
<div class="wf-dot" style="border-color:var(--text-m);color:var(--text-m)">8</div>
<div class="wf-label">Закрыт<br><small>рук. работ + отв. проведения</small></div>
<div class="wf-ep">ЭП п.17 ×2</div>
</div>
</div>
<div style="margin-top:40px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:20px 24px;font-size:13px;color:var(--text-s)">
<strong style="color:var(--amber)">Земляные, высотные, сварочные и ещё четыре типа</strong> — они идут по укороченному пути. Шаг с подтверждением пожарного инспектора там не нужен: Приказ РТН №485, Приложение №4 прямо об этом говорит. Система знает разницу и применяет правильный воркфлоу автоматически.
</div>
</div>
</section>
<!-- ══ TRAINING (модуль ОТ/ПБ) ═══════════════════════════════════════════════ -->
<section class="section" id="training">
<div class="container">
<div class="tag tag-info">Инструктажи и проверка знаний</div>
<h2 class="section-title">Инструктаж просрочен? Допуска не будет.</h2>
<p class="section-sub">Журнал инструктажей, проверка знаний по Постановлению 2464 и допуск к работам — один контур. Система сама видит, кто не готов, и не пропустит его в наряд.</p>
<div class="features-grid">
<div class="feat-card">
<div class="feat-icon">🦺</div>
<div class="feat-title">Журнал, который не перепишешь</div>
<div class="feat-desc">Вводные, первичные, повторные, внеплановые и целевые инструктажи по ОТ и ПБ. Каждая запись подписана криптографически и защищена от правок задним числом на уровне базы. Печатная форма — журнал регистрации по ГОСТ 12.0.004, одной кнопкой.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🚦</div>
<div class="feat-title">Светофор готовности бригады</div>
<div class="feat-desc">Прямо на карточке наряда: у кого истёк повторный по ОТ, кому нужен противопожарный, кто без целевого. Режим на выбор организации: предупреждать — или жёстко блокировать допуск, пока нарушения не устранены.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">📝</div>
<div class="feat-title">Проверка знаний по 2464</div>
<div class="feat-desc">Банки вопросов, случайные билеты, серверный таймер — списать не получится. Подсчёт результата только на сервере, попытка фиксирует снапшот билета. Протокол подписывает комиссия — электронно, с кворумом. Сдал тест — инструктаж продлён автоматически.</div>
</div>
<div class="feat-card">
<div class="feat-icon">📲</div>
<div class="feat-title">QR — и работник сдаёт сам</div>
<div class="feat-desc">У рабочих бригад нет учёток — и не нужно. Инструктор показывает QR-код, работник сдаёт тест со своего телефона без регистрации. Или киоск-режим: планшет инструктора по кругу, контролирующий фиксируется в протоколе.</div>
</div>
<div class="feat-card">
<div class="feat-icon">🤳</div>
<div class="feat-title">Инструктаж в поле, без связи</div>
<div class="feat-desc">Целевой инструктаж бригаде — с телефона инструктора, подтверждение биометрией. Нет сети на объекте? Факт встаёт в очередь и синхронизируется сам, как только связь появится. Подпись ставит сервер — юридическая значимость не страдает.</div>
</div>
<div class="feat-card">
<div class="feat-icon feat-icon-info">🔁</div>
<div class="feat-title">Инцидент закрывает круг</div>
<div class="feat-desc">Серьёзное происшествие по наряду автоматически назначает бригаде внеплановый инструктаж — и до его проведения допуск считается нарушением. Напоминания за 14, 7 и 1 день до истечения сроков. Отчёт «Обученность персонала» — покрытие и pass-rate по каждой организации.</div>
</div>
</div>
<div class="norms" style="margin-top:32px">
<span class="norm-tag">Постановление Правительства №2464 от 24.12.2021</span>
<span class="norm-tag">Приказ МЧС №806 от 18.11.2021</span>
<span class="norm-tag">ГОСТ 12.0.004-2015 (журнал, формы А.5/А.6)</span>
</div>
</div>
</section>
<!-- ══ COMPLIANCE (v2.21) ════════════════════════════════════════════════════ -->
<section class="section section-alt" id="compliance">
<div class="container">
<div class="tag tag-info">Нормативное соответствие</div>
<h2 class="section-title">15+ нормативных документов. Каждый — с привязкой к модулю.</h2>
<p class="section-sub">Каждая форма и каждый воркфлоу в системе имеют нормативный источник. Не «похоже на приказ», а взят из конкретного пункта конкретного НТД — с указанием модуля, который его реализует.</p>
<div class="compliance-grid">
<div class="comp-block">
<div class="comp-block-title">🔥 Наряды-допуски и ОПО</div>
<div class="comp-chips">
<span class="comp-chip">ФЗ-116</span>
<span class="comp-chip">Приказ МЧС №1800</span>
<span class="comp-chip">ПБ 09-560-03</span>
<span class="comp-chip">Приказ РТН №485</span>
</div>
</div>
<div class="comp-block">
<div class="comp-block-title">🎓 Обучение и инструктажи</div>
<div class="comp-chips">
<span class="comp-chip">ПП РФ №2464</span>
<span class="comp-chip">Приказ Минтруда №772н</span>
<span class="comp-chip">Приказ Минтруда №766н</span>
<span class="comp-chip">Приказ Минтруда №782н</span>
</div>
</div>
<div class="comp-block">
<div class="comp-block-title">🩺 Медицина и СИЗ</div>
<div class="comp-chips">
<span class="comp-chip">Приказ Минздрава №29н</span>
<span class="comp-chip">Приказ Минздрава №266н</span>
<span class="comp-chip">ФЗ-102 (поверки)</span>
</div>
</div>
<div class="comp-block">
<div class="comp-block-title">⚖️ Трудовой кодекс</div>
<div class="comp-chips">
<span class="comp-chip">ст. 220 ТК РФ</span>
<span class="comp-chip">ст. 226 ТК РФ (микротравмы)</span>
<span class="comp-chip">ст. 218 ТК РФ (ОПР)</span>
<span class="comp-chip">ст. 227-231 ТК РФ (НС)</span>
</div>
</div>
<div class="comp-block">
<div class="comp-block-title">🔐 Криптография и ЭП</div>
<div class="comp-chips">
<span class="comp-chip">ФЗ-63 (ЭП)</span>
<span class="comp-chip">ГОСТ Р 34.10-2012</span>
<span class="comp-chip">Ed25519 (RFC 8032)</span>
<span class="comp-chip">AES-GCM (NIST SP 800-38D)</span>
<span class="comp-chip">Argon2id (RFC 9106)</span>
</div>
</div>
<div class="comp-block">
<div class="comp-block-title">🔒 ПДн и информбезопасность</div>
<div class="comp-chips">
<span class="comp-chip">ФЗ-152</span>
<span class="comp-chip">Приказ ФСТЭК №21</span>
<span class="comp-chip">ГОСТ 12.0.004-2015</span>
</div>
</div>
</div>
</div>
</section>
<!-- ══ PRICING ════════════════════════════════════════════════════════════════ -->
<section class="section" id="pricing">
<div class="container">
<div class="tag">Тарифы</div>
<h2 class="section-title">Своя лицензия — для каждой компании.</h2>
<p class="section-sub">Заказчики и подрядчики лицензируются отдельно. Цена зависит от числа пользователей и выбранных модулей: платите за ядро нарядов-допусков плюс те пакеты надстроек, которые нужны. Наряды расходуют квоту заказчика — на чьём объекте выполняются работы.</p>
<!-- Ползунки -->
<div class="pricing-controls">
<h3>ПОСЧИТАЙТЕ ДЛЯ СВОЕЙ ОРГАНИЗАЦИИ</h3>
<div class="slider-row">
<span class="slider-label">Пользователей в организации</span>
<input type="range" id="p-users" min="5" max="500" value="30" step="5">
<span class="slider-val" id="p-users-out">30</span>
</div>
<div class="slider-row">
<span class="slider-label">Нарядов в месяц</span>
<input type="range" id="p-permits" min="10" max="2000" value="150" step="10">
<span class="slider-val" id="p-permits-out">150</span>
</div>
<div style="font-size:13px;color:var(--text-m);margin-top:4px;padding:0 4px">
Для заказчика: добавьте пользователей всех согласующих служб. Для подрядчика: только ваши инициаторы.
</div>
<!-- v2.21: модульные пакеты — цена зависит от выбранных надстроек -->
<div class="mod-head">
<span class="mh-title">Модули (12 в 5 пакетах)</span>
<span class="mh-hint">Ядро включено · надстройки — по потребности</span>
</div>
<div class="mod-grid" id="mod-grid"><!-- рендерится из MODULE_PACKS --></div>
<div class="rate-line">
Тариф за пользователя:
<span>ядро <b id="rate-core">—</b></span>
<span>+ модули <b id="rate-mods">—</b></span>
<span>= <b id="rate-total">—</b> ₽/польз./мес</span>
</div>
</div>
<!-- Метрики -->
<div class="pricing-metrics">
<div class="pm-card"><div class="pm-val" id="pm-per-user">—</div><div class="pm-lbl">₽ / польз. / мес<br>(годовой тариф)</div></div>
<div class="pm-card"><div class="pm-val" id="pm-saving">—</div><div class="pm-lbl">₽ экономия<br>vs ежемесячной</div></div>
<div class="pm-card"><div class="pm-val" id="pm-permits-year">—</div><div class="pm-lbl">нарядов<br>в год</div></div>
<div class="pm-card"><div class="pm-val" id="pm-per-permit">—</div><div class="pm-lbl">₽ / наряд<br>(годовой тариф)</div></div>
</div>
<!-- Демо-плашка -->
<div style="background:var(--amber-d);border:1px solid rgba(247,166,33,.3);border-radius:var(--radius);
padding:16px 20px;margin-bottom:20px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;">
<div>
<span style="font-weight:700;font-size:14px;">Демо-доступ — бесплатно, 14 дней</span>
<span style="font-size:13px;color:var(--text-s);margin-left:12px;">До 5 пользователей · Все функции · Без карты</span>
</div>
<button class="btn btn-primary btn-sm" onclick="openModal('demo')">Получить демо →</button>
</div>
<!-- Пояснение модели лицензирования -->
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:24px">
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px">
<div style="font-size:12px;font-weight:700;color:var(--amber);letter-spacing:.06em;text-transform:uppercase;margin-bottom:8px">🏭 Заказчик</div>
<div style="font-size:13px;color:var(--text-s);line-height:1.6">Платит за своих согласующих: руководитель работ, пожарная служба, ОТ и ПБ, смежные службы. Квота нарядов — это нагрузка на его объект.</div>
</div>
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px">
<div style="font-size:12px;font-weight:700;color:var(--accent-2);letter-spacing:.06em;text-transform:uppercase;margin-bottom:8px">🔧 Подрядчик</div>
<div style="font-size:13px;color:var(--text-s);line-height:1.6">Платит за своих инициаторов. Наряды, которые они создают на объектах заказчика, идут в квоту заказчика — не подрядчика.</div>
</div>
</div>
<!-- Карточки тарифов -->
<div class="pricing-cards">
<div class="price-card">
<div class="price-name">Месячная подписка</div>
<div class="price-amount" id="pc-month">—</div>
<div class="price-period">₽ / месяц, оплата ежемесячно</div>
<ul class="price-feats">
<li>Ядро: все 10 типов нарядов</li>
<li style="color:var(--amber);font-weight:600">+ выбранные пакеты модулей</li>
<li>Веб + мобильное приложение</li>
<li>ЭП на каждом шаге</li>
<li>Поддержка 8×5</li>
<li style="color:var(--green);font-weight:600">Лимит = число оплаченных пользователей</li>
<li class="no">Нет скидки к годовому</li>
</ul>
<div class="price-cta">
<button class="btn btn-outline" style="width:100%" onclick="openModal('month')">Попробовать</button>
</div>
</div>
<div class="price-card featured">
<div class="price-badge">БЕРУТ ЧАЩЕ ВСЕГО</div>
<div class="price-name">Годовая подписка</div>
<div class="price-amount" id="pc-year">—</div>
<div class="price-period">₽ / месяц · <span class="price-discount" id="pc-year-saving">−20%</span> · оплата раз в год</div>
<ul class="price-feats">
<li>Всё из месячного</li>
<li>Поддержка 12×7 — без выходных</li>
<li>Печатные формы и реестр таблицей</li>
<li>Метрики и экран мониторинга</li>
<li>Онлайн-обучение команды</li>
<li style="color:var(--green);font-weight:600">Лимит = число оплаченных пользователей</li>
<li>Итого в год: <strong id="pc-year-total">—</strong> ₽</li>
</ul>
<div class="price-cta">
<button class="btn btn-primary" style="width:100%" onclick="openModal('year')">Оформить</button>
</div>
</div>
<div class="price-card">
<div class="price-name">Бессрочная лицензия</div>
<div class="price-amount" id="pc-perp">—</div>
<div class="price-period">₽ · единоразово · on-premise / ваше облако</div>
<ul class="price-feats">
<li>Всё из годового</li>
<li>Разворачиваете сами — мы помогаем</li>
<li>Пакет развёртывания, контейнеры, оркестрация</li>
<li>1 год поддержки в цене</li>
<li style="color:var(--green);font-weight:600">Лимит фиксируется в договоре</li>
<li>Со второго года: <span id="pc-support">—</span> ₽/год</li>
<li>Окупаемость: <span id="pc-payback">—</span></li>
</ul>
<div class="price-cta">
<button class="btn btn-outline" style="width:100%" onclick="openModal('perp')">Запросить КП</button>
</div>
</div>
</div>
<!-- ROI + Сравнение -->
<div class="roi-block">
<div>
<div style="font-size:14px;font-weight:600;margin-bottom:16px">Что экономит система (расчёт для заказчика)</div>
<div id="roi-rows"></div>
</div>
<div>
<div style="font-size:14px;font-weight:600;margin-bottom:16px">Сравнение с альтернативами</div>
<table class="comp-table">
<thead>
<tr><th>Решение</th><th class="num">₽/мес (ваш объём)</th><th class="num">Типов</th></tr>
</thead>
<tbody>
<tr class="our"><td><strong>Наряд-Допуск v2.21</strong></td><td class="num c-amber" id="comp-our">—</td><td class="num c-green">10</td></tr>
<tr><td>Visitech (SL Soft)</td><td class="num c-red">от 120 000</td><td class="num">6–8</td></tr>
<tr><td>1С:Производственная безопасность</td><td class="num c-red" id="comp-1c">—</td><td class="num">4</td></tr>
<tr><td>Бумажный процесс (скрытые затраты)</td><td class="num c-red" id="comp-paper">—</td><td class="num">∞</td></tr>
</tbody>
</table>
</div>
<!-- Пояснение к расчёту — на всю ширину блока, под обеими колонками -->
<p class="roi-note">
<strong>Как считаем.</strong> Один бумажный наряд — это 3.5 часа согласующих: физическая передача между кабинетами, ожидание подписей, архив. Система режет это на 70%. Ставка специалиста ОТ — 116 000 ₽ ÷ 176 рабочих часов = 659 ₽/ч. Подрядчику тоже выгодно: меньше времени инициатора на оформление — больше времени на саму работу. Для подрядчика экономия другая, но реальная.
</p>
</div>
</div>
</section>
<!-- ══ CTA ════════════════════════════════════════════════════════════════════ -->
<section class="section section-alt" id="contact">
<div class="container" style="text-align:center">
<div class="cta-banner">
<div class="tag" style="margin:0 auto 20px">Попробуйте</div>
<h2>Два дня — и стенд готов.</h2>
<p>Разворачиваем демо с вашими организациями и пользователями. Показываем весь путь наряда — от черновика до закрытия. Без презентаций. Руками.</p>
<div class="cta-btns">
<button class="btn btn-primary btn-lg" onclick="openModal()">Заказать демо-доступ</button>
<a class="btn btn-outline btn-lg" id="cta-phone-btn">Позвоните нам</a>
</div>
<div style="margin-top:28px;display:flex;justify-content:center;gap:32px;flex-wrap:wrap;font-size:14px;color:var(--text-s)">
<span id="cta-phone-text"></span>
<span id="cta-email-text"></span>
<span id="cta-tg-text"></span>
</div>
</div>
</div>
</section>
<!-- ══ MOBILE STICKY CTA ══════════════════════════════════════════════════════ -->
<div class="mobile-sticky-cta" id="mobile-sticky-cta">
<button class="btn btn-primary" onclick="openModal()">Заказать демо →</button>
<div class="sticky-phone"><a id="sticky-phone-link" href="#" style="color:var(--text-s)">📞 Позвонить</a></div>
</div>
<!-- ══ КНОПКА «НАВЕРХ» ════════════════════════════════════════════════════════ -->
<button class="to-top" id="to-top" type="button" aria-label="Вернуться в начало страницы" title="Наверх" onclick="scrollToTop()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M12 19V5"/><path d="M5 12l7-7 7 7"/>
</svg>
</button>
<!-- ══ FOOTER ══════════════════════════════════════════════════════════════════ -->
<!-- LAND-DES-02 (Sprint D): Social proof — testimonials для B2B доверия -->
<section class="section" id="trust" style="background:var(--bg);">
<div class="container">
<h2 class="section-title" style="text-align:center">Нам доверяют промышленные предприятия</h2>
<p class="section-sub" style="text-align:center;margin:0 auto 40px;">
Система эксплуатируется на объектах нефтегазового и химического комплекса
</p>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-bottom:36px;">
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:24px;">
<div style="font-size:28px;color:var(--amber);margin-bottom:8px;">★★★★★</div>
<p style="font-size:14px;line-height:1.6;color:var(--text);margin-bottom:16px;">
«Перешли с бумажных нарядов на электронные. Время согласования сократилось
с 2 дней до 2 часов. Пожарная служба и ОТ видят наряды мгновенно.»
</p>
<div style="display:flex;align-items:center;gap:12px;">
<div style="width:40px;height:40px;border-radius:50%;background:var(--amber-d);display:flex;align-items:center;justify-content:center;font-weight:700;color:var(--amber);">АИ</div>
<div>
<div style="font-size:13px;font-weight:600;color:var(--text);">Александр Иванов</div>
<div style="font-size:11px;color:var(--text-s);">Инженер ОТ и ПБ · нефтехимическое производство</div>
</div>
</div>
</div>
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:24px;">
<div style="font-size:28px;color:var(--amber);margin-bottom:8px;">★★★★★</div>
<p style="font-size:14px;line-height:1.6;color:var(--text);margin-bottom:16px;">
«Мобильное приложение с оффлайн-режимом — критично для полевых работников
на ОПО. QR-коды на нарядах, моментальная проверка подписей.»
</p>
<div style="display:flex;align-items:center;gap:12px;">
<div style="width:40px;height:40px;border-radius:50%;background:var(--amber-d);display:flex;align-items:center;justify-content:center;font-weight:700;color:var(--amber);">МП</div>
<div>
<div style="font-size:13px;font-weight:600;color:var(--text);">Михаил Петров</div>
<div style="font-size:11px;color:var(--text-s);">Руководитель подрядной организации</div>
</div>
</div>
</div>
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:24px;">
<div style="font-size:28px;color:var(--amber);margin-bottom:8px;">★★★★★</div>
<p style="font-size:14px;line-height:1.6;color:var(--text);margin-bottom:16px;">
«Электронные подписи с SHA-256 — прошли аудит Ростехнадзора.
История действий защищена триггерами БД, откат невозможен.»
</p>
<div style="display:flex;align-items:center;gap:12px;">
<div style="width:40px;height:40px;border-radius:50%;background:var(--amber-d);display:flex;align-items:center;justify-content:center;font-weight:700;color:var(--amber);">ЕС</div>
<div>
<div style="font-size:13px;font-weight:600;color:var(--text);">Елена Смирнова</div>
<div style="font-size:11px;color:var(--text-s);">Служба безопасности · ОПО</div>
</div>
</div>
</div>
</div>
<div style="display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin-top:24px;">
<span style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:8px 16px;font-size:12px;color:var(--text-s);">📋 ФЗ-116 (ОПО)</span>
<span style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:8px 16px;font-size:12px;color:var(--text-s);">✍ ФЗ-63 (ЭП)</span>
<span style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:8px 16px;font-size:12px;color:var(--text-s);">🔒 ФЗ-152 (ПДн)</span>
<span style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:8px 16px;font-size:12px;color:var(--text-s);">🔥 Приказ МЧС №1800</span>
<span style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:8px 16px;font-size:12px;color:var(--text-s);">⛏ Приказ РТН №485</span>
</div>
</div>
</section>
<footer>
<div class="container">
<div class="footer-inner">
<div class="footer-logo">
<svg width="24" height="24" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="Наряд-Допуск">
<!-- Logo A · Solid Shield — design-system/assets/logo.svg -->
<path d="M100 14 L170 40 L170 106 Q170 156 100 184 Q30 156 30 106 L30 40 Z" fill="#1A1E2C" stroke="#F7A621" stroke-width="9" stroke-linejoin="round"/>
<path d="M100 60 L141 128 Q144 134 137 134 L63 134 Q56 134 59 128 Z" fill="#F7A621"/>
<rect x="94" y="82" width="12" height="26" rx="4" fill="#1A1E2C"/>
<circle cx="100" cy="120" r="6" fill="#1A1E2C"/>
</svg>
<span style="font-family:var(--ff-head);letter-spacing:.06em;font-size:16px">НАРЯД-ДОПУСК v2.21</span>
</div>
<p class="footer-copy">© 2026 Наряд-Допуск v2.21 · Формы соответствуют: ФЗ-116, Приказ МЧС №1800, РТН №485, ПОТ РМ-016-2001, Приказ Минтруда №772н/766н/782н, Постановление №2464, Приказ Минздрава №29н/№266н, ФЗ-102, ФЗ-63, ст. 218/220/226/227-231 ТК РФ, ГОСТ 12.0.004-2015</p>
<div class="footer-links">
<a href="#features">Возможности</a>
<a href="#modules">Модули v2.21</a>
<a href="#architecture">Архитектура</a>
<a href="#compliance">Нормативка</a>
<a href="#pricing">Тарифы</a>
<a id="footer-email" href="#">Написать</a>
<a id="footer-tg" href="#">Telegram</a>
</div>
</div>
</div>
</footer>
<!-- ══ MODAL ═══════════════════════════════════════════════════════════════════ -->
<div class="overlay" id="overlay">
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<button class="modal-close" onclick="closeModal()" aria-label="Закрыть">×</button>
<div id="modal-form">
<h3 id="modal-title">ОСТАВЬТЕ ЗАЯВКУ</h3>
<p>Перезвоним в течение двух рабочих часов. Или напишите прямо сейчас — не будем тянуть.</p>
<div class="form-contact" id="form-contact-block"></div>
<!-- Бейдж лимита пользователей — показывается только для демо -->
<div id="f-limit-badge" style="display:none;background:rgba(245,158,11,.12);border:1px solid rgba(245,158,11,.35);
border-radius:var(--radius);padding:10px 14px;font-size:13px;color:#F59E0B;margin-bottom:16px;">
</div>
<div class="form-group">
<label>Имя и должность *</label>
<input type="text" id="f-name" placeholder="Иванов Иван Иванович, инженер ОТ и ПБ" required>
</div>
<div class="form-group">
<label>Компания *</label>
<input type="text" id="f-company" placeholder="ООО «Газпром добыча Ноябрьск»" required>
</div>
<div class="form-group">
<label>Телефон *</label>
<input type="tel" id="f-phone" placeholder="+7 (000) 000-00-00" required>
</div>
<div class="form-group">
<label>Электронная почта</label>
<input type="email" id="f-email" placeholder="ivan@company.ru">
</div>
<div class="form-group">
<label>Тариф</label>
<select id="f-plan">
<option value="">— Выбрать тариф —</option>
<option value="month">Месячная подписка — без ограничений по пользователям</option>
<option value="year">Годовая подписка — без ограничений по пользователям</option>
<option value="perp">Бессрочная лицензия — объём согласуется в КП</option>
<option value="demo">Демо-доступ — до 5 пользователей, 14 дней</option>
</select>
</div>
<div class="form-group" id="f-users-group">
<label>Примерное количество пользователей</label>
<select id="f-users-count">
<option value="">— Выбрать —</option>
<option value="5">До 5</option>
<option value="20">6–20</option>
<option value="50">21–50</option>
<option value="100">51–100</option>
<option value="200">101–200</option>
<option value="500">Более 200</option>
</select>
</div>
<div class="form-group">
<label>Комментарий</label>
<textarea id="f-comment" placeholder="Тип производства, срочность, особые требования..."></textarea>
</div>
<!-- Honeypot: поле скрыто от человека и невидимо для скринридера.
Боты заполняют все поля подряд — заполненное поле отсеивает заявку
на сервере. -->
<div style="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden" aria-hidden="true">
<label for="f-website">Не заполняйте это поле</label>
<input type="text" id="f-website" name="website" tabindex="-1" autocomplete="off">
</div>
<!-- LAND-SEO-07 (Sprint D): 152-ФЗ consent checkbox — обязателен для обработки ПДн -->
<div class="form-group" style="display:flex;align-items:flex-start;gap:10px;">
<input type="checkbox" id="f-consent" required style="margin-top:4px;flex-shrink:0;width:18px;height:18px;">
<label for="f-consent" style="font-size:12px;font-weight:400;line-height:1.5;color:var(--text-s);">
Я соглашаюсь с обработкой персональных данных в соответствии с
<a href="#" style="color:var(--amber);text-decoration:underline;">политикой конфиденциальности</a>
(ФЗ-152 «О персональных данных»). Данные используются только для связи по заявке.
</label>
</div>
<button class="btn btn-primary" style="width:100%" onclick="submitForm()">Отправить заявку →</button>
</div>
<div class="form-success" id="modal-success" style="display:none">
<div class="check">✅</div>
<h4>Получили.</h4>
<p>Свяжемся в течение двух часов. Если срочно — звоните прямо сейчас:</p>
<a class="btn btn-primary" style="margin-top:20px;display:inline-flex" id="success-phone">Позвонить</a>
</div>
</div>
</div>
<!-- ══ JAVASCRIPT ═════════════════════════════════════════════════════════════ -->
<script>
// ════════════════════════════════════════════════════════════════════════════
// НАРЯД-ДОПУСК — лендинг, основной скрипт
// Правило: функции вызываемые из onclick="" — только в глобальном scope.
// Инициализация DOM — только после DOMContentLoaded.
// ════════════════════════════════════════════════════════════════════════════
// ── Константы ценообразования (глобальные) ───────────────────────────────────
var BASE_PER_USER = 2200;
var YR_DISC = 0.20;
var SALARY = 116000;
var WH_MONTH = 176;
var HRS_PER = 3.5;
// v2.21: \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b-\u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u0426\u0435\u043d\u0430 \u2014 \u20bd/\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c/\u043c\u0435\u0441 \u0441\u0432\u0435\u0440\u0445 \u044f\u0434\u0440\u0430.
// 12 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 v2.18\u2013v2.21 \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 5 \u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432.
// id \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0435 (on:true) \u043e\u0442\u0440\u0430\u0436\u0430\u044e\u0442 \u0442\u0438\u043f\u043e\u0432\u0443\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0430 \u041e\u041f\u041e.
var MODULE_PACKS = [
{ id: 'core', name: '\u042f\u0434\u0440\u043e \u00b7 \u041d\u0430\u0440\u044f\u0434\u044b-\u0434\u043e\u043f\u0443\u0441\u043a\u0438', price: BASE_PER_USER, core: true,
desc: '10+ \u0442\u0438\u043f\u043e\u0432 \u043d\u0430\u0440\u044f\u0434\u043e\u0432, \u042d\u041f \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0448\u0430\u0433\u0435, \u0432\u0435\u0431 + \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435' },
{ id: 'labor', name: '\u041e\u0445\u0440\u0430\u043d\u0430 \u0442\u0440\u0443\u0434\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0430', price: 350, on: true,
desc: '\u041c\u0435\u0434\u043e\u0441\u043c\u043e\u0442\u0440\u044b, \u0418\u041e\u0422-\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b, \u0441\u0442\u0430\u0436\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430 \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u043c\u0435\u0441\u0442\u0435' },
{ id: 'assets', name: '\u0410\u043a\u0442\u0438\u0432\u044b \u0438 \u0434\u043e\u043f\u0443\u0441\u043a', price: 250, on: true,
desc: '\u0421\u0418\u0417 \u0438 \u043d\u043e\u0440\u043c\u044b \u0432\u044b\u0434\u0430\u0447\u0438, \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0432\u0435\u0440\u043a\u0438 (\u0424\u0417-102)' },
{ id: 'risk', name: '\u0420\u0438\u0441\u043a\u0438 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c', price: 400, on: false,
desc: '\u041e\u041f\u0420 (\u043e\u0446\u0435\u043d\u043a\u0430 \u043f\u0440\u043e\u0444. \u0440\u0438\u0441\u043a\u043e\u0432), \u041f\u0410\u0411, \u0441\u043a\u043e\u0440\u0438\u043d\u0433 \u043f\u043e\u0434\u0440\u044f\u0434\u0447\u0438\u043a\u043e\u0432' },
{ id: 'safety', name: '\u041f\u0440\u043e\u0438\u0441\u0448\u0435\u0441\u0442\u0432\u0438\u044f', price: 300, on: false,
desc: '\u041c\u0438\u043a\u0440\u043e\u0442\u0440\u0430\u0432\u043c\u044b, \u0440\u0430\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u041d\u0421 + CAPA, \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b \u0437\u043e\u043d' },
{ id: 'iot', name: 'IoT \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438', price: 500, on: false,
desc: 'IoT-\u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f \u0433\u0430\u0437\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432, 1\u0421:\u0417\u0423\u041f / \u0415\u0418\u0421\u041e\u0422 / \u0421\u042d\u0414 / \u0421\u041e\u0423\u0422' }
];
var PLAN_LIMITS = { month: null, year: null, perp: null, demo: 5 };
function fmtN(n) { return Math.round(n).toLocaleString('ru-RU'); }
function fmtR(n) { return fmtN(n) + ' \u20bd'; }
// \u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0442\u0430\u0440\u0438\u0444 \u0437\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f = \u044f\u0434\u0440\u043e + \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b.
function perUserRate() {
return MODULE_PACKS.reduce(function(s, p) { return s + ((p.core || p.on) ? p.price : 0); }, 0);
}
function modulesAddon() { return perUserRate() - BASE_PER_USER; }
// \u041e\u0431\u044a\u0451\u043c\u043d\u0430\u044f \u0441\u043a\u0438\u0434\u043a\u0430 \u043f\u043e \u0447\u0438\u0441\u043b\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e \u0432\u0441\u0435\u043c\u0443 \u0442\u0430\u0440\u0438\u0444\u0443
// (\u044f\u0434\u0440\u043e + \u043c\u043e\u0434\u0443\u043b\u0438), \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u044f\u0434\u0440\u0443.
function calcMonthly(users) {
var rate = perUserRate();
var tiers = [[20,0],[80,.2],[Infinity,.4]];
var total = 0, rem = users, prev = 0;
for (var i = 0; i < tiers.length; i++) {
var lim = tiers[i][0], disc = tiers[i][1];
var take = Math.min(rem, lim - prev);
if (take <= 0) break;
total += take * rate * (1 - disc);
rem -= take; prev = lim;
if (rem <= 0) break;
}
return Math.round(total);
}
// \u0420\u0435\u043d\u0434\u0435\u0440 \u0442\u0443\u043c\u0431\u043b\u0435\u0440\u043e\u0432 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 + \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.
function renderModulePacks() {
var grid = document.getElementById('mod-grid');
if (!grid) return;
grid.innerHTML = MODULE_PACKS.map(function(p) {
var active = p.core || p.on;
var cls = 'mod-toggle' + (p.core ? ' core' : (p.on ? ' on' : ''));
var priceHtml = p.core
? '<span class="mod-price">' + fmtN(p.price) + ' \u20bd</span>'
: '<span class="mod-price">+' + fmtN(p.price) + ' \u20bd</span>';
// type="button" только для настоящей кнопки: на <div> это невалидный атрибут.
return '<' + (p.core ? 'div' : 'button type="button"') + ' class="' + cls + '"' +
(p.core ? '' : ' data-pack="' + p.id + '" aria-pressed="' + active + '"') + '>' +
'<span class="mod-check">' + (active ? '\u2713' : '') + '</span>' +
'<span class="mod-body"><span class="mod-name">' + p.name + '</span>' +
'<span class="mod-desc">' + p.desc + '</span></span>' +
priceHtml +
'</' + (p.core ? 'div' : 'button') + '>';
}).join('');
grid.querySelectorAll('[data-pack]').forEach(function(btn) {
btn.addEventListener('click', function() {
var id = btn.getAttribute('data-pack');
var pack = MODULE_PACKS.filter(function(p) { return p.id === id; })[0];
if (pack) { pack.on = !pack.on; renderModulePacks(); updatePricing(); }
});
});
}
// ── Ценообразование ──────────────────────────────────────────────────────────
function updatePricing() {
var users = +document.getElementById('p-users').value;
var permits = +document.getElementById('p-permits').value;
document.getElementById('p-users-out').textContent = users;
document.getElementById('p-permits-out').textContent = permits;
var monthly = calcMonthly(users);
var yearMo = Math.round(monthly * (1 - YR_DISC));
var yearTotal = yearMo * 12;
var perp = monthly * 36;
var suppRen = Math.round(perp * .2);
var payback = Math.round(perp / monthly);
function setText(id, v) { var el = document.getElementById(id); if (el) el.textContent = v; }
// Разбивка тарифа за пользователя: ядро + модули = итог.
setText('rate-core', fmtN(BASE_PER_USER) + ' ₽');
setText('rate-mods', fmtN(modulesAddon()) + ' ₽');
setText('rate-total', fmtN(perUserRate()));
setText('pc-month', fmtN(monthly));
setText('pc-year', fmtN(yearMo));
setText('pc-year-total', fmtN(yearTotal));
setText('pc-perp', fmtN(perp));
setText('pc-support', fmtN(suppRen));
setText('pc-payback', payback + ' мес.');
var el = document.getElementById('pc-year-saving');
// Только скидка: остальной текст строки («оплата раз в год») уже в разметке.
// Раньше сюда дописывалось «Итого в год:» и строка читалась как обрывок.
if (el) el.textContent = '\u221220%';
setText('pm-per-user', fmtN(Math.round(yearMo / users)));
setText('pm-saving', fmtN((monthly - yearMo) * 12));
setText('pm-permits-year', fmtN(permits * 12));
setText('pm-per-permit', fmtN(Math.round(yearTotal / (permits * 12))));
var hrCost = Math.round(SALARY / WH_MONTH);
var paperHrs = permits * HRS_PER;
var savedHrs = Math.round(paperHrs * 0.70);
var saved = Math.round(savedHrs * hrCost);
var roiNet = saved - yearMo;
var roiEl = document.getElementById('roi-rows');
if (roiEl) roiEl.innerHTML =
'<div class="roi-row"><span>\u0427\u0430\u0441\u043e\u0432 \u043d\u0430 \u0431\u0443\u043c\u0430\u0436\u043d\u044b\u0435 \u043d\u0430\u0440\u044f\u0434\u044b \u0432 \u043c\u0435\u0441\u044f\u0446</span><span>' + fmtN(Math.round(paperHrs)) + ' \u0447</span></div>' +
'<div class="roi-row"><span>\u0421\u0442\u0430\u0432\u043a\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u0430 \u041e\u0422 (116 000 \u00f7 176 \u0447)</span><span>' + fmtN(hrCost) + ' \u20bd/\u0447</span></div>' +
'<div class="roi-row"><span>\u042d\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u221270% (' + fmtN(savedHrs) + ' \u0447 \u00d7 ' + fmtN(hrCost) + ' \u20bd)</span><span class="roi-green">+' + fmtR(saved) + '/\u043c\u0435\u0441</span></div>' +
'<div class="roi-row"><span>\u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 (\u0433\u043e\u0434\u043e\u0432\u043e\u0439 \u0442\u0430\u0440\u0438\u0444)</span><span class="roi-red">\u2212' + fmtR(yearMo) + '/\u043c\u0435\u0441</span></div>' +
'<div class="roi-row"><span>\u0427\u0438\u0441\u0442\u0430\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u044f</span><span class="' + (roiNet>=0?'roi-green':'roi-red') + '">' + (roiNet>=0?'+':'') + fmtR(roiNet) + '/\u043c\u0435\u0441</span></div>' +
'<div class="roi-row"><span>\u0427\u0438\u0441\u0442\u0430\u044f \u0432\u044b\u0433\u043e\u0434\u0430 \u0437\u0430 \u0433\u043e\u0434</span><span class="' + (roiNet>=0?'roi-green':'roi-red') + '">' + (roiNet>=0?'+':'') + fmtR(roiNet * 12) + '</span></div>';
var compOur = document.getElementById('comp-our');
var comp1c = document.getElementById('comp-1c');
var compPaper = document.getElementById('comp-paper');
if (compOur) compOur.textContent = fmtR(yearMo);
if (comp1c) comp1c.textContent = fmtR(Math.round(35000 + users * 3240 / 12));
if (compPaper) compPaper.textContent = fmtR(saved) + '/\u043c\u0435\u0441';
}
// ── Лимиты по тарифам ────────────────────────────────────────────────────────
function updateLimitBadge(plan) {
var badge = document.getElementById('f-limit-badge');
if (!badge) return;
var limit = PLAN_LIMITS[plan] || null;
if (limit) {
badge.textContent = '\u26a0 \u0414\u0435\u043c\u043e-\u0434\u043e\u0441\u0442\u0443\u043f: \u0434\u043e ' + limit + ' \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439';
badge.style.display = 'block';
} else {
badge.style.display = 'none';
}
}
// ── Модальное окно ────────────────────────────────────────────────────────────
function openModal(plan) {
var ov = document.getElementById('overlay');
if (!ov) return;
ov.style.display = 'flex';
document.documentElement.style.overflow = 'hidden';
var formEl = document.getElementById('modal-form');
var okEl = document.getElementById('modal-success');
if (formEl) formEl.style.display = '';
if (okEl) okEl.style.display = 'none';
if (plan) {
var sel = document.getElementById('f-plan');
if (sel) { sel.value = plan; updateLimitBadge(plan); }
}
}
function closeModal() {
var ov = document.getElementById('overlay');
if (ov) ov.style.display = 'none';
document.documentElement.style.overflow = '';
}
function closeIfOutside(e) {
if (e.target && e.target.id === 'overlay') closeModal();
}
function submitForm() {
var name = (document.getElementById('f-name') || {}).value || '';
var company = (document.getElementById('f-company') || {}).value || '';
var phone = (document.getElementById('f-phone') || {}).value || '';
var email = (document.getElementById('f-email') || {}).value || '';
var plan = (document.getElementById('f-plan') || {}).value || '';
var users = (document.getElementById('f-users-count') || {}).value || '';
var comment = (document.getElementById('f-comment') || {}).value || '';
var consent = (document.getElementById('f-consent') || {}).checked || false;
var website = (document.getElementById('f-website') || {}).value || ''; // honeypot
if (!name.trim() || !company.trim() || !phone.trim()) {
alert('Пожалуйста, заполните обязательные поля: Имя, Компания, Телефон');
return;
}
// LAND-SEO-07: проверка согласия 152-ФЗ
if (!consent) {
alert('Пожалуйста, подтвердите согласие на обработку персональных данных (ФЗ-152).');
return;
}
// Отправка заявки на почту через автономный мейлер лендинга (landing/mailer).
// Эндпоинт /api/lead намеренно НЕ ведёт в основное приложение: заявки должны
// доходить, даже когда backend недоступен.
var btn = event && event.target ? event.target : null;
if (btn) { btn.disabled = true; btn.textContent = 'Отправка…'; }
fetch('/api/lead', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: name.trim(), company: company.trim(), phone: phone.trim(),
email: email.trim(), plan: plan, users_count: users,
comment: comment.trim(), consent: true, website: website,
source: 'landing', submitted_at: new Date().toLocaleString('ru-RU'),
}),
}).then(function(res) {
// Разбираем текст ошибки от сервера — он объясняет причину человеку
// (не настроен SMTP, слишком часто, не заполнены поля).
if (!res.ok) {
return res.json().catch(function() { return {}; }).then(function(data) {
throw new Error(data.error || ('HTTP ' + res.status));
});
}
var formEl = document.getElementById('modal-form');
var successEl = document.getElementById('modal-success');
if (formEl) formEl.style.display = 'none';
if (successEl) successEl.style.display = '';
}).catch(function(err) {
// Ошибка — возвращаем кнопку и даём запасной канал связи
if (btn) { btn.disabled = false; btn.textContent = 'Отправить заявку →'; }
alert('Не удалось отправить заявку: ' + (err.message || 'сетевая ошибка') +
'\n\nПозвоните нам: ' + CONTACT_PHONE + ' или напишите: ' + CONTACT_EMAIL);
});
}
// ── Кнопка «Наверх» ──────────────────────────────────────────────────────────
function scrollToTop() {
closeMenu();
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
try {
window.scrollTo({ top: 0, behavior: reduce ? 'auto' : 'smooth' });
} catch (e) {
window.scrollTo(0, 0); // старые браузеры без объектной сигнатуры scrollTo
}
}
// ── Бургер-меню ──────────────────────────────────────────────────────────────
var _menuOpen = false;
function toggleMenu() {
_menuOpen = !_menuOpen;
var btn = document.getElementById('burger-btn');
var menu = document.getElementById('mobile-menu');
if (btn) { btn.classList.toggle('open', _menuOpen); btn.setAttribute('aria-expanded', _menuOpen); }
if (menu) { menu.classList.toggle('open', _menuOpen); menu.setAttribute('aria-hidden', !_menuOpen); }
document.body.style.overflow = _menuOpen ? 'hidden' : '';
}
function closeMenu() {
if (!_menuOpen) return;
_menuOpen = false;
var btn = document.getElementById('burger-btn');
var menu = document.getElementById('mobile-menu');
if (btn) { btn.classList.remove('open'); btn.setAttribute('aria-expanded', 'false'); }
if (menu) { menu.classList.remove('open'); menu.setAttribute('aria-hidden', 'true'); }
document.body.style.overflow = '';
}
// ── Инициализация (запускается после загрузки DOM) ───────────────────────────
document.addEventListener('DOMContentLoaded', function() {
// Контакты
var phone = (typeof CONTACT_PHONE !== 'undefined') ? CONTACT_PHONE : '+7 (912)420-23-89';
var email = (typeof CONTACT_EMAIL !== 'undefined') ? CONTACT_EMAIL : 'Bobretsov.AA@gmail.com';
var tg = (typeof CONTACT_TELEGRAM !== 'undefined') ? CONTACT_TELEGRAM : '@BobretsovAA';
var phoneHref = 'tel:' + phone.replace(/[^+\d]/g, '');
function setHTML(id, v) { var el = document.getElementById(id); if (el) el.innerHTML = v; }
function setText(id, v) { var el = document.getElementById(id); if (el) el.textContent = v; }
function setHref(id, v) { var el = document.getElementById(id); if (el) el.href = v; }
var navPhone = document.getElementById('nav-phone-link');
if (navPhone) {
navPhone.href = phoneHref;
navPhone.innerHTML = '\u260e\ufe0f ' + phone;
}
var mmPhone = document.getElementById('mobile-menu-phone');
if (mmPhone) { mmPhone.href = phoneHref; mmPhone.textContent = '\ud83d\udcde ' + phone; }
var stPhone = document.getElementById('sticky-phone-link');
if (stPhone) { stPhone.href = phoneHref; stPhone.textContent = phone; }
var ctaBtn = document.getElementById('cta-phone-btn');
if (ctaBtn) { ctaBtn.href = phoneHref; ctaBtn.textContent = '\ud83d\udcde ' + phone; }
setHTML('cta-phone-text', '\ud83d\udcde <a href="' + phoneHref + '" style="color:var(--text-s)">' + phone + '</a>');
setHTML('cta-email-text', '\u2709\ufe0f <a href="mailto:' + email + '" style="color:var(--text-s)">' + email + '</a>');
setHTML('cta-tg-text', '\ud83d\udcac <a href="https://t.me/' + tg.replace('@','') + '" style="color:var(--text-s)">' + tg + '</a>');
setHref('footer-email', 'mailto:' + email); setText('footer-email', email);
setHref('footer-tg', 'https://t.me/' + tg.replace('@','')); setText('footer-tg', tg);
setHref('success-phone', phoneHref); setText('success-phone', phone);
setHTML('form-contact-block',
'\u0418\u043b\u0438 \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e: ' +
'<a href="' + phoneHref + '">' + phone + '</a> · ' +
'<a href="mailto:' + email + '">' + email + '</a> · ' +
'<a href="https://t.me/' + tg.replace('@','') + '">' + tg + '</a>');
// Слайдеры ценообразования
var sliders = ['p-users', 'p-permits'];
sliders.forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('input', updatePricing);
});
renderModulePacks(); // v2.21: тумблеры модульных пакетов
updatePricing();
// Смена тарифа в форме
var planSel = document.getElementById('f-plan');
if (planSel) planSel.addEventListener('change', function() { updateLimitBadge(this.value); });
// Escape закрывает модалку
document.addEventListener('keydown', function(e) { if (e.key === 'Escape') closeModal(); });
// Закрыть меню при клике вне
document.addEventListener('click', function(e) {
var btn = document.getElementById('burger-btn');
var menu = document.getElementById('mobile-menu');
if (_menuOpen && btn && menu && !menu.contains(e.target) && !btn.contains(e.target)) closeMenu();
});
// Клик на оверлей вне модалки — закрыть
var overlay = document.getElementById('overlay');
if (overlay) overlay.addEventListener('click', closeIfOutside);
// Sticky CTA (после hero) и кнопка «Наверх» (после 400px) — один обработчик
// прокрутки на оба элемента вместо двух независимых слушателей.
var stickyCta = document.getElementById('mobile-sticky-cta');
var toTop = document.getElementById('to-top');
if (stickyCta) stickyCta.style.display = 'none';
function onScroll() {
var y = window.scrollY || document.documentElement.scrollTop;
if (stickyCta) {
var hero = document.querySelector('.hero');
// display CTA переключается только на мобайле (медиазапрос ставит flex),
// поэтому здесь снимаем/возвращаем inline-стиль, а не задаём его жёстко.
stickyCta.style.display = (hero && y > hero.offsetHeight) ? '' : 'none';
}
if (toTop) toTop.classList.toggle('show', y > 400);
}
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
}); // DOMContentLoaded
</script>
</body>
</html>
Sitemap
Кол-во: 0
XML-карта сайта для поисковиков
?
Sitemap.xml помогает поисковику быстрее находить и индексировать страницы. Особенно важен для крупных сайтов и новых страниц, на которые ещё нет входящих ссылок.
Robots.txt не содержит ссылку на карту сайта. Рекомендуется добавить карту сайта и указать ссылку на нее в robots.txt.
Внутренние ссылки
Не найдено
Ссылки на другие страницы своего сайта
?
Внутренние ссылки распределяют ссылочный вес между страницами и помогают поисковику обходить сайт. Пустые анкоры и ссылки на запрещённые robots.txt страницы — типичные ошибки.
Внутренних ссылок на странице 0 оптимально.
Внешние ссылки
Не найдено
Ссылки на сторонние сайты
?
Исходящие внешние ссылки передают часть ссылочного веса на чужие сайты. Ссылки на авторитетные ресурсы безопасны; ссылки на мусорные сайты могут навредить репутации страницы.
Внешних ссылок на странице не найдено.
Конкуренты Готовность: 0%
Конкуренты в Яндексе
Кол-во: 0
Топ сайтов-конкурентов в Яндексе
?
Сайты, чаще всего появляющиеся в ТОПе Яндекса по запросам из семантического ядра этой страницы.
Мы не нашли у вас конкурентов в Яндексе. Сайт или очень молодой или плохо продвигается.
Конкурентов в ТОП-10 Яндекса не нашлось.
Конкуренты в Google
Кол-во: 0
Топ сайтов-конкурентов в Google
?
Сайты, чаще всего появляющиеся в ТОПе Google по запросам из семантического ядра этой страницы.
Конкуренты в Google тоже не найдены. Займитесь продвижением сайта!
Конкурентов в ТОП-10 Google не нашлось.
ФЗ-152: ПД Готовность: 40%
РКН
ОК
Сайт не заблокирован
Контакты
https://narad-dopusk.ru/contacts/
Страница с контактами найдена
Политика ПД
https://narad-dopusk.ru/policy/
Страница политики обработки ПД найдена
Согласие
https://narad-dopusk.ru/personal/
Страница согласия на обработку ПД найдена
Чекбокс согласия
Не найден
Чекбокс согласия на обработку ПД в формах сайта не найден
Счётчики до согласия
ОК
Счётчики аналитики не собирают данные до согласия пользователя
ЗоЗПП: права потребителей Готовность: 25%
Наименование продавца
ОК
Полное наименование продавца на сайте
?
Ст. 9 ЗоЗПП: продавец обязан довести до покупателя фирменное наименование организации (ООО «…») или ФИО индивидуального предпринимателя. Укажите его в подвале сайта или на странице «Контакты».
Указано полное наименование продавца
Адрес продавца
Нарушение
Адрес (место нахождения) продавца
?
Ст. 9 ЗоЗПП: на сайте должен быть адрес места нахождения продавца. Добавьте его в подвал сайта или на страницу «Контакты».
Не указан адрес места нахождения продавца
ОГРН / ОГРНИП
Нарушение
Сведения о государственной регистрации продавца
?
Для дистанционной продажи обязательны сведения о госрегистрации продавца. Укажите ОГРН (для ИП — ОГРНИП) рядом с реквизитами, обычно в подвале сайта.
Не указан ОГРН/ОГРНИП
ИНН
Нарушение
ИНН продавца
?
Укажите ИНН организации или индивидуального предпринимателя рядом с остальными реквизитами продавца.
Не указан ИНН
Публичная оферта
Нарушение
Публичная оферта или условия продажи
?
Правила дистанционной продажи (ПП РФ № 2463) требуют довести до покупателя условия договора до его заключения. Опубликуйте публичную оферту или условия продажи и дайте на них ссылку из подвала сайта.
Нет публичной оферты / условий продажи
Возврат и доставка
Нарушение
Порядок возврата и доставки товара
?
Ст. 26.1 ЗоЗПП: при дистанционной продаже покупатель вправе отказаться от товара в течение 7 дней после получения. Опишите порядок и сроки возврата, обмена и доставки на отдельной странице.
Не описан порядок возврата (ст. 26.1 — 7 дней для дистанционной продажи)
Цены в рублях
ОК
Цены товаров в рублях
?
Ст. 10 ЗоЗПП: цена товара указывается в рублях. Добавьте обозначение валюты (₽ или руб.) к ценам на сайте.
Цены указаны в рублях
Режим работы
Нарушение
Режим работы продавца
?
Ст. 9 ЗоЗПП: укажите режим работы продавца (например, «пн–пт с 9:00 до 18:00») — обычно в шапке или подвале сайта.
Не указан режим работы
ФЗ-149: рекомендательные технологии Готовность: 100%
Нарушения
Не выявлены
Рекомендательные блоки («с этим покупают», «похожие товары» и т.п.) на сайте не обнаружены — требования ст. 10.7 ФЗ-149 к сайту не применяются. Нарушений нет.
ФЗ-38: реклама Готовность: 0%
Оговорка об оферте
Нарушение
Оговорка «не является публичной офертой» у цен
?
Ст. 3 ФЗ-38 (добросовестность рекламы): цены без условий договора могут вводить покупателя в заблуждение. Добавьте рядом с ценами оговорку «не является публичной офертой» либо опубликуйте публичную оферту.
Рекламные цены без страницы оферты и оговорки «не является публичной офертой» (ст. 3)
ФЗ-436: защита детей Готовность: 0%
Возрастная маркировка
Нарушение
Знак возрастной категории (0+, 6+, 12+, 16+ или 18+)
?
Ст. 11–12 ФЗ-436: информационная продукция (новости, видео, книги, игры, курсы) должна сопровождаться знаком возрастной категории. Разместите знак на видном месте — обычно в шапке или подвале сайта.
Информационная продукция без возрастной маркировки (ст. 11 ФЗ-436)
Вердикт
Оптимизация сайта narad-dopusk.ru выполнена на 74%, что говорит о высокой готовности к продвижению.
Исправьте ошибки в мета-тегах.
Поделитесь с друзьями: