diff --git a/frontend/textbooks/algebra_11_ch2.html b/frontend/textbooks/algebra_11_ch2.html
index e1ce5b4..b06e806 100644
--- a/frontend/textbooks/algebra_11_ch2.html
+++ b/frontend/textbooks/algebra_11_ch2.html
@@ -1459,31 +1459,707 @@ function buildP5(){
function buildP6(){
const box = document.getElementById('p6-body');
let html = '';
- html += makeCard('theory', 'В разработке', '6.0', `
-
Содержание параграфа Показательные неравенства будет добавлено в Phase 1+.
- Раздел Phase 0 — skeleton. Здесь появятся теория, примеры и интерактивы.
- Ключевая формула: $a^x > b$
- `);
+
+ /* === ТЕОРИЯ === */
+
+ html += makeCard('theory', 'Основное правило', '6.1', `
+ Показательным неравенством называется неравенство вида $a^{f(x)} > a^{g(x)}$ (или $<$, $\\ge$, $\\le$), где $a > 0$, $a \\ne 1$.
+ Поскольку функция $y = a^x$ монотонна (см. §4), при переходе от степеней к показателям всё зависит от того, возрастает она или убывает:
+
+ $a^{f(x)} > a^{g(x)} \\;\\Leftrightarrow\\; \\begin{cases} f(x) > g(x), & \\text{если } a > 1, \\\\ f(x) < g(x), & \\text{если } 0 < a < 1. \\end{cases}$
+
+ Запомни :
+
+ при $a > 1$ знак неравенства сохраняется (функция возрастает — порядок сохраняется);
+ при $0 < a < 1$ знак неравенства меняется на противоположный (функция убывает — порядок переворачивается).
+
+ Это правило — прямое следствие монотонности показательной функции (см. §4).
`);
+
+ html += makeCard('rule', 'Алгоритм решения', '6.2', `
+ Алгоритм похож на алгоритм для уравнений из §5, но требует постоянного контроля знака неравенства:
+
+ Привести обе части к степени с одинаковым основанием $a$.
+ Сравнить значение $a$ с единицей и записать неравенство показателей с правильным знаком.
+ Решить полученное неравенство для $x$ и записать ответ интервалом.
+
+ Пример 1. $2^{x-1} > 8$.
+ $8 = 2^3$, поэтому $2^{x-1} > 2^3$. Основание $a = 2 > 1$ — знак сохраняется : $x - 1 > 3 \\Rightarrow x > 4$.
+ Ответ: $x \\in (4;\\;+\\infty)$.
+ Пример 2. $\\left(\\dfrac{1}{3}\\right)^x \\ge 9$.
+ $9 = 3^2 = \\left(\\dfrac{1}{3}\\right)^{-2}$. Тогда $\\left(\\dfrac{1}{3}\\right)^x \\ge \\left(\\dfrac{1}{3}\\right)^{-2}$. Основание $a = \\dfrac{1}{3} < 1$ — знак меняется : $x \\le -2$.
+ Ответ: $x \\in (-\\infty;\\;-2]$.
`);
+
+ html += makeCard('example', 'Метод замены переменной', '6.3', `
+ Если неравенство содержит $a^{2x}$ и $a^x$, делаем замену $t = a^x$, причём обязательно $t > 0$ . Получаем алгебраическое неравенство (чаще квадратное), которое решаем методом интервалов.
+
+ $A \\cdot a^{2x} + B \\cdot a^x + C \\;\\gtrless\\; 0 \\;\\xrightarrow{\\;t = a^x > 0\\;}\\; A t^2 + B t + C \\;\\gtrless\\; 0$
+
+ Алгоритм :
+
+ Сделать замену $t = a^x$, $t > 0$.
+ Решить полученное неравенство для $t$ методом интервалов.
+ Пересечь полученное множество с условием $t > 0$.
+ Вернуться к $x$ из $a^x \\in [\\,t_1;\\,t_2\\,]$ с учётом монотонности.
+
+ Пример. $4^x - 5 \\cdot 2^x + 4 \\le 0$.
+ Замечаем $4^x = (2^x)^2$. Замена $t = 2^x > 0$: $t^2 - 5t + 4 \\le 0$. Корни $t = 1$, $t = 4$, значит $t \\in [1;\\;4]$ (оба положительны — условие выполнено).
+ Возвращаемся: $1 \\le 2^x \\le 4 \\Leftrightarrow 2^0 \\le 2^x \\le 2^2$. Основание $2 > 1$ — знак сохраняется: $0 \\le x \\le 2$.
+ Ответ: $x \\in [0;\\;2]$.
`);
+
+ /* === ИНТЕРАКТИВЫ === */
+
+ /* IV1 — решатель показательных неравенств с шагами и числовой прямой */
+ html += `
+
+
Выбери задачу ползунком и нажимай «Следующий шаг ▶». В конце появится ответ на числовой прямой. Просмотри все 5 задач — получишь XP.
+
+ Задача № 1 / 5
+
+
+
+
+
+ Следующий шаг ▶
+ Показать все шаги
+ Скрыть шаги
+
+
`;
+
+ /* IV2 — калькулятор a^(kx+b) > c */
+ html += ``;
+
+ /* IV3 — знак сохраняется или меняется? */
+ html += `
+
+
Глядя на основание степени, определи, что произойдёт со знаком неравенства при переходе к показателям. 8 заданий.
+
Задача 1 / 8 Очки: 0 / 8
+
+
+
+
Начать заново
+
`;
+
+ /* IV4 — тренажёр неравенств */
+ html += `
+
+
Реши неравенство и введи границу интервала ответа (например, для $x > 3$ ввести $3$; для $x \\in [0;\\,2]$ ввести любую границу — указано в задании). Допуск $\\pm 0{,}05$. 6 задач.
+
Задача 1 / 6 Очки: 0 / 6
+
+
+ граница =
+
+ Проверить
+ Заново
+
+
+
`;
+
html += secNavFor('p6');
html += readButton('p6');
+
box.innerHTML = html;
renderMath(box);
+
+ /* === IV1 — решатель с шагами и числовой прямой === */
+ (function(){
+ /* line: {min, max, lo, hi, openLo, openHi, dirLeft, dirRight}
+ dirLeft/dirRight — стрелка уходит влево/вправо за границу видимой части */
+ const TASKS = [
+ {
+ q: '$2^x > 8$',
+ steps: [
+ 'Приводим к одному основанию: $8 = 2^3$, поэтому $2^x > 2^3$.',
+ 'Основание $a = 2 > 1$ — знак сохраняется : $x > 3$.',
+ 'Ответ: $x \\in (3;\\;+\\infty)$.'
+ ],
+ line: { min:-2, max:8, lo:3, hi:null, openLo:true, dirRight:true }
+ },
+ {
+ q: '$\\left(\\dfrac{1}{2}\\right)^x \\ge 4$',
+ steps: [
+ 'Приводим к одному основанию: $4 = 2^2 = \\left(\\dfrac{1}{2}\\right)^{-2}$.',
+ 'Получаем $\\left(\\dfrac{1}{2}\\right)^x \\ge \\left(\\dfrac{1}{2}\\right)^{-2}$.',
+ 'Основание $a = \\dfrac{1}{2} < 1$ — знак меняется : $x \\le -2$.',
+ 'Ответ: $x \\in (-\\infty;\\;-2]$.'
+ ],
+ line: { min:-7, max:3, lo:null, hi:-2, openHi:false, dirLeft:true }
+ },
+ {
+ q: '$3^{x+1} < 27$',
+ steps: [
+ 'Приводим к одному основанию: $27 = 3^3$, поэтому $3^{x+1} < 3^3$.',
+ 'Основание $a = 3 > 1$ — знак сохраняется : $x + 1 < 3$.',
+ 'Откуда $x < 2$.',
+ 'Ответ: $x \\in (-\\infty;\\;2)$.'
+ ],
+ line: { min:-3, max:7, lo:null, hi:2, openHi:true, dirLeft:true }
+ },
+ {
+ q: '$4^x - 5 \\cdot 2^x + 4 \\le 0$',
+ steps: [
+ 'Замечаем $4^x = (2^x)^2$. Замена $t = 2^x$, $t > 0$.',
+ 'Получаем квадратное: $t^2 - 5t + 4 \\le 0$. Корни $t = 1$, $t = 4$.',
+ 'Решение по $t$: $t \\in [1;\\;4]$ (оба положительны).',
+ 'Возвращаемся: $1 \\le 2^x \\le 4$, то есть $2^0 \\le 2^x \\le 2^2$. Знак сохраняется: $0 \\le x \\le 2$.',
+ 'Ответ: $x \\in [0;\\;2]$.'
+ ],
+ line: { min:-2, max:5, lo:0, hi:2, openLo:false, openHi:false }
+ },
+ {
+ q: '$\\left(\\dfrac{1}{3}\\right)^{x-1} > 9$',
+ steps: [
+ 'Приводим к одному основанию: $9 = 3^2 = \\left(\\dfrac{1}{3}\\right)^{-2}$.',
+ 'Получаем $\\left(\\dfrac{1}{3}\\right)^{x-1} > \\left(\\dfrac{1}{3}\\right)^{-2}$.',
+ 'Основание $a = \\dfrac{1}{3} < 1$ — знак меняется : $x - 1 < -2$.',
+ 'Откуда $x < -1$.',
+ 'Ответ: $x \\in (-\\infty;\\;-1)$.'
+ ],
+ line: { min:-6, max:4, lo:null, hi:-1, openHi:true, dirLeft:true }
+ }
+ ];
+
+ function drawLine(L){
+ const W = 420, H = 84, padL = 24, padR = 24;
+ const y = 44;
+ const lo = (L.lo!=null) ? L.lo : L.min;
+ const hi = (L.hi!=null) ? L.hi : L.max;
+ const span = L.max - L.min;
+ const toX = v => padL + (v - L.min) * (W - padL - padR) / span;
+ let s = '';
+ // главная ось
+ s += ' ';
+ s += ' ';
+ // тики и подписи
+ for(let v = Math.ceil(L.min); v <= Math.floor(L.max); v++){
+ const x = toX(v);
+ s += ' ';
+ s += ''+v+' ';
+ }
+ // закрашенная область
+ const xLo = toX(lo), xHi = toX(hi);
+ let x1 = xLo, x2 = xHi;
+ if(L.dirLeft){ x1 = padL + 2; }
+ if(L.dirRight){ x2 = W - padR - 2; }
+ s += ' ';
+ if(L.dirLeft){
+ s += ' ';
+ }
+ if(L.dirRight){
+ s += ' ';
+ }
+ // граничные точки
+ if(L.lo != null){
+ const fill = L.openLo ? '#fff' : '#7c3aed';
+ s += ' ';
+ s += ''+L.lo+' ';
+ }
+ if(L.hi != null){
+ const fill = L.openHi ? '#fff' : '#7c3aed';
+ s += ' ';
+ s += ''+L.hi+' ';
+ }
+ s += ' ';
+ return s;
+ }
+
+ const sn = document.getElementById('p6-iv1-sn');
+ const nL = document.getElementById('p6-iv1-n');
+ const qEl = document.getElementById('p6-iv1-q');
+ const stepsEl = document.getElementById('p6-iv1-steps');
+ const lineEl = document.getElementById('p6-iv1-line');
+ const nextBtn = document.getElementById('p6-iv1-next');
+ const allBtn = document.getElementById('p6-iv1-all');
+ const resetBtn = document.getElementById('p6-iv1-reset');
+ const seen = new Set();
+ let _done = false;
+ let cur = 0, shown = 1;
+
+ function render(){
+ const t = TASKS[cur];
+ nL.textContent = (cur + 1);
+ qEl.innerHTML = t.q;
+ stepsEl.innerHTML = t.steps.map((s, i) => {
+ const visible = i < shown;
+ const isLast = i === t.steps.length - 1 && visible;
+ const bg = isLast ? '#dcfce7' : 'var(--card)';
+ const brd = isLast ? '2px solid #16a34a' : '1px solid var(--border)';
+ return 'Шаг '+(i+1)+': '+s+'
';
+ }).join('');
+ renderMath(qEl);
+ renderMath(stepsEl);
+ if(shown >= t.steps.length){
+ lineEl.innerHTML = 'Ответ на числовой прямой:
' + drawLine(t.line);
+ lineEl.style.display = 'block';
+ seen.add(cur);
+ if(!_done && seen.size >= 5){ _done = true; addXp(10, 'p6-iv1'); bumpProgress('p6', 15); }
+ } else {
+ lineEl.style.display = 'none';
+ }
+ }
+ function load(n){ cur = Math.max(0, Math.min(TASKS.length - 1, n)); shown = 1; render(); }
+ sn.addEventListener('input', () => load((+sn.value) - 1));
+ nextBtn.addEventListener('click', () => {
+ if(shown < TASKS[cur].steps.length){ shown++; render(); }
+ });
+ allBtn.addEventListener('click', () => { shown = TASKS[cur].steps.length; render(); });
+ resetBtn.addEventListener('click', () => { shown = 1; render(); });
+ load(0);
+ })();
+
+ /* === IV2 — калькулятор a^(kx+b) > c === */
+ (function(){
+ const aI = document.getElementById('p6-iv2-a');
+ const kI = document.getElementById('p6-iv2-k');
+ const bI = document.getElementById('p6-iv2-b');
+ const sgI = document.getElementById('p6-iv2-sg');
+ const cI = document.getElementById('p6-iv2-c');
+ const go = document.getElementById('p6-iv2-go');
+ const out = document.getElementById('p6-iv2-out');
+ const fb = document.getElementById('p6-iv2-fb');
+ const used = new Set();
+ let _done = false;
+
+ document.querySelectorAll('#p6-iv2 [data-set]').forEach(btn => {
+ btn.addEventListener('click', () => {
+ const v = btn.dataset.set.split(',');
+ aI.value = v[0]; kI.value = v[1]; bI.value = v[2]; sgI.value = v[3]; cI.value = v[4];
+ calc();
+ });
+ });
+
+ const SIGN_TEX = { gt:'>', ge:'\\ge', lt:'<', le:'\\le' };
+ const SIGN_INT = { gt:'(', ge:'[', lt:')', le:']' };
+ // переворот знака неравенства при умножении/делении на отрицательное
+ function flipSign(s){ return ({gt:'lt',ge:'le',lt:'gt',le:'ge'})[s]; }
+
+ function calc(){
+ const a = parseFloat(aI.value);
+ const k = parseFloat(kI.value);
+ const b = parseFloat(bI.value);
+ const c = parseFloat(cI.value);
+ const sg = sgI.value;
+ if(![a,k,b,c].every(isFinite)){ feedback(fb, false, '✗ Введи все четыре числа.'); return; }
+ if(a <= 0 || Math.abs(a - 1) < 1e-9){ feedback(fb, false, '✗ Основание $a$ должно быть $> 0$ и $\\ne 1$.'); return; }
+ if(k === 0){ feedback(fb, false, '✗ При $k = 0$ показатель не зависит от $x$.'); return; }
+
+ const expTex = (k===1?'':k) + 'x' + (b>0?'+'+b:(b<0?b:''));
+ const ineq = '$' + a + '^{' + expTex + '} ' + SIGN_TEX[sg] + ' ' + c + '$';
+ let html = 'Неравенство: '+ineq+'
';
+
+ // Случай c <= 0 — левая часть всегда > 0
+ if(c <= 0){
+ if(sg === 'gt' || sg === 'ge'){
+ html += 'Левая часть $a^{kx+b} > 0$ при любых $x$, а правая $\\le 0$. Значит неравенство верно при всех $x \\in \\mathbb{R}$.
';
+ } else {
+ html += 'Левая часть $a^{kx+b} > 0$, а требуется $\\le c \\le 0$. Решений нет .
';
+ }
+ out.innerHTML = html;
+ renderMath(out);
+ feedback(fb, true, '✓ Решено: см. ответ выше.');
+ used.add(aI.value+','+kI.value+','+bI.value+','+sgI.value+','+cI.value);
+ if(!_done && used.size >= 4){ _done = true; addXp(10, 'p6-iv2'); bumpProgress('p6', 15); }
+ return;
+ }
+
+ // Анализ монотонности
+ let sgEff = sg;
+ if(a < 1){
+ html += 'Основание $a = '+a+' < 1$ — функция убывает, знак неравенства МЕНЯЕТСЯ .
';
+ sgEff = flipSign(sgEff);
+ } else {
+ html += 'Основание $a = '+a+' > 1$ — функция возрастает, знак неравенства сохраняется .
';
+ }
+
+ // Степень
+ let intLog = null;
+ for(let p = -10; p <= 12; p++){
+ if(Math.abs(Math.pow(a, p) - c) < 1e-9){ intLog = p; break; }
+ }
+ let rhsTex;
+ if(intLog !== null){
+ html += '$'+c+' = '+a+'^{'+intLog+'}$, поэтому неравенство показателей: $'+expTex+' '+SIGN_TEX[sgEff]+' '+intLog+'$.
';
+ rhsTex = String(intLog);
+ } else {
+ rhsTex = '\\log_{'+a+'} '+c;
+ html += 'Неравенство показателей: $'+expTex+' '+SIGN_TEX[sgEff]+' \\log_{'+a+'} '+c+'$.
';
+ }
+
+ // Решаем kx + b [sgEff] R, где R = intLog (или log_a c)
+ // x [?] (R - b) / k. Если k<0, знак ещё раз меняется.
+ let sgFinal = sgEff;
+ if(k < 0){
+ html += 'Делим на $k = '+k+' < 0$ — знак снова меняется .
';
+ sgFinal = flipSign(sgFinal);
+ }
+
+ const xNum = (intLog !== null) ? (intLog - b) : (Math.log(c)/Math.log(a) - b);
+ const xVal = xNum / k;
+ const xStr = (Math.abs(xVal - Math.round(xVal)) < 1e-9) ? String(Math.round(xVal)) : (+xVal.toFixed(4)).toString();
+
+ // Формируем интервал
+ let interval;
+ if(sgFinal === 'gt') interval = '('+xStr+';\\,+\\infty)';
+ else if(sgFinal === 'ge') interval = '['+xStr+';\\,+\\infty)';
+ else if(sgFinal === 'lt') interval = '(-\\infty;\\,'+xStr+')';
+ else interval = '(-\\infty;\\,'+xStr+']';
+
+ html += '$\\Rightarrow\\; x '+SIGN_TEX[sgFinal]+' '+xStr+',\\quad x \\in '+interval+'$
';
+
+ out.innerHTML = html;
+ renderMath(out);
+ feedback(fb, true, '✓ Решено.');
+ used.add(aI.value+','+kI.value+','+bI.value+','+sgI.value+','+cI.value);
+ if(!_done && used.size >= 4){ _done = true; addXp(10, 'p6-iv2'); bumpProgress('p6', 15); }
+ }
+ go.addEventListener('click', calc);
+ [aI, kI, bI, cI].forEach(i => i.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); }));
+ calc();
+ })();
+
+ /* === IV3 — сохраняется или меняется? === */
+ (function(){
+ const OPTS = ['Сохраняется', 'Меняется'];
+ const Q = [
+ { q: '$2^{f(x)} > 2^{g(x)}$', ans: 0, hint: 'Основание $2 > 1$ — функция возрастает, знак сохраняется.' },
+ { q: '$\\left(\\dfrac{1}{3}\\right)^{f(x)} > \\left(\\dfrac{1}{3}\\right)^{g(x)}$', ans: 1, hint: 'Основание $\\dfrac{1}{3} < 1$ — функция убывает, знак меняется.' },
+ { q: '$5^x < 25$', ans: 0, hint: 'Приводим: $5^x < 5^2$. Основание $5 > 1$ — знак сохраняется.' },
+ { q: '$\\left(\\dfrac{1}{2}\\right)^x > 8$', ans: 1, hint: 'Приводим: $\\left(1/2\\right)^x > \\left(1/2\\right)^{-3}$. Основание $< 1$ — знак меняется.' },
+ { q: '$0{,}1^x \\le 0{,}01$', ans: 1, hint: 'Приводим: $0{,}1^x \\le 0{,}1^2$. Основание $0{,}1 < 1$ — знак меняется.' },
+ { q: '$3^x \\ge 27$', ans: 0, hint: 'Приводим: $3^x \\ge 3^3$. Основание $3 > 1$ — знак сохраняется.' },
+ { q: '$10^x > 100$', ans: 0, hint: 'Приводим: $10^x > 10^2$. Основание $10 > 1$ — знак сохраняется.' },
+ { q: '$\\left(\\dfrac{2}{5}\\right)^x < 1$', ans: 1, hint: 'Приводим: $\\left(2/5\\right)^x < \\left(2/5\\right)^0$. Основание $< 1$ — знак меняется.' },
+ ];
+ let i = 0, score = 0;
+ const qEl = document.getElementById('p6-iv3-q');
+ const oEl = document.getElementById('p6-iv3-opts');
+ const fb = document.getElementById('p6-iv3-fb');
+ const iEl = document.getElementById('p6-iv3-i');
+ const sEl = document.getElementById('p6-iv3-s');
+
+ function show(){
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: '+score+' / '+Q.length;
+ oEl.innerHTML = '';
+ if(score === Q.length){ addXp(15, 'p6-iv3'); bumpProgress('p6', 25); }
+ else if(score >= 6){ addXp(8, 'p6-iv3'); bumpProgress('p6', 15); }
+ return;
+ }
+ iEl.textContent = (i + 1);
+ sEl.textContent = score;
+ const item = Q[i];
+ qEl.innerHTML = 'Знак неравенства при переходе к показателям: ' + item.q;
+ oEl.innerHTML = OPTS.map((m, k) => ''+m+' ').join('');
+ fb.style.display = 'none';
+ renderMath(qEl);
+ oEl.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ const k = +b.dataset.k;
+ if(k === item.ans){ score++; feedback(fb, true, '✓ Верно! '+item.hint+' Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Правильно: '+OPTS[item.ans]+' . '+item.hint+' Дальше ▶');
+ sEl.textContent = score;
+ oEl.querySelectorAll('button').forEach(x => x.disabled = true);
+ i++;
+ setTimeout(show, 1500);
+ });
+ });
+ }
+ document.getElementById('p6-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
+ /* === IV4 — тренажёр неравенств === */
+ (function(){
+ const Q = [
+ { q: '$2^x > 16$ — введи границу', ans: 4, hint: '$2^x > 2^4 \\Rightarrow x > 4$. Граница — $4$.' },
+ { q: '$\\left(\\dfrac{1}{3}\\right)^x \\ge 9$ — введи границу', ans: -2, hint: '$\\left(1/3\\right)^x \\ge \\left(1/3\\right)^{-2}$. Знак меняется: $x \\le -2$. Граница — $-2$.' },
+ { q: '$5^x < 1$ — введи границу', ans: 0, hint: '$5^x < 5^0$. Знак сохраняется: $x < 0$. Граница — $0$.' },
+ { q: '$3^{x-1} \\le 81$ — введи границу', ans: 5, hint: '$3^{x-1} \\le 3^4 \\Rightarrow x - 1 \\le 4 \\Rightarrow x \\le 5$. Граница — $5$.' },
+ { q: '$\\left(\\dfrac{1}{2}\\right)^x > 0{,}25$ — введи границу', ans: 2, hint: '$\\left(1/2\\right)^x > \\left(1/2\\right)^2$. Знак меняется: $x < 2$. Граница — $2$.' },
+ { q: '$4^x \\ge 8$ — введи границу', ans: 1.5, hint: '$2^{2x} \\ge 2^3 \\Rightarrow 2x \\ge 3 \\Rightarrow x \\ge 1{,}5$. Граница — $1{,}5$.' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ const qEl = document.getElementById('p6-iv4-q');
+ const iEl = document.getElementById('p6-iv4-i');
+ const sEl = document.getElementById('p6-iv4-s');
+ const fb = document.getElementById('p6-iv4-fb');
+ const ansI = document.getElementById('p6-iv4-ans');
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: '+score+' / '+Q.length;
+ if(score === Q.length){ addXp(15, 'p6-iv4'); bumpProgress('p6', 25); }
+ else if(score >= 4){ addXp(8, 'p6-iv4'); bumpProgress('p6', 15); }
+ return;
+ }
+ iEl.textContent = (i + 1);
+ sEl.textContent = score;
+ qEl.innerHTML = Q[i].q;
+ ansI.value = '';
+ renderMath(qEl);
+ fb.style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p6-iv4-fb');
+ const raw = document.getElementById('p6-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ if(Math.abs(ans - Q[i].ans) < 0.05){
+ score++;
+ feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶');
+ } else {
+ feedback(fb, false, '✗ Неверно. Граница: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶');
+ }
+ document.getElementById('p6-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1500);
+ }
+ document.getElementById('p6-iv4-go').addEventListener('click', go);
+ document.getElementById('p6-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p6-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p6');
}
function buildFinal2(){
const box = document.getElementById('final2-body');
let html = '';
- html += makeCard('theory', 'В разработке', '★.0', `
- Содержание финала главы Финал главы будет добавлено в Phase 1+.
- Раздел Phase 0 — skeleton. Здесь появятся теория, примеры и интерактивы.
- Ключевая формула: Итоги · боссы главы 2
- `);
- html += secNavFor('final2');
- html += readButton('final2');
+
+ /* Часть А — Шпаргалка главы (3 mini-карточки) */
+ html += `
+
+
+
Ключевые формулы и идеи всех трёх параграфов в одном месте — просмотри перед битвой с боссами.
+
+
+
+
+
§ 4 · Показ. функция
+
+
$y = a^x$ ($a > 0$, $a \\ne 1$). $D = \\mathbb{R}$, $E = (0;\\,+\\infty)$. При $a > 1$ — возрастает, при $0 < a < 1$ — убывает. Через $(0;\\,1)$. Асимптота $y = 0$.
+
+
+
+
+
§ 5 · Показ. уравнения
+
+
$a^{f(x)} = a^{g(x)} \\Leftrightarrow f(x) = g(x)$. Четыре метода: одинаковое основание, замена переменной ($t = a^x > 0$), однородные, графический.
+
+
+
+
+
§ 6 · Показ. неравенства
+
+
При $a > 1$ знак сохраняется , при $0 < a < 1$ — меняется . Замена $t = a^x > 0$ — обязательно учитывать положительность.
+
+
+
+
`;
+
+ /* Часть Б — 5 боссов (intro) */
+ html += `
+
+
+
5 интегрированных задач по всей главе. За каждого побеждённого босса: +10 XP, +18% к прогрессу . Победишь всех — ачивка «Магистр показательной функции» и +50 XP бонус .
+
+
`;
+
+ html += '
';
+
+ html += `
+
Прогресс по боссам
+
0 / 5 боссов побеждено
+
+
+
Магистр показательной функции
+
Глава 2 пройдена! Все 5 боссов повержены. +50 XP бонус.
+
Дальше: Глава 3
+
+
`;
+
+ html += secNav('p6', null);
+
box.innerHTML = html;
renderMath(box);
- wireReadBtn('final2');
+
+ /* Боссы */
+ const BOSSES = [
+ {
+ n:1, color:'#10b981',
+ title:'Циклоп Показательной',
+ tag:'§ 4',
+ q:'Найдите значение функции $y = 3^x$ при $x = -2$. Введите ответ числом (допуск $\\pm 0{,}05$).',
+ ans:1/9,
+ hint:'$3^{-2} = \\dfrac{1}{3^2} = \\dfrac{1}{9} \\approx 0{,}11$.'
+ },
+ {
+ n:2, color:'#0891b2',
+ title:'Минотавр Уравнений',
+ tag:'§ 5',
+ q:'Решите уравнение $5^{2x-1} = 125$. Введите $x$.',
+ ans:2,
+ hint:'$125 = 5^3$, поэтому $2x - 1 = 3 \\Rightarrow x = 2$.'
+ },
+ {
+ n:3, color:'#7c3aed',
+ title:'Гарпия Неравенств',
+ tag:'§ 6',
+ q:'Решите $\\left(\\dfrac{1}{2}\\right)^x > 32$. Введите наибольшее целое $x$.',
+ ans:-6,
+ hint:'$\\left(1/2\\right)^x > \\left(1/2\\right)^{-5}$. Знак меняется: $x < -5$. Наибольшее целое — $-6$.'
+ },
+ {
+ n:4, color:'#dc2626',
+ title:'Дракон Замены',
+ tag:'§ 5 + § 6',
+ q:'Найдите сумму корней уравнения $9^x - 10 \\cdot 3^x + 9 = 0$.',
+ ans:2,
+ hint:'Замена $t = 3^x$: $t^2 - 10t + 9 = 0 \\Rightarrow t = 1$ или $t = 9$. $x = 0$ и $x = 2$. Сумма — $2$.'
+ },
+ {
+ n:5, color:'#f59e0b',
+ title:'Мастер Показательной',
+ tag:'§ 4 + § 5 + § 6',
+ q:'При каком $a$ функция $y = (3a - 5)^x$ убывает на $\\mathbb{R}$? Найдите сумму целых значений $a$ из найденного интервала.',
+ ans:0,
+ hint:'Убывает при $0 < 3a - 5 < 1$, то есть $\\dfrac{5}{3} < a < 2$. Целых $a$ в этом интервале нет — сумма равна $0$.'
+ },
+ ];
+
+ const cont = document.getElementById('ch2-bosses-container');
+ const STATE_KEY = 'algebra11_ch2_bosses';
+ const BOSS_STATE = (function(){
+ try{ const s = localStorage.getItem(STATE_KEY); if(s){ const p = JSON.parse(s); if(Array.isArray(p) && p.length === BOSSES.length) return p; } }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('ch2-boss-overall');
+ const fill = document.getElementById('ch2-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('ch2-final-reward');
+ if(reward && reward.style.display === 'none'){
+ reward.style.display = 'block';
+ if(!STATE.achievements.has('ch2_done')){
+ achievement('ch2_done','Магистр показательной функции');
+ addXp(50, 'ch2-bonus');
+ bumpProgress('final2', 30);
+ if(window.confetti){ try{ confetti(); }catch(e){} }
+ }
+ }
+ }
+ }
+
+ BOSSES.forEach((b, idx)=>{
+ const card = document.getElementById('boss2-'+b.n+'-card');
+ const goBtn = document.getElementById('boss2-'+b.n+'-go');
+ const hintBtn = document.getElementById('boss2-'+b.n+'-hint');
+ const ansInp = document.getElementById('boss2-'+b.n+'-ans');
+ if(BOSS_STATE[idx].defeated){
+ card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))';
+ card.classList.add('glow');
+ 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('boss2-'+b.n+'-fb');
+ const raw = ansInp.value.replace(',', '.');
+ const val = parseFloat(raw);
+ if(isNaN(val)){ feedback(fb, false, '✗ Введи число.'); return; }
+ if(Math.abs(val - b.ans) < 0.05){
+ BOSS_STATE[idx].defeated = true; saveBosses();
+ feedback(fb, true, '✓ Босс '+b.n+' повержен! +10 XP. '+b.hint);
+ addXp(10, 'boss-ch2-'+b.n);
+ bumpProgress('final2', 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))';
+ card.classList.add('glow','pulse');
+ setTimeout(()=>card.classList.remove('pulse'), 900);
+ refreshOverall();
+ } else {
+ feedback(fb, false, '✗ Промах. Попробуй ещё. Подсказка доступна.');
+ }
+ });
+ hintBtn.addEventListener('click', ()=>{
+ const fb = document.getElementById('boss2-'+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 ===== */