- Новый порядок этапов (D-026): фаза 1 — концепт на dev без внешних сервисов (1b сайт, 1c вход, 1d ключи, 1e счёт и демо-оплата, 1f демо-выдача, 1g продления, 1h рефералы); фаза 2 — Telegram; фаза 3 — ALTCHA, ЮKassa, почта, Twenty, Chatwoot, Umami, выдача через API и публичный запуск; фаза 4 — звёзды и эквайринги. - Решения: демо-оплата по списку IP (D-027), выдача ключей через адаптер manual/demo/api (D-028), страницы сайта из блоков Payload (D-029), пересборка через revalidatePath (D-030), RU-адрес у mass (D-031), счётчик свободных серверов (D-032), переводы на 5 языков в каждом этапе (D-033). - Тексты описывают работающий продукт; Вейликс — выделенный IP на общем сервере; Telegram поддержки — @veilix_support; сроки ответа не обещаем; VPN-серверы не ведут журналов. - Ссылки на этапы во всех документах, Q-12 решён (ЮKassa для RUB), R-19 (библиотеки для headless Chromium) сделано. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15 KiB
07. Фронтенд
1. Макеты
- Источник — design/handoff/project/, экспорт Claude Design. Прототипы на HTML: разметка внутри
<x-dc>, логика в<script data-dc-script>, стили — inline плюс CSS-переменные в<style>.support.js— среда выполнения прототипа, в продукт не переносится. - Задача — воспроизвести внешний вид точно, читая код макетов: отступы, размеры, цвета, состояния. Внутреннюю структуру прототипа не копируем.
- Тексты макетов — на русском, английские версии — в
i18n.js(словарь «русская строка → английская»). - Бриф дизайна —
design/handoff/project/uploads/(файл «Дизайн VEILIX.md»). Где бриф расходится с прототипами или с 01-product.md, верны прототипы и 01-product.
2. Какой макет куда
| Макет | Вейликс | ВейликсВПН |
|---|---|---|
Main / MassMain |
veilix.app / |
veilixvpn.com / |
Price / MassPrice |
/pricing |
/pricing |
Locations / MassLocations |
/locations |
/locations |
Support / MassSupport |
/support |
/support |
Order / MassOrder |
my.veilix.app /order |
my.veilixvpn.com /order |
App / MassApp |
my.veilix.app: /login, /, /keys, /keys/[id], /buy, /billing, /referral |
то же на my.veilixvpn.com |
AppTG / MassAppTG |
tg.veilix.app (этап 2a) | tg.veilixvpn.com (этап 2a) |
Плюс страницы без макета: /legal/terms, /legal/privacy, /legal/refund, /legal/cookies, 404 и 500 — в стиле сайта.
3. Маршруты кабинета
| Путь | Что |
|---|---|
/login |
вход по коду |
/ |
главная: ключи, «Купить ключ», FAQ |
/keys, /keys/[id] |
список ключей, страница ключа: срок, автопродление, «Продлить сейчас», WG-конфиги (скачать, QR), ссылка Happ/Xray (копировать, QR) |
/buy |
покупка внутри кабинета: dedicated — сетка локаций с ценами, mass — «Месяц» и «Год» |
/order |
оформление заказа: шаги «Почта» и «Оплата», сводка |
/billing |
баланс, пополнение, карта, ближайшие списания, история |
/referral |
реферальная программа |
/more |
вкладка «Ещё» на узком экране: счёт, рефералы, поддержка, тема, язык |
/r/[код] |
реферальная ссылка: ставит cookie и ведёт на сайт бренда |
Навигация по макету: на широком экране — боковая панель, на узком — плавающая панель вкладок «Главная, Ключи, Купить, Ещё».
4. Темы и токены
- Tailwind v4: токены макета — CSS-переменные, подключённые в
@theme. Бренд задаёт атрибутdata-site="dedicated|mass"на<html>, тему —data-theme="light|dark". Режим «Как в системе» следуетprefers-color-scheme. - Переключатель темы — 3 режима, как в макете. Выбор хранится в localStorage (ключ
vx_theme), тема применяется скриптом в<head>до отрисовки. Новый посетитель видит «Как в системе». localStorage у каждого хоста свой: тема, выбранная на сайте, не переходит в кабинет. - Токены в OKLCH, как в макете. Ниже — для ориентира; точные значения — в
<style>прототипов, при расхождении верен прототип.
| Токен | Вейликс светлая | Вейликс тёмная | ВейликсВПН светлая | ВейликсВПН тёмная |
|---|---|---|---|---|
--bg |
99% .005 296 (#fcfbff) | 17% .022 296 (#100d18) | 99.6% .0015 215 | 23% .026 210 |
--surface |
100% 0 0 | 21% .026 296 | 100% 0 0 | 26.5% .028 210 |
--surface-2 |
97.5% .01 296 | 24% .03 296 | 98.4% .003 215 | 30% .03 210 |
--ink |
24% .04 296 (#211b30) | 96% .01 296 | 24% .04 204 | 96% .012 196 |
--ink-2 |
45% .03 296 | 79% .02 296 | 45% .03 204 | 80% .02 196 |
--ink-3 |
60% .025 296 | 63% .025 296 | 60% .025 204 | 65% .025 196 |
--border |
92% .014 296 | 31% .032 296 | 92% .014 200 | 36% .04 204 |
--accent |
45% .17 296 (#6137a6) | 74% .15 296 (#b495fe) | 48% .105 178 (#00705e) | 76% .105 190 (#52c6c0) |
--accent-hover |
38% .17 296 | 80% .13 296 | 41% .1 178 | 83% .09 190 |
--accent-soft |
95.5% .028 296 | 27% .05 296 | 95.5% .032 180 | 31% .05 190 |
--on-accent |
99% .01 296 | 17% .03 296 | 99% .01 180 | 20% .04 204 |
--glow-1/2/3 |
86% .1 296 / 89% .09 266 / 91% .08 332 | 45% / 40% / 42% | 86% .085 190 / 88% .075 205 / 89% .07 172 | 52% .09 200 / 47% .085 215 / 50% .08 180 |
--sel |
— | — | 96.5% .016 190 | 30% .03 195 |
Общие для брендов: --warn (62% .14 62 / 78% .13 62), --tg (62% .15 250 / 70% .13 250), --veil (белый 55% / 7%), --shadow, цвета карты --land, --land-line, --ocean.
В коде токены — src/styles/tokens.css, утилиты Tailwind называются так же (bg-surface, text-ink-2, bg-sel); стандартная палитра Tailwind отключена. У Вейликса --sel равен --accent-soft. Цвета карт Вейликса: глобус в hero — значения Main (они светлее), плоская карта — значения Locations (решено на этапе 1b).
5. Шрифты, иконки, логотип
- Commissioner 300–600 — весь текст; Unbounded 600 — только надпись логотипа. Подключение через
next/font: файлы скачиваются при сборке и отдаются с нашего домена, без запросов к Google Fonts. Наборы символов: latin, latin-ext, cyrillic. - Иконки, флаги и логотип в макете нарисованы CSS-фигурами. Переносим их React-компонентами, сохраняя вид.
- Логотип — вариант «Слои». Фавиконы —
favicon.svgиfavicon-mass.svgиз макета.
6. Карта мира
- В макете карта строится в браузере через d3 и topojson с загрузкой данных с CDN. В продукте SVG-карта рендерится на сервере при сборке: d3-geo, проекция Natural Earth, данные
world-atlas(countries-110m) из npm. - В браузере — только интерактив: подсветка, всплывающая карточка, синхронизация с сеткой локаций.
- На узком экране карта прокручивается горизонтально, как в макете.
- Глобус в hero главной (
Main,MassMain) — ортографическая проекция, тоже рисуется на сервере, без интерактива.
7. Решения по расхождениям в макетах
- Устройств — 5, это поле тарифа. Цена продления dedicated — 2 499 ₽, цены задаются тарифами (3 уровня).
- Оформление заказа получает тариф, локацию и валюту из ссылки. В макете там всегда Нидерланды и 4 900 ₽.
- Поля номера карты из макета
Orderне делаем: карта вводится в виджете провайдера (этап 4b). В фазе 1 — демо-оплата (D-027). - Mass: в кабинете «Список ключей», без «текущей/запасной локации» и без экрана смены страны. Внутри ключа — ссылка Xray и WG-конфиги по странам.
- Статус локации показываем везде одинаково: в списках, карточках и на карте.
- Кнопка «Получить VPN» на главной ведёт к блоку цен на этой же странице, на остальных страницах — на
/pricing. - FAQ — одна коллекция с местами показа: главная, цены, поддержка (3 раздела), кабинет, MiniApp.
- Контакты поддержки берутся из настроек сайта, Telegram — ссылка на бота поддержки.
- Плашки способов оплаты в подвале — по активным платёжным системам сайта.
- Добавляем то, чего нет в макете: переключатель валюты,
<title>и мета-описания, H1 на каждой странице, поддержкуprefers-reduced-motionдля анимаций. - Количество свободных серверов показываем рядом со статусом, если поле заполнено (D-032).
- Переключатели при 5 языках и с валютой (в макете только RU/EN, валюты нет). В шапке — выпадающие списки языка и валюты. В подвале, мобильном меню и кабинете — сегменты с кодами языков (EN RU DE FR ES) и символами валют (₽ $). В оболочке кабинета валюты нет: она появится в настройках (1f).
- В подвале четыре документа: добавлена «Политика cookies». Плашек способов оплаты нет, пока нет видимых пользователю платёжных систем (пункт 9).
- Кабинет mass: подписи навигации те же, что у dedicated («Список ключей», «Купить ключ», «Ключи»). Подписи макета MassApp («Подключения», «Выбрать страну», «Подписка») не используем (пункт 4).
- Ширина надписи логотипа — по содержимому: в макете она подогнана под русское название.
-
- При
notFound()Next 16 отдаёт пустую оболочку (<html id="__next_error__">), а страница 404 в оформлении бренда отрисовывается в браузере; статус ответа — 404. Серверную отрисовку 404 и 500 решаем на этапе 1b вместе с их оформлением: вариант —global-not-found.js.
- При
- Реферальная программа (1h): бонус — дни срока ключа, а не деньги (D-025). Текст под ссылкой «Месяц начисляется вам и другу… и применяется к ближайшему списанию» заменяем на условия в днях. В истории платежей строка «Реферальный бонус» показывает «+30 дней» вместо «+2 499 ₽». Счётчик «Месяцев начислено» и статусы приглашённых остаются.
- Тексты описывают работающий продукт, а не ограничения текущего этапа: «сразу после оплаты», оплата картой, автопродление, смена страны — как в макетах (D-026).
- Тексты страниц — в Payload, страницы собираются из блоков (D-029).
- Вейликс — «индивидуальный IP»: выделенный адрес на общем сервере. Формулировки «персональный сервер», «без соседей по серверу», «персональные VPN-серверы» не используем.
- ВейликсВПН: RU-адрес входит в ключ, но страной не считается (D-031); число стран — из данных, только «Включено»; протоколы — Xray и WireGuard.
- Поддержка: сроки ответа не обещаем, часы — «с 10 до 20 по московскому времени в рабочие дни». Telegram —
@veilix_supportу обоих брендов, пока нет ботов поддержки (этап 3e).
8. Состояния, которых нет в макетах
Рисуем в стиле макета на соответствующих этапах:
- Вход: ошибка кода, истёкший код, таймер повторной отправки, загрузка.
- Ключ: готовится (до 24 часов), льготный период, истёк, заблокирован; пустой список ключей; ключ без подключений.
- Заказ: «ожидает оплаты», не хватает баланса, оплата не прошла (этап 1e); 3-D Secure и счёт в криптовалюте — этап 4b.
- Счёт: своя сумма пополнения, подтверждение отвязки карты, результат пополнения.
- Общие: уведомления (тосты), скелетоны загрузки, страницы 404 и 500, ошибки валидации форм.
9. Производительность и доступность
- Маркетинговые страницы: Lighthouse mobile ≥ 90 (цель 95+), LCP ≤ 2 с, CLS ≤ 0.05, INP ≤ 200 мс.
- JavaScript в браузере — только интерактивные островки: переключатели языка, валюты и темы, FAQ, выбор локации, формы, карта.
- Сторонние скрипты при первой загрузке — только Umami (асинхронно). ALTCHA подгружается только на формах.
- Доступность — WCAG 2.1 AA: контраст, видимый фокус, работа с клавиатуры для выпадающих списков, аккордеонов и шитов, области нажатия ≥ 44 px.