# Комментарии · дизайн для согласования **DRAFT · 01.11.2026 · только дизайн. Owner approval: PENDING. UAT: NOT_TESTED.** Открыть `index.html` локально. Переключатели: игра / площадка / игрок, 15 состояний, viewport 390 / 1024 / 1440. «К комментариям» прокручивает внутри preview; «Вписать» меняет масштаб, сохраняя CSS viewport. Есть реальные локальные взаимодействия: набор, отправка с промежуточным состоянием, ответы, сортировка, раскрытие длинного текста, дополнительные ветки, редактирование, подтверждение удаления, Safety-диалоги. Данные живут только в памяти; выбор другого контекста или состояния начинает новый пример. Переключение ширины сохраняет текущий пример. ## Предложение Один спокойный блок «Комментарии» в основном потоке страницы. Белая поверхность на paper, обычная типографика, метаданные компактнее текста. Лаймовый акцент оставлен основному действию; purple — пояснениям и локальным состояниям. Нет отдельного социального feed, огромного героя профиля или новых Postgame-экранов. | Контекст | Место и окружение | |---|---| | GameDetailPage | После условий, доступных контактов площадки и существующего условного чата, в основной колонке `gb-game-detail-grid`. В галерее показаны сокращённые GameHero, contextual actions и условия. Чат не показан: активный `getGameChat` здесь не имитируется. | | VenuePage | После существующих VenueGallery / VenuePublicProfile / GamesMapView в `gb-venue-layout__main`. В галерее их контекст сокращён до схемы площадки и одной строки игры. Правая колонка остаётся вспомогательной. | | PublicPlayerProfilePage | В `PublicPlayerProfile`, после ближайших игр в `player-profile-body__main`. Один существующий профиль сверху, отдельная Safety-колонка справа. Не добавлять блок в универсальный PlayerProfileContent: он переиспользуется в других поверхностях. | Сокращённое окружение — ориентация для review, не новый дизайн всей страницы. В реализации сохраняются полные действующие hero, контакты, управление участием, карты и все существующие gates. При 390 вторичная колонка в галерее скрыта; это не инструкция скрывать реальные контакты или Safety в продукте — они сохраняют свой действующий мобильный flow. ## Компонент и поведение - Заголовок, количество доступных неудалённых записей, включая ответы; компактный select «Сначала старые / Сначала новые». Это предложенная семантика счётчика, не подтверждённый контракт. - Composer сразу над разговором. Аватар-заглушка, явная подпись поля, текст 16 px, кнопка неактивна для пустого ввода. Демолимит 1000 символов — параметр для согласования, не существующее ограничение backend. - Корневая запись: инициалы, имя, дата, текст, контекстное меню. Краткие сообщения не имеют лишней рамки. Длинный пример находится под «Показать ещё» и раскрывается целиком. - Один уровень ответов. Первый пример содержит рабочее «Показать ответы» и inline composer. Ответы внутри этой ветки не создают второй уровень. Остальные ветки демонстрируют текст и меню; их отдельные ответные ветки не моделируются. - Начальный набор: четыре корневые записи и один ответ; сначала видны две ветки. «Показать ещё · 2» догружает локальный остаток. Сортировка меняет порядок корней; ответы остаются при родителе. Курсор/стратегия backend не проектируются. - Редактируется собственная запись. Удаление требует отдельного подтверждения и показывает tombstone. Визуальное предложение — скрыть текст и сохранить место в разговоре; сроки, аудит, восстановление и права модератора не определены. - Ни лайков, ни рейтинга, ни репутации, ни свидетельств/верификации, ни обещания уведомлений. ## Состояния | Выбор в галерее | Что проверять | |---|---| | Небольшое обсуждение | Встроенный контекст, единая структура; ответы, меню, сортировка, load more. | | Пока нет комментариев | Приглашение начать разговор и обычный composer; отправка создаёт только первый комментарий. | | Без входа · чтение | Разговор читается в этом предложенном сценарии; composer заменён входом. Диалог — заглушка существующего auth flow, без ввода настоящих данных. | | Набор комментария | Заполненное поле и активная отправка. | | Отправка | Readonly draft, disabled submit, `aria-busy`. Выбранный сценарий зафиксирован; обычная интерактивная отправка завершается через 850 ms только в памяти. | | Успешная отправка | Добавленная запись и явный demo status. | | Ошибка чтения | Нет ложного нуля/пустоты; локальное «Попробовать снова». | | Отправка не подтверждена | Текст сохраняется в текущей вкладке, submit заблокирован. «Проверить результат» демонстрирует всё ещё неизвестный результат, без повторной записи. | | Редактирование своего | Inline edit, сохранить/отмена. | | Подтверждение удаления | Scoped диалог, безопасный начальный фокус на отмене, X44. | | Комментарий удалён | Текст и действия удалённой записи скрыты; место сохранено. | | Ответ в ветке | Один раскрытый уровень и отдельное поле ответа. | | Жалоба / блокировка | Минимальная оболочка существующего Safety: действия на игрока. Завершение не заявляет реальную отправку. | | Комментарии отключены | Нет composer, текста и количества; причина без догадок об инициаторе отключения. | | Нет доступа | Нет текста, количества или возможности обойти gate. | Все состояния доступны в каждом контексте. Это варианты композиции, **не утверждение**, что все комбинации разрешены в действующем продукте. Право читать, писать, отвечать, редактировать, удалять и видеть количество должен подтверждать сервер. Кнопки не устанавливают права. ## Решения, которые нужны Owner до реализации 1. **Профиль игрока:** предлагать ли вообще комментарии, кому они видны и кто пишет? Возможность владельца разрешать/отключать обсуждение, скрывать чужие записи или ограничивать аудиторию **не утверждена**. Галерея явно помечает этот контекст как предложение и содержит disabled/restricted варианты; переключателя «включить всем» в продуктовой части нет. 2. **Игра и площадка:** аудитория чтения/записи, доступ гостя и участников; связь с доступностью самой сущности. Guest-read показан как вариант, не default. 3. **Модерация:** кто может удалять/скрывать записи, что остаётся при удалении родителя, редактирование после ответа, восстановление, влияние блокировки на видимость. Наличие Safety для игрока не даёт автоматически этих полномочий организатору, владельцу площадки или профиля. 4. **Параметры:** лимит текста, начальный порядок, смысл счётчика и размер порции. В макете — 1000 символов, старые сначала, count с ответами, две видимые ветки. Принятие визуального макета само по себе не утверждает эти правила. Общесайтовая приватность аккаунта, контакты, настройки уведомлений и сроки хранения не выводятся из этого дизайна. ## Приватность и граница Postgame Комментарии — отдельный предлагаемый разговор об одной сущности. Они не являются приватной обратной связью после игры, отзывом/оценкой организации, личной заметкой или приватным чатом. Нет импорта, автопубликации или CTA «сделать отзыв публичным». Никакие Postgame permissions и данные не переиспользуются как разрешение на комментарии. В макете нет настоящих людей, фотографий, контактов, личных идентификаторов, адресов или результатов участия. Даты внутри сообщений — вымышленные образцы, не даты релиза. Только локальный Onest, существующий логотип и простая SVG-схема. CSP запрещает сетевые подключения; HTML открывается автономно. ## Узкий handoff в исходники Проверенный source HEAD: `2e668d564dcbc47f47b0896b09b6f45bcaf0ca57` в `/home/agentagency-dev/owner-swipe438-empty-20261101`. Источник задания указывает accepted `8733578`; полный ref локально: `8733578a2f8a6cfd860371e8a2c2aa39f1b885bb`. `git diff --name-only 8733578 HEAD` содержит release-history и player-browse изменения, не перечисленные ниже страницы или найденные `apps/api/src/games/game-outcomes.{service,policy}.ts`. Runtime не исследовался. | Проверенный seam | Следующий ограниченный шаг после принятия политики | |---|---| | `apps/web/src/components/consumer/pages/GameDetailPage.tsx:130` | Один общий блок внутри основной колонки после существующих условий/контактов/условного чата. Сохранить `GameHero`, contextual recommendation/share и единственный `GameActionBar`. | | `apps/web/src/components/consumer/venues/VenuePage.tsx:38` | Один блок после `GamesMapView` в main, не в popup/sheet и не вместо карты. | | `apps/web/src/components/consumer/pages/PublicPlayerProfilePage.tsx:14` | Сохранить ConsumerShell и общий левый Back. Обёртка сама не владеет загруженным профилем/его разрешениями. | | `apps/web/src/components/consumer/players/PublicPlayerProfile.tsx:159` | Условное встраивание в `player-profile-body__main`, после ближайших игр, только для обычной страницы и принятого read gate. Не распространять автоматически на Radar/embedded. | | `ConsumerShell.tsx`, `Surfaces.tsx`, `players/ProfileComposition.tsx` | Переиспользовать shell, ContentContainer/SurfacePanel, SectionHeader, Avatar, AuthChooser/AuthEntry, ProfileDialog. Не переносить gallery shell/JS в приложение. | | `messages/ConversationSafety.tsx`, `messages/useSocialMutation.ts`, `messages/MessageComposition.tsx`, `lib/player-presentation.ts` | Reference существующих Safety, pending/UNKNOWN и reason labels. Не вызывать существующую player-report API как выдуманную comment-report API. | | `CloseButton.tsx`, `styles/desktop-overlays.css` | Существующие X44 и «Просторный40». Production dialog сохраняет history, Escape/backdrop, focus и busy guards текущего host. | Пути в последних четырёх строках относительны `apps/web/src/components/consumer/`, кроме `lib/player-presentation.ts` и `styles/desktop-overlays.css`, которые относительны `apps/web/src/`. Вероятный новый presentational seam — `consumer/comments/CommentsSection.tsx` с локальными CommentItem/Composer, если равнозначного компонента не появится к моменту реализации. **Этого файла сейчас нет.** Один внешний компонент на три entity-context; controller/contracts определяются принятой Issue. Не нужны новый framework, модальная система, API-платформа или scheduler. Поиск по трём host-страницам, `apps/web/src/lib`, `packages/contracts/src`, `apps/api/src` не подтвердил общего comments feature/контракта. Это ограниченная проверка seams, не аудит всего репозитория. Нельзя выводить «feature ready» из наличия макета, общих primitives или существующего player Safety. ## STYLE_GUIDE_PARITY и evidence Прочитаны действующие `SITEWIDE_UI_STYLE_GUIDE.md`, `DESKTOP_OVERLAY_STYLE_GUIDE.md`, scoped Style Guide First decision, локальные `ConstructionKit` и tokens в `/opt/gobadminton-clean-qa/style-guide/src/{App.tsx,index.css}`. Использованы SectionHeader / ContentContainer / SurfacePanel / ListRow, формы, notices, empty/error, native dialog как автономная демонстрация ProfileDialog. **STYLE_GUIDE_GAP:** составной comments block и одноуровневая ветка не подтверждены как существующее семейство. Ограниченное расширение из имеющихся primitives, без новых глобальных токенов. **OWNER_VISUAL_OVERRIDE:** не заявлен. Отдельный draft guide находится в `STYLE_GUIDE_COMMENTS.md`, действующие документы не менялись. Прочитан доступный Postgame `index.html` в соседнем evidence-каталоге: совпадают палитра, shell rail, Onest, радиусы и язык диалогов. Его `DESIGN.md` отсутствовал в момент чтения; работа от него не зависит. Ничего в соседний каталог не записывалось. Проверки: ненулевые файлы; Node syntax check обеих inline scripts; статическая проверка локальных assets, вариантов и responsive/CSP markers. Браузер/Playwright/Selenium не обнаружены, поэтому screenshot/layout/клавиатурный preview **NOT_RUN**. Это авторская проверка артефакта, не независимая QA, Product CI, DEV smoke или Owner UAT. Результаты и hashes — `coverage.json`. Исходники, Git, runtime, DB, PROD и документы действующего процесса не изменены. Публикация не выполнялась. Дизайн готов к рассмотрению; продуктовая реализация, приёмка и release не заявляются.