Этот документ — единственный источник правды по блоку #training-photos:
ассеты, лайтбокс, свёртка ленты. Открыть ПЕРЕД любой правкой галереи или
добавлением/заменой кадров. Секция-обёртка блока подчиняется правилам слоёв —
см. STACKING.md.
Блок #training-photos (src/components/TrainingPhotos.astro) — masonry-лента из 93 кадров во всю ширину экрана + лайтбокс #modal-gallery (ModalGallery.astro + src/scripts/gallery.ts, поверх общего setupModal).
Кадры сняты на разных программах Дениса, не только на ПРП. Заголовок, надзаголовок и alt-тексты обязаны оставаться нейтральными к теме конкретного тренинга — не привязывать блок к «Профессиональному решению проблем».
| Папка | Формат | Кто обрабатывает | Куда идёт |
|---|---|---|---|
src/assets/images/trainings/preview/ |
.jpg, 800px |
<Image /> → webp 320/480/800 |
сетка, loading="lazy" |
src/assets/images/trainings/full/ |
.webp, ≤1920px |
никто, отдаётся как есть | лайтбокс, грузится только по клику |
Имена файлов в обеих папках совпадают до расширения (denis-bulgin-trening-NNN) — компонент сопоставляет пары именно по ним и падает на сборке, если пара не найдена.
Astro эмитит в dist/ исходник каждого импортированного изображения, и для картинок, прогоняемых через getImage() (а не через <Image />), лишний оригинал из сборки не вычищается. На 93 фотографиях это давало 35 МБ мёртвого груза в dist/ — ни одной ссылки в HTML.
Поэтому кадры ужимаются заранее, один раз:
# 1. Положить исходники .jpg в src/assets/images/trainings/full/
# и превью с ТЕМИ ЖЕ именами — в .../preview/
npm run photos:prepareСкрипт переименовывает исходники в denis-bulgin-trening-NNN.webp, ужимает до 1920px по длинной стороне (withoutEnlargement — мелкие кадры не растягиваются) и удаляет .jpg. Превью он не трогает: их всё равно перекодирует <Image />, а webp → webp — лишний цикл потерь.
Exclude: [(File) => File.includes('denis-bulgin-trening-')],Кадры галереи уже ужаты (full — скриптом, превью — самим Astro). Повторный проход @playform/compress с webp: { effort: 6 } по 372 файлам растягивал сборку с 11 с до 76 с и не давал выигрыша в весе.
.gallery-masonry[data-collapsed] режет ленту по max-height: 150vh. Скрывать «лишние» кадры через display: none нельзя: в колоночной раскладке раскрытие переливает элементы между колонками, и уже просмотренные фото прыгают на другие места.
Атрибут data-collapsed ставит синхронный is:inline-скрипт внутри компонента, а не разметка. Без JS кнопка «Показать ещё» не заработает — и клип оставил бы 60+ кадров недостижимыми.
Брейкпоинты column-count в global.css (2 / 3 / 4 / 5 / 6 на 0 / 30 / 40 / 64 / 96rem) и атрибут sizes у <Image> в TrainingPhotos.astro описывают одно и то же. Меняешь одно — правь второе, иначе браузер выберет не тот размер из srcset.