diff --git a/frontend/textbooks/algebra_8.html b/frontend/textbooks/algebra_8.html index e04ce8a..0606b55 100644 --- a/frontend/textbooks/algebra_8.html +++ b/frontend/textbooks/algebra_8.html @@ -454,6 +454,28 @@ input,select,textarea{font-family:inherit} /* hover-preview карточек выключен — мешал перекрытием соседних рядов */ .psel-card-preview{display:none!important} +/* Конвейер x → x² → √(x²) в §1 */ +.dual-pipeline{display:flex;align-items:center;justify-content:space-between;gap:6px;flex-wrap:wrap;margin-top:14px;padding:14px 8px;background:var(--card);border-radius:12px;border:1px solid var(--border)} +.dual-step{flex:1;min-width:90px;text-align:center;padding:10px 8px;border-radius:10px;background:rgba(233,30,99,0.04);border:1.5px solid var(--border)} +.dual-step.dual-input{background:rgba(233,30,99,0.12);border-color:rgba(233,30,99,0.4)} +.dual-step.dual-square{background:rgba(155,93,229,0.10);border-color:rgba(155,93,229,0.35)} +.dual-step.dual-output{background:rgba(3,169,244,0.12);border-color:rgba(3,169,244,0.4)} +.dual-step-lab{font-size:.66rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:4px} +.dual-step-val{font-size:1.8rem;font-weight:900;color:var(--text);font-family:'JetBrains Mono',monospace;line-height:1} +.dual-step-val.small{font-size:1.3rem;margin-top:4px} +.dual-step-cap{font-size:.78rem;color:var(--muted);margin-top:4px;font-family:'JetBrains Mono',monospace} +.dual-arrow{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;min-width:60px} +.dual-arrow svg{width:54px;height:24px} +.dual-arrow-lab{font-size:.68rem;color:var(--pri2);font-weight:600;margin-top:2px;text-align:center;line-height:1.2} +.dual-formula{margin-top:14px;padding:10px 14px;background:linear-gradient(135deg,var(--pri-soft),var(--acc-soft));border-radius:9px;text-align:center;font-size:.95rem;line-height:1.7;border:1px solid var(--border)} +.dual-formula.mod-active{background:linear-gradient(135deg,#fef3c7,#fce7f3);border-color:var(--warn)} +@media(max-width:680px){ + .dual-pipeline{flex-direction:column;gap:8px} + .dual-step{width:100%} + .dual-arrow{flex-direction:row;gap:8px} + .dual-arrow svg{transform:rotate(90deg);width:24px;height:54px} +} + /* Task 8: section fade transitions */ .sec.fade-out{animation:secFadeOut .18s ease forwards} .sec.fade-in{animation:secFadeIn .22s ease forwards} @@ -1697,25 +1719,40 @@ function buildP1(){ `)} - ${widget('Связка x² ↔ √x', 'VISUAL', 'Слева — площадь квадрата (x²). Справа — длина стороны (√x). Меняйте x ползунком — оба зеркалят друг друга.', ` -
+ ${widget('Конвейер: x → x² → √(x²)', 'VISUAL', 'Двигайте ползунок. Слева — возведение в квадрат, справа — извлечение корня. Попробуйте отрицательное x — результат всё равно положительный!', ` +
x = - - 5.0 + + 3.0
-
-
-
x²: квадрат со стороной x
- -
S = 25.0
+
+
+
Вход
+
3
+
x
-
-
√(x²): сторона возвращается
- -
сторона = 5.0
+
+ +
возвести в квадрат
+
+
+
Площадь
+ +
9
+
x² = $x \\cdot x$
+
+
+ +
извлечь корень
+
+
+
Выход
+
3
+
$\\sqrt{x^2} = |x|$
-

√(x²) = |x| — корень и квадрат «отменяют» друг друга для неотрицательных чисел.

+
$x = 3$ → $x^2 = 9$ → $\\sqrt{9} = 3$ ✓ (вернулись к исходному)
+

При отрицательном x результат всё равно положительный — это и есть смысл $\\sqrt{x^2} = |x|$

`)} ${makeCard('home','Домашнее задание','1.11–1.15',` @@ -2059,19 +2096,44 @@ function initDual(){ const x = document.getElementById('dual-x'); if(!x) return; const xv = document.getElementById('dual-x-val'); + const inEl = document.getElementById('dual-in'); const sq = document.getElementById('dual-sq'); const area = document.getElementById('dual-area'); - const side = document.getElementById('dual-side'); + const out = document.getElementById('dual-out'); + const formula = document.getElementById('dual-formula'); + function fmt(n){ return Number.isInteger(n) ? String(n) : n.toFixed(1); } function upd(){ const v = +x.value; - xv.textContent = v.toFixed(1); - const sz = Math.min(120, v * 10); - sq.setAttribute('x', 80 - sz/2); - sq.setAttribute('y', 80 - sz/2); - sq.setAttribute('width', Math.max(2, sz)); - sq.setAttribute('height', Math.max(2, sz)); - area.textContent = (v*v).toFixed(1); - side.textContent = v.toFixed(1); + const sq2 = v * v; + const root = Math.sqrt(sq2); + xv.textContent = fmt(v); + if(inEl) inEl.textContent = fmt(v); + // Размер квадрата: |v|·8, max 60 + const sz = Math.min(60, Math.abs(v) * 8 + 2); + if(sq){ + sq.setAttribute('x', 40 - sz/2); + sq.setAttribute('y', 40 - sz/2); + sq.setAttribute('width', sz); + sq.setAttribute('height', sz); + } + if(area) area.textContent = fmt(sq2); + if(out) out.textContent = fmt(root); + // Подсветка: если v < 0 — показать что вернулось |v|, а не v + if(formula){ + if(v < 0){ + formula.innerHTML = `$x = ${fmt(v)}$ → $x^2 = ${fmt(sq2)}$ → $\\sqrt{${fmt(sq2)}} = ${fmt(root)}$ ≠ ${fmt(v)} → это |x| = ${fmt(root)}`; + formula.classList.add('mod-active'); + } else if(v === 0){ + formula.innerHTML = `$x = 0$ → $x^2 = 0$ → $\\sqrt{0} = 0$ — особый случай`; + formula.classList.remove('mod-active'); + } else { + formula.innerHTML = `$x = ${fmt(v)}$ → $x^2 = ${fmt(sq2)}$ → $\\sqrt{${fmt(sq2)}} = ${fmt(root)}$ ✓ (вернулись к исходному)`; + formula.classList.remove('mod-active'); + } + if(window.renderMathInElement){ + try{ renderMathInElement(formula, {delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false}],throwOnError:false}); }catch(e){} + } + } } x.addEventListener('input', upd); upd();