Andrey Epifancev d2b4ff2018 feat: skill aura-design — дизайн-система AURA для личных проектов (#17)
Скилл переносится из ~/.claude/skills/aura-design в репозиторий обвязки:
SKILL.md, справочники reference/ и набор kit/ (токены, base.css, компоненты
React, оболочка AppShell, тест токенов, test-setup, примеры входа).
install.sh ставит его в ~/.claude/skills/aura-design, --check его видит.
tests/test-aura-design.sh проверяет структуру и инварианты набора.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 12:10:34 +04:00

80 lines
8.7 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.

# AURA — раскладка и UX
## Оболочка (`AppShell`)
- Слева **закреплённая боковая панель** 240 px (`position: sticky; height: 100dvh`), прокрутка — у окна. Сверху
вниз: название приложения (16/24 700) и кнопка свёртки → `top` (выбор проекта/аккаунта) → разделы (иконка 20 +
подпись, высота 40, активный — фон selected и зелёный текст, `aria-current="page"`) → растяжка → `bottom` (состояние
данных, синхронизация) → подвал: `ThemeSwitch` и меню «Ещё» (открывается вверх).
- Свёрнутая панель 64 px: только иконки, подписи — `visually-hidden` + `title`; состояние в `localStorage`.
- **Телефон (<640 px)**: вместо панели закреплённая строка 56 px: «Меню» (гамбургер), название, `topbarEnd`.
Панель выезжает слева (`min(300px, 85vw)`) поверх подложки 45%; фокус — на первый раздел, Esc и щелчок по подложке
закрывают, фокус возвращается на «Меню». Нижней панели вкладок нет.
- Верхней шапки во всю ширину нет: общие действия (тема, синхронизация, аккаунт) живут в панели.
- Липкие элементы страниц: `top: var(--topbar-h, 0)`.
## Страница
- `main.page`: до 1440 px по центру, поля 24/16; `wide` — во всю ширину (доски, графики, широкие таблицы).
- `.page` — контейнер (`container: page/inline-size`): пороги раскладки внутри страниц — **`@container page`**, не
`@media`. Рядом панель, поэтому ширина окна врёт. `@media (max-width: 639px)` — только для оболочки.
- Сверху `PageHeader`: заголовок, подзаголовок-сводка вторичным («12 подписок · 3 просрочено»), справа одна
`primary` («Добавить …») и при необходимости `secondary`/меню «⋯».
## Шаблоны экранов
- **Список/таблица:** под заголовком `.ui-toolbar` — `SearchInput`, `Segmented` для 2–3 состояний («Все /
Активные / Просроченные»), фильтры-списки: один — кнопка с его именем («Категория (N)»), несколько — одна кнопка
«Фильтры (N)» → панель со списками. Выбранные значения — `Chip`-ами в `.ui-chips` с «Сбросить». Не выкладывать
шесть селектов в ряд. Таблица — `Panel padding="none"` +
`.ui-table`, шапка липнет, строка 44, щелчок по строке открывает карточку (`tr.is-clickable` + ссылка в первой
ячейке для клавиатуры). На узкой странице — горизонтальная прокрутка внутри панели, не карточки; ширину, уже
которой колонки не сжимаются, задай `--table-min` на таблице.
- **Действия строки:** частые (1–2: «Изменить», «Удалить») — `IconButton` с `label` «Удалить: <название>» в
`td.actions`. Меню «⋯» в строке таблицы не ставить: обёртка таблицы обрезает выпадашку. Удаление — через `Confirm`.
- **Редкие действия** (экспорт, импорт, сброс, настройки вида) — в меню «⋯» (`Menu`), переключатели в нём —
`pressed`. Разрушительные — `danger` в конце, после `MenuSeparator`, с подтверждением.
- **Форма:** поля столбцом с шагом 16, `Field` над каждым контролом, обязательность — в подписи или подсказке.
Проверка при отправке и при уходе с поля; ошибка под полем + `aria-invalid`; фокус на первое невалидное. Кнопки
внизу справа: `secondary` «Отмена» слева от `primary`. Во время отправки — `loading`, повторный щелчок невозможен.
- **Окно:** `Dialog` → `h2.ui-dialog__title`, `form.ui-form`, `div.ui-actions`. Esc и «Отмена» закрывают; щелчок по
фону закрывает только окно без ввода. Есть несохранённый ввод — спросить через `Confirm` («Закрыть без
сохранения?», `danger`), не `window.confirm`.
- **Карточка объекта:** основная колонка + боковая колонка свойств на `--color-bg-subtle`; уже ~900 px — колонкой.
## Состояния и статусы
- Статус — `Badge` с текстом; цвет только дублирует текст.
- **Просрочка/срок:** просрочено, если срок **строго раньше сегодняшней даты** (сегодня — ещё не просрочка) и объект
не закрыт/не на паузе. Красным (`.ui-late`: цвет ошибки, 600) — сама дата, плюс `title="просрочено"` и
`<span class="visually-hidden">, просрочено</span>`; статус-`Badge error` — если в таблице есть колонка статуса.
Строку не заливать красным, полос и рамок не добавлять. Сводка в подзаголовке: «… · N просрочено».
- **Чередование строк («зебра») не делать**: мешает читать цветовые пометки. Разделение — границей и hover.
- Загрузка: кнопка `loading` или `.ui-spinner` на месте результата; скелетоны не обязательны.
- Ошибка загрузки/операции — `Notice error` с действием «Повторить»; успех фоновой операции — текст успеха,
гаснет через ~10 с; предупреждение («нет связи, показаны прежние данные») — `Notice warning`.
- Пусто — `.ui-empty`: заголовок 16/24 700, одна строка пояснения, `primary`-действие («Добавить первую …»);
`primary` в `PageHeader` на это время скрыть — основная кнопка на экране одна.
«Ничего не найдено» по фильтру — с кнопкой «Сбросить фильтры».
## Тема
- `:root` — светлая; тёмная — `prefers-color-scheme` или `data-theme="dark"` на `<html>`; выбор хранится в
`localStorage` (`THEME_KEY`). Встроенный скрипт в `<head>` ставит `data-theme` до отрисовки (см. SKILL.md).
- Любой новый цвет — токен в трёх блоках `tokens.css`; тест паритета ловит забытый.
## Доступность (минимум)
- Видимый `:focus-visible` (уже в base.css); всё кликабельное — `button`/`a`, не `div`.
- Кнопка без текста — `IconButton` с `label`. Меню/выпадашки — `aria-expanded`, Esc закрывает.
- Живые сообщения о ходе операции — `role="status"`; ошибки — `role="alert"`.
- Контраст: вторичный текст не мельче 12 px; предупреждение на светлом — через `color-mix` (см. foundations).
## Проверка перед сдачей
- Скриншоты 1920×1080 и 390×844 в обеих темах (Playwright).
- Вне `tokens.css` нет литералов цвета (`tokens.test.ts` зелёный).
- Высоты контролов 32/40, кнопки — «таблетки», панели — радиус 16, одна `primary` на экран.
- Нет текстовых символов вместо иконок (✕ ⋯ ▼ ☰ ⚙ ☀ ☾).
- Узкая страница: ничего не вылезает за правый край (`document.documentElement.scrollWidth === innerWidth`).