From dfb2311e325e0d298e6f8037b4cf71a0b0a3b521 Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Thu, 27 Aug 2026 18:49:31 +0500 Subject: [PATCH] docs: update re-design plan --- docs/plan-redesign.md | 428 +++++++++++++++++++++++++++++------------- 1 file changed, 298 insertions(+), 130 deletions(-) diff --git a/docs/plan-redesign.md b/docs/plan-redesign.md index f361d96..974ea5f 100644 --- a/docs/plan-redesign.md +++ b/docs/plan-redesign.md @@ -1,27 +1,72 @@ -# План: переезд на новый дизайн (refs) +# План: переезд на новый дизайн (refs) — параллельная сборка > Статус: план к выполнению. > -> Источники: `refs/` — Next/React-референс (правда по пикселям), `refs-html/` — -> статические HTML-снимки для быстрого просмотра в браузере. +> Источники: `refs/` — Next/React-референс (правда по пикселям и интерактиву), +> `refs-html/` — статические HTML-снимки для быстрого просмотра в браузере. +> +> **Стратегия изменена.** Вместо in-place рестайла (старый план A–F, правка +> общих компонентов на месте с алиасами токенов) — **параллельная сборка**: +> новый дизайн строится отдельно, изолируется от старого, проверяется +> целиком, затем становится основным и старый удаляется. Старое приложение +> остаётся рабочим и шippable на всём протяжении перехода. -## 1. Что происходит +## 0. Почему меняем стратегию -В `refs/` лежит новый визуальный язык проекта: «чертёжный» техно-стиль — -сетка на фоне, IBM Plex Sans/Mono, моно-микролейблы в верхнем регистре, -острые углы 4px, панели с 1px-бордером, акценты синий/циан/амбер, зелёные -статус-точки. Референс написан на Next 16 + Tailwind v4, но **переезд -дизайновый, а не фреймворковый**: SvelteKit в `web/` остаётся, переносится -только дизайн-слой (токены → примитивы → UI-kit → страницы). +- **Старый план (A–F):** правим `ui/*` и страницы на месте, держим старые + токены как алиасы, чтобы ничего не сломалось до этапа F. Риск: общие + компоненты редактируются вживую → регресс старого UI во время работы, + новый дизайн нельзя принять изолированно. +- **Новый подход (5 фаз):** (1) строим новый ui-kit, (2) строим новые + страницы рядом, не трогая старые, (3) проверяем новый дизайн, (4) делаем + его основным, (5) удаляем старый. Ниже фазы 1–5 — это требуемые шаги. +- **Главный технический риск и его решение.** Сейчас `web/src/app.css` + импортируется в **корневом** `web/src/routes/+layout.svelte:2` и потому + грузится на ВСЕХ маршрутах, включая новые. Решение — **не префиксовать + новый CSS (никакого `.ds2`), а разнести глобальные стили по layout'ам без + наследования**: (а) убрать `import '../app.css'` из корневого layout; + (б) старые маршруты обернуть группой `(old)/` с собственным layout, + импортирующим `app.css`; (в) новые маршруты (`preview/*`) — собственный + layout, импортирующий `design2.css`. SvelteKit делает code-splitting CSS + по маршрутам, а стили компонентов скоупятся сами — поэтому глобальные + стили каждого дизайна живут только в своей ветке, и префикс-обёртка + `.ds2` не нужна. Старые `ui/` и страницы не трогаются до фазы 5. -Чего не делаем: не тащим Tailwind и React в проект. Токены из -`refs/app/globals.css` переносятся в наш vanilla-CSS слой почти один в один, -классы референса (`step-card`, `setting-group`, …) воспроизводятся как наши -глобальные утилиты и стили компонентов. +## 1. Источники и их оценка -## 2. Токены (фундамент) +### `refs-html/` — витрина разметки -Маппинг старых токенов `web/src/app.css` → новые из референса: +Покрытие достаточное: + +| Файл | Что показывает | Оценка | +| ------------------------- | ----------------------------------------- | ---------------- | +| `index.html` | Главная: pipeline-воркспейс + превью | ✅ | +| `demo.html` | Зеркало `index.html` (идентичны) | ⚠️ дубликат | +| `gradient.html` | Инструмент «Градиент»: настройки + превью | ✅ (тёмная тема) | +| `background-remover.html` | Инструмент «Удаление фона»: source/result | ✅ (тёмная тема) | +| `list-tools.html` | Каталог инструментов | ✅ | + +- **Статика без JS** — интерактив (тумблеры/слайдеры/перетаскивание) брать из + кода `refs/`, не из HTML. HTML — только визуальная правда по разметке/классам. +- По 4 файлам собран инвентарь классов — это и есть спецификация kit'а: + `app-shell`, `page-grid`, `eyebrow`, `brand-mark`, `topbar`, `footer`, + `panel-heading`, `setting-group`, `settings-footer`, `settings-panel`, + `segmented`, `status`, `step-card` (`step-index`/`step-heading`/`step-type`/ + `step-body`/`drag`), `color-field` (`swatch`/`native-color`), + `preview-toolbar`/`checker` (`tile-canvas`/`remover-canvas`/`comparison-grid`), + `result-meta`/`meta-row`, `tool-card`/`image-card` (`tool-icon`/`tool-index`/ + `tool-copy`), `code-block`, `icon-btn`, `download-btn`, `reset-btn`, `lede`, + `auto-note`, `label`, `toggle`/`toggle-group`, `direction-grid`, `gradient-bar`. +- **Дыры в refs-html:** нет состояний empty/error/loading, нет глобальных + модалок/тултипов, i18n не представлен (все лейблы — английские брендовые). + Решения — см. §9. + +## 2. Токены (фундамент нового дизайна) + +Живут в `src/lib/styles/design2.css` как обычный `:root { … }` (плюс +`[data-theme='dark'] { … }`). Файл грузится **только** layout'ом новой +ветки (§5), поэтому глобально не конфликтует со старым `app.css`. Маппинг +старых токенов `web/src/app.css` → новые: | Старый | Новый | Light | Dark | | -------------- | -------------- | --------- | ------------------------ | @@ -38,135 +83,172 @@ Прочее: -- Радиусы: вместо `--radius-s/m` один `--radius: 4px`. Скруглённая мягкость - старой темы уходит. +- Радиусы: один `--radius: 4px` (мягкость старой темы уходит). - Шрифты: `IBM Plex Sans` + `IBM Plex Mono`, self-host через `@fontsource` - (проект offline-first, CDN нельзя). Mono — рабочий шрифт для лейблов, - метаданных, цифр; Sans — для заголовков и текста. -- Фон-сетка приложения (32px blueprint-grid) и шахматка канвасов — - отдельные утилиты `.app-shell`, `.checker-canvas`, не токены. -- Тёмная тема остаётся на `[data-theme='dark']` (инлайн-скрипт в `app.html` - уже есть); класс `.dark-mode` из референса не переносим. -- На переходный период старые имена живут как алиасы - (`--bg: var(--background)` …), чтобы существующие компоненты не ломались - до этапа D. В конце алиасы удаляются. + (offline-first, CDN нельзя). Mono — рабочий шрифт для лейблов/метаданных/ + цифр; Sans — заголовки и текст. Задаются на `.app-shell` (корень новой + ветки), чтобы не зависеть от старых глобальных правил `body`. +- Фон-сетка (32px blueprint-grid) и шахматка канвасов — утилиты `.page-grid` + и `.checker-canvas` внутри `.ds2`, не токены. +- Тёмная тема — на `[data-theme='dark']` (инлайн-скрипт уже есть в + `app.html`); класс `.dark-mode` из рефа не переносим, используем наш + механизм. На переходный период **никаких алиасов старых токенов** (старые + страницы сами живут на своём `app.css`). -## 3. Базовые примитивы дизайн-системы +## 3. Базовые примитивы дизайн-системы (все — компоненты) -Повторяющиеся паттерны референса выносим в глобальные классы `app.css` -(по одному определению, без копипасты между компонентами): +Правило фазы 1: **любой повторяющийся паттерн — компонент**, даже «просто +div с двумя стилями». Никакой копипасты классов между страницами. Каждый +примитив ниже — отдельный `.svelte` в `src/lib/components/kit/`. -- `.mono-label` — микро-лейбл: mono 10px, uppercase, letter-spacing .1em, - цвет muted; модификаторы `.mono-label--accent` (синие eyebrow/version). -- `.status-dot` / `.status-line` — точка `--success` + подпись +- `MonoLabel` — микро-лейбл: mono 10px, uppercase, letter-spacing .1em, + muted; слот-модификатор accent (синие eyebrow/version). +- `StatusDot` / `StatusLine` — точка `--success` + подпись («AUTO PIPELINE», «LIVE PREVIEW»). -- `.panel` — панель: фон `--panel`, бордер `--line`; композиция - `.panel-heading` (label + strong + правый слот) / `.setting-group` / - `.settings-footer` с разделителями. -- `.checker-canvas` — рабочая поверхность превью: тёмная подложка + - шахматка; размеры через контейнер. -- `.meta-row` — пары «CAPTION значение» (dimensions/format/size, - result-meta). -- `.segmented` — сегмент-переключатель (общий для языка, типа градиента, - пресетов). +- `Panel` / `PanelHeading` / `SettingGroup` / `SettingsFooter` — панель с + 1px-бордером, составные части с разделителями. +- `CheckerCanvas` — рабочая поверхность превью: тёмная подложка + шахматка. +- `MetaRow` / `MetaList` — пары «CAPTION значение». +- `Segmented` — сегмент-переключатель (язык, тип градиента, пресеты). +- `Badge` — тег типа шага (BACKGROUND/TRANSFORM/STYLE), чип «✓ AUTO». +- `StepCard` — нумерованная карточка этапа: индекс `01`, drag-handle, + Badge типа, заголовок, кнопка удаления; слот для параметров. +- `ToolCard` — карточка каталога (icon, index, title, copy, arrow). +- `ImageCard` / `PreviewTile` — label сверху + canvas-превью. +- `AppShell` — корневой контейнер `.app-shell` + `.page-grid` (обёртка + новой ветки маршрутов); задаёт шрифты и фон нового дизайна. +- `BlueprintGrid` — фоновая сетка (используется в `AppShell`). +- `IconButton`, `Icon` (обёртка `lucide-svelte`, 16–17px, muted). -## 4. Минимальный UI-kit (`src/lib/components/ui/`) +## 4. Минимальный UI-kit (`src/lib/components/kit/`) -API компонентов сохраняем, меняем внутренности. Новые компоненты — только -те, для которых нет аналога: +Контролы, поверх примитивов §3. API проектируем сразу под новый дизайн +(обратной совместимости со старым `ui/` не нужно — старые страницы его +продолжают использовать). -| Компонент | Статус | Что меняется | -| --------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------- | -| `Button.svelte` | рестайл | варианты `primary` (синий solid) / `secondary` (outline) / `ghost` + `icon`-режим; busy-логика остаётся | -| `Field.svelte` | рестайл | обёртка в стиле `.setting-group`: mono-label + output справа | -| `SliderField` | рестайл | range + `` значения, опциональная строка подсказок («strict edges … more removal») | -| `ColorField` | рестайл | swatch + hex-input + нативный color-picker в одном поле | -| `TextField` / `SelectField` / `CheckboxField` | рестайл | чекбокс → switch-toggle 32×18 как в рефе | -| `SegmentedControl.svelte` | **новый** | RU/EN, Linear/Radial, пресеты прозрачности | -| `Badge.svelte` | **новый** | тег типа шага (BACKGROUND/TRANSFORM/STYLE), чип «✓ AUTO» | -| `MetaList.svelte` | **новый** | `.meta-row` для DIMENSIONS/FORMAT/SIZE | -| `EmptyState.svelte` | рестайл | под новый стиль панелей | +| Компонент | Назначение | +| ------------------------- | ----------------------------------------------------------------- | +| `Button.svelte` | `primary` (solid blue) / `secondary` (outline) / `ghost` + `icon` | +| `Field.svelte` | обёртка: `MonoLabel` + слот значения/контрола | +| `SliderField.svelte` | range + ``, опц. строка подсказок | +| `ColorField.svelte` | swatch + hex-input + нативный picker | +| `TextField.svelte` | текстовый ввод в стиле дизайна | +| `SelectField.svelte` | селект в стиле дизайна | +| `CheckboxField.svelte` | чекбокс → switch-toggle 32×18 | +| `Toggle.svelte` | переключатель (для toggle-group) | +| `SegmentedControl.svelte` | на базе `Segmented` — RU/EN, Linear/Radial, пресеты | +| `Badge.svelte` | на базе `Badge` | +| `MetaList.svelte` | на базе `MetaRow` | +| `EmptyState.svelte` | пустое состояние под новый стиль | +| `CodeBlock.svelte` | блок кода (gradient-art / direction-grid) | +| `DownloadButton.svelte` | кнопка скачивания (можно переиспользовать идею старой) | -Иконки: в рефе lucide-react; берём `lucide-svelte` (те же пути, MIT) — -16–17px, stroke, приглушённый цвет. +Иконки: `lucide-svelte` (те же пути, MIT), 16–17px, stroke, muted. -## 5. Шелл и страницы +## 5. Изоляция старого и нового (критично) -### 5.1 Layout (`+layout.svelte`) +Без префиксов и обёрток — только за счёт того, какие layout грузят какой CSS. -- Topbar: brand-mark «EP» (синий квадрат 30px) + `easy-png-tools` + версия - суффиксом `/ v0.x`; справа — статус «LOCAL-ONLY», icon-btn темы - (Moon/Sun), сегмент RU|EN. -- Footer: `easy-png-tools vX` · `pipeline is local-only` · © год. -- Фон-сетка на корневом контейнере `.app-shell`. +- **Корневой layout `src/routes/+layout.svelte`** перестаёт импортировать + `../app.css`. В нём остаётся только общая логика (init темы/locale) и + нейтральный `
{children}
` без глобальных стилей дизайна. +- **Старая ветка `src/routes/(old)/+layout.svelte`** импортирует `app.css` + и содержит текущую шапку/подвал (разметку из нынешнего корневого layout). + Все старые страницы переносятся внутрь `(old)/` (группа в скобках не + меняет URL): `(old)/+page.svelte`, `(old)/demo/...`, + `(old)/list-tools/...`, `(old)/tools/[id]/...`. +- **Новая ветка `src/routes/preview/+layout.svelte`** импортирует + `design2.css` и рендерит ``. Сюда же — новые страницы (§6). +- Благодаря code-splitting CSS в SvelteKit: на старых маршрутах грузится + только `app.css`, на `preview/*` — только `design2.css`. Скоуп стилей + Svelte-компонентов добавляет второй уровень изоляции. Никаких `.ds2`. +- Переключатель для ручной проверки: временный флаг `previewDesign` в + `localStorage` + кнопка в старой шапке («Preview v2»), ведущая на + `/preview`. На фазе 4 флаг убираем. -### 5.2 `/` — воркспейс +> Почему не `(new)`-группа с теми же путями вместо `preview/*`: две группы +> не могут одновременно определять один и тот же URL (`(old)/+page.svelte` +> и `(new)/+page.svelte` оба → `/` = конфликт маршрутов). Поэтому новая +> ветка живёт под префиксом `preview/`, а на фазе 4 файлы переносятся на +> реальные пути и группа `(old)` удаляется. +> +> Это совпадает с рекомендованным в документации SvelteKit паттерном: +> «put your entire app inside one or more groups except the routes that +> should not inherit the common layouts» — старое целиком в `(old)`, новое +> снаружи. Синтаксис `@`-breakout (`+layout@.svelte`, `+page@.svelte`) здесь +> не требуется: «выломаться» можно лишь до корня, а нам нужно, чтобы именно +> у корня НЕ было `app.css`; если позже захотим держать новые маршруты внутри +> группы, `@` пригодится для сброса родительского layout. -Текущий hero + ToolSearch переезжает в рампу референса: eyebrow -«PNG PROCESSING / WORKSPACE», крупный h1 (clamp 36–64px, tracking −0.06em), -lede; поиск — строка в стиле file-chip/pipeline-head. «Открыть последний» — -кнопка secondary. Каталог `/list-tools` — сетка карточек в стиле -`image-card` (label сверху, canvas-превью). +## 6. Маршрутизация параллельных страниц -### 5.3 `/tools/[id]` — страница инструмента - -Главная перестройка. Целевая раскладка из рефа — двухпанельная: +Новые страницы живут в **отдельной ветке `preview/*`**, не трогая старые: ```txt -eyebrow + tool-title (+ LIVE PREVIEW) -┌─ settings-panel ────────┐ ┌─ preview-panel ─────────┐ -│ panel-heading │ │ preview-toolbar │ -│ setting-group ×N │ │ checker-canvas / source │ -│ (Slider/Color/Toggle…) │ │ + result comparison │ -│ settings-footer (reset) │ │ meta-row │ -└─────────────────────────┘ └─────────────────────────┘ +src/routes/+layout.svelte # нейтральный, БЕЗ app.css +src/routes/(old)/+layout.svelte # импорт app.css + старая шапка/подвал +src/routes/(old)/+page.svelte # / (старое) +src/routes/(old)/demo/+page.svelte # /demo +src/routes/(old)/list-tools/... +src/routes/(old)/tools/[id]/... +src/routes/preview/+layout.svelte # импорт design2.css, +src/routes/preview/+page.svelte # /preview — воркспейс (index/demo) +src/routes/preview/demo/+page.svelte # /preview/demo +src/routes/preview/list-tools/+page.svelte +src/routes/preview/tools/[id]/+page.svelte ``` -- `ParamsCard`/`ParamForm` → секция настроек: поля становятся - `.setting-group` через обновлённый `ui/*`. -- `SourceCard`/`ResultCard`/`Preview` → превью-панель: toolbar с именем - файла и download-btn, canvas на шахматке, result-meta снизу. -- Chain-блоки (`ChainToolBlock`) — нумерованные step-cards из главной - рефа: индекс `01`, drag-handle, Badge типа, заголовок, кнопка удаления; - параметры этапа — те же setting-groups внутри карточки. -- Существующий `ToolStageClassic`/inline-вариант заменяются целевой - раскладкой; stage-абстракция из plan-inline-params закрывается этим - переездом. +- Каждая новая страница импортирует **только** `kit/*`. Старые страницы + не изменяются (только перемещены в `(old)/`). +- Фаза 4: содержимое `preview/*` переносится на реальные маршруты + (move-файлы), группа `(old)/` удаляется, `design2.css` подключается в + корневом `+layout.svelte` (как новый основной слой), временный флаг/кнопка + убираются. -### 5.4 `/demo` +## 7. Фазы выполнения (1–5 по запросу) -Зеркало `refs-html/index.html` — витрина пайплайна, используется как -приёмочный стенд нового стиля (делается первым среди страниц). +Каждая фаза заканчивается зелёными `test`/`check`/`build` и ревью в браузере +(обе темы) против `refs-html/`. -## 6. Этапы и проверки +- **Фаза 1 — Фундамент + UI-kit.** Токены §2, `design2.css` по §5, все + примитивы §3 и контролы §4 как отдельные компоненты. Критерий: + демо-страница kit'а (`/preview` или временная) показывает все состояния + (light/dark, hover/disabled, все варианты Button/Segmented/Badge); + unit-тесты форм не падают; **старые страницы визуально не изменились** + (изоляция работает). -Каждый этап заканчивается зелёными `test`/`check`/`build` и ревью в браузере -(обе темы) против соответствующего HTML из `refs-html/`. +- **Фаза 2 — Новые страницы.** Под `preview/*` (§6): воркспейс, demo, + list-tools, tool-page (двухпанельная раскладка из рефа: settings-panel + + preview-panel, step-cards для chain). Критерий: разметка соответствует + `refs-html/index.html`, `gradient.html`, `background-remover.html`, + `list-tools.html`; интерактив (слайдеры/тоглы/загрузка/автозапуск) работает + в новом стиле; старые маршруты продолжают работать как раньше. -- **A. Фундамент** — новые токены + алиасы старых, @fontsource IBM Plex, - утилиты §3, тёмная тема на `[data-theme]`. Критерий: приложение выглядит - по-старому (алиасы дают прежние цвета близко к новым), тесты зелёные, - FOUC-скрипт темы работает. -- **B. UI-kit** — компоненты §4: сначала рестайл существующих, потом новые - (`SegmentedControl`, `Badge`, `MetaList`). Критерий: демо-страница kit'а - или `/demo` показывает все состояния; unit-тесты форм не падают. -- **C. Шелл** — topbar/footer по §5.1, переключение темы и языка в новом - виде. Критерий: i18n/theme тесты зелёные, разметка шапки соответствует - рефу. -- **D. Страница инструмента** — раскладка §5.3 на `/demo`, затем на всех - инструментах; chain-карточки. Критерий: смоук §7, скриншоты против - `refs-html/gradient.html` и `background-remover.html`. -- **E. Главная и каталог** — §5.2. Критерий: поиск/фильтры работают, - покрытие search-coverage/i18n тестов зелёное. -- **F. Чистка** — удаление алиасов старых токенов, неиспользуемых классов - `app.css` (`.tool-stage`, `.pane*`…), финальный проход по брейкпоинтам - 1200/1100/800/480 из рефа. Критерий: grep по старым токенам пуст, - build без предупреждений. +- **Фазa 3 — Проверка нового дизайна.** Смоук §8 (обе темы, узкий экран, + 800px), скриншоты против `refs-html/`, прогон старого тест-сьюта для + доказательства отсутствия регресса, RU/EN-локализация новых лейблов. + Критерий: визуальное совпадение с рефом, зелёные тесты, записанные + скриншоты приняты. -Оценка объёма: A+B — фундамент (~полдня), C+D — основная работа (~1–2 дня), -E+F — добивка (~полдня). +- **Фаза 4 — Сделать новый дизайн основным.** Перенос `preview/*` → + реальные маршруты; `design2.css` подключается в корневом `+layout.svelte`; + удаление preview-группы и временного флага/кнопки. Старые страницы теперь + не используются (мёртвый код), но физически ещё в репо. + Критерий: реальные маршруты отдают новый дизайн, тесты зелёные, билд без + предупреждений. -## 7. Смоук (после этапа D) +- **Фаза 5 — Удалить старый дизайн.** Удаление старых страниц, старого + `ui/`, старого `app.css` (и его токенов), неиспользуемых классов; + переименование `kit/` → `ui/` (финальное имя) либо оставление `kit/` как + основного — решается на фазе 1. Финальный проход по брейкпоинтам + 1200/1100/800/480. Критерий: `grep` по старым токенам/классам пуст, + build чистый, старый дизайн нигде не упоминается. + +Оценка объёма: Фаза 1 — фундамент+kit (~1 день), Фаза 2 — страницы +(~1–2 дня), Фаза 3 — проверка (~полдня), Фаза 4–5 — переключение и чистка +(~полдня). + +## 8. Смоук (после фазы 3, контроль на фазе 4) 1. Светлая и тёмная тема: сетка фона, панели, шахматка канвасов читаются, контраст mono-лейблов достаточный. @@ -176,16 +258,102 @@ E+F — добивка (~полдня). шахматке. 4. Chain из 3+ инструментов: step-cards рендерятся, удаление/сброс работают. 5. Узкий экран 800px: настройки над превью, sticky выключается как в рефе. -6. RU/EN: новые лейблы локализованы; mono-лейблы рефа либо ключи i18n, - либо осознанно английские брендовые элементы (см. §8). +6. RU/EN: новые лейблы локализованы; mono-лейблы рефа — либо ключи i18n, + либо осознанно английские брендовые элементы (см. §9). -## 8. Открытые вопросы +## 9. Открытые вопросы -- Mono-лейблы рефа на английском (`PROCESSING PIPELINE`). Предложение: - завести i18n-ключи, но для техно-эстетики допустимо оставить часть - английскими как «приборную панель». Решить на этапе A. -- Версия в топбаре/футере: брать из package.json при сборке (define) или - захардкодить? Мелочь, решить на этапе C. -- `refs/` оставляем в репо как источник правды; при изменении дизайна — - правки там, затем синхронизация вручную. Регенерация refs-html описана в - его README. +- **Имя финального каталога компонентов:** оставить `kit/` как основное имя + или переименовать в `ui/` на фазе 5 (удалив старое `ui/`). Рекомендую + сразу писать в `kit/`, на фазе 5 переименовать в `ui/`. Решить на фазе 1. +- **Изоляция через layout:** `app.css` вынесен из корневого layout в + `(old)/+layout.svelte`; новый `design2.css` — только в `preview/+layout`. + Проверить на фазе 1, что на `/preview/*` не попадают стили старого + дизайна (DevTools → вкладка Styles, нет правил из `app.css`). +- **Переключатель для проверки:** рекомендую `localStorage`-флаг + + кнопка «Preview v2» в старой шапке + группа `preview/*`. Убрать на фазе 4. +- **Mono-лейблы рефа на английском** (`PROCESSING PIPELINE`): завести i18n- + ключи, но допустить часть английских брендовых («приборная панель»). +- **Версия в шапке/футере:** из `package.json` через `define` или + захардкодить — мелочь, решить при сборке topbar. +- **`refs/` и `refs-html/` — одноразовый источник, НЕ поддерживаемый.** + После внедрения нового дизайна все правки дизайна делаются сразу в + продакшен-коде (`design2.css` + `kit/`), а не в `refs/`. Механизм + синхронизации «ref → код» не нужен и не создаётся. `refs/` и `refs-html/` + можно удалить из репо на фазе 5 (по желанию), они не являются частью + рантайма. + +## 10. План исполнения (мелкие коммиты) + +Ветка `feat/redesign`. Каждый шаг — отдельный коммит, цель < ~500 строк. +Перед стартом: `test`/`build` зелёные на базе (якорь регрессии). + +### Шаг 0. Изоляция layout (без дизайна) + +- [ ] **[C1]** Сделать корневой `routes/+layout.svelte` нейтральным: убрать + `import '../app.css'`, оставить только init темы/locale и + `
{children}
`. +- [ ] **[C2]** Создать `routes/(old)/+layout.svelte` (импорт `app.css` + старая + шапка/подвал) и перенести старые страницы (`+page`, `demo`, `list-tools`, + `tools/[id]`) в `(old)/`. URL не меняются. Проверка: старый сайт идентичен. + _(файлы — move, объём строк минимален)_ + +### Шаг 1. Фундамент нового дизайна + +- [ ] **[C3]** Добавить `@fontsource/ibm-plex-sans` + `@fontsource/ibm-plex-mono`, + подключить шрифты в `design2.css` (self-host, offline-first). +- [ ] **[C4]** Создать `src/lib/styles/design2.css` — **только токены** `:root` + + `[data-theme='dark']` (таблица §2). Без утилитарных классов. +- [ ] **[C5]** Примитивы batch 1: `AppShell`, `BlueprintGrid`, `CheckerCanvas`, + `MonoLabel`, `StatusDot`/`StatusLine`. +- [ ] **[C6]** Примитивы batch 2: `Panel`, `PanelHeading`, `SettingGroup`, + `SettingsFooter`, `MetaRow`/`MetaList`, `Segmented`, `Badge`, `StepCard`, + `ToolCard`, `ImageCard`/`PreviewTile`. _(при превышении 500 строк — + разбить на C6a/C6b)_ +- [ ] **[C7]** Контролы: `Icon`, `IconButton`, `Button`, `Field`, `SliderField`, + `ColorField`, `TextField`, `SelectField`, `CheckboxField`, `Toggle`, + `SegmentedControl`, `EmptyState`, `CodeBlock`, `DownloadButton`. + +### Шаг 2. Витрина kit (проверка компонентов) + +- [ ] **[C8]** `preview/+layout.svelte` (импорт `design2.css` + ``) и + временная `preview/kit` страница со всеми состояниями (light/dark, + hover/disabled, варианты Button/Segmented/Badge). Проверка: визуально + против `refs-html/`, старый сайт не затронут. + +### Шаг 3. Новые страницы + +- [ ] **[C9]** `/preview` — воркспейс (eyebrow, h1, lede, поиск, «открыть последний»). +- [ ] **[C10]** `/preview/list-tools` — каталог карточек. +- [ ] **[C11]** `/preview/demo` — зеркало воркспейса (приёмочный стенд). +- [ ] **[C12]** `/preview/tools/[id]` — раскладка gradient (settings-panel + preview-panel). +- [ ] **[C13]** `/preview/tools/[id]` — раскладка background-remover (comparison-grid). +- [ ] **[C14]** step-cards для chain в tool-page. + +### Шаг 4. Переключатель и проверка + +- [ ] **[C15]** Кнопка «Preview v2» + `localStorage`-флаг в старой шапке (ведёт на + `/preview`). +- [ ] **[C16]** Смоук §8, скриншоты против `refs-html/`, прогон старых тестов + (доказательство отсутствия регресса). Фиксы по результатам — отдельными + мелкими коммитами. + +### Шаг 5. Сделать новый дизайн основным + +- [ ] **[C17]** Перенести `preview/*` → реальные маршруты (move), удалить + `(old)/`, корневой `+layout.svelte` импортирует `design2.css` + новый shell. + Убрать флаг/кнопку. +- [ ] **[C18]** Правки импортов/редиректов после переноса, проверка билда. + +### Шаг 6. Удаление старого + +- [ ] **[C19]** Удалить старое `ui/`, прочие старые компоненты, старый `app.css`, + неиспользуемые классы. Переименовать `kit/` → `ui/` (если решено на C1). +- [ ] **[C20]** Финальный проход по брейкпоинтам 1200/1100/800/480; build без + предупреждений; `grep` по старым токенам/классам пуст. +- [ ] **[C21]** _(опционально)_ Удалить `refs/` и `refs-html/` из репо — они + больше не источник правды. + +> Если какой-то коммит тянет за собой > 500 строк (например, C6/C7), +> разбивать на под-коммиты по 2–4 компонента. Тесты/билд прогонять после +> каждого коммита, чтобы регрессия локализовалась одним шагом назад.