Перейти к содержанию

UI-система SKUARO

Статус: эталон frontend-прототипа

Версия: 0.4

Обновлено: 2026-08-26.

Назначение

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

Эталон визуального языка системы — экран «Сегодня». Он остаётся продуктовым модулем /today, а не главным экраном после входа. Новые внутренние экраны переиспользуют его токены, плотность и компоненты внутри общего AppShell. Изменение визуального языка начинается с обновления этого документа, Storybook и эталонных снимков.

Визуальный характер

  • Холодная светлая или тёмная рабочая область для таблиц и длинной ежедневной работы.
  • Графитовая навигация сохраняет узнаваемость SKUARO и отделяет структуру продукта от данных.
  • Кобальтовый используется для главного действия, активного состояния и фокуса.
  • Зелёный используется только для подтверждённого успеха, оранжевый обозначает внимание, красный — ошибку или просрочку.
  • Карточки применяются только для смысловой группировки; основа desktop-интерфейса — плоские списки и таблицы.
  • Технологичность создаётся плотностью, точной сеткой, табличными числами и ясной иерархией, а не декоративными эффектами.

Источники паттернов

Мы не копируем чужие экраны целиком. Для SKUARO зафиксированы конкретные заимствуемые принципы:

Источник Берём Не берём
Linear плотные списки, приоритет важного, быстрые действия без ухода со страницы терминологию и модель управления разработкой
Attio строку как запись, настраиваемые таблицы, переход из списка в контекст клиента универсальную CRM-модель и избыток атрибутов
Stripe чёткую иерархию, семантические статусы, пояснение следующего действия финансовую визуальную идентичность
Mobbin Web Apps поиск конкретных SaaS-сценариев при проектировании нового экрана буквальное копирование найденных решений
shadcn/ui открытый код компонентов, размещённый внутри проекта внешний закрытый слой, ограничивающий стилизацию
Radix Primitives доступное поведение сложных контролов и управление фокусом готовый визуальный стиль
docs/ui-agent/results/UIREF-2026-08-26-full-ui-redesign/revision-1/ принятое направление SKUARO Control Surface, плотность, queue/detail и responsive data composition standalone prototype, непроверенный logo asset и изменения Product contracts

Цветовые токены

Источником истины для кода является packages/ui/src/styles/globals.css.

Токен Значение Назначение
--graphite-950 #111720 основная навигация
--canvas #F4F6F8 фон светлой рабочей области
--surface #FFFFFF таблицы, поля, панели
--surface-subtle #EEF2F6 заголовки таблиц, тихие области
--text #172033 основной текст
--text-muted #526176 пояснения и вторичная информация
--text-subtle #5F6D81 тихие подписи на светлых secondary surfaces
--border #D7DEE8 стандартные разделители
--primary #2556D8 основное действие, active и focus
--attention #A84C08 действие требуется сегодня
--danger #B42318 просрочка и ошибка
--danger-foreground #FFFFFF текст опасной кнопки
--success #067647 завершённое действие

Тёмный режим использует те же semantic roles: canvas #0D1117, surface #151B24, surface-subtle #1B2430, text #F1F5F9, muted #AEB9C8, subtle #8E9BAD, border #334052, primary #7FA2FF, danger #FF938D, danger-foreground #27100F. Режим выбирается системной настройкой prefers-color-scheme; отдельные страницы не переключают тему самостоятельно.

Исполняемый browser-тест tests/visual/contrast.spec.ts проверяет фактические computed foreground/background пары primary и danger buttons, checked controls, status badges, административного status message и 10 px sidebar label в light и dark mode. Для normal text применяется порог WCAG AA 4.5:1; текущий набор пар проходит этот порог в обоих режимах.

Правила:

  • цвет всегда дублируется текстом или иконкой;
  • зелёный не используется для нейтрального декора;
  • оранжевый не обозначает ошибку;
  • красный не используется для привлечения внимания к обычному CTA;
  • фон строки меняется только при выборе или фокусе.

Типографика

Базовый стек: Inter, затем системные sans-serif. Внешняя загрузка шрифта для прототипа не нужна.

Роль Размер / интерлиньяж Начертание
Заголовок экрана 32 / 38 px, mobile 28 / 34 px 700
Заголовок раздела 18 / 24 px 700
Основной текст 14 / 20 px 400–500
Название клиента / действие 14 / 20 px 600–700
Подпись 12 / 16 px 400–600
Табличный заголовок 11 / 16 px 600, uppercase

Текст интерфейса — на русском. Код и идентификаторы — на английском. Формулировки короткие и объясняют действие: «Добавить обращение», «Следующий шаг», «Просрочено», «Позже».

Сетка и геометрия

  • Базовый шаг отступов: 4 px.
  • Рабочие значения: 4, 8, 12, 16, 20, 24, 32, 40 px.
  • Desktop sidebar: 188 px; desktop topbar: 56 px.
  • Максимальная ширина рабочего контента: 1540 px.
  • Высота обычного контрола: 40 px; основного мобильного действия: не менее 44 px.
  • Радиусы: 8 px для контролов и 12 px для панелей; большие «пузырьковые» карточки не применяются.
  • Тень используется только для плавающих слоёв: dropdown, dialog, side panel.
  • Табличная строка desktop: 74 px; информация умещается в два текстовых уровня.

Адаптивность

Подход desktop-first, но ключевой сценарий полностью доступен на телефоне.

Desktop, от 1024 px

  • постоянная графитовая боковая навигация;
  • клиентская очередь представлена таблицей;
  • поиск и фильтр по статусу находятся в одной строке;
  • карточка клиента открывается в боковой панели без потери списка.

Mobile, до 1023 px

  • компактная верхняя панель и modal drawer навигации с focus containment;
  • основное действие «Добавить обращение» остаётся над первым скроллом;
  • таблица преобразуется в вертикальные клиентские записи без горизонтального скролла;
  • следующий шаг и статус видны до открытия карточки;
  • форма и карточка клиента занимают доступную ширину, основные действия закреплены снизу.

Области рабочего экрана

Защищённая часть приложения использует единый словарь зон. В постановке UI-задачи достаточно указать идентификатор зоны и страницу.

Зона Содержимое
S1 основная навигация по разделам и доступным модулям
S2 текущая организация или платформенный контекст, переключатель контекста
S3 помощь, документация, аккаунт и выход
P1 заголовок, описание и breadcrumbs
P2 действия текущей страницы
P3 сводка, статусы и ключевые показатели
P4 поиск, фильтры, сортировка и вид
P5 основная рабочая область
P6 счётчики, порядок, пагинация и метаданные
O1 контекстная боковая панель
O2 dialog отдельного действия
O3 уведомления, подтверждения и ошибки

На desktop зоны S1–S3 образуют постоянную боковую панель 188 px; P1–P6 находятся в рабочей области. На mobile используются компактная верхняя панель и modal drawer, зоны P1–P6 идут вертикально, O1 занимает весь экран. В коде устойчивые контейнеры получают data-ui-zone, например data-ui-zone="P5"; это служебный контракт для обсуждения и тестов, а не CSS-селектор оформления.

Регистрация и доступ

  • На desktop auth-страницы используют графитовую смысловую панель и отдельную светлую область формы; на mobile остаются компактная шапка и полноширинная форма.
  • Поля имеют постоянные label над контролом, ошибку под контролом и корректный autocomplete; пароль можно показать и скрыть без запрета вставки.
  • Экран регистрации заранее объясняет порядок аккаунт -> подтверждение email -> организация.
  • До подключения backend страницы явно помечены как деморежим и запрещают реальные персональные данные; успешное состояние не изображает отправку письма или выполненную авторизацию.
  • Восстановление доступа отвечает нейтрально и не повторяет введённый email, чтобы не раскрывать наличие аккаунта.

