mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-09-14 21:46:35 +00:00
386 lines
30 KiB
Markdown
386 lines
30 KiB
Markdown
# План: переезд на новый дизайн (refs) — параллельная сборка
|
||
|
||
> Статус: план к выполнению.
|
||
>
|
||
> Источники: `refs/` — Next/React-референс (правда по пикселям и интерактиву),
|
||
> `refs-html/` — статические HTML-снимки для быстрого просмотра в браузере.
|
||
>
|
||
> **Стратегия изменена.** Вместо in-place рестайла (старый план A–F, правка
|
||
> общих компонентов на месте с алиасами токенов) — **параллельная сборка**:
|
||
> новый дизайн строится отдельно, изолируется от старого, проверяется
|
||
> целиком, затем становится основным и старый удаляется. Старое приложение
|
||
> остаётся рабочим и шippable на всём протяжении перехода.
|
||
|
||
## 0. Почему меняем стратегию
|
||
|
||
- **Старый план (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.
|
||
|
||
## 1. Источники и их оценка
|
||
|
||
### `refs-html/` — витрина разметки
|
||
|
||
Покрытие достаточное:
|
||
|
||
| Файл | Что показывает | Оценка |
|
||
| ------------------------- | ----------------------------------------- | ---------------- |
|
||
| `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 |
|
||
| -------------- | -------------- | --------- | ------------------------ |
|
||
| `--bg` | `--background` | `#eef1f4` | `#11171d` |
|
||
| `--surface` | `--panel` | `#f8fafb` | `#182129` |
|
||
| `--text` | `--foreground` | `#17212b` | `#e8eef2` |
|
||
| `--text-muted` | `--muted` | `#6d7883` | `#91a0ac` |
|
||
| `--border` | `--line` | `#cbd3da` | `#33414c` |
|
||
| `--accent` | `--blue` | `#1769d2` | `#54a2ff` |
|
||
| — | `--cyan` | `#00a8c7` | `#00a8c7` |
|
||
| — | `--amber` | `#bd7411` | `#bd7411` |
|
||
| — | `--success` | `#25a96a` | `#25a96a` (статус-точки) |
|
||
| `--danger` | без изменений | `#e5484d` | `#ff7479` |
|
||
|
||
Прочее:
|
||
|
||
- Радиусы: один `--radius: 4px` (мягкость старой темы уходит).
|
||
- Шрифты: `IBM Plex Sans` + `IBM Plex Mono`, self-host через `@fontsource`
|
||
(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. Базовые примитивы дизайн-системы (все — компоненты)
|
||
|
||
Правило фазы 1: **любой повторяющийся паттерн — компонент**, даже «просто
|
||
div с двумя стилями». Никакой копипасты классов между страницами. Каждый
|
||
примитив ниже — отдельный `.svelte` в `src/lib/components/kit/`.
|
||
|
||
- `MonoLabel` — микро-лейбл: mono 10px, uppercase, letter-spacing .1em,
|
||
muted; слот-модификатор accent (синие eyebrow/version).
|
||
- `StatusDot` / `StatusLine` — точка `--success` + подпись
|
||
(«AUTO PIPELINE», «LIVE PREVIEW»).
|
||
- `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/kit/`)
|
||
|
||
Контролы, поверх примитивов §3. API проектируем сразу под новый дизайн
|
||
(обратной совместимости со старым `ui/` не нужно — старые страницы его
|
||
продолжают использовать).
|
||
|
||
| Компонент | Назначение |
|
||
| ------------------------- | ----------------------------------------------------------------- |
|
||
| `Button.svelte` | `primary` (solid blue) / `secondary` (outline) / `ghost` + `icon` |
|
||
| `Field.svelte` | обёртка: `MonoLabel` + слот значения/контрола |
|
||
| `SliderField.svelte` | range + `<output>`, опц. строка подсказок |
|
||
| `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-svelte` (те же пути, MIT), 16–17px, stroke, muted.
|
||
|
||
## 5. Изоляция старого и нового (критично)
|
||
|
||
Без префиксов и обёрток — только за счёт того, какие layout грузят какой CSS.
|
||
|
||
- **Корневой layout `src/routes/+layout.svelte`** перестаёт импортировать
|
||
`../app.css`. В нём остаётся только общая логика (init темы/locale) и
|
||
нейтральный `<div>{children}</div>` без глобальных стилей дизайна.
|
||
- **Старая ветка `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` и рендерит `<AppShell>`. Сюда же — новые страницы (§6).
|
||
- Благодаря code-splitting CSS в SvelteKit: на старых маршрутах грузится
|
||
только `app.css`, на `preview/*` — только `design2.css`. Скоуп стилей
|
||
Svelte-компонентов добавляет второй уровень изоляции. Никаких `.ds2`.
|
||
- Переключатель для ручной проверки: временный флаг `previewDesign` в
|
||
`localStorage` + кнопка в старой шапке («Preview v2»), ведущая на
|
||
`/preview`. На фазе 4 флаг убираем.
|
||
|
||
> Почему не `(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.
|
||
|
||
## 6. Маршрутизация параллельных страниц
|
||
|
||
Новые страницы живут в **отдельной ветке `preview/*`**, не трогая старые:
|
||
|
||
```txt
|
||
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, <AppShell>
|
||
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
|
||
```
|
||
|
||
- Каждая новая страница импортирует **только** `kit/*`. Старые страницы
|
||
не изменяются (только перемещены в `(old)/`).
|
||
- Фаза 4: содержимое `preview/*` переносится на реальные маршруты
|
||
(move-файлы), группа `(old)/` удаляется, `design2.css` подключается в
|
||
корневом `+layout.svelte` (как новый основной слой), временный флаг/кнопка
|
||
убираются.
|
||
|
||
## 7. Фазы выполнения (1–5 по запросу)
|
||
|
||
Каждая фаза заканчивается зелёными `test`/`check`/`build` и ревью в браузере
|
||
(обе темы) против `refs-html/`.
|
||
|
||
- **Фаза 1 — Фундамент + UI-kit.** Токены §2, `design2.css` по §5, все
|
||
примитивы §3 и контролы §4 как отдельные компоненты. Критерий:
|
||
демо-страница kit'а (`/preview` или временная) показывает все состояния
|
||
(light/dark, hover/disabled, все варианты Button/Segmented/Badge);
|
||
unit-тесты форм не падают; **старые страницы визуально не изменились**
|
||
(изоляция работает).
|
||
|
||
- **Фаза 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 3 — Проверка нового дизайна.** Смоук §8 (обе темы, узкий экран,
|
||
800px), скриншоты против `refs-html/`, прогон старого тест-сьюта для
|
||
доказательства отсутствия регресса, RU/EN-локализация новых лейблов.
|
||
Критерий: визуальное совпадение с рефом, зелёные тесты, записанные
|
||
скриншоты приняты.
|
||
|
||
- **Фаза 4 — Сделать новый дизайн основным.** Перенос `preview/*` →
|
||
реальные маршруты; `design2.css` подключается в корневом `+layout.svelte`;
|
||
удаление preview-группы и временного флага/кнопки. Старые страницы теперь
|
||
не используются (мёртвый код), но физически ещё в репо.
|
||
Критерий: реальные маршруты отдают новый дизайн, тесты зелёные, билд без
|
||
предупреждений.
|
||
|
||
- **Фаза 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-лейблов достаточный.
|
||
2. Инструмент с параметрами (градиент): slider/color/toggle в стиле
|
||
setting-groups, автозапуск не регрессировал.
|
||
3. Удаление фона: сравнение source/result, маска, пипетка работают на новой
|
||
шахматке.
|
||
4. Chain из 3+ инструментов: step-cards рендерятся, удаление/сброс работают.
|
||
5. Узкий экран 800px: настройки над превью, sticky выключается как в рефе.
|
||
6. RU/EN: новые лейблы локализованы; mono-лейблы рефа — либо ключи i18n,
|
||
либо осознанно английские брендовые элементы (см. §9).
|
||
|
||
## 9. Открытые вопросы
|
||
|
||
- **Имя финального каталога компонентов:** оставить `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 (без дизайна)
|
||
|
||
- [x] **[C1]** Сделать корневой `routes/+layout.svelte` нейтральным: убрать
|
||
`import '../app.css'`, оставить только init темы/locale и
|
||
`<div>{children}</div>`.
|
||
- [x] **[C2]** Создать `routes/(old)/+layout.svelte` (импорт `app.css` + старая
|
||
шапка/подвал) и перенести старые страницы (`+page`, `demo`, `list-tools`,
|
||
`tools/[id]`) в `(old)/`. URL не меняются. Проверка: старый сайт идентичен.
|
||
_(файлы — move, объём строк минимален)_
|
||
|
||
### Шаг 1. Фундамент нового дизайна
|
||
|
||
- [x] **[C3]** Создать `src/lib/styles/design2.css` (токены `:root` + `[data-theme='dark']` по §2) и подключить `@fontsource/ibm-plex-sans` + `@fontsource/ibm-plex-mono` (self-host, offline-first).
|
||
подключить шрифты в `design2.css` (self-host, offline-first).
|
||
- [x] **[C4]** _(слит в C3: шрифты нельзя подключить до создания `design2.css`)_
|
||
`[data-theme='dark']` (таблица §2). Без утилитарных классов.
|
||
- [x] **[C5]** Примитивы batch 1: `AppShell`, `BlueprintGrid`, `CheckerCanvas`,
|
||
`MonoLabel`, `StatusDot`/`StatusLine`.
|
||
- [x] **[C6]** Примитивы batch 2: `Panel`, `PanelHeading`, `SettingGroup`,
|
||
`SettingsFooter`, `MetaRow`/`MetaList`, `Segmented`, `Badge`, `StepCard`,
|
||
`ToolCard`, `ImageCard`/`PreviewTile`.
|
||
- [x] **[C7]** Контролы: `Icon`, `IconButton`, `Button`, `Field`, `SliderField`,
|
||
`ColorField`, `TextField`, `SelectField`, `CheckboxField`, `Toggle`,
|
||
`SegmentedControl` (= `Segmented` из C6), `EmptyState`, `CodeBlock`,
|
||
`DownloadButton`.
|
||
|
||
### Шаг 2. Витрина kit (проверка компонентов)
|
||
|
||
- [ ] **[C8]** `preview/+layout.svelte` (импорт `design2.css` + `<AppShell>`) и
|
||
временная `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.
|
||
Убрать флаг/кнопку. **И обновить `newCode` в `web/eslint.config.js`:** заменить
|
||
`src/routes/preview/**` на `src/routes/**` (после переезда все маршруты —
|
||
новый дизайн), компонентный glob `src/lib/components/kit/**` пока оставить.
|
||
- [ ] **[C18]** Правки импортов/редиректов после переноса, проверка билда.
|
||
|
||
### Шаг 6. Удаление старого
|
||
|
||
- [ ] **[C19]** Удалить старое `ui/`, прочие старые компоненты, старый `app.css`,
|
||
неиспользуемые классы. Переименовать `kit/` → `ui/` (если решено на C1 —
|
||
тогда в `eslint.config.js` обновить и компонентный glob).
|
||
**И раскрыть ESLint `recommended` на весь код** — убрать scoped-блок
|
||
`newCode` в `web/eslint.config.js` (см. AGENTS.md), прогнать `lint` и
|
||
починить всплывшие ошибки в оставшемся коде.
|
||
_Примечание: доменные модули (`lib/core`, `lib/registry`, тесты и т.п.) —
|
||
это не «старый дизайн», у них свой линт-долг; расширение `recommended` на
|
||
них может выдать много ошибок. Решить на C19: либо чиним сразу, либо
|
||
расширяем scoped только на `src/routes/**` + `src/lib/components/**`._
|
||
- [ ] **[C20]** Финальный проход по брейкпоинтам 1200/1100/800/480; build без
|
||
предупреждений; `grep` по старым токенам/классам пуст.
|
||
- [ ] **[C21]** _(опционально)_ Удалить `refs/` и `refs-html/` из репо — они
|
||
больше не источник правды.
|
||
|
||
> Если какой-то коммит тянет за собой > 500 строк (например, C6/C7),
|
||
> разбивать на под-коммиты по 2–4 компонента. Тесты/билд прогонять после
|
||
> каждого коммита, чтобы регрессия локализовалась одним шагом назад.
|
||
>
|
||
> **Атомарность и точки «поломки» между коммитами.**
|
||
>
|
||
> - C1+C2 уже сделаны вместе (связаны: нейтральный root без `(old)`-layout
|
||
> ломает старый сайт). Аналогично связанных пар больше нет.
|
||
> - C3 и C4 слиты: шрифты подключаются внутри `design2.css`, поэтому файл
|
||
> должен существовать в том же коммите.
|
||
> - Коммиты **C3→C16 не трогают старый сайт** `(old)/` — они только
|
||
> добавляют новые файлы/маршруты, сломать старый сайт на них нельзя.
|
||
> - **C17 — единственный атомарный переключатель**: перенос `preview/*` на
|
||
> реальные пути + удаление `(old)/` + смена root-layout должны быть в
|
||
> ОДНОМ коммите (иначе конфликт маршрутов или пропажа страниц). Не дробить.
|
||
> - **C19 должен идти строго после C17** (старый `app.css`/`ui/` удаляем
|
||
> только когда old-сайт уже выключен).
|
||
> - Очерёдность зависимостей: `design2.css` (C3) и kit-компоненты (C5–C7)
|
||
> должны существовать до страниц, которые их импортируют (C8–C14).
|