Skip to content
cylaroPublic

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Сайт автосервиса «100 Машин», Воронеж

Статический сайт для GitHub Pages. Без бэкенда, без npm-зависимостей. 28 страниц, открытый прайс на 159 позиций, запись через WhatsApp.

Что нужно сделать перед публикацией

Пять пунктов, без которых сайт работает, но не в полную силу.

1. Домен

В CNAME указан 100mashin.ru — это заглушка, домен ещё не куплен.

Важно: 100-машин.рф занят несвязанным бизнесом — автосалоном подержанных машин с телефоном краснодарского кода. Использовать его нельзя.

Свободные варианты для проверки: 100mashin.ru, 100mashin36.ru, stomashin.ru, sto-mashin.ru, 100mashin-vrn.ru.

После покупки:

  1. Замените домен в CNAME (одна строка, без https://, без слэша).
  2. Замените https://100mashin.ru в src/pages/_shared.js (константа SITE) и в tools/build.mjs (константа SITE).
  3. Пересоберите: node tools/build.mjs.
  4. Настройте DNS у регистратора:
; Апекс — все четыре A-записи обязательны
100mashin.ru.      3600  IN  A     185.199.108.153
100mashin.ru.      3600  IN  A     185.199.109.153
100mashin.ru.      3600  IN  A     185.199.110.153
100mashin.ru.      3600  IN  A     185.199.111.153

; IPv6 — дополнительно к A, не вместо
100mashin.ru.      3600  IN  AAAA  2606:50c0:8000::153
100mashin.ru.      3600  IN  AAAA  2606:50c0:8001::153
100mashin.ru.      3600  IN  AAAA  2606:50c0:8002::153
100mashin.ru.      3600  IN  AAAA  2606:50c0:8003::153

; www → апекс, БЕЗ имени репозитория
www.100mashin.ru.  3600  IN  CNAME <ваш-логин>.github.io.
  1. В Settings → Pages укажите домен, дождитесь выпуска сертификата и включите Enforce HTTPS.
  2. Там же нажмите Verify domain и добавьте TXT-запись — это защищает от захвата поддомена.

Проверка DNS в PowerShell: Resolve-DnsName 100mashin.ru -Type A

2. Приём заявок на почту (необязательно)

Сейчас форма записи работает в режиме WhatsApp: заявка собирается в браузере и открывается в мессенджере с готовым текстом. Сеть не используется, ключи не нужны, всё работает сразу.

Если нужны дубли заявок на e-mail:

  1. Зарегистрируйтесь на web3forms.com (бесплатно, 250 заявок в месяц), укажите почту autolaw@inbox.ru.
  2. Впишите ключ в assets/js/config.js:
    export const WEB3FORMS_KEY = 'ваш-ключ-отсюда';
  3. Больше ничего делать не нужно. Форма уже помечена атрибутами data-booking и data-form, а собранный текст заявки лежит в скрытом поле message. Как только ключ задан, booking.js после открытия WhatsApp дополнительно отправляет ту же заявку на почту через form.js.

Пока ключ не задан, второй канал не активируется — иначе WhatsApp открывался бы дважды. Логика в booking.js, функция hasMailChannel().

Важно про 152-ФЗ: Web3Forms размещён за пределами РФ, это трансграничная передача данных. Раздел 4 в /politika/ описывает текущую схему (без передачи через сайт). Если подключите Web3Forms, дополните раздел 7 политики и проконсультируйтесь с юристом о необходимости уведомления Роскомнадзора.

3. Яндекс Метрика

  1. Создайте счётчик на metrika.yandex.ru.
  2. Впишите номер в assets/js/config.js:
    export const METRIKA_ID = 12345678;
  3. Раскомментируйте блок Метрики в src/partials/footer.html, подставив номер вместо 00000000.
  4. Пересоберите: node tools/build.mjs.

Пока METRIKA_ID = 0, трекинг полностью выключен и не даёт ошибок.

Цели, которые нужно создать в интерфейсе Метрики (тип — «JavaScript-событие»):

Идентификатор Что означает
PHONE_CLICK клик по телефону
WHATSAPP_CLICK переход в WhatsApp

| VK_CLICK | переход во ВКонтакте | | BOOKING_SEND | отправлена заявка на запись | | FORM_START | начал заполнять форму | | FORM_SUBMIT | форма отправлена | | CALC_USE | воспользовался калькулятором | | PRICE_VIEW | дочитал прайс до середины | | MAP_OPEN | открыл карту | | ROUTE_CLICK | построил маршрут |

4. Панели вебмастера

В src/partials/head.html замените заглушки:

<meta name="yandex-verification" content="REPLACE_YANDEX_VERIFICATION">
<meta name="google-site-verification" content="REPLACE_GOOGLE_VERIFICATION">

Затем в Яндекс Вебмастере: добавьте sitemap.xml, задайте регион Воронеж (Информация о сайте → Региональность) и создайте карточку в Яндекс Бизнесе, чтобы данные совпадали с микроразметкой.

5. Фотографии

Своих фотографий на сайте нет — намеренно. Стоковые картинки с иностранными номерами выглядят фальшиво и вредят доверию.

Что снять и добавить в assets/img/:

  • ремонтная зона, машины на подъёмниках;
  • станочный участок: фрезеровка и опрессовка ГБЦ, расточка блока;
  • мастера за работой (с их согласия), для страницы «О сервисе»;
  • магазин запчастей, стеллажи;
  • зона ожидания;
  • въезд и вывеска на обеих площадках — особенно на Труда, 46И, там сложный проезд и это отмечено в отзывах;
  • работы «до/после» для страницы /raboty/.

Формат: <picture> с AVIF/WebP/JPEG, обязательные width и height, осмысленный alt. Первое изображение на экране — fetchpriority="high" без loading="lazy", остальные — loading="lazy" decoding="async".

Как устроен проект

├── index.html, ceny/, uslugi/, ...   ← собранные страницы (не править вручную)
├── sitemap.xml                        ← генерируется сборщиком
├── CNAME, robots.txt, .nojekyll, manifest.webmanifest, favicon.ico
│
├── assets/
│   ├── css/
│   │   ├── styles.css        дизайн-система: @layer reset→tokens→base→layout→components→utilities
│   │   └── components/
│   │       ├── hero.css      первый экран, композиция главной, ритм секций
│   │       └── blocks.css    адреса, контакты, прайс, отзывы, гарантия
│   ├── js/                   ES-модули без зависимостей
│   │   ├── config.js         ВСЕ бизнес-данные: телефоны, адреса, ключи
│   │   ├── app.js            точка входа, вызывает остальные модули
│   │   ├── nav.js            меню, ловушка фокуса, отметка текущей страницы
│   │   ├── prices.js         рендер и фильтрация прайса
│   │   ├── calc.js           калькулятор оценки
│   │   ├── booking.js        запись → сообщение в WhatsApp
│   │   ├── form.js           отправка форм, режим WhatsApp / Web3Forms
│   │   ├── deeplinks.js      сборка ссылок WhatsApp
│   │   ├── map.js            карта по клику
│   │   ├── lazyblock.js      предзагрузка карт при приближении
│   │   ├── tabs.js           доступные табы
│   │   └── analytics.js      цели Метрики
│   ├── data/prices.json      159 позиций прайса
│   ├── fonts/                Golos Text, кириллический сабсет
│   └── img/
│
├── src/                      ← ИСТОЧНИК, правьте здесь
│   ├── partials/             head, header, footer — общие для всех страниц
│   └── pages/                по файлу на страницу или группу
│       ├── _shared.js        данные и переиспользуемые блоки
│       └── _service-page.js  конструктор страниц услуг
│
└── tools/build.mjs           сборщик

Как вносить правки

# собрать сайт
node tools/build.mjs

# только проверить, ничего не записывая
node tools/build.mjs --check

# качество разметки: h1, canonical, alt, JSON-LD, вес страниц
node tools/check.mjs

# логика модулей: прайс, калькулятор, слоты записи, ссылки
node tools/smoke.mjs

# мобильная адаптация в реальном браузере: 5 экранов x 12 страниц
# проверяет горизонтальную прокрутку, цели нажатия, перекрытия
node tools/mobile-audit.mjs

# визуальная согласованность: выравнивание колонок, единый набор радиусов
# и кеглей, контраст текста по WCAG, ритм отступов, пустоты в первом экране
node tools/check-design.mjs

# предзагрузка карт при подходе к блоку адресов
node tools/check-lazy.mjs

# посмотреть локально
python -m http.server 8000
# → http://localhost:8000

mobile-audit.mjs требует установленного Chrome или Edge: он поднимает браузер в headless-режиме и замеряет вычисленные стили, а не догадывается по CSS. Остальные проверки работают на одном Node.

Правьте только src/. Файлы index.html, ceny/index.html и остальные собранные страницы перезаписываются сборщиком.

Где что менять:

Что нужно Где править
Телефон, адрес, часы работы assets/js/config.js и src/pages/_shared.js
Цены assets/data/prices.json + таблицы в src/pages/uslugi-*.js
Меню, шапка, подвал src/partials/header.html, footer.html
Текст страницы соответствующий файл в src/pages/
Новая страница услуги добавить вызов servicePage({...}) в src/pages/uslugi-*.js
Стили assets/css/styles.css

Сборщик проверяет: дубли адресов, наличие и длину title и description, ровно один <h1> на странице, валидность JSON-LD и все внутренние ссылки. Если что-то не так, сборка сообщит об ошибке.

Что важно знать про содержание

Сайт построен на проверенных данных: рейтинг 4,7 и 120 оценок на Яндекс Картах, регистрация ООО «СТО МАШИН» с 27.09.2018, 17 сотрудников по отчётности за 2025 год, нормочас 1200 ₽, цены шиномонтажа с карточки Яндекса.

Осознанные решения, которые лучше не отменять:

  • aggregateRating в микроразметке отсутствует. Google запрещает самостоятельную разметку собственных отзывов, а перенос рейтинга Яндекса в свою разметку — нарушение. Рейтинг показывается виджетом Яндекса.
  • Отрицательные отзывы опубликованы на /otzyvy/ вместе с описанием изменений. Они всё равно видны на Картах; честный разбор работает лучше умолчания.
  • Часть цен помечена «оценка». Это позиции, рассчитанные по нормочасу, а не взятые из подтверждённого прайса. Пометка задаётся флагом est в prices.json. Перед публикацией стоит сверить их с мастерами.
  • Telegram не указан нигде — аккаунта у сервиса нет.
  • Доступность для маломобильных посетителей описана честно: оборудованного доступа нет, это указано в FAQ на /o-nas/.

Что стоит уточнить у сервиса

Список вопросов, ответы на которые улучшат сайт:

  1. Точные условия гарантии. Сроки в /garantiya/ составлены по отраслевой практике. Единственное упоминание в открытых источниках — «6 месяцев на капремонт», причём из жалобы. Нужно подтверждение владельца.
  2. Суббота — рабочая или нет. Источники расходятся, на сайте указано «по предварительной записи».
  3. Количество постов, подъёмников, площадь, марки оборудования — сильный аргумент доверия, данных нет.
  4. Эвакуатор — свой или партнёрский, радиус выезда.
  5. Автостёкла — реальная услуга или устаревшая категория в справочнике.
  6. Имена мастеров для страницы «О сервисе». В отзывах упоминаются Игорь, Андрей, Денис, Руслан, Александр, Дмитрий, Михаил.
  7. Сертификат представителя масел — какой бренд, действует ли.
  8. Мотоциклы и грузоперевозки рефрижератором — направления упоминались во ВКонтакте в 2025 году, актуальны ли сейчас.

Публикация

git add -A
git commit -m "Сайт автосервиса «100 Машин»"
git push -u origin main

Затем Settings → Pages → Source: Deploy from a branch, ветка main, папка / (root).

Обратите внимание: GitHub Pages отдаёт всё с Cache-Control: max-age=600 и изменить это нельзя. Поэтому имена файлов без хешей — кеш обновляется сам в течение 10 минут после публикации.

Дизайн-решения, которые лучше не откатывать

Каждое из них появилось после замера в браузере, а не по вкусу.

Правая колонка первого экрана. На всех страницах она заполнена карточкой (heroAside() в src/pages/_shared.js). Раньше внутренние страницы были одноколоночными, и при ширине 1440px справа оставалось 759px пустоты, а текст был зажат в 417px из-за max-width: 42ch у .hero__body. Это ограничение снято: ширину текста задаёт сам .hero__lead, а не контейнер.

Никакого абсолютного позиционирования плашек над текстом. Прежний .hero__media-note был спозиционирован absolute в расчёте на фотографию, которой нет, и накрывал список принципов. Правила удалены полностью.

Затемнённые оттенки для текста и заливок. Фирменные #e8590c и #1faa53 не проходят по контрасту, если на них белый текст полужирностью 600: дают 3,58 и 3,03 при норме 4,5. Поэтому кнопки залиты --amber-600 и --color-wa-hover, а зелёный текст ссылок использует отдельный токен --color-wa-text (5,43 на белом). Звёзды рейтинга — --amber-700. Номера в списках — --color-text-muted, а не --color-text-faint.

Разный ритм секций. Одинаковые отступы у всех секций читаются как машинная раскладка. Модификаторы: .section--chapter (смысловой водораздел, больше воздуха), .section--follow (продолжение мысли, меньше), .section--close. На каждой странице есть хотя бы один акцент — это проверяет check-design.mjs.

Колонки выровнены по высоте. .split--stretch тянет врезку на всю высоту строки: при align-items: start короткая колонка заканчивалась на 129px выше длинной, и блок выглядел несобранным.

Категории прайса свёрнуты. Все 159 позиций разом давали простыню на телефоне. Открыта первая группа, при поиске или выборе категории — раскрываются все (assets/js/prices.js, функция render).

Фотографий на сайте нет намеренно. Стоковые снимки с чужими машинами и иностранными номерами вредят доверию сильнее, чем помогает картинка. Место под фотографии в вёрстке предусмотрено — см. раздел 5 выше.

Анимации только как дополнение. Появление секций реализовано через animation-timeline: view() внутри @supports и @media (prefers-reduced-motion: no-preference). Элементы видимы по умолчанию: без поддержки браузера ничего не пропадает. opacity: 0 в базовом состоянии не используется нигде.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages