Files
veilix.app/docs/07-frontend.md
T
andreypr207andClaude Opus 5.5 515acfb69d Документация: этапы по фазам, решения D-026…D-033
- Новый порядок этапов (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>
2026-10-22 03:48:10 +02:00

15 KiB
Raw Blame History

07. Фронтенд

1. Макеты

  1. Источник — design/handoff/project/, экспорт Claude Design. Прототипы на HTML: разметка внутри <x-dc>, логика в <script data-dc-script>, стили — inline плюс CSS-переменные в <style>. support.js — среда выполнения прототипа, в продукт не переносится.
  2. Задача — воспроизвести внешний вид точно, читая код макетов: отступы, размеры, цвета, состояния. Внутреннюю структуру прототипа не копируем.
  3. Тексты макетов — на русском, английские версии — в i18n.js (словарь «русская строка → английская»).
  4. Бриф дизайна — 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. Темы и токены

  1. Tailwind v4: токены макета — CSS-переменные, подключённые в @theme. Бренд задаёт атрибут data-site="dedicated|mass" на <html>, тему — data-theme="light|dark". Режим «Как в системе» следует prefers-color-scheme.
  2. Переключатель темы — 3 режима, как в макете. Выбор хранится в localStorage (ключ vx_theme), тема применяется скриптом в <head> до отрисовки. Новый посетитель видит «Как в системе». localStorage у каждого хоста свой: тема, выбранная на сайте, не переходит в кабинет.
  3. Токены в 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. Шрифты, иконки, логотип

  1. Commissioner 300–600 — весь текст; Unbounded 600 — только надпись логотипа. Подключение через next/font: файлы скачиваются при сборке и отдаются с нашего домена, без запросов к Google Fonts. Наборы символов: latin, latin-ext, cyrillic.
  2. Иконки, флаги и логотип в макете нарисованы CSS-фигурами. Переносим их React-компонентами, сохраняя вид.
  3. Логотип — вариант «Слои». Фавиконы — favicon.svg и favicon-mass.svg из макета.

6. Карта мира

  1. В макете карта строится в браузере через d3 и topojson с загрузкой данных с CDN. В продукте SVG-карта рендерится на сервере при сборке: d3-geo, проекция Natural Earth, данные world-atlas (countries-110m) из npm.
  2. В браузере — только интерактив: подсветка, всплывающая карточка, синхронизация с сеткой локаций.
  3. На узком экране карта прокручивается горизонтально, как в макете.
  4. Глобус в hero главной (Main, MassMain) — ортографическая проекция, тоже рисуется на сервере, без интерактива.

7. Решения по расхождениям в макетах

  1. Устройств — 5, это поле тарифа. Цена продления dedicated — 2 499 ₽, цены задаются тарифами (3 уровня).
  2. Оформление заказа получает тариф, локацию и валюту из ссылки. В макете там всегда Нидерланды и 4 900 ₽.
  3. Поля номера карты из макета Order не делаем: карта вводится в виджете провайдера (этап 4b). В фазе 1 — демо-оплата (D-027).
  4. Mass: в кабинете «Список ключей», без «текущей/запасной локации» и без экрана смены страны. Внутри ключа — ссылка Xray и WG-конфиги по странам.
  5. Статус локации показываем везде одинаково: в списках, карточках и на карте.
  6. Кнопка «Получить VPN» на главной ведёт к блоку цен на этой же странице, на остальных страницах — на /pricing.
  7. FAQ — одна коллекция с местами показа: главная, цены, поддержка (3 раздела), кабинет, MiniApp.
  8. Контакты поддержки берутся из настроек сайта, Telegram — ссылка на бота поддержки.
  9. Плашки способов оплаты в подвале — по активным платёжным системам сайта.
  10. Добавляем то, чего нет в макете: переключатель валюты, <title> и мета-описания, H1 на каждой странице, поддержку prefers-reduced-motion для анимаций.
  11. Количество свободных серверов показываем рядом со статусом, если поле заполнено (D-032).
  12. Переключатели при 5 языках и с валютой (в макете только RU/EN, валюты нет). В шапке — выпадающие списки языка и валюты. В подвале, мобильном меню и кабинете — сегменты с кодами языков (EN RU DE FR ES) и символами валют (₽ $). В оболочке кабинета валюты нет: она появится в настройках (1f).
  13. В подвале четыре документа: добавлена «Политика cookies». Плашек способов оплаты нет, пока нет видимых пользователю платёжных систем (пункт 9).
  14. Кабинет mass: подписи навигации те же, что у dedicated («Список ключей», «Купить ключ», «Ключи»). Подписи макета MassApp («Подключения», «Выбрать страну», «Подписка») не используем (пункт 4).
  15. Ширина надписи логотипа — по содержимому: в макете она подогнана под русское название.
    1. При notFound() Next 16 отдаёт пустую оболочку (<html id="__next_error__">), а страница 404 в оформлении бренда отрисовывается в браузере; статус ответа — 404. Серверную отрисовку 404 и 500 решаем на этапе 1b вместе с их оформлением: вариант — global-not-found.js.
  16. Реферальная программа (1h): бонус — дни срока ключа, а не деньги (D-025). Текст под ссылкой «Месяц начисляется вам и другу… и применяется к ближайшему списанию» заменяем на условия в днях. В истории платежей строка «Реферальный бонус» показывает «+30 дней» вместо «+2 499 ₽». Счётчик «Месяцев начислено» и статусы приглашённых остаются.
  17. Тексты описывают работающий продукт, а не ограничения текущего этапа: «сразу после оплаты», оплата картой, автопродление, смена страны — как в макетах (D-026).
  18. Тексты страниц — в Payload, страницы собираются из блоков (D-029).
  19. Вейликс — «индивидуальный IP»: выделенный адрес на общем сервере. Формулировки «персональный сервер», «без соседей по серверу», «персональные VPN-серверы» не используем.
  20. ВейликсВПН: RU-адрес входит в ключ, но страной не считается (D-031); число стран — из данных, только «Включено»; протоколы — Xray и WireGuard.
  21. Поддержка: сроки ответа не обещаем, часы — «с 10 до 20 по московскому времени в рабочие дни». Telegram — @veilix_support у обоих брендов, пока нет ботов поддержки (этап 3e).

8. Состояния, которых нет в макетах

Рисуем в стиле макета на соответствующих этапах:

  1. Вход: ошибка кода, истёкший код, таймер повторной отправки, загрузка.
  2. Ключ: готовится (до 24 часов), льготный период, истёк, заблокирован; пустой список ключей; ключ без подключений.
  3. Заказ: «ожидает оплаты», не хватает баланса, оплата не прошла (этап 1e); 3-D Secure и счёт в криптовалюте — этап 4b.
  4. Счёт: своя сумма пополнения, подтверждение отвязки карты, результат пополнения.
  5. Общие: уведомления (тосты), скелетоны загрузки, страницы 404 и 500, ошибки валидации форм.

9. Производительность и доступность

  1. Маркетинговые страницы: Lighthouse mobile ≥ 90 (цель 95+), LCP ≤ 2 с, CLS ≤ 0.05, INP ≤ 200 мс.
  2. JavaScript в браузере — только интерактивные островки: переключатели языка, валюты и темы, FAQ, выбор локации, формы, карта.
  3. Сторонние скрипты при первой загрузке — только Umami (асинхронно). ALTCHA подгружается только на формах.
  4. Доступность — WCAG 2.1 AA: контраст, видимый фокус, работа с клавиатуры для выпадающих списков, аккордеонов и шитов, области нажатия ≥ 44 px.