Files
andreypr207andClaude Opus 5.5 20491d1ba4 Этап 1b: сайт
- Страницы обоих брендов из блоков Payload (D-029): главная, цены,
  локации, поддержка, 4 юридические, 404 и 500. Коллекции pages
  (черновики и версии) и faq с местами показа, 12 типов блоков; поля
  sites — почта и Telegram поддержки, часы работы, SEO по умолчанию.
- Карта и глобус рисуются на сервере (d3-geo), контуры во внешнем
  SVG через <use>; выбор локации синхронизирован между картой и сеткой.
- Тексты сайта и юридические черновики на 5 языках: de, fr, es —
  перевод с глоссарием; seed создаёт страницы и FAQ, только если их
  нет, SEED_CONTENT=reset пересоздаёт.
- SEO: title и описания, canonical, hreflang с x-default,
  sitemap.xml и robots.txt на каждый домен, картинки для соцсетей.
- Статическая сборка и пересборка через revalidatePath из хуков
  Payload (D-030); /svc/internal/revalidate для проверки.
- 404 — статичная страница со статусом 404 через proxy; на сайте
  только опубликованные страницы.
- Производительность: Client Hints темы Payload только в админке,
  предзагрузка 2 файлов шрифтов вместо 6; Lighthouse mobile 97–99.
- Контраст --ink-3 по WCAG AA, радиокнопки вместо div role=button.
- Документация: итоги 1b, глоссарий de/fr/es, трактовки юридических
  черновиков подтверждены, переносимые вопросы — в этапах 3e–3h.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:53:15 +02:00

18 KiB
Raw Permalink 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 53% .025 296 66% .025 296 53% .025 204 69% .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 и cyrillic у Commissioner; остальные наборы (latin-ext с «₽») и Unbounded браузер скачивает по unicode-range, когда встречает их символы.
  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. Ширина надписи логотипа — по содержимому: в макете она подогнана под русское название.
  16. 404 и 500 (решено на этапе 1b): a. notFound() в Next 16 отдаёт пустую оболочку (<html id="__next_error__">) и рисует 404 в браузере: клиентская граница при серверной отрисовке не срабатывает. Поэтому proxy ведёт неизвестные адреса сайта на внутреннюю статичную страницу page-not-found со статусом 404 (NextResponse.rewrite с status, decide.ts). Она отрисована на сервере, в шапке и подвале бренда, на языке из адреса; b. notFound() остаётся для внутренних путей и удалённых в админке страниц — там 404 по-прежнему рисуется в браузере; c. 500: error.tsx сайта (шапка и подвал на месте, кнопка «Обновить страницу») и global-error.tsx на случай, когда не отрисовался корневой layout (бренд — по домену, язык — по префиксу адреса). Ошибки Next по устройству рисует в браузере.
  17. Реферальная программа (1h): бонус — дни срока ключа, а не деньги (D-025). Текст под ссылкой «Месяц начисляется вам и другу… и применяется к ближайшему списанию» заменяем на условия в днях. В истории платежей строка «Реферальный бонус» показывает «+30 дней» вместо «+2 499 ₽». Счётчик «Месяцев начислено» и статусы приглашённых остаются.
  18. Тексты описывают работающий продукт, а не ограничения текущего этапа: «сразу после оплаты», оплата картой, автопродление, смена страны — как в макетах (D-026).
  19. Тексты страниц — в Payload, страницы собираются из блоков (D-029).
  20. Вейликс — «индивидуальный IP»: выделенный адрес на общем сервере. Формулировки «персональный сервер», «без соседей по серверу», «персональные VPN-серверы» не используем.
  21. ВейликсВПН: RU-адрес входит в ключ, но страной не считается (D-031); число стран — из данных, только «Включено»; протоколы — Xray и WireGuard.
  22. Поддержка: сроки ответа не обещаем, часы — «с 10 до 20 по московскому времени в рабочие дни». Telegram — @veilix_support у обоих брендов, пока нет ботов поддержки (этап 3e).
  23. Контраст: --ink-3 подобран до 4,5:1 (WCAG AA) на всех фонах темы, включая выделенные карточки; в макетах было 3,5–4,3:1 (таблица в разделе 4).
  24. Карта локаций: точки расположены как в макете, клик выбирает ближайшую точку (в Европе точки перекрываются); выбор синхронизирован с сеткой карточек и отмечен кольцом на карте; всплывающая карточка — HTML поверх карты, со статусом. Контуры стран и глобуса — внешний SVG /svc/geo/… с версией в адресе: в HTML они попали бы дважды (разметка и данные React).
  25. Межстрочный интервал в секциях страниц — normal, как в макетах (там он нигде не задан); у текстов с заданным интервалом — их значения. Шапка и подвал из 1a не менялись.
  26. Текущий раздел в шапке выделен цветом текста, как в макетах: CSS по атрибуту data-page страницы, без JavaScript.
  27. Под формами — строка о согласии с политикой конфиденциальности со ссылкой; формы до этапов 3d и 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.
  5. Заголовки Client Hints темы (Accept-CH, Critical-CH, Vary), которые withPayload ставит на все адреса, оставлены только админке (next.config.ts): на сайте Critical-CH заставлял Chrome повторять первый запрос страницы, Lighthouse оценивал это в 0,7 с.