diff --git a/frontend/textbooks/physics_8_ch2.html b/frontend/textbooks/physics_8_ch2.html
index 250fc9e..4fbee97 100644
--- a/frontend/textbooks/physics_8_ch2.html
+++ b/frontend/textbooks/physics_8_ch2.html
@@ -423,8 +423,19 @@ const SIDEBARS = {
["ТБ","не голыми руками!"],
["Заземление","для защиты"]
]},
- p28:{title:"Шпаргалка § 28",rows:[["В разработке","Phase 4 Wave 1"]]},
- p29:{title:"Шпаргалка § 29",rows:[["В разработке","Phase 4 Wave 1"]]},
+ p28:{title:"Шпаргалка § 28",rows:[
+ ["Полюсы","N (север), S (юг)"],
+ ["Одноим.","отталкиваются"],
+ ["Разноим.","притягиваются"],
+ ["Разрез магнита","2 новых магнита (нет монополя)"],
+ ["Магн. поле Земли","ось $\\approx$ географ."]
+ ]},
+ p29:{title:"Шпаргалка § 29",rows:[
+ ["$\\vec B$","магнитная индукция, Тл"],
+ ["Линии $\\vec B$","выходят из N, входят в S"],
+ ["Линии замкнуты","нет источника / стока"],
+ ["Опилки","показывают линии $\\vec B$"]
+ ]},
p30:{title:"Шпаргалка § 30",rows:[["В разработке","Phase 4 Wave 2"]]},
p31:{title:"Шпаргалка § 31",rows:[["В разработке","Phase 4 Wave 2"]]},
final2:{title:"Шпаргалка ★",rows:[["В разработке","Phase 4 Wave 2"]]}
@@ -447,8 +458,8 @@ const TIPS=[
{sec:'p25',html:"При параллельном соединении на каждой ветви одно и то же напряжение. Токи складываются. Сопротивление считается по особой формуле — в итоге $R_{общ}$ меньше любого из $R_1$, $R_2$."},
{sec:'p26',html:"$A = UIt$ — энергия, которую ток отдаёт прибору. $P = UI$ — это мощность (Дж/с = Вт). В резисторе вся эта энергия превращается в тепло — это закон Джоуля-Ленца: $Q = I^2 R t$."},
{sec:'p27',html:"Счётчик в квартире меряет энергию в кВт·ч: 1 кВт·ч — это работа за 1 час мощностью 1 кВт. Стоимость = энергия × тариф. ТБ: розетка под 220 В может ударить смертельным током."},
- {sec:'p28',html:"Параграф § 28 будет реализован в Phase 4 Wave 1. Используем хелперы из phys.js и optics.js."},
- {sec:'p29',html:"Параграф § 29 будет реализован в Phase 4 Wave 1. Используем хелперы из phys.js и optics.js."},
+ {sec:'p28',html:"Два полюса магнита: N (север) и S (юг). Как и заряды: одноимённые отталкиваются, разноимённые притягиваются. Но в отличие от зарядов, разрезать магнит и получить «только N» нельзя — выскочат новые два полюса."},
+ {sec:'p29',html:"Вокруг магнита есть магнитное поле — оно действует на железные предметы и магнитные стрелки. Линии поля выходят из N и входят в S, и они замкнуты (в отличие от линий эл. поля). Опилки на бумаге над магнитом красиво «рисуют» эти линии."},
{sec:'p30',html:"Параграф § 30 будет реализован в Phase 4 Wave 2. Используем хелперы из phys.js и optics.js."},
{sec:'p31',html:"Параграф § 31 будет реализован в Phase 4 Wave 2. Используем хелперы из phys.js и optics.js."},
{sec:'final2',html:"Параграф ★ будет реализован в Phase 4 Wave 2. Используем хелперы из phys.js и optics.js."}
@@ -471,8 +482,8 @@ const BUILDERS = {
p25: ()=>{ build_p25(); },
p26: ()=>{ build_p26(); },
p27: ()=>{ build_p27(); },
- p28: ()=>{ const box=document.getElementById('p28-body'); box.innerHTML = buildStub('p28', 'Постоянные магниты', 'Phase 4 Wave 1') + secNavFor('p28') + readButton('p28'); renderMath(box); wireReadBtn('p28'); },
- p29: ()=>{ const box=document.getElementById('p29-body'); box.innerHTML = buildStub('p29', 'Магнитное поле', 'Phase 4 Wave 1') + secNavFor('p29') + readButton('p29'); renderMath(box); wireReadBtn('p29'); },
+ p28: ()=>{ build_p28(); },
+ p29: ()=>{ build_p29(); },
p30: ()=>{ const box=document.getElementById('p30-body'); box.innerHTML = buildStub('p30', 'Магнитное поле тока', 'Phase 4 Wave 2') + secNavFor('p30') + readButton('p30'); renderMath(box); wireReadBtn('p30'); },
p31: ()=>{ const box=document.getElementById('p31-body'); box.innerHTML = buildStub('p31', 'Магнитное поле прямого проводника и катушки с током. Электромагнит', 'Phase 4 Wave 2') + secNavFor('p31') + readButton('p31'); renderMath(box); wireReadBtn('p31'); },
final2: ()=>{ const box=document.getElementById('final2-body'); box.innerHTML = buildStub('final2', 'Финал главы', 'Phase 4 Wave 2') + secNavFor('final2') + readButton('final2'); renderMath(box); wireReadBtn('final2'); }
@@ -4337,6 +4348,429 @@ function _initP27_tasks(){
render();
}
+/* ======================================================================
+ PHASE 4 · WAVE 1 — §28, §29
+ ====================================================================== */
+
+/* Хелпер: рисует магнитную полосу N-S */
+function _drawMagnet(x, y, w, hMag, flipped){
+ const halfW = w/2;
+ const nCol = '#dc2626', sCol = '#2563eb';
+ const left = flipped ? sCol : nCol;
+ const right = flipped ? nCol : sCol;
+ const leftLab = flipped ? 'S' : 'N';
+ const rightLab = flipped ? 'N' : 'S';
+ let s = '';
+ s += '';
+ s += '';
+ s += ''+leftLab+'';
+ s += ''+rightLab+'';
+ return s;
+}
+
+/* ======== §28 — Постоянные магниты ======== */
+function build_p28(){
+ const box = document.getElementById('p28-body');
+ let h = '';
+
+ h += makeCard('theory', 'Что такое магнит', '§ 28.1',
+ '
Постоянный магнит — тело, обладающее магнитными свойствами длительное время. Чаще всего из железа, никеля, кобальта или сплавов (например, «магнитное железо» — ферриты).
'
+ +'
У любого магнита есть два полюса: северный (N) и южный (S). Они расположены на противоположных концах.
'
+ +'
Сила взаимодействия сосредоточена у полюсов — там магнит «прилипает» к железу сильнее всего.
'
+ );
+ h += makeCard('rule', 'Закон взаимодействия полюсов', '§ 28.2',
+ '
По аналогии с зарядами:
'
+ +'
'
+ +'
Одноимённые полюсы (N-N или S-S) — отталкиваются.
'
+ +'
Разноимённые (N-S) — притягиваются.
'
+ +'
'
+ +'
В отличие от электрических зарядов, нельзя получить магнит только с одним полюсом. Если разрезать магнит пополам — получатся два новых магнита, у каждого свои N и S.
'
+ );
+ h += makeCard('example', 'Магнитное поле Земли', '§ 28.3',
+ '
Земля — гигантский магнит. Её магнитные полюсы расположены вблизи географических (но не точно на них).
'
+ +'
Важно: «северный географический» близок к южному магнитному полюсу Земли. Поэтому северный конец стрелки компаса (он же N) притягивается к географическому северу.
'
+ +'
Магнитное поле Земли защищает нас от космических лучей и помогает ориентироваться компасу. Полюсы со временем «дрейфуют».
'
+ );
+
+ /* IV1 — взаимодействие двух магнитов */
+ h += '
'
+ +'
IV-1
Два магнита
'
+ +'
Переворачивай второй магнит — наблюдай притяжение/отталкивание.
Магнитное поле наглядно изображают линиями магнитной индукции:
'
+ +'
'
+ +'
выходят из N и входят в S полюс магнита снаружи;
'
+ +'
внутри магнита идут от S к N — поэтому они замкнуты;
'
+ +'
не пересекаются;
'
+ +'
чем гуще линии, тем сильнее поле.
'
+ +'
'
+ +'
Важное отличие от электрического поля: линии магн. поля всегда замкнуты (нет «магнитных зарядов»).
'
+ );
+ h += makeCard('example', 'Опыт с железными опилками', '§ 29.3',
+ '
Если на стекло над магнитом насыпать железные опилки, они выстраиваются вдоль линий магнитной индукции. Получается «фотография» магнитного поля.
'
+ +'
Сейчас увидим, как это выглядит.
'
+ );
+
+ /* IV1 — линии магн. индукции */
+ h += '
'
+ +'
IV-1
Линии магнитного поля полосового магнита
'
+ +'
Линии выходят из N и входят в S — снаружи. Внутри магнита идут от S к N, замыкая контур.
'
+ +''
+ +'
';
+
+ /* IV2 — викторина «где северный полюс» */
+ h += '
'
+ +'
IV-2
Знаешь линии поля?
'
+ +'
Правда или ложь о линиях $\\vec B$.
'
+ +''
+ +''
+ +'
Раунд: 1 / 5Правильно: 0
'
+ +'
';
+
+ /* IV3 — DnD сравнение полей */
+ h += '
'
+ +'
IV-3
Электрическое vs магнитное поле
'
+ +'
К какому полю относится свойство?
'
+ +''
+ +'
'
+ +'
Электрическое
'
+ +'
Магнитное
'
+ +'
'
+ +''
+ +''
+ +'
';
+
+ /* IV4 — MCQ */
+ h += '
'
+ +'
IV-4
Тренажёр: 6 вопросов
'
+ +'
4+ — +15 XP.
'
+ +''
+ +'
Вопрос: 1 / 6Правильно: 0
'
+ +'
';
+
+ box.innerHTML = h + secNavFor('p29') + readButton('p29');
+ renderMath(box);
+ wireReadBtn('p29');
+
+ _initP29_lines();
+ _initP29_quiz();
+ _initP29_dnd();
+ _initP29_mcq();
+}
+
+function _initP29_lines(){
+ const svg = document.getElementById('p29-sim'); if(!svg) return;
+ /* Полосовой магнит N(слева) S(справа), линии поля изгибаются.
+ Параметрически: серия эллиптических дуг разного размера, выходящих из N. */
+ const cx = 230, cy = 140;
+ const magW = 160, magH = 40;
+ let s = '';
+ /* нарисуем магнит */
+ s += _drawMagnet(cx - magW/2, cy - magH/2, magW, magH, false); /* N(left), S(right) */
+ /* линии: эллипсы между N(150,140) и S(310,140), радиус растёт */
+ for(let k = 0; k < 7; k++){
+ const ry = 30 + k*25;
+ /* нарисуем верхнюю и нижнюю половину эллипса как path */
+ const xN = cx - magW/2;
+ const xS = cx + magW/2;
+ /* верхняя половина: дуга от xN,cy через (cx,cy-ry) до xS,cy */
+ const cx1 = (xN+xS)/2;
+ /* стрелка на верхушке */
+ s += '';
+ s += '';
+ /* стрелка направления — посередине верхней дуги, направлена вправо */
+ if(k < 5){
+ s += window.PHYS.drawArrow(cx-6, cy - ry + 2, cx+6, cy - ry + 2, '#7c3aed', 1.5, 7);
+ s += window.PHYS.drawArrow(cx-6, cy + ry - 2, cx+6, cy + ry - 2, '#7c3aed', 1.5, 7);
+ }
+ }
+ /* пара прямых линий близко к оси (горизонтально между полюсами) */
+ s += '';
+ s += '';
+ /* подписи */
+ s += 'линии магнитной индукции $\\vec B$';
+ s += 'снаружи: N → S';
+ s += 'внутри: S → N (замыкают)';
+ svg.innerHTML = s;
+}
+
+function _initP29_quiz(){
+ const QS = [
+ {st:'Линии магнитного поля выходят из S и входят в N.', ans:'F', why:'Наоборот: из N в S.'},
+ {st:'Линии магнитного поля замкнуты.', ans:'T', why:'Внутри магнита они идут от S к N, замыкая контур.'},
+ {st:'Линии магнитного поля могут пересекаться.', ans:'F', why:'В каждой точке вектор $\\vec B$ имеет одно направление.'},
+ {st:'Чем гуще линии, тем сильнее поле.', ans:'T', why:'Густота показывает $|B|$.'},
+ {st:'Магнитное поле действует на неподвижный заряд.', ans:'F', why:'Только на движущийся заряд и на ток!'}
+ ];
+ let i = 0, ok = 0;
+ function render(){
+ const q = QS[i]; const wrap = document.getElementById('p29-quiz'); if(!wrap) return;
+ wrap.innerHTML =
+ '
"'+q.st+'"
'
+ +'
'
+ +''
+ +''
+ +'
'
+ +'';
+ document.getElementById('p29-quiz-r').textContent = (i+1);
+ document.getElementById('p29-quiz-ok').textContent = ok;
+ wrap.querySelectorAll('[data-pick]').forEach(btn=>{
+ btn.addEventListener('click', ()=>{
+ if(btn.disabled) return; wrap.querySelectorAll('[data-pick]').forEach(b=>b.disabled=true);
+ const fb = document.getElementById('p29-quiz-fb');
+ if(btn.dataset.pick === q.ans){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(3,'p29-quiz'); bumpProgress('p29', 4); }
+ else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
+ document.getElementById('p29-quiz-ok').textContent = ok;
+ renderMath(wrap);
+ });
+ });
+ renderMath(wrap);
+ }
+ document.getElementById('p29-quiz-next').addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
+ render();
+}
+
+function _initP29_dnd(){
+ const items = [
+ {id:'a', cat:'e', html:'линии начинаются на +, кончаются на −'},
+ {id:'b', cat:'e', html:'действует на любой заряд'},
+ {id:'c', cat:'e', html:'источники — заряды'},
+ {id:'d', cat:'e', html:'$U = A/q$'},
+ {id:'e', cat:'m', html:'линии замкнуты (без начала и конца)'},
+ {id:'f', cat:'m', html:'действует на движ. заряды и ток'},
+ {id:'g', cat:'m', html:'источники — магниты и токи'},
+ {id:'h', cat:'m', html:'$\\vec B$ — индукция, [Тл]'}
+ ];
+ const dnd = setupSorter({ poolId:'p29-dnd-pool', scopeSelector:'#sec-p29', cats:['e','m'], items, columnLayout:false });
+ document.getElementById('p29-dnd-check').addEventListener('click', ()=>{
+ const fb = document.getElementById('p29-dnd-fb');
+ let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; });
+ if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. Эл. поле — открытые линии, магн. поле — замкнутые.'; addXp(15,'p29-dnd'); bumpProgress('p29', 20); renderMath(fb); }
+ else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'.'; renderMath(fb); }
+ });
+ document.getElementById('p29-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p29-dnd-fb'); fb.style.display='none'; });
+}
+
+function _initP29_mcq(){
+ const QS = [
+ {q:'Что обозначают $\\vec B$?', opts:['напряжённость','индукцию','потенциал','работу'], ans:1, why:'Магнитная индукция.'},
+ {q:'Единица измерения $|B|$?', opts:['Вольт','Ампер','Тесла','Ом'], ans:2, why:'Тесла (Тл).'},
+ {q:'Куда направлены линии вне магнита?', opts:['от N к S','от S к N','внутри по кругу','хаос'], ans:0, why:'Снаружи — от N к S.'},
+ {q:'Линии $\\vec B$ обладают свойством…', opts:['открытости','замкнутости','пересечения','исчезновения'], ans:1, why:'Магнитное поле — соленоидальное.'},
+ {q:'Что отклоняет стрелку компаса?', opts:['заряд','свет','магнитное поле Земли','гравитация'], ans:2, why:'Земля — гигантский магнит.'},
+ {q:'Как «увидеть» магнитное поле?', opts:['опилками','спиртом','краской','углём'], ans:0, why:'Железные опилки выстраиваются вдоль линий.'}
+ ];
+ let i = 0, ok = 0, done = 0, awarded = false;
+ function render(){
+ const q = QS[i]; const wrap = document.getElementById('p29-mcq'); if(!wrap) return;
+ let h = '
Вопрос '+(i+1)+'. '+q.q+'
';
+ q.opts.forEach((opt,k)=>{ h += ''; });
+ h += '