feat(phys8 ch2): Phase 2.1 — визуальный hero + 20 IV-6 stubs

Hero: новый p8-hero с electric-pulse градиентом (5s), молнией
SVG-watermark (flicker анимация 3.2s), live meter тока в углу
(0.5 → 2.0 → 1.2 → 0.8 → 1.5 А, плавная tween).

20 section watermarks: тематические SVG символы по теме § —
2 заряда, проводник, индукция, атом, силовые линии, U-стрелка,
батарея, цепь, омега Ω, зигзаг ρl/S, посл/парал соединения,
P-мощность, магнит N/S, компас, электромагнит.

20 IV-6 stubs: 'Новый интерактив §N · coming soon' (заглушки
для Phase 2. bulk content). Все 20 builders на месте,
JS парсится.
This commit is contained in:
Maxim Dolgolyov
2026-05-30 10:14:21 +03:00
parent d190fd2de9
commit 1de2aed05d
2 changed files with 415 additions and 27 deletions
+140
View File
@@ -0,0 +1,140 @@
// Phase 2.1 — визуальный редизайн ch2 (Электромагнитные явления):
// 1. Hero: новый p8-hero с electric theme, lightning SVG watermark.
// 2. Section watermarks: тематические SVG в каждой <section sec-pN>.
// 3. IV-6 stubs для §12-31 (20 параграфов).
'use strict';
const fs = require('fs');
const path = require('path');
const DST = path.join(__dirname, '..', '..', 'frontend', 'textbooks', 'physics_8_ch2.html');
let h = fs.readFileSync(DST, 'utf8');
// === 1. Replace .hdr block with p8-hero ===
const LIGHTNING_WM = `<svg viewBox="0 0 100 100" aria-hidden="true">
<path d="M55 8 L25 56 L46 56 L40 92 L75 38 L52 38 L60 8 Z"/>
</svg>`;
const NEW_HERO = `<header class="p8-hero">
<div class="p8-hero-wm">${LIGHTNING_WM}</div>
<div class="p8-hero-meter" id="p8-meter-ch2"><span id="p8-meter-val">0.5</span> А</div>
<div class="p8-hero-inner">
<div class="p8-hero-eyebrow">Глава 2 · 20 параграфов</div>
<h1 class="p8-hero-title">Электромагнитные явления</h1>
<div class="p8-hero-sub">Заряд, ток, цепь, магнитное поле. Конструируйте цепи из компонентов, перемещайте заряды, наблюдайте за искрами и полями.</div>
<div class="hdr-side" style="margin-top:18px;display:flex;gap:8px;flex-wrap:wrap;position:relative;z-index:1">
<a href="/textbook/physics-8" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К физике 8</a>
<button id="search-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg> Поиск</button>
<button id="sidebar-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="14" y2="18"/></svg> Шпаргалка</button>
<button id="theme-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg><span id="theme-lab">Тёмная</span></button>
</div>
</div>
</header>`;
const oldHdrRegex = /<header class="hdr">[\s\S]*?<\/header>/;
if (h.match(oldHdrRegex)) {
h = h.replace(oldHdrRegex, NEW_HERO);
console.log('Hero replaced');
}
// === 2. Live meter скрипт (ток 0.5 → 2 → 1.2 → 0.8 → 1.5 А) ===
const METER_SCRIPT = `
<script>
/* P8 hero meter — анимированный ток (Phase 2 electric) */
(function(){
function init(){
const el = document.getElementById('p8-meter-val');
if (!el || !window.P8Anim) return;
const targets = [0.5, 2.0, 1.2, 0.8, 1.5];
let i = 0;
function step(){
const from = parseFloat(el.textContent) || 0;
const to = targets[i % targets.length];
P8Anim.tween({
from, to, duration: 1200, easing: 'cubicInOut',
onUpdate: v => { el.textContent = v.toFixed(1); },
onComplete: () => { i++; setTimeout(step, 1500); }
});
}
setTimeout(step, 1200);
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
else init();
})();
</script>
`;
if (!h.includes('P8 hero meter')) {
h = h.replace('</body>', METER_SCRIPT + '\n</body>');
console.log('Meter animation added');
}
// === 3. Section watermarks ===
const SEC_SYMBOLS = {
p12: '<svg viewBox="0 0 100 100"><circle cx="35" cy="50" r="14" fill="currentColor"/><circle cx="65" cy="50" r="14" fill="currentColor"/><path d="M40 50 L60 50 M50 40 L50 60" stroke="currentColor" stroke-width="3" fill="none"/></svg>', // 2 заряда
p13: '<svg viewBox="0 0 100 100"><rect x="20" y="40" width="60" height="20" fill="none" stroke="currentColor" stroke-width="4"/><circle cx="35" cy="50" r="3" fill="currentColor"/><circle cx="50" cy="50" r="3" fill="currentColor"/><circle cx="65" cy="50" r="3" fill="currentColor"/></svg>', // проводник
p14: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="24" fill="none" stroke="currentColor" stroke-width="4"/><path d="M50 26 L50 14 M50 86 L50 74 M26 50 L14 50 M86 50 L74 50" stroke="currentColor" stroke-width="4"/></svg>', // индукция
p15: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="16" fill="currentColor"/><path d="M50 30 L50 18 M50 82 L50 70 M30 50 L18 50 M82 50 L70 50" stroke="currentColor" stroke-width="3"/></svg>', // заряд центр
p16: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="6" fill="currentColor"/><ellipse cx="50" cy="50" rx="32" ry="14" fill="none" stroke="currentColor" stroke-width="2.5"/><ellipse cx="50" cy="50" rx="14" ry="32" fill="none" stroke="currentColor" stroke-width="2.5"/></svg>', // атом
p17: '<svg viewBox="0 0 100 100"><line x1="20" y1="50" x2="80" y2="50" stroke="currentColor" stroke-width="3"/><line x1="20" y1="35" x2="80" y2="65" stroke="currentColor" stroke-width="3"/><line x1="20" y1="65" x2="80" y2="35" stroke="currentColor" stroke-width="3"/></svg>', // силовые линии
p18: '<svg viewBox="0 0 100 100"><path d="M30 50 L70 50" stroke="currentColor" stroke-width="5" fill="none"/><path d="M65 45 L70 50 L65 55" stroke="currentColor" stroke-width="3" fill="none"/><text x="30" y="40" font-family="Inter" font-size="14" font-weight="700" fill="currentColor">U</text></svg>', // напряжение
p19: '<svg viewBox="0 0 100 100"><rect x="20" y="40" width="14" height="20" fill="currentColor"/><rect x="38" y="35" width="6" height="30" fill="currentColor"/><line x1="50" y1="50" x2="80" y2="50" stroke="currentColor" stroke-width="3"/></svg>', // батарея
p20: '<svg viewBox="0 0 100 100"><path d="M20 70 L40 30 L60 70 L80 30" stroke="currentColor" stroke-width="4" fill="none"/></svg>', // I=q/t
p21: '<svg viewBox="0 0 100 100"><rect x="20" y="40" width="60" height="20" fill="none" stroke="currentColor" stroke-width="3"/><path d="M30 50 L50 50 M55 45 L60 50 L55 55" stroke="currentColor" stroke-width="2" fill="none"/></svg>', // цепь
p22: '<svg viewBox="0 0 100 100"><text x="50" y="60" font-family="Unbounded" font-size="36" font-weight="900" fill="currentColor" text-anchor="middle">Ω</text></svg>', // Ом
p23: '<svg viewBox="0 0 100 100"><path d="M20 50 Q30 20, 40 50 T60 50 T80 50" stroke="currentColor" stroke-width="4" fill="none"/></svg>', // ρl/S зигзаг
p24: '<svg viewBox="0 0 100 100"><path d="M15 50 L25 50 L30 40 L40 60 L50 40 L60 60 L70 40 L75 50 L85 50" stroke="currentColor" stroke-width="3" fill="none"/></svg>', // последовательно
p25: '<svg viewBox="0 0 100 100"><path d="M20 30 L80 30 M20 70 L80 70 M50 30 L50 70" stroke="currentColor" stroke-width="3" fill="none"/></svg>', // параллельно
p26: '<svg viewBox="0 0 100 100"><text x="50" y="60" font-family="Unbounded" font-size="32" font-weight="900" fill="currentColor" text-anchor="middle">P</text></svg>', // мощность
p27: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="28" fill="none" stroke="currentColor" stroke-width="4"/><path d="M28 50 L72 50 M50 28 L50 72" stroke="currentColor" stroke-width="3"/></svg>', // энергия
p28: '<svg viewBox="0 0 100 100"><rect x="20" y="42" width="60" height="16" fill="currentColor"/><text x="32" y="56" font-family="Unbounded" font-size="14" font-weight="900" fill="#fff" text-anchor="middle">N</text><text x="68" y="56" font-family="Unbounded" font-size="14" font-weight="900" fill="#fff" text-anchor="middle">S</text></svg>', // магнит
p29: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="6" fill="currentColor"/><ellipse cx="50" cy="50" rx="36" ry="18" fill="none" stroke="currentColor" stroke-width="3"/><path d="M82 38 L86 48 L78 46" stroke="currentColor" stroke-width="3" fill="none"/></svg>', // силовые линии магн
p30: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="6" fill="currentColor"/><line x1="50" y1="20" x2="50" y2="80" stroke="currentColor" stroke-width="3"/><line x1="20" y1="50" x2="80" y2="50" stroke="currentColor" stroke-width="3"/></svg>', // компас
p31: '<svg viewBox="0 0 100 100"><path d="M30 30 Q40 20, 50 30 T70 30 M30 50 Q40 40, 50 50 T70 50 M30 70 Q40 60, 50 70 T70 70" stroke="currentColor" stroke-width="3" fill="none"/><rect x="48" y="20" width="4" height="60" fill="currentColor"/></svg>' // электромагнит
};
let secWmInjected = 0;
for (const pid of Object.keys(SEC_SYMBOLS)) {
const symbol = SEC_SYMBOLS[pid];
const secOpenRegex = new RegExp(`(<section[^>]+id="sec-${pid}"[^>]*>)`);
if (h.match(secOpenRegex) && !h.includes(`p8-sec-wm-${pid}`)) {
const wmDiv = `<div class="p8-sec-wm" id="p8-sec-wm-${pid}" aria-hidden="true">${symbol}</div>`;
h = h.replace(secOpenRegex, '$1\n ' + wmDiv);
secWmInjected++;
}
}
console.log('Section watermarks injected:', secWmInjected);
// === 4. IV-6 stubs для §12-31 ===
let stubsAdded = 0;
for (let n = 12; n <= 31; n++) {
const pid = 'p' + n;
const stubHtml = `
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.${n}) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §${n}</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.${n} — coming soon</div>'
+'</div>'
+'</div>';
`;
const marker = `box.innerHTML = h + secNavFor('${pid}') + readButton('${pid}');`;
if (!h.includes(`Новый интерактив §${n}`) && h.includes(marker)) {
h = h.replace(marker, stubHtml.trim() + '\n\n ' + marker);
stubsAdded++;
}
}
console.log('IV-6 stubs added:', stubsAdded);
fs.writeFileSync(DST, h);
console.log('ch2 final size:', h.length);
const scripts = [...h.matchAll(/<script>([\s\S]*?)<\/script>/g)];
for (const m of scripts) {
try { new Function(m[1]); }
catch (e) { console.error('JS PARSE FAIL:', e.message.slice(0, 150)); process.exit(1); }
}
console.log('inline JS parses OK');
const fns = [...h.matchAll(/function build_p(\d+)\(\)/g)].map(m => parseInt(m[1]));
console.log('Builders after:', fns.length, fns);
+275 -27
View File
@@ -630,13 +630,16 @@ a{color:inherit;text-decoration:none}
</head>
<body class="p8-theme-electric">
<header class="hdr">
<div class="hdr-row">
<div>
<h1>Физика 8 · Глава 2</h1>
<div class="hdr-sub">Электризация · ток · закон Ома · магнитное поле</div>
</div>
<div class="hdr-side">
<header class="p8-hero">
<div class="p8-hero-wm"><svg viewBox="0 0 100 100" aria-hidden="true">
<path d="M55 8 L25 56 L46 56 L40 92 L75 38 L52 38 L60 8 Z"/>
</svg></div>
<div class="p8-hero-meter" id="p8-meter-ch2"><span id="p8-meter-val">0.5</span> А</div>
<div class="p8-hero-inner">
<div class="p8-hero-eyebrow">Глава 2 · 20 параграфов</div>
<h1 class="p8-hero-title">Электромагнитные явления</h1>
<div class="p8-hero-sub">Заряд, ток, цепь, магнитное поле. Конструируйте цепи из компонентов, перемещайте заряды, наблюдайте за искрами и полями.</div>
<div class="hdr-side" style="margin-top:18px;display:flex;gap:8px;flex-wrap:wrap;position:relative;z-index:1">
<a href="/textbook/physics-8" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К физике 8</a>
<button id="search-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg> Поиск</button>
<button id="sidebar-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="14" y2="18"/></svg> Шпаргалка</button>
@@ -667,26 +670,46 @@ a{color:inherit;text-decoration:none}
<div id="psel-grid" class="psel-grid"></div>
</section>
<section id="sec-p12" class="sec"><div class="sec-header"><span class="sec-num">&sect; 12</span><h2 class="sec-h">Электризация тел. Взаимодействие зарядов</h2></div><div id="p12-body"></div></section>
<section id="sec-p13" class="sec"><div class="sec-header"><span class="sec-num">&sect; 13</span><h2 class="sec-h">Проводники и диэлектрики</h2></div><div id="p13-body"></div></section>
<section id="sec-p14" class="sec"><div class="sec-header"><span class="sec-num">&sect; 14</span><h2 class="sec-h">Электризация через влияние</h2></div><div id="p14-body"></div></section>
<section id="sec-p15" class="sec"><div class="sec-header"><span class="sec-num">&sect; 15</span><h2 class="sec-h">Электрический заряд. Элементарный заряд</h2></div><div id="p15-body"></div></section>
<section id="sec-p16" class="sec"><div class="sec-header"><span class="sec-num">&sect; 16</span><h2 class="sec-h">Строение атома. Ионы</h2></div><div id="p16-body"></div></section>
<section id="sec-p17" class="sec"><div class="sec-header"><span class="sec-num">&sect; 17</span><h2 class="sec-h">Электрическое поле. Электрическое напряжение</h2></div><div id="p17-body"></div></section>
<section id="sec-p18" class="sec"><div class="sec-header"><span class="sec-num">&sect; 18</span><h2 class="sec-h">Единица электрического напряжения. Расчёт работы в электрическом поле</h2></div><div id="p18-body"></div></section>
<section id="sec-p19" class="sec"><div class="sec-header"><span class="sec-num">&sect; 19</span><h2 class="sec-h">Электрический ток. Источники тока</h2></div><div id="p19-body"></div></section>
<section id="sec-p20" class="sec"><div class="sec-header"><span class="sec-num">&sect; 20</span><h2 class="sec-h">Сила и направление электрического тока</h2></div><div id="p20-body"></div></section>
<section id="sec-p21" class="sec"><div class="sec-header"><span class="sec-num">&sect; 21</span><h2 class="sec-h">Электрическая цепь. Измерение силы тока и напряжения</h2></div><div id="p21-body"></div></section>
<section id="sec-p22" class="sec"><div class="sec-header"><span class="sec-num">&sect; 22</span><h2 class="sec-h">Связь силы тока и напряжения. Закон Ома для участка электрической цепи</h2></div><div id="p22-body"></div></section>
<section id="sec-p23" class="sec"><div class="sec-header"><span class="sec-num">&sect; 23</span><h2 class="sec-h">Единица сопротивления. Расчёт сопротивления</h2></div><div id="p23-body"></div></section>
<section id="sec-p24" class="sec"><div class="sec-header"><span class="sec-num">&sect; 24</span><h2 class="sec-h">Последовательное соединение проводников. Реостат</h2></div><div id="p24-body"></div></section>
<section id="sec-p25" class="sec"><div class="sec-header"><span class="sec-num">&sect; 25</span><h2 class="sec-h">Параллельное соединение проводников</h2></div><div id="p25-body"></div></section>
<section id="sec-p26" class="sec"><div class="sec-header"><span class="sec-num">&sect; 26</span><h2 class="sec-h">Работа и мощность электрического тока. Закон Джоуля — Ленца</h2></div><div id="p26-body"></div></section>
<section id="sec-p27" class="sec"><div class="sec-header"><span class="sec-num">&sect; 27</span><h2 class="sec-h">Использование и экономия электроэнергии. Безопасность</h2></div><div id="p27-body"></div></section>
<section id="sec-p28" class="sec"><div class="sec-header"><span class="sec-num">&sect; 28</span><h2 class="sec-h">Постоянные магниты</h2></div><div id="p28-body"></div></section>
<section id="sec-p29" class="sec"><div class="sec-header"><span class="sec-num">&sect; 29</span><h2 class="sec-h">Магнитное поле</h2></div><div id="p29-body"></div></section>
<section id="sec-p30" class="sec"><div class="sec-header"><span class="sec-num">&sect; 30</span><h2 class="sec-h">Магнитное поле тока</h2></div><div id="p30-body"></div></section>
<section id="sec-p31" class="sec"><div class="sec-header"><span class="sec-num">&sect; 31</span><h2 class="sec-h">Магнитное поле прямого проводника и катушки с током. Электромагнит</h2></div><div id="p31-body"></div></section>
<section id="sec-p12" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p12" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="35" cy="50" r="14" fill="currentColor"/><circle cx="65" cy="50" r="14" fill="currentColor"/><path d="M40 50 L60 50 M50 40 L50 60" stroke="currentColor" stroke-width="3" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 12</span><h2 class="sec-h">Электризация тел. Взаимодействие зарядов</h2></div><div id="p12-body"></div></section>
<section id="sec-p13" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p13" aria-hidden="true"><svg viewBox="0 0 100 100"><rect x="20" y="40" width="60" height="20" fill="none" stroke="currentColor" stroke-width="4"/><circle cx="35" cy="50" r="3" fill="currentColor"/><circle cx="50" cy="50" r="3" fill="currentColor"/><circle cx="65" cy="50" r="3" fill="currentColor"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 13</span><h2 class="sec-h">Проводники и диэлектрики</h2></div><div id="p13-body"></div></section>
<section id="sec-p14" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p14" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="24" fill="none" stroke="currentColor" stroke-width="4"/><path d="M50 26 L50 14 M50 86 L50 74 M26 50 L14 50 M86 50 L74 50" stroke="currentColor" stroke-width="4"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 14</span><h2 class="sec-h">Электризация через влияние</h2></div><div id="p14-body"></div></section>
<section id="sec-p15" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p15" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="16" fill="currentColor"/><path d="M50 30 L50 18 M50 82 L50 70 M30 50 L18 50 M82 50 L70 50" stroke="currentColor" stroke-width="3"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 15</span><h2 class="sec-h">Электрический заряд. Элементарный заряд</h2></div><div id="p15-body"></div></section>
<section id="sec-p16" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p16" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="6" fill="currentColor"/><ellipse cx="50" cy="50" rx="32" ry="14" fill="none" stroke="currentColor" stroke-width="2.5"/><ellipse cx="50" cy="50" rx="14" ry="32" fill="none" stroke="currentColor" stroke-width="2.5"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 16</span><h2 class="sec-h">Строение атома. Ионы</h2></div><div id="p16-body"></div></section>
<section id="sec-p17" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p17" aria-hidden="true"><svg viewBox="0 0 100 100"><line x1="20" y1="50" x2="80" y2="50" stroke="currentColor" stroke-width="3"/><line x1="20" y1="35" x2="80" y2="65" stroke="currentColor" stroke-width="3"/><line x1="20" y1="65" x2="80" y2="35" stroke="currentColor" stroke-width="3"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 17</span><h2 class="sec-h">Электрическое поле. Электрическое напряжение</h2></div><div id="p17-body"></div></section>
<section id="sec-p18" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p18" aria-hidden="true"><svg viewBox="0 0 100 100"><path d="M30 50 L70 50" stroke="currentColor" stroke-width="5" fill="none"/><path d="M65 45 L70 50 L65 55" stroke="currentColor" stroke-width="3" fill="none"/><text x="30" y="40" font-family="Inter" font-size="14" font-weight="700" fill="currentColor">U</text></svg></div><div class="sec-header"><span class="sec-num">&sect; 18</span><h2 class="sec-h">Единица электрического напряжения. Расчёт работы в электрическом поле</h2></div><div id="p18-body"></div></section>
<section id="sec-p19" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p19" aria-hidden="true"><svg viewBox="0 0 100 100"><rect x="20" y="40" width="14" height="20" fill="currentColor"/><rect x="38" y="35" width="6" height="30" fill="currentColor"/><line x1="50" y1="50" x2="80" y2="50" stroke="currentColor" stroke-width="3"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 19</span><h2 class="sec-h">Электрический ток. Источники тока</h2></div><div id="p19-body"></div></section>
<section id="sec-p20" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p20" aria-hidden="true"><svg viewBox="0 0 100 100"><path d="M20 70 L40 30 L60 70 L80 30" stroke="currentColor" stroke-width="4" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 20</span><h2 class="sec-h">Сила и направление электрического тока</h2></div><div id="p20-body"></div></section>
<section id="sec-p21" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p21" aria-hidden="true"><svg viewBox="0 0 100 100"><rect x="20" y="40" width="60" height="20" fill="none" stroke="currentColor" stroke-width="3"/><path d="M30 50 L50 50 M55 45 L60 50 L55 55" stroke="currentColor" stroke-width="2" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 21</span><h2 class="sec-h">Электрическая цепь. Измерение силы тока и напряжения</h2></div><div id="p21-body"></div></section>
<section id="sec-p22" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p22" aria-hidden="true"><svg viewBox="0 0 100 100"><text x="50" y="60" font-family="Unbounded" font-size="36" font-weight="900" fill="currentColor" text-anchor="middle">Ω</text></svg></div><div class="sec-header"><span class="sec-num">&sect; 22</span><h2 class="sec-h">Связь силы тока и напряжения. Закон Ома для участка электрической цепи</h2></div><div id="p22-body"></div></section>
<section id="sec-p23" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p23" aria-hidden="true"><svg viewBox="0 0 100 100"><path d="M20 50 Q30 20, 40 50 T60 50 T80 50" stroke="currentColor" stroke-width="4" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 23</span><h2 class="sec-h">Единица сопротивления. Расчёт сопротивления</h2></div><div id="p23-body"></div></section>
<section id="sec-p24" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p24" aria-hidden="true"><svg viewBox="0 0 100 100"><path d="M15 50 L25 50 L30 40 L40 60 L50 40 L60 60 L70 40 L75 50 L85 50" stroke="currentColor" stroke-width="3" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 24</span><h2 class="sec-h">Последовательное соединение проводников. Реостат</h2></div><div id="p24-body"></div></section>
<section id="sec-p25" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p25" aria-hidden="true"><svg viewBox="0 0 100 100"><path d="M20 30 L80 30 M20 70 L80 70 M50 30 L50 70" stroke="currentColor" stroke-width="3" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 25</span><h2 class="sec-h">Параллельное соединение проводников</h2></div><div id="p25-body"></div></section>
<section id="sec-p26" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p26" aria-hidden="true"><svg viewBox="0 0 100 100"><text x="50" y="60" font-family="Unbounded" font-size="32" font-weight="900" fill="currentColor" text-anchor="middle">P</text></svg></div><div class="sec-header"><span class="sec-num">&sect; 26</span><h2 class="sec-h">Работа и мощность электрического тока. Закон Джоуля — Ленца</h2></div><div id="p26-body"></div></section>
<section id="sec-p27" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p27" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="28" fill="none" stroke="currentColor" stroke-width="4"/><path d="M28 50 L72 50 M50 28 L50 72" stroke="currentColor" stroke-width="3"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 27</span><h2 class="sec-h">Использование и экономия электроэнергии. Безопасность</h2></div><div id="p27-body"></div></section>
<section id="sec-p28" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p28" aria-hidden="true"><svg viewBox="0 0 100 100"><rect x="20" y="42" width="60" height="16" fill="currentColor"/><text x="32" y="56" font-family="Unbounded" font-size="14" font-weight="900" fill="#fff" text-anchor="middle">N</text><text x="68" y="56" font-family="Unbounded" font-size="14" font-weight="900" fill="#fff" text-anchor="middle">S</text></svg></div><div class="sec-header"><span class="sec-num">&sect; 28</span><h2 class="sec-h">Постоянные магниты</h2></div><div id="p28-body"></div></section>
<section id="sec-p29" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p29" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="6" fill="currentColor"/><ellipse cx="50" cy="50" rx="36" ry="18" fill="none" stroke="currentColor" stroke-width="3"/><path d="M82 38 L86 48 L78 46" stroke="currentColor" stroke-width="3" fill="none"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 29</span><h2 class="sec-h">Магнитное поле</h2></div><div id="p29-body"></div></section>
<section id="sec-p30" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p30" aria-hidden="true"><svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="6" fill="currentColor"/><line x1="50" y1="20" x2="50" y2="80" stroke="currentColor" stroke-width="3"/><line x1="20" y1="50" x2="80" y2="50" stroke="currentColor" stroke-width="3"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 30</span><h2 class="sec-h">Магнитное поле тока</h2></div><div id="p30-body"></div></section>
<section id="sec-p31" class="sec">
<div class="p8-sec-wm" id="p8-sec-wm-p31" aria-hidden="true"><svg viewBox="0 0 100 100"><path d="M30 30 Q40 20, 50 30 T70 30 M30 50 Q40 40, 50 50 T70 50 M30 70 Q40 60, 50 70 T70 70" stroke="currentColor" stroke-width="3" fill="none"/><rect x="48" y="20" width="4" height="60" fill="currentColor"/></svg></div><div class="sec-header"><span class="sec-num">&sect; 31</span><h2 class="sec-h">Магнитное поле прямого проводника и катушки с током. Электромагнит</h2></div><div id="p31-body"></div></section>
<section id="sec-final2" class="sec"><div class="sec-header"><span class="sec-num">&#9733;</span><h2 class="sec-h">Финал главы</h2></div><div id="final2-body"></div></section>
</div>
@@ -1384,6 +1407,16 @@ function build_p12(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p12-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p12-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.12) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §12</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.12 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p12') + readButton('p12');
renderMath(box);
wireReadBtn('p12');
@@ -1618,6 +1651,16 @@ function build_p13(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p13-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p13-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.13) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §13</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.13 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p13') + readButton('p13');
renderMath(box);
wireReadBtn('p13');
@@ -1862,6 +1905,16 @@ function build_p14(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p14-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p14-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.14) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §14</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.14 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p14') + readButton('p14');
renderMath(box);
wireReadBtn('p14');
@@ -2089,6 +2142,16 @@ function build_p15(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p15-task-i">1</b> / 5</span><span>Правильно: <b id="p15-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.15) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §15</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.15 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p15') + readButton('p15');
renderMath(box);
wireReadBtn('p15');
@@ -2294,6 +2357,16 @@ function build_p16(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p16-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p16-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.16) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §16</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.16 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p16') + readButton('p16');
renderMath(box);
wireReadBtn('p16');
@@ -2527,6 +2600,16 @@ function build_p17(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p17-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p17-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.17) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §17</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.17 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p17') + readButton('p17');
renderMath(box);
wireReadBtn('p17');
@@ -2720,6 +2803,16 @@ function build_p18(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p18-task-i">1</b> / 5</span><span>Правильно: <b id="p18-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.18) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §18</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.18 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p18') + readButton('p18');
renderMath(box);
wireReadBtn('p18');
@@ -2931,6 +3024,16 @@ function build_p19(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p19-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p19-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.19) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §19</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.19 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p19') + readButton('p19');
renderMath(box);
wireReadBtn('p19');
@@ -3188,6 +3291,16 @@ function build_p20(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p20-task-i">1</b> / 5</span><span>Правильно: <b id="p20-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.20) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §20</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.20 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p20') + readButton('p20');
renderMath(box);
wireReadBtn('p20');
@@ -3425,6 +3538,16 @@ function build_p21(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p21-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p21-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.21) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §21</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.21 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p21') + readButton('p21');
renderMath(box);
wireReadBtn('p21');
@@ -3638,6 +3761,16 @@ function build_p22(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p22-task-i">1</b> / 6</span><span>Правильно: <b id="p22-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.22) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §22</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.22 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p22') + readButton('p22');
renderMath(box);
wireReadBtn('p22');
@@ -3871,6 +4004,16 @@ function build_p23(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p23-task-i">1</b> / 5</span><span>Правильно: <b id="p23-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.23) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §23</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.23 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p23') + readButton('p23');
renderMath(box);
wireReadBtn('p23');
@@ -4087,6 +4230,16 @@ function build_p24(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p24-task-i">1</b> / 5</span><span>Правильно: <b id="p24-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.24) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §24</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.24 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p24') + readButton('p24');
renderMath(box);
wireReadBtn('p24');
@@ -4301,6 +4454,16 @@ function build_p25(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p25-task-i">1</b> / 6</span><span>Правильно: <b id="p25-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.25) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §25</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.25 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p25') + readButton('p25');
renderMath(box);
wireReadBtn('p25');
@@ -4531,6 +4694,16 @@ function build_p26(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p26-task-i">1</b> / 6</span><span>Правильно: <b id="p26-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.26) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §26</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.26 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p26') + readButton('p26');
renderMath(box);
wireReadBtn('p26');
@@ -4750,6 +4923,16 @@ function build_p27(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p27-task-i">1</b> / 5</span><span>Правильно: <b id="p27-task-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.27) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §27</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.27 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p27') + readButton('p27');
renderMath(box);
wireReadBtn('p27');
@@ -4978,6 +5161,16 @@ function build_p28(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p28-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p28-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.28) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §28</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.28 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p28') + readButton('p28');
renderMath(box);
wireReadBtn('p28');
@@ -5187,6 +5380,16 @@ function build_p29(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p29-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p29-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.29) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §29</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.29 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p29') + readButton('p29');
renderMath(box);
wireReadBtn('p29');
@@ -5408,6 +5611,16 @@ function build_p30(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p30-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p30-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.30) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §30</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.30 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p30') + readButton('p30');
renderMath(box);
wireReadBtn('p30');
@@ -5645,6 +5858,16 @@ function build_p31(){
+'<div class="score-display" style="margin-top:10px"><span>Задача: <b id="p31-tasks5-i">1</b> / 5</span><span>Правильно: <b id="p31-tasks5-ok">0</b></span></div>'
+'</div>';
/* IV6 — flagship интерактив (заглушка Phase 2, наполнение в Phase 2.31) */
h += '<div class="wg p8-iv6">'
+'<div class="wg-header"><span class="wg-badge p8-badge p8-badge-electric">IV-6</span><div class="wg-title">Новый интерактив §31</div></div>'
+'<div class="wg-help">Готовится: интерактивная визуализация с drag-and-drop для углубления темы. Скоро будет доступна.</div>'
+'<div style="padding:30px;text-align:center;color:var(--p8-muted);font-style:italic">'
+'<svg viewBox="0 0 24 24" style="width:32px;height:32px;stroke:currentColor;fill:none;stroke-width:1.5;opacity:.4"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>'
+'<div style="margin-top:8px;font-size:.86rem">Phase 2.31 — coming soon</div>'
+'</div>'
+'</div>';
box.innerHTML = h + secNavFor('p31') + readButton('p31');
renderMath(box);
wireReadBtn('p31');
@@ -5928,5 +6151,30 @@ document.addEventListener('DOMContentLoaded', init);
</script>
<script>
/* P8 hero meter — анимированный ток (Phase 2 electric) */
(function(){
function init(){
const el = document.getElementById('p8-meter-val');
if (!el || !window.P8Anim) return;
const targets = [0.5, 2.0, 1.2, 0.8, 1.5];
let i = 0;
function step(){
const from = parseFloat(el.textContent) || 0;
const to = targets[i % targets.length];
P8Anim.tween({
from, to, duration: 1200, easing: 'cubicInOut',
onUpdate: v => { el.textContent = v.toFixed(1); },
onComplete: () => { i++; setTimeout(step, 1500); }
});
}
setTimeout(step, 1200);
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
else init();
})();
</script>
</body>
</html>