# План: визуальное оформление и улучшение интерактивов — Физика 9

**Цель:** довести Физику 9 до качества Физики 8/10/11 — единый стиль, плавные анимации, читаемые подписи, тёмная тема, удалить Font Awesome, отрефакторить «голые» канвасы.

**Исходное состояние:** 5 глав (`physics_9_ch1..ch5.html`) + монолитный `phys9_legacy.js` (5952 строк) + 36 параграфов + 5 финалов + 12 ЛР. Legacy-код — это извлечённый монолит, всё внутри IIFE, симуляции на `<canvas>` без масштаба, цвета и подписи в стиле «школьная тетрадь».

---

## 📊 Аудит текущего состояния

### Что уже работает (после фиксов сегодня)
- Контент глав отображается, навигация по § работает.
- Подключён `phys9_legacy.js` во все 5 ch-файлов.
- Хуки `ensureBuilt` инжектят блок задач из POOLS[pN] под каждый §.
- Экспорт `window.POOLS`, `window.STATE`, `window.startAnim*`, `window.upd*`, `window.draw*`.
- Все 36 пулов `TASKS_P1..P36 + TASKS_HARD` доступны.

### Что не так визуально
| # | Проблема | Где | Влияние |
|---|----------|-----|---------|
| 1 | **Font Awesome** иконки (`fas fa-*`) — нарушение проектной политики «только inline SVG `.ic`» | `phys9_legacy.js` (8 мест) + ch1 (1) | Несогласованность с остальным каталогом |
| 2 | **30+ канвасов без масштаба** — `cv1..cv30` рисуются по px-координатам, не подписаны единицами, цвета случайные | `phys9_legacy.js` все `upd*` / `draw*` | Не читаются на мобильных, выглядят «школьно» |
| 3 | **Нет цветовой кодировки** по типу величины (масса, скорость, сила) | везде | Учащийся не отличает кинематические/динамические величины |
| 4 | **Тёмная тема не покрывает legacy-элементы** — стрелки, оси, текст всегда чёрные | canvas-рендер в legacy | На тёмной теме нечитаемо |
| 5 | **Подписи на канвасах**: `Arial 12px`, мелко, не масштабируется | `ctx.font = '12px sans-serif'` | Плохо на больших экранах и на мобильных |
| 6 | **Кнопки-управление симуляциями** разнородные: где `<button class="btn">`, где `<input type="range">` без подписей | разные параграфы | Нет единого UX |
| 7 | **Анимации без паузы / сброса** — startAnim1, startAnim15 запускаются автоматически, остановить нельзя | `phys9_legacy.js:start*` | Жжёт CPU на фоне |
| 8 | **Графики $T(t)$, $v(t)$ нарисованы вручную** через `lineTo` — без сетки, без подписей осей в СИ | `upd9`, `upd11`, `upd13` | Бесполезны для понимания |
| 9 | **Нет «3 видов задач»** — есть только пул задач из POOLS, нет калькуляторов и DnD-сортировок (как в Физике 8/10) | архитектура | Меньше вовлечения |
| 10 | **CSS-перегружен** — есть `.fcard`, `.formula-grid`, `.section-title`, `.para-hero`, `.ph-tag`, `.ph-tags`, `.ph-formula` — устаревшая визуальная стилистика | inline `<style>` в ch1..ch5 | Тяжело сопровождать |
| 11 | **Финалы** глав (`final1..final5`) — заглушки без интегрированных боссов и ачивок | builders в ch | Нет «магистра» главы |
| 12 | **ЛР 1-12 в ch5** — ссылаются на `cvLab11`, но `drawLab11` пишет напрямую координаты грузов в граммах с маленькими подписями | `phys9_legacy.js` | Не похоже на «лабораторный отчёт» |

---

## 🎨 Целевой облик (как у Физики 8/10/11)

