diff --git a/backend/src/db/migrations/030_physics_10_hub.sql b/backend/src/db/migrations/030_physics_10_hub.sql
new file mode 100644
index 0000000..5062a54
--- /dev/null
+++ b/backend/src/db/migrations/030_physics_10_hub.sql
@@ -0,0 +1,40 @@
+-- Physics 10 hub migration.
+-- Adds hub row + 6 chapter children for Физика 10 (Беларусь, 2019).
+-- Pattern mirrors 025_algebra_11_hub.sql.
+
+-- 1. Hub row.
+INSERT INTO textbooks
+ (slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active)
+VALUES
+ ('physics-10', 'physics', 10, 'Физика — 10 класс', '',
+ 'Полный курс физики 10 класса: молекулярная физика, термодинамика, электростатика, ток, магнитное поле, ток в средах. 6 глав, 37 параграфов.',
+ 'physics_10_hub.html', 37, 'amber', 11, 1);
+
+-- 2. Chapter children.
+INSERT INTO textbooks
+ (slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active, parent_slug)
+VALUES
+ ('physics-10-ch1', 'physics', 10, 'Физика 10 · Основы МКТ',
+ '',
+ '§1–§10: молекулярно-кинетическая теория, идеальный газ, изопроцессы, строение твёрдых тел и жидкостей, влажность воздуха.',
+ 'physics_10_ch1.html', 10, 'blue', 1, 1, 'physics-10'),
+ ('physics-10-ch2', 'physics', 10, 'Физика 10 · Термодинамика',
+ '',
+ '§11–§15: внутренняя энергия, работа и количество теплоты, первый закон термодинамики, тепловые двигатели, цикл Карно.',
+ 'physics_10_ch2.html', 5, 'green', 2, 1, 'physics-10'),
+ ('physics-10-ch3', 'physics', 10, 'Физика 10 · Электростатика',
+ '',
+ '§16–§24: электрический заряд, закон Кулона, напряжённость и потенциал электростатического поля, конденсаторы, энергия поля.',
+ 'physics_10_ch3.html', 9, 'violet', 3, 1, 'physics-10'),
+ ('physics-10-ch4', 'physics', 10, 'Физика 10 · Постоянный ток',
+ '',
+ '§25–§26: ЭДС источника, закон Ома для полной электрической цепи, КПД источника.',
+ 'physics_10_ch4.html', 2, 'pink', 4, 1, 'physics-10'),
+ ('physics-10-ch5', 'physics', 10, 'Физика 10 · Магнитное поле и ЭМИ',
+ '',
+ '§27–§33: магнитное поле, сила Ампера, сила Лоренца, электромагнитная индукция, закон Фарадея, самоиндукция.',
+ 'physics_10_ch5.html', 7, 'cyan', 5, 1, 'physics-10'),
+ ('physics-10-ch6', 'physics', 10, 'Физика 10 · Ток в различных средах',
+ '',
+ '§34–§37: электрический ток в металлах и сверхпроводимость, электролиз, разряды в газах и плазма, полупроводники.',
+ 'physics_10_ch6.html', 4, 'emerald', 6, 1, 'physics-10');
diff --git a/frontend/js/phys.js b/frontend/js/phys.js
new file mode 100644
index 0000000..ccca6d9
--- /dev/null
+++ b/frontend/js/phys.js
@@ -0,0 +1,252 @@
+// phys.js — модуль физических хелперов для учебника Физика 10
+// Экспорт в window.PHYS = { ... }
+(function(){
+'use strict';
+
+// === Стрелка вектора (2D) ===
+function drawArrow(x1, y1, x2, y2, color, width, headSize) {
+ width = width || 2;
+ headSize = headSize || 10;
+ const dx = x2 - x1, dy = y2 - y1;
+ const len = Math.sqrt(dx*dx + dy*dy);
+ if (len < 1e-6) return '';
+ const ux = dx / len, uy = dy / len;
+ const px = -uy, py = ux;
+ const h = headSize, w = headSize * 0.6;
+ const bx = x2 - ux*h, by = y2 - uy*h;
+ const lx = bx + px*w, ly = by + py*w;
+ const rx = bx - px*w, ry = by - py*w;
+ return ` `
+ + ` `;
+}
+
+// === Линии электрического поля от точечного заряда ===
+function fieldLinesPointCharge(cx, cy, sign, scale, numLines) {
+ numLines = numLines || 16;
+ scale = scale || 80;
+ let s = '';
+ const color = sign > 0 ? '#dc2626' : '#2563eb';
+ for (let i = 0; i < numLines; i++) {
+ const a = 2 * Math.PI * i / numLines;
+ const r1 = 18, r2 = scale;
+ const x1 = cx + r1*Math.cos(a), y1 = cy + r1*Math.sin(a);
+ const x2 = cx + r2*Math.cos(a), y2 = cy + r2*Math.sin(a);
+ if (sign > 0) s += drawArrow(x1, y1, x2, y2, color, 1.4, 7);
+ else s += drawArrow(x2, y2, x1, y1, color, 1.4, 7);
+ }
+ return s;
+}
+
+// === Обозначение заряда (кружок с +/-) ===
+function chargeMark(cx, cy, sign, r, label) {
+ r = r || 14;
+ const color = sign > 0 ? '#dc2626' : '#2563eb';
+ const fill = sign > 0 ? '#fecaca' : '#bfdbfe';
+ let s = '';
+ s += ` `;
+ if (sign > 0) {
+ s += ` `;
+ s += ` `;
+ } else {
+ s += ` `;
+ }
+ if (label) {
+ s += `${label} `;
+ }
+ return s;
+}
+
+// === Магнитное поле сквозь экран (сетка крестиков или точек) ===
+function magneticFieldGrid(x0, y0, w, h, cols, rows, direction) {
+ // direction: 'in' = крест (× — вошло в плоскость), 'out' = точка (• — вышло)
+ let s = '';
+ const dx = w / (cols - 1), dy = h / (rows - 1);
+ const color = '#7c3aed';
+ for (let i = 0; i < cols; i++) {
+ for (let j = 0; j < rows; j++) {
+ const cx = x0 + i * dx, cy = y0 + j * dy;
+ s += ` `;
+ if (direction === 'in') {
+ s += ` `;
+ s += ` `;
+ } else {
+ s += ` `;
+ }
+ }
+ }
+ return s;
+}
+
+// === Молекула газа (частица) ===
+function molecule(x, y, r, color) {
+ r = r || 4;
+ color = color || '#2563eb';
+ return ` `;
+}
+
+// === Симуляция газа (упругое столкновение со стенками) ===
+function createGasSim(opts) {
+ opts = opts || {};
+ const N = opts.N || 30;
+ const W = opts.W || 320;
+ const H = opts.H || 220;
+ const baseSpeed = opts.speed || 60; // px/s
+ const r = opts.r || 4;
+ const particles = [];
+ for (let i = 0; i < N; i++) {
+ particles.push({
+ x: r + Math.random() * (W - 2*r),
+ y: r + Math.random() * (H - 2*r),
+ vx: (Math.random() - 0.5) * 2 * baseSpeed,
+ vy: (Math.random() - 0.5) * 2 * baseSpeed
+ });
+ }
+ return {
+ W: W, H: H, r: r, particles: particles,
+ step(dt) {
+ for (const p of particles) {
+ p.x += p.vx * dt; p.y += p.vy * dt;
+ if (p.x < r) { p.x = r; p.vx = -p.vx; }
+ if (p.x > W - r) { p.x = W - r; p.vx = -p.vx; }
+ if (p.y < r) { p.y = r; p.vy = -p.vy; }
+ if (p.y > H - r) { p.y = H - r; p.vy = -p.vy; }
+ }
+ },
+ render(color) {
+ color = color || '#2563eb';
+ return particles.map(p => molecule(p.x, p.y, r, color)).join('');
+ },
+ setSpeed(scale) {
+ for (const p of particles) { p.vx *= scale; p.vy *= scale; }
+ }
+ };
+}
+
+// === Электрические схемы: компоненты ===
+// orientation: 'h' (горизонтально, по умолчанию) или 'v' (вертикально)
+function batteryEMF(x, y, EMF, orientation) {
+ orientation = orientation || 'h';
+ let s = '';
+ if (orientation === 'h') {
+ s += ` `;
+ s += ` `;
+ s += `+ `;
+ s += `− `;
+ if (EMF !== undefined) s += `ε = ${EMF} `;
+ } else {
+ s += ` `;
+ s += ` `;
+ if (EMF !== undefined) s += `ε = ${EMF} `;
+ }
+ return s;
+}
+
+function resistor(x, y, R, orientation) {
+ orientation = orientation || 'h';
+ let s = '';
+ if (orientation === 'h') {
+ s += ` `;
+ if (R !== undefined) s += `R = ${R} `;
+ } else {
+ s += ` `;
+ if (R !== undefined) s += `R = ${R} `;
+ }
+ return s;
+}
+
+function capacitorSymbol(x, y, C, orientation) {
+ orientation = orientation || 'h';
+ let s = '';
+ if (orientation === 'h') {
+ s += ` `;
+ s += ` `;
+ if (C !== undefined) s += `C = ${C} `;
+ }
+ return s;
+}
+
+function ammeterSymbol(x, y, r) {
+ r = r || 14;
+ return ` `
+ + `A `;
+}
+
+function voltmeterSymbol(x, y, r) {
+ r = r || 14;
+ return ` `
+ + `V `;
+}
+
+function lightbulbSymbol(x, y, r) {
+ r = r || 14;
+ let s = '';
+ s += ` `;
+ s += ` `;
+ s += ` `;
+ return s;
+}
+
+function inductorSymbol(x, y, L, orientation) {
+ orientation = orientation || 'h';
+ let s = '';
+ if (orientation === 'h') {
+ for (let i = 0; i < 4; i++) {
+ const cx = x - 15 + i * 10;
+ s += ` `;
+ }
+ if (L !== undefined) s += `L = ${L} `;
+ }
+ return s;
+}
+
+function wire(x1, y1, x2, y2) {
+ return ` `;
+}
+
+// === Эталонные константы ===
+const CONST = {
+ k: 9e9, // Кулона
+ e: 1.6e-19, // элементарный заряд
+ eps0: 8.85e-12, // электрическая постоянная
+ kB: 1.38e-23, // Больцмана
+ NA: 6.022e23, // Авогадро
+ R: 8.314, // универсальная газовая
+ c: 3e8, // скорость света
+ g: 9.8, // ускорение свободного падения
+ atm: 101325, // 1 атм в Па
+ T0: 273.15 // ноль Цельсия в К
+};
+
+// === Конвертеры единиц ===
+function celsiusToKelvin(t) { return t + 273.15; }
+function kelvinToCelsius(T) { return T - 273.15; }
+function atmToPa(p) { return p * 101325; }
+function paToAtm(p) { return p / 101325; }
+function litersToM3(V) { return V / 1000; }
+function m3ToLiters(V) { return V * 1000; }
+
+// === Экспорт ===
+window.PHYS = {
+ drawArrow: drawArrow,
+ fieldLinesPointCharge: fieldLinesPointCharge,
+ chargeMark: chargeMark,
+ magneticFieldGrid: magneticFieldGrid,
+ molecule: molecule,
+ createGasSim: createGasSim,
+ batteryEMF: batteryEMF,
+ resistor: resistor,
+ capacitorSymbol: capacitorSymbol,
+ ammeterSymbol: ammeterSymbol,
+ voltmeterSymbol: voltmeterSymbol,
+ lightbulbSymbol: lightbulbSymbol,
+ inductorSymbol: inductorSymbol,
+ wire: wire,
+ CONST: CONST,
+ celsiusToKelvin: celsiusToKelvin,
+ kelvinToCelsius: kelvinToCelsius,
+ atmToPa: atmToPa,
+ paToAtm: paToAtm,
+ litersToM3: litersToM3,
+ m3ToLiters: m3ToLiters
+};
+})();
diff --git a/frontend/textbooks/physics_10_ch1.html b/frontend/textbooks/physics_10_ch1.html
new file mode 100644
index 0000000..ca7e5e8
--- /dev/null
+++ b/frontend/textbooks/physics_10_ch1.html
@@ -0,0 +1,992 @@
+
+
+
+
+
+
+
+Физика 10 · Глава 1 · «Основы МКТ»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика 10 · Глава 1
+
Молекулярно-кинетическая теория · идеальный газ · изопроцессы · влажность
+
+
+
+
+
+
+
+
+
+ Молекулярная физика — почему вещество ведёт себя так
+ Молекулярно-кинетическая теория объясняет свойства вещества движением и взаимодействием молекул. Изучаем газы, твёрдые тела, жидкости, температуру, давление и влажность.
+
+
Начать § 1
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/textbooks/physics_10_ch2.html b/frontend/textbooks/physics_10_ch2.html
new file mode 100644
index 0000000..f51782e
--- /dev/null
+++ b/frontend/textbooks/physics_10_ch2.html
@@ -0,0 +1,877 @@
+
+
+
+
+
+
+
+Физика 10 · Глава 2 · «Термодинамика»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика 10 · Глава 2
+
Внутренняя энергия · работа · теплота · 1-й закон · тепловые двигатели
+
+
+
+
+
+
+
+
+
+ Термодинамика — превращения энергии
+ Термодинамика — наука о превращении энергии. Внутренняя энергия, работа газа, количество теплоты, первый закон и тепловые двигатели.
+
+
Начать § 11
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/textbooks/physics_10_ch3.html b/frontend/textbooks/physics_10_ch3.html
new file mode 100644
index 0000000..35f0be0
--- /dev/null
+++ b/frontend/textbooks/physics_10_ch3.html
@@ -0,0 +1,969 @@
+
+
+
+
+
+
+
+Физика 10 · Глава 3 · «Электростатика»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика 10 · Глава 3
+
Заряд · Кулон · поле · потенциал · напряжение · конденсаторы
+
+
+
+
+
+
+
+
+
+ Электростатика — поле неподвижных зарядов
+ Электрический заряд создаёт поле. Изучаем закон Кулона, напряжённость и потенциал поля, конденсаторы и их энергию.
+
+
Начать § 16
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/textbooks/physics_10_ch4.html b/frontend/textbooks/physics_10_ch4.html
new file mode 100644
index 0000000..124d8d6
--- /dev/null
+++ b/frontend/textbooks/physics_10_ch4.html
@@ -0,0 +1,808 @@
+
+
+
+
+
+
+
+Физика 10 · Глава 4 · «Постоянный ток»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика 10 · Глава 4
+
ЭДС источника · закон Ома для полной цепи · КПД
+
+
+
+
+
+
+
+
+
+ Постоянный ток в полной цепи
+ Постоянный ток в полной цепи: ЭДС источника, закон Ома, КПД источника.
+
+
Начать § 25
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/textbooks/physics_10_ch5.html b/frontend/textbooks/physics_10_ch5.html
new file mode 100644
index 0000000..cff47aa
--- /dev/null
+++ b/frontend/textbooks/physics_10_ch5.html
@@ -0,0 +1,923 @@
+
+
+
+
+
+
+
+Физика 10 · Глава 5 · «Магнитное поле и ЭМИ»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика 10 · Глава 5
+
Магнитное поле · Ампер · Лоренц · поток · индукция · Ленц · Фарадей · самоиндукция
+
+
+
+
+
+
+
+
+
+ Магнитное поле и электромагнитная индукция
+ Магнитное поле тока, сила Ампера, сила Лоренца, явление электромагнитной индукции и закон Фарадея.
+
+
Начать § 27
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/textbooks/physics_10_ch6.html b/frontend/textbooks/physics_10_ch6.html
new file mode 100644
index 0000000..d62db79
--- /dev/null
+++ b/frontend/textbooks/physics_10_ch6.html
@@ -0,0 +1,854 @@
+
+
+
+
+
+
+
+Физика 10 · Глава 6 · «Ток в различных средах»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика 10 · Глава 6
+
Металлы · сверхпроводимость · электролиз · газы · плазма · полупроводники
+
+
+
+
+
+
+
+
+
+ Электрический ток в разных средах
+ Электрический ток ведёт себя по-разному в металлах, электролитах, газах и полупроводниках. Сверхпроводимость, электролиз, плазма, p-n переход.
+
+
Начать § 34
+
+
Прогресс по главе
+
+
0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/textbooks/physics_10_hub.html b/frontend/textbooks/physics_10_hub.html
new file mode 100644
index 0000000..82a414f
--- /dev/null
+++ b/frontend/textbooks/physics_10_hub.html
@@ -0,0 +1,763 @@
+
+
+
+
+
+
+
+
+Физика 10 класс — учебник
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Физика — 10 класс
+
Полный курс физики 10 класса: молекулярная физика, термодинамика, электростатика, магнитное поле, ток в средах
+
+
+
+
+
+
+
+
+ f
+
+
Общий прогресс по курсу
+
Загрузка...
+
+
+ 0 XP
+
+
+
+
+
+
T
+
Глава 1
+
Основы МКТ
+
§1–§10 + Финал
+
+
+
Молекулярно-кинетическая теория, идеальный газ, изопроцессы, строение твёрдых тел и жидкостей, влажность воздуха.
+
+
+
+
+
+
+
+
ΔU
+
Глава 2
+
Термодинамика
+
§11–§15 + Финал
+
+
+
Внутренняя энергия, работа и количество теплоты, первый закон термодинамики, тепловые двигатели, цикл Карно.
+
+
+
+
+
+
+
+
+q
+
Глава 3
+
Электростатика
+
§16–§24 + Финал
+
+
+
Электрический заряд, закон Кулона, напряжённость и потенциал электростатического поля, конденсаторы, энергия поля.
+
+
+
+
+
+
+
+
I
+
Глава 4
+
Постоянный ток
+
§25–§26 + Финал
+
+
+
ЭДС источника, закон Ома для полной электрической цепи, КПД источника.
+
+
+
+
+
+
+
+
B
+
Глава 5
+
Магнитное поле
+
§27–§33 + Финал
+
+
+
Магнитное поле, сила Ампера, сила Лоренца, электромагнитная индукция, закон Фарадея, самоиндукция.
+
+
+
+
+
+
+
+
n/p
+
Глава 6
+
Ток в средах
+
§34–§37 + Финал
+
+
+
Электрический ток в металлах и сверхпроводимость, электролиз, разряды в газах и плазма, полупроводники.
+
+
+
+
+
+
+
+
+
+
+
+
Финал курса
+
Босс-проверка по всему курсу
+
Шпаргалка курса и интегрированные боссы по всем 6 главам. В разработке (Phase 7).
+
+
+
+
+
+
+
+
Финал курса — в разработке
+
Итоговая шпаргалка по всем 37 параграфам и 8–10 интегрированных боссов появятся в Phase 7 (после завершения всех 6 глав).
+
+
+
+
+
+
+
Курс Физика 10 пройден!
+
Вы прошли всю итоговую проверку курса. +50 XP, ачивка «Магистр физики 10» получена.
+
+
+ К каталогу учебников
+
+
+
+
+
+
+
+
+
+
+
Магистр физики 10
+
Прочитайте все 37 параграфов курса, чтобы получить достижение, чтобы получить достижение
+
+
+
+
+
+
+
+
+
+
+