Files
SHiNE-server/docs/UI-Design/DESIGN.md
T
2026-09-22 14:09:02 +03:00

48 KiB

SHiNE — дизайн приложения

Версия 0.2 · 22 сентября 2026.

Статус: первый перенос списка каналов, ленты, ветки и общего редактора выполнен в рабочем дереве. Состав изменений, автоматические проверки и оставшаяся визуальная приёмка описаны в IMPLEMENTATION.md. Точные размеры и поведение на устройствах остаются целями приёмки, а не утверждением о выполненном тестировании на телефонах.

Этот файл — актуальный источник решений по дизайну. Галерея channels-v1 остаётся историей четырёх исходных вариантов: она ещё не показывает итоговое сочетание двух тем, компактной шапки и полноэкранного ответа. При расхождении руководствоваться этим документом.

1. Задача и границы

Сделать общение понятным с первого открытия. Начинаем со списка каналов, ленты канала, ветки обсуждения и мобильного редактора ответа. Затем распространяем выбранную систему на личные сообщения, связи, уведомления, профиль, поиск, создание каналов и настройки.

Основа — предоставленные пользователем скриншоты Threads и SHiNE. Заимствуем знакомые расположения и сценарии, сохраняя особенности продукта. Этот документ не утверждает новые возможности API и не меняет правила записи, реакции или блокчейна.

Исходные направления представлены в HTML-галерее. Выбрана одна система интерфейса с двумя темами: композиция Ночного SHiNE, ночная палитра из него же, дневная палитра из Тёплого SHiNE. Шапка канала компактная по образцу Компактного клуба; редактор ответа полноэкранный, как у Компактного клуба / Чистого монохрома.

Тема меняет цвета, но не геометрию, навигацию, типографику или порядок действий. Из Тёплого SHiNE берём палитру, а не карточную компоновку, увеличенные заголовки Georgia и редактор-лист.

2. Принципы для всего приложения

  1. Содержимое важнее оформления: текст без свечения, минимум декоративных рамок, спокойные поверхности.
  2. Один акцентный цвет обозначает активный раздел, главное действие и выбранное состояние.
  3. Главное действие доступно без прокрутки до конца. Его содержание зависит от роли и текущего экрана.
  4. Всегда видно, где пользователь находится и кому отвечает. Возврат сохраняет позицию списка или ленты.
  5. Редкие и технические действия помещаются в меню, но остаются доступными.
  6. Пустота, загрузка и ошибка — полноценные состояния. Ошибка не уничтожает введённый текст.
  7. Метки, иконки и расположение действий повторяются во всех разделах.
  8. Не выдавать отсутствующую функцию за существующую. В частности, не добавлять репост, GIF-поиск или сортировку по популярности только потому, что они есть в референсе.

3. Принятые решения

Решение пользователя Правило для реализации
Основа — Ночной SHiNE Плоская широкая лента, сдержанные поверхности, единые линейные иконки
Дневной и ночной режим сразу Оба режима обязательны для каждого переносимого компонента и состояния
Дневные цвета — из Тёплого Кремовые поверхности, тёмный тёплый текст, янтарно-коричневый акцент
Шапка сообщений — компактнее, как в Клубе Панель 56 px, без большого описания и декоративного баннера перед лентой
Ответ — как у Клуба / Монохрома Полноэкранный мобильный редактор, короткий контекст, основное место отдано вводу
Лайки — общее количество Один счётчик. Типы лайков и их статистика не входят в первый перенос
Статистика позднее, возможно долгим тапом Возможное будущее взаимодействие, не обязательство реализовать жест сейчас
Оглавление используется редко Только в меню канала, без отдельной кнопки в шапке или под описанием
Плотность мокапов подходит Сохраняем ритм Ночного SHiNE; уплотняем шапку, не всю ленту до варианта Клуба

Эти решения приняты 22.09.2026 в обсуждении с пользователем. Повторно выбирать направление не требуется.

4. Базовые параметры

