diff --git a/frontend/textbooks/algebra_9_ch4.html b/frontend/textbooks/algebra_9_ch4.html
index 4784466..66b119d 100644
--- a/frontend/textbooks/algebra_9_ch4.html
+++ b/frontend/textbooks/algebra_9_ch4.html
@@ -2304,21 +2304,231 @@ function buildP19(){
}
function buildFinal4(){
- const root = document.getElementById('final4-body');
- root.innerHTML = `
-
- `;
+
+ /* Часть Б — 5 боссов */
+ html += `
+
+
+
5 интегрированных задач. Каждая комбинирует несколько тем главы 4. За каждого побеждённого босса — +10 XP . Победишь всех — +50 XP бонус и ачивка «Магистр прогрессий»!
+
+
`;
+
+ html += '
';
+
+ html += `
+
Прогресс по боссам
+
0 / 5 боссов побеждено
+
+
+
Магистр прогрессий
+
Алгебра 9 пройдена! Все 4 главы изучены. Готовы к Геометрии 9!
+
+50 XP бонус начислены.
+
К хабу Алгебры 9
+
+
`;
+
+ html += secNav('p19', null);
+
+ box.innerHTML = html;
+ renderMath(box);
+
+ /* Боссы */
+ const BOSSES = [
+ {
+ n:1, color:'#10b981',
+ title:'Гном Арифметики',
+ tag:'§ 15 + § 16',
+ q:'В арифметической прогрессии $a_1 = 3$, $d = 4$. Найди $S_{10}$.',
+ ans:210,
+ hint:'$a_{10} = a_1 + 9d = 3 + 9 \\cdot 4 = 39$. Тогда $S_{10} = \\dfrac{a_1 + a_{10}}{2} \\cdot 10 = \\dfrac{3 + 39}{2} \\cdot 10 = \\mathbf{210}$.'
+ },
+ {
+ n:2, color:'#0891b2',
+ title:'Эльф Геометрии',
+ tag:'§ 17 + § 18',
+ q:'В геометрической прогрессии $b_1 = 2$, $q = 3$. Найди $S_5$.',
+ ans:242,
+ hint:'$S_5 = \\dfrac{b_1(q^5 - 1)}{q - 1} = \\dfrac{2(243 - 1)}{3 - 1} = \\dfrac{2 \\cdot 242}{2} = \\mathbf{242}$.'
+ },
+ {
+ n:3, color:'#7c3aed',
+ title:'Орк Сходимости',
+ tag:'§ 19 — синтез',
+ q:'Преврати периодическую дробь $0{,}\\overline{18}$ в обыкновенную и введи
знаменатель несократимой дроби.',
+ ans:11,
+ hint:'$0{,}\\overline{18} = \\dfrac{0{,}18}{1 - 0{,}01} = \\dfrac{18}{99} = \\dfrac{2}{11}$. Знаменатель: $\\mathbf{11}$.'
+ },
+ {
+ n:4, color:'#dc2626',
+ title:'Маг Двух Прогрессий',
+ tag:'§ 15 + § 17',
+ q:'Числа $x, y, z$ — арифм. прогрессия; числа $x, y-1, z$ — геом. прогрессия. Если $x + y + z = 12$, найди $y$.',
+ ans:4,
+ hint:'Из арифм.: $y = \\dfrac{x + z}{2} \\Rightarrow x + z = 2y$. Тогда $x + y + z = 3y = 12 \\Rightarrow y = \\mathbf{4}$. (Проверка геом.: $(y-1)^2 = xz$, т.е. $9 = xz$ с $x+z = 8$ — корни $t^2 - 8t + 9 = 0$, всё ок.)'
+ },
+ {
+ n:5, color:'#f59e0b',
+ title:'Архимаг Прогрессий',
+ tag:'§§ 14–19 — синтез',
+ q:'В геометрической прогрессии $b_1 = 16$, $q = \\dfrac{1}{2}$. Найди
сумму бесконечно убывающей прогрессии.',
+ ans:32,
+ hint:'$|q| = \\dfrac{1}{2} < 1$ — формула работает. $S = \\dfrac{b_1}{1 - q} = \\dfrac{16}{1 - 1/2} = \\dfrac{16}{1/2} = \\mathbf{32}$.'
+ },
+ ];
+
+ const cont = document.getElementById('ch4-bosses-container');
+ const STATE_KEY = 'algebra9_ch4_bosses';
+ const BOSS_STATE = (function(){
+ try{ const s = localStorage.getItem(STATE_KEY); if(s) return JSON.parse(s); }catch(e){}
+ return BOSSES.map(()=>({defeated:false}));
+ })();
+ function saveBosses(){ try{ localStorage.setItem(STATE_KEY, JSON.stringify(BOSS_STATE)); }catch(e){} }
+
+ cont.innerHTML = BOSSES.map((b, idx)=>{
+ return '
'
+ +'
'
+ +'
'
+ +'
Босс '+b.n+': '+b.title+'
'
+ +'
'+b.tag+'
'
+ +'
'
+ +'
'+b.q+'
'
+ +'
'
+ +'ответ = '
+ +' '
+ +'Атаковать '
+ +'Подсказка '
+ +'
'
+ +'
'
+ +'
';
+ }).join('');
+ renderMath(cont);
+
+ function refreshOverall(){
+ const won = BOSS_STATE.filter(s => s.defeated).length;
+ const txt = document.getElementById('ch4-boss-overall');
+ const fill = document.getElementById('ch4-boss-overall-fill');
+ if(txt) txt.textContent = won + ' / ' + BOSSES.length + ' боссов побеждено';
+ if(fill) fill.style.width = (won * 100 / BOSSES.length) + '%';
+ if(won >= BOSSES.length){
+ const reward = document.getElementById('ch4-final-reward');
+ if(reward && reward.style.display === 'none'){
+ reward.style.display = 'block';
+ if(!STATE.achievements.has('ch4_done')){
+ achievement('ch4_done','Магистр прогрессий');
+ addXp(50, 'ch4-bonus');
+ bumpProgress('final4', 30);
+ if(window.confetti){ try{ confetti(); }catch(e){} }
+ }
+ }
+ }
+ }
+
+ BOSSES.forEach((b, idx)=>{
+ const card = document.getElementById('boss4-'+b.n+'-card');
+ const goBtn = document.getElementById('boss4-'+b.n+'-go');
+ const hintBtn = document.getElementById('boss4-'+b.n+'-hint');
+ const ansInp = document.getElementById('boss4-'+b.n+'-ans');
+ if(BOSS_STATE[idx].defeated){
+ card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))';
+ goBtn.disabled = true; goBtn.style.opacity = .55; goBtn.textContent = '✓ Повержен';
+ ansInp.disabled = true;
+ }
+ goBtn.addEventListener('click', ()=>{
+ if(BOSS_STATE[idx].defeated) return;
+ const fb = document.getElementById('boss4-'+b.n+'-fb');
+ const val = parseInt(ansInp.value, 10);
+ if(isNaN(val)){ feedback(fb, false, '✗ Введи целое число.'); return; }
+ if(val === b.ans){
+ BOSS_STATE[idx].defeated = true; saveBosses();
+ feedback(fb, true, '✓ Босс '+b.n+' повержен! +10 XP. '+b.hint);
+ addXp(10, 'boss-ch4-'+b.n);
+ bumpProgress('final4', 18);
+ goBtn.disabled = true; goBtn.style.opacity = .55; goBtn.textContent = '✓ Повержен';
+ ansInp.disabled = true;
+ card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))';
+ refreshOverall();
+ } else {
+ feedback(fb, false, '✗ Промах. Попробуй ещё. Подсказка доступна.');
+ }
+ });
+ hintBtn.addEventListener('click', ()=>{
+ const fb = document.getElementById('boss4-'+b.n+'-fb');
+ fb.className = 'feedback ok';
+ fb.innerHTML = '
Подсказка: '+b.hint;
+ fb.style.display = 'block';
+ fb.style.background = 'var(--warn-bg)';
+ fb.style.color = '#92400e';
+ fb.style.borderLeftColor = 'var(--warn)';
+ renderMath(fb);
+ });
+ ansInp.addEventListener('keydown', e=>{ if(e.key === 'Enter') goBtn.click(); });
+ });
+
+ refreshOverall();
}
/* ===== Search ===== */