8.0 KiB
Отчёт этапа 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/.darkHSL-тройки заменены 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 — модули тем/скинов), ожидаемо.
Отклонения от плана
- План предполагал, что замена alpha-модификаторов может быть не нужна, если Tailwind справится; фактически без замены классы исчезли бы из CSS — замена выполнена массово (166 мест), как и предписывал план.
--elevate-1/2: план →rgba(0,0,0,.05/.08); основной клиент использует.03/.08(light) и.03/.08(dark). Следовал плану: light.05/.08, darkrgba(255,255,255,.05/.08).bg-warningи др. пока не используются в DI2 — классы не генерируются (конфиг готов к этапу 3).- В собранном 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).