1. **SVG-канвасы вместо `<canvas>`** где можно — векторные, масштабируемые, темнее/светлее по теме.
2. **Цветовая кодировка:**
   - Скорость $\vec v$ — голубой `#0891b2`
   - Ускорение $\vec a$ — оранжевый `#ea580c`
   - Сила $\vec F$ — зелёный `#10b981`
   - Масса/тело — серый `#475569`
   - Сила тяжести — синий `#2563eb`
   - Сила трения — фиолетовый `#7c3aed`
3. **Хелперы** общие с другими физиками: `phys.js` (`drawArrow`, `axes2D`, `plotFunc`).
4. **Каждый интерактив:**
   - Slider'ы с подписями единиц (м/с, м/с², Н)
   - Кнопки **Пауза / Сброс**
   - `cancelAnimationFrame` при unmount
   - Текстовая «выкладка» текущих значений в `.score-display`
5. **Тёмная тема:** SVG использует `currentColor` или CSS-переменные, не хардкод `#000`.
6. **Финал главы:** шпаргалка + 5-10 интегрированных боссов + ачивка `master_chN`.

---

## 🚀 Фазы реализации

### Phase 0 — Аудит и подготовка (1 коммит)
- [ ] Список всех 30+ канвасов с описанием: что симулирует, какие параметры, какой §
- [ ] Список всех `upd*` / `draw*` / `startAnim*` с их вход/выход
- [ ] Решение: какие canvas → SVG, какие оставить (большие частицы/тысячи точек)
- [ ] Перечислить все `fa-*` → план замены на inline SVG `.ic`
- [ ] Документ: `plans/textbooks-9/PHYS9_INTERACTIVES_INVENTORY.md`

### Phase 1 — Удаление Font Awesome из физики 9 (1 коммит)
- [ ] Заменить все 8 вхождений `<i class="fas fa-*">` в `phys9_legacy.js` на inline SVG
- [ ] Заменить 1 вхождение в `physics_9_ch1.html`
- [ ] Удалить `<link rel=stylesheet ... font-awesome>` из ch-страниц
- [ ] Smoke-test: открыть все 5 ch — иконки сохранились

### Phase 2 — Цветовая кодировка и легенда (1 коммит)
- [ ] Создать `frontend/js/phys9_palette.js` — единый объект `PHYS9_COLORS`
- [ ] Перенести жёстко закодированные цвета (`fillStyle = '#xxx'`) на ссылки `PHYS9_COLORS.velocity` и т.д.
- [ ] Создать `frontend/css/phys9-canvas.css` — переменные для тёмной темы
- [ ] Использовать `getComputedStyle` для текущего цвета (поддержка тёмной темы автоматом)

### Phase 3 — Стандарт SVG-визуализации (3-5 коммитов)
Большинство канвасов — это статические сцены: брусок + сила + стрелка. Их можно перевести на SVG.

**Канвасы-кандидаты на SVG:**
- §3 `drawArrow3` — вектор силы (просто SVG `<line>` + `<polygon>`)
- §10 `upd10` (касательная/нормальная скорость)
- §11 `upd11` (равноуск. движение, графики $v(t)$, $s(t)$)
- §19 `drawSpring19` (пружина)
- §20 `drawFriction20` (брусок + трение)
- §23 `drawGravity23` (сила тяжести)
- §24 `drawElevator24` (лифт + вес)
- §25 `drawSeesaw25` (рычаг)
- §26 `drawLever26` (рычаг 2-го рода)
- §28 `drawEquilibrium28` (рычаг + плечи)
- §29 `drawArchimedes29` (плавание тел)
- §30 `drawShip30` (корабль)

**Оставить на canvas (анимации с многими точками):**
- §1 `startAnim1` — Броуновское движение, 30+ частиц
- §15 `startAnim15` — гравитация / движение планет
- §17 `startAnim17` — равномерное движение по окружности
- §22 `drawAngularThrow22` — баллистика с траекторией

