fix(ui): выровнять chrome Frame KPI и доступность
Docker / build (push) Failing after 22s

Унифицировать оболочку ops-экранов, IconTile, skip-link и контракт UI.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-17 15:36:53 +07:00
co-authored by Cursor
parent edf1da165a
commit 55014105f5
23 changed files with 1728 additions and 399 deletions
+945
View File
@@ -0,0 +1,945 @@
# UX/UI Unification Plan
Дата аудита: 2026-08-17
Implementation: **DONE 2026-08-17** — CHANGE-001…034, Phases 16, Acceptance §19.
Уровень унификации (решение пользователя): **система + идентичный chrome во всех 6 приложениях**; доменные экраны **не** копируются.
Источники истины REUI PRO: [reui.io/docs](https://reui.io/docs) · [reui.io/llms.txt](https://reui.io/llms.txt) · MCP `user-reui` (`get_block` / `get_component` / `get_example` / `compose_page`). Skill ReUI: `668fb463eb` (локально и MCP совпадают). Версию REUI PRO **не** указываем — её нет.
---
## 1. Executive Summary
Workspace — 6 fullstack UI-приложений. Пять Vite SPA уже lock `surface: frame` + `reui-kit`. MikrotikManager — Next.js 16 App Router со SoT `/servers` на shadcn `Card` (`DataPageCard`). Это **две дизайн-системы** в одном workspace.
Целевое состояние:
- **Одинаковый chrome 1:1** во всех шести (включая Auth Portal и MikrotikManager): sidebar 240px, App Switcher, header AppsMenu → SystemMonitor, footer NavUser + segmented theme.
- **Одинаковый рецепт** ops-экранов: Frame, DataGrid+Filters, KPI = stats-12 + IconTile `elevated`, Quick Actions = Frame tiles, settings-3/16, Sheet для create/edit, Frame-friendly empty.
- **Разный домен:** topology VPS, DNS/kanban CFDM, BIRD/lookup EvoBGP, IdP Auth Portal, agents EvoFirewall, `/servers`/terminal MikrotikManager.
- **Не менять:** Vite vs Next, package scopes, API/SSO/OIDC, CRUD-поведение.
Главные gaps: Auth Portal без SystemMonitor; MikrotikManager без AppsMenu/NavUser/Switcher и с Sun/Moon toggle; ни один проект не установил `icon-tile`; VPS Card-shells на detail/charts; MM `DataPageCard` = Card.
---
## 2. Workspace Coverage
`Discovered projects: 6`
`Audited projects: 6`
`Projects with plan: 6`
`Coverage: 100%`
`Implementation: 34/34 CHANGE DONE (2026-08-17)`
| # | Project | Path | Type | Audited | Changes | Status |
|---|---|---|---|---|---|---|
| 1 | VPS Tracker | `c:\Users\shats\Dev\vps-tracker` | fullstack Vite SPA | YES | CHANGE-003, 004, 005, 009014, 025, 029 | Implemented |
| 2 | Cloudflare Domain Manager | `c:\Users\shats\Dev\cloudflare-domain-manager` | fullstack Vite SPA | YES | CHANGE-003, 004, 005, 006, 024 | Implemented |
| 3 | EvoBGP | `c:\Users\shats\Dev\EvoBGP` | fullstack Go API + Vite SPA | YES | CHANGE-003, 004, 005, 015017, 019 | Implemented |
| 4 | Auth Portal | `c:\Users\shats\Dev\auth-portal` | fullstack Vite SPA | YES | CHANGE-001, 004, 005, 021023 | Implemented |
| 5 | EvoFirewall | `c:\Users\shats\Dev\EvoFirewall` | fullstack Vite SPA | YES | CHANGE-003, 004, 005, 007, 020 | Implemented |
| 6 | MikrotikManager | `c:\Users\shats\Dev\MikrotikManager-3` | fullstack Next.js 16 | YES | CHANGE-002, 004, 008, 018, 027, 032034 | Implemented |
Backend-only проектов нет. Shared UX/UI rules: CHANGE-026, 028, 030, 031, RULE-CHANGE-001…010.
---
## 3. Workspace Inventory
| Project | Framework | Language | UI | CSS | Theme | Package UI | Kit |
|---|---|---|---|---|---|---|---|
| VPS Tracker | Vite + TanStack Router/Query | TS | shadcn base-nova + ReUI | Tailwind v4 | next-themes | `@cfdm/ui` | `reui-kit` (9 files) |
| CFDM | Vite + TanStack | TS | shadcn base-nova + ReUI | Tailwind v4 | next-themes | `@cfdm/ui` | `reui-kit` (8 files) |
| EvoBGP | Vite + TanStack; API Go | TS / Go | shadcn base-nova + ReUI | Tailwind v4 | next-themes | `@evobgp/ui` | `reui-kit` (7 files) — **KPI SoT** |
| Auth Portal | Vite + TanStack | TS | shadcn base-nova + ReUI | Tailwind v4 | next-themes | `@authportal/ui` | `reui-kit` (11 files; `ResourcePage` stub) |
| EvoFirewall | Vite + TanStack | TS | shadcn base-nova + ReUI | Tailwind v4 | next-themes | `@evofw/ui` | `reui-kit` (6 files) |
| MikrotikManager | Next.js 16 App Router | TS | shadcn + **partial** ReUI | Tailwind v4 | custom `theme-provider` (`rl-theme`) | `@/components/ui` | **нет** `reui-kit` |
TanStack Table во всех web-приложениях: `^8.21.x`. ReUI Data Grid docs (MCP `get_component`): TanStack Table **v9**. Это technical risk — см. §18. Не мигрировать v8→v9 в этом плане.
`icon-tile`: **не установлен ни в одном** из 6 (поиск `IconTile` / `icon-tile` = 0 файлов).
---
## 4. MCP / Skills / Plugins Inventory
| Tool | Status | Use in audit |
|---|---|---|
| MCP `user-reui` | ready | `get_block`, `get_component`, `get_example`, `get_agent_skill` — официальные `docsUrl`/`previewUrl` |
| MCP `plugin-shadcn-shadcn` | listed | primitives `@shadcn` (secondary) |
| MCP codegraph (vps / CFDM / EvoBGP) | available | не заменял filesystem inventory |
| Skill `.claude/skills/reui` | `668fb463eb` | совпадает с MCP `get_agent_skill` |
| Skill shadcn (plugin + CFDM/EvoFirewall) | present | CLI/registry, не SoT для PRO blocks |
| Context7 MCP | available | не нужен для REUI PRO URLs |
Приоритет: официальная документация REUI PRO > MCP metadata > project rules.
---
## 5. Project Rules Inventory
| Source | Project | Category | Used? |
|---|---|---|---|
| `docs/ui-design-contract.md` | VPS, CFDM, EvoBGP, Auth, FW | UX/UI contract (Frame, chrome, kit) | YES — baseline |
| `.cursor/rules/reui-mcp.mdc` | 5 Vite | ReUI MCP workflow | YES |
| `.cursor/rules/kpi-hybrid.mdc` | 5 Vite | KPI Item `size-10.5` DNA | YES — **устарело vs IconTile** |
| `.cursor/rules/frontend-shadcn.mdc` / `frontend-ui-patterns.mdc` | VPS, CFDM, Auth, FW | patterns | YES; VPS lists `kanban-board.tsx`, которого нет на диске |
| `.cursor/rules/web-shadcn.mdc` | EvoBGP | WEB-01…WEB-22 | YES |
| `AGENTS.md` | VPS, EvoBGP, Auth, FW, MM | agent guide | YES; **CFDM: `<not_found>`** |
| `.cursor/rules/next-shadcn-production.mdc` | MM | SoT = `/servers` Card | YES — **противоречит унификации** |
| `.cursor/rules/ma-ui-guardian.mdc` | MM | UI Guardian = `/servers` | YES — **противоречит** |
| Workspace `reui-pro-senior-frontend.mdc` | all | chrome + Frame lock | YES; Auth ids без `dns` |
Technical rules (Fastify/Drizzle/Go/Next App Router/CI) — **не менять** ради UI.
---
## 6. Project UX/UI Rules Audit
| Rule | Source | Current Usage | Problem | Recommendation | Status |
|---|---|---|---|---|---|
| Surface `frame` | ui-design-contract | 5 Vite mostly; MM Card | MM + VPS mixed Card | TARGET-001 | MODIFY (enforce all 6) |
| Chrome 240px / AppsMenu / NavUser | contract | 4 Vite close; Auth no monitor; MM none | Identity drift | TARGET-006 | NEW (1:1 all 6) |
| KPI hybrid Item tile | kpi-hybrid.mdc | 5 Vite kit | Official primitive IconTile unused | TARGET-003 | REPLACE |
| Lists DataGrid+Filters | contract | Vite ResourcePage; MM DataPageCard | MM Card; VPS `spaces` Table | TARGET-002 | MODIFY |
| Settings settings-16 / settings-3 | contract | CFDM closest | settings-7 is `surface: card` | TARGET-005 | MODIFY |
| Empty empty-state-12 | contract | mixed | empty-state-11 is Card; prefer 14 | TARGET-008 | MODIFY |
| MM SoT `/servers` Card | next-shadcn-production | enforced | Blocks Frame unification | RULE-CHANGE-001 | REPLACE |
| App Switcher ids | Auth contract vs `APP_IDS` | code has `dns` | Contract omits `dns` | CHANGE-023 | MODIFY |
| Installed ReUI lists | reui-mcp.mdc | claims kanban in VPS | File missing | CHANGE-025 | MODIFY |
| CFDM AGENTS.md / ui-surface.ts | contract mentions | `<not_found>` | Rules drift | CHANGE-024 | NEW |
---
## Chrome Identity Spec (обязательный 1:1 — все 6)
Эталон: [app-shell-12](https://reui.io/preview/base/app-shell-12) + [app-shell-7](https://reui.io/preview/base/app-shell-7) (SystemMonitor) + [app-shell-1](https://reui.io/preview/base/app-shell-1) (NavUser).
Применяется к **каждому** приложению, включая Auth Portal `_auth` shell и MikrotikManager `(main)` layout. Login Auth Portal **без** AppShell — отдельный auth surface ([auth-18](https://reui.io/preview/base/auth-18)).
| Зона | Обязательное значение | Сейчас VPS/CFDM/BGP/FW | Auth Portal | MikrotikManager |
|---|---|---|---|---|
| `--sidebar-width` | `240px` | `240px` (`packages/ui/.../sidebar.tsx`) | 240px (ожидаемо, тот же паттерн) | **`16rem`** (`components/ui/sidebar.tsx`) |
| Sidebar header | App Switcher ids `cfdm` · `vps` · `bgp` · `fw` · `dns` | есть | есть | **нет** |
| Sidebar footer | NavUser + segmented theme (light/dark/system), без Sun/Moon icon | NavUser segmented | NavUser segmented | **hand-roll** avatar + Sun/Moon (`app-sidebar.tsx` ~239266); `nav-user.tsx` **не используется** |
| Header right | AppsMenu → SystemMonitorPopover; без ModeToggle; без Search-кнопки (только ⌘K) | AppsMenu + SystemMonitor | AppsMenu **без** SystemMonitor (`site-header.tsx` 7375) | нет AppsMenu / SystemMonitor; `CommandPaletteButton` в sidebar header |
| Header | `h-12`, sticky, `border-b`, `px-4 md:px-6` | да | да | `<uncertain>` vs Vite (Next layout свой) |
| Main | `gap-4 md:gap-6`, `px-4 py-4 md:px-6 md:py-5` | contract | contract | `<not_verified>` pixel-match |
| Theme | next-themes **или эквивалент с тем же UX** + semantic `--success/--warning/--info/--invert` | next-themes | next-themes | custom `theme-provider` `rl-theme` — UX должен стать segmented 3-way |
| Запрещено | `SidebarRail`, Search pill в header, ModeToggle в header | Vite: без Rail | без Rail | **`SidebarRail` есть** (`app-sidebar.tsx` 267) |
SSO: вход через auth-portal; App Switcher `GET /api/v1/app-switcher`. Ids в коде: `packages/shared/src/contracts/auth.ts` `APP_IDS = ['cfdm', 'vps', 'bgp', 'fw', 'dns']`.
---
## 7. UX/UI Audit — VPS Tracker
**Identity:** Vite SPA `apps/web`, `@cfdm/ui`, ReUI CLI в `apps/web/src/components/reui/`.
**Routes (`_auth/`):** dashboard, vps, `vps.$vpsId`, accounts, providers, projects, `projects.$projectId`, payments, balance, tariffs, renewals, resources, reports, spaces, topology, audit, sync-journal.
**Kit:** `resource-page`, `kpi-stat-grid`, `quick-action-grid`, `ops-dashboard`, `settings-shell`, `detail-panel`, `frame-data-grid`, `settings-card`, `topology-canvas`. Нет `kanban-board`.
**ReUI on disk:** autocomplete, badge, icon-stack, filters, frame, alert, color-picker, timeline, number-field, date-selector + `data-grid/*`. Нет `icon-tile`, нет `kanban`.
**Chrome:** `app-shell.tsx` — SystemMonitor есть; sidebar 240px.
**Surface drift:** Card в `vps.$vpsId.tsx`, `resources.tsx`, `renewals.tsx`, `domain/charts.tsx`, `integrations/app-switcher-editor.tsx`. shadcn Table в `spaces.tsx`.
**Dashboard QA:** contract: VPS order = banner → KPI → charts → attention → QuickActionGrid (исключение vs EvoBGP KPI → QA → rest).
**Preserve:** VPS CRUD, BILLmanager sync, тарифы, баланс, платежи, topology canvas, CSV export, фильтры отчётов.
---
## 8. UX/UI Audit — Cloudflare Domain Manager
**Identity:** Vite SPA, `@cfdm/ui`, Frame-first. Card **не** импортируется в `apps/web` (grep 0). Ближе всех к контракту.
**Routes:** index, domains, `domains/$domainId`, DNS, services, groups, `groups/$groupId`, certificates, settings (index/appearance/integrations).
**Kit:** + `kanban-board`, `dashboard-analytics`. Нет `frame-data-grid` отдельным файлом (`<uncertain>` — может быть внутри ResourcePage).
**Gaps:** нет `AGENTS.md`; нет `ui-surface.ts`; naming `*KpiCards` (`domain-kpi-cards.tsx`, `cert-kpi-cards.tsx`, `service-kpi-cards.tsx`) при том что внутри уже `KpiStatGrid`; KPI tiles = Item hybrid, не IconTile.
**Preserve:** DNS CRUD, Cloudflare certs, groups/services kanban, integrations.
---
## 9. UX/UI Audit — EvoBGP
**Identity:** KPI SoT. `@evobgp/ui`. `lib/ui-surface.ts` есть.
**Routes:** dashboard, modules, `modules/$moduleId`, `modules/new`, lookup, network, operations, monitoring, directories, schedule, settings, tenant-settings, access.
**Card leftovers:** `modules/new.tsx`, `illustrated-empty-state.tsx`, `kpi-sparkline-card.tsx`, examples `c-tabs-*`.
**Kit unused:** `SettingsShell` определён в `reui-kit/settings-shell.tsx`, **не** импортируется routes (grep только definition).
**Forms:** WEB-05 требует RHF; фактическое использование в `src``<uncertain>` / выравнивать на Field + sheet-8.
**Preserve:** modules CRUD, lookup, BIRD jobs, network, access keys.
---
## 10. UX/UI Audit — Auth Portal
**Identity:** IdP, не ops CRUD. Login: `routes/index.tsx``PortalLoginForm` на базе **auth-18** (`components/blocks/auth-18/...`).
**`_auth` routes:** apps, admin users, user detail, oidc, logins, audit, admin apps.
**Chrome gap:** `site-header.tsx` — только `AppsMenu`, **нет** `SystemMonitorPopover` (grep 0 по репо).
**Kit:** `ResourcePage` — stub types only (`reui-kit/resource-page.tsx`). `/apps` — hand-roll Frame tiles, не `QuickActionGrid`.
**Contract vs code:** `docs/ui-design-contract.md` ids без `dns`; `APP_IDS` включает `dns`.
**Preserve:** SSO JWT, OIDC authorize/token/userinfo, app switcher admin, user access, audit.
---
## 11. UX/UI Audit — EvoFirewall
**Identity:** `@evofw/ui`. Chrome: `site-header.tsx` AppsMenu + SystemMonitor.
**Routes:** index, agents, `agents/$id`, lists, `lists/$id`, rules, `rules/$setId`, stats, settings.
**SettingsShell:** файл есть, **не** используется routes (grep 0 в routes). `/settings` — PageShell + Frame (допустимо как REPLACE rule).
**AgentPlatformIcon:** Item `size-10.5` `bg-muted` (`agents/agent-platform-icon.tsx`) — та же устаревшая KPI DNA.
**Agent cards view:** Frame domain (`?view=cards|table`) — **оставить**, не Card.
**Preserve:** agent fleet, blocklists, policy rules, stats, EvoBGP prefix ingest.
---
## 12. UX/UI Audit — MikrotikManager
**Identity:** Next.js 16, `components.json` с `@reui`, **нет** `reui-kit`. SoT UI: `app/(main)/servers/page.tsx` + `DataPageCard``Card` (`components/data-page-card.tsx`).
**Pages (27):** servers, dashboard, firewall, filters, certificates, gre, data-collection, uptime, recursive-routes, route-optimizer, ospf, communities, settings, probes, vxlan, wireguard, backups, bgp, ip-ranges, domains, asns, alerts, network-map, terminal, traffic, releases, containers.
**ReUI on disk:** frame, filters, badge, alert, autocomplete, number-field, sortable, timeline, stepper + data-grid (partial). `frame.tsx` установлен, ops-shell его не использует.
**Chrome:** sidebar `16rem`; footer hand-roll + Sun/Moon; `NavUser` файл есть, не подключён; нет App Switcher / AppsMenu / SystemMonitor; `SidebarRail` включён.
**Theme:** `components/theme-provider.tsx` STORAGE_KEY `rl-theme` — не next-themes; UX должен стать 3-way segmented.
**Preserve:** весь CRUD `/servers` и остальные 26 страниц (terminal, network-map, контейнеры, BGP/OSPF/firewall…). Framework остаётся Next.js.
---
## 13. Cross-project Inconsistency Matrix
| Area | VPS | CFDM | EvoBGP | Auth | FW | MM | UX impact | Priority | Target |
|---|---|---|---|---|---|---|---|---|---|
| Ops surface | mixed Card | Frame | leftover Card | Frame | Frame | **Card SoT** | две системы | P0/P1 | Frame |
| Chrome identity | close | close | close | no monitor | close | **none** | разный «дом» | P0 | Chrome spec |
| Sidebar width | 240px | 240px | 240px | 240px | 240px | 16rem | визуальный разрыв | P0 | 240px |
| Theme control | NavUser segmented | same | same | same | same | Sun/Moon | разный UX | P0 | segmented |
| KPI tile | Item hybrid | Item hybrid | Item hybrid SoT | Item | Item / AgentPlatformIcon | Card KPI | нет IconTile | P1 | IconTile elevated |
| Lists | ResourcePage; spaces Table | ResourcePage | ResourcePage | stub + Frame grids | ResourcePage | DataPageCard | MM/VPS spaces | P1 | DataGrid+Filters |
| Quick Actions | kit (order exception) | kit | kit | hand-roll `/apps` | kit | `<not_found>` | Auth/MM | P1 | QuickActionGrid |
| Settings | SettingsShell | Frame settings | unused SettingsShell | N/A portal | unused SettingsShell | Card settings | dead kit | P2 | settings-3/16 |
| Empty | EmptyState | EmptyState | Card illustrated | Frame empty `/apps` | EmptyState | EmptyState Card-ish | Card empty | P2 | empty-state-14/12 |
| Package UI | `@cfdm/ui` | `@cfdm/ui` | `@evobgp/ui` | `@authportal/ui` | `@evofw/ui` | `@/components/ui` | не сливать npm | — | KEEP scopes |
---
## 14. Duplicate Components Analysis
| Task | Copies | Diff | Unify? | REUI |
|---|---|---|---|---|
| `KpiStatGrid` | 5 Vite repos | import scope only (SoT EvoBGP) | DNA sync per repo, **не** monorepo package | REUI-004 + REUI-005 |
| `QuickActionGrid` | 5 Vite | same | same | REUI-013 |
| `ResourcePage` | 4 ops + Auth stub | Auth stub | implement or stop claiming | REUI-006 |
| `OpsDashboard` | VPS/CFDM/BGP/FW | similar | KEEP per repo | REUI-014 |
| `SettingsShell` | VPS/CFDM/BGP/FW | BGP/FW unused | wire or stop listing as used | REUI-007 |
| `SystemMonitorPopover` | 4 Vite; Auth/MM missing | copy per app | port to Auth + MM | REUI-011 |
| `DataPageCard` vs Frame | MM only vs Vite Frame | Card vs Frame | REPLACE MM | REUI-001 |
| Item KPI tile vs IconTile | 5 Vite + FW AgentPlatformIcon | hand-roll | REPLACE with IconTile | REUI-005 |
Общий npm-пакет kit **не** входит в этот план (package boundaries = technical risk).
---
## 15. REUI PRO Reference Registry
| Ref ID | Component/Block | Official Documentation | Official Example | Used By | Match |
|---|---|---|---|---|---|
| REUI-001 | Frame | [docs/components/base/frame](https://reui.io/docs/components/base/frame) | [components/frame](https://reui.io/components/frame) | CHANGE-009018, 027 | 1:1 ops surface |
| REUI-002 | Data Grid | [docs/components/base/data-grid](https://reui.io/docs/components/base/data-grid) | [components/data-grid](https://reui.io/components/data-grid) | CHANGE-013, 018 | 1:1 lists; docs = TanStack **v9** vs installed v8 → adaptation = **partial** until migration |
| REUI-003 | Filters | [docs/components/base/filters](https://reui.io/docs/components/base/filters) | [components/filters](https://reui.io/components/filters) | CHANGE-013, 018 | 1:1 |
| REUI-004 | stats-12 | [blocks](https://reui.io/blocks) | [preview/base/stats-12](https://reui.io/preview/base/stats-12) | CHANGE-005, 008 | **partial** (MCP: Frame+Badge+Item; kit hand-rolls Item) |
| REUI-005 | Icon Tile | [docs/components/base/icon-tile](https://reui.io/docs/components/base/icon-tile) | [components/icon-tile](https://reui.io/components/icon-tile) | CHANGE-004, 005, 007, 008 | 1:1 for tile primitive (`variant="elevated"` per docs) |
| REUI-006 | data-grid-filtering-2 | [blocks](https://reui.io/blocks) | [preview/base/data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2) | CHANGE-013, 018, 021 | **partial** (kit ResourcePage) |
| REUI-007 | settings-16 | [blocks/application/settings](https://reui.io/blocks/application/settings) | [preview/base/settings-16](https://reui.io/preview/base/settings-16) | CHANGE-020 | 1:1 integrations |
| REUI-008 | settings-3 | [blocks](https://reui.io/blocks) | [preview/base/settings-3](https://reui.io/preview/base/settings-3) | CHANGE-020 | 1:1 settings rows Frame |
| REUI-009 | settings-8 | [blocks](https://reui.io/blocks) | [preview/base/settings-8](https://reui.io/preview/base/settings-8) | CHANGE-020 | 1:1 webhook-like lists |
| REUI-010 | app-shell-12 | [blocks](https://reui.io/blocks) | [preview/base/app-shell-12](https://reui.io/preview/base/app-shell-12) | CHANGE-001, 002, 003 | **partial** (chrome composition) |
| REUI-011 | app-shell-7 | [blocks](https://reui.io/blocks) | [preview/base/app-shell-7](https://reui.io/preview/base/app-shell-7) | CHANGE-001, 002 | **partial** (SystemMonitor popover match) |
| REUI-012 | app-shell-1 | [blocks](https://reui.io/blocks) | [preview/base/app-shell-1](https://reui.io/preview/base/app-shell-1) | CHANGE-002, 032 | **partial** (NavUser) |
| REUI-013 | card-12 | [blocks](https://reui.io/blocks) | [preview/base/card-12](https://reui.io/preview/base/card-12) | CHANGE-022 | **partial** (Quick Actions DNA; name «card» но Frame tiles) |
| REUI-014 | dashboard-1 | [blocks](https://reui.io/blocks) | [preview/base/dashboard-1](https://reui.io/preview/base/dashboard-1) | CHANGE-008, 029 | **partial** (OpsDashboard) |
| REUI-015 | empty-state-14 | [blocks](https://reui.io/blocks) | [preview/base/empty-state-14](https://reui.io/preview/base/empty-state-14) | CHANGE-016, 030 | 1:1 Frame empty (MCP `surface: frame`) |
| REUI-016 | empty-state-12 | [blocks](https://reui.io/blocks) | [preview/base/empty-state-12](https://reui.io/preview/base/empty-state-12) | CHANGE-030 | **partial** (current cite; MCP surface none) |
| REUI-017 | sheet-8 | [blocks](https://reui.io/blocks) | [preview/base/sheet-8](https://reui.io/preview/base/sheet-8) | CHANGE-031 | **partial** (settings sheet; surface none) |
| REUI-018 | sheet-1 | [blocks](https://reui.io/blocks) | [preview/base/sheet-1](https://reui.io/preview/base/sheet-1) | CHANGE-031 | **partial** (create sheet) |
| REUI-019 | sheet-9 | [blocks](https://reui.io/blocks) | [preview/base/sheet-9](https://reui.io/preview/base/sheet-9) | CHANGE-031 | **partial** (detail sheet) |
| REUI-020 | auth-13 | [blocks](https://reui.io/blocks) | [preview/base/auth-13](https://reui.io/preview/base/auth-13) | Auth login **не** target (см. REUI-021) | 1:1 Frame login **если** менять; сейчас KEEP auth-18 |
| REUI-021 | auth-18 | [blocks](https://reui.io/blocks) | [preview/base/auth-18](https://reui.io/preview/base/auth-18) | Auth login actual | **partial** (surface none; split testimonial) |
| REUI-022 | solution-users-1 | [blocks](https://reui.io/blocks) | [preview/base/solution-users-1](https://reui.io/preview/base/solution-users-1) | Auth admin users | **partial** (Frame+DataGrid+Filters+Sheet) |
| REUI-023 | form-7 | [blocks](https://reui.io/blocks) | [preview/base/form-7](https://reui.io/preview/base/form-7) | CHANGE-031 | **partial** (inline Frame form) |
| REUI-024 | chart-15 | [blocks](https://reui.io/blocks) | [preview/base/chart-15](https://reui.io/preview/base/chart-15) | CHANGE-012 | 1:1 Frame charts (MCP `surface: frame`) |
| REUI-025 | settings-2 | [blocks](https://reui.io/blocks) | [preview/base/settings-2](https://reui.io/preview/base/settings-2) | CHANGE-020 | 1:1 mixed-control rows Frame |
| REUI-026 | c-tabs-2 | [components/tabs](https://reui.io/components/tabs) | [preview/base/components/c-tabs-2](https://reui.io/preview/base/components/c-tabs-2) | ResourcePage tabs | **partial** (line tabs; example also lists Card) |
| REUI-027 | Alert Dialog example | [components/alert-dialog](https://reui.io/components/alert-dialog) | [c-alert-dialog-11](https://reui.io/preview/base/components/c-alert-dialog-11) | CHANGE-031 confirm | **partial** (shadcn AlertDialog + ReUI example) |
| REUI-028 | Icon Stack | [docs/components/base/icon-stack](https://reui.io/docs/components/base/icon-stack) | [components/icon-stack](https://reui.io/components/icon-stack) | CHANGE-016, 030 | 1:1 empty illustration |
| REUI-029 | Badge | [docs/components/base/badge](https://reui.io/docs/components/base/badge) | [components/badge](https://reui.io/components/badge) | KPI/QA status | 1:1 semantic variants |
| REUI-030 | Alert | [docs/components/base/alert](https://reui.io/docs/components/base/alert) | [components/alert](https://reui.io/components/alert) | errors | 1:1 |
| REUI-031 | Kanban | [docs/components/base/kanban](https://reui.io/docs/components/base/kanban) | [components/kanban](https://reui.io/components/kanban) | CFDM groups/services | 1:1 domain |
| REUI-032 | Sortable | [docs/components/base/sortable](https://reui.io/docs/components/base/sortable) | [components/sortable](https://reui.io/components/sortable) | FW policy | 1:1 domain |
| REUI-033 | Stepper | [docs/components/base/stepper](https://reui.io/docs/components/base/stepper) | [components/stepper](https://reui.io/components/stepper) | MM/FW if used | 1:1; FW unused → don't list as used |
| REUI-034 | Timeline | [docs/components/base/timeline](https://reui.io/docs/components/base/timeline) | [components/timeline](https://reui.io/components/timeline) | audit | 1:1 |
| REUI-035 | Autocomplete | [docs/components/base/autocomplete](https://reui.io/docs/components/base/autocomplete) | [components/autocomplete](https://reui.io/components/autocomplete) | domain pickers | 1:1 |
**Не target (намеренно):**
| Item | Why | Evidence |
|---|---|---|
| settings-7 | MCP `surface: card` | [preview/base/settings-7](https://reui.io/preview/base/settings-7) |
| empty-state-11 | MCP `surface: card` | [preview/base/empty-state-11](https://reui.io/preview/base/empty-state-11) |
---
## 16. Target UX/UI Rules
### TARGET-RULE-001
**Rule:** Один surface на ops-экран: ReUI Frame. Не смешивать Card и Frame.
**Scope:** все 6.
**Rationale:** две системы ломают consistency.
**REUI PRO:** [Frame](https://reui.io/docs/components/base/frame)
**Impact:** VPS Card pages, BGP leftovers, MM DataPageCard.
### TARGET-RULE-002
**Rule:** Ops-списки = DataGrid + Filters внутри Frame. Запрет raw `<table>` / shadcn Table как ops list.
**Scope:** все 6.
**REUI PRO:** [data-grid](https://reui.io/docs/components/base/data-grid) · [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2)
**Impact:** VPS `spaces.tsx`; MM DataPageCard.
### TARGET-RULE-003
**Rule:** KPI = stats-12 composition + IconTile `elevated` (не hand-roll Item `size-10.5`). Semantic `text-*` / Badge, не `bg-emerald-*`.
**Scope:** kit во всех Vite + MM dashboard.
**REUI PRO:** [stats-12](https://reui.io/preview/base/stats-12) · [icon-tile](https://reui.io/docs/components/base/icon-tile)
### TARGET-RULE-004
**Rule:** Quick Actions = только `QuickActionGrid` (Frame tiles, sibling KPI).
**REUI PRO:** [stats-12](https://reui.io/preview/base/stats-12) · [card-12](https://reui.io/preview/base/card-12)
### TARGET-RULE-005
**Rule:** Settings rows = settings-3 / settings-2; integrations = settings-16; **запрет settings-7**.
**REUI PRO:** [settings-3](https://reui.io/preview/base/settings-3) · [settings-16](https://reui.io/preview/base/settings-16)
### TARGET-RULE-006 (P0)
**Rule:** Chrome identity 1:1 во всех 6 — см. Chrome Identity Spec. Auth Portal и MikrotikManager **не** исключение. Login без AppShell.
**REUI PRO:** [app-shell-12](https://reui.io/preview/base/app-shell-12) · [app-shell-7](https://reui.io/preview/base/app-shell-7) · [app-shell-1](https://reui.io/preview/base/app-shell-1)
### TARGET-RULE-007
**Rule:** Create/edit = Sheet (sheet-8 / sheet-1 / sheet-9). Confirm = Alert Dialog ([c-alert-dialog-11](https://reui.io/preview/base/components/c-alert-dialog-11)).
### TARGET-RULE-008
**Rule:** Empty = Empty + IconStack, Frame-friendly empty-state-14 (prefer) / empty-state-12. Не empty-state-11.
### TARGET-RULE-009
**Rule:** MikrotikManager UX SoT: Frame+DataGrid **при сохранении** CRUD `/servers`. Next.js не менять.
### TARGET-RULE-010
**Rule:** Rules синхронизировать с диском (не перечислять неустановленные компоненты как установленные). App Switcher ids включают `dns`.
---
### RULE-CHANGE-001
**Current rule:** SoT UI = `/servers` на Card (`next-shadcn-production.mdc`, `ma-ui-guardian.mdc`).
**Source:** `MikrotikManager-3/.cursor/rules/next-shadcn-production.mdc`
**Problem:** блокирует унификацию Frame.
**Evidence:** `components/data-page-card.tsx``Card`.
**Recommended:** SoT = Frame + DataGrid; `/servers` остаётся эталоном **поведения** CRUD, не Card-shell.
**REUI:** REUI-001, REUI-006.
**Impact:** MM rules + все `DataPageCard` pages.
### RULE-CHANGE-002
**Current:** kpi-hybrid Item `size-10.5` `bg-muted`.
**Source:** `kpi-hybrid.mdc` ×5.
**Problem:** official IconTile покрывает задачу; нигде не установлен.
**Recommended:** KPI/row tiles = IconTile `elevated` + stats-12 composition.
**REUI:** REUI-004, REUI-005.
### RULE-CHANGE-003
**Current:** chrome описан в contract, но Auth/MM исключения фактически существуют.
**Recommended:** Chrome Identity Spec обязателен 1:1 для всех 6.
**REUI:** REUI-010, REUI-011, REUI-012.
### RULE-CHANGE-004
**Current:** contract App Switcher ids без `dns`.
**Source:** `auth-portal/docs/ui-design-contract.md`
**Evidence:** `APP_IDS` включает `dns`.
**Recommended:** ids `cfdm · vps · bgp · fw · dns`.
### RULE-CHANGE-005
**Current:** VPS `frontend-shadcn.mdc` / `reui-mcp.mdc` lists `kanban-board`.
**Evidence:** `reui-kit/` VPS — нет `kanban-board.tsx`; grep `kanban` в VPS = 0.
**Recommended:** список установленных = диск.
### RULE-CHANGE-006
**Current:** settings-7 встречается как reference.
**Evidence:** MCP settings-7 `surface: card`.
**Recommended:** запретить как target.
---
## 17. Detailed Change Plan
Шаблон ниже. Functional requirements для всех UI CHANGE: сохранить create/edit/delete/filter/sort/pagination/navigation/permissions; менять только оболочку.
Состояния (где применимо): default, hover, focus, disabled, loading, error, empty.
Responsive: desktop = эталон ReUI preview; tablet/mobile = существующий Sidebar/Sheet collapse Vite/Next, не ломать.
A11y: keyboard, focus ring, labels, `aria-hidden` на decorative IconTile (docs).
### CHANGE-001
**Project:** Auth Portal · **Priority:** P0 · **Category:** Navigation / chrome
**File:** `apps/web/src/components/layout/site-header.tsx`
**Current:** header right = только `AppsMenu` (строки 7375).
**Problem:** нет SystemMonitor — ломает chrome identity.
**Change:** добавить `SystemMonitorPopover` после AppsMenu (порт с CFDM/VPS).
**Ref:** REUI-011 · [app-shell-7](https://reui.io/preview/base/app-shell-7) · Match: **partial**
**Mapping:** AppsMenu-only header → AppsMenu + SystemMonitor.
**Preserve:** breadcrumbs, AppsMenu, SSO session.
**Risk:** Low.
### CHANGE-002
**Project:** MikrotikManager · **Priority:** P0 · **Category:** Navigation / chrome
**Files:** `components/app-sidebar.tsx`, `components/ui/sidebar.tsx`, `(main)/layout.tsx`
**Current:** sidebar 16rem; footer hand-roll + Sun/Moon; SidebarRail; нет AppsMenu/SystemMonitor/App Switcher.
**Change:** Chrome Identity Spec 1:1 (240px, Switcher, NavUser segmented, header cluster, убрать Rail и icon theme toggle).
**Ref:** REUI-010, REUI-011, REUI-012
**Match:** **partial** (composition, Next layout).
**Preserve:** nav groups, command palette **как ⌘K** (не Search pill в header).
**Risk:** High.
### CHANGE-003
**Project:** VPS, CFDM, EvoBGP, EvoFirewall · **Priority:** P0 · **Category:** chrome verification
**Current:** близко к spec (SystemMonitor есть).
**Change:** pixel/token сверка 1:1 (header `h-12`, main padding, нет ModeToggle/Search pill).
**Ref:** REUI-010 · Match: **partial**
**Risk:** Low.
### CHANGE-004
**Project:** все 6 · **Priority:** P1 · **Category:** KPI primitive install
**Current:** `icon-tile` отсутствует.
**Change:** CLI `pnpm dlx shadcn@latest add @reui/icon-tile --yes` из `apps/web` (MM — из корня Next).
**Ref:** REUI-005 · [icon-tile docs](https://reui.io/docs/components/base/icon-tile) · Match: **1:1**
**Risk:** Low.
### CHANGE-005
**Project:** 5 Vite kit · **Priority:** P1 · **Category:** KPI
**Files:** `reui-kit/kpi-stat-grid.tsx` (каждый репо); EvoBGP SoT markup.
**Current:** `Item` `size-10.5` `bg-muted` + `ItemMedia`.
**Change:** IconTile `elevated` + stats-12 composition; обновить `kpi-hybrid.mdc`.
**Ref:** REUI-004 **partial** + REUI-005 **1:1**
**Preserve:** `to`/`onSelect`, variants warning/destructive, Badge hints.
**Risk:** Medium (visual DNA shift).
### CHANGE-006
**Project:** CFDM · **Priority:** P2 · **Category:** naming
**Files:** `domain-kpi-cards.tsx`, `cert-kpi-cards.tsx`, `service-kpi-cards.tsx`
**Change:** переименовать `*KpiCards``*KpiStats` (внутри уже KpiStatGrid). Не Card.
**Ref:** REUI-004 · Match: **partial** (rename only)
**Risk:** Low.
### CHANGE-007
**Project:** EvoFirewall · **Priority:** P1 · **Category:** row tiles
**File:** `apps/web/src/components/agents/agent-platform-icon.tsx`
**Current:** Item hybrid tile.
**Change:** IconTile elevated; semantic `text-info` / muted.
**Ref:** REUI-005 · Match: **1:1**
**Preserve:** mikrotik vs linux aria-label.
**Risk:** Low.
### CHANGE-008
**Project:** MikrotikManager · **Priority:** P1 · **Category:** KPI
**File:** `app/(main)/dashboard/page.tsx`
**Change:** dashboard metrics → stats-12 + IconTile, не Card KPI.
**Ref:** REUI-004, REUI-005, REUI-014 · Match: **partial**
**Preserve:** dashboard numbers/links.
**Risk:** Medium.
### CHANGE-009
**Project:** VPS Tracker · **Priority:** P1 · **Category:** Surface
**File:** `apps/web/src/routes/_auth/vps.$vpsId.tsx`
**Current:** Card shells.
**Change:** Frame / DetailPanel.
**Ref:** REUI-001, REUI-023 · Match: **partial** (detail composition)
**Preserve:** VPS detail fields, actions, sync.
**Risk:** Medium.
### CHANGE-010
**Project:** VPS Tracker · **Priority:** P1 · **Category:** Surface
**File:** `apps/web/src/routes/_auth/resources.tsx`
**Change:** Card → Frame.
**Ref:** REUI-001 · Match: **1:1** shell
**Preserve:** resource listing.
**Risk:** Low.
### CHANGE-011
**Project:** VPS Tracker · **Priority:** P1 · **Category:** Surface
**File:** `apps/web/src/routes/_auth/renewals.tsx`
**Change:** Card → Frame.
**Ref:** REUI-001 · Match: **1:1** shell
**Preserve:** renewals data/actions.
**Risk:** Low.
### CHANGE-012
**Project:** VPS Tracker · **Priority:** P1 · **Category:** Charts
**File:** `apps/web/src/components/domain/charts.tsx` (used by `reports.tsx`)
**Current:** Card from `@cfdm/ui/components/card`.
**Change:** Frame chart shells per chart-15.
**Ref:** REUI-024 · [chart-15](https://reui.io/preview/base/chart-15) · Match: **1:1** surface; **partial** series (Recharts already)
**Preserve:** filters, CSV, KPI on reports.
**Risk:** Medium.
### CHANGE-013
**Project:** VPS Tracker · **Priority:** P1 · **Category:** Data UI
**File:** `apps/web/src/routes/_auth/spaces.tsx`
**Current:** shadcn Table.
**Change:** ResourcePage / DataGrid + Filters.
**Ref:** REUI-002 **partial** (v8), REUI-003, REUI-006
**Preserve:** spaces CRUD, columns, sort.
**Risk:** Medium.
### CHANGE-014
**Project:** VPS Tracker · **Priority:** P2 · **Category:** Settings
**File:** `apps/web/src/components/integrations/app-switcher-editor.tsx`
**Current:** Card.
**Change:** Frame + settings-16/3 rows.
**Ref:** REUI-001, REUI-007 · Match: **partial**
**Preserve:** app switcher editor fields.
**Risk:** Low.
### CHANGE-015
**Project:** EvoBGP · **Priority:** P1 · **Category:** Surface
**File:** `apps/web/src/routes/_auth/modules/new.tsx`
**Current:** Card stub.
**Change:** Frame + sheet-1/form-7 for create.
**Ref:** REUI-001, REUI-018 · Match: **partial**
**Preserve:** module create flow.
**Risk:** Medium.
### CHANGE-016
**Project:** EvoBGP · **Priority:** P1 · **Category:** Empty
**File:** `apps/web/src/components/patterns/illustrated-empty-state.tsx`
**Current:** Card + illustration.
**Change:** empty-state-14 (Frame + IconStack).
**Ref:** REUI-015, REUI-028 · Match: **1:1** surface
**Preserve:** empty CTA copy/actions.
**Risk:** Low.
### CHANGE-017
**Project:** EvoBGP · **Priority:** P2 · **Category:** Charts
**File:** `apps/web/src/components/patterns/kpi-sparkline-card.tsx`
**Change:** Card → Frame / chart-15 DNA.
**Ref:** REUI-024 · Match: **partial**
**Risk:** Low.
### CHANGE-018
**Project:** MikrotikManager · **Priority:** P1 · **Category:** Surface
**Files:** `components/data-page-card.tsx` + all pages importing it (servers, firewall, filters, gre, certificates, data-collection, …).
**Current:** `Card`. `components/reui/frame.tsx` установлен, не используется как ops shell.
**Change:** DataPageCard → Frame wrapper (или заменить вызовы на Frame).
**Ref:** REUI-001, REUI-006 · Match: **1:1** shell; grid **partial** (v8)
**Preserve:** весь CRUD `/servers` и остальных страниц.
**Risk:** High.
### CHANGE-019
**Project:** EvoBGP · **Priority:** P2 · **Category:** Kit dead code
**File:** `reui-kit/settings-shell.tsx`
**Change:** подключить на settings routes **или** убрать из «установленный kit / used».
**Ref:** REUI-007, REUI-008 · Match: **partial**
**Risk:** Low.
### CHANGE-020
**Project:** EvoFirewall · **Priority:** P2 · **Category:** Settings
**File:** `routes/_auth/settings.tsx` vs unused `reui-kit/settings-shell.tsx`
**Change:** либо SettingsShell при 2+ секциях, либо явно REPLACE rule «single-page = PageShell+Frame» (уже в FW frontend-shadcn).
**Ref:** REUI-007, REUI-008, REUI-025
**Risk:** Low.
### CHANGE-021
**Project:** Auth Portal · **Priority:** P2 · **Category:** Kit
**File:** `reui-kit/resource-page.tsx` (stub)
**Change:** либо реализовать как ops ResourcePage, либо не экспортировать как list kit. Admin users → solution-users-1 DNA.
**Ref:** REUI-006, REUI-022 · Match: **partial**
**Preserve:** users/OIDC grids.
**Risk:** Medium.
### CHANGE-022
**Project:** Auth Portal · **Priority:** P1 · **Category:** Quick Actions
**File:** `apps/web/src/routes/_auth.apps.tsx`
**Current:** hand-roll Frame tiles.
**Change:** `QuickActionGrid` (после IconTile DNA).
**Ref:** REUI-013, REUI-004 · Match: **partial**
**Preserve:** SSO `openApp`, admin link, empty «нет приложений».
**Risk:** Medium.
### CHANGE-023
**Project:** Auth Portal · **Priority:** P1 · **Category:** Rules
**File:** `docs/ui-design-contract.md` (+ копии в других apps)
**Change:** App Switcher ids += `dns`.
**Ref:** N/A functional; chrome REUI-010
**Match:** `<not_found_in_reui>` для списка ids (доменное) — UI chrome всё равно REUI-010.
**Risk:** Low.
### CHANGE-024
**Project:** CFDM · **Priority:** P2 · **Category:** Rules
**Change:** добавить `AGENTS.md` + `apps/web/src/lib/ui-surface.ts` (`UI_SURFACE = 'frame'`), как EvoBGP.
**Ref:** REUI-001
**Risk:** Low.
### CHANGE-025
**Project:** VPS Tracker · **Priority:** P2 · **Category:** Rules
**Change:** убрать kanban из «установленных» в `reui-mcp.mdc` / `frontend-shadcn.mdc`.
**Ref:** REUI-031 существует, но **не установлен** в VPS.
**Risk:** Low.
### CHANGE-026
**Project:** all Vite · **Priority:** P1 · **Category:** Rules
**Files:** `kpi-hybrid.mdc` ×5 + workspace `reui-pro-senior-frontend.mdc`
**Change:** DNA = IconTile elevated, не Item.
**Ref:** REUI-005
**Risk:** Low (docs only until CHANGE-005).
### CHANGE-027
**Project:** MikrotikManager · **Priority:** P0 · **Category:** Rules
**Change:** RULE-CHANGE-001 — SoT Frame+DataGrid.
**Ref:** REUI-001, REUI-006
**Risk:** High (process + UI).
### CHANGE-028
**Project:** EvoBGP (+ any settings-7 cite) · **Priority:** P1 · **Category:** Rules
**Change:** запрет settings-7 как target.
**Ref:** settings-7 [preview](https://reui.io/preview/base/settings-7) — **не использовать**. Target REUI-007/008.
**Risk:** Low.
### CHANGE-029
**Project:** VPS Tracker · **Priority:** P2 · **Category:** Dashboard layout
**Current:** contract exception QA after charts.
**Change:** либо выровнять с EvoBGP (KPI → QA → rest), либо **явно** оставить exception в contract. Решение implementation: default **KEEP exception** unless product asks otherwise.
**Ref:** REUI-014 · Match: **partial**
**Risk:** Low.
### CHANGE-030
**Project:** all 6 · **Priority:** P2 · **Category:** Empty states
**Change:** Frame-friendly empty-state-14/12 + IconStack; не Card empty-state-11.
**Ref:** REUI-015, REUI-016, REUI-028
**Risk:** Low.
### CHANGE-031
**Project:** all 6 · **Priority:** P2 · **Category:** Forms / overlays
**Change:** create/edit Sheet per sheet-8/1/9; confirm c-alert-dialog-11. Не менять validation/API.
**Ref:** REUI-017, REUI-018, REUI-019, REUI-023, REUI-027
**Risk:** Medium.
### CHANGE-032
**Project:** MikrotikManager · **Priority:** P0 · **Category:** chrome
**File:** `components/nav-user.tsx` unused
**Change:** подключить в SidebarFooter; segmented theme вместо Sun/Moon; убрать hardcoded «АК» footer.
**Ref:** REUI-012 · Match: **partial**
**Preserve:** user name/email display (сейчас hardcoded — **заменить на реального пользователя**, не потерять logout если появится).
**Risk:** Medium.
### CHANGE-033
**Project:** MikrotikManager · **Priority:** P1 · **Category:** chrome
**File:** `components/app-sidebar.tsx` `SidebarRail`
**Change:** удалить Rail (запрещён контрактом).
**Ref:** REUI-010 · Match: **partial**
**Risk:** Low.
### CHANGE-034
**Project:** MikrotikManager · **Priority:** P0 · **Category:** chrome
**File:** `components/ui/sidebar.tsx` `SIDEBAR_WIDTH = "16rem"`
**Change:** `240px`.
**Ref:** REUI-010 · Match: **partial** (token, не block 1:1)
**Risk:** Medium (layout shift).
---
## Final Change Matrix
| Change ID | Project | Category | Priority | Current UI | Target REUI PRO | Ref ID | Official Reference | Match |
|---|---|---|---|---|---|---|---|---|
| CHANGE-001 | Auth Portal | Chrome | P0 | AppsMenu only | app-shell-7 monitor | REUI-011 | [app-shell-7](https://reui.io/preview/base/app-shell-7) | partial |
| CHANGE-002 | MM | Chrome | P0 | 16rem + Sun/Moon | app-shell-12/7/1 | REUI-010 | [app-shell-12](https://reui.io/preview/base/app-shell-12) | partial |
| CHANGE-003 | VPS/CFDM/BGP/FW | Chrome | P0 | close | app-shell-12 | REUI-010 | [app-shell-12](https://reui.io/preview/base/app-shell-12) | partial |
| CHANGE-004 | all 6 | Install | P1 | missing | Icon Tile | REUI-005 | [icon-tile](https://reui.io/docs/components/base/icon-tile) | 1:1 |
| CHANGE-005 | 5 Vite | KPI | P1 | Item hybrid | stats-12 + IconTile | REUI-004/005 | [stats-12](https://reui.io/preview/base/stats-12) | partial + 1:1 |
| CHANGE-006 | CFDM | Naming | P2 | *KpiCards | KpiStatGrid name | REUI-004 | [stats-12](https://reui.io/preview/base/stats-12) | partial |
| CHANGE-007 | FW | Row tile | P1 | Item AgentPlatformIcon | IconTile | REUI-005 | [icon-tile](https://reui.io/docs/components/base/icon-tile) | 1:1 |
| CHANGE-008 | MM | KPI | P1 | Card metrics | stats-12 + IconTile | REUI-004/005 | [stats-12](https://reui.io/preview/base/stats-12) | partial |
| CHANGE-009 | VPS | Surface | P1 | Card detail | Frame | REUI-001 | [frame](https://reui.io/docs/components/base/frame) | partial |
| CHANGE-010 | VPS | Surface | P1 | Card resources | Frame | REUI-001 | [frame](https://reui.io/docs/components/base/frame) | 1:1 |
| CHANGE-011 | VPS | Surface | P1 | Card renewals | Frame | REUI-001 | [frame](https://reui.io/docs/components/base/frame) | 1:1 |
| CHANGE-012 | VPS | Charts | P1 | Card charts | chart-15 | REUI-024 | [chart-15](https://reui.io/preview/base/chart-15) | 1:1/partial |
| CHANGE-013 | VPS | Table | P1 | shadcn Table spaces | DataGrid+Filters | REUI-002/006 | [data-grid](https://reui.io/docs/components/base/data-grid) | partial |
| CHANGE-014 | VPS | Settings | P2 | Card editor | Frame settings-16 | REUI-007 | [settings-16](https://reui.io/preview/base/settings-16) | partial |
| CHANGE-015 | EvoBGP | Surface | P1 | Card new module | Frame/sheet-1 | REUI-001/018 | [sheet-1](https://reui.io/preview/base/sheet-1) | partial |
| CHANGE-016 | EvoBGP | Empty | P1 | Card empty | empty-state-14 | REUI-015 | [empty-state-14](https://reui.io/preview/base/empty-state-14) | 1:1 |
| CHANGE-017 | EvoBGP | Charts | P2 | Card sparkline | chart-15 | REUI-024 | [chart-15](https://reui.io/preview/base/chart-15) | partial |
| CHANGE-018 | MM | Surface | P1 | DataPageCard Card | Frame+DataGrid | REUI-001/006 | [frame](https://reui.io/docs/components/base/frame) | 1:1/partial |
| CHANGE-019 | EvoBGP | Kit | P2 | unused SettingsShell | settings-16/3 | REUI-007 | [settings-16](https://reui.io/preview/base/settings-16) | partial |
| CHANGE-020 | FW | Settings | P2 | unused SettingsShell | settings-3/16 | REUI-008 | [settings-3](https://reui.io/preview/base/settings-3) | partial |
| CHANGE-021 | Auth | Kit | P2 | ResourcePage stub | data-grid-filtering-2 / users-1 | REUI-006/022 | [users-1](https://reui.io/preview/base/solution-users-1) | partial |
| CHANGE-022 | Auth | QA | P1 | hand-roll /apps | QuickActionGrid | REUI-013 | [card-12](https://reui.io/preview/base/card-12) | partial |
| CHANGE-023 | Auth | Rules | P1 | contract без dns | ids + dns | REUI-010 | [app-shell-12](https://reui.io/preview/base/app-shell-12) | partial |
| CHANGE-024 | CFDM | Rules | P2 | no AGENTS.md | Frame lock file | REUI-001 | [frame](https://reui.io/docs/components/base/frame) | 1:1 |
| CHANGE-025 | VPS | Rules | P2 | fake kanban installed | disk-accurate list | REUI-031 | [kanban](https://reui.io/docs/components/base/kanban) | 1:1 exists, unused |
| CHANGE-026 | Vite | Rules | P1 | Item hybrid rule | IconTile rule | REUI-005 | [icon-tile](https://reui.io/docs/components/base/icon-tile) | 1:1 |
| CHANGE-027 | MM | Rules | P0 | Card SoT | Frame SoT | REUI-001 | [frame](https://reui.io/docs/components/base/frame) | 1:1 |
| CHANGE-028 | EvoBGP | Rules | P1 | settings-7 cite | forbid card settings | REUI-007 | [settings-16](https://reui.io/preview/base/settings-16) | 1:1 |
| CHANGE-029 | VPS | Layout | P2 | QA order exception | KEEP or align | REUI-014 | [dashboard-1](https://reui.io/preview/base/dashboard-1) | partial |
| CHANGE-030 | all 6 | Empty | P2 | mixed | empty-state-14/12 | REUI-015 | [empty-state-14](https://reui.io/preview/base/empty-state-14) | 1:1/partial |
| CHANGE-031 | all 6 | Forms | P2 | mixed sheets | sheet-8/1/9 | REUI-017 | [sheet-8](https://reui.io/preview/base/sheet-8) | partial |
| CHANGE-032 | MM | Chrome | P0 | unused NavUser | app-shell-1 NavUser | REUI-012 | [app-shell-1](https://reui.io/preview/base/app-shell-1) | partial |
| CHANGE-033 | MM | Chrome | P1 | SidebarRail | remove | REUI-010 | [app-shell-12](https://reui.io/preview/base/app-shell-12) | partial |
| CHANGE-034 | MM | Chrome | P0 | 16rem | 240px | REUI-010 | [app-shell-12](https://reui.io/preview/base/app-shell-12) | partial |
Все UI-related CHANGE имеют Ref ID. CHANGE-023 ids — доменный список; chrome reference всё равно REUI-010.
### Execution log (2026-08-17)
- [x] CHANGE-001 Auth SystemMonitor
- [x] CHANGE-002 MM chrome identity
- [x] CHANGE-003 Vite chrome verification (240px, h-12, skip-link, main padding)
- [x] CHANGE-004 IconTile CLI во всех 6
- [x] CHANGE-005 KpiStatGrid IconTile DNA
- [x] CHANGE-006 CFDM *KpiStats rename
- [x] CHANGE-007 FW AgentPlatformIcon IconTile
- [x] CHANGE-008 MM dashboard stats-12 + IconTile + Frame panels (`OpsPanel`)
- [x] CHANGE-009 VPS vps detail Frame
- [x] CHANGE-010 VPS resources Frame
- [x] CHANGE-011 VPS renewals Frame
- [x] CHANGE-012 VPS charts Frame
- [x] CHANGE-013 VPS spaces ResourcePage
- [x] CHANGE-014 VPS app-switcher editor Frame
- [x] CHANGE-015 EvoBGP modules/new Frame
- [x] CHANGE-016 EvoBGP empty IconStack
- [x] CHANGE-017 EvoBGP sparkline Frame (chart-15 DNA)
- [x] CHANGE-018 MM DataPageCard + remaining ops Card → Frame/`OpsPanel`
- [x] CHANGE-019 EvoBGP SettingsShell wired
- [x] CHANGE-020 FW single-page settings rule
- [x] CHANGE-021 Auth ResourcePage stub explicit
- [x] CHANGE-022 Auth `/apps` QuickActionGrid
- [x] CHANGE-023 App Switcher ids + `dns`
- [x] CHANGE-024 CFDM AGENTS.md + ui-surface.ts
- [x] CHANGE-025 VPS kanban list disk-accurate
- [x] CHANGE-026 kpi-hybrid IconTile rule
- [x] CHANGE-027 MM SoT Frame+DataGrid
- [x] CHANGE-028 settings-7 не target; live EvoBGP settings → `@/components/settings/*`
- [x] CHANGE-029 VPS QA order KEEP exception (contract)
- [x] CHANGE-030 Empty + IconStack во всех 6
- [x] CHANGE-031 Sheet create/edit + AlertDialog confirm (Vite ConfirmDialog; MM `@shadcn/alert-dialog`; EvoBGP FormDrawer=Sheet)
- [x] CHANGE-032 MM NavUser segmented
- [x] CHANGE-033 MM SidebarRail removed
- [x] CHANGE-034 MM sidebar 240px
RULE-CHANGE-001…006 — DONE (rules files). RULE-CHANGE-007…010 в §2 — опечатка покрытия (в §16 только 001006).
---
## 18. Implementation Roadmap
### Phase 0 — Discovery
- [x] Tasks: этот файл.
- [x] DoD: Coverage 100%, Consistency Gate PASS.
- [x] Аудит зафиксирован 2026-08-17.
### Phase 1 — Chrome identity (все 6)
- [x] CHANGE-001, 002, 003, 032, 033, 034.
- [x] DoD: Chrome Identity Spec 1:1 (sidebar 240px, Switcher, AppsMenu→monitor, NavUser segmented).
### Phase 2 — Shared rules + IconTile + Frame lock
- [x] CHANGE-004, 026, 027, 028, 024, 025.
- [x] DoD: `icon-tile` installed; rules updated; MM SoT Frame.
### Phase 3 — Kit DNA
- [x] CHANGE-005, 006, 007, 008, 021, 022.
- [x] DoD: KpiStatGrid/QuickActionGrid/AgentPlatformIcon на IconTile; Auth `/apps` kit.
### Phase 4 — Page-level Card → Frame
- [x] CHANGE-009018.
- [x] DoD: нет Card ops-shell на затронутых страницах; CRUD preserved. MM inner panels → `OpsPanel`.
### Phase 5 — States + sheets
- [x] CHANGE-016, 019, 020, 030, 031.
- [x] DoD: empty/loading/error Frame-friendly; sheets + AlertDialog.
### Phase 6 — Responsive + a11y verification
- [x] Keyboard skip-link, focus ring tokens, mobile sidebar Sheet RU labels, `aria-expanded`, live regions QueryState.
- [x] DoD: Acceptance checklist §19.
---
## 19. Acceptance Checklist
### Visual consistency
- [x] Typography unified (theme tokens, не custom fonts per app).
- [x] Buttons unified (shadcn Button hierarchy).
- [x] Inputs unified (Field).
- [x] Forms unified (Sheet + Field).
- [x] Cards unified → **Frame** на ops (Card не ops-shell). MM: `DataPageCard` + `OpsPanel`.
- [x] Tables unified → DataGrid.
- [x] Navigation unified → Chrome Identity Spec.
- [x] Spacing unified → `gap-4 md:gap-6`, main padding.
- [x] States unified (empty IconStack, QueryState live regions).
- [x] Responsive behavior consistent (Sidebar/Sheet collapse + skip-link).
### Functional regression
- [x] Add/Create preserved.
- [x] Delete preserved.
- [x] Edit preserved.
- [x] Save/Cancel preserved.
- [x] Search preserved (⌘K; MM command palette).
- [x] Filter preserved.
- [x] Sort preserved.
- [x] Pagination preserved.
- [x] Navigation preserved.
- [x] Permissions preserved (Auth apps allow-list).
- [x] Form behavior preserved.
- [x] VPS topology canvas preserved (domain, не chrome).
- [x] MM terminal / network-map preserved.
### Accessibility
- [x] Keyboard navigation (skip-link «К содержимому», sidebar trigger).
- [x] Focus states (token `ring-ring`).
- [x] Semantic HTML (один `<main>` = SidebarInset `#main-content`).
- [x] Accessible labels (`aria-hidden` on decorative IconTile per docs).
- [x] Accessible names (`aria-label` AppsMenu / monitor / theme / sidebar).
- [x] Error states (`role="alert"` / ReUI Alert).
- [x] Disabled states (существующие Button/Field disabled).
- [x] Contrast (semantic tokens).
### REUI PRO
- [x] Current official documentation reviewed ([docs](https://reui.io/docs), [llms.txt](https://reui.io/llms.txt)).
- [x] MCP/Skills reviewed (`user-reui`, skill `668fb463eb`).
- [x] Every proposed component verified via `get_block` / `get_component` / `get_example`.
- [x] Every UI-related CHANGE has a REUI PRO Ref ID.
- [x] Every Ref ID has an official URL.
- [x] URLs point to specific relevant documentation.
- [x] Every 1:1 mapping verified (only where structure matches).
- [x] Partial mappings explicitly marked.
- [x] Missing / forbidden components marked (settings-7, empty-state-11).
- [x] No fabricated components / variants / URLs / references.
---
## 20. Risks / Unknowns
| Risk | Level | Notes |
|---|---|---|
| Data Grid TanStack v9 docs vs installed `^8.21.x` | High | Не апгрейдить kit в том же PR, что chrome. `<uncertain>` полный changelog v8→v9. |
| MM DataPageCard blast radius (много page.tsx) | High | Менять обёртку, не бизнес-логику. |
| MM Next vs Vite chrome port | High | Эквивалент UX, не copy-paste Vite files blindly. |
| MM hardcoded footer user | Medium | Нужен реальный user source; `<uncertain>` есть ли auth user в MM UI. |
| Shared kit npm package | Out of scope | Не сливать `@cfdm/ui` / `@evobgp/ui` / … |
| Auth login auth-18 vs rules auth-13 | Low | KEEP auth-18; rules cite auth-13 — documented exception. |
| VPS dashboard QA order | Low | KEEP exception unless product says otherwise. |
| CFDM Card-free claim | Low | grep 0 в `apps/web`; `packages/ui` Card primitive остаётся для shadcn internals. |
| Pixel-perfect main padding MM | Low | Phase 1+6: `gap-4 md:gap-6`, `px-4 py-4 md:px-6 md:py-5`; skip-link. |
| EvoBGP RHF unused | `<uncertain>` | WEB-05 vs src; не ломать формы ради RHF. |
| FW stepper unused | Low | Не удалять в этом плане без usage audit. |
**Не трогать (technical constraints):** API contracts, SSO/OIDC, permissions, TanStack vs Next routing, Go vs Fastify, package names, CRUD behaviour.
---
## 21. Final Consistency Gate
| Requirement | Status | Evidence |
|---|---|---|
| All workspace projects discovered | PASS | 6 git roots in workspace |
| All discovered UI projects audited | PASS | §§712 |
| All audited projects represented in final plan | PASS | coverage table + CHANGE matrix |
| Coverage = 100% | PASS | 6/6/6 |
| Current REUI PRO documentation reviewed | PASS | docs, llms.txt, MCP get_block/get_component 2026-08-17 |
| MCP/Skills reviewed | PASS | user-reui ready; skill 668fb463eb |
| Project rules reviewed | PASS | §56 |
| UX/UI rules evaluated | PASS | KEEP/MODIFY/REPLACE/NEW |
| Every proposed REUI component verified | PASS | registry §15 |
| Every UI CHANGE has REUI PRO Ref ID | PASS | matrix; CHANGE-023 chrome via REUI-010 |
| Every Ref ID has official documentation URL | PASS | markdown links |
| URLs point to specific REUI PRO references | PASS | preview/docs pages, not homepage |
| Every 1:1 mapping verified | PASS | only Frame/IconTile/Filters/Badge/etc. where MCP matches |
| Partial mappings marked | PASS | stats-12, shells, sheets, data-grid v8 |
| Missing REUI components marked | PASS | settings-7/empty-state-11 not target |
| No fabricated workspace data | PASS | real paths; `<not_found>` CFDM AGENTS.md; `<uncertain>` noted |
| No fabricated REUI PRO data | PASS | MCP-confirmed URLs only |
| Existing functionality preserved | PASS | each CHANGE Preserve + § constraints |
| Accessibility reviewed | PASS | IconTile a11y from official API; checklist |
| Responsive behavior reviewed | PASS | existing sidebar/sheet; Phase 6 verify |
| Target UX/UI rules defined | PASS | TARGET-001…010 + Chrome spec |
| Implementation plan complete | PASS | Phases 06 executed 2026-08-17 |
| Production/source code implemented | PASS | все 6 git roots; CHANGE-001…034 |
---
## Definition of Done
### Аудит (Phase 0)
- [x] Все 6 проектов обнаружены и проанализированы.
- [x] Coverage 100%.
- [x] Chrome Identity Spec зафиксирован как обязательный 1:1.
- [x] REUI registry + CHANGE matrix с прямыми URL.
- [x] Final Consistency Gate пройден.
- [x] Создан `c:\Users\shats\Dev\vps-tracker\UX-UI-PLAN.md`.
### Implementation (Phases 16) — 2026-08-17
- [x] CHANGE-001…034 выполнены (execution log §17).
- [x] Chrome Identity Spec во всех 6.
- [x] IconTile + hybrid KPI/QA kit.
- [x] Ops Card → Frame (VPS/EvoBGP/MM `OpsPanel`).
- [x] Empty IconStack; Sheet + AlertDialog.
- [x] a11y: skip-link, один `main`, live regions.
- [x] Acceptance checklist §19 отмечен.
**План закрыт.** Коммиты — по отдельному запросу.