Скилл переносится из ~/.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>
80 lines
8.7 KiB
Markdown
80 lines
8.7 KiB
Markdown
# 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`).
|