Каждый SVG-перенос:
- 1 коммит на 2-3 канваса
- Использовать `phys.js` хелперы (`drawArrow`, `axes2D`, `plotFunc`)
- Сохранить функцию-обёртку с тем же именем, чтобы legacy кнопки `onclick="upd23()"` продолжали работать

### Phase 4 — Графики $T(t)$, $v(t)$, $s(t)$ через `phys.js` (2 коммита)
- [ ] §9 — графики координаты от времени
- [ ] §11 — равноуск. движение, $v$-$t$, $s$-$t$
- [ ] §13 — графики ускорения
- [ ] §14 — графики $v$ при разных $a$

Унифицировать оси (СИ, шкала, надписи), цвета (`PHYS9_COLORS`), легенду.

### Phase 5 — Тёмная тема для всех визуализаций (1 коммит)
- [ ] Все SVG: использовать `currentColor` / CSS-переменные
- [ ] Canvas: проверять `document.documentElement.classList.contains('dark')` и менять `ctx.strokeStyle`
- [ ] Сетка + оси: `var(--border)` вместо `#ccc`
- [ ] Текстовые подписи: `var(--text)` вместо `#000`

### Phase 6 — Управление симуляциями (2 коммита)
- [ ] Все `startAnim*` получают кнопки **Пауза/Запуск/Сброс**
- [ ] При смене параграфа (`goTo`) — отменять текущие `requestAnimationFrame`
- [ ] Slider'ы — с подписями единиц (м/с, °, кг)
- [ ] Текстовая выкладка: `.score-display` с текущими значениями

### Phase 7 — Калькуляторы и DnD как в Физике 8/10 (3-5 коммитов)
В монолите Физики 9 нет калькуляторов и DnD-сортировок — только пулы задач. Это упущение.

**Добавить для каждой главы 1-2 калькулятора:**
- Глава 1: калькулятор $s = v_0 t + at^2/2$ + DnD «равномерное / равноуск.»
- Глава 2: калькулятор $F = ma$ + DnD «причина / следствие»
- Глава 3: калькулятор плечей рычага + DnD «выигрыш в силе / расстоянии»
- Глава 4: калькулятор Архимеда + DnD «плавает / тонет»
- Глава 5: калькулятор периода маятника + DnD «механ. / эл. колебания»

Каждый — отдельная `<div class="wg">` карточка под секцией §, как в Физике 8.

### Phase 8 — Финалы глав (5 коммитов, по 1 на главу)
Сейчас `final1..final5` — пустышки. Сделать как у Физики 8:
- Шпаргалка по главе (6-10 формул)
- 5-10 интегрированных боссов (числовые задачи с подсказками)
- Ачивка `physics9_chN_master` (+50 XP)
- Кнопка перехода к следующей главе

### Phase 9 — Лабораторный практикум ch5 (1-2 коммита)
12 ЛР сейчас — голые таблицы. Сделать как у Физики 8:
- Цель работы (карточка)
- Оборудование (список)
- Ход работы (нумерованный)
- Виртуальная установка (SVG-симуляция)
- Таблица измерений с автозаполнением
- Калькулятор результата
- Кнопка «Сдать работу (+30 XP)»
- Ачивка `physics9_lab_master` (+50 XP) после всех 12

### Phase 10 — Респонсивность и a11y (1 коммит)
- [ ] Все SVG/canvas с `width:100%;height:auto;max-width:600px`
- [ ] Шрифты подписей: `clamp(11px, 1vw, 14px)`
- [ ] `aria-label` на интерактивных SVG-элементах
- [ ] `role="img"` на статических SVG

### Phase 11 — Удаление legacy CSS (1 коммит)
- [ ] Перенести стили `.fcard`, `.formula-grid`, `.section-title`, `.para-hero`, `.ph-tag`, `.ph-tags`, `.ph-formula` в `frontend/css/phys9-theme.css`
- [ ] Удалить дублирование из 5 ch-файлов (CSS сейчас инлайн в каждом)
- [ ] Подключить общий файл

