Кейс · 22 июня 2026 · v5.3

Ребилд лендинга UsmanovaFit в чистом HTML.

Тестовое задание: повторить три экрана лендинга фитнес-марафонов с реальными фото, ценами и рабочей формой. Сделано в одном файле за ~40 минут, без сборщиков и фреймворков.

Время ~40 мин
Стэк HTML · CSS · JS
Объём 4 экрана + v5.3 polish
В проде Vercel

Что просили повторить

Возьмите наш лендинг usmanovafit.gymteam.ru/mainpage и повторите любые три его экрана на ваш выбор в вашем вайбкодерском инструменте. Нужно, чтобы было собрано чисто и аккуратно, корректно открывалось на телефоне и ничего не разъезжалось, а кнопки и форма реально нажимались и работали. Источник: тестовое задание заказчика · вторая ссылка — kdz_june (форма)

Как собирал — по шагам

01

Скачал оригинал

Headless-Chrome (Playwright) на usmanovafit.gymteam.ru/mainpage + /kdz_june с полным рендером. Сохранил HTML, скриншоты, вытащил 102 URL фото через обход DOM и background-image.

02

Разобрал контент

Из DOM достал реальные названия 12 програм, описания, FAQ, реквизиты, ссылки на юридические документы. Цены тарифов нашёл на странице /maysale2026_7 — там, куда ведёт «Подробнее» в каталоге.

03

Скачал фото

13 изображений (1 hero + 12 программ) с их CDN GetCourse. Локально, без зависимости от чужих серверов. Имена переименовал в hero.jpg + program_01.pngprogram_12.png.

04

Собрал v1 → получил фидбэк → собрал v2

Первая версия была с силуэтами и сгенерированными текстами — заказчик попросил реальные фото, текста, цены и юридические блоки. Пересобрал: дословные описания, реальные тарифы, 4 модалки с офертой/политикой/согласием/службой заботы.

05

Автотесты Playwright

Прогнал на трёх вьюпортах (390/768/1440): document.scrollWidth = ширине вьюпорта (без overflow), scrollIntoView для кнопок, валидация формы (3 ошибки на пустую отправку), маска телефона, тик таймера, открытие/закрытие всех модалок. 0 JS-ошибок в консоли.

06

Деплой на Vercel

vercel deploy --prod --yes из папки проекта → алиас usmanovafit-test.vercel.app. Verify на живом URL тем же Playwright-набором. 0 failed requests, 13/13 фото загрузились, 4/4 модалки работают.

Три экрана — до и после

Выбрал воронку: первое касание → выбор программы → конверсия. Стилистика — моя (минимализм + крупная типографика, единая палитра), контент и фото — их.

Hero · первое касание

01

Большой розовый заголовок как единственный якорь на экране. Реальное фото Кати вместо стокового силуэта. CTA — в программы, а не «узнать больше».

Было · mainpage
Оригинальный hero
Стоковое позирование, cookie-баннер поверх, кнопка «Для корректной работы сайта отключите VPN» мешает первому экрану.
Стало · ребилд
Ребилд hero
Реальное фото с их CDN, тот же заголовок в оригинальной кодировке, stat-карточки (15 лет · 12 программ · −20кг) сразу дают социальное доказательство.

Каталог · выбор программы

02

На оригинале каталог скрывает цены за кнопкой «Подробнее» — это лишний клик. Я показал цены сразу, реальные фото каждой программы (12 карточек), дословные описания.

Было · mainpage
Оригинальный каталог
Карточки идут в длинной ленте, цены скрыты, к каждой ведёт отдельный клик на внешнюю страницу оплаты.
Стало · ребилд
Ребилд каталога
3 колонки на десктопе → 2 на планшете → 1 на мобиле. Флагманская карточка (тёмная, отдельный акцент) — первая в сетке. Цены сразу: 990–6 900 ₽.

Форма · конверсия

03

Тёмный лендинг с kdz_june: таймер, два тарифа, форма «Имя + E-mail + Телефон», живая маска на телефоне, валидация, success-экран. Юр. ссылки кликабельны — открывают модалки.

Было · kdz_june
Оригинальный kdz
GetCourse-форма с кучей скрытых полей, редирект на платежный шлюз, без явного success-состояния.
Стало · ребилд
Ребилд формы
Два тарифа с реальными ценами (6 900 ₽ / 5 600 ₽) переключаются радиокнопками. Маска +7 (___) ___-__-__. Согласие на рассылку с галочкой. Success: «Спасибо, {имя}!».