Ниже единые размеры для обеих тем. Референс плотности — Ночной SHiNE. Не переносить мелкие служебные подписи галереи буквально: текст остаётся читаемым на телефоне. Размеры задавать через общие токены с поддержкой системного увеличения шрифта; фиксированные высоты ниже являются минимальными, если тексту требуется больше места.

Параметр Целевое значение
Основной текст публикации / ответа 15 px / 23 px; редактор ввода 16 px / 24 px
Имя автора 14 px / 20 px, вес 600
Вторичная информация 12 px / 18 px
Заголовок корневого экрана 24 px / 30 px, вес 600
Название канала в компактной панели 17 px / 22 px, вес 600
Заголовок обычной модальной панели / редактора 16 px / 24 px, вес 600
Шкала отступов 4 / 8 / 12 / 16 / 24 / 32 px
Горизонтальные поля телефона 16 px; между аватаром и текстом 10–12 px
Вертикальный ритм Публикация: 16 px сверху, 8 px снизу; абзацы: 8–12 px; строка канала: 14 px сверху и снизу
Аватар 36 px в ленте; 48 px в списке; 32 px у ответа; 40 px в редакторе
Область нажатия Не менее 44 × 44 px для всех действий, включая меню, закрытие, лайки и вкладки
Иконки Единая линейная система, 20–24 px, одинаковая толщина штриха
Скругления Поле/файл/кнопка 12 px; медиа 14 px; меню-лист 20 px; полноэкранный ответ без скругления внешнего края
Контраст текста Цель WCAG AA; проверить утверждённую палитру
Анимация 150–200 мс, отключение при reduced motion

4.1. Семантические цвета двух тем

Использовать роли, а не прямые цвета внутри страниц. Имена ниже описывают контракт дизайна; при реализации сопоставить их существующей системе переменных, не создавать параллельную систему токенов. Основная палитра взята из выбранных мокапов; статусные цвета — дополнение спецификации.

Роль Ночь День Где используется
background #101B20 #FAF7F0 Основной фон, шапка и навигация
surface #17272D #FFFDF8 Поле поиска, меню, карточка файла
surface-selected #213B3A #EFE6D6 Выбранная вкладка, лёгкое выделение
text-primary #E8F2F1 #302C25 Основной текст
text-secondary #98ADAF #706658 Время, авторские идентификаторы, подсказки
border-subtle #2A3B40 #E6DFD1 Декоративное разделение строк
border-control #71888A #978B79 Граница поля, если нужна для распознавания контроля
accent #94E1CE #93511E Главное действие, ссылки, активная навигация
on-accent #102C27 #FFFAF3 Текст на залитой акцентом кнопке
focus-ring #94E1CE #93511E Контур клавиатурного фокуса
reaction-active #F29AAB #A43350 Сердце выбранного лайка, не системная ошибка
danger #FFABA8 #B13135 Ошибка, подтверждение удаления
success #94E1CE #346A48 Успешное действие, с текстовым пояснением
warning #E6C184 #845B14 Предупреждение, с текстовым пояснением
scrim #00000099 #302C2566 Затемнение под меню/диалогом

Шрифт системный sans-serif в обеих темах: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif. Georgia из тёплого концепта не переносить. Не использовать свечение текста и цветные тени кнопок. Допустима лёгкая тень у всплывающего меню, но не у каждой публикации.

Небольшая коррекция исходной дневной палитры: вторичный текст затемнён с #7B7264 до #706658. Расчёт контраста исходного цвета на основном фоне дал 4.43:1, на выбранной поверхности — 3.83:1. Новый цвет даёт соответственно 5.26:1 и 4.55:1, сохраняя тёплый характер. Это уточнение для читаемости, а не смена выбранной палитры.

border-subtle не служит единственным указателем поля или выбранного состояния. Контраст проверять для конкретных пар: обычный текст ≥ 4.5:1; значимые иконки/границы и фокус ≥ 3:1. Не снижать контраст вторичного текста общей прозрачностью контейнера. Disabled обозначать одновременно неактивностью и стилем; ожидаемое действие пояснять при необходимости.

4.2. Выбор темы