### Phase 12 — Полное ревью + KaTeX-аудит (1 коммит)
- [ ] Smoke-test всех 36 § в браузере (light + dark)
- [ ] KaTeX-аудит: `[^\\]\\[a-zA-Z]{2,}` в JS-блоках (одинарный backslash где не надо)
- [ ] JS parse-check всех 5 ch + legacy.js
- [ ] Проверка: ни одного `console.log/warn/error` debug-вызова в hot-path

---

## 📦 Оценка объёма

| Phase | Коммитов | LOC изм. | Приоритет |
|-------|----------|----------|-----------|
| 0 — Аудит | 1 | 300 (документ) | КРИТИЧНО |
| 1 — Удаление FA | 1 | ~30 | КРИТИЧНО |
| 2 — Цветовая кодировка | 1 | ~200 | ВЫСОКО |
| 3 — SVG визуализация | 5 | ~1500 | ВЫСОКО |
| 4 — Графики | 2 | ~400 | ВЫСОКО |
| 5 — Тёмная тема | 1 | ~200 | СРЕДНЕ |
| 6 — Управление симуляциями | 2 | ~300 | СРЕДНЕ |
| 7 — Калькуляторы / DnD | 5 | ~1500 | СРЕДНЕ |
| 8 — Финалы глав | 5 | ~1000 | ВЫСОКО |
| 9 — ЛР практикум | 2 | ~600 | СРЕДНЕ |
| 10 — Респонсив / a11y | 1 | ~200 | НИЗКО |
| 11 — Очистка CSS | 1 | ~100 (-) | НИЗКО |
| 12 — Финальное ревью | 1 | ~50 | КРИТИЧНО |
| **Итого** | **~28 коммитов** | **~6 400 LOC** | |

---

## ⚠️ Архитектурное предупреждение

`phys9_legacy.js` **генерируется** скриптом [backend/scripts/extract_phys9_legacy.cjs](backend/scripts/extract_phys9_legacy.cjs) из монолита `physics_9.html`. **Все ручные правки исчезнут**, если кто-то запустит экстрактор повторно.

**Два пути:**

**Путь A (быстрый, hacky):** править `phys9_legacy.js` напрямую и заморозить экстрактор (переименовать с пометкой `DO_NOT_RUN_anymore.cjs`).

**Путь B (правильный, долгий):** переписать ch1..ch5 на конвенцию Физики 8/10:
- Каждый параграф — `build_pN()` в inline `<script>`, без legacy
- POOLS_PN перенести в каждую главу-файл как локальный объект
- Удалить `phys9_legacy.js` целиком
- Тогда хелперы из `phys.js` будут использоваться нативно

**Рекомендация:** для критичных фиксов (Phase 1, 2, 8, 12) — путь B, в новой архитектуре. Для остальных — путь A, с заморозкой экстрактора.

---

## 🎬 Запуск

1. **Phase 0** — сделать инвентаризацию (`PHYS9_INTERACTIVES_INVENTORY.md`).
2. **Phase 1** — удалить Font Awesome (быстрая победа, заметна сразу).
3. Решить путь A или B.
4. Если B — начать с ch1 (большой объём — 14 §, можно как pilot).
5. Дальше по приоритету: финалы → SVG-визуализации → калькуляторы.

После Phase 1-3 курс уже будет выглядеть «как остальные учебники проекта». Phase 4-9 — углубление качества. Phase 10-12 — полировка.

---

## 🔗 Связанные документы

- [PLAN_PHYSICS_9.md](PLAN_PHYSICS_9.md) — исходный план учебника
- [PLAN_PHYSICS_8.md](../textbooks-8/PLAN_PHYSICS_8.md) — образец архитектуры
- [PLAN_PHYSICS_10.md](../textbooks-10/PLAN_PHYSICS_10.md) — образец визуализации (canvas + SVG)
