# Площадка без фотографии · addendum v2 07.11.2026 · Owner steering после DEV alpha.45. [Открыть прототип](index.html) · [10 PNG](screenshots.html) · [Manifest](design-manifest.json) ## Решение Для площадки с отсутствующим опубликованным медиа показывается готовая растровая иллюстрация из текущей библиотеки GoBadminton. Существующий `venueIllustrationUrl(venueId)` выбирает один из четырёх WebP через deterministic FNV-1a. Одна площадка получает одинаковый asset на странице, карте, в compact preview и picker. В кадре видна подпись «Иллюстрация». Alt — «Иллюстрация: бадминтон». Миниатюра использует тот же asset, а подпись располагается в строке площадки. Кадр сохраняет существующую геометрию и `object-fit: cover` с центральной композицией. Выбрана готовая библиотека `racket-v1.webp`, `hand-v1.webp`, `shuttles-v1.webp`, `pair-v1.webp`. Для фактической площадки BADMCLUB ГБУ «Дворец детского спорта» с ID `c64190f9-5c93-5ec5-ba02-75a5dea3cbe3` текущий helper выбирает `racket-v1.webp`. Все четыре варианта доступны в раскрываемом блоке библиотеки внутри прототипа. Эта редакция заменяет решение v1 о текстовом no-photo в обложке площадки согласно новому уточнению Owner. В готовом состоянии пользователь видит полноценную иллюстрацию. ## Переходы медиа | Условие | Представление | |---|---| | Опубликованного медиа нет, выбранный WebP ещё загружается | Статичный skeleton, `aria-busy=true`, «Загружаем иллюстрацию…» | | Default WebP декодирован | Растровая иллюстрация и видимая подпись «Иллюстрация» | | Default WebP не загрузился | «Не удалось загрузить иллюстрацию» и retry текущего asset | | Сервер разрешил реальное фото | Loading/ready/error действующей фотографии с её точным credit | | Сервер разрешил official illustration | Готовое изображение с точным `credit.kind=illustration` и подписью источника | | Известный URL фотографии завершился ошибкой | Ошибка фотографии и retry этого URL | Skeleton используется и во время загрузки иллюстрации. Ошибка опубликованного фото сохраняет явную семантику error. Default illustration относится к отсутствию разрешённого опубликованного медиа. Счётчик официальной галереи берётся из её items. Default asset служит обложкой состояния no-photo. ## Точный author scope | Файл / ветка DEV45 | Адресная доработка | |---|---| | `VenueCover.tsx`, `noMedia` | Выбрать fallback через текущий `venueIllustrationUrl(venueId)`, отследить pending/decoded/error для этого asset, показать raster + label | | `SelectedVenueCover.tsx`, `intendedSrc()` и `paint()` | В отсутствие uploaded URL выбрать illustration для venue ID. Текущий единственный image resource переносится между compact/info slots. Состояние отсутствия фото получает собственный pending/ready/error выбранного asset | | `VenueGallery.tsx`, `items.length === 0` | Обе ветки zero-items, включая `coverSlot`, выводят fallback resource. Текстовые overlays DEV45 заменяются готовым визуальным состоянием после decode | | `venue-illustration.ts` | Переиспользовать существующие FNV-1a helper, список четырёх URL и illustration alt | | `games.css`, `venue-gallery.css` | Использовать действующие размеры, skeleton и `data-fallback=illustration` для готового default asset. В compact/picker подпись доступна вне тесной миниатюры | Ключ идентичности учитывает площадку и intended source. При быстрой смене площадки предыдущий decode не должен перерисовать новую площадку. Cache hit отображает уже декодированный asset сразу. Повтор загрузки относится к нужному URL. У retry внутри picker отдельная доступная кнопка вне select-row. Принятые native-arrow guard и `draggable=false` входят в regression contract. Проверка касается mouse arrow, клавиатуры, image swipe, vertical sheet gesture, current image resource при morph, zero/one/multiple gallery и корректного credit. Стрелки следуют реальному набору gallery items. ## Фактическая база Anonymous GET `/v1/meta` подтвердил DEV45 SHA `2650fcbe21976564b8b1ff90aac67ea4eca5b569`, API 0.37.0. Сохранён [ответ metadata](inputs/dev-meta.json). Anonymous GET площадки подтвердил `cover.uploadedUrl=null`, `gallery.items=[]`. Сохранён [публичный ответ](inputs/venue-public.json). Браузерный снимок текущего DEV45 находится в [inputs/dev45-no-photo-390.png](inputs/dev45-no-photo-390.png). Read-only source inspection выполнен в `/home/agentagency-dev/owner-moderation506-public-text-20261107`. Assignment указывает snapshot de811 и соответствие product tree accepted SHA. Проверены три media-компонента, helper и scoped CSS. Per-file SHA256 указаны в manifest. ## Проверка дизайна Прототип показывает четыре затронутых контекста на 390 и 1280 CSS px, а также ожидание и ошибку illustration asset. Кнопка повторного показа вводит 1,2 секунды для визуальной демонстрации локальной загрузки. Browser evidence содержит проверки deterministic asset, видимой подписи, decode, статичного skeleton, стабильного размера кадра и retry. Это авторская проверка прототипа. Реализация, независимая QA и Owner UAT выполняются в продуктовом цикле. Старые #507 и loader v1 packs имеют отдельные manifest/checksum. Проверка их файлов записана в manifest v2. Для публикации подготовлен self-contained каталог по конвенции `projects/gobadminton/design/style-guide/venue-loader/20261107-astra-v2/`. Факт публикации фиксирует trusted publisher. Локальный просмотр — `python3 -m http.server 8509 --bind 127.0.0.1` из этой папки.