Личный и административный кабинеты

  • /home, /today, /settings/*, /organization/settings/* и /admin/* используют общий AppShell; отдельные глобальные оболочки для кабинетов больше не являются целевым паттерном.
  • /settings/profile и /settings/security содержат только данные и безопасность собственной учётной записи.
  • Подключённые модули, тариф и права сотрудников находятся в /organization/settings/*, а не в личном профиле.
  • /admin всегда показывает текущую платформенную роль и контекст. «Карта проекта» остаётся административным разделом, но не является универсальной главной после входа.
  • Главная /home меняет сводки и действия по эффективным capabilities; при сочетании платформенной роли и membership показывает явный переключатель «Платформа / Организация».
  • «Активный прототип» и «production готов» являются разными состояниями и не подменяют друг друга.
  • Административные таблицы на mobile преобразуются в карточки без горизонтального скролла.
  • Опасные действия над пользователями открываются в отдельном dialog, объясняют последствия и остаются демонстрационными до подключения backend.

Компоненты и состояния

Переиспользуемые компоненты находятся в packages/ui/src/components; feature-композиции могут оставаться внутри приложения. Состояния общих компонентов сохраняются в Storybook, а продуктовых экранов — в browser- и visual-тестах.

Компонент Обязательные состояния
Button primary, secondary, ghost, danger, disabled, loading, icon, sizes
TextField / SearchField default, hint, error, disabled, leading icon
Checkbox unchecked, checked, indeterminate, disabled
SelectField placeholder, selected, disabled, open/focus через Radix
StatusBadge neutral, success, attention, danger, without dot
Avatar initials fallback, small, medium, large
SummaryStrip normal values, zero values, mobile stack
SidebarNav / MobileNav active item, disabled item, dynamic badge count, desktop/mobile
ClientQueue default, selected rows, empty, desktop/mobile
CreateRequestDialog closed, open, focused first field
ClientDetailPanel closed, open, desktop side panel, mobile full-width
EmptyState no filtered results, zero inbox
AuthShell и auth-формы registration, login, recovery, reset, check email, validation, demo success, desktop/mobile
AppShell / PageFrame S1–S3, P1–P6, organization/platform context, desktop/mobile
ContextSwitcher organization, platform, single-context, loading, denied
HomePage owner, admin, member, viewer, platform_admin, super_admin, loading, empty, error
Административные разделы project map, administrators, users, organizations, protected account, desktop/mobile

Доступность

  • Все интерактивные элементы доступны с клавиатуры и имеют видимый focus ring.
  • Checkbox, Select, Dialog, Dropdown Menu, Avatar и Tooltip используют Radix Primitives.
  • Иконка без текста всегда получает доступное имя через aria-label.
  • Декоративные иконки скрываются через aria-hidden.
  • Диалоги имеют Title и Description, а формы связывают label, hint и error.
  • Элементы без реализованного действия показываются недоступными и не используют фиктивные ссылки.
  • Анимации почти не используются и отключаются при prefers-reduced-motion.

Storybook

Запуск:

npm run storybook

Проверка статической сборки:

npm run build:storybook

Storybook является каталогом состояний компонентов, а не отдельным источником дизайн-токенов.

Визуальные эталоны

Playwright хранит снимки экрана «Сегодня», формы обращения и карточки клиента в:

tests/visual/today.spec.ts-snapshots/

Снимки регистрации, входа и восстановления доступа находятся в:

tests/visual/auth.spec.ts-snapshots/

Снимки карты проекта, пользователей и личного кабинета находятся в:

tests/visual/admin.spec.ts-snapshots/

Проверка:

npm run test:visual

Осознанное обновление после принятого изменения UI:

npm run test:visual:update

Эталоны создаются отдельно для desktop Chromium и mobile Chromium. Результаты могут отличаться между ОС и версиями браузера, поэтому baseline обновляется в контролируемом окружении и только после визуального просмотра.

Правило изменения UI

Внешний UI/UX-агент получает визуальную задачу через docs/ui-agent/TASK.md, изучает developer docs и сохраняет reference package в docs/ui-agent/results/. Reference становится Product UI только после отдельной внутренней реализации и проверки.

  1. Уточнить пользовательский сценарий и состояние данных.
  2. Переиспользовать существующий компонент или добавить новый в packages/ui.
  3. Добавить все состояния компонента в Storybook.
  4. Изменить эталонный экран «Сегодня», если затронут общий паттерн.
  5. Запустить lint, typecheck, обе сборки и Playwright.
  6. Просмотреть diff снимков и обновить baseline только для осознанного изменения.

Пока не зафиксировано

  • финальный логотип и брендовые иллюстрации;
  • английская локализация;
  • сложные графики и отчёты;
  • визуальный язык командной работы и ролей;
  • production-интеграция компонентов с backend и реальными данными.
  • production-auth, email-провайдер и серверная anti-abuse защита.