Этап 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>
This commit is contained in:
andreypr207andClaude Opus 5.5 committed 2026-10-22 04:53:15 +02:00
1 parent 515acfb69d
commit 20491d1ba4
134 files changed
+11232 -212

No files matched your search

+12 -3
View File
@@ -50,7 +50,7 @@
| `--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 |
| `--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 |
@@ -65,7 +65,7 @@
## 5. Шрифты, иконки, логотип
1. Commissioner 300–600 — весь текст; Unbounded 600 — только надпись логотипа. Подключение через `next/font`: файлы скачиваются при сборке и отдаются с нашего домена, без запросов к Google Fonts. Наборы символов: latin, latin-ext, cyrillic.
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` из макета.
@@ -93,13 +93,21 @@
13. В подвале четыре документа: добавлена «Политика cookies». Плашек способов оплаты нет, пока нет видимых пользователю платёжных систем (пункт 9).
14. Кабинет mass: подписи навигации те же, что у dedicated («Список ключей», «Купить ключ», «Ключи»). Подписи макета MassApp («Подключения», «Выбрать страну», «Подписка») не используем (пункт 4).
15. Ширина надписи логотипа — по содержимому: в макете она подогнана под русское название.
16. 404. При `notFound()` Next 16 отдаёт пустую оболочку (`<html id="__next_error__">`), а страница 404 в оформлении бренда отрисовывается в браузере; статус ответа — 404. Серверную отрисовку 404 и 500 решаем на этапе 1b вместе с их оформлением: вариант — `global-not-found.js`.
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](decisions/D-025-referral-days.md)). Текст под ссылкой «Месяц начисляется вам и другу… и применяется к ближайшему списанию» заменяем на условия в днях. В истории платежей строка «Реферальный бонус» показывает «+30 дней» вместо «+2 499 ₽». Счётчик «Месяцев начислено» и статусы приглашённых остаются.
18. Тексты описывают работающий продукт, а не ограничения текущего этапа: «сразу после оплаты», оплата картой, автопродление, смена страны — как в макетах ([D-026](decisions/D-026-stage-order.md)).
19. Тексты страниц — в Payload, страницы собираются из блоков ([D-029](decisions/D-029-pages-blocks.md)).
20. Вейликс — «индивидуальный IP»: выделенный адрес на общем сервере. Формулировки «персональный сервер», «без соседей по серверу», «персональные VPN-серверы» не используем.
21. ВейликсВПН: RU-адрес входит в ключ, но страной не считается ([D-031](decisions/D-031-mass-ru-address.md)); число стран — из данных, только «Включено»; протоколы — 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. Состояния, которых нет в макетах
@@ -117,3 +125,4 @@
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 с.