Рабочее решение для реализации: настройка «Оформление» с пунктами «Как на устройстве», «Дневное», «Ночное». По умолчанию — как на устройстве. Явный выбор сохраняется локально и имеет приоритет; изменение системной темы применяется только в режиме «Как на устройстве». Это проектное допущение, пользователь отдельно не выбирал способ переключения.

Обновление темы не перезагружает экран, не закрывает редактор и не сбрасывает черновик или прокрутку. Выбранный режим применяется до первой видимой отрисовки, без вспышки противоположного фона. Все модальные окна, меню, системные поля и состояния используют ту же тему. Фотографии и аватары не инвертируются. Не нужна постоянная кнопка солнца/луны в тесной шапке канала.

5. Список каналов

Верх: заголовок «Каналы», видимая кнопка создания, поиск. Фильтры «Все», «Подписки», «Мои» вынесены из выпадающего заголовка на поверхность.

Строка: аватар, название, автор/идентификатор при необходимости, однострочное превью, время, число непрочитанных. Длинное название сокращается в строке, полное доступно внутри канала. На карточке не нужно одновременно показывать описание, технический путь, общее число сообщений и длинное превью.

Поиск в прототипе фильтрует примеры по названию и автору. В текущем приложении серверный поиск начинается с логина/начала логина автора: полноценный глобальный поиск по названию здесь является предложением, а не обещанием текущего API. При реализации можно сохранить существующую семантику с подсказкой «Найти по @автору».

Нижняя навигация сохраняет пять существующих разделов: «Личные», «Каналы», «Связи», «Уведомления», «Профиль». Иконки приводятся к одной системе. Высота рабочей зоны 64 px плюс нижний safe area; иконка 22 px, подпись 11 px. Активный пункт отмечается акцентом и мягкой подложкой под иконкой. При крупном системном шрифте панель может увеличивать высоту; нельзя уменьшать шрифт, скрывать смысловые подписи или обрезать «Уведомления» ради фиксированной высоты.

Не выделять первую строку автоматически только потому, что она первая. Непрочитанное отмечается счётчиком и более заметным превью, выбранное — фактическим состоянием выбора. Просмотр канала и подписка — разные действия; открытие строки не подписывает пользователя автоматически.

6. Канал и сообщения

6.1. Компактная шапка

Верхняя панель высотой 56 px плюс верхний safe area: возврат 44 px, растягивающийся блок названия, уведомления 44 px, меню 44 px. Внутри блока — название 17/22 px и вторичная строка @автор 12/16 px. Название в одну строку с многоточием; полное название, идентификатор и описание доступны в «О канале». На очень узком экране и при крупном шрифте уведомления переносятся в меню, чтобы сохранить место названию. Название канала открывает информацию о канале.

Под панелью сразу начинается лента. Убрать большой блок описания, декоративный градиентный баннер и постоянно видимый статус «Вы подписаны». Описание и управление подпиской — в меню/информации о канале. Для неподписанного читателя допустима компактная строка «Подписаться» над лентой; после подписки она исчезает. Метка «Новые сообщения» занимает одну строку и появляется только при наличии непрочитанного.

Порядок меню канала: «О канале», «Оглавление», настройка уведомлений, действие подписки/отписки, затем доступные владельцу действия. Пункты показываются по реальным правам. Оглавление не дублируется в шапке, под описанием или в строке действий публикации. При пустом оглавлении показать «В этом канале пока нет оглавления»; создание доступно владельцу только через существующий сценарий.

6.2. Публикация

Публикация: автор, время, меню, текст, вложение и действия. Порядок действий — лайк, открыть обсуждение, поделиться; явное «Ответить» открывает редактор. Это разделяет чтение ветки и написание ответа, сейчас они завязаны на разные области карточки.

У лайка сейчас только общий счётчик likesCount: не суммировать его повторно с подкатегориями. Один тап ставит/снимает лайк; выбранное состояние — заполненное сердце и reaction-active. Повторное действие во время запроса блокируется, при ошибке состояние и число восстанавливаются с коротким пояснением. Нулевой счётчик можно показывать как 0, одинаково во всех разделах. У кнопки есть доступное название и состояние, например «Нравится, 24» и aria-pressed.

