Files
iistwin/.superpowers/sdd/di2-restyle/task-2-report.md

48 lines
8.0 KiB
Markdown
Raw Permalink 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.

# Отчёт этапа 2 — Мост тем/скинов iistwin в DI2
Дата: 2026-09-07. Коммит: **`b457934`** — `DI2: мост тем/скинов iistwin — Di2ThemeProvider, общий generated-skins.css, токены в формате основного клиента` (32 файла, +588/−348). Push в main выполнен, pre-push hook (check+build) — «All checks passed». Автодеплой запущен.
## Что сделано
### Общий код тем
- `vite.config.di2.ts` — алиас `@skin` → `client/src/themes` (resolve.alias; покрывает `@skin` и `@skin/*`).
- `client-di2/tsconfig.json` — paths: `"@skin": ["../client/src/themes/index.ts"]`, `"@skin/*": ["../client/src/themes/*"]`.
- `client-di2/src/index.css` — первой строкой `@import '../../client/src/themes/styles/generated-skins.css'` (8 селекторов `[data-skin="..."][data-theme="..."]` в собранном CSS — проверено).
### Di2ThemeProvider (`client-di2/src/themes/Di2ThemeProvider.tsx`, новый)
- Порт логики `client/src/themes/ThemeProvider.tsx` без useAuth/useQuery (plain fetch, credentials: include).
- Приоритет скина: `localStorage['skin']` (валидация среди BUILT_IN_SKINS + кастомных с сервера) → `GET /api/organization/current-skin` → `'iistwin'`. Формат ответов сверён с `server/routes/organization-skins.routes.ts` (`{success, skins: [{id, name, description, isEditable, isBuiltIn}]}`, `{success, skinId, skin}`, `{success, skin}`).
- Кастомные скины: список через `/api/organization/skins`, токены текущего кастомного — через `/api/organization/skins/:id`; runtime CSS через `generateSkinCss` в `<style id="skin-runtime">` (тот же генератор, что в основном клиенте).
- Тема: `localStorage['theme']` → `prefers-color-scheme` + слушатель.
- На `<html>`: `data-skin`, `data-theme`, класс `light|dark`. Ключи localStorage общие с основным приложением — выбор синхронизируется iistwin ↔ /di2.
- Экспортирует `useDi2Theme()` (theme/setTheme/toggleTheme/skinId/setSkinId/availableSkins) и `useDi2Skin()` — для переключателя темы на этапе 3.
- `client-di2/src/main.tsx` — `<Router base="/di2"><Di2ThemeProvider><App/></Di2ThemeProvider></Router>`.
### Перевод DI2 на полный формат токенов
- `client-di2/tailwind.config.ts` — все цвета `hsl(var(--x) / <alpha-value>)` → `var(--x)`; радиусы → `var(--radius)` + каскад `calc(-2px/-4px)`; добавлены `warning/success/info` (+foreground); структура `sidebar`/`sidebar-primary`/`sidebar-accent` и DI2-nested border'ы (`card.border` → `card-border` и т.д.) сохранены; `status` (rgb, неиспользуемый) оставлен без изменений.
- `client-di2/src/index.css` — собственные `:root`/`.dark` HSL-тройки заменены fallback-блоками из `client/src/index.css:13-138`; DI2-only переменные переопределены: `--card-border`/`--popover-border` → `var(--border)`, `--primary-border`/`--secondary-border`/`--muted-border`/`--accent-border`/`--destructive-border`/`--sidebar-primary-border`/`--sidebar-accent-border` → `color-mix(in oklab, var(--X) 82%, black)`, `--button-outline` → `color-mix(in oklab, var(--primary) 35%, transparent)`, `--badge-outline` → `color-mix(in oklab, var(--muted-foreground) 35%, transparent)`, `--elevate-1/2` → `rgba(0,0,0,.05/.08)` (в `.dark` — светлые); удалены `--opaque-button-border-intensity` и все `hsl(from ...)` relative-color блоки; жёсткие `--font-sans: Open Sans` и т.п. удалены (шрифты эмитит `generateSkinCss` из токенов скина); `hsl(var(--muted-foreground))` в contenteditable-плейсхолдере → `var(--muted-foreground)`. Слой elevate-утилит DI2 (hover-elevate и т.д.) сохранён — используется badge/button.
- `client-di2/index.html` — `lang="ru"`, viewport без `maximum-scale=1` + `interactive-widget=resizes-content`, оба preconnect и мега-link (23 семейства) заменены одним линком Inter + DM Mono как в `client/index.html:23`.
### Alpha-модификаторы семантических цветов — важная находка
Эмпирическая проверка на Tailwind 3.4.19 (тестовый скрипт, затем удалён): класс с модификатором прозрачности (`bg-muted/50`) для цвета-`var()` **молча не генерируется** в CSS вообще (Tailwind не умеет alpha для var-цветов; трюки с `<alpha-value>` + color-mix в конфиге дают битый CSS через legacy `--tw-bg-opacity`). Основной клиент iistwin живёт с этим же ограничением.
Решение (как в плане): 166 вхождений в client-di2/src заменены скриптом `tmp/di2-alpha-replace.cjs` (удалён после прогона) на arbitrary values: `bg-muted/50` → `bg-[color-mix(in_oklab,var(--muted)_50%,transparent)]`. Варианты (`hover:`, `aria-selected:`, arbitrary-variant) сохраняются. Палитровые цвета (`bg-green-500/10`, `bg-black/80` и т.п. — с ними alpha работает штатно) не тронуты. Полный список заменённых паттернов — в выводе скрипта (скопирован в git-коммит-сообщение частично, полный лог не сохранялся; повторяемость: bg-muted/50 ×37, bg-muted/30 ×28, border-muted-foreground/30 ×10 и т.д.).
## Проверки
- `npm run check` (tsc корневой + `tsc -p client-di2/tsconfig.json`) — чисто.
- `npm run build` (main → di2 → server) — успешно.
- Собранный `dist/public-di2/assets/index-*.css` (116.4 kB, было 88.3 kB) проверен grep/node: `.bg-primary{background-color:var(--primary)}`, 8 селекторов `[data-skin=...]`, правила `color-mix(in oklab,var(--muted) N%,transparent)` для bg/border/divide/stroke/text + hover-варианты, `border-radius:var(--radius)`.
- JS-бандл DI2 вырос с 1363 до 1405 kB (~42 kB — модули тем/скинов), ожидаемо.
## Отклонения от плана
1. План предполагал, что замена alpha-модификаторов может быть не нужна, если Tailwind справится; фактически без замены классы исчезли бы из CSS — замена выполнена массово (166 мест), как и предписывал план.
2. `--elevate-1/2`: план → `rgba(0,0,0,.05/.08)`; основной клиент использует `.03/.08` (light) и `.03/.08` (dark). Следовал плану: light `.05/.08`, dark `rgba(255,255,255,.05/.08)`.
3. `bg-warning` и др. пока не используются в DI2 — классы не генерируются (конфиг готов к этапу 3).
4. В собранном CSS замечен `var(--color-border)` из `client-di2/src/components/ui/chart.tsx` (собственная индикатор-переменная recharts-обёртки, inline-стили) — не конфликтует с нашими токенами, не трогал.
## Оставшееся (этапы 3–4)
Этап 3 (визуальный рестайл: графики var(--chart-*), хардкод-цвета, таблицы, контролы, нижняя панель по референсу FinanceBottomNav.reference.tsx, переключатель темы), этап 4 (проверка, документация, ручной Google redirect URI).