Files
vps-tracker/UX-UI-PLAN.md
T
DenozordecandCursor 55014105f5
Docker / build (push) Failing after 22s
fix(ui): выровнять chrome Frame KPI и доступность
Унифицировать оболочку ops-экранов, IconTile, skip-link и контракт UI.

Co-authored-by: Cursor <[email protected]>
2026-08-17 15:36:53 +07:00

946 lines
57 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 отмечен.
**План закрыт.** Коммиты — по отдельному запросу.