Статистику типов не показывать ни на панели, ни в меню первого переноса. Долгий тап по лайкам — отложенная идея пользователя; порог жеста, содержимое и доступную альтернативу согласовать позднее. Если жест появится, ему понадобится явный пункт меню для клавиатуры и пользователей, которые не знают о долгом тапе. Сейчас не добавлять неработающую подсказку или заглушку для этого жеста.

«Данные блокчейна», доступная история, редактирование и удаление помещаются в меню. Редактирование и удаление доступны только для собственных сообщений; удаление требует понятного подтверждения с описанием реального эффекта существующего протокола. Отдельные оценки не возвращаются на панель действий: в коде они намеренно скрыты.

Кнопка публикации закреплена снизу у владельца. У читателя в ленте нет поля, которое обещало бы писать непосредственно в чужой канал. Ответ доступен под публикацией, а на экране ветки — также в нижнем поле. Для неподписанного пользователя нужна заметная подписка, для гостя — корректное приглашение войти перед действием.

Вложения: компактная карточка файла с названием, типом и размером; изображения — в ширину текста с ограничением высоты. У галереи нужен индикатор количества. Реальные превью, загрузка и ошибки файлов проектируются отдельно; изображение в мокапе — встроенная SVG-иллюстрация без внешних ресурсов.

7. Ветка обсуждения

Исходное сообщение остаётся наверху, ниже — счётчик и ответы в последовательном порядке. Не предлагать «Популярные» до подтверждения алгоритма и источника данных.

Для вложенных ответов показывать «В ответ …» и короткий контекст. Не уменьшать ширину текстовой колонки бесконечными отступами: после одного уровня показывать связь подписью или открывать подветку, используя имеющуюся маршрутизацию. Тонкая линия допустима только для обозначения реальной связи, не вокруг каждого комментария. Плотность ответов сохраняется близкой к Ночному SHiNE; выбор полноэкранного редактора из Клуба не означает переноса всей его плотности.

Возврат ведёт в тот же канал и на прежнюю позицию. После отправки новый ответ появляется в ветке; при ошибке остаются текст и вложения. Длинные ветки потребуют отдельной проверки пагинации, состояния загрузки и перехода к конкретному ответу.

8. Мобильный редактор ответа

Полноэкранный мобильный редактор в обеих темах — принятое решение. Он закрывает нижнюю навигацию и занимает доступную область приложения; не является маленькой центральной модалкой или частично открытым листом. Нет ручки перетаскивания, переключателя разворачивания и декоративного верхнего отступа.

Верхняя панель 56 px: закрытие 44 px слева, заголовок «Ответ» по центру; место справа не заполнять лишними действиями. Ниже — короткий контекст исходного сообщения, собственный аватар, поле и вложения. Нижняя панель: «Прикрепить», счётчик и кнопка «Ответить». Для нового сообщения тот же редактор с заголовком «Новое сообщение» и кнопкой «Опубликовать», без цитаты.

При первом открытии показать адресата и цитату максимум в две строки плюс «Показать целиком» при обрезке. Не повторять весь исходный пост с изображением в редакторе. Для ответа на файл без текста показать название/тип вложения. Раскрытая цитата находится в прокручиваемой области и не вытесняет навсегда поле. Адресат берётся из выбранного сообщения, а не всегда из автора канала.

Поле ввода занимает всё оставшееся свободное место, растёт вместе с текстом в общей прокручиваемой области. Шапка и нижняя панель остаются видимыми. При открытии по нажатию фокус переходит в поле; курсор при восстановлении черновика остаётся в тексте. Системная клавиатура не должна перекрывать отправку: учитывать visual viewport, поворот устройства и безопасные отступы. Не рисовать свою клавиатуру в приложении — иллюстрация есть только в галерее.

