# Стек и приёмы: как сделаны 30 работ

Документ для заказчиков и коллег: какие технологии, библиотеки и подходы использованы в портфолио.
Живая витрина: **https://kravtsovlabpro.ru/portfolio/**

Демо проектов: **https://kravtsovlabpro.ru/landings/**

## Базовый стек статических работ

| Слой | Что используется | Зачем |
|------|------------------|-------|
| Разметка | Семантический **HTML5** | Доступность (aria-атрибуты, роли, skip-логика), SEO |
| Стили | **CSS3** — custom properties, Grid/Flexbox, `clamp()` | Самостоятельная визуальная система для каждого проекта |
| Логика | **Vanilla JavaScript (ES2020+)** | Никаких React/jQuery — только платформа и точечные библиотеки |
| Сборка | Проекты 24–28: **Vite** production bundle; остальные — автономный HTML/CSS/JS | Локальные variable fonts и минимум внешних зависимостей |
| Шрифты | Google Fonts и self-hosted variable fonts | Характер задают Fraunces, Prata, Unbounded, Bodoni Moda, Bricolage Grotesque, Source Serif 4 и другие семьи |
| Изображения | **WebP** (конверсия из AI-генераций), lazy loading | Вес страниц в 2–4 раза меньше |
| Метаданные | OG/Twitter-теги + og-превью 1200×630 на каждый проект | Красивые карточки при шаринге в мессенджерах |

## Адаптивность и доступность

- Брейкпоинты 375 / 560 / 768 / 1024 px, мобильное бургер-меню на каждом проекте
- Тач-цели ≥ 44px, видимые фокус-состояния, контраст по WCAG
- **`prefers-reduced-motion`** уважается везде: анимации отключаются, контент показывается в финальном состоянии

## Анимационный стек (проекты 11–29)

| Инструмент | Где лежит | Что делает |
|-----------|-----------|------------|
| **GSAP 3.13** + **ScrollTrigger** | `vendor/` (self-hosted, без CDN) | Скролл-хореография: пиннинг секций, scrub-таймлайны, параллакс, счётчики |
| **SplitText** (бесплатен с 2025) | `vendor/` | Заголовки, разлетающиеся по буквам и словам (17, 18, 19) |
| **MorphSVGPlugin** | `vendor/` | Морфинг SVG-форм — «дышащий» блоб в проекте 18 |
| **Lenis** | `vendor/` | Плавный инерционный скролл («всё плывёт») |
| **Canvas 2D** | свой код | Волны и рябь (11), споры света (12), взрывы частиц (13), звёздное небо с высотной сменой палитры (19) |
| **WebGL-шейдеры** | свой код, ~120 строк GLSL на проект, **без Three.js** | 14 — «жидкий шёлк» (domain-warped fbm), 15 — рубиновая жидкость (ускоряется от скролла), 16 — световые полосы + перекраска сцены через uniform |

## Фирменные приёмы по проектам

- **11 AQUEA** — интерактивная рябь по клику, горизонтальный скролл-пиннинг «путь воды»
- **12 Гербарий** — SVG-лоза, которая растёт по мере скролла (stroke-dashoffset + scrub)
- **13 РАЗРЯД** — взрыв частиц в точке клика, тряска экрана, глитч-заголовок
- **14 VELOUR** — фон-шейдер закручивается вихрем вокруг курсора
- **15 Гранат №1** — жидкость «льётся» быстрее, когда пользователь скроллит быстрее
- **16 AXIOM** — курсор работает фарой; paint-shop меняет цвет всей WebGL-сцены
- **17 PULSE X** — скролл-история в стиле Apple: продукт «живёт» в закреплённой сцене из 4 глав
- **18 СДВИГ** — кастомный курсор, магнитные кнопки, превью работ следует за мышью
- **19 ОРБИТА** — скролл = набор высоты: живой альтиметр, небо темнеет, звёзды разгораются
- **20 STRIDE ONE** — скролл управляет последовательностью из 142 кадров как киноплёнкой
- **21 AEON** — Three.js-конфигуратор часов: вращение, зум, материалы и цена в реальном времени
- **22 MIRA** — Web Audio-анализатор управляет фоном, спектральным кольцом и частицами
- **23 Шахматный Штурм** — турнирная структура и регистрационная форма с валидацией
- **24 Asteria** — Timeline, маршрутная линия и параллакс превращают поездку в последовательную историю
- **25 Foldform** — GSAP Flip объясняет смену отделки, объект физически реагирует на курсор
- **26 Resonant** — Web Audio-превью, waveform, SplitText и горизонтальный ScrollTrigger-каталог
- **27 Canopy Civic** — sticky-stack визуализирует накопление городского леса по мере скролла
- **28 Afterlight** — clip-path раскрывает кадр как занавес, программа переносит сеанс в билетную форму
- **29 KILN** — sticky-stack процесс на ScrollTrigger, canvas-орбиты, bento-композиция и инженерная форма
- **30 SitePulse AI** — статический продуктовый кейс связан с рабочим Next.js-сервисом; URL-форма передаёт адрес в настоящий аудит, а кнопка отчёта открывает проверяемый результат

## SitePulse AI — рабочий продукт № 30

Портфолио показывает не только интерфейс, но и действующий сервис:

- **Next.js + TypeScript** — приложение, API, отчёты и проекты наблюдения;
- **PostgreSQL + worker queue** — хранение аудитов и фоновые задачи;
- **Playwright** — Chromium, WebKit и Firefox, девять ширин 320–1440 px;
- **Lighthouse × 5** — медиана и разброс вместо единственного случайного замера;
- **axe-core** — автоматические проверки доступности с узлами и селекторами;
- **SEO-краулер** — до 30 страниц: HTTP, title, description, H1, canonical и индексация;
- **MiniMax** — объясняет только уже подтверждённые измерениями проблемы;
- **PDF, JSON и CSV** — отчёт для владельца и структурированные данные для команды.

## Производительность

- WebGL: DPR ≤ 1.5, 4–5 октав шума, `powerPreference:'low-power'`
- Рендер-циклы останавливаются, когда сцена вне вьюпорта (IntersectionObserver)
- Только `transform`/`opacity` в анимациях — без перекладки лейаута
- Фолбэки: нет WebGL → CSS-градиент; нет JS → весь контент виден

## Контент и инструменты (`_tools/`)

- **Фотографии** — сгенерированы MiniMax `image-01` по детальным промптам (`gen_image.py`)
- **`split_assets.py`** — вынос inline CSS/JS в `css/style.css` + `js/main.js`
- **`optimize.py`** — JPG→WebP, генерация og.jpg, инъекция OG-метатегов
- **`screenshot.py`** — full-page скриншоты (desktop 1440 / mobile 390) через Playwright

## Хостинг

VPS с nginx. Путь `/var/www/landings-portfolio/` опубликован через `alias`: корневая витрина доступна по адресу `https://kravtsovlabpro.ru/portfolio/`, а отдельные демо — внутри `https://kravtsovlabpro.ru/landings/`.

Новые версии загружаются в `/var/www/landings-releases/<release>/`, проверяются и затем атомарно подключаются симлинком `/var/www/landings-portfolio`. Предыдущий release остаётся доступным для отката. `.git`, macOS metadata и внутренние инструменты в публичный каталог не попадают.

Критические зависимости новых проектов self-hosted, поэтому работы 24–29 не зависят от внешних JS CDN. Кейс № 30 остаётся доступным как статическая страница даже при недоступности рабочего API.