Тарифы · отдельный блок

04

В оригинале тарифы спрятаны внутри формы. Я вынес их в отдельный светлый блок между каталогом и формой: посетитель видит цены и состав ДО конверсии, не нажимая лишних кнопок. Тариф «Чемпионка» (6 900 ₽) — флагман с тёмной карточкой, «Спортсменка» (5 600 ₽) — базовый. Клик на CTA в карточке тарифа автоматически пре-селектит нужный тариф в форме ниже.

Стало · ребилд v4
Ребилд тарифов
Две карточки тарифов с фото, списком бонусов, ценой и рассрочкой. Без фреймов, без сторонних шрифтов, без модалок для выбора тарифа.

Lead-magnet −80% — одна фраза, не крик

В v4 я переборщил со скидкой 80% — она торчала и в hero, и в форме, и на фото. Заказчик попросил сделать чисто. Итог: одно упоминание в форме, тонкое напоминание сверху, ноль дублей.

A

Стёр из верхних блоков

Hero price-bar, вращающийся −80% бейдж на фото, plan__savings пилюля в карточке Чемпионки, sticky promo-бар — всё ушло. Hero снова чистый, плашка скидки не лезет в первый экран.

B

Оставил в форме — стильно

Заголовок form-section: «Превратите абонемент — со скидкой 80%». Розовый курсив, как паттерн «выберите свой» в блоке тарифов. Без тяжёлой тёмной плашки с гигантской цифрой, без пульса.

C

Вернул тонкий promo-бар

Сверху sticky строчка: «−80% Скидка 80% на тариф «Чемпионка» — только до конца акции» + CTA «Забрать со скидкой». Всегда видна, не мешает фото, ведёт к форме. −67% на «Спортсменке» — оставил (другая скидка, не дубль).

Было · v4
v4 форма с дублями 80%
3 упоминания 80% в одном блоке: tag + big-цифра в тёмном боксе + пилюля на карточке тарифа + кнопка. Шумно.
Стало · v5.3
v5.3 форма с одним упоминанием 80%
1 упоминание 80% в title (розовый курсив). Тонкий promo-бар сверху как напоминание. В карточках тарифов — только цены и −67% (другая скидка).

Стэк — нарочно простой

Никаких фреймворков, сборщиков, CDN-картинок. Один HTML-файл, inline CSS и JS, папка с фото. Открывается офсейн после первой загрузки шрифта.

01

HTML5 + CSS3

CSS Grid + Flexbox, custom properties, @media для мобилки. Без препроцессоров, без Tailwind — всё написано руками для полного контроля над метриками.

02

Vanilla JS

~120 строк: smooth scroll, IntersectionObserver для reveal-анимаций, таймер обратного отсчёта, валидация формы, маска телефона, модалки по data-modal + Escape для закрытия.

03

Manrope + Fraunces

Manrope (sans, кириллица) для основного текста, как в оригинале. Крупные цифры — без засечек. Шрифты с Google Fonts, с preconnect для скорости.

Автотесты на живом URL

Playwright-скрипт прогоняется после каждого изменения. Вот что он ловит на usmanovafit-test.vercel.app:

13 из 13 фото загрузились (hero jpg + 12 программ)
Hero CTA плавно скроллит к #programs
Кнопки «Подробнее» на карточках → #signup
4 из 4 модалки (Служба заботы / Оферта / Политика / Согласие) открываются
Закрытие по клику на бэкдроп и по Escape
2 из 2 тарифа переключаются радиокнопками
Клик на CTA в карточке тарифа → пре-селект в форме
Пустая отправка формы → 3 ошибки (имя / e-mail / телефон)
Валидная отправка → success-экран «Спасибо, {имя}!»
Маска 9261234567+7 (926) 123-45-67
Countdown тикает (замерял: 21с → 19с за 1.5с реального времени)
Sticky promo-бар вверху → CTA ведёт к #signup
−80% упоминается в форме ОДИН раз (в title), плюс в тонком promo-баре. −67% в «Спортсменке» — другая скидка.
0 горизонтального overflow на 390 / 768 / 1440
0 JS-ошибок в консоли

Готовый лендинг — живой

Кликайте кнопки, отправляйте форму, открывайте юр. модалки. Сайт реально работает на Vercel, проверки в этом кейсе — не теория, а факт прогона.

Открыть лендинг

Исходник: один HTML-файл · дизайн: Mavis