Крестик, системный возврат и Escape закрывают редактор с одинаковой политикой черновика. Возврат восстанавливает место в обсуждении и фокус инициирующей кнопки. На desktop редактор может быть центрированной панелью шириной до 640 px и высотой до доступного viewport с теми же тремя зонами; на телефоне всегда полный экран.

Enter создаёт новую строку. Отправка — по явной кнопке; Ctrl/Cmd+Enter можно поддержать как дополнительное desktop-действие с подсказкой. Не отправлять во время IME/composition. В текущем редакторе есть обработчик plain Enter, поэтому это намеренное изменение поведения, которое нужно отдельно учитывать при переносе.

Состояния отправки:

  • Пустой текст без вложений: кнопка неактивна.
  • Есть текст или вложение: отправка доступна; лимит текста 2000 символов сохранён из текущего редактора ответа.
  • Загрузка вложения: прогресс, возможность отмены, запрет отправлять незавершённое вложение.
  • Отправка: индикатор, блокировка повторного нажатия.
  • Ошибка: понятная причина, повтор, сохранённый текст.
  • Успех: новый ответ и восстановленный контекст обсуждения.
  • Закрытие: черновик остаётся; очистка по отдельному явному действию, не по Escape.

В исходной HTML-галерее воспроизведены пустое/заполненное поле, лимит, выбранное вложение, закрытие с черновиком и локальная успешная отправка. Загрузка/ошибка сети и прогресс — требования будущей реализации. Счётчик 2000 относится к ответу согласно просмотренному коду; лимиты публикаций и вложений брать из соответствующих существующих валидаторов, не вводить общий лимит для всех сообщений только по этому документу.

Черновик в приложении изолировать ключом «аккаунт + канал + идентификатор исходного сообщения + режим редактора». Никогда не переносить текст ответа на другой пост молча. В первом переносе достаточно сохранения при закрытии/возврате в рамках текущей сессии интерфейса. Переживание перезагрузки/закрытия приложения не обещать, пока не выбраны хранение и политика очистки. При выходе из аккаунта его черновики не показываются другому пользователю.

9. Что подтверждено кодом

Возможность Где прочитано Решение макета
Все / свои / подписки; поиск; создание shine-UI/js/pages/channels-list.js, render, openChannelFinderModal Показать поиск и фильтры явно
Непрочитанные, превью, автор и время Там же, построение строк списка Сохранить иерархию без перегрузки
Публикация владельцем shine-UI/js/pages/channel-view.js, ветка isOwnChannel Закреплённое действие только для роли владельца
Подписка и оглавление channel-view.js Сделать доступными в информации о канале
Лайки трёх категорий, ответ, отправка ссылки channel-view.js, построение действий сообщения Только общий счётчик; детализация отложена; ветка отдельно от ответа
Технические данные и редактирование channel-view.js Перенести в меню, учитывать авторство
Оценки временно скрыты Комментарий возле действий сообщения в channel-view.js Не возвращать без решения продукта
Ответы и вложения; 2000 символов openReplyModal в channel-view.js и channel-thread-view.js Мобильный редактор с контекстом

Просмотр кода был целевым, не полным аудитом. Права всех типов каналов, статусы пользователей, истории, специальные подтипы и поведение гостя нужно проверить перед реализацией. Переключатель роли в галерее предназначен для оценки размещения действий, не моделирует авторизацию.

10. Состояния для следующей итерации

Область Нужные дополнительные макеты
Список Пустые подписки; первый запуск; загрузка; ошибка; нет результатов
Канал Гость; неподписанный; владелец; пустой канал; недоступный канал; очень длинное название
Сообщение Длинный текст; несколько изображений; файл без текста; удалённое; изменённое; специальный подтип
Ветка Нет ответов; много ответов; вложенная ветка; переход по ссылке
Ответ Длинная цитата; ошибка отправки; загрузка файла; черновик; клавиатура; возврат фокуса
Доступность Клавиатура; screen reader; крупный шрифт; контраст; reduced motion

11. Общие компоненты для единообразия

