# AGIL Calls — аудит иконок (visual QA: icons)

> Проверка **всех** иконок сервиса: инвентаризация наборов, рендер в сетке 16/20/24/32/40/64px
> на светлом и тёмном фоне, геометрия путей (bbox, центрирование, отступы, ink coverage,
> кривые), иконки в живом UI (размеры, stroke, выравнивание с текстом, ARIA/alt,
> пустые/битые кнопки), брендинг (favicon/logo/manifest/og, прозрачность, читаемость 16/32px).
>
> **Стенд:** `https://calls.guardify.ru` · **Дата:** 13.11.2026 · **Chrome headless (puppeteer-core)**
> **Пост-фикс прогон:** 13.11.2026 — наборы иконок не изменились, все 22 замечания
> остаются открытыми (статусы в [§9](#9-пост-фикс-билд-13112026-статусы)).
> **Зона записи:** `qa/icons/**`, `docs/qa-icons.md`, `docs/screenshots/qa-icons-*.png`.
> Исходники приложения не менялись. Скриншоты — `qa/icons/screenshots/**`, `qa/icons/live/**`.

---

## Оглавление

1. [Сводка](#1-сводка)
2. [Методика](#2-методика)
3. [Инвентаризация наборов](#3-инвентаризация-наборов)
4. [Баг-лист отрисовки](#4-баг-лист-отрисовки)
5. [Иконки в живом UI](#5-иконки-в-живом-ui)
6. [Брендинг: favicon/logo/manifest/og](#6-брендинг)
7. [Рекомендации по единому icon-set](#7-рекомендации-по-единому-icon-set)
8. [Воспроизведение и повторный прогон](#8-воспроизведение-и-повторный-прогон)
9. [Пост-фикс билд (13.11.2026): статусы](#9-пост-фикс-билд-13112026-статусы)
10. [Индекс скриншотов](#10-индекс-скриншотов)
11. [Финальный аудит (13.11.2026): эмодзи, флаги, регрессии](#11-финальный-аудит-13112026-эмодзи-флаги-регрессии)

---

## 1. Сводка

| Метрика | Значение |
|---------|----------|
| Наборов иконок | 3: widget (inline path set), dashboard (inline path set), editor (inline `<symbol>` sprite) |
| Уникальных иконок | **117** = 40 widget + 50 dashboard + 27 editor |
| Рендер-ячеек в галерее | **1 404** (117 × 6 размеров × 2 фона) |
| Иконок в живом UI | **88** SVG-инстансов на 5 поверхностях (`/`, join, звонок, dashboard, editor) |
| Кнопок в живом UI | 74, из них 31 icon-only, 29 icon+text |
| Брендинг-ассетов | 14 (favicon.ico + 12 PNG + webmanifest) |
| **Замечаний** | **22**: P0 — 0, **P1 — 2**, **P2 — 12**, **P3 — 8** |

### Что критично

1. **Единого icon-set нет.** 16 из 17 одноимённых иконок нарисованы по-разному;
   `settings` — шестерёнка в звонке и слайдеры в админке/редакторе, `refresh` —
   одна стрелка в виджете и две в админке. Пользователь видит «разные продукты».
2. **Масштаб и штрих разъезжаются:** в живом UI иконки 12–22px (в звонке 15/16/18/22,
   в панели 14/15/16/17/18/20, в редакторе 12/14/15/16/18/30), штрих 1.8 (widget/editor),
   2.0 (dashboard) и 1.6 (одна иконка редактора). Это главный источник «иконки выглядят
   по-разному» при одинаковом функционале.
3. **Реальные дефекты отрисовки:** иконка замка в подсказке логина сжата до 13.4×15px
   (flex-shrink), `editor/reset` прижата к левому краю (bbox x=0.1 при stroke 1.8),
   `dashboard/key` смещена (off 1.6/−1.5), `editor/sparkles` смещена (1.75) и теряет искры
   на 16px, `editor/palette` — это капля, а не палитра.
4. **Брендинг:** `logo-on-light/dark` — 960×230 с контентом 575×181 (367px прозрачной
   пустоты справа) и **нигде не используется**; `favicon.ico` содержит только 16×16;
   `apple-touch-icon` (full-bleed) и `branding/agil-icon-180` (прозрачный с отступами) —
   два разных дизайна одного размера; maskable-иконка манифеста прозрачная.

### Что в порядке (не переделывать)

- **A11y иконок:** все SVG `aria-hidden="true" focusable="false"`, иконки-кнопки имеют
  `aria-label`/`title` — 0 безымянных из 31 icon-only, 0 пустых кнопок.
- **Выравнивание иконки с текстом:** 0 из 29 кнопок icon+text с расхождением центров >1px
  или «плохим» зазором.
- **Битые/пустые иконки:** 0 пустых SVG, 0 неразрешённых `<use>`, 0 missing-имён —
  все используемые имена определены в своих наборах.
- **viewBox:** у всех 117 иконок 24×24; ни одна не выходит за viewBox по bbox.
- **Favicon/manifest на подприложениях:** `/dashboard/*`, `/editor/*` отдают 200 (не 404).
- **OG-изображение 1200×630**, apple-touch 180×180, manifest sizes 192/512 совпадают с файлами.

---

## 2. Методика

| Скрипт | Что делает | Результат |
|--------|-----------|-----------|
| `qa/icons/extract-icons.mjs` | Парсит `icons.ts` (widget, dashboard) и `<symbol>` спрайт редактора; сканирует usage/mentions по исходникам; ищет unused/missing/duplicates | `qa/icons/icons.json` |
| `qa/icons/build-gallery.mjs` | Собирает `qa/icons/gallery.html`: 117 иконок × 16/20/24/32/40/64px × light/dark, сравнение 17 одноимённых, диагностика в браузере (getBBox, margins, off-center, ink@16/96, subpaths, curve share) | `gallery.html` |
| `qa/icons/capture-gallery.mjs` | Chrome headless: скриншоты секций, флагов и курированных зумов; выгружает метрики | `screenshots/**`, `icon-audit.json` |
| `qa/icons/live-ui-audit.mjs` | 5 поверхностей стенда: размеры SVG, stroke, viewBox/aria-hidden, `<use>` resolve, icon-only без имени, пустые кнопки, выравнивание icon+text, alt у img | `qa/icons/live/live-audit.json`, скриншоты тулбаров |
| `qa/icons/branding-audit.mjs` | 14 ассетов: нативные размеры, alpha, trimmed bbox/margins, ink@16/32/64, corner alpha, manifest consistency | `qa/icons/live/branding-audit.json`, `branding-sheet.png` |

Пороговые правила диагностики: `OUTSIDE viewBox` — bbox±stroke выходит за 0…24;
`TINY` — max(w,h)<4; `OFF-CENTER` — центр bbox дальше 1.2 от 12,12;
`ASYM-X/Y` — разница отступов >1.5; `INVISIBLE@16` — ink<1.2% на 16px; `TOO-HEAVY` — ink>65%.

Ограничения: ink-coverage — грубая метрика (не оценивает красоту формы); «кривые» пути
считаются по доле команд C/S/Q/T/A и приведены как информационная колонка, а не баг;
canvas-рендер `<use>` в редакторе инлайнится (иначе символы не рендерятся в blob).

---

## 3. Инвентаризация наборов

| Набор | Источник | Кол-во | viewBox | stroke | cap/join | Иконки |
|-------|----------|--------|---------|--------|----------|--------|
| Widget (звонок) | `packages/widget/src/icons.ts` | **40** | 24×24 | **1.8** | round/round, `currentColor`, fill none | mic, mic-off, camera, camera-off, screen, screen-off, blur, chat, hand, smile, settings, leave, send, close, paperclip, download, pin, fullscreen, pip, shield, check, note, transcript, record, users, warning, info, copy, chevron-left, chevron-right, sun, moon, monitor, refresh, grid, minimize, restore, external, more, user-check |
| Dashboard (админка) | `apps/dashboard/src/icons.ts` | **50** | 24×24 | **2.0** | round/round | overview, rooms, chat, security, audit, recordings, settings, menu, logout, sun, moon, monitor, plus, refresh, copy, external, lock, unlock, trash, search, chevron-left, chevron-right, check, x, alert-triangle, shield-check, mic, mic-off, video, video-off, key, link, code, server, download, cpu, globe, activity, clock, file, filter, info, play, user-check, user-x, terminal, arrow-up-right, eye, eye-off, shield |
| Editor (панель настройки) | `apps/editor/index.html` → `<symbol id="i-*">` | **27** | 24×24 | **1.8** (`.icon` CSS), одна иконка 1.6 | round/round | alert, book, check, code, copy, door, download, external, file, grid, info, key, layers, moon, palette, plug, plus, refresh, reset, save, shield, sliders, sparkles, sun, trash, upload, video |

### Unused / missing / duplicates

| Набор | Не используется в коде (mentions=0) | Ссылки на несуществующие иконки | Дубли |
|-------|-------------------------------------|--------------------------------|-------|
| Widget | `chevron-left`, `chevron-right`, `refresh` (3) | нет | нет |
| Dashboard | `clock`, `user-check`, `terminal`, `arrow-up-right` (4) | нет | **`security` ≡ `shield`** (идентичные path data) |
| Editor | нет (все 27 упоминаются) | нет | нет |

Дополнительно не используются файлы брендинга: `branding/agil-logo-on-light.png`,
`branding/agil-logo-on-dark.png` (в UI шапка собрана из icon+text).

### Одно понятие — разные имена/формы

| Понятие | Widget | Dashboard | Editor |
|---------|--------|-----------|--------|
| настройки | `settings` = **шестерёнка** | `settings` = **слайдеры** | `sliders` (слайдеры) |
| обновить | `refresh` = **одна стрелка** | `refresh` = **две стрелки (sync)** | `refresh` = две стрелки |
| участники/комнаты | `users` | `rooms` = users-подобная | — |
| запись | `record` (кольцо+точка) | `recordings` (кольцо+точка) | — |
| камера/видео | `camera` | `video` | `video` |
| закрыть | `close` | `x` | — |
| сетка/обзор | `grid` | `overview` | `grid` |
| файл/вложение | `paperclip` | `file` | `file` |
| предупреждение | `warning` | `alert-triangle` | `alert` |
| AI/ассистент | `note` (лист) | — | `sparkles` |

Итог по одноимённым: **17 общих имён, 16 из них — разная геометрия** (совпадает только
`check`; остальные 16: mic, mic-off, chat, settings, download, shield, info, copy,
chevron-left, chevron-right, sun, moon, monitor, refresh, external, user-check).

---

## 4. Баг-лист отрисовки

### P1

| ID | Место | Размер | Что не так | Почему плохо | Скриншот |
|----|-------|--------|------------|--------------|----------|
| **IC-01** | Все приложения | 16–24 | Нет единого icon-set: 16/17 одноимённых иконок нарисованы по-разному; `settings` — шестерёнка vs слайдеры; `refresh` — одна стрелка vs две | Одинаковые действия выглядят разными продуктами; ломается узнаваемость | `qa-icons-shared.png` (сравнение), `qa-icons-call-toolbar.png`, `qa-icons-dashboard-nav.png` |
| **IC-02** | Все приложения | 12–22 | Размеры иконок вне шкалы: call 15/16/18/22, dashboard 14/15/16/17/18/20, editor 12/14/15/16/18/30; stroke 1.8/2.0/1.6 | Оптический «пляшущий» вес, особенно рядом друг с другом | `qa-icons-call-header.png`, `qa-icons-dashboard-nav.png`, `qa-icons-editor-nav.png` |

### P2

| ID | Место | Размер | Что не так | Почему плохо | Скриншот |
|----|-------|--------|------------|--------------|----------|
| IC-03 | Dashboard, логин, подсказка `.auth-hint` | 15→**13.4×15** | Иконка замка сжата по ширине flex-контейнером (нет `flex:0 0 auto`) — не-квадратный viewBox → искажение | Видимая деформация иконки | `qa-icons-login-card.png`, `qa-icons-dashboard-nav.png` |
| IC-04 | Dashboard, `mic`/`mic-off` | 24 | Занимают весь viewBox 0…24 (margins 0), тогда как соседи — 2–3px; оптически крупнее и «впритык» к краю | Выбиваются из ряда, при обрезке/маске обрежутся | `qa-icons-dashboard.png` |
| IC-05 | Dashboard, `key` | 24 | Смещена от центра: off (−1.6, +1.5), margins 5.22/2/4/1 | «Пьяная» иконка, заметно в списках/кнопках | `qa-icons-flag-dashboard-key.png` |
| IC-06 | Editor, `reset` (сброс) | 24 | bbox x=0.1 при stroke 1.8 → левый край фактически обрезан | Срез линии, выглядит как брак | `qa-icons-flag-editor-reset.png` |
| IC-07 | Editor, `sparkles` (AI) | 24 | Смещена (off 1.75), мелкие искры исчезают на 16px (ink16 27%) | На маленьком размере читается как одна звезда | `qa-icons-flag-editor-sparkles.png` |
| IC-08 | Editor/Widget, семантика | 20–24 | `palette` нарисована **каплей**, хотя это «тема/цвет»; кнопка ассистента в звонке использует `note` (лист бумаги), а не AI-иконку | Иконка не по смыслу — пользователь не находит «Тему»/AI | `qa-icons-editor.png`, `qa-icons-call-header.png` |
| IC-09 | Widget, `minimize`/`restore` | 16–24 | Обе — «монитор с крошечной стрелкой»; на 16/20px неразличимы, метафора «свернуть звонок» не читается | Нельзя отличить свернуть от развернуть | `qa-icons-widget.png` |
| IC-10 | Код, все наборы | — | Дубли/конфликты: `dashboard.security ≡ shield`; close/x, grid/overview, record/recordings, camera/video, users/rooms | Dead code и несогласованный словарь | `qa-icons-dashboard.png`, `qa-icons-shared.png` |
| IC-11 | Editor, offline-warning | 18 | `stroke-width:1.6` против 1.8 в наборе | Иконка «тоньше» остальных | `qa-icons-editor-nav.png` |
| IC-12 | Branding, `agil-logo-on-*.png` | 960×230 | Контент 575×181, 367px прозрачной пустоты справа/снизу; в UI не используется (шапка = icon+text) | При подключении даст мелкий логотип и лишние отступы; сейчас мёртвый ассет | `qa-icons-branding.png` |
| IC-13 | Manifest, maskable 512 | 512 | Maskable-иконка — тот же PNG с **прозрачным** фоном; у maskable должен быть непрозрачный safe-фон и ≥10% padding | На Android-лаунчерах прозрачные края дают артефакты/обрезку | `qa-icons-branding.png` |
| IC-14 | `favicon.ico` | 16×16 (одна страница) | В .ico нет 32/48; на 32px используется отдельный PNG, но прямые запросы `/favicon.ico` (закладки, старые браузеры) получат мыло | Нечёткий фавикон в части контекстов | `qa-icons-branding.png` |

### P3

| ID | Место | Размер | Что не так | Скриншот |
|----|-------|--------|------------|----------|
| IC-15 | Widget, `screen` | 24 | ASYM-Y 2.0: монитор вместе с подставкой смещён вниз на ~1px | `qa-icons-flag-widget-screen.png` |
| IC-16 | Widget, `more` | 16 | Три точки `h.01`: ink16=3.5% (минимум среди всех) — на 16px почти сливаются | `qa-icons-widget.png` |
| IC-17 | Widget | 16–24 | Смешение fill/stroke: `send` (заливка) и точка `record` (заливка) в outline-наборе; в dashboard `play` — контур | `qa-icons-widget.png` |
| IC-18 | Код | — | 7 неиспользуемых определений: widget chevron-left/right, refresh; dashboard clock, user-check, terminal, arrow-up-right | `qa-icons-widget.png`, `qa-icons-dashboard.png` |
| IC-19 | Branding | 180×180 | `apple-touch-icon.png` (full-bleed, непрозрачный) vs `branding/agil-icon-180.png` (прозрачный, с отступами) — два разных дизайна одного размера | `qa-icons-branding.png` |
| IC-20 | Все приложения | 16 | При stroke 1.8 в 16px линия = 1.2px, при 2.0 — 1.33px (субпиксель) | — (метрика) |
| IC-21 | Лендинг `/` | — | 0 SVG-иконок: навигация и фичи только текстом | `qa-icons-call-header.png` / live landing |
| IC-22 | `favicon*` | 32 | Контент касается края (margins 1/2/0/2) — при маске/скруглении возможна обрезка | `qa-icons-branding.png` |

### Иконки по чек-листу пользователя (покрытие и качество)

| Иконка/понятие | Где есть | Состояние |
|----------------|----------|-----------|
| mic / camera / record | widget (mic/mic-off, camera/camera-off, record) | ✅ по смыслу, ⚠️ геометрия mic отличается от dashboard |
| assistant (AI) | widget: `note` (лист) → **семантика спорная**; editor: `sparkles` | ⚠️ IC-08 |
| settings | widget: gear; dashboard/editor: sliders | ⚠️ IC-01 |
| fullscreen / pip / minimize / newtab | widget: fullscreen, pip, minimize/restore, external (newtab) | fullscreen/pip/external ок; minimize/restore — IC-09 |
| chat / files / participants | widget: chat, paperclip, users; dashboard: chat, file, rooms | ✅ (разная геометрия) |
| notes / transcript | widget: note, transcript | ✅ |
| blur / hand / reactions | widget: blur, hand, smile | ✅ |
| security / lock | widget: shield; dashboard: security(=shield), lock, shield-check | lock есть только в админке (в звонке не нужен) |
| kick | dashboard: user-x | ✅, но имя не `kick` |
| eye | dashboard: eye/eye-off | ✅ |
| copy / refresh / plus / trash / check / alert | widget: copy/refresh/check/warning; dashboard: copy/refresh/plus/trash/check/alert-triangle | ⚠️ refresh разный (IC-01) |
| code / palette / sliders / layers / shield | dashboard/editor | ✅, palette = капля (IC-08) |
| video / sparkles / door / grid / info / file / key / book | editor/dashboard | ✅ |

---

## 5. Иконки в живом UI

Аудит 5 поверхностей стенда (`landing`, `join-screen`, `call`, `dashboard-login`, `dashboard`, `editor`):

| Поверхность | SVG | Размеры в UI | stroke | icon-only | icon+text | Безымянные icon-only | Пустые кнопки | Битые `<use>` |
|-------------|-----|--------------|--------|-----------|-----------|----------------------|---------------|----------------|
| Лендинг `/` | 0 | — | — | 0 | 0 | 0 | 0 | 0 |
| Экран входа | 4 | 18×18, 40×40 | 1.8 | 2 | 0 | 0 | 0 | 0 |
| Звонок | 20 | **15/16/18/22** | 1.8 | 10 | 6 | 0 | 0 | 0 |
| Логин панели | 6 | 13.4×15 (искажена), 15×15, 16×16 | 2.0 | 2 | 1 | 0 | 0 | 0 |
| Dashboard | 32 | 14/15/16/17/18/20 | 2.0 | 12 | 9 | 0 | 0 | 0 |
| Editor | 26 | 12/14/15/16/18/30 | 1.8 / **1.6** | 5 | 13 | 0 | 0 | 0 |
| **Итого** | **88** | — | 1.8 / 2.0 / 1.6 | **31** | **29** | **0** | **0** | **0** |

- Выравнивание icon+text: **0 из 29** кнопок с расхождением центров >1px или «плохим» зазором
  (измерялось между rect SVG и rect текстового узла).
- A11y: `aria-hidden` на всех SVG, `aria-label`/`title` у всех icon-only — **0 нарушений**.
- `img`: логотип в шапке звонка `alt="AGIL Calls"`; остальные логотипы `alt=""` рядом
  с текстовым названием — допустимо (декоративные), у всех есть атрибут `alt`.
- Битые изображения: 0; naturalWidth логотипа 256 при рендере 30–34px — ок (downscale).
- Найдено искажение: замок 13.4×15 (IC-03).

Скриншоты тулбаров/навигации: `qa-icons-call-toolbar.png`, `qa-icons-call-header.png`,
`qa-icons-dashboard-nav.png`, `qa-icons-editor-nav.png`, `qa-icons-login-card.png`.

---

## 6. Брендинг

| Ассет | Размер | Alpha | Trim (контент) | Margins L/T/R/B | Ink@16 | Комментарий |
|-------|--------|-------|----------------|-----------------|--------|-------------|
| favicon.ico | 16×16 | да | 15×12 | 1/2/0/2 | 60.9% | одна страница 16×16 (IC-14, IC-22) |
| favicon-16.png | 16×16 | да | 15×12 | 1/2/0/2 | 60.9% | ок |
| favicon-32.png | 32×32 | да | 29×22 | 2/5/1/5 | 60.9% | контент прижат к правому краю (1px) |
| apple-touch-icon.png | 180×180 | **нет** | 180×180 | 0/0/0/0 | 100% | full-bleed — правильно для iOS ⚠️ но отличается от icon-180 |
| agil-icon-180.png | 180×180 | да | 159×120 | 12/30/9/30 | 62.1% | прозрачный, отступы 17% сверху/снизу |
| agil-icon-192.png | 192×192 | да | 169×128 | 13/32/10/32 | 61.3% | соответствует manifest 192 |
| agil-icon-256.png | 256×256 | да | 226×170 | 17/43/13/43 | 60.5% | используется в шапках (34/30px) |
| agil-icon-32.png | 32×32 | да | 29×22 | 2/5/1/5 | 60.5% | совпадает с favicon-32 |
| agil-icon-512.png | 512×512 | да | 452×342 | 34/85/26/85 | 60.5% | manifest 512 + **maskable с прозрачностью** (IC-13) |
| agil-logo-on-light.png | 960×230 | да | 575×181 | 18/32/**367**/17 | 50.8% | пустота 367px справа; **не используется** (IC-12) |
| agil-logo-on-dark.png | 960×230 | да | 575×181 | 18/32/**367**/17 | 50.8% | то же (IC-12) |
| agil-og.png | 1200×630 | нет | 1200×630 | 0/0/0/0 | 100% | корректный OG |

Manifest (`/site.webmanifest`): name/short_name/description/start_url/display корректны;
icons: 192 (any), 512 (any), 512 (maskable) — размеры файлов совпадают с заявленными,
`theme_color=#2563eb`, `background_color=#0b1220`. Favicon/manifest на `/dashboard/`
и `/editor/` отдаются с 200.

Брендинг-скриншот: `qa-icons-branding.png` (native + 64/32/16 + dark, с шахматкой).

---

## 7. Рекомендации по единому icon-set

### Спецификация (принять один раз и зафиксировать в `@agil/icons`)

1. **Один источник правды** — пакет `packages/icons` (или `@agil/icons`) с манифестом
   `{ name, tags, viewBox: '0 0 24 24', paths }`; widget/dashboard/editor собирают
   из него inline-набор/спрайт. Сейчас три набора дублируют ~17 имён.
2. **Геометрия:** viewBox 24×24; stroke **1.8** (или единый 2.0 — решить и пересобрать
   dashboard), `fill="none"`, `stroke="currentColor"`, `stroke-linecap/linejoin="round"`,
   заполнения — только для семантических акцентов (точка записи) и задокументированы.
3. **Размеры UI:** шкала {16, 20, 24}; по умолчанию **20px**; 16px — только для плотных
   таблиц/бейджей, с stroke 2.0 (иначе hairline 1.2px). Не масштабировать SVG произвольно
   через CSS (`12/14/15/17/22` из аудита — убрать).
4. **Кнопки:** иконка flex:0 0 auto (лечит IC-03), hit-area ≥40×40, иконка 20px,
   gap 8px, вертикальное центрирование через flex (сейчас уже 0 расхождений).
5. **Именование:** kebab-case, `*-off` для перечёркнутых, одно понятие — одно имя
   (`sett` vs `device-settings`/`tenant-settings`; `reconnect` vs `refresh`; `kick`
   вместо `user-x`; `close` вместо `x`; `participants` вместо `rooms`, если это люди).
6. **Семантика:** исправить `palette` (капля → палитра/круг цветов), assistant (note →
   sparkles/AI), минимизацию (монитор+стрелка → chevron-down / collapse to corner),
   refresh (по смыслу: «переподключить» vs «обновить данные»).
7. **Убрать:** дубликат `dashboard.security` (−1), неиспользуемые 7 определений,
   неиспользуемые logo-файлы (или подключить их в шапки вместо icon+text).
8. **Брендинг:** обрезать canvas логотипов до trim (575×181) + `padding` в CSS,
   либо использовать icon+text везде; сгенерировать `favicon.ico` с 16/32/48;
   отдельный maskable PNG с непрозрачным фоном и safe-zone ≥10%; согласовать
   apple-touch и icon-180 (один дизайн, разные назначения — задокументировать).
9. **CI-гард:** скрипт `qa/icons/extract-icons.mjs` + `build-gallery.mjs` уже проверяют
   missing/unused/duplicates/bbox/margins; добавить в CI проверки:
   каждый icon использован, нет дублей path-data, нет `OUTSIDE/TINY/INVISIBLE@16`,
   у всех SVG `aria-hidden`, нет произвольных размеров вне шкалы, splash-gallery
   как визуальный diff.

### План миграции (для команды, ~1.5–2 дня)

1. Сгенерировать `@agil/icons` из widget-набора как базы + добавить отсутствующие
   admin/editor-иконки (lock, eye, plus, trash, code, key, book, palette, layers,
   sliders, sparkles, door, plug, upload, save, reset, terminal, cpu, server, globe,
   activity, filter, play, arrow-up-right, search, menu, logout, overview и т.д.).
2. Заменить локальные `icons.ts`/спрайт на импорт из пакета (3 файла).
3. Унифицировать CSS: один `.icon { width:20px; height:20px; flex:0 0 auto }` + модификаторы.
4. Прогнать `qa/icons/*` + `verify` и приложить before/after галерею.

---

## 8. Воспроизведение и повторный прогон

```powershell
cd E:\Claude\VideoCalls
$env:ADMIN_KEY='<admin-key>'                 # нужен для dashboard/editor/звонка
node qa/icons/extract-icons.mjs              # инвентаризация + unused/missing/duplicates
node qa/icons/build-gallery.mjs              # gallery.html (117 × 6 размеров × 2 фона)
node qa/icons/capture-gallery.mjs            # скриншоты + icon-audit.json
node qa/icons/live-ui-audit.mjs              # живой UI: размеры/выравнивание/aria
node qa/icons/branding-audit.mjs             # favicon/logo/manifest/og
```

После деплоя фикс-билда (и если меняются иконки) — прогнать те же 5 команд и сравнить
`qa/icons/icon-audit.json` / `live/live-audit.json` / `live/branding-audit.json`
с текущими (они сохраняются как baseline в `qa/icons/`), обновить раздел 4 и скриншоты.

---

## 9. Пост-фикс билд (13.11.2026): статусы

> Прогон всех скриптов на задеплоенном фикс-билде: наборы иконок **не менялись**
> (фикс касался тем/лейаута/уведомлений/типографики, не иконок). Baseline «до»:
> `qa/icons/baseline-2026-11-13-pre-fix/` (icon-audit, icons, live-audit, branding-audit).

| Что | До фикса | После фикса | Статус |
|-----|----------|-------------|--------|
| Наборы иконок | 40 + 50 + 27 = 117 | 117 (идентично) | не менялось |
| Unused-определения | 3 widget + 4 dashboard | 7 (те же) | **открыто** (IC-18) |
| Дубли | `dashboard.security ≡ shield` | тот же дубль | **открыто** (IC-10) |
| Дефекты геометрии (bbox/центр) | 4: widget/screen, dashboard/key, editor/reset, editor/sparkles | **те же 4** | **открыто** (IC-03…IC-07) |
| Искажённый замок в логине | 13.4×15 | 13.4×15 | **открыто** (IC-03) |
| Штрихи | 1.8 / 2.0 / 1.6 | 1.8 / 2.0 / 1.6 | **открыто** (IC-02, IC-11) |
| Размеры иконок в UI | 12–22px | 12–22px (call 15/16/18/22; dashboard 14–20; editor 12/14/15/16/18/30) | **открыто** (IC-02) |
| Шестерёнка vs слайдеры (`settings`) | есть | есть | **открыто** (IC-01) |
| Семантика (`palette`=капля, assistant=`note`) | есть | есть | **открыто** (IC-08) |
| A11y (aria/имена кнопок) | 0 нарушений | 0 нарушений (95 SVG, 83 кнопки, 33 icon-only) | ✅ без регрессий |
| Брендинг (logo/favicon/maskable) | IC-12…IC-14 | без изменений | **открыто** |

**Итог:** все 22 замечания (P1=2, P2=12, P3=8) остаются **открытыми** — это ожидаемо,
так как фикс-билд не содержал изменений иконок. Новых дефектов не появилось;
a11y-показатели и брендинг не деградировали.

**Новая поверхность — `/guardify.html`:** добавлено ещё 5 inline-SVG (brand-щит 18×18,
placeholder 40×40), у них **смешаны stroke 2 и 1.8**, а brand-щит нарисован отдельно
от widget/dashboard `shield` (третий вариант одной метафоры) — усиливает IC-01/IC-02.
A11y на странице в порядке: 0 безымянных icon-only, 0 пустых кнопок.
**Island-лейаут:** 14 кнопок, размеры 40px в острове, overflow 0, тач-таргеты 390 — 0
мелких; новых иконочных дефектов нет. Замечание по disabled-состоянию кнопки выхода —
в `docs/qa-visual.md` §1.1.

---

## 10. Индекс скриншотов

| Файл | Что |
|------|-----|
| `docs/screenshots/qa-icons-gallery.png` | Вся галерея (fullpage) |
| `docs/screenshots/qa-icons-widget.png` | Widget: 40 иконок × 16/20/24/32/40/64 × light/dark + диагностика |
| `docs/screenshots/qa-icons-dashboard.png` | Dashboard: 50 иконок, та же сетка |
| `docs/screenshots/qa-icons-editor.png` | Editor: 27 символов, та же сетка |
| `docs/screenshots/qa-icons-shared.png` | 17 одноимённых: widget / dashboard / editor, light+dark |
| `docs/screenshots/qa-icons-branding.png` | Брендинг: native + 64/32/16 + dark, шахматка |
| `docs/screenshots/qa-icons-call-toolbar.png`, `qa-icons-call-header.png` | Иконки звонка в живом UI |
| `docs/screenshots/qa-icons-dashboard-nav.png`, `qa-icons-editor-nav.png` | Навигация панели/редактора |
| `docs/screenshots/qa-icons-login-card.png` | Логин (включая искажённый замок) |
| `docs/screenshots/qa-icons-flag-*.png` | 4 иконки с дефектами геометрии (screen/key/reset/sparkles) |

Полный набор: `qa/icons/screenshots/**` (галереи, 69 зумов, 4 флага),
`qa/icons/live/**` (страницы, тулбары, брендинг-шит).

---

## 11. Финальный аудит (13.11.2026): эмодзи, флаги, регрессии

> Повторный прогон inventory/gallery/live на финальном образе + целевой аудит эмодзи
> (`qa/visual/audit-emoji.mjs`): реакции, чат-эмодзи, флаги стран, DPR 1/2.
> Наборы иконок не менялись; отчёт `docs/qa-visual.md` §13.

### Иконки: без регрессий, 22 замечания в бэклоге

| Показатель | Значение | Статус |
|------------|----------|--------|
| Наборы | 117 (widget 40 + dashboard 50 + editor 27) | без изменений |
| Live SVG на страницах | 95, кнопок 83, icon-only 33 | 0 безымянных, 0 пустых, 0 misaligned ✅ |
| Геометрические дефекты | те же 4: widget/screen, dashboard/key, editor/reset, editor/sparkles | открыто (IC-03…IC-07) |
| Unused / дубли | 7 unused, `dashboard.security ≡ shield` | открыто (IC-10, IC-18) |
| Stroke / размеры | 1.8 / 2.0 / 1.6; 12–22px | открыто (IC-02, IC-11) |
| Искажённый замок логина | 13.4×15 | открыто (IC-03) |
| Брендинг (logo/favicon/maskable) | без изменений | открыто (IC-12…IC-14, IC-22) |
| Clickall публичных страниц | 6 прогонов, 0 console/page errors | ✅ |

**Итог:** новых иконочных дефектов нет, **22 замечания остаются в бэклоге**
(P1=2, P2=12, P3=8) — регрессом не является.

### Эмодзи — отдельный слой (не icon-set), 2 новых замечания

| ID | Замечание | Факт | Сев. |
|----|-----------|------|------|
| **IC-23** | Флаги стран — региональные emoji-индикаторы | `countryLabel()` = emoji-флаг + код; на Windows флаг рендерится буквами → в панели «RS RS», «TR TR» (дубль кода, без флага); 1 эмодзи-элемент на room-detail, 13px | P2 |
| **IC-24** | Реакции/чат-эмодзи — растровые | в задеплоенном образе `menuSvgs=0`: 6 реакций рисуются текстовым emoji-глифом 14px (Inter→emoji fallback), чат — 13/14/22.4px; на DPR1 ступенчато. В HEAD `8168d84` уже SVG 20px (`agil-emoji-svg`, `shape-rendering: geometricPrecision`) — **не задеплоено** | P2 |

**Рекомендация:** задеплоить SVG-эмодзи из HEAD; флаги перевести на SVG-sprite или
текстовый код (без emoji); в чате — шкала 16/20/24px. Детали и кропы —
`docs/qa-visual.md` §12.2–12.3, `docs/screenshots/qa-audit-emoji-*`, `qa-audit-dashboard-seed-overview.png`.
`qa/icons/baseline-2026-11-13-pre-fix/` — baseline для диффа.


---

## Dashboard: фикс 2026-11-13 (IC-01/02/03/05/10/12/19)

Зона: `apps/dashboard/src/icons.ts`, `src/ui/layout.ts`, `src/styles.css`.
Проверка: headless Chrome, `qa/dashboard/qa-icons.json`,
скриншоты `qa/dashboard/screens/icons/nav-{light,dark,mobile}.png`.
Общий отчёт панели — `docs/qa-dashboard.md` §10.

| IC | Проблема | Статус |
|---|---|---|
| IC-01 | «Настройки» — sliders, в звонке gear | ✅ gear-иконка используется и в nav, и в действиях настройки |
| IC-02 | key смещена от центра bbox | ✅ key-round path, bboxCenter 12.02/11.98, margins 2/1.96/1.96/2 |
| IC-03 | непоследовательный flex/size иконок | ✅ `.nav-icon { flex:0 0 auto; width:20px; height:20px }` |
| IC-05 | key смотрелась меньше/смещённой | ✅ 20×20, stroke 2, центр bbox 12/12 |
| IC-10 | rooms = users (путаница), recordings = record-dot | ✅ rooms — дверь; recordings — film; knowledge — book |
| IC-12 | Knowledge cpu слишком плотная на 20px | ✅ book/book-database, проще и читаемее |
| IC-19 | одинаковое действие — разные иконки | ✅ settings gear везде; security использует shield; дубль `shield` удалён |

Дополнительно:

- Все 9 nav-иконок **20×20**, `stroke-width=2`, вертикальная разница центров
  с label = **−0.01 px** (порог ≤1 px), bbox center — **12/12** у всех.
- Rooms path перецентрован: bbox center 12/12, margins 3/3/2/2.
- Удалены дубли/неиспользуемые: `security ≡ shield`, `clock`, `user-check`,
  `terminal`, `arrow-up-right`; `book`/`send` добавлены осознанно.
- Названия: `overview` (grid), `rooms` (door), `recordings` (film),
  `settings` (gear), `security` (shield), `knowledge` (book).

Скриншоты светлая/тёмная/390: `qa/dashboard/screens/icons/`.
