diff --git a/openspec/changes/make-design-tokens-portable/.openspec.yaml b/openspec/changes/make-design-tokens-portable/.openspec.yaml new file mode 100644 index 0000000..7d363ac --- /dev/null +++ b/openspec/changes/make-design-tokens-portable/.openspec.yaml @@ -0,0 +1,2 @@ +schema: wealth-ledger-sdd +created: 2026-09-08 diff --git a/openspec/changes/make-design-tokens-portable/design.md b/openspec/changes/make-design-tokens-portable/design.md new file mode 100644 index 0000000..f4b1d22 --- /dev/null +++ b/openspec/changes/make-design-tokens-portable/design.md @@ -0,0 +1,119 @@ +## Context + +Текущий shared/theme задаёт blue, font family и colorRoles в TypeScript; +остальные опубликованные шкалы получает из DEFAULT_THEME Mantine 9.5.1. +Приложение и Storybook уже используют один provider contract; 9 групп / 30 +stories существуют. Переносимость требует источника, который читается обычным +JSON parser без runtime этих библиотек. + +## Goals / Non-Goals + +**Goals:** JSON ownership общих токенов и semantic descriptions, узкий Mantine +adapter, валидация source contract, прежние эффективные размеры/цвета/поведение. + +**Non-Goals:** новый token engine, внешние integrations или публикация пакета, +автоматическая совместимость с DTCG импортерами, dark theme, новые компоненты, +редизайн, перенос локальных product literals, изменение API/backend и архивов. + +## Decisions + +- `shared/theme/tokens.json` — единственный редактируемый источник опубликованных + токенов: formatVersion, description, palette/base colors, default shades, + semantic roles с description, typography, spacing/radius, shadows, breakpoints. + JSON самодостаточен: нет DEFAULT_THEME imports, CSS variables и executable code. +- Формат WealthLedger v1 документируется явно. Hex colors, числовые weights и + unitless line heights, размерные группы с unit px, breakpoints с unit em; + shadow состоит из упорядоченных слоёв offsetX/offsetY/blur/spread в px, + color и opacity. Font families — строки CSS font stacks. Semantic role + ссылается на palette/base color по имени и optional shade; null shade палитры + означает primaryShade.light для поддерживаемой светлой схемы. Base colors + используют null shade. Описания ролей также принадлежат JSON. +- В source закрепляются blue, gray, dark, red, green, yellow, grape и orange + (используется Product), white/black, все опубликованные typography/layout scales. + Их текущие значения принимаются один раз из baseline. Необъявленные Mantine + palettes и UI behavior defaults остаются библиотечными и не считаются токенами + переносимого контракта. JSON не генерируется обратно из Mantine. +- `theme.ts` адаптирует проверенные данные: native rem(px) сохраняет scale, + breakpoints преобразуются в em без scale, shadows — в CSS с теми же слоями. + Primary role сохраняет native filled reference; resolver выдаёт прежние + --wl-color-* aliases. App/preview, shared styles и компоненты не меняются. +- Установленный Zod валидирует shape, units/ranges, palette cardinality и role + references при чтении source; некорректные tokens не получают fallback. + Это ограниченная схема текущего формата, без цепочек aliases, resolver graph, + plugin architecture или динамической загрузки внешних tokens. +- Foundations читает effective theme и JSON descriptions; показывает источник + и границу portable contract, сохраняя story IDs и оба блока. Frontend импортирует + theme/tokens через public API; внешний потребитель читает raw JSON напрямую, + не исполняя barrel с CSS и Mantine. + +## UI/UX Applicability and Package + +**Applicability and scope:** new/changed только для пояснений Foundations и +добавления уже используемой orange palette в обзор. Приложение, общие компоненты, +Product states/interactions и responsive поведение сохраняются без нового макета. + +**Package revision:** 1, полностью inline Markdown, exports не нужны. + +**Screens, states and interactions:** Colors содержит те же semantic role cards, +данные/описания из JSON и palette swatches, включая orange. Typography и Layout +сохраняют образцы, поясняют JSON ownership вместо DEFAULT_THEME ownership. +Button, StateView, LoadingSkeleton и Product используют прежние реализации. + +**Responsive behavior:** существующие grids/stack сохраняются; длинные source +пояснения переносятся на 375px. Изменение Mantine scale продолжает масштабировать +spacing/radius/type/shadow dimensions; responsive thresholds остаются em. + +**Reused source and differences:** implementation baseline; historical Design +package не переиспользуется как external authority, archived artifacts не меняются. + +## Delivery Map + +| Area | Status | Architectural outcome or N/A reason | +| --- | --- | --- | +| frontend | affected | Самодостаточный tokens.json, schema и Mantine adapter, актуальный Foundations | +| backend | N/A | API/auth/storage и денежные вычисления не затронуты | +| specs | affected | Уточнённый source/ownership contract и фактическое evidence | +| docs | affected | As-built JSON format, ownership, usage и integration limits | + +### Contract Gate Decision + +| Gate | Status | Reason | +| --- | --- | --- | +| runtime-openapi | N/A | Frontend/backend API contract не меняется | + +## Solution Assessment + +Обычный JSON читается стандартными парсерами без operating dependencies; +Mantine rem/createTheme/getThemeColor и установленный Zod покрывают adaptation +и validation. Полный DTCG или Style Dictionary уместен при выбранном потребителе +и требованиях к transforms, но сейчас добавляет форматные преобразования и +tooling без подтверждённой совместимости целевого инструмента. Собственный +контракт ограничен данными и прямым adapter, без универсального движка. При +выборе внешнего потребителя оценить его importer и трансформацию в требуемый формат. + +## Risks / Trade-offs + +- JSON теперь владеет принятыми шкалами: обновление Mantine не заменяет их + автоматически; локальные library defaults вне portable contract могут измениться. +- Числовые px в adapter используют rem, а не простые rem strings, чтобы сохранить + --mantine-scale. Breakpoints не масштабируются. Structured shadows могут дать + другой строковый порядок CSS при одинаковом computed value. +- Публичный format v1 требует явного изменения контракта при несовместимом изменении; + существующая browser интеграция не доказывает импорт конкретным внешним инструментом. + +## Migration Plan + +Сохранить baseline; перенести данные в JSON, включить schema и adapter; обновить +Foundations и документацию. Выполнить checks и независимый read-only review, +затем canonical completion. Прямое разрешение владельца в беседе сохраняет +workflow без session records и повторных промежуточных approval stops. + +### Rollback Contract + +| Field | Decision | +| --- | --- | +| Status | required | +| Trigger | Нарушено представление или потребление нового source contract | +| Actions | Вернуть delivery diff frontend/docs и соответствующую spec delta; не править исторические архивы. При появлении реального внешнего потребителя сохранить v1 JSON до его согласованной миграции. | +| Data safety | User data/auth не меняются; экспортированный v1 источник сохраняется для уже подключённых потребителей | +| Verification | Прежняя тема и обе сборки проходят gates; browser образцы совпадают с baseline | diff --git a/openspec/changes/make-design-tokens-portable/proposal.md b/openspec/changes/make-design-tokens-portable/proposal.md new file mode 100644 index 0000000..0dd284f --- /dev/null +++ b/openspec/changes/make-design-tokens-portable/proposal.md @@ -0,0 +1,36 @@ +## Why + +Общий визуальный фундамент теперь существует, но его токены доступны только +через frontend runtime и часть значений принадлежит UI-библиотеке. Это затрудняет +их повторное использование другими системами. Владелец согласовал переносимость +токенов как следующий шаг после complete-shared-design-system. + +## What Changes + +- Единый переносимый источник значений, типов, единиц и семантических ролей, + читаемый без приложения и UI-библиотеки. +- Приложение и каталог получают тот же фундамент через адаптацию исходных токенов. +- Используемые общие шкалы сохраняют значения; их редактирование происходит + в одном месте. Внешний вид, поведение и оба блока каталога сохраняются. +- Документация объясняет формат, ownership и границы интеграции. + +Non-goals: подключение конкретных внешних систем, публикация пакета, универсальный +движок токенов, новые зависимости, редизайн, миграция локальных product values, +dark theme, продуктовый пилот и изменение исторических archives/state. + +## Capabilities + +### New Capabilities + +Нет. + +### Modified Capabilities + +- `frontend-design-system`: `specs/frontend-design-system/spec.md` — переносимый + источник общего визуального фундамента и односторонняя адаптация для приложения. + +## Impact + +Frontend, canonical specs и as-built docs. Backend, API/auth и данные +пользователя не затронуты. Прямой workflow без session records сохраняется +по разрешению владельца в этой беседе. diff --git a/openspec/changes/make-design-tokens-portable/specs/frontend-design-system/spec.md b/openspec/changes/make-design-tokens-portable/specs/frontend-design-system/spec.md new file mode 100644 index 0000000..517a541 --- /dev/null +++ b/openspec/changes/make-design-tokens-portable/specs/frontend-design-system/spec.md @@ -0,0 +1,55 @@ +## MODIFIED Requirements + +### Requirement: Приложение и каталог используют единый визуальный фундамент + +Приложение и каталог SHALL использовать один источник темы и токенов: цвета +с семантическими ролями, типографику, интервалы, радиусы, тени и применимые +адаптивные параметры. Общий фундамент MUST быть независим от бизнес-сущностей +и уровня приложения; подключение провайдеров принадлежит приложению и runtime +каталога. Объявленные общие токены SHALL иметь единый переносимый машиночитаемый +источник значений, единиц, семантических ссылок и описаний, доступный без +приложения или UI-библиотеки. Адаптер приложения SHALL потреблять этот источник +без ручного дублирования значений. Перенос владения опубликованными шкалами +из UI-библиотеки в токены MUST сохранять их эффективные значения; не включённые +в контракт библиотечные defaults MAY оставаться у библиотеки. Выделение фундамента MUST сохранять текущий +внешний вид, светлую схему и поведение приложения без массовой замены локальных +значений оформления. + +#### Scenario: Компонент отображается в приложении и каталоге + +- **WHEN** один компонент с одинаковыми props отображается в обоих runtime +- **THEN** он получает одинаковые тему, токены и общие визуальные правила + +#### Scenario: Участник выбирает токен + +- **WHEN** участник изучает фундамент дизайн-системы +- **THEN** доступны используемые шкалы, их значения, семантические роли и правила + применения без необходимости обращаться к данным приложения + +#### Scenario: Владение темой перенесено + +- **WHEN** приложение использует выделенный общий фундамент +- **THEN** исходные эффективные значения и внешний вид остаются прежними, + включая встроенные шкалы, глобальные стили и локальное оформление + +#### Scenario: Токены использует другая система + +- **WHEN** потребитель читает исходный файл обычным парсером данных +- **THEN** объявленные цвета, роли, типографика, интервалы, радиусы, тени и + адаптивные пороги доступны с определёнными единицами и ссылками без React, + Mantine, CSS runtime или запуска приложения; интеграция конкретного инструмента + не заявляется автоматически + +#### Scenario: Изменён исходный токен + +- **WHEN** валидное значение или семантическая ссылка изменены в едином источнике +- **THEN** приложение и каталог получают изменение через один адаптер, без + повторного редактирования визуального значения в коде темы + +#### Scenario: Исходные токены некорректны + +- **WHEN** источник содержит неподдерживаемую единицу, некорректную шкалу или + семантическую ссылку на отсутствующий цвет +- **THEN** ошибка обнаруживается при проверке или загрузке фундамента, без + молчаливой подстановки другого визуального значения + diff --git a/openspec/changes/make-design-tokens-portable/tasks.md b/openspec/changes/make-design-tokens-portable/tasks.md new file mode 100644 index 0000000..be95e4b --- /dev/null +++ b/openspec/changes/make-design-tokens-portable/tasks.md @@ -0,0 +1,17 @@ +## 1. Переносимый фундамент + +- [x] 1.1 [frontend] Перенести опубликованные токены и role descriptions в self-contained JSON v1, добавить проверку контракта и прямой Mantine adapter без дублирования values. + - **Covers:** `frontend-design-system` — `Приложение и каталог используют единый визуальный фундамент` + - **Verification:** Обычный JSON parser читает source; tests проверяют валидный документ, ошибочные units/palettes/role refs, rem/primary/shadow adaptation; сохранение baseline effective values. +- [x] 1.2 [frontend] Обновить Foundations и frontend ownership docs, сохранив story IDs, оба блока и использование общего source; выполнить frontend gate и browser proof. + - **Covers:** `frontend-design-system` — `Приложение и каталог используют единый визуальный фундамент` + - **Verification:** npm ci и npm run verify под .nvmrc; browser Foundations/Product/login до/после, 375px, CSS scale/shadows и прежние interactions; FSD и runtime stories isolation. + +## 2. Authority и документация + +- [x] 2.1 [specs] Оформить отдельный согласованный change с новым source contract, Design и фактическими Tasks без изменения старых archives/state. + - **Covers:** `frontend-design-system` — `Приложение и каталог используют единый визуальный фундамент` + - **Verification:** openspec schema validate wealth-ledger-sdd --verbose; openspec validate make-design-tokens-portable --type change --strict --store wealth-ledger-specs; openspec validate --specs --strict --store wealth-ledger-specs; semantic comparison с main baseline. +- [x] 2.2 [docs] Обновить as-built формат JSON, ownership, способы чтения и ограничения внешних интеграций. + - **Covers:** `frontend-design-system` — `Приложение и каталог используют единый визуальный фундамент` + - **Verification:** npm ci и npm run verify под docs .nvmrc; проверка affected local links и соответствия описания source/schema/adapter.