DI2 restyle: отчёт этапа 3 (визуальный рестайл)

This commit is contained in:
2026-09-07 00:06:47 +03:00
parent 968010c411
commit 47b785edcd

View File

@@ -0,0 +1,63 @@
# Отчёт этапа 3 — визуальный рестайл DI2
Дата: 2026-09-08 (сессия продолжения плана `di2-restyle`)
Коммит: `968010c` (в main, запушен, автодеплой запущен)
## Что сделано
### 1. Графики recharts: hex/hsl → токены скина
Все палитры графиков переведены на `var(--chart-1..5)` (цикл по позиции), семантические ряды — на `var(--info/success/warning/destructive)`:
- `pages/calculations.tsx` — `COLORS` (income→info, expense→destructive, profit→success, tax→warning, toPay→chart-1, cumulative→chart-2), `HIGHLIGHT_COLORS` (10 → цикл chart-1..5).
- `pages/debt.tsx` — `OVERDUE_COLORS` и `clsColorMap`: возрастная шкала cls0→success, 1-30→info, 31-60→warning, 61-90→`color-mix(warning 55%, destructive)`, 91-365→destructive, >365→`color-mix(destructive 70%, black)`; fallback `#94a3b8`→`var(--muted-foreground)`; линии ДЗ/ПДЗ stroke→info/destructive.
- `pages/income-overview.tsx`, `pages/expenses-overview.tsx` — `COLORS` (20 цветов → цикл chart-1..5), fallback `#999`/`#ccc`→`var(--muted-foreground)`.
- `pages/salary.tsx` — `CHART_COLORS` (20 → цикл), `__other__`→muted-foreground.
- `pages/income-categories.tsx` — `TAG_COLORS` (8 → цикл chart-1..5).
- `pages/planning.tsx` — `PIE_COLORS` (8 → цикл), paid→success, debt/totalDebt→info, totalOverdue→destructive, зарплаты→chart-4 (прогноз — `color-mix(... 50%, transparent)`), чистая прибыль→chart-1.
- `pages/profitability.tsx` — income→success, expense→destructive, profit→info.
- `pages/heatmap.tsx` — `#6b7280`→`var(--muted-foreground)`.
### 2. Палитровые Tailwind-классы → семантика
~133 вхождений `text-red-500`, `bg-amber-50 dark:bg-amber-950/30` и т.п. заменены на семантические классы. Alpha-варианты (`bg-green-500/10`) — на `bg-[color-mix(in_oklab,var(--token)_N%,transparent)]` (Tailwind v3.4 не генерирует alpha для var-цветов, паттерн этапа 2). Пары `light/dark:` свёрнуты в один класс (токен адаптируется скином).
**Grep-контроль (итог):**
- Палитровые классы: **0 вхождений**.
- Hex: остались только обоснованные исключения:
- `components/ui/chart.tsx:55` — селекторы `[fill='#ccc']`/`[fill='#fff']` (шаблонный файл shadcn, это селекторы, а не UI-цвета);
- `pages/heatmap.tsx:30` — `#fff`/`#111` контрастный текст на вычисляемой тепловой шкале (динамический фон, не токен UI).
- Собранный CSS (`dist/public-di2/assets/index-*.css`): `.text-success/.text-info/.text-chart-1/.bg-info` присутствуют, `red-500/green-600` — 0.
### 3. Таблицы `ui/table.tsx` по UI Style Guide
- `TableHead`: `h-[var(--table-row-height,40px)]`, `bg-[color-mix(in_oklab,var(--muted)_50%,transparent)]`, `text-[12px] font-medium text-muted-foreground`, `px-3`.
- `TableRow`: hover `muted 40%`.
- `TableCell`: `px-3 py-2` (вместо `p-4`).
### 4. `lib/field-styles.ts` + кастомные контролы
- Порт `client/src/components/fields/field-styles.ts` → `client-di2/src/lib/field-styles.ts` с адаптацией: `hover:border-primary/50` и `focus:ring-ring/20` заменены на color-mix arbitrary values (в DI2 конфиге цветы — голые var(), alpha-модификаторы не генерируются).
- `fieldControlClass("form", "h-7 pl-5 pr-1.5 text-xs ...")` применён в `components/column-filter.tsx`.
- В `draggable-column-list.tsx` и `copyable-cell.tsx` кастомных input/select нет (только shadcn Checkbox/Button и текстовый спан) — применять нечего, shadcn-обёртки не тронуты.
### 5. `app-sidebar.tsx`
Брендинг: «ОмегаПром» font-semibold + «Финансы» text-xs muted (было почти целевое), отступы `py-5`→`py-4`, `gap-2.5`→`gap-2`, `leading-tight` у текстового блока.
### 6. Мобильная нижняя панель `components/bottom-nav.tsx`
По референсу `FinanceBottomNav.reference.tsx`: fixed bottom-0 `bg-background border-t z-50 md:hidden safe-area-bottom`, nav h-14, три кнопки flex-col (иконка w-5 h-5 + подпись text-[10px]), активная — `text-primary`, «Разделы» — DropdownMenu side="top" с 9 разделами (Доходы, Расходы, Дебиторка, Расчёты, Планирование, Зарплата, Аудит, Прибыльность, Тепловая карта) и индикатором-точкой. wouter `Link` base-aware (Router base="/di2"). Подключена в `App.tsx`, контент `<main>` получил `pb-20 md:pb-0`. Утилита `.safe-area-bottom` добавлена в `client-di2/src/index.css` (паттерн основного клиента). `SidebarTrigger` скрыт на мобильном (`hidden md:flex`) — Sheet-сайдбар остаётся в дереве, но недоступен (минимальное решение, компонент `ui/sidebar.tsx` не переписывался).
### 7. Переключатель темы
Кнопка Sun/Moon в хедере справа через `useDi2Theme().toggleTheme` (Di2ThemeProvider с этапа 2), с tooltip. Ключи localStorage общие с основным приложением — тема синхронизируется.
### 8. Заголовки страниц
Все h1: `text-2xl font-bold` → `text-lg font-semibold` (audit, dashboard, debt, expense-categories, expenses-overview, income-categories, income-overview, not-found, profitability, settings).
Отклонение: KPI-значение на дашборде (`stat-value`, dashboard.tsx:79) оставлено `text-2xl font-bold` — это метрика, а не заголовок; крупный размер даёт иерархию над заголовком text-lg.
## Проверки
- `npm run check` (`tsc && tsc -p client-di2/tsconfig.json`) — чисто.
- `npm run build` (main → di2 → server) — чисто; pre-push hook при push повторил обе проверки успешно.
- Grep-контроли: палитровые классы 0, hex только исключения, семантические классы в собранном CSS присутствуют.
## Отклонения и заметки
1. Скрипты-заменялки писались как `tmp/*.cjs` и удалены после прогона. Первая версия молча теряла hex-фазу из-за дублей ключей объекта и безусловного OK — поймана пост-grep'ом, исправлена вторая версия (отдельные объекты HEX/PALETTE, CRLF-адаптация, контроль счётчиков).
2. Файлы DI2 в CRLF — многострочные шаблоны скрипта конвертировались в `\r\n`; git предупреждает о переводе в LF при коммите (нормально для репо).
3. Циклическая палитра chart-1..5 даёт повторы цветов при >5 рядов (раньше было 20 различимых цветов) — осознанный компромисс за skin-адаптивность по плану.
4. `draggable-column-list.tsx` / `copyable-cell.tsx` без изменений (см. п.4 выше).
5. Heatmap-шкала и `#fff/#111` не переведены на токены — вычисляемый цветовой градиент, привязанный к light-шкале (зафиксировано как исключение).