Компактное портфолио независимого веб-дизайнера: Astro, React, WebGL2 / Three.js / R3F, авторская геометрия, GLSL-проявление краски, GSAP. Четыре раздела и три концепта. Статический HTML остаётся доступен без JavaScript.
Требуется Node.js 24 LTS (минимум 22.12), npm.
npm ci
npm run dev
npm run build
npm startProduction-сервер слушает 0.0.0.0, использует PORT (по умолчанию 4321), поддерживает HEAD, MIME, ETag, Brotli/gzip, кеширование и настоящий 404. /health возвращает JSON. Сборка статическая, база данных и секреты не нужны. .env.example намеренно отсутствует.
src/config/content.ts — единственный конфиг названий, текстов, услуг и контактов. brand.contact.email и brand.contact.telegram пока пустые: владелец ещё не подтвердил контакт для SPRAYFORM. Когда один из них заполнен и сайт пересобран, кнопка ведёт на реальный адрес. До этого сайт честно сообщает, что контакт скоро появится, и ничего не отправляет.
PULSE, FORM, ORBIT помечены как концепты. Клиенты, результаты, награды, стаж и отзывы не выдуманы. Диалоги открываются с клавиатуры, закрываются Escape, удерживают и возвращают фокус, блокируют прокрутку фона. При отключённом JS ссылки ведут на самостоятельные страницы проектов.
Использованы предоставленные владельцем файлы 01–07. Соответствие, размеры, форматы и назначение: assets-manifest.json. Оригиналы остаются в Библиотеке владельца; оптимизированные изображения уже включены в public/assets и не требуют повторной подготовки.
Для регенерации размеров из исходников:
node scripts/prepare-assets.mjs /absolute/path/to/source-assets
node scripts/copy-fonts.mjs01 — эталон композиции и статичный fallback. Hero строится реальной геометрией, 01 не имитирует WebGL. 02 используется без тайлинга на каждой стене, глубина из её теней не восстанавливается. 03 — RGBA-декаль с собственным шейдером проявления. 04–06 — художественные обложки. 07 перерисован в чистый монохромный SVG, растровые артефакты не используются.
Golos Text (кириллица + латиница) и Space Grotesk размещены локально. SIL OFL и уведомления зависимостей: licenses/, THIRD_PARTY_NOTICES.md. GSAP имеет отдельную Standard No Charge License, не MIT. Платные плагины не используются.
Один canvas. Небольшой угол из двух стен и пола, мягко скруглённый подиум, объёмные ленты и кольцо. Геометрия: src/lib/sculpture.ts. Подсветка и поведение: src/components/Scene.tsx. Без удалённых HDRI, моделей, шрифтов или текстур.
frameloop="demand": кадры появляются при вступлении, движении указателя и скролле; в покое перерисовка останавливается. За экраном и в скрытой вкладке установлен never. DPR до 1.5 на мобильном, пониженное качество теней на слабых устройствах. Локальный горизонтальный жест ограничен примерно ±13°, pointercancel сбрасывает поворот; вертикальная прокрутка и pinch zoom остаются браузеру.
Reduced motion отключает сборку, проявление и движение камеры. Без WebGL или при ошибке контекста остаётся статичная композиция. Для ручной проверки fallback есть /?no-webgl.
npx playwright install chromium
npm run build
npm start
# В другом терминале:
npm testМожно задать TEST_URL и CHROMIUM_PATH. В данной среде проверка запускалась в Chromium 141 headless со SwiftShader, потому что CDN новых бинарников Chromium возвращал ошибочную HTML-страницу. Это эмуляция, не испытание на физическом iPhone. Отчёт: QA.md. Стабильные 60 fps на реальных устройствах не заявляются.
Имя нового отдельного проекта: sprayform-portfolio. Dockerfile и railway.json готовы. Runtime-образ содержит только Node, сервер и статическую сборку. Railway получает PORT автоматически. Никакие существующие проекты не менялись.
Опубликовано 3 октября 2026: https://sprayform-portfolio-production.up.railway.app/ Репозиторий, созданный владельцем: https://github.com/aodess/Test. Отдельный проект Railway: sprayform-portfolio. Production deployment успешно прошёл сборку и healthcheck; публичная страница и диалоги проверены в браузере.
Текущие решения и оценка графики для совместной работы: DECISIONS.md. Исходники, production-сборка и превью включены в передаваемый архив. Никаких ключей или токенов в проекте нет.