# #600 · приёмка против референса > Запись закрытой задачи. Кадры `pairs/`, `screenshots/` и прототип `reference/`, > на которые она ссылается, удалены из дерева в #681 и лежат в истории git > (`git checkout f989fbfe -- docs/design/600-settings-dialogs`); новая съёмка > пишет в `artifacts/design-pairs-600/`. AC1 в #600 требует не «эталоны изменились», а **парное сравнение с референсом**: для каждого диалога кадр продукта рядом с кадром референса, и каждое расхождение названо со ссылкой на пункт `SPEC.md` или узел `reference/`. Этот документ — место, где такое сравнение живёт. Он пополняется по мере реализации, по одной таблице на диалог, и предъявляется на код-ревью вместе с кадрами. ## Как снимать парные кадры Кадры продукта — одной командой из корня репозитория, на собранном бандле: ``` npm run build && npm run bundle:sync node demo/capture_design_pairs_600.mjs # → artifacts/design-pairs-600/<диалог>-<тема>.png ``` Скрипт открывает четыре диалога в состояниях макетов (пространство с температурной заливкой и своим севером, общие настройки со статическим фоном, комната с эффективной температурной заливкой, привязанный светильник с ролью Always и фиксированным свечением), раскрывает скроллер на всю высоту и снимает поверхность 560 px в светлой и тёмной теме. Кадры референса — `screenshots/` из архива дизайнера (светлая тема, 1120 px при devicePixelRatio 2). Это **диагностические** кадры, а не golden-базы: они не принимаются `golden:accept` и не участвуют в `golden:verify`. Эталоны живут отдельно и закрываются AC10: принято **13 сцен** (`ed2af1b1`) — одиннадцать из ТЗ (список AC10 унаследован от #598, где диалог комнаты не менялся) плюс две `room-temperature-dialog-{desktop-en,mobile-ru}`, потому что диалог комнаты в скоупе #600. PNG пережаты в палитру 256 цветов — для сравнения раскладки этого достаточно, а вес папки остаётся в полумегабайте. ## #609: оболочка в настоящем Home Assistant Парные кадры выше были сняты в нативной ветке `hp-dialog`. Для #609 отдельно проверена ветка настоящего `ha-dialog` из закреплённого `home-assistant-frontend==20260729.7` (SHA-256 `ba01782297e9506d3185f99a74d829f3811df322623848af21bcc0b8ea834c12`): ```sh npm run bundle:sync node demo/verify_ha_form_shell_609.mjs --capture ``` Официальный компонент и его CSS не модифицируются; локальная фикстура не поднимает HA, не обращается к сети и падает при внешнем запросе, WebSocket или ошибке страницы. Измерения после завершения 200-миллисекундной анимации показа: | Режим | Поверхность | Проверенный результат | |---|---:|---| | desktop 1600×1000 | 560×940 | канва вокруг карточек, один скроллер `.body` HA, footer внутри | | dark + text 200%, 1600×1000 | 560×940 | root font 32 px, один HA-скроллер, footer внутри, канва не сливается с карточками | | граница 480×800 | 480×800 | fullscreen, радиус 0, горизонтального переполнения нет | | mobile 390×844 | 390×844 | fullscreen, радиус 0, footer внутри | | низкое окно 1280×480 | 1280×480 | штатный fullscreen HA сохранён | Снимки приёмки: `pairs/room-ha-light.png`, `pairs/room-ha-dark-text-200.png` и `pairs/room-ha-mobile-light.png`. Это диагностические доказательства, а не golden-базы; 13 нативных golden-сцен остаются неизменными. Быстрый обязательный свидетель тех же публичных CSS-контрактов — `demo/smoke_ha_form_shell_parity.mjs`, а перечень пяти потребителей оболочки закреплён в `test/form-shell-consumers.test.mjs`. ## Статус по диалогам | Диалог | Серия | Референс | Продукт (светлая / тёмная) | Расхождения названы | Готово | |---|---|---|---|---|---| | Space settings | 1 | `screenshots/space-settings-2026-09-18.png` | `pairs/space-light.png` / `pairs/space-dark.png` | ниже | да | | General settings | 2 | `screenshots/general-settings-2026-09-18.png` | `pairs/general-light.png` / `pairs/general-dark.png` | ниже | да | | Room settings | 3 | `screenshots/room-settings-2026-09-18.png` | `pairs/room-light.png` / `pairs/room-dark.png` | ниже | да | | Device on the plan | 4 | `screenshots/device-on-the-plan-2026-09-18.png` | `pairs/device-light.png` / `pairs/device-dark.png` | ниже | да | ## Расхождения с референсом, по диалогам Каждая строка — что видно на кадре продукта иначе, чем на кадре референса, со ссылкой на пункт `SPEC.md` или узел `reference/`, и чем это закрыто. ### Space settings (§4) | Что | Референс | Продукт | Основание | |---|---|---|---| | Образец карточки комнаты | убран (§4.2) | внутри карточки Room cards на тинте | решение владельца Q2 | | Поле цвета | `input[type=color]` (§3.2) | плашка вокруг `hp-color-opacity` | решение владельца Q5 | | Тексты подписей | Space name, Floor plan, Appearance, Room cards, Sun & light… | те же (переименования Q6) | §4.1, решение владельца Q6 | | Подписи сегмента заливки | Custom · Zigbee · Lights · Temperature | те же — короткие ключи `fill.seg_*` ленивого словаря, общие с комнатой (r1 M1: полные `fill.*` в RU переносились посреди слова) | §4.2 `reference/app.js` `fillOptions` | | Копия / удаление | Copy и Delete слева в футере | то же | §4.1 «Футер» | ### General settings (§5) | Что | Референс | Продукт | Основание | |---|---|---|---| | Zigbee links | один заголовок, тумблер, callout | то же: блок `hp-zigbee-topology-settings` в режиме `embedded` без своего заголовка | §5.1, дефект 1 из #600 | | Плитки цвета | 3 в ряд, hex, число прозрачности | то же; свотч — trigger прежнего пикера | Q5 | | Компас | 44 px справа от поля севера | то же, с сохранённым перетаскиванием стрелки | §3.1 «Компас»; прежний ввод с свидетелем `smoke_sun` | ### Room settings (§6) | Что | Референс | Продукт | Основание | |---|---|---|---| | Образец карточки | убран (§6.1 «Font sizes») | под подсказкой размеров, на тинте | решение владельца Q2 | | «?» у Basics | у поля Home Assistant area | у поля Home Assistant area (перенесён с заголовка карточки) | §6.1 | | Подписи сегмента заливки | None · Zigbee · Lights · Temperature · Custom, по одной строке на пункт | те же — короткие ключи `fill.seg_*` (общие с пространством). Ревью r1 M1: «Temperature» рвалось посреди слова в пяти равных колонках — колонка сегмента больше не сжимается ниже самого длинного слова, слова переносятся только по пробелам, не поместившийся сегмент переносится на вторую строку целыми кнопками; свидетель — `smoke_dialog_segments_i18n` (четыре диалога × en/ru/de/fr) | §6.1, §3.1 «Сегмент» | | Подписи источников | Temperature / Humidity | Temperature source / Humidity source (прежние ключи) | текст, не раскладка | | Поле цвета «Свой цвет» | `input[type=color]` | плашка вокруг `hp-color-opacity` | Q5 | | Кнопка выбора датчика | в потоке, панель с поиском | то же (`sourcePicker` набора) | §3.1 «Кнопка выбора источника» | ### Device on the plan (§7) | Что | Референс | Продукт | Основание | |---|---|---|---| | Подписи сегмента привязки | Virtual device · Pick from the HA list | Virtual device (no binding) · Pick from the HA list | прежний ключ `marker.virtual_option`; текст, не раскладка | | «Show entities» | в панели выбора рядом с поиском | то же | решение владельца Q8 | | Ask for confirmation | скрыта при Do nothing | показана только при toggle / run | Q8; прежнее условие | | Display preview | упрощённый макет: сцена и таблица фактов | `hp-device-preview` целиком со своим заголовком «Display preview · Now» и переключателем деталей | решение владельца Q3, §3.1 «Превью маркера» | | Additional actions | строка-тумблер «This is a presence radar» | подзаголовок и кнопка «Объявить радаром» — прежнее действие радара; секции радара и пылесоса внутри диалога рисуются своими модулями без изменений | §7.2: ветки вне прототипа теми же примитивами; внутренняя разметка радара — вне скоупа #600 | | Иконка | поле с превью, Clear, Pin в подсказке | то же; в HA — `ha-icon-picker` вместо текстового поля | §7.1 | | Value badge | тумблер, Value, Position сегментом | то же; предупреждения бейджа — заметки и callout'ы | §7.1 | ## AC8: девять прямых дефектов выпущенного — свидетель на каждый | № | Дефект (тело issue) | Чем закрыт | Свидетель | |---|---|---|---| | 1 | дублированный заголовок Zigbee links | карточка рисует заголовок и «?», `hp-zigbee-topology-settings` в режиме `embedded` своего не рисует | `smoke_general_settings_form` → `zigbeeHeadingOnce`; мутант `topology-embedded-draws-its-own-heading` | | 2 | «Fill color» дважды в строке заливки пространства | плашка цвета с одной подписью поля (`colorRow` + `colorField`, у пикера `hide-label`) | `smoke_space_settings_form` → `hexIsPrinted`, `noNativeColorInputs`; `noLegacyMarkup` | | 3 | семь `rhint`-абзацев в четырёх диалогах | пояснения — под «?» (`_help`/`shelp`), сообщения о состоянии — callout'ы (К5) | `noLegacyMarkup` в четырёх фокусных смоках (класс `.rhint` отсутствует); `test/i18n-dead-keys`; мутант `state-callout-hidden-under-help` | | 4 | карточка внутри карточки (`fieldset` в Light and glow, Value badge) | плоские блоки `.hpf-block` с подзаголовком | `smoke_device_settings_form` → `noLegacyMarkup` (`fieldset`, `.markerlightgroup`), `badgeBlock`, `neverDisablesGlowBlock` | | 5 | поповер «?» обрезается границей диалога комнаты | подсказка живёт в top layer (Popover API) либо в портале `.overlay-portal` **вне** поверхности диалога; тело формы без своего скроллера — резать нечем | **`smoke_dialog_help_clipping`**: короткое окно, «?» нижней карточки комнаты, подсказка выходит за край скроллера и остаётся hit-test'ируемой во всех точках; четыре ветки — нативный `` и `ha-dialog` × Popover и fallback. Ветка `ha-dialog` — заглушка с ловушками настоящей mwc-поверхности (`transform` + `overflow: hidden` + свой скроллер); настоящий `ha-dialog` (#505, загрузка колеса HA-frontend) — отдельная диагностическая приёмка владельца, `demo/capture_summary_panel_505.mjs` как образец | | 6 | белый инпут на тёмной теме у Glow radius | поле набора `.hpf-unit` на токенах темы | `pairs/device-dark.png`; `smoke_device_settings_form` | | 7 | два скролла (тело формы и оболочка) | скроллер один — `.content` в `hp-dialog`; `.body` без `max-height`/`overflow` | фокусные смоки → `singleScroller` / `bodyHasNoOwnScroller` | | 8 | пустое пространство внизу | `.body` без `max-height` и лишнего `padding-bottom` | те же; кадры `pairs/` | | 9 | «Загружаем редактор…» | `editor.loading` → «Загрузка…» / «Loading…» | `src/i18n/*.json` | ## Принятые адаптации Расхождения, которые **не** являются дефектом, потому что продиктованы контрактами House Plan или решением владельца. Заполняется по ходу работы; каждая строка — с доводом, а не «так вышло». | Место | Референс | Продукт | Почему | |---|---|---|---| | Образцы карточки комнаты | убраны (`SPEC.md` §4.2, §6.1) | сохранены, встроены в карточку | решение владельца Q2: слайдер размера без образца — подбор вслепую | | Поле цвета | нативный `input[type=color]` (`SPEC.md` §3.2) | прежний `hp-color-opacity`, новая только раскладка | решение владельца Q5; `nativeColors() === 0` — контракт со свидетелем `smoke_color_picker_consumers` | | Цвета | фиксированные hex (`#4a9ec6`, `#f6f6f6`, …) | переменные темы HA | `SPEC.md` §2 «допустимые адаптации»; тёмная тема обязательна | | Шапка | круглая кнопка × слева, заголовок, бейдж справа | прежняя шапка `hp-dialog` (× справа) с бейджем в слоте заголовка | `SPEC.md` §3 «Шапка»: «существующая шапка hp-dialog; бейдж добавляется» | | Тумблеры | `input[type=checkbox][role=switch]` с нарисованной дорожкой | нативный чекбокс, нарисованный CSS набора; `ha-switch` не используется | К7: один вид в HA, на стенде и в golden; `smoke_ha_controls` | | Радар и пылесос внутри диалога устройства | нет в прототипе | прежняя разметка секций (`radar-section.ts`, `_renderVacSection`) | `SPEC.md` §7.2: ветки вне прототипа; их внутренняя раскладка — отдельная задача | | Высота строки подписи | 22 px, «?» 22 px | 32 px — по высоте кнопки `hp-help` | подписи с «?» и без стоят на одной линии в сетке из двух полей |