Компонент Единое правило
TopBar Общие высота, поля, возврат и меню. Большой заголовок только у корневого экрана, компактный у вложенного
Primary button Заливка accent, текст on-accent, высота 44 px, радиус 12 px; одно главное действие в области
Secondary button Поверхность/контур, без конкуренции с primary; тот же размер текста и зона нажатия
Icon button Иконка 22 px внутри зоны 44 px, доступное название; одинаковые pressed/focus/disabled
Field Метка по смыслу, текст 16 px, вспомогательная подпись и ошибка под полем; placeholder не заменяет метку
Search Небольшое поле с лупой; очистка видна при непустом запросе; отдельно загрузка, отсутствие результатов и ошибка
Tabs Одинаковый selected-стиль, минимум 44 px по высоте; не создавать страницу со своей системой вкладок
Avatar Круглый, устойчивый размер; fallback с инициалами; выбранная тема не перекрашивает фотографию
List row Аватар/иконка → основной и вторичный текст → время/счётчик; вся строка открывает объект
Overflow menu Те же отступы и строки 44 px; на телефоне допустим общий лист, на desktop привязка к кнопке
Attachment Единая карточка имени/типа/размера, отдельные состояния загрузки и ошибки; медиа не растягивает страницу по ширине
Empty state Короткий заголовок, причина/следующий шаг, одно уместное действие; без большого декоративного баннера
Inline error Возле неудавшегося действия, понятный текст и повтор; технические подробности раскрываются отдельно
Toast Короткое подтверждение без перехвата фокуса; не единственный способ сообщить о блокирующей ошибке
Confirmation Называет действие и объект; основной акцент для обычного действия, danger для удаления
Fullscreen editor Один визуальный контракт публикации/ответа/редактирования с вариантами заголовка и контекста

Каждый компонент определяет normal, hover для указателя, pressed, focus-visible, disabled, loading и error, если они применимы. Selected и pressed различать: selected сохраняется после нажатия, pressed — краткий отклик. Выбор и ошибку не кодировать только цветом.

Для клавиатуры соблюдать логичный порядок фокуса; у диалогов — семантика dialog, фокус внутри и возврат инициатору. Screen reader получает названия и состояния переключателей, общий счётчик лайков и информацию об отправке. Обновление ленты не должно каждый раз перехватывать фокус или зачитывать весь экран.

11.1. Общая адаптация

Телефоны 320–430 CSS px: одна колонка, боковые поля 16 px, никакого горизонтального скролла страницы. Горизонтальная прокрутка допустима только внутри явно обозначенной галереи вложений. Длинные слова/ссылки переносятся; имена и заголовки сокращаются только там, где предусмотрен доступ к полному тексту.

При ширине 600 px и выше текстовая колонка не шире 640 px, центрируется; верхняя панель, лента и composer выровнены по её краям. Desktop-навигация использует существующий shell. Новую многоколоночную архитектуру приложения этот документ не требует.

Safe area учитывается ровно один раз владельцем оболочки. При открытом редакторе нет двойной нижней панели. При увеличении текста до 200% допускается рост высот; кнопки не накладываются, действия не исчезают. Анимация открытия 150–200 мс; при reduced motion переход без движения.

11.2. Применение к остальным разделам

Раздел Что наследует Что требует отдельного проектирования
Личные сообщения Палитры, текст, аватары, строки списка, вложения, поля и меню Геометрия диалога, входящие/исходящие, статусы доставки/прочтения, звонки
Связи Строки людей, профильные аватары, кнопки, пустые состояния Запросы, типы отношений и правила доступности
Уведомления Строки, типографика, счётчики, непрочитанное Группировка, переход к объекту, состояния удалённого объекта
Профиль TopBar, разделители, поля, кнопки и обе темы Состав профиля, редактирование, настройки оформления
Вход/регистрация Цвета, поля, ошибки и focus-стили Чувствительные сценарии, последовательность шагов, тексты восстановления
Создание/настройка канала Общие формы, редакторы, меню и подтверждения Права, типы канала и специфические настройки

Наследование визуальной системы не означает изменения протоколов или применения ленты каналов к личному диалогу. Каждый следующий раздел добавляет свои сценарии в отдельный документ со ссылкой на эту основу, а не копирует собственные палитры и наборы кнопок.

12. Допущения и отложенные решения

Блокирующих вопросов для документа нет. Рабочие решения: тема по системе с ручным выбором, размеры из раздела 4, сохранение черновика внутри текущей сессии, единый редактор с адаптацией для desktop.

До переноса проверить по коду матрицу прав всех типов каналов, доступность ответа для гостя/неподписанного, ограничения вложений и существующие переменные темы. Если для предложения нужны новые серверные данные, явно отметить зависимость и сохранить доступный сценарий; не расширять API автоматически.

Позднее: статистика типов лайков и долгий тап; глобальный поиск по названию; постоянные черновики; подробные сценарии остальных разделов. Эти пункты не являются задачами текущего переноса.

13. Перенос в приложение и критерии готовности

На следующем этапе использовать существующие AppShell/TopBar/Dropdown/Avatar/Composer. Не копировать автономный JS из мокапа в production: он работает на демонстрационных данных и не реализует lifecycle приложения.

Последовательность: сопоставить текущие токены и владельцев компонентов → подготовить обе палитры → реализовать общие варианты компонентов → перенести список/канал/ветку/ответ → закрыть состояния из раздела 10 → проверить устройства и темы → расширять на другие разделы по отдельным задачам. Перед реализацией удобно обновить автономный мокап выбранного сочетания; исходную галерею сохранять как историю выбора.

Матрица приёмки для первого переноса:

Проверка Ожидаемый результат
День ↔ ночь на каждом экране Геометрия совпадает; нет чужих тёмных/светлых элементов и вспышки при старте
Переключение темы с открытым ответом Текст, вложения, адресат, фокус и позиция не сбрасываются
Шапка канала Компактная; нет баннера описания и кнопки оглавления вне меню
Роль читателя/владельца/гостя Только доступные действия; нет ложного обещания писать в чужой канал
Лайки Один общий счётчик; постановка/снятие; защита от повторного запроса; восстановление после ошибки
Оглавление Доступно через меню, включая пустое состояние
Ответ на пост и ответ на комментарий Верный адресат и цитата; полноэкранный редактор; отправка видна над клавиатурой
Длинный ответ и Enter Перенос строки без отправки; поле и курсор доступны при прокрутке
Черновик Закрытие/возврат сохраняет текст в текущей сессии; другой адресат не получает чужой текст
Вложения Текст или вложение; прогресс/ошибка; отправка незавершённого файла недоступна
Навигация Возврат сохраняет позицию; отправленный ответ виден; обновление не пересоздаёт страницу целиком
Загрузка/ошибка/пустота Понятные отдельные состояния; введённые данные не теряются
320 / 390 / 430 px, большой экран, 200% текст Нет наложений и горизонтальной прокрутки страницы; все действия достижимы
Android / iOS, экранная клавиатура, поворот Поле и отправка доступны; safe area не дублируется
Клавиатура / screen reader / reduced motion Фокус видим и возвращается; семантика доступна; движение отключается

Все четыре экрана проверяются в обеих темах, включая меню, редактор, ошибку и пустое состояние. Тесты поведения не заменяют визуальную проверку на телефоне.

Документ служит общим справочником приложения. Новые разделы описывают сценарии, владельцев компонентов, состояния и принятые решения, сохраняя принципы разделов 2, 4 и 11. Обнаруженные при реализации ограничения записывать как явные отклонения с причиной, а не незаметно создавать новый стиль страницы.

14. Журнал решений

Дата Версия Решение
22.09.2026 0.1 Четыре самостоятельных HTML-направления для обсуждения
22.09.2026 0.2 Пользователь выбрал Ночной SHiNE, дневную тёплую палитру, компактную шапку, полноэкранный ответ; общее число лайков, оглавление в меню; плотность принята
22.09.2026 0.2 Специфицированы семантические цвета двух тем, общие компоненты, состояния, адаптация, правила расширения и матрица приёмки. Это документация будущего переноса, не выполненное изменение приложения