diff --git a/frontend/textbooks/physics_10_ch1.html b/frontend/textbooks/physics_10_ch1.html
index cb01da6..3f8e8ae 100644
--- a/frontend/textbooks/physics_10_ch1.html
+++ b/frontend/textbooks/physics_10_ch1.html
@@ -117,6 +117,11 @@ a{color:inherit;text-decoration:none}
.feedback.ok{display:block;background:var(--ok-bg);color:#065f46;border-left:4px solid var(--ok)}
.feedback.fail{display:block;background:var(--fail-bg);color:#7f1d1d;border-left:4px solid var(--fail)}
+.boss-card{transition:border-color .35s,box-shadow .6s,background .3s,transform .2s;position:relative;overflow:hidden}
+.boss-card.glow{box-shadow:0 0 24px rgba(16,185,129,.6),0 0 0 2px rgba(16,185,129,.45)!important}
+@keyframes bossPulse{0%{box-shadow:0 0 0 0 rgba(16,185,129,.55)}70%{box-shadow:0 0 0 14px rgba(16,185,129,0)}100%{box-shadow:0 0 0 0 rgba(16,185,129,0)}}
+.boss-card.pulse{animation:bossPulse .8s ease-out}
+
.wg{background:linear-gradient(135deg,var(--card),var(--sec-acc-soft,var(--pri-soft)));border:1.5px solid var(--sec-acc,var(--pri));border-radius:14px;padding:18px 20px;margin-bottom:18px;box-shadow:var(--sh2);position:relative;z-index:1}
.wg-header{display:flex;align-items:center;gap:8px;margin-bottom:14px}
.wg-badge{padding:4px 9px;background:var(--sec-acc,var(--pri));color:#fff;border-radius:6px;font-family:'Unbounded',sans-serif;font-size:.68rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em}
@@ -3584,55 +3589,1004 @@ function build_p8(){
wireReadBtn('p8');
}
+/* ========== §9 ИСПАРЕНИЕ И КОНДЕНСАЦИЯ. НАСЫЩЕННЫЙ ПАР ========== */
+
+/* Табличные значения давления насыщенного пара воды (кПа) при t в °C — используется в §9 и §10. */
+const P9_PNTABLE = [
+ { t: 0, p: 0.61 },
+ { t: 10, p: 1.23 },
+ { t: 20, p: 2.34 },
+ { t: 30, p: 4.24 },
+ { t: 40, p: 7.38 },
+ { t: 50, p: 12.3 },
+ { t: 60, p: 19.9 },
+ { t: 70, p: 31.2 },
+ { t: 80, p: 47.4 },
+ { t: 90, p: 70.1 },
+ { t: 100, p: 101.3 },
+];
+function pSatWater(t){
+ if(t <= P9_PNTABLE[0].t) return P9_PNTABLE[0].p;
+ if(t >= P9_PNTABLE[P9_PNTABLE.length-1].t) return P9_PNTABLE[P9_PNTABLE.length-1].p;
+ for(let i = 0; i < P9_PNTABLE.length - 1; i++){
+ const a = P9_PNTABLE[i], b = P9_PNTABLE[i+1];
+ if(t >= a.t && t <= b.t){
+ const k = (t - a.t) / (b.t - a.t);
+ return a.p + k * (b.p - a.p);
+ }
+ }
+ return 0;
+}
+function dewPointWater(p){
+ // обратная интерполяция: при каком t выполняется p_н(t) = p?
+ if(p <= P9_PNTABLE[0].p) return P9_PNTABLE[0].t;
+ if(p >= P9_PNTABLE[P9_PNTABLE.length-1].p) return P9_PNTABLE[P9_PNTABLE.length-1].t;
+ for(let i = 0; i < P9_PNTABLE.length - 1; i++){
+ const a = P9_PNTABLE[i], b = P9_PNTABLE[i+1];
+ if(p >= a.p && p <= b.p){
+ const k = (p - a.p) / (b.p - a.p);
+ return a.t + k * (b.t - a.t);
+ }
+ }
+ return 0;
+}
+
function build_p9(){
const box = document.getElementById('p9-body');
let html = '';
- html += makeCard('theory', "Испарение и конденсация. Насыщенный пар", "§9", `
-
Испарение и конденсация. Насыщенный пар — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Испарение и конденсация */
+ html += makeCard('theory', "Испарение и конденсация", "§9", `
+
Испарение — переход жидкости в пар с её поверхности. Происходит при любой температуре (даже при $0°$C — мокрое бельё высыхает зимой).
+
Молекулы с наибольшей кинетической энергией вылетают с поверхности, преодолевая силы притяжения остальных. При этом средняя энергия оставшихся молекул уменьшается — жидкость охлаждается при испарении (поэтому мокрое полотенце холодит кожу).
+
Скорость испарения растёт при:
+
+
повышении температуры $T$ (растёт доля «быстрых» молекул);
+
увеличении площади свободной поверхности;
+
удалении паров над поверхностью (например, ветер);
+
понижении внешнего давления над поверхностью.
+
+
Конденсация — обратный процесс: пар → жидкость. При конденсации выделяется то же количество энергии, которое было затрачено на испарение.
`);
+
+ /* THEORY 2 — Насыщенный пар */
+ html += makeCard('rule', "Насыщенный пар", "§9", `
+
Насыщенный пар — пар, находящийся в динамическом равновесии с жидкостью: число молекул, испаряющихся в единицу времени, равно числу молекул, конденсирующихся обратно.
+
Главное свойство: давление насыщенного пара $p_н$ зависит только от температуры и не зависит от объёма!
+
+
При повышении $T$: $p_н$ растёт (примерно экспоненциально).
+
При сжатии сосуда: часть пара конденсируется, давление остаётся $p = p_н(T)$.
+
При расширении: жидкость испаряется, давление снова $p = p_н(T)$.
+
+
Кипение наступает при такой температуре $T_{\\text{кип}}$, когда $p_н(T_{\\text{кип}}) = p_{\\text{атм}}$. Для воды при 1 атм ($\\approx 101{,}3$ кПа) это $T_{\\text{кип}} = 100°$C.
+
Значения $p_н$ для воды (кПа): при $20°$C — $2{,}34$; при $50°$C — $12{,}3$; при $80°$C — $47{,}4$; при $100°$C — $101{,}3$.
+ `);
+
+ /* THEORY 3 — Виды пара */
+ html += makeCard('example', "Три вида пара", "§9", `
+
Насыщенный пар. Пар в равновесии с жидкостью. $p = p_н(T)$. Подчиняется законам идеального газа только приближённо.
+
Ненасыщенный пар. $p < p_н$. «Обычный» пар, без жидкости поблизости. Хорошо описывается законами идеального газа и уравнением Менделеева–Клапейрона.
+
Перенасыщенный пар. $p > p_н$. Нестабильное состояние — пар спонтанно конденсируется. Возникает при резком охлаждении чистого пара (без центров конденсации).
+
Примеры в природе и технике:
+
+
Туман — водяной пар, охладившийся ниже точки росы → конденсация в капельки.
+
Запотевание окон зимой — конденсация пара из тёплого воздуха на холодном стекле.
+
Облака — конденсат водяного пара в верхних слоях атмосферы.
Давление насыщенного пара: $p_н(t) \\approx '+(+pn.toFixed(2))+'$ кПа
'
+ + '
'+comment+'
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ used.add(Math.round(t/15));
+ if(!_done && used.size >= 3){ _done = true; addXp(10, 'p9-iv2'); bumpProgress('p9', 15); }
+ }
+ go.addEventListener('click', calc);
+ tInp.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); });
+ })();
+
+ /* IV3 — Какой пар? */
+ (function(){
+ // 0 = насыщенный, 1 = ненасыщенный, 2 = перенасыщенный
+ const Q = [
+ { q:'Пар в закрытом сосуде над водой в равновесии при $T = 300$ К', ans:0, why:'Динамическое равновесие — это и есть насыщенный пар.' },
+ { q:'Воздух комнаты при $\\varphi = 30\\%$, далеко от точки росы', ans:1, why:'$p < p_н$ — ненасыщенный пар.' },
+ { q:'Чистый пар охладили в камере Вильсона ниже точки росы (без центров конденсации)', ans:2, why:'Перенасыщенный пар — нестабильное состояние, $p > p_н$.' },
+ { q:'Пар над кипящим чайником, который только что закрыли крышкой', ans:0, why:'В замкнутом объёме над водой быстро устанавливается насыщенный пар.' },
+ { q:'Утренний туман: пар охладился, образовались капельки', ans:0, why:'В тумане устанавливается насыщенный пар над поверхностью капель.' },
+ { q:'Воздух в комнате с $\\varphi = 95\\%$ при $t = 20°$C', ans:1, why:'Пока $\\varphi < 100\\%$, пар остаётся ненасыщенным (хоть и близко к насыщению).' },
+ ];
+ const LABELS = ['Насыщенный', 'Ненасыщенный', 'Перенасыщенный'];
+ const COLORS = ['#10b981', '#0ea5e9', '#f59e0b'];
+ let i = 0, score = 0;
+ const qEl = document.getElementById('p9-iv3-q');
+ const oEl = document.getElementById('p9-iv3-opts');
+ const fb = document.getElementById('p9-iv3-fb');
+ const iEl = document.getElementById('p9-iv3-i');
+ const sEl = document.getElementById('p9-iv3-s');
+ function show(){
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ oEl.innerHTML = '';
+ if(score === Q.length){ addXp(15, 'p9-iv3'); bumpProgress('p9', 25); }
+ else if(score >= 4){ addXp(8, 'p9-iv3'); bumpProgress('p9', 15); }
+ return;
+ }
+ iEl.textContent = (i+1); sEl.textContent = score;
+ qEl.innerHTML = Q[i].q;
+ oEl.innerHTML = LABELS.map((l, k) =>
+ ''
+ ).join('');
+ fb.style.display = 'none';
+ renderMath(qEl);
+ oEl.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ const v = +b.dataset.v;
+ if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+' Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Это '+LABELS[Q[i].ans]+'. '+Q[i].why+' Дальше ▶');
+ sEl.textContent = score;
+ oEl.querySelectorAll('button').forEach(x => x.disabled = true);
+ i++;
+ setTimeout(show, 1900);
+ });
+ });
+ }
+ document.getElementById('p9-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
+ /* IV4 — Тренажёр пара */
+ (function(){
+ const Q = [
+ { q:'При $t = 100°$C давление насыщенного пара воды равно ... кПа?', ans:101.3, tol:1, hint:'$p_н(100°) = 101{,}3$ кПа — это и есть атмосферное.' },
+ { q:'При какой температуре (в °C) начинается кипение воды при атмосферном давлении 1 атм?', ans:100, tol:1, hint:'Кипение наступает при $p_н = p_{\\text{атм}}$ — для 1 атм это $100°$C.' },
+ { q:'В закрытом сосуде с водой нагрели содержимое с $20°$C до $50°$C. Во сколько раз вырастет $p_н$? ($p_н(20°) = 2{,}34$ кПа, $p_н(50°) = 12{,}3$ кПа)', ans:5.26, tol:0.5, hint:'$\\dfrac{12{,}3}{2{,}34} \\approx 5{,}26$.' },
+ { q:'Зависит ли давление насыщенного пара от объёма сосуда? Введи 1 — да, 2 — нет.', ans:2, tol:0.1, hint:'$p_н$ зависит только от $T$.' },
+ { q:'Что забирает больше энергии на 1 г: испарение воды ($r \\approx 2260$ кДж/кг) или плавление льда ($\\lambda \\approx 334$ кДж/кг)? Введи 1 — испарение, 2 — плавление.', ans:1, tol:0.1, hint:'$r \\gg \\lambda$ — испарение «дороже» в 6–7 раз.' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p9-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p9-iv4'); bumpProgress('p9', 25); }
+ else if(score >= 3){ addXp(8, 'p9-iv4'); bumpProgress('p9', 15); }
+ return;
+ }
+ document.getElementById('p9-iv4-i').textContent = (i+1);
+ document.getElementById('p9-iv4-s').textContent = score;
+ document.getElementById('p9-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p9-iv4-ans').value = '';
+ renderMath(document.getElementById('p9-iv4-q'));
+ document.getElementById('p9-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p9-iv4-fb');
+ const raw = document.getElementById('p9-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ const tol = Q[i].tol || Math.max(0.05 * Math.abs(Q[i].ans), 0.05);
+ if(Math.abs(ans - Q[i].ans) < tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶');
+ document.getElementById('p9-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1900);
+ }
+ document.getElementById('p9-iv4-go').addEventListener('click', go);
+ document.getElementById('p9-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p9-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p9');
}
+/* ========== §10 ВЛАЖНОСТЬ ВОЗДУХА ========== */
+
function build_p10(){
const box = document.getElementById('p10-body');
let html = '';
- html += makeCard('theory', "Влажность воздуха", "§10", `
-
Влажность воздуха — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Абсолютная и относительная влажность */
+ html += makeCard('theory', "Абсолютная и относительная влажность", "§10", `
+
Абсолютная влажность $\\rho_a$ — масса водяного пара в $1$ м³ воздуха. Единица: г/м³.
+
Относительная влажность $\\varphi$ — характеризует, насколько воздух близок к насыщению:
где $p$, $\\rho_a$ — реальные значения, $p_н$, $\\rho_н$ — для насыщенного пара при той же $T$.
+
+
$\\varphi = 100\\%$ — воздух полностью насыщен; начинается конденсация.
+
$\\varphi < 100\\%$ — пар ненасыщенный, испарение продолжается.
+
$\\varphi = 0\\%$ — абсолютно сухой воздух.
+
`);
+
+ /* THEORY 2 — Точка росы */
+ html += makeCard('rule', "Точка росы", "§10", `
+
Точка росы $T_{\\text{росы}}$ — температура, до которой нужно охладить воздух при неизменном давлении, чтобы пар стал насыщенным ($\\varphi = 100\\%$).
+
При охлаждении ниже точки росы начинается конденсация: образуются роса, туман, иней, капли на стекле.
+
Условие точки росы: $p_н(T_{\\text{росы}}) = p$ — то есть при $T = T_{\\text{росы}}$ табличное давление насыщенного пара равно реальному давлению пара $p$ в воздухе.
Финал главы 1 — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+ ${ICONS.theory}
+ Шпаргалка главы 1 — Основы МКТ
+ Итог
+
+
+
Ключевые формулы и идеи всех 10 параграфов в одном месте — просмотри перед битвой с боссами.
+
+ ${SHEET.map(s => `
+
+ ${s.icon}
+
${s.t}
+
+
${s.body}
+
`).join('')}
+
+
+
`;
+
+ /* Часть Б — 7 боссов (intro) */
+ html += `
+
+ ${ICONS.rule}
+ Боссы главы 1
+ 7
+
+
+
7 интегрированных задач — каждая комбинирует ≥ 2 темы. За каждого побеждённого босса: +10 XP, +14% к прогрессу. Победишь всех — ачивка «Мастер МКТ» и +50